added selecting level from the level info screen
authorHolger Schemel <holger.schemel@virtion.de>
Mon, 18 Nov 2024 00:06:57 +0000 (01:06 +0100)
committerHolger Schemel <holger.schemel@virtion.de>
Mon, 18 Nov 2024 00:15:25 +0000 (01:15 +0100)
build-scripts/create_element_defs.pl
src/conf_gfx.c
src/main.h
src/screens.c

index 08d4e946f2c5ebff89cd2ec93724a839d6be19f6..ec2d579c750600531d364f5dfa59fd0055bd25b8 100755 (executable)
@@ -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_/;
index 137dfce9ca1acbb2608ccea7331bee61d8043a5f..0fe8e04bdf3f31ffeefc9b522581c454592979ec 100644 (file)
@@ -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"                        },
index acaf07feb86909d0d15ed8f88d3c60949217e4b4..befd24d54fb1563aa796f1e3f6e4a3fb5d006107 100644 (file)
@@ -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;
 };
index 724573594a8ee8e10d0aeae5ae93e6d8f9a6f9a6..cebf4fdd8e70314d9b5ad10fd4bd87324540ea1c 100644 (file)
 #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
 #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;