From e8ef079170087a242af3846d39d3c062354a6513 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 18 Nov 2024 01:06:57 +0100 Subject: [PATCH] added selecting level from the level info screen --- build-scripts/create_element_defs.pl | 1 + src/conf_gfx.c | 14 +++ src/main.h | 12 +++ src/screens.c | 146 ++++++++++++++++++++++----- 4 files changed, 147 insertions(+), 26 deletions(-) diff --git a/build-scripts/create_element_defs.pl b/build-scripts/create_element_defs.pl index 08d4e946..ec2d579c 100755 --- a/build-scripts/create_element_defs.pl +++ b/build-scripts/create_element_defs.pl @@ -2518,6 +2518,7 @@ sub print_config_vars # --- some prefix replacements --- $var =~ s/^main\./menu.main./; + $var =~ s/^info\./menu.info./; $var =~ s/^setup\./menu.setup./; $var =~ s/^scores\./menu.scores./; $var =~ s/^\[player\]\./game.player_/; diff --git a/src/conf_gfx.c b/src/conf_gfx.c index 137dfce9..0fe8e04b 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -7315,6 +7315,15 @@ struct ConfigInfo image_config[] = { "menu.button_prev_level2.active", UNDEFINED_FILENAME }, { "menu.button_prev_level2.active.clone_from", "menu.button_left.active" }, + { "menu.button_next_level3", UNDEFINED_FILENAME }, + { "menu.button_next_level3.clone_from", "menu.button_right" }, + { "menu.button_next_level3.active", UNDEFINED_FILENAME }, + { "menu.button_next_level3.active.clone_from", "menu.button_right.active" }, + { "menu.button_prev_level3", UNDEFINED_FILENAME }, + { "menu.button_prev_level3.clone_from", "menu.button_left" }, + { "menu.button_prev_level3.active", UNDEFINED_FILENAME }, + { "menu.button_prev_level3.active.clone_from", "menu.button_left.active" }, + { "menu.button_next_score", UNDEFINED_FILENAME }, { "menu.button_next_score.clone_from", "menu.button_down" }, { "menu.button_next_score.active", UNDEFINED_FILENAME }, @@ -9677,6 +9686,11 @@ struct ConfigInfo image_config[] = { "scores.button.play_tape.x", "-1" }, { "scores.button.play_tape.y", "-1" }, + { "info.button.prev_level.x", "-1" }, + { "info.button.prev_level.y", "-1" }, + { "info.button.next_level.x", "-1" }, + { "info.button.next_level.y", "-1" }, + { "preview.x", "272" }, { "preview.y", "380" }, { "preview.align", "center" }, diff --git a/src/main.h b/src/main.h index acaf07fe..befd24d5 100644 --- a/src/main.h +++ b/src/main.h @@ -3324,6 +3324,17 @@ struct MenuMainInfo struct TextPosInfo network_players; }; +struct MenuInfoButtonInfo +{ + struct MenuPosInfo prev_level; + struct MenuPosInfo next_level; +}; + +struct MenuInfoInfo +{ + struct MenuInfoButtonInfo button; +}; + struct MenuSetupButtonInfo { struct MenuPosInfo prev_player; @@ -3449,6 +3460,7 @@ struct MenuInfo struct MenuTextInfo text; struct MenuMainInfo main; + struct MenuInfoInfo info; struct MenuSetupInfo setup; struct MenuScoresInfo scores; }; diff --git a/src/screens.c b/src/screens.c index 72457359..cebf4fdd 100644 --- a/src/screens.c +++ b/src/screens.c @@ -236,32 +236,34 @@ #define SCREEN_CTRL_ID_NEXT_LEVEL 1 #define SCREEN_CTRL_ID_PREV_LEVEL2 2 #define SCREEN_CTRL_ID_NEXT_LEVEL2 3 -#define SCREEN_CTRL_ID_PREV_SCORE 4 -#define SCREEN_CTRL_ID_NEXT_SCORE 5 -#define SCREEN_CTRL_ID_PLAY_TAPE 6 -#define SCREEN_CTRL_ID_FIRST_LEVEL 7 -#define SCREEN_CTRL_ID_LAST_LEVEL 8 -#define SCREEN_CTRL_ID_LEVEL_NUMBER 9 -#define SCREEN_CTRL_ID_PREV_PLAYER 10 -#define SCREEN_CTRL_ID_NEXT_PLAYER 11 -#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_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 21 - -#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 25 +#define SCREEN_CTRL_ID_PREV_LEVEL3 4 +#define SCREEN_CTRL_ID_NEXT_LEVEL3 5 +#define SCREEN_CTRL_ID_PREV_SCORE 6 +#define SCREEN_CTRL_ID_NEXT_SCORE 7 +#define SCREEN_CTRL_ID_PLAY_TAPE 8 +#define SCREEN_CTRL_ID_FIRST_LEVEL 9 +#define SCREEN_CTRL_ID_LAST_LEVEL 10 +#define SCREEN_CTRL_ID_LEVEL_NUMBER 11 +#define SCREEN_CTRL_ID_PREV_PLAYER 12 +#define SCREEN_CTRL_ID_NEXT_PLAYER 13 +#define SCREEN_CTRL_ID_INSERT_SOLUTION 14 +#define SCREEN_CTRL_ID_PLAY_SOLUTION 15 +#define SCREEN_CTRL_ID_LEVELSET_INFO 16 +#define SCREEN_CTRL_ID_LEVEL_INFO 17 +#define SCREEN_CTRL_ID_SWITCH_ECS_AGA 18 +#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE 19 +#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE 20 +#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE2 21 +#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2 22 + +#define NUM_SCREEN_MENUBUTTONS 23 + +#define SCREEN_CTRL_ID_SCROLL_UP 23 +#define SCREEN_CTRL_ID_SCROLL_DOWN 24 +#define SCREEN_CTRL_ID_SCROLL_VERTICAL 25 +#define SCREEN_CTRL_ID_NETWORK_SERVER 26 + +#define NUM_SCREEN_GADGETS 27 #define NUM_SCREEN_SCROLLBUTTONS 2 #define NUM_SCREEN_SCROLLBARS 1 @@ -276,6 +278,7 @@ #define SCREEN_MASK_TOUCH2 (1 << 6) #define SCREEN_MASK_SCORES (1 << 7) #define SCREEN_MASK_SCORES_INFO (1 << 8) +#define SCREEN_MASK_INFO (1 << 9) // graphic position and size values for buttons and scrollbars #define SC_MENUBUTTON_XSIZE TILEX @@ -361,6 +364,7 @@ static void execSaveAndExitSetup(void); static void DrawHallOfFame_setScoreEntries(void); static void HandleHallOfFame_SelectLevel(int, int); +static void HandleInfoScreen_SelectLevel(int, int); static char *getHallOfFameRankText(int, int); static char *getHallOfFameScoreText(int, int); static char *getInfoScreenTitle_Generic(void); @@ -4380,6 +4384,9 @@ static void DrawInfoScreen_GenericScreen(int screen_nr, int num_screens, int use int font_foot = MENU_INFO_FONT_FOOT; int yfooter = MENU_SCREEN_INFO_FOOTER; + // unmap optional scroll bar gadgets (may not be used on this screen) + UnmapScreenGadgets(); + ClearField(); DrawInfoScreen_Headline(screen_nr, num_screens, use_global_screens); @@ -4454,6 +4461,10 @@ static void DrawInfoScreen_GenericScreen(int screen_nr, int num_screens, int use char *text_foot = (last_screen ? TEXT_NEXT_MENU : TEXT_NEXT_PAGE); DrawTextSCentered(yfooter, font_foot, text_foot); + + // redraw level selection buttons (which have just been erased) + if (info_mode == INFO_MODE_LEVEL) + RedrawScreenMenuGadgets(SCREEN_MASK_INFO); } static void DrawInfoScreen_Generic(void) @@ -4476,6 +4487,10 @@ static void DrawInfoScreen_Generic(void) FreeScreenGadgets(); CreateScreenGadgets(); + // map gadgets for level info screen + if (info_mode == INFO_MODE_LEVEL) + MapScreenMenuGadgets(SCREEN_MASK_INFO); + HandleInfoScreen_Generic(0, 0, 0, 0, MB_MENU_INITIALIZE); PlayInfoSoundsAndMusic(); @@ -4609,11 +4624,21 @@ void HandleInfoScreen_Generic(int mx, int my, int dx, int dy, int button) DrawTextSCentered(ystart, font_title, text_no_info); DrawTextSCentered(yfooter, font_foot, TEXT_NEXT_MENU); + // redraw level selection buttons (which have just been erased) + if (info_mode == INFO_MODE_LEVEL) + RedrawScreenMenuGadgets(SCREEN_MASK_INFO); + return; } DrawInfoScreen_GenericScreen(screen_nr, num_screens, use_global_screens); } + else if (info_mode == INFO_MODE_LEVEL & ABS(dx) == 1) + { + HandleInfoScreen_SelectLevel(1, dx); + + return; + } else if (button == MB_MENU_LEAVE || dx < 0) { PlaySound(SND_MENU_ITEM_SELECTING); @@ -4797,6 +4822,33 @@ boolean ShowStoryScreen_FromInitGame(void) return TRUE; } +static void HandleInfoScreen_SelectLevel(int step, int direction) +{ + int old_level_nr = level_nr; + int new_level_nr = old_level_nr + step * direction; + + if (new_level_nr < leveldir_current->first_level) + new_level_nr = leveldir_current->first_level; + if (new_level_nr > leveldir_current->last_level) + new_level_nr = leveldir_current->last_level; + + if (setup.allow_skipping_levels != STATE_TRUE && new_level_nr > leveldir_current->handicap_level) + new_level_nr = leveldir_current->handicap_level; + + if (new_level_nr != old_level_nr) + { + PlaySound(SND_MENU_ITEM_SELECTING); + + level_nr = new_level_nr; + + LoadLevel(level_nr); + + HandleInfoScreen_Generic(0, 0, 0, 0, MB_MENU_INITIALIZE); + + SaveLevelSetup_SeriesInfo(); + } +} + void HandleInfoScreen(int mx, int my, int dx, int dy, int button) { // fix "continue" button mode for screens that do not support it @@ -10775,6 +10827,22 @@ static struct GD_EVENT_PRESSED | GD_EVENT_REPEATED, FALSE, "next level" }, + { + IMG_MENU_BUTTON_PREV_LEVEL3, IMG_MENU_BUTTON_PREV_LEVEL3_ACTIVE, -1, + &menu.info.button.prev_level, NULL, + SCREEN_CTRL_ID_PREV_LEVEL3, + SCREEN_MASK_INFO, + GD_EVENT_PRESSED | GD_EVENT_REPEATED, + FALSE, "previous level" + }, + { + IMG_MENU_BUTTON_NEXT_LEVEL3, IMG_MENU_BUTTON_NEXT_LEVEL3_ACTIVE, -1, + &menu.info.button.next_level, NULL, + SCREEN_CTRL_ID_NEXT_LEVEL3, + SCREEN_MASK_INFO, + GD_EVENT_PRESSED | GD_EVENT_REPEATED, + FALSE, "next level" + }, { IMG_MENU_BUTTON_PREV_SCORE, IMG_MENU_BUTTON_PREV_SCORE_ACTIVE, -1, &menu.scores.button.prev_score, NULL, @@ -10990,6 +11058,7 @@ static void CreateScreenMenubuttons(void) boolean is_touch_button = menubutton_info[i].is_touch_button; boolean is_check_button = menubutton_info[i].check_value != NULL; boolean is_score_button = (screen_mask & SCREEN_MASK_SCORES_INFO); + boolean is_info_button = (screen_mask & SCREEN_MASK_INFO); boolean has_gfx_pressed = (menubutton_info[i].gfx_pressed == menubutton_info[i].gfx_unpressed); boolean has_gfx_active = (menubutton_info[i].gfx_active != -1); @@ -11086,6 +11155,23 @@ static void CreateScreenMenubuttons(void) y = (id == SCREEN_CTRL_ID_PREV_LEVEL2 || id == SCREEN_CTRL_ID_NEXT_LEVEL2 ? mSY + MENU_TITLE1_YPOS : 0); } + else if (is_info_button) + { + // if x/y set to -1, dynamically place buttons next to title text + int title_width = getTextWidth(STR_INFO_LEVEL, FONT_TITLE_1); + + // use "SX" here to center buttons (ignore horizontal draw offset) + if (pos->x == -1) + x = (id == SCREEN_CTRL_ID_PREV_LEVEL3 ? + SX + (SXSIZE - title_width) / 2 - width * 3 / 2 : + id == SCREEN_CTRL_ID_NEXT_LEVEL3 ? + SX + (SXSIZE + title_width) / 2 + width / 2 : 0); + + // use "mSY" here to place buttons (respect vertical draw offset) + if (pos->y == -1) + y = (id == SCREEN_CTRL_ID_PREV_LEVEL3 || + id == SCREEN_CTRL_ID_NEXT_LEVEL3 ? mSY + MENU_TITLE1_YPOS : 0); + } if (id == SCREEN_CTRL_ID_LEVELSET_INFO) { @@ -11508,6 +11594,14 @@ static void HandleScreenGadgets(struct GadgetInfo *gi) HandleHallOfFame_SelectLevel(step, +1); break; + case SCREEN_CTRL_ID_PREV_LEVEL3: + HandleInfoScreen_SelectLevel(step, -1); + break; + + case SCREEN_CTRL_ID_NEXT_LEVEL3: + HandleInfoScreen_SelectLevel(step, +1); + break; + case SCREEN_CTRL_ID_PREV_SCORE: HandleScoreInfo_SelectScore(step, -1); break; -- 2.34.1