From d30adaf83e17eef0c2b186c6fd622baa506df4f0 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 29 Jan 2023 14:55:18 +0100 Subject: [PATCH] added support for text envelope elements to the MM engine --- src/conf_gfx.c | 17 ++++++++++++++ src/editor.c | 13 ++++++++--- src/engines.h | 1 + src/game_mm/export.h | 2 +- src/game_mm/mm_game.c | 54 +++++++++++++++++++++++++++++++++++++++++-- src/game_mm/mm_init.c | 12 ++++++++++ src/game_mm/mm_main.h | 21 ++++++++++++++++- src/main.c | 24 +++++++++---------- src/main.h | 17 ++++++++++---- src/tools.c | 10 ++++++++ 10 files changed, 147 insertions(+), 24 deletions(-) diff --git a/src/conf_gfx.c b/src/conf_gfx.c index b4789635..3616c73b 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -5223,6 +5223,23 @@ struct ConfigInfo image_config[] = { "mm_pacman.eating.down.ypos", "4" }, { "mm_pacman.eating.down.frames", "1" }, + { "mm_envelope_1", UNDEFINED_FILENAME }, + { "mm_envelope_1.clone_from", "envelope_1" }, + { "mm_envelope_1.collecting", UNDEFINED_FILENAME }, + { "mm_envelope_1.collecting.clone_from", "envelope_1.collecting" }, + { "mm_envelope_2", UNDEFINED_FILENAME }, + { "mm_envelope_2.clone_from", "envelope_2" }, + { "mm_envelope_2.collecting", UNDEFINED_FILENAME }, + { "mm_envelope_2.collecting.clone_from", "envelope_2.collecting" }, + { "mm_envelope_3", UNDEFINED_FILENAME }, + { "mm_envelope_3.clone_from", "envelope_3" }, + { "mm_envelope_3.collecting", UNDEFINED_FILENAME }, + { "mm_envelope_3.collecting.clone_from", "envelope_3.collecting" }, + { "mm_envelope_4", UNDEFINED_FILENAME }, + { "mm_envelope_4.clone_from", "envelope_4" }, + { "mm_envelope_4.collecting", UNDEFINED_FILENAME }, + { "mm_envelope_4.collecting.clone_from", "envelope_4.collecting" }, + { "[mm_default].exploding", "RocksMM.png" }, { "[mm_default].exploding.xpos", "0" }, { "[mm_default].exploding.ypos", "8" }, diff --git a/src/editor.c b/src/editor.c index 6df9c2ed..ab9b1c00 100644 --- a/src/editor.c +++ b/src/editor.c @@ -4644,7 +4644,12 @@ static int editor_el_mirror_magic[] = EL_MM_WOODEN_GRID_FIXED_1, EL_MM_WOODEN_GRID_FIXED_2, EL_MM_WOODEN_GRID_FIXED_3, - EL_MM_WOODEN_GRID_FIXED_4 + EL_MM_WOODEN_GRID_FIXED_4, + + EL_MM_ENVELOPE_1, + EL_MM_ENVELOPE_2, + EL_MM_ENVELOPE_3, + EL_MM_ENVELOPE_4 }; static int *editor_hl_mirror_magic_ptr = editor_hl_mirror_magic; static int *editor_el_mirror_magic_ptr = editor_el_mirror_magic; @@ -9962,6 +9967,7 @@ static boolean checkPropertiesConfig(int element) IS_EMPTY_ELEMENT(element) || IS_BALLOON_ELEMENT(element) || IS_ENVELOPE(element) || + IS_MM_ENVELOPE(element) || IS_MM_MCDUFFIN(element) || IS_DF_LASER(element) || IS_PLAYER_ELEMENT(element) || @@ -10266,13 +10272,14 @@ static void DrawPropertiesConfig(void) if (IS_BALLOON_ELEMENT(properties_element)) MapSelectboxGadget(ED_SELECTBOX_ID_WIND_DIRECTION); - if (IS_ENVELOPE(properties_element)) + if (IS_ENVELOPE(properties_element) || + IS_MM_ENVELOPE(properties_element)) { int counter1_id = ED_COUNTER_ID_ENVELOPE_XSIZE; int counter2_id = ED_COUNTER_ID_ENVELOPE_YSIZE; int button1_id = ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP; int button2_id = ED_CHECKBUTTON_ID_ENVELOPE_CENTERED; - int envelope_nr = properties_element - EL_ENVELOPE_1; + int envelope_nr = ENVELOPE_NR(properties_element); counterbutton_info[counter1_id].value = &level.envelope[envelope_nr].xsize; counterbutton_info[counter2_id].value = &level.envelope[envelope_nr].ysize; diff --git a/src/engines.h b/src/engines.h index 254f82d4..142c064f 100644 --- a/src/engines.h +++ b/src/engines.h @@ -64,6 +64,7 @@ int el2img_mm(int); int el_act2img_mm(int, int); void CheckSingleStepMode_MM(boolean, boolean); +void ShowEnvelope_MM(int); int getGraphicAnimationFrame(int, int); int getGraphicAnimationFrameXY(int, int, int); diff --git a/src/game_mm/export.h b/src/game_mm/export.h index b628a8d0..8b92ab0a 100644 --- a/src/game_mm/export.h +++ b/src/game_mm/export.h @@ -34,7 +34,7 @@ #define EL_MM_START_1_NATIVE 0 -#define EL_MM_END_1_NATIVE 155 +#define EL_MM_END_1_NATIVE 159 #define EL_MM_CHAR_START_NATIVE 160 #define EL_MM_CHAR_END_NATIVE 239 diff --git a/src/game_mm/mm_game.c b/src/game_mm/mm_game.c index 641aa4fd..27aada30 100644 --- a/src/game_mm/mm_game.c +++ b/src/game_mm/mm_game.c @@ -1663,9 +1663,11 @@ boolean HitElement(int element, int hit_mask) element == EL_KEY || element == EL_LIGHTBALL || element == EL_PACMAN || - IS_PACMAN(element)) + IS_PACMAN(element) || + IS_ENVELOPE(element)) { - if (!IS_PACMAN(element)) + if (!IS_PACMAN(element) && + !IS_ENVELOPE(element)) Bang_MM(ELX, ELY); if (element == EL_PACMAN) @@ -1693,6 +1695,10 @@ boolean HitElement(int element, int hit_mask) { DeletePacMan(ELX, ELY); } + else if (IS_ENVELOPE(element)) + { + Tile[ELX][ELY] = EL_ENVELOPE_1_OPENING + ENVELOPE_NR(Tile[ELX][ELY]); + } RaiseScoreElement_MM(element); @@ -2482,6 +2488,42 @@ static void OpenSurpriseBall(int x, int y) } } +static void OpenEnvelope(int x, int y) +{ + int num_frames = 8; // seven frames plus final empty space + + if (!MovDelay[x][y]) // next animation frame + MovDelay[x][y] = num_frames; + + if (MovDelay[x][y]) // wait some time before next frame + { + int nr = ENVELOPE_OPENING_NR(Tile[x][y]); + + MovDelay[x][y]--; + + if (MovDelay[x][y] > 0 && IN_SCR_FIELD(x, y)) + { + int graphic = el_act2gfx(EL_ENVELOPE_1 + nr, MM_ACTION_COLLECTING); + int frame = num_frames - MovDelay[x][y] - 1; + + DrawGraphicAnimation_MM(x, y, graphic, frame); + + laser.redraw = TRUE; + } + + if (MovDelay[x][y] == 0) + { + Tile[x][y] = EL_EMPTY; + + DrawField_MM(x, y); + + ScanLaser(); + + ShowEnvelope_MM(nr); + } + } +} + static void MeltIce(int x, int y) { int frames = 5; @@ -2983,6 +3025,12 @@ boolean ClickElement(int x, int y, int button) element_clicked = TRUE; } + else if (IS_ENVELOPE(element)) + { + Tile[x][y] = EL_ENVELOPE_1_OPENING + ENVELOPE_NR(element); + + element_clicked = TRUE; + } click_delay.value = (new_button ? CLICK_DELAY_FIRST : CLICK_DELAY); new_button = FALSE; @@ -3239,6 +3287,8 @@ static void GameActions_MM_Ext(void) OpenExit(x, y); else if (element == EL_GRAY_BALL_OPENING) OpenSurpriseBall(x, y); + else if (IS_ENVELOPE_OPENING(element)) + OpenEnvelope(x, y); else if (IS_WALL_CHANGING(element) && Store[x][y] == EL_WALL_ICE) MeltIce(x, y); else if (IS_WALL_CHANGING(element) && Store[x][y] == EL_WALL_AMOEBA) diff --git a/src/game_mm/mm_init.c b/src/game_mm/mm_init.c index 6ed89c95..a82b61df 100644 --- a/src/game_mm/mm_init.c +++ b/src/game_mm/mm_init.c @@ -171,6 +171,15 @@ void InitElementProperties_MM(void) }; static int ep_pacman_num = sizeof(ep_pacman) / sizeof(int); + static int ep_envelope[] = + { + EL_ENVELOPE_1, + EL_ENVELOPE_2, + EL_ENVELOPE_3, + EL_ENVELOPE_4, + }; + static int ep_envelope_num = sizeof(ep_envelope) / sizeof(int); + static long ep_bit[] = { EP_BIT_GRID, @@ -186,6 +195,7 @@ void InitElementProperties_MM(void) EP_BIT_INACTIVE, EP_BIT_WALL, EP_BIT_PACMAN, + EP_BIT_ENVELOPE, }; static int *ep_array[] = { @@ -202,6 +212,7 @@ void InitElementProperties_MM(void) ep_inactive, ep_wall, ep_pacman, + ep_envelope, }; static int *ep_num[] = { @@ -218,6 +229,7 @@ void InitElementProperties_MM(void) &ep_inactive_num, &ep_wall_num, &ep_pacman_num, + &ep_envelope_num, }; static int num_properties = sizeof(ep_num) / sizeof(int *); diff --git a/src/game_mm/mm_main.h b/src/game_mm/mm_main.h index 0fb74d9e..dafaa5d6 100644 --- a/src/game_mm/mm_main.h +++ b/src/game_mm/mm_main.h @@ -48,6 +48,7 @@ #define EP_BIT_INACTIVE (1 << 11) #define EP_BIT_WALL (1 << 12) #define EP_BIT_PACMAN (1 << 13) +#define EP_BIT_ENVELOPE (1 << 14) #define IS_GRID(e) (Elementeigenschaften[e] & EP_BIT_GRID) #define IS_MCDUFFIN(e) (Elementeigenschaften[e] & EP_BIT_MCDUFFIN) @@ -63,6 +64,7 @@ #define IS_INACTIVE(e) (Elementeigenschaften[e] & EP_BIT_INACTIVE) #define IS_MM_WALL(e) (Elementeigenschaften[e] & EP_BIT_WALL) #define IS_PACMAN(e) (Elementeigenschaften[e] & EP_BIT_PACMAN) +#define IS_ENVELOPE(e) (Elementeigenschaften[e] & EP_BIT_ENVELOPE) #define IS_WALL_STEEL(e) ((e) >= EL_WALL_STEEL_START && \ (e) <= EL_WALL_STEEL_END) @@ -122,6 +124,12 @@ (e) == EL_BOMB || \ IS_WALL_AMOEBA(e)) +#define IS_ENVELOPE_OPENING(e) ((e) >= EL_ENVELOPE_OPENING_START && \ + (e) <= EL_ENVELOPE_OPENING_END) + +#define ENVELOPE_NR(e) ((e) - EL_ENVELOPE_1) +#define ENVELOPE_OPENING_NR(e) ((e) - EL_ENVELOPE_1_OPENING) + #define CAN_MOVE(e) ((e) == EL_PACMAN) #define IS_FREE(x,y) (Tile[x][y] == EL_EMPTY) @@ -451,8 +459,12 @@ extern int num_element_info; #define EL_GRID_WOOD_03 (EL_GRID_WOOD_START + 3) #define EL_GRID_WOOD_END EL_GRID_WOOD_03 #define EL_FUEL_EMPTY 155 +#define EL_ENVELOPE_1 156 +#define EL_ENVELOPE_2 157 +#define EL_ENVELOPE_3 158 +#define EL_ENVELOPE_4 159 -#define EL_MM_END_1 155 +#define EL_MM_END_1 159 #define EL_CHAR_START 160 #define EL_CHAR_ASCII0 (EL_CHAR_START - 32) @@ -655,6 +667,13 @@ extern int num_element_info; #define EL_AMOEBA_WALL_GROWING 504 #define EL_BOMB_ACTIVE 505 #define EL_MINE_ACTIVE 506 +#define EL_ENVELOPE_1_OPENING 507 +#define EL_ENVELOPE_2_OPENING 508 +#define EL_ENVELOPE_3_OPENING 509 +#define EL_ENVELOPE_4_OPENING 510 + +#define EL_ENVELOPE_OPENING_START EL_ENVELOPE_1_OPENING +#define EL_ENVELOPE_OPENING_END EL_ENVELOPE_4_OPENING #define EL_WALL_CHANGING 512 #define EL_WALL_CHANGING_START (EL_WALL_CHANGING + 0) diff --git a/src/main.c b/src/main.c index 13cab898..cf51e039 100644 --- a/src/main.c +++ b/src/main.c @@ -5297,24 +5297,24 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] = "extra energy ball (empty)" }, { - "mm_unused_156", - "unused", - "(not used)" + "mm_envelope_1", + "mm_envelope", + "mail envelope 1 (MM style)" }, { - "mm_unused_157", - "unused", - "(not used)" + "mm_envelope_2", + "mm_envelope", + "mail envelope 2 (MM style)" }, { - "mm_unused_158", - "unused", - "(not used)" + "mm_envelope_3", + "mm_envelope", + "mail envelope 3 (MM style)" }, { - "mm_unused_159", - "unused", - "(not used)" + "mm_envelope_4", + "mm_envelope", + "mail envelope 4 (MM style)" }, { "df_mirror_1", diff --git a/src/main.h b/src/main.h index a943547a..e111f027 100644 --- a/src/main.h +++ b/src/main.h @@ -727,6 +727,9 @@ #define IS_ENVELOPE(e) ((e) >= EL_ENVELOPE_1 && \ (e) <= EL_ENVELOPE_4) +#define IS_MM_ENVELOPE(e) ((e) >= EL_MM_ENVELOPE_1 && \ + (e) <= EL_MM_ENVELOPE_4) + #define IS_BALLOON_ELEMENT(e) ((e) == EL_BALLOON || \ (e) == EL_BALLOON_SWITCH_LEFT || \ (e) == EL_BALLOON_SWITCH_RIGHT || \ @@ -802,6 +805,11 @@ IS_EM_GATE_GRAY(e) ? EM_GATE_GRAY_NR(e) : \ IS_EMC_GATE_GRAY(e) ? EMC_GATE_GRAY_NR(e) : 0) +#define RND_ENVELOPE_NR(e) ((e) - EL_ENVELOPE_1) +#define MM_ENVELOPE_NR(e) ((e) - EL_MM_ENVELOPE_1) +#define ENVELOPE_NR(e) (IS_ENVELOPE(e) ? RND_ENVELOPE_NR(e) : \ + MM_ENVELOPE_NR(e)) + #define IS_ACID_POOL_OR_ACID(e) (IS_ACID_POOL(e) || (e) == EL_ACID) #define IS_EMC_PILLAR(e) ((e) >= EL_EMC_WALL_1 && \ @@ -1702,11 +1710,10 @@ #define EL_MM_WOODEN_GRID_FIXED_4 (EL_MM_WOODEN_GRID_FIXED_START + 3) #define EL_MM_WOODEN_GRID_FIXED_END EL_MM_WOODEN_GRID_FIXED_03 #define EL_MM_FUEL_EMPTY (EL_MM_START + 155) - -#define EL_MM_UNUSED_156 (EL_MM_START + 156) -#define EL_MM_UNUSED_157 (EL_MM_START + 157) -#define EL_MM_UNUSED_158 (EL_MM_START + 158) -#define EL_MM_UNUSED_159 (EL_MM_START + 159) +#define EL_MM_ENVELOPE_1 (EL_MM_START + 156) +#define EL_MM_ENVELOPE_2 (EL_MM_START + 157) +#define EL_MM_ENVELOPE_3 (EL_MM_START + 158) +#define EL_MM_ENVELOPE_4 (EL_MM_START + 159) #define EL_MM_END_1 (EL_MM_START + 159) #define EL_MM_START_2 (EL_MM_START + 160) diff --git a/src/tools.c b/src/tools.c index 5e5a2e1d..d9e3652c 100644 --- a/src/tools.c +++ b/src/tools.c @@ -2989,6 +2989,16 @@ void ShowEnvelope(int envelope_nr) BackToFront(); } +void ShowEnvelope_MM(int envelope_nr) +{ + BlitBitmap(backbuffer, bitmap_db_field, REAL_SX, REAL_SY, + FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY); + + ShowEnvelope(envelope_nr); + + SetDrawtoField(DRAW_TO_BACKBUFFER); +} + static void PrepareEnvelopeRequestToScreen(Bitmap *bitmap, int sx, int sy, int xsize, int ysize) { -- 2.34.1