From 1a5c85211f0a5b74366d264260d464266afb208d Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Tue, 7 Feb 2017 23:56:41 +0100 Subject: [PATCH] added basic support for Mirror Magic game engine (first part) --- src/Makefile | 16 ++++++++-- src/engines.h | 11 +++++++ src/files.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.h | 6 +++- src/tools.c | 46 +++++++++++++++++++++++++++ src/tools.h | 3 ++ 6 files changed, 164 insertions(+), 4 deletions(-) diff --git a/src/Makefile b/src/Makefile index bacc168d..f33c2e86 100644 --- a/src/Makefile +++ b/src/Makefile @@ -195,7 +195,10 @@ GAME_EM = $(GAME_EM_DIR)/game_em.a GAME_SP_DIR = game_sp GAME_SP = $(GAME_SP_DIR)/game_sp.a -RNDLIBS = $(LIBGAME) $(GAME_EM) $(GAME_SP) +GAME_MM_DIR = game_mm +GAME_MM = $(GAME_MM_DIR)/game_mm.a + +RNDLIBS = $(LIBGAME) $(GAME_EM) $(GAME_SP) $(GAME_MM) AUTOCONF = conf_gfx.h conf_snd.h conf_mus.h ICONBASE = windows_icon @@ -213,7 +216,7 @@ GRAPHICS_DIR = ../graphics # build targets # ----------------------------------------------------------------------------- -all: $(AUTOCONF) libgame_dir game_em_dir game_sp_dir $(PROGNAME) graphics_dir +all: $(AUTOCONF) libgame_dir game_em_dir game_sp_dir game_mm_dir $(PROGNAME) graphics_dir $(PROGNAME): $(RNDLIBS) $(TIMESTAMP_FILE) $(OBJS) $(ICON) $(CC) $(PROFILING) $(OBJS) $(ICON) $(RNDLIBS) $(LDFLAGS) -o $(PROGNAME) @@ -236,6 +239,11 @@ game_sp_dir: $(GAME_SP): @$(MAKE) -C $(GAME_SP_DIR) +game_mm_dir: + @$(MAKE) -C $(GAME_MM_DIR) +$(GAME_MM): + @$(MAKE) -C $(GAME_MM_DIR) + auto-conf: @for i in $(CNFS); do \ echo "$(CNFS_CMD) $$i > $$i"; \ @@ -276,6 +284,7 @@ clean-obj: $(MAKE) -C $(LIBGAME_DIR) clean $(MAKE) -C $(GAME_EM_DIR) clean $(MAKE) -C $(GAME_SP_DIR) clean + $(MAKE) -C $(GAME_MM_DIR) clean $(RM) $(OBJS) $(RM) $(RNDLIBS) @@ -314,12 +323,13 @@ valgrind: # ----------------------------------------------------------------------------- tags: - $(ETAGS) *.[ch] $(LIBGAME_DIR)/*.[ch] $(GAME_EM_DIR)/*.[ch] $(GAME_SP_DIR)/*.[ch] + $(ETAGS) *.[ch] $(LIBGAME_DIR)/*.[ch] $(GAME_EM_DIR)/*.[ch] $(GAME_SP_DIR)/*.[ch] $(GAME_MM_DIR)/*.[ch] depend: $(MAKE) -C $(LIBGAME_DIR) depend $(MAKE) -C $(GAME_EM_DIR) depend $(MAKE) -C $(GAME_SP_DIR) depend + $(MAKE) -C $(GAME_MM_DIR) depend for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend ifeq (.depend,$(wildcard .depend)) diff --git a/src/engines.h b/src/engines.h index ab6c38fd..f7b00018 100644 --- a/src/engines.h +++ b/src/engines.h @@ -16,6 +16,7 @@ #include "game_em/export.h" #include "game_sp/export.h" +#include "game_mm/export.h" #include "game.h" @@ -51,4 +52,14 @@ int getGraphicInfo_Delay(int); boolean isNextAnimationFrame_SP(int, int); +/* ========================================================================= */ +/* functions and definitions exported from main program to game_mm */ +/* ========================================================================= */ + +void SetDrawtoField(int); + +void getGraphicSource(int, int, Bitmap **, int *, int *); +void getSizedGraphicSource(int, int, int, Bitmap **, int *, int *); + + #endif /* ENGINES_H */ diff --git a/src/files.c b/src/files.c index 85d17128..e387efc7 100644 --- a/src/files.c +++ b/src/files.c @@ -1604,6 +1604,7 @@ static void setLevelInfoToDefaults_Level(struct LevelInfo *level) level->native_em_level = &native_em_level; level->native_sp_level = &native_sp_level; + level->native_mm_level = &native_mm_level; level->file_version = FILE_VERSION_ACTUAL; level->game_version = GAME_VERSION_ACTUAL; @@ -3869,6 +3870,74 @@ static void CopyNativeTape_SP_to_RND(struct LevelInfo *level) } +/* ------------------------------------------------------------------------- */ +/* functions for loading MM level */ +/* ------------------------------------------------------------------------- */ + +void CopyNativeLevel_RND_to_MM(struct LevelInfo *level) +{ + struct LevelInfo_MM *level_mm = level->native_mm_level; + int x, y; + + level_mm->file_version = level->file_version; + level_mm->game_version = level->game_version; + level_mm->encoding_16bit_field = level->encoding_16bit_field; + + level_mm->fieldx = MIN(level->fieldx, MM_MAX_PLAYFIELD_WIDTH); + level_mm->fieldy = MIN(level->fieldx, MM_MAX_PLAYFIELD_HEIGHT); + + level_mm->time = level->time; + level_mm->kettles_needed = level->gems_needed; + level_mm->auto_count_kettles = FALSE; + level_mm->laser_red = FALSE; + level_mm->laser_green = FALSE; + level_mm->laser_blue = TRUE; + + strcpy(level_mm->name, level->name); + strcpy(level_mm->author, level->author); + + level_mm->score[SC_PACMAN] = level->score[SC_PACMAN]; + level_mm->score[SC_KEY] = level->score[SC_PACMAN]; + level_mm->score[SC_TIME_BONUS] = level->score[SC_TIME_BONUS]; + + level_mm->amoeba_speed = level->amoeba_speed; + level_mm->time_fuse = 0; + + for (y = 0; y < level_mm->fieldx; y++) + for (x = 0; x < level_mm->fieldy; x++) + level_mm->field[x][y] = map_element_RND_to_MM(level->field[x][y]); +} + +void CopyNativeLevel_MM_to_RND(struct LevelInfo *level) +{ + struct LevelInfo_MM *level_mm = level->native_mm_level; + int x, y; + + level->file_version = level_mm->file_version; + level->game_version = level_mm->game_version; + level->encoding_16bit_field = level_mm->encoding_16bit_field; + + level->fieldx = MIN(level_mm->fieldx, MAX_LEV_FIELDX); + level->fieldy = MIN(level_mm->fieldx, MAX_LEV_FIELDY); + + level->time = level_mm->time; + level->gems_needed = level_mm->kettles_needed; + + strcpy(level->name, level_mm->name); + strcpy(level->author, level_mm->author); + + level->score[SC_PACMAN] = level_mm->score[SC_PACMAN]; + level->score[SC_KEY] = level_mm->score[SC_PACMAN]; + level->score[SC_TIME_BONUS] = level_mm->score[SC_TIME_BONUS]; + + level->amoeba_speed = level_mm->amoeba_speed; + + for (y = 0; y < level->fieldx; y++) + for (x = 0; x < level->fieldy; x++) + level->field[x][y] = map_element_MM_to_RND(level_mm->field[x][y]); +} + + /* ------------------------------------------------------------------------- */ /* functions for loading DC level */ /* ------------------------------------------------------------------------- */ @@ -5898,12 +5967,22 @@ static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, level->no_valid_file = TRUE; } +static void LoadLevelFromFileInfo_MM(struct LevelInfo *level, + struct LevelFileInfo *level_file_info, + boolean level_info_only) +{ + if (!LoadNativeLevel_MM(level_file_info->filename, level_info_only)) + level->no_valid_file = TRUE; +} + void CopyNativeLevel_RND_to_Native(struct LevelInfo *level) { if (level->game_engine_type == GAME_ENGINE_TYPE_EM) CopyNativeLevel_RND_to_EM(level); else if (level->game_engine_type == GAME_ENGINE_TYPE_SP) CopyNativeLevel_RND_to_SP(level); + else if (level->game_engine_type == GAME_ENGINE_TYPE_MM) + CopyNativeLevel_RND_to_MM(level); } void CopyNativeLevel_Native_to_RND(struct LevelInfo *level) @@ -5912,6 +5991,8 @@ void CopyNativeLevel_Native_to_RND(struct LevelInfo *level) CopyNativeLevel_EM_to_RND(level); else if (level->game_engine_type == GAME_ENGINE_TYPE_SP) CopyNativeLevel_SP_to_RND(level); + else if (level->game_engine_type == GAME_ENGINE_TYPE_MM) + CopyNativeLevel_MM_to_RND(level); } void SaveNativeLevel(struct LevelInfo *level) @@ -5956,6 +6037,11 @@ static void LoadLevelFromFileInfo(struct LevelInfo *level, level->game_engine_type = GAME_ENGINE_TYPE_SP; break; + case LEVEL_FILE_TYPE_MM: + LoadLevelFromFileInfo_MM(level, level_file_info, level_info_only); + level->game_engine_type = GAME_ENGINE_TYPE_MM; + break; + case LEVEL_FILE_TYPE_DC: LoadLevelFromFileInfo_DC(level, level_file_info, level_info_only); break; diff --git a/src/main.h b/src/main.h index 13fa9ee3..6cb89a4b 100644 --- a/src/main.h +++ b/src/main.h @@ -23,6 +23,7 @@ #include "libgame/libgame.h" #include "game_em/game_em.h" #include "game_sp/game_sp.h" +#include "game_mm/game_mm.h" #include "conf_gfx.h" /* include auto-generated data structure definitions */ #include "conf_snd.h" /* include auto-generated data structure definitions */ @@ -2140,14 +2141,16 @@ #define LEVEL_FILE_TYPE_DX 5 #define LEVEL_FILE_TYPE_SB 6 #define LEVEL_FILE_TYPE_DC 7 +#define LEVEL_FILE_TYPE_MM 8 -#define NUM_LEVEL_FILE_TYPES 8 +#define NUM_LEVEL_FILE_TYPES 9 /* values for game engine type identifier */ #define GAME_ENGINE_TYPE_UNKNOWN LEVEL_FILE_TYPE_UNKNOWN #define GAME_ENGINE_TYPE_RND LEVEL_FILE_TYPE_RND #define GAME_ENGINE_TYPE_EM LEVEL_FILE_TYPE_EM #define GAME_ENGINE_TYPE_SP LEVEL_FILE_TYPE_SP +#define GAME_ENGINE_TYPE_MM LEVEL_FILE_TYPE_MM #define NUM_ENGINE_TYPES 4 @@ -2518,6 +2521,7 @@ struct LevelInfo /* level stored in native format for the alternative native game engines */ struct LevelInfo_EM *native_em_level; struct LevelInfo_SP *native_sp_level; + struct LevelInfo_MM *native_mm_level; int file_version; /* file format version the level is stored with */ int game_version; /* game release version the level was created with */ diff --git a/src/tools.c b/src/tools.c index 21f062b4..fcc82f30 100644 --- a/src/tools.c +++ b/src/tools.c @@ -358,12 +358,40 @@ static int getLevelFromScreenY_SP(int sy) return ly; } +static int getLevelFromScreenX_MM(int sx) +{ + int level_xsize = level.native_mm_level->fieldx; + int full_xsize = level_xsize * TILESIZE_VAR; + + sx -= (full_xsize < SXSIZE ? (SXSIZE - full_xsize) / 2 : 0); + + int px = sx - SX; + int lx = px / TILESIZE_VAR; + + return lx; +} + +static int getLevelFromScreenY_MM(int sy) +{ + int level_ysize = level.native_mm_level->fieldy; + int full_ysize = level_ysize * TILESIZE_VAR; + + sy -= (full_ysize < SYSIZE ? (SYSIZE - full_ysize) / 2 : 0); + + int py = sy - SY; + int ly = py / TILESIZE_VAR; + + return ly; +} + int getLevelFromScreenX(int x) { if (level.game_engine_type == GAME_ENGINE_TYPE_EM) return getLevelFromScreenX_EM(x); if (level.game_engine_type == GAME_ENGINE_TYPE_SP) return getLevelFromScreenX_SP(x); + if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + return getLevelFromScreenX_MM(x); else return getLevelFromScreenX_RND(x); } @@ -374,6 +402,8 @@ int getLevelFromScreenY(int y) return getLevelFromScreenY_EM(y); if (level.game_engine_type == GAME_ENGINE_TYPE_SP) return getLevelFromScreenY_SP(y); + if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + return getLevelFromScreenY_MM(y); else return getLevelFromScreenY_RND(y); } @@ -465,6 +495,8 @@ void RedrawPlayfield() RedrawPlayfield_EM(TRUE); else if (level.game_engine_type == GAME_ENGINE_TYPE_SP) RedrawPlayfield_SP(TRUE); + else if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + RedrawPlayfield_MM(); else if (level.game_engine_type == GAME_ENGINE_TYPE_RND) RedrawPlayfield_RND(); @@ -611,6 +643,8 @@ void BlitScreenToBitmap(Bitmap *target_bitmap) BlitScreenToBitmap_EM(target_bitmap); else if (level.game_engine_type == GAME_ENGINE_TYPE_SP) BlitScreenToBitmap_SP(target_bitmap); + else if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + BlitScreenToBitmap_MM(target_bitmap); else if (level.game_engine_type == GAME_ENGINE_TYPE_RND) BlitScreenToBitmap_RND(target_bitmap); @@ -7194,6 +7228,16 @@ int map_action_SP_to_RND(int action_sp) } } +int map_element_RND_to_MM(int element_rnd) +{ + return (element_rnd > 1000 ? element_rnd - 1000 : 0); +} + +int map_element_MM_to_RND(int element_mm) +{ + return 1000 + element_mm; +} + int get_next_element(int element) { switch (element) @@ -7438,6 +7482,8 @@ unsigned int InitRND(int seed) return InitEngineRandom_EM(seed); else if (level.game_engine_type == GAME_ENGINE_TYPE_SP) return InitEngineRandom_SP(seed); + else if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + return InitEngineRandom_MM(seed); else return InitEngineRandom_RND(seed); } diff --git a/src/tools.h b/src/tools.h index 38b1c5c1..cdee2635 100644 --- a/src/tools.h +++ b/src/tools.h @@ -219,6 +219,9 @@ int map_element_RND_to_SP(int); int map_element_SP_to_RND(int); int map_action_SP_to_RND(int); +int map_element_RND_to_MM(int); +int map_element_MM_to_RND(int); + int get_next_element(int); int el_act_dir2img(int, int, int); int el_act2img(int, int); -- 2.34.1