replaced graphics based element masks with pre-calculated array (MM engine)
[rocksndiamonds.git] / src / game_mm / mm_game.c
index 192dbf585aada246cfb17f0dd7fe484f5ed69430..84242f0be78ce1a6ff95bc6f8ee7d84f6658378d 100644 (file)
@@ -88,6 +88,238 @@ static void ContinueMoving_MM(int, int);
 static void Moving2Blocked_MM(int, int, int *, int *);
 
 
+#if 0
+// =============================================================================
+// TMP_dump_masks_MM (code)
+// =============================================================================
+
+void TMP_dump_masks_MM()
+{
+  int i;
+
+  printf("static const char mm_masks[10][16][16] =\n");
+  printf("{\n");
+
+  for (i = EL_MM_MASK_MCDUFFIN_RIGHT; i <= EL_MM_MASK_CIRCLE; i++)
+  {
+    int graphic_mask = el2gfx(i);
+    Bitmap *bitmap;
+    int src_x, src_y;
+    int x, y;
+
+    getGraphicSource(graphic_mask, 0, &bitmap, &src_x, &src_y);
+
+    printf("  {\n");
+
+    for (y = 0; y < TILEY; y += 2)
+    {
+      printf("    \"");
+
+      for (x = 0; x < TILEX; x += 2)
+      {
+       Pixel pixel = GetPixel(bitmap, src_x + x, src_y + y);
+
+       printf("%c", (pixel ? 'X' : ' '));
+      }
+
+      printf("\",\n");
+    }
+
+    printf("  },\n");
+  }
+
+  printf("};\n");
+}
+#endif
+
+// =============================================================================
+// TMP_dump_masks_MM (result)
+// =============================================================================
+
+static const char mm_masks[10][16][16 + 1] =
+{
+  {
+    "                ",
+    "    XXXXX       ",
+    "   XXXXXXX      ",
+    "  XXXXXXXXXXX   ",
+    "  XXXXXXXXXXXXX ",
+    "  XXXXXXXXXXXXXX",
+    "  XXXXXXXXXXXXXX",
+    "  XXXXXXXXXXXXX ",
+    "  XXXXXXXXXXXXX ",
+    "  XXXXXXXXXXXXX ",
+    "  XXXXXXXXXXXXX ",
+    "  XXXXXXXXXXXXX ",
+    "  XXXXXXXXXXXXX ",
+    "  XXXXXXXXXXXXX ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+  },
+  {
+    "                ",
+    "    XXXXXXXX    ",
+    "  XXXXXXXXXXXX  ",
+    " XXXXXXXXXXXXXX ",
+    " XXXXXXXXXXXXXX ",
+    " XXXXXXXXXXXXXX ",
+    " XXXXXXXXXXXXXX ",
+    " XXXXXXXXXXXXXX ",
+    " XXXXXXXXXXXXXX ",
+    " XXXXXXXXXXXXXX ",
+    " XXXXXXXXXXXXXX ",
+    " XXXXXXXXXXXXXX ",
+    " XXXXXXXXXXXXXX ",
+    "  XXXXXXXXXXXXX ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+  },
+  {
+    "                ",
+    "    XXXXXX      ",
+    "  XXXXXXXXX     ",
+    " XXXXXXXXXXX    ",
+    "XXXXXXXXXXXXX   ",
+    "XXXXXXXXXXXXX   ",
+    "XXXXXXXXXXXXXX  ",
+    " XXXXXXXXXXXXX  ",
+    " XXXXXXXXXXXXX  ",
+    " XXXXXXXXXXXXX  ",
+    " XXXXXXXXXXXXX  ",
+    " XXXXXXXXXXXXX  ",
+    " XXXXXXXXXXXXX  ",
+    " XXXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+  },
+  {
+    "                ",
+    "    XXXXXX      ",
+    "   XXXXXXXX     ",
+    "  XXXXXXXXXX    ",
+    "  XXXXXXXXXXX   ",
+    "  XXXXXXXXXXX   ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXX  XXXXX  ",
+  },
+  {
+    " XXXXXX  XXXXXX ",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "                ",
+    "                ",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    " XXXXXX  XXXXXX ",
+  },
+  {
+    " XXXXXX  XXXXXX ",
+    "XXXXXXX  XXXXXXX",
+    "XXXXXXX  XXXXXXX",
+    "XXXXXXX  XXXXXXX",
+    "XXXXXXX  XXXXXXX",
+    "XXXXXXX  XXXXXXX",
+    "XXXXXXX  XXXXXXX",
+    " XXXXXX  XXXXXX ",
+    " XXXXXX  XXXXXX ",
+    "XXXXXXX  XXXXXXX",
+    "XXXXXXX  XXXXXXX",
+    "XXXXXXX  XXXXXXX",
+    "XXXXXXX  XXXXXXX",
+    "XXXXXXX  XXXXXXX",
+    "XXXXXXX  XXXXXXX",
+    " XXXXXX  XXXXXX ",
+  },
+  {
+    "     XX  XXXXX  ",
+    "    XXX  XXXX   ",
+    "   XXXX  XXX   X",
+    "  XXXXXXXXX   XX",
+    " XXXXXXXXX   XXX",
+    "XXXXXXXXX   XXXX",
+    "XXXXXXXX   XXXXX",
+    "   XXXX   XXX   ",
+    "   XXX   XXXX   ",
+    "XXXXX   XXXXXXXX",
+    "XXXX   XXXXXXXXX",
+    "XXX   XXXXXXXXX ",
+    "XX   XXXXXXXXX  ",
+    "X   XXX  XXXX   ",
+    "   XXXX  XXX    ",
+    "  XXXXX  XX     ",
+  },
+  {
+    "  XXXXX  XX     ",
+    "   XXXX  XXX    ",
+    "X   XXX  XXXX   ",
+    "XX   XXXXXXXXX  ",
+    "XXX   XXXXXXXXX ",
+    "XXXX   XXXXXXXXX",
+    "XXXXX   XXXXXXXX",
+    "   XXX   XXXX   ",
+    "   XXXX   XXX   ",
+    "XXXXXXXX   XXXXX",
+    "XXXXXXXXX   XXXX",
+    " XXXXXXXXX   XXX",
+    "  XXXXXXXXX   XX",
+    "   XXXX  XXX   X",
+    "    XXX  XXXX   ",
+    "     XX  XXXXX  ",
+  },
+  {
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+    "XXXXXXXXXXXXXXXX",
+  },
+  {
+    "                ",
+    "      XXXX      ",
+    "    XXXXXXXX    ",
+    "   XXXXXXXXXX   ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+    " XXXXXXXXXXXXXX ",
+    " XXXXXXXXXXXXXX ",
+    " XXXXXXXXXXXXXX ",
+    " XXXXXXXXXXXXXX ",
+    "  XXXXXXXXXXXX  ",
+    "  XXXXXXXXXXXX  ",
+    "   XXXXXXXXXX   ",
+    "    XXXXXXXX    ",
+    "      XXXX      ",
+    "                ",
+  },
+};
+
 static int get_element_angle(int element)
 {
   int element_phase = get_element_phase(element);
@@ -275,6 +507,9 @@ static void InitLaser()
   laser.num_beamers = 0;
   laser.beamer_edge[0] = 0;
 
+  laser.dest_element = EL_EMPTY;
+  laser.wall_mask = 0;
+
   AddLaserEdge(LX, LY);                /* set laser starting edge */
 
   pen_ray = GetPixelFromRGB(window,
@@ -287,6 +522,10 @@ void InitGameEngine_MM()
 {
   int i, x, y;
 
+#if 0
+  TMP_dump_masks_MM();
+#endif
+
   /* set global game control values */
   game_mm.num_cycle = 0;
   game_mm.num_pacman = 0;
@@ -525,17 +764,9 @@ int ScanPixel()
        }
        else
        {
-         int graphic_mask = getMaskFromElement(element);
-         Bitmap *bitmap;
-         int src_x, src_y;
-         int mask_x, mask_y;
+         int pos = getMaskFromElement(element) - IMG_MM_MASK_MCDUFFIN_RIGHT;
 
-         getGraphicSource(graphic_mask, 0, &bitmap, &src_x, &src_y);
-
-         mask_x = src_x + dx;
-         mask_y = src_y + dy;
-
-         pixel = (ReadPixel(bitmap, mask_x, mask_y) ? 1 : 0);
+         pixel = (mm_masks[pos][dy / 2][dx / 2] == 'X' ? 1 : 0);
        }
       }
       else
@@ -738,7 +969,7 @@ void ScanLaser()
   if (rf)
     DrawLaser(rf - 1, DL_LASER_ENABLED);
 
-  Ct = CT = Counter();
+  Ct = CT = FrameCounter;
 
 #if 0
     if (!IN_LEV_FIELD(ELX, ELY))
@@ -2181,17 +2412,19 @@ static void Explode_MM(int x, int y, int phase, int mode)
   {
     if (Store[x][y] == EL_BOMB)
     {
-      laser.num_damages--;
       DrawLaser(0, DL_LASER_DISABLED);
-      laser.num_edges = 0;
+      InitLaser();
 
       Bang_MM(laser.start_edge.x, laser.start_edge.y);
       Store[x][y] = EL_EMPTY;
+
+      game_mm.game_over = TRUE;
+      game_mm.game_over_cause = GAME_OVER_BOMB;
+
+      laser.overloaded = FALSE;
     }
     else if (IS_MCDUFFIN(Store[x][y]))
     {
-      game_mm.game_over = TRUE;
-      game_mm.game_over_cause = GAME_OVER_BOMB;
       Store[x][y] = EL_EMPTY;
     }
 
@@ -2733,9 +2966,9 @@ void ColorCycling(void)
   if (color_status == STATIC_COLORS)
     return;
 
-  CC = Counter();
+  CC = FrameCounter;
 
-  if (CC < Cc || CC > Cc + 50)
+  if (CC < Cc || CC > Cc + 2)
   {
     Cc = CC;
 
@@ -2811,7 +3044,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
   laser.redraw = FALSE;
 #endif
 
-  CT = Counter();
+  CT = FrameCounter;
 
   if (game_mm.num_pacman && FrameReached(&pacman_delay, PACMAN_MOVE_DELAY))
   {
@@ -3015,7 +3248,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
 
   CT -= Ct;
 
-  if (element == EL_BOMB && CT > 1500)
+  if (element == EL_BOMB && CT > 75)
   {
     if (game_mm.cheat_no_explosion)
       return;
@@ -3053,7 +3286,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
     return;
   }
 
-  if (element == EL_FUSE_ON && CT > 500)
+  if (element == EL_FUSE_ON && CT > 25)
   {
     laser.fuse_off = TRUE;
     laser.fuse_x = ELX;
@@ -3063,7 +3296,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
     DrawGraphic_MM(ELX, ELY, IMG_MM_FUSE);
   }
 
-  if (element == EL_BALL_GRAY && CT > 1500)
+  if (element == EL_BALL_GRAY && CT > 75)
   {
     static int new_elements[] =
     {
@@ -3182,7 +3415,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
     return;
   }
 
-  if (IS_WALL_ICE(element) && CT > 1000)
+  if (IS_WALL_ICE(element) && CT > 50)
   {
     PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_SHRINKING);
 
@@ -3234,7 +3467,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
     return;
   }
 
-  if (IS_WALL_AMOEBA(element) && CT > 1200)
+  if (IS_WALL_AMOEBA(element) && CT > 60)
   {
     int k1, k2, k3, dx, dy, de, dm;
     int element2 = Feld[ELX][ELY];
@@ -3352,7 +3585,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
   }
 
   if ((element == EL_BLOCK_WOOD || element == EL_BLOCK_STONE) &&
-      laser.stops_inside_element && CT > 1500)
+      laser.stops_inside_element && CT > 75)
   {
     int x, y;
     int k;
@@ -3409,7 +3642,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
     return;
   }
 
-  if (element == EL_FUEL_FULL && CT > 200)
+  if (element == EL_FUEL_FULL && CT > 10)
   {
     for (i = game_mm.energy_left; i <= MAX_LASER_ENERGY; i+=2)
     {
@@ -3511,7 +3744,7 @@ void MovePacMen()
 
       getGraphicSource(graphic, 0, &bitmap, &src_x, &src_y);
 
-      CT = Counter();
+      CT = FrameCounter;
       ox = SX + ox * TILEX;
       oy = SY + oy * TILEY;
 
@@ -3519,7 +3752,7 @@ void MovePacMen()
        BlitBitmap(bitmap, window,
                   src_x, src_y, TILEX, TILEY,
                   ox + i * mx, oy + i * my);
-      Ct = Ct + Counter() - CT;
+      Ct = Ct + FrameCounter - CT;
     }
 
     DrawField_MM(nx, ny);