improved MM graphics engine to support custom explosions of elements
authorHolger Schemel <info@artsoft.org>
Thu, 5 Jan 2023 01:50:25 +0000 (02:50 +0100)
committerHolger Schemel <info@artsoft.org>
Thu, 5 Jan 2023 01:51:54 +0000 (02:51 +0100)
graphics/gfx_classic/RocksMM.png
src/conf_gfx.c
src/engines.h
src/game_mm/mm_game.c
src/game_mm/mm_main.h
src/game_mm/mm_tools.c
src/game_mm/mm_tools.h
src/tools.c

index b5066c690a137cc11e7c0384538c2f03a90d9920..c993e64ca6c4aab80384e313443023f967747e98 100644 (file)
Binary files a/graphics/gfx_classic/RocksMM.png and b/graphics/gfx_classic/RocksMM.png differ
index 5b601e626fae1c3dde606f68b027c60b51181d20..b810bce8c3e7ffdbbd01160f8706ce8ff70b16da 100644 (file)
@@ -5037,14 +5037,14 @@ struct ConfigInfo image_config[] =
   { "mm_teleporter_blue_16.frames",            "1"                     },
 
   { "mm_kettle",                               "RocksMM.png"           },
-  { "mm_kettle.xpos",                          "12"                    },
-  { "mm_kettle.ypos",                          "1"                     },
+  { "mm_kettle.xpos",                          "9"                     },
+  { "mm_kettle.ypos",                          "8"                     },
   { "mm_kettle.frames",                                "1"                     },
   { "mm_kettle.exploding",                     "RocksMM.png"           },
-  { "mm_kettle.exploding.xpos",                        "13"                    },
-  { "mm_kettle.exploding.ypos",                        "1"                     },
-  { "mm_kettle.exploding.frames",              "3"                     },
-  { "mm_kettle.exploding.delay",               "4"                     },
+  { "mm_kettle.exploding.xpos",                        "10"                    },
+  { "mm_kettle.exploding.ypos",                        "8"                     },
+  { "mm_kettle.exploding.frames",              "6"                     },
+  { "mm_kettle.exploding.delay",               "2"                     },
   { "mm_kettle.exploding.anim_mode",           "linear"                },
 
   { "mm_bomb",                                 "RocksMM.png"           },
@@ -5070,11 +5070,23 @@ struct ConfigInfo image_config[] =
   { "mm_steel_lock.xpos",                      "8"                     },
   { "mm_steel_lock.ypos",                      "2"                     },
   { "mm_steel_lock.frames",                    "1"                     },
+  { "mm_steel_lock.exploding",                 "RocksMM.png"           },
+  { "mm_steel_lock.exploding.xpos",            "4"                     },
+  { "mm_steel_lock.exploding.ypos",            "8"                     },
+  { "mm_steel_lock.exploding.frames",          "5"                     },
+  { "mm_steel_lock.exploding.delay",           "2"                     },
+  { "mm_steel_lock.exploding.anim_mode",       "linear"                },
 
   { "mm_wooden_lock",                          "RocksMM.png"           },
   { "mm_wooden_lock.xpos",                     "9"                     },
   { "mm_wooden_lock.ypos",                     "6"                     },
   { "mm_wooden_lock.frames",                   "1"                     },
+  { "mm_wooden_lock.exploding",                        "RocksMM.png"           },
+  { "mm_wooden_lock.exploding.xpos",           "4"                     },
+  { "mm_wooden_lock.exploding.ypos",           "8"                     },
+  { "mm_wooden_lock.exploding.frames",         "5"                     },
+  { "mm_wooden_lock.exploding.delay",          "2"                     },
+  { "mm_wooden_lock.exploding.anim_mode",      "linear"                },
 
   { "mm_steel_block",                          "RocksMM.png"           },
   { "mm_steel_block.xpos",                     "8"                     },
@@ -5202,8 +5214,8 @@ struct ConfigInfo image_config[] =
   { "mm_pacman.eating.down.frames",            "1"                     },
 
   { "[mm_default].exploding",                  "RocksMM.png"           },
-  { "[mm_default].exploding.xpos",             "8"                     },
-  { "[mm_default].exploding.ypos",             "4"                     },
+  { "[mm_default].exploding.xpos",             "0"                     },
+  { "[mm_default].exploding.ypos",             "8"                     },
   { "[mm_default].exploding.frames",           "8"                     },
   { "[mm_default].exploding.delay",            "2"                     },
   { "[mm_default].exploding.anim_mode",                "linear"                },
index c90cc0a182665a79bb2281e46dbb8d89a744d476..dadfa21dfed5c8bc604736a7ff78697e269692ee 100644 (file)
@@ -61,6 +61,7 @@ boolean isNextAnimationFrame_SP(int, int);
 void SetDrawtoField(int);
 
 int el2img_mm(int);
+int el_act2img_mm(int, int);
 
 void CheckSingleStepMode_MM(boolean, boolean);
 
index 164f1e394b0139f92dba98aebab6f3167aa3fb05..85a9d4092995b18fcbdd5550ab4b60d1911a7895 100644 (file)
@@ -25,9 +25,8 @@
 
 // values for Explode_MM()
 #define EX_PHASE_START         0
-#define EX_NORMAL              0
-#define EX_KETTLE              1
-#define EX_SHORT               2
+#define EX_TYPE_NONE           0
+#define EX_TYPE_NORMAL         (1 << 0)
 
 // special positions in the game control window (relative to control window)
 #define XX_LEVEL               36
@@ -2525,13 +2524,20 @@ static void Explode_MM(int x, int y, int phase, int mode)
       Store[x][y] = EL_EMPTY;
 
     Store2[x][y] = mode;
+
     Tile[x][y] = EL_EXPLODING_OPAQUE;
+    GfxElement[x][y] = center_element;
+
     MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
+
     ExplodePhase[x][y] = 1;
 
     return;
   }
 
+  if (phase == 1)
+    GfxFrame[x][y] = 0;                // restart explosion animation
+
   ExplodePhase[x][y] = (phase < last_phase ? phase + 1 : 0);
 
   if (phase == half_phase)
@@ -2572,44 +2578,10 @@ static void Explode_MM(int x, int y, int phase, int mode)
   }
   else if (!(phase % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
   {
-    int graphic = IMG_MM_DEFAULT_EXPLODING;
-    int graphic_phase = (phase / delay - 1);
-    Bitmap *bitmap;
-    int src_x, src_y;
+    int graphic = el_act2gfx(GfxElement[x][y], MM_ACTION_EXPLODING);
+    int frame = getGraphicAnimationFrameXY(graphic, x, y);
 
-    if (Store2[x][y] == EX_KETTLE)
-    {
-      if (graphic_phase < 3)
-      {
-       graphic = IMG_MM_KETTLE_EXPLODING;
-      }
-      else if (graphic_phase < 5)
-      {
-       graphic_phase += 3;
-      }
-      else
-      {
-       graphic = IMG_EMPTY;
-       graphic_phase = 0;
-      }
-    }
-    else if (Store2[x][y] == EX_SHORT)
-    {
-      if (graphic_phase < 4)
-      {
-       graphic_phase += 4;
-      }
-      else
-      {
-       graphic = IMG_EMPTY;
-       graphic_phase = 0;
-      }
-    }
-
-    getGraphicSource(graphic, graphic_phase, &bitmap, &src_x, &src_y);
-
-    BlitBitmap(bitmap, drawto_field, src_x, src_y, TILEX, TILEY,
-              cFX + x * TILEX, cFY + y * TILEY);
+    DrawGraphicAnimation_MM(x, y, graphic, frame);
 
     MarkTileDirty(x, y);
   }
@@ -2618,28 +2590,11 @@ static void Explode_MM(int x, int y, int phase, int mode)
 static void Bang_MM(int x, int y)
 {
   int element = Tile[x][y];
-  int mode = EX_NORMAL;
 
 #if 0
   DrawLaser(0, DL_LASER_ENABLED);
 #endif
 
-  switch (element)
-  {
-    case EL_KETTLE:
-      mode = EX_KETTLE;
-      break;
-
-    case EL_GATE_STONE:
-    case EL_GATE_WOOD:
-      mode = EX_SHORT;
-      break;
-
-    default:
-      mode = EX_NORMAL;
-      break;
-  }
-
   if (IS_PACMAN(element))
     PlayLevelSound_MM(x, y, element, MM_ACTION_EXPLODING);
   else if (element == EL_BOMB || IS_MCDUFFIN(element))
@@ -2649,7 +2604,7 @@ static void Bang_MM(int x, int y)
   else
     PlayLevelSound_MM(x, y, element, MM_ACTION_EXPLODING);
 
-  Explode_MM(x, y, EX_PHASE_START, mode);
+  Explode_MM(x, y, EX_PHASE_START, EX_TYPE_NORMAL);
 }
 
 void TurnRound(int x, int y)
@@ -3174,7 +3129,7 @@ static void GameActions_MM_Ext(void)
     else if (IS_MOVING(x, y))
       ContinueMoving_MM(x, y);
     else if (IS_EXPLODING(element))
-      Explode_MM(x, y, ExplodePhase[x][y], EX_NORMAL);
+      Explode_MM(x, y, ExplodePhase[x][y], EX_TYPE_NORMAL);
     else if (element == EL_EXIT_OPENING)
       OpenExit(x, y);
     else if (element == EL_GRAY_BALL_OPENING)
index 2c12cfcca502bfd61601d8f4d37a37f7f5a2afeb..5d0718f5f4ae188e37ed43d1db9313b776a9efdb 100644 (file)
@@ -207,6 +207,9 @@ extern short                AmoebaCnt[MAX_NUM_AMOEBA];
 extern short           AmoebaCnt2[MAX_NUM_AMOEBA];
 extern short           ExplodePhase[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 
+extern int             GfxFrame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern int             GfxElement[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+
 extern unsigned int    Elementeigenschaften[MAX_ELEMENTS];
 
 extern int             level_nr;
index d4bb5d37553ae80e1c72032f91e2cfc5146f281a..3a3aa2e8a723f99f2b2464dd64066b77705e8e01 100644 (file)
@@ -1292,6 +1292,11 @@ int el2gfx(int element)
   return el2img_mm(map_element(element));
 }
 
+int el_act2gfx(int element, int action)
+{
+  return el_act2img_mm(map_element(element), action);
+}
+
 void RedrawPlayfield_MM(void)
 {
   DrawLevel_MM();
index d6679de56b0932058a9c3645d95501227cd5331c..58b2beb05dafd0e6ea3c5f9da6b4555d15282ba3 100644 (file)
@@ -107,5 +107,6 @@ int get_num_elements(int);
 int get_rotated_element(int, int);
 
 int el2gfx(int);
+int el_act2gfx(int, int);
 
 #endif
index 7f448fdfc25df57f38c753c924afafc00d0e2c90..351c36e43e820d421b7502cc08592265cb351c73 100644 (file)
@@ -8323,6 +8323,11 @@ int el2img_mm(int element_mm)
   return el2img(map_element_MM_to_RND(element_mm));
 }
 
+int el_act2img_mm(int element_mm, int action)
+{
+  return el_act2img(map_element_MM_to_RND(element_mm), action);
+}
+
 int el_act_dir2img(int element, int action, int direction)
 {
   element = GFX_ELEMENT(element);