From 2423fa287d0892156976c064369a32eaa73bcb3a Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Wed, 9 Oct 2024 19:05:07 +0200 Subject: [PATCH] added support for level specific information text messages By placing a text file into "docs/levels/XXX.txt" inside the level set directory (or directly inside the level set directory just next to the level file itself), the text message can be shown by pressing the envelope icon that appears in the bottom left corner of the main menu (similar to the level set information by the icon on the bottom right, if available). The level information text can also be accessed from the info screen. --- src/conf_gfx.c | 24 +++++++++ src/conf_mus.c | 1 + src/conf_snd.c | 1 + src/init.c | 1 + src/libgame/setup.c | 38 +++++++++++++- src/libgame/setup.h | 1 + src/libgame/system.h | 2 + src/main.c | 1 + src/main.h | 3 ++ src/screens.c | 118 ++++++++++++++++++++++++++++++++++--------- 10 files changed, 165 insertions(+), 25 deletions(-) diff --git a/src/conf_gfx.c b/src/conf_gfx.c index 8eece06a..885f9151 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -7379,6 +7379,13 @@ struct ConfigInfo image_config[] = { "menu.button_levelset_info.active", UNDEFINED_FILENAME }, { "menu.button_levelset_info.active.clone_from", "envelope_1" }, + { "menu.button_level_info", UNDEFINED_FILENAME }, + { "menu.button_level_info.clone_from", "envelope_2" }, + { "menu.button_level_info.pressed", UNDEFINED_FILENAME }, + { "menu.button_level_info.pressed.clone_from", "envelope_2.collecting" }, + { "menu.button_level_info.active", UNDEFINED_FILENAME }, + { "menu.button_level_info.active.clone_from", "envelope_2" }, + { "menu.button_switch_ecs_aga", UNDEFINED_FILENAME }, { "menu.button_switch_ecs_aga.active", UNDEFINED_FILENAME }, @@ -8050,6 +8057,9 @@ struct ConfigInfo image_config[] = { "font.info.levelset", UNDEFINED_FILENAME }, { "font.info.levelset.clone_from", "font.level_number" }, + { "font.info.level", UNDEFINED_FILENAME }, + { "font.info.level.clone_from", "font.level_number" }, + { "font.main.network_players", UNDEFINED_FILENAME }, { "font.main.network_players.clone_from", "font.level_number" }, @@ -8581,6 +8591,7 @@ struct ConfigInfo image_config[] = { "background.INFO[PROGRAM]", UNDEFINED_FILENAME }, { "background.INFO[VERSION]", UNDEFINED_FILENAME }, { "background.INFO[LEVELSET]", UNDEFINED_FILENAME }, + { "background.INFO[LEVEL]", UNDEFINED_FILENAME }, { "background.SETUP", UNDEFINED_FILENAME }, { "background.PLAYING", UNDEFINED_FILENAME }, { "background.DOOR", UNDEFINED_FILENAME }, @@ -9215,6 +9226,8 @@ struct ConfigInfo image_config[] = { "menu.draw_yoffset.INFO[VERSION]", "0" }, { "menu.draw_xoffset.INFO[LEVELSET]", "0" }, { "menu.draw_yoffset.INFO[LEVELSET]", "0" }, + { "menu.draw_xoffset.INFO[LEVEL]", "0" }, + { "menu.draw_yoffset.INFO[LEVEL]", "0" }, { "menu.draw_xoffset.SETUP", "0" }, { "menu.draw_yoffset.SETUP", "0" }, { "menu.draw_xoffset.SETUP[GAME]", "0" }, @@ -9279,6 +9292,7 @@ struct ConfigInfo image_config[] = { "menu.left_spacing.INFO[PROGRAM]", "16" }, { "menu.left_spacing.INFO[VERSION]", "16" }, { "menu.left_spacing.INFO[LEVELSET]", "16" }, + { "menu.left_spacing.INFO[LEVEL]", "16" }, { "menu.left_spacing.SETUP[INPUT]", "16" }, { "menu.middle_spacing.INFO[ELEMENTS]", "16" }, @@ -9292,6 +9306,7 @@ struct ConfigInfo image_config[] = { "menu.right_spacing.INFO[PROGRAM]", "16" }, { "menu.right_spacing.INFO[VERSION]", "16" }, { "menu.right_spacing.INFO[LEVELSET]", "16" }, + { "menu.right_spacing.INFO[LEVEL]", "16" }, { "menu.right_spacing.SETUP[INPUT]", "16" }, { "menu.top_spacing.SCOREINFO", "100" }, @@ -9303,6 +9318,7 @@ struct ConfigInfo image_config[] = { "menu.top_spacing.INFO[PROGRAM]", "100" }, { "menu.top_spacing.INFO[VERSION]", "100" }, { "menu.top_spacing.INFO[LEVELSET]", "100" }, + { "menu.top_spacing.INFO[LEVEL]", "100" }, { "menu.top_spacing.SETUP[INPUT]", "100" }, { "menu.bottom_spacing.SCOREINFO", "20" }, @@ -9314,6 +9330,7 @@ struct ConfigInfo image_config[] = { "menu.bottom_spacing.INFO[PROGRAM]", "20" }, { "menu.bottom_spacing.INFO[VERSION]", "20" }, { "menu.bottom_spacing.INFO[LEVELSET]", "20" }, + { "menu.bottom_spacing.INFO[LEVEL]", "20" }, { "menu.bottom_spacing.SETUP[INPUT]", "20" }, { "menu.paragraph_spacing.SCOREINFO", "-2" }, @@ -9325,6 +9342,7 @@ struct ConfigInfo image_config[] = { "menu.paragraph_spacing.INFO[PROGRAM]", "-3" }, { "menu.paragraph_spacing.INFO[VERSION]", "-2" }, { "menu.paragraph_spacing.INFO[LEVELSET]", "-3" }, + { "menu.paragraph_spacing.INFO[LEVEL]", "-3" }, { "menu.paragraph_spacing.SETUP[INPUT]", "-1" }, { "menu.headline1_spacing.SCOREINFO", "-2" }, @@ -9336,6 +9354,7 @@ struct ConfigInfo image_config[] = { "menu.headline1_spacing.INFO[PROGRAM]", "-2" }, { "menu.headline1_spacing.INFO[VERSION]", "-2" }, { "menu.headline1_spacing.INFO[LEVELSET]", "-2" }, + { "menu.headline1_spacing.INFO[LEVEL]", "-2" }, { "menu.headline1_spacing.SETUP[INPUT]", "-2" }, { "menu.headline2_spacing.SCOREINFO", "-1" }, @@ -9347,6 +9366,7 @@ struct ConfigInfo image_config[] = { "menu.headline2_spacing.INFO[PROGRAM]", "-1" }, { "menu.headline2_spacing.INFO[VERSION]", "-1" }, { "menu.headline2_spacing.INFO[LEVELSET]", "-1" }, + { "menu.headline2_spacing.INFO[LEVEL]", "-1" }, { "menu.headline2_spacing.SETUP[INPUT]", "-1" }, { "menu.line_spacing.SCOREINFO", "0" }, @@ -9358,6 +9378,7 @@ struct ConfigInfo image_config[] = { "menu.line_spacing.INFO[PROGRAM]", "0" }, { "menu.line_spacing.INFO[VERSION]", "0" }, { "menu.line_spacing.INFO[LEVELSET]", "0" }, + { "menu.line_spacing.INFO[LEVEL]", "0" }, { "menu.line_spacing.SETUP[INPUT]", "0" }, { "menu.extra_spacing.SCOREINFO", "2" }, @@ -9369,6 +9390,7 @@ struct ConfigInfo image_config[] = { "menu.extra_spacing.INFO[PROGRAM]", "2" }, { "menu.extra_spacing.INFO[VERSION]", "2" }, { "menu.extra_spacing.INFO[LEVELSET]", "2" }, + { "menu.extra_spacing.INFO[LEVEL]", "2" }, { "menu.extra_spacing.SETUP[INPUT]", "2" }, { "main.button.name.x", "0" }, @@ -9407,6 +9429,8 @@ struct ConfigInfo image_config[] = { "main.button.levelset_info.x", "-1" }, { "main.button.levelset_info.y", "-1" }, + { "main.button.level_info.x", "-1" }, + { "main.button.level_info.y", "-1" }, { "main.button.switch_ecs_aga.x", "-1" }, { "main.button.switch_ecs_aga.y", "-1" }, diff --git a/src/conf_mus.c b/src/conf_mus.c index 0df8a79b..786035af 100644 --- a/src/conf_mus.c +++ b/src/conf_mus.c @@ -41,6 +41,7 @@ struct ConfigInfo music_config[] = { "background.INFO[PROGRAM]", UNDEFINED_FILENAME }, { "background.INFO[VERSION]", UNDEFINED_FILENAME }, { "background.INFO[LEVELSET]", UNDEFINED_FILENAME }, + { "background.INFO[LEVEL]", UNDEFINED_FILENAME }, { "background.SETUP", UNDEFINED_FILENAME }, { "background.titlescreen_initial_1", UNDEFINED_FILENAME }, diff --git a/src/conf_snd.c b/src/conf_snd.c index 815ed400..5b351495 100644 --- a/src/conf_snd.c +++ b/src/conf_snd.c @@ -424,6 +424,7 @@ struct ConfigInfo sound_config[] = { "background.INFO[PROGRAM]", UNDEFINED_FILENAME }, { "background.INFO[VERSION]", UNDEFINED_FILENAME }, { "background.INFO[LEVELSET]", UNDEFINED_FILENAME }, + { "background.INFO[LEVEL]", UNDEFINED_FILENAME }, { "background.SETUP", UNDEFINED_FILENAME }, { "background.titlescreen_initial_1", UNDEFINED_FILENAME }, diff --git a/src/init.c b/src/init.c index cf131e54..956a5d01 100644 --- a/src/init.c +++ b/src/init.c @@ -1879,6 +1879,7 @@ static void InitGraphicInfo(void) IMG_BACKGROUND_INFO_PROGRAM, IMG_BACKGROUND_INFO_VERSION, IMG_BACKGROUND_INFO_LEVELSET, + IMG_BACKGROUND_INFO_LEVEL, IMG_BACKGROUND_SETUP, IMG_BACKGROUND_PLAYING, IMG_BACKGROUND_DOOR, diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 23170fa6..07e0969e 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -870,6 +870,15 @@ static char *getLevelSetInfoBasename(int nr) return basename; } +static char *getLevelInfoBasename(int level_nr) +{ + static char basename[32]; + + sprintf(basename, "%03d.txt", level_nr); + + return basename; +} + char *getLevelSetInfoFilename(int nr) { char *basename = getLevelSetInfoBasename(nr); @@ -881,7 +890,7 @@ char *getLevelSetInfoFilename(int nr) checked_free(filename); - // look for level set info file the current level set directory + // look for level set info file in the current level set's "docs/levelset" sub-directory filename = getPath3(getCurrentLevelDir(), info_subdir, basename); if (fileExists(filename)) return filename; @@ -903,6 +912,7 @@ char *getLevelSetInfoFilename(int nr) }; int i; + // look for README style level set info file directly in the current level set directory for (i = 0; basenames[i] != NULL; i++) { checked_free(filename); @@ -915,6 +925,32 @@ char *getLevelSetInfoFilename(int nr) return NULL; } +char *getLevelInfoFilename(int level_nr) +{ + char *basename = getLevelInfoBasename(level_nr); + static char *info_subdir = NULL; + static char *filename = NULL; + + if (info_subdir == NULL) + info_subdir = getPath2(DOCS_DIRECTORY, LEVEL_INFO_DIRECTORY); + + checked_free(filename); + + // look for level info file in the current level set's "docs/levels" sub-directory + filename = getPath3(getCurrentLevelDir(), info_subdir, basename); + if (fileExists(filename)) + return filename; + + checked_free(filename); + + // look for level style level info file directly in the current level set directory + filename = getPath2(getCurrentLevelDir(), basename); + if (fileExists(filename)) + return filename; + + return NULL; +} + static char *getLevelSetTitleMessageBasename(int nr, boolean initial) { static char basename[32]; diff --git a/src/libgame/setup.h b/src/libgame/setup.h index 5692c9da..c540b801 100644 --- a/src/libgame/setup.h +++ b/src/libgame/setup.h @@ -283,6 +283,7 @@ char *getFilenameFromCurrentLevelDirUpward(char *); char *getHelpAnimFilename(void); char *getHelpTextFilename(void); char *getLevelSetInfoFilename(int); +char *getLevelInfoFilename(int); char *getLevelSetTitleMessageFilename(int, boolean); char *getCreditsFilename(int, boolean); char *getProgramInfoFilename(int); diff --git a/src/libgame/system.h b/src/libgame/system.h index 1c1b50be..62547122 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -681,6 +681,7 @@ #define CREDITS_DIRECTORY "credits" #define PROGRAM_INFO_DIRECTORY "program" #define LEVELSET_INFO_DIRECTORY "levelset" +#define LEVEL_INFO_DIRECTORY "levels" #define CACHE_DIRECTORY "cache" #define CONF_DIRECTORY "conf" #define NETWORK_DIRECTORY "network" @@ -1460,6 +1461,7 @@ struct SetupInternalInfo boolean info_program; boolean info_version; boolean info_levelset; + boolean info_level; boolean info_exit; }; diff --git a/src/main.c b/src/main.c index 37e7cbbb..24e3ffd8 100644 --- a/src/main.c +++ b/src/main.c @@ -9378,6 +9378,7 @@ struct FontInfo font_info[NUM_FONTS + 1] = { "font.game_info" }, { "font.info.elements" }, { "font.info.levelset" }, + { "font.info.level" }, { "font.main.network_players" }, { NULL } diff --git a/src/main.h b/src/main.h index 8b477c85..7eb0e47f 100644 --- a/src/main.h +++ b/src/main.h @@ -2856,6 +2856,7 @@ enum GFX_SPECIAL_ARG_INFO_PROGRAM, GFX_SPECIAL_ARG_INFO_VERSION, GFX_SPECIAL_ARG_INFO_LEVELSET, + GFX_SPECIAL_ARG_INFO_LEVEL, NUM_SPECIAL_GFX_INFO_ARGS }; @@ -3031,6 +3032,7 @@ enum FONT_GAME_INFO, FONT_INFO_ELEMENTS, FONT_INFO_LEVELSET, + FONT_INFO_LEVEL, FONT_MAIN_NETWORK_PLAYERS, NUM_FONTS @@ -3261,6 +3263,7 @@ struct MenuMainButtonInfo struct MenuPosInfo play_solution; struct MenuPosInfo levelset_info; + struct MenuPosInfo level_info; struct MenuPosInfo switch_ecs_aga; }; diff --git a/src/screens.c b/src/screens.c index 5e7bd315..b902af3f 100644 --- a/src/screens.c +++ b/src/screens.c @@ -37,8 +37,9 @@ #define INFO_MODE_PROGRAM 5 #define INFO_MODE_VERSION 6 #define INFO_MODE_LEVELSET 7 +#define INFO_MODE_LEVEL 8 -#define MAX_INFO_MODES 8 +#define MAX_INFO_MODES 9 // screens on the setup screen // (must match GFX_SPECIAL_ARG_SETUP_* values as defined in src/main.h) @@ -107,6 +108,7 @@ #define STR_INFO_PROGRAM "Program Info" #define STR_INFO_VERSION "Version Info" #define STR_INFO_LEVELSET "Level Set Info" +#define STR_INFO_LEVEL "Level Info" #define STR_INFO_EXIT "Exit" // setup screen titles @@ -235,20 +237,21 @@ #define SCREEN_CTRL_ID_INSERT_SOLUTION 12 #define SCREEN_CTRL_ID_PLAY_SOLUTION 13 #define SCREEN_CTRL_ID_LEVELSET_INFO 14 -#define SCREEN_CTRL_ID_SWITCH_ECS_AGA 15 -#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE 16 -#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE 17 -#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE2 18 -#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2 19 +#define SCREEN_CTRL_ID_LEVEL_INFO 15 +#define SCREEN_CTRL_ID_SWITCH_ECS_AGA 16 +#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE 17 +#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE 18 +#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE2 19 +#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2 20 -#define NUM_SCREEN_MENUBUTTONS 20 +#define NUM_SCREEN_MENUBUTTONS 21 -#define SCREEN_CTRL_ID_SCROLL_UP 20 -#define SCREEN_CTRL_ID_SCROLL_DOWN 21 -#define SCREEN_CTRL_ID_SCROLL_VERTICAL 22 -#define SCREEN_CTRL_ID_NETWORK_SERVER 23 +#define SCREEN_CTRL_ID_SCROLL_UP 21 +#define SCREEN_CTRL_ID_SCROLL_DOWN 22 +#define SCREEN_CTRL_ID_SCROLL_VERTICAL 23 +#define SCREEN_CTRL_ID_NETWORK_SERVER 24 -#define NUM_SCREEN_GADGETS 24 +#define NUM_SCREEN_GADGETS 25 #define NUM_SCREEN_SCROLLBUTTONS 2 #define NUM_SCREEN_SCROLLBARS 1 @@ -256,12 +259,13 @@ #define SCREEN_MASK_MAIN (1 << 0) #define SCREEN_MASK_MAIN_HAS_SOLUTION (1 << 1) -#define SCREEN_MASK_MAIN_HAS_SET_INFO (1 << 2) -#define SCREEN_MASK_INPUT (1 << 3) -#define SCREEN_MASK_TOUCH (1 << 4) -#define SCREEN_MASK_TOUCH2 (1 << 5) -#define SCREEN_MASK_SCORES (1 << 6) -#define SCREEN_MASK_SCORES_INFO (1 << 7) +#define SCREEN_MASK_MAIN_HAS_LEVELSET_INFO (1 << 2) +#define SCREEN_MASK_MAIN_HAS_LEVEL_INFO (1 << 3) +#define SCREEN_MASK_INPUT (1 << 4) +#define SCREEN_MASK_TOUCH (1 << 5) +#define SCREEN_MASK_TOUCH2 (1 << 6) +#define SCREEN_MASK_SCORES (1 << 7) +#define SCREEN_MASK_SCORES_INFO (1 << 8) // graphic position and size values for buttons and scrollbars #define SC_MENUBUTTON_XSIZE TILEX @@ -720,7 +724,7 @@ static int align_yoffset = 0; // (there are no draw offset definitions needed for INFO_MODE_TITLE) #define DRAW_MODE_INFO(i) ((i) >= INFO_MODE_TITLE && \ - (i) <= INFO_MODE_LEVELSET ? (i) : \ + (i) <= INFO_MODE_LEVEL ? (i) : \ INFO_MODE_MAIN) #define DRAW_MODE_SETUP(i) ((i) >= SETUP_MODE_MAIN && \ @@ -1033,6 +1037,11 @@ static boolean hasLevelSetInfo(void) return (getLevelSetInfoFilename(0) != NULL); } +static boolean hasLevelInfo(void) +{ + return (getLevelInfoFilename(level_nr) != NULL); +} + static int getTitleScreenGraphic(int nr, boolean initial) { return (initial ? IMG_TITLESCREEN_INITIAL_1 : IMG_TITLESCREEN_1) + nr; @@ -1688,6 +1697,10 @@ static void DrawInfoScreen_Headline(int screen_nr, int num_screens, { sprintf(info_text_title_2, "Page %d of %d", screen_nr + 1, num_screens); } + else if (info_mode == INFO_MODE_LEVEL) + { + snprintf(info_text_title_2, MAX_LINE_LEN, "for level %d", level_nr); + } else { char *text_format = (use_global_screens ? "for %s" : "for \"%s\""); @@ -2002,7 +2015,8 @@ void DrawMainMenu(void) MapTapeButtons(); MapScreenMenuGadgets(SCREEN_MASK_MAIN); UpdateScreenMenuGadgets(SCREEN_MASK_MAIN_HAS_SOLUTION, hasSolutionTape()); - UpdateScreenMenuGadgets(SCREEN_MASK_MAIN_HAS_SET_INFO, hasLevelSetInfo()); + UpdateScreenMenuGadgets(SCREEN_MASK_MAIN_HAS_LEVELSET_INFO, hasLevelSetInfo()); + UpdateScreenMenuGadgets(SCREEN_MASK_MAIN_HAS_LEVEL_INFO, hasLevelInfo()); // copy actual game door content to door double buffer for OpenDoor() BlitBitmap(drawto, bitmap_db_door_1, DX, DY, DXSIZE, DYSIZE, 0, 0); @@ -2324,6 +2338,7 @@ static void HandleMainMenu_SelectLevel(int step, int direction, SaveLevelSetup_SeriesInfo(); UpdateScreenMenuGadgets(SCREEN_MASK_MAIN_HAS_SOLUTION, hasSolutionTape()); + UpdateScreenMenuGadgets(SCREEN_MASK_MAIN_HAS_LEVEL_INFO, hasLevelInfo()); // force redraw of playfield area (may be reset at this point) redraw_mask |= REDRAW_FIELD; @@ -2607,6 +2622,13 @@ static void execInfoLevelSet(void) DrawInfoScreen(); } +static void execInfoLevel(void) +{ + info_mode = INFO_MODE_LEVEL; + + DrawInfoScreen(); +} + static void execExitInfo(void) { SetGameStatus(GAME_MODE_MAIN); @@ -2623,6 +2645,7 @@ static struct TokenInfo info_info_main[] = { TYPE_ENTER_SCREEN, execInfoProgram, STR_INFO_PROGRAM }, { TYPE_ENTER_SCREEN, execInfoVersion, STR_INFO_VERSION }, { TYPE_ENTER_SCREEN, execInfoLevelSet, STR_INFO_LEVELSET }, + { TYPE_ENTER_SCREEN, execInfoLevel, STR_INFO_LEVEL }, { TYPE_EMPTY, NULL, "" }, { TYPE_LEAVE_MENU, execExitInfo, STR_INFO_EXIT }, @@ -4012,6 +4035,7 @@ static char *getInfoScreenTitle_Generic(void) info_mode == INFO_MODE_PROGRAM ? STR_INFO_PROGRAM : info_mode == INFO_MODE_VERSION ? STR_INFO_VERSION : info_mode == INFO_MODE_LEVELSET ? STR_INFO_LEVELSET : + info_mode == INFO_MODE_LEVEL ? STR_INFO_LEVEL : ""); } @@ -4023,6 +4047,7 @@ static int getInfoScreenBackgroundImage_Generic(void) info_mode == INFO_MODE_PROGRAM ? IMG_BACKGROUND_INFO_PROGRAM : info_mode == INFO_MODE_VERSION ? IMG_BACKGROUND_INFO_VERSION : info_mode == INFO_MODE_LEVELSET ? IMG_BACKGROUND_INFO_LEVELSET : + info_mode == INFO_MODE_LEVEL ? IMG_BACKGROUND_INFO_LEVEL : IMG_BACKGROUND_INFO); } @@ -4033,6 +4058,7 @@ static int getInfoScreenBackgroundSound_Generic(void) info_mode == INFO_MODE_PROGRAM ? SND_BACKGROUND_INFO_PROGRAM : info_mode == INFO_MODE_VERSION ? SND_BACKGROUND_INFO_VERSION : info_mode == INFO_MODE_LEVELSET ? SND_BACKGROUND_INFO_LEVELSET : + info_mode == INFO_MODE_LEVEL ? SND_BACKGROUND_INFO_LEVEL : SND_BACKGROUND_INFO); } @@ -4043,6 +4069,7 @@ static int getInfoScreenBackgroundMusic_Generic(void) info_mode == INFO_MODE_PROGRAM ? MUS_BACKGROUND_INFO_PROGRAM : info_mode == INFO_MODE_VERSION ? MUS_BACKGROUND_INFO_VERSION : info_mode == INFO_MODE_LEVELSET ? MUS_BACKGROUND_INFO_LEVELSET : + info_mode == INFO_MODE_LEVEL ? MUS_BACKGROUND_INFO_LEVEL : MUS_BACKGROUND_INFO); } @@ -4051,6 +4078,7 @@ static char *getInfoScreenFilename_Generic(int nr, boolean global) return (info_mode == INFO_MODE_CREDITS ? getCreditsFilename(nr, global) : info_mode == INFO_MODE_PROGRAM ? getProgramInfoFilename(nr) : info_mode == INFO_MODE_LEVELSET ? getLevelSetInfoFilename(nr) : + info_mode == INFO_MODE_LEVEL ? getLevelInfoFilename(level_nr) : NULL); } @@ -4086,9 +4114,12 @@ static void DrawInfoScreen_GenericScreen(int screen_nr, int num_screens, filename, font_text, chars, -1, lines, line_spacing, -1, autowrap, centered, parse_comments); } - else if (info_mode == INFO_MODE_LEVELSET) + else if (info_mode == INFO_MODE_LEVELSET || + info_mode == INFO_MODE_LEVEL) { struct TitleMessageInfo *tmi = &readme; + int font = (info_mode == INFO_MODE_LEVEL && tmi->font == FONT_INFO_LEVELSET ? FONT_INFO_LEVEL : + tmi->font); // if x position set to "-1", automatically determine by playfield width if (tmi->x == -1) @@ -4119,7 +4150,7 @@ static void DrawInfoScreen_GenericScreen(int screen_nr, int num_screens, tmi->height = tmi->lines * getFontHeight(tmi->font); DrawTextFile(mSX + ALIGNED_TEXT_XPOS(tmi), mSY + ALIGNED_TEXT_YPOS(tmi), - filename, tmi->font, tmi->chars, -1, tmi->lines, 0, -1, + filename, font, tmi->chars, -1, tmi->lines, 0, -1, tmi->autowrap, tmi->centered, tmi->parse_comments); } @@ -4195,6 +4226,16 @@ void HandleInfoScreen_Generic(int dx, int dy, int button) text_no_info = "No level set info available."; } + else if (info_mode == INFO_MODE_LEVEL) + { + use_global_screens = FALSE; + + // determine number of level info screens + if (getLevelInfoFilename(level_nr) != NULL) + num_screens = 1; + + text_no_info = "No level info available."; + } if (num_screens == 0) { @@ -4268,6 +4309,8 @@ static void DrawInfoScreen(void) DrawInfoScreen_Version(); else if (info_mode == INFO_MODE_LEVELSET) DrawInfoScreen_Generic(); + else if (info_mode == INFO_MODE_LEVEL) + DrawInfoScreen_Generic(); else DrawInfoScreen_Main(); } @@ -4325,6 +4368,8 @@ void HandleInfoScreen(int mx, int my, int dx, int dy, int button) HandleInfoScreen_Version(button); else if (info_mode == INFO_MODE_LEVELSET) HandleInfoScreen_Generic(dx, dy, button); + else if (info_mode == INFO_MODE_LEVEL) + HandleInfoScreen_Generic(dx, dy, button); else HandleInfoScreen_Main(mx, my, dx, dy, button); } @@ -7909,6 +7954,7 @@ static struct { &setup.internal.info_program, execInfoProgram }, { &setup.internal.info_version, execInfoVersion }, { &setup.internal.info_levelset, execInfoLevelSet }, + { &setup.internal.info_level, execInfoLevel }, { &setup.internal.info_exit, execExitInfo }, { NULL, NULL } @@ -10332,10 +10378,19 @@ static struct IMG_MENU_BUTTON_LEVELSET_INFO_ACTIVE, &menu.main.button.levelset_info, NULL, SCREEN_CTRL_ID_LEVELSET_INFO, - SCREEN_MASK_MAIN_HAS_SET_INFO, + SCREEN_MASK_MAIN_HAS_LEVELSET_INFO, GD_EVENT_RELEASED, FALSE, "show level set info" }, + { + IMG_MENU_BUTTON_LEVEL_INFO, IMG_MENU_BUTTON_LEVEL_INFO_PRESSED, + IMG_MENU_BUTTON_LEVEL_INFO_ACTIVE, + &menu.main.button.level_info, NULL, + SCREEN_CTRL_ID_LEVEL_INFO, + SCREEN_MASK_MAIN_HAS_LEVEL_INFO, + GD_EVENT_RELEASED, + FALSE, "show level info" + }, { IMG_MENU_BUTTON_SWITCH_ECS_AGA, IMG_MENU_BUTTON_SWITCH_ECS_AGA_ACTIVE, -1, &menu.main.button.switch_ecs_aga, &setup.prefer_aga_graphics, @@ -10570,6 +10625,15 @@ static void CreateScreenMenubuttons(void) } } } + else if (id == SCREEN_CTRL_ID_LEVEL_INFO) + { + if (pos->x == -1 && pos->y == -1) + { + // use "SX" here to place button (ignore draw offsets) + x = SX + TILESIZE; + y = SY + SYSIZE - 2 * TILESIZE; + } + } gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, @@ -10840,7 +10904,9 @@ static void UnmapScreenMenuGadgets(int screen_mask) { UnmapGadget(screen_gadget[menubutton_info[i].gadget_id]); - if (screen_mask & SCREEN_MASK_MAIN_HAS_SOLUTION) + // undraw buttons for solution tapes or level info that may not exist for the selected level + if (screen_mask & SCREEN_MASK_MAIN_HAS_SOLUTION || + screen_mask & SCREEN_MASK_MAIN_HAS_LEVEL_INFO) DrawBackground(screen_gadget[menubutton_info[i].gadget_id]->x, screen_gadget[menubutton_info[i].gadget_id]->y, screen_gadget[menubutton_info[i].gadget_id]->width, @@ -10991,6 +11057,10 @@ static void HandleScreenGadgets(struct GadgetInfo *gi) DrawInfoScreen_FromMainMenu(INFO_MODE_LEVELSET); break; + case SCREEN_CTRL_ID_LEVEL_INFO: + DrawInfoScreen_FromMainMenu(INFO_MODE_LEVEL); + break; + case SCREEN_CTRL_ID_SWITCH_ECS_AGA: setup.prefer_aga_graphics = !setup.prefer_aga_graphics; DrawMainMenu(); -- 2.34.1