added support for gadget-like pressable menu buttons on main screen
[rocksndiamonds.git] / src / screens.c
index 9113105623bb2c561b841b6445cba65e6266b5d0..e8e4133f76551431deb3d3527b217fa03cdb78d1 100644 (file)
@@ -317,6 +317,9 @@ static struct
 } volumes_list[] =
 {
   {    0,      "0 %"                           },
+  {    1,      "1 %"                           },
+  {    2,      "2 %"                           },
+  {    5,      "5 %"                           },
   {    10,     "10 %"                          },
   {    20,     "20 %"                          },
   {    30,     "30 %"                          },
@@ -420,6 +423,9 @@ static struct
 #define MAX_NUM_TITLE_SCREENS  (2 * MAX_NUM_TITLE_IMAGES +             \
                                 2 * MAX_NUM_TITLE_MESSAGES)
 
+#define NO_DIRECT_LEVEL_SELECT (-1)
+
+
 static int num_title_screens = 0;
 
 struct TitleControlInfo
@@ -958,10 +964,8 @@ static void InitializeMainControls()
 
     if (pos_button != NULL)            /* (x/y may be -1/-1 here) */
     {
-      if (pos_button->width == 0)
-       pos_button->width = button_width;
-      if (pos_button->height == 0)
-       pos_button->height = button_height;
+      pos_button->width  = button_width;
+      pos_button->height = button_height;
     }
 
     if (pos_text != NULL)              /* (x/y may be -1/-1 here) */
@@ -969,18 +973,19 @@ static void InitializeMainControls()
       /* calculate size for non-clickable text -- needed for text alignment */
       boolean calculate_text_size = (pos_button == NULL && text != NULL);
 
+      if (pos_text->width == -1 || calculate_text_size)
+       pos_text->width = text_width;
+      if (pos_text->height == -1 || calculate_text_size)
+       pos_text->height = text_height;
+
       if (visibleMenuPos(pos_button))
       {
        if (pos_text->x == -1)
          pos_text->x = pos_button->x + pos_button->width;
        if (pos_text->y == -1)
-         pos_text->y = pos_button->y;
+         pos_text->y =
+           pos_button->y + (pos_button->height - pos_text->height) / 2;
       }
-
-      if (pos_text->width == -1 || calculate_text_size)
-       pos_text->width = text_width;
-      if (pos_text->height == -1 || calculate_text_size)
-       pos_text->height = text_height;
     }
 
     if (pos_input != NULL)             /* (x/y may be -1/-1 here) */
@@ -1001,8 +1006,24 @@ static void InitializeMainControls()
   }
 }
 
+static void DrawPressedGraphicThruMask(int dst_x, int dst_y,
+                                      int graphic, boolean pressed)
+{
+  struct GraphicInfo *g = &graphic_info[graphic];
+  Bitmap *src_bitmap;
+  int src_x, src_y;
+  int xoffset = (pressed ? g->pressed_xoffset : 0);
+  int yoffset = (pressed ? g->pressed_yoffset : 0);
+
+  getFixedGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y);
+
+  BlitBitmapMasked(src_bitmap, drawto, src_x + xoffset, src_y + yoffset,
+                  g->width, g->height, dst_x, dst_y);
+}
+
 static void DrawCursorAndText_Main_Ext(int nr, boolean active_text,
-                                      boolean active_input)
+                                      boolean active_input,
+                                      boolean pressed_button)
 {
   int i;
 
@@ -1039,7 +1060,7 @@ static void DrawCursorAndText_Main_Ext(int nr, boolean active_text,
        int y = mSY + pos->y;
 
        DrawBackgroundForGraphic(x, y, pos->width, pos->height, button_graphic);
-       DrawFixedGraphicThruMaskExt(drawto, x, y, button_graphic, 0);
+       DrawPressedGraphicThruMask(x, y, button_graphic, pressed_button);
       }
 
       if (visibleTextPos(pos_text) && text != NULL)
@@ -1071,15 +1092,17 @@ static void DrawCursorAndText_Main_Ext(int nr, boolean active_text,
   }
 }
 
-static void DrawCursorAndText_Main(int nr, boolean active_text)
+static void DrawCursorAndText_Main(int nr, boolean active_text,
+                                  boolean pressed_button)
 {
-  DrawCursorAndText_Main_Ext(nr, active_text, FALSE);
+  DrawCursorAndText_Main_Ext(nr, active_text, FALSE, pressed_button);
 }
 
 #if 0
-static void DrawCursorAndText_Main_Input(int nr, boolean active_text)
+static void DrawCursorAndText_Main_Input(int nr, boolean active_text,
+                                        boolean pressed_button)
 {
-  DrawCursorAndText_Main_Ext(nr, active_text, TRUE);
+  DrawCursorAndText_Main_Ext(nr, active_text, TRUE, pressed_button);
 }
 #endif
 
@@ -1221,10 +1244,7 @@ void DrawTitleScreenImage(int nr, boolean initial)
   ClearRectangleOnBackground(drawto, 0, 0, WIN_XSIZE, WIN_YSIZE);
 
   if (DrawingOnBackground(dst_x, dst_y))
-  {
-    SetClipOrigin(bitmap, bitmap->stored_clip_gc, dst_x - src_x, dst_y - src_y);
     BlitBitmapMasked(bitmap, drawto, src_x, src_y, width, height, dst_x, dst_y);
-  }
   else
     BlitBitmap(bitmap, drawto, src_x, src_y, width, height, dst_x, dst_y);
 
@@ -1310,9 +1330,6 @@ void DrawMainMenuExt(int fade_mask, boolean do_fading)
   KeyboardAutoRepeatOn();
   ActivateJoystick();
 
-  SetDrawDeactivationMask(REDRAW_NONE);
-  SetDrawBackgroundMask(REDRAW_FIELD);
-
   audio.sound_deactivated = FALSE;
 
   GetPlayerConfig();
@@ -1374,16 +1391,20 @@ void DrawMainMenuExt(int fade_mask, boolean do_fading)
   LoadLevel(level_nr);
   LoadScore(level_nr);
 
+  // set this after "ChangeViewportPropertiesIfNeeded()" (which may reset it)
+  SetDrawDeactivationMask(REDRAW_NONE);
+  SetDrawBackgroundMask(REDRAW_FIELD);
+
   SetMainBackgroundImage(IMG_BACKGROUND_MAIN);
 
   if (fade_mask == REDRAW_ALL)
-    RedrawBackground();
+    RedrawGlobalBorder();
 
   ClearField();
 
   InitializeMainControls();
 
-  DrawCursorAndText_Main(-1, FALSE);
+  DrawCursorAndText_Main(-1, FALSE, FALSE);
   DrawPreviewLevelInitial();
 
   HandleMainMenu(0, 0, 0, 0, MB_MENU_INITIALIZE);
@@ -1619,9 +1640,11 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button)
 
     if (game_status == GAME_MODE_INFO)
     {
+      int fade_mask = (num_title_screens == 0 ? REDRAW_FIELD : REDRAW_ALL);
+
       info_mode = INFO_MODE_MAIN;
 
-      DrawInfoScreenExt(REDRAW_ALL, use_fading_main_menu);
+      DrawInfoScreenExt(fade_mask, use_fading_main_menu);
     }
     else       /* default: return to main menu */
     {
@@ -1632,12 +1655,16 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button)
   }
 }
 
-void HandleMainMenu_SelectLevel(int step, int direction)
+void HandleMainMenu_SelectLevel(int step, int direction, int selected_level_nr)
 {
   int old_level_nr = level_nr;
   int new_level_nr;
 
-  new_level_nr = old_level_nr + step * direction;
+  if (selected_level_nr != NO_DIRECT_LEVEL_SELECT)
+    new_level_nr = selected_level_nr;
+  else
+    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)
@@ -1646,7 +1673,7 @@ void HandleMainMenu_SelectLevel(int step, int direction)
   if (setup.handicap && new_level_nr > leveldir_current->handicap_level)
   {
     /* skipping levels is only allowed when trying to skip single level */
-    if (setup.skip_levels && step == 1 &&
+    if (setup.skip_levels && new_level_nr == old_level_nr + 1 &&
        Request("Level still unsolved! Skip despite handicap?", REQ_ASK))
     {
       leveldir_current->handicap_level++;
@@ -1677,19 +1704,21 @@ void HandleMainMenu_SelectLevel(int step, int direction)
 
     /* needed because DrawPreviewLevelInitial() takes some time */
     BackToFront();
-    SyncDisplay();
+    /* SyncDisplay(); */
   }
 }
 
 void HandleMainMenu(int mx, int my, int dx, int dy, int button)
 {
   static int choice = MAIN_CONTROL_GAME;
+  static boolean button_pressed_last = FALSE;
+  boolean button_pressed = FALSE;
   int pos = choice;
   int i;
 
   if (button == MB_MENU_INITIALIZE)
   {
-    DrawCursorAndText_Main(choice, TRUE);
+    DrawCursorAndText_Main(choice, TRUE, FALSE);
 
     return;
   }
@@ -1709,6 +1738,16 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
        break;
       }
     }
+
+    // handle pressed/unpressed state for active/inactive menu buttons
+    // (if pos != -1, "i" contains index position corresponding to "pos")
+    if (button &&
+       pos >= MAIN_CONTROL_NAME && pos <= MAIN_CONTROL_QUIT &&
+       insideMenuPosRect(main_controls[i].pos_button, mx - mSX, my - mSY))
+      button_pressed = TRUE;
+
+    if (button_pressed != button_pressed_last)
+      DrawCursorAndText_Main(choice, TRUE, button_pressed);
   }
   else if (dx || dy)   /* keyboard input */
   {
@@ -1721,15 +1760,15 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
 
   if (pos == MAIN_CONTROL_LEVELS && dx != 0 && button)
   {
-    HandleMainMenu_SelectLevel(1, dx < 0 ? -1 : +1);
+    HandleMainMenu_SelectLevel(1, (dx < 0 ? -1 : +1), NO_DIRECT_LEVEL_SELECT);
   }
   else if (pos == MAIN_CONTROL_FIRST_LEVEL && !button)
   {
-    HandleMainMenu_SelectLevel(MAX_LEVELS, -1);
+    HandleMainMenu_SelectLevel(MAX_LEVELS, -1, NO_DIRECT_LEVEL_SELECT);
   }
   else if (pos == MAIN_CONTROL_LAST_LEVEL && !button)
   {
-    HandleMainMenu_SelectLevel(MAX_LEVELS, +1);
+    HandleMainMenu_SelectLevel(MAX_LEVELS, +1, NO_DIRECT_LEVEL_SELECT);
   }
   else if (pos == MAIN_CONTROL_LEVEL_NUMBER && !button)
   {
@@ -1747,8 +1786,8 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
       {
        PlaySound(SND_MENU_ITEM_ACTIVATING);
 
-       DrawCursorAndText_Main(choice, FALSE);
-       DrawCursorAndText_Main(pos, TRUE);
+       DrawCursorAndText_Main(choice, FALSE, FALSE);
+       DrawCursorAndText_Main(pos, TRUE, button_pressed);
 
        choice = pos;
       }
@@ -1835,6 +1874,8 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
       }
     }
   }
+
+  button_pressed_last = button_pressed;
 }
 
 
@@ -1947,7 +1988,7 @@ static void DrawInfoScreen_Main(int fade_mask, boolean do_fading)
 
   if (fade_mask == REDRAW_ALL)
   {
-    RedrawBackground();
+    RedrawGlobalBorder();
 
     OpenDoor(DOOR_CLOSE_1 | DOOR_CLOSE_2 | DOOR_NO_DELAY | DOOR_FORCE_REDRAW);
   }
@@ -2086,7 +2127,7 @@ void DrawInfoScreen_NotAvailable(char *text_title, char *text_error)
   int ystart2 = mSY - SY + 150;
   int ybottom = mSY - SY + SYSIZE - 20;
 
-  SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_LEVELSET);
+  SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO);
 
   FadeOut(REDRAW_FIELD);
 
@@ -3013,6 +3054,41 @@ void DrawInfoScreen_LevelSet()
 {
   struct TitleMessageInfo *tmi = &readme;
   char *filename = getLevelSetInfoFilename();
+  char *title = "Level Set Information:";
+  int ystart1 = mSY - SY + 100;
+  int ybottom = mSY - SY + SYSIZE - 20;
+
+  if (filename == NULL)
+  {
+    DrawInfoScreen_NotAvailable(title, "No information for this level set.");
+
+    return;
+  }
+
+  SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_LEVELSET);
+
+  FadeOut(REDRAW_FIELD);
+
+  ClearField();
+  DrawHeadline();
+
+  DrawTextSCentered(ystart1, FONT_TEXT_1, title);
+
+  /* if x position set to "-1", automatically determine by playfield width */
+  if (tmi->x == -1)
+    tmi->x = SXSIZE / 2;
+
+  /* if y position set to "-1", use static default value */
+  if (tmi->y == -1)
+    tmi->y = 150;
+
+  /* if width set to "-1", automatically determine by playfield width */
+  if (tmi->width == -1)
+    tmi->width = SXSIZE - 2 * TILEX;
+
+  /* if height set to "-1", automatically determine by playfield height */
+  if (tmi->height == -1)
+    tmi->height = SYSIZE - 20 - tmi->y - 10;
 
   /* if chars set to "-1", automatically determine by text and font width */
   if (tmi->chars == -1)
@@ -3026,25 +3102,12 @@ void DrawInfoScreen_LevelSet()
   else
     tmi->height = tmi->lines * getFontHeight(tmi->font);
 
-  SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_LEVELSET);
-
-  FadeOut(REDRAW_FIELD);
-
-  ClearField();
-  DrawHeadline();
-
-  DrawTextCentered(mSY + 100, FONT_TEXT_1, "Level Set Information:");
-
-  if (filename != NULL)
-    DrawTextFile(mSX + ALIGNED_TEXT_XPOS(tmi), mSY + ALIGNED_TEXT_YPOS(tmi),
-                filename, tmi->font, tmi->chars, -1, tmi->lines, 0, -1,
-                tmi->autowrap, tmi->centered, tmi->parse_comments);
-  else
-    DrawTextCentered(mSY + ALIGNED_TEXT_YPOS(tmi), FONT_TEXT_2,
-                    "No information for this level set.");
+  DrawTextFile(mSX + ALIGNED_TEXT_XPOS(tmi), mSY + ALIGNED_TEXT_YPOS(tmi),
+              filename, tmi->font, tmi->chars, -1, tmi->lines, 0, -1,
+              tmi->autowrap, tmi->centered, tmi->parse_comments);
 
-  DrawTextCentered(mSY + SYSIZE - 20, FONT_TEXT_4,
-                  "Press any key or button for info menu");
+  DrawTextSCentered(ybottom, FONT_TEXT_4,
+                   "Press any key or button for info menu");
 
   FadeIn(REDRAW_FIELD);
 }
@@ -3225,6 +3288,8 @@ void HandleTypeName(int newxpos, Key key)
 
 static void DrawChooseTree(TreeInfo **ti_ptr)
 {
+  int fade_mask = (DrawingAreaChanged() ? REDRAW_ALL : REDRAW_FIELD);
+
   UnmapAllGadgets();
 
   FreeScreenGadgets();
@@ -3232,14 +3297,14 @@ static void DrawChooseTree(TreeInfo **ti_ptr)
 
   CloseDoor(DOOR_CLOSE_2);
 
-  FadeOut(REDRAW_FIELD);
+  FadeOut(fade_mask);
 
   ClearField();
 
   HandleChooseTree(0, 0, 0, 0, MB_MENU_INITIALIZE, ti_ptr);
   MapScreenTreeGadgets(*ti_ptr);
 
-  FadeIn(REDRAW_FIELD);
+  FadeIn(fade_mask);
 
   InitAnimation();
 }
@@ -3268,8 +3333,8 @@ static void clearMenuListArea()
   int scrollbar_xpos = mSX + SC_SCROLLBAR_XPOS + menu.scrollbar_xoffset;
 
   /* correct scrollbar position if placed outside menu (playfield) area */
-  if (scrollbar_xpos > SC_SCROLLBAR_XPOS)
-    scrollbar_xpos = SC_SCROLLBAR_XPOS;
+  if (scrollbar_xpos > SX + SC_SCROLLBAR_XPOS)
+    scrollbar_xpos = SX + SC_SCROLLBAR_XPOS;
 
   /* clear menu list area, but not title or scrollbar */
   DrawBackground(mSX, mSY + MENU_SCREEN_START_YPOS * 32,
@@ -3450,7 +3515,11 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
     else
     {
       if (game_status == GAME_MODE_LEVELNR)
-       level_nr = atoi(level_number_current->identifier);
+      {
+       int new_level_nr = atoi(level_number_current->identifier);
+
+       HandleMainMenu_SelectLevel(0, 0, new_level_nr);
+      }
 
       game_status = GAME_MODE_MAIN;
 
@@ -3644,7 +3713,11 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
        else
        {
          if (game_status == GAME_MODE_LEVELNR)
-           level_nr = atoi(level_number_current->identifier);
+         {
+           int new_level_nr = atoi(level_number_current->identifier);
+
+           HandleMainMenu_SelectLevel(0, 0, new_level_nr);
+         }
 
          game_status = GAME_MODE_MAIN;
 
@@ -3733,6 +3806,8 @@ void HandleChooseLevelNr(int mx, int my, int dx, int dy, int button)
 
 void DrawHallOfFame(int highlight_position)
 {
+  int fade_mask = (DrawingAreaChanged() ? REDRAW_ALL : REDRAW_FIELD);
+
   UnmapAllGadgets();
   FadeSoundsAndMusic();
 
@@ -3751,7 +3826,7 @@ void DrawHallOfFame(int highlight_position)
 
   FadeSetEnterScreen();
 
-  FadeOut(REDRAW_FIELD);
+  FadeOut(fade_mask);
 
   InitAnimation();
 
@@ -3760,7 +3835,7 @@ void DrawHallOfFame(int highlight_position)
 
   HandleHallOfFame(highlight_position, 0, 0, 0, MB_MENU_INITIALIZE);
 
-  FadeIn(REDRAW_FIELD);
+  FadeIn(fade_mask);
 }
 
 static void drawHallOfFameList(int first_entry, int highlight_position)
@@ -4309,6 +4384,7 @@ static void execSetupSound()
 {
   if (volumes_simple == NULL)
   {
+    boolean current_volume_simple_found = FALSE;
     int i;
 
     for (i = 0; volumes_list[i].value != -1; i++)
@@ -4330,6 +4406,31 @@ static void execSetupSound()
       setString(&ti->infotext, "Sound Volume");
 
       pushTreeInfo(&volumes_simple, ti);
+
+      if (value == setup.volume_simple)
+        current_volume_simple_found = TRUE;
+    }
+
+    if (!current_volume_simple_found)
+    {
+      // add entry for non-preset volume value
+
+      TreeInfo *ti = newTreeInfo_setDefaults(TREE_TYPE_UNDEFINED);
+      char identifier[32], name[32];
+      int value = setup.volume_simple;
+
+      ti->node_top = &volumes_simple;
+      ti->sort_priority = value;
+
+      sprintf(identifier, "%d", value);
+      sprintf(name, "%d %% (Current)", value);
+
+      setString(&ti->identifier, identifier);
+      setString(&ti->name, name);
+      setString(&ti->name_sorting, name);
+      setString(&ti->infotext, "Sound Volume");
+
+      pushTreeInfo(&volumes_simple, ti);
     }
 
     /* sort volume values to start with lowest volume value */
@@ -4351,6 +4452,7 @@ static void execSetupSound()
 
   if (volumes_loops == NULL)
   {
+    boolean current_volume_loops_found = FALSE;
     int i;
 
     for (i = 0; volumes_list[i].value != -1; i++)
@@ -4372,6 +4474,31 @@ static void execSetupSound()
       setString(&ti->infotext, "Loops Volume");
 
       pushTreeInfo(&volumes_loops, ti);
+
+      if (value == setup.volume_loops)
+        current_volume_loops_found = TRUE;
+    }
+
+    if (!current_volume_loops_found)
+    {
+      // add entry for non-preset volume value
+
+      TreeInfo *ti = newTreeInfo_setDefaults(TREE_TYPE_UNDEFINED);
+      char identifier[32], name[32];
+      int value = setup.volume_loops;
+
+      ti->node_top = &volumes_loops;
+      ti->sort_priority = value;
+
+      sprintf(identifier, "%d", value);
+      sprintf(name, "%d %% (Current)", value);
+
+      setString(&ti->identifier, identifier);
+      setString(&ti->name, name);
+      setString(&ti->name_sorting, name);
+      setString(&ti->infotext, "Loops Volume");
+
+      pushTreeInfo(&volumes_loops, ti);
     }
 
     /* sort volume values to start with lowest volume value */
@@ -4393,6 +4520,7 @@ static void execSetupSound()
 
   if (volumes_music == NULL)
   {
+    boolean current_volume_music_found = FALSE;
     int i;
 
     for (i = 0; volumes_list[i].value != -1; i++)
@@ -4414,6 +4542,31 @@ static void execSetupSound()
       setString(&ti->infotext, "Music Volume");
 
       pushTreeInfo(&volumes_music, ti);
+
+      if (value == setup.volume_music)
+        current_volume_music_found = TRUE;
+    }
+
+    if (!current_volume_music_found)
+    {
+      // add entry for non-preset volume value
+
+      TreeInfo *ti = newTreeInfo_setDefaults(TREE_TYPE_UNDEFINED);
+      char identifier[32], name[32];
+      int value = setup.volume_music;
+
+      ti->node_top = &volumes_music;
+      ti->sort_priority = value;
+
+      sprintf(identifier, "%d", value);
+      sprintf(name, "%d %% (Current)", value);
+
+      setString(&ti->identifier, identifier);
+      setString(&ti->name, name);
+      setString(&ti->name_sorting, name);
+      setString(&ti->infotext, "Music Volume");
+
+      pushTreeInfo(&volumes_music, ti);
     }
 
     /* sort volume values to start with lowest volume value */
@@ -5278,6 +5431,7 @@ static void drawSetupInfoList(struct TokenInfo *setup_info,
 
 static void DrawSetupScreen_Generic()
 {
+  int fade_mask = (DrawingAreaChanged() ? REDRAW_ALL : REDRAW_FIELD);
   boolean redraw_all = FALSE;
   char *title_string = NULL;
   int i;
@@ -5292,7 +5446,7 @@ static void DrawSetupScreen_Generic()
   if (redraw_mask & REDRAW_ALL)
     redraw_all = TRUE;
 
-  FadeOut(REDRAW_FIELD);
+  FadeOut(fade_mask);
 
   ClearField();
 
@@ -5379,9 +5533,9 @@ static void DrawSetupScreen_Generic()
   MapScreenGadgets(max_setup_info);
 
   if (redraw_all)
-    redraw_mask = REDRAW_ALL;
+    redraw_mask = fade_mask = REDRAW_ALL;
 
-  FadeIn(redraw_mask);
+  FadeIn(fade_mask);
 
   InitAnimation();
 }
@@ -6556,8 +6710,8 @@ static void CreateScreenScrollbuttons()
     height = SC_SCROLLBUTTON_YSIZE;
 
     /* correct scrollbar position if placed outside menu (playfield) area */
-    if (x > SC_SCROLL_UP_XPOS)
-      x = SC_SCROLL_UP_XPOS;
+    if (x > SX + SC_SCROLL_UP_XPOS)
+      x = SX + SC_SCROLL_UP_XPOS;
 
     if (id == SCREEN_CTRL_ID_SCROLL_DOWN)
       y = mSY + (SC_SCROLL_VERTICAL_YPOS +
@@ -6625,8 +6779,8 @@ static void CreateScreenScrollbars()
     height = scrollbar_info[i].height;
 
     /* correct scrollbar position if placed outside menu (playfield) area */
-    if (x > SC_SCROLL_VERTICAL_XPOS)
-      x = SC_SCROLL_VERTICAL_XPOS;
+    if (x > SX + SC_SCROLL_VERTICAL_XPOS)
+      x = SX + SC_SCROLL_VERTICAL_XPOS;
 
     if (id == SCREEN_CTRL_ID_SCROLL_VERTICAL)
       height = (NUM_MENU_ENTRIES_ON_SCREEN - 2) * SC_SCROLLBUTTON_YSIZE;
@@ -6732,11 +6886,11 @@ static void HandleScreenGadgets(struct GadgetInfo *gi)
   switch (id)
   {
     case SCREEN_CTRL_ID_PREV_LEVEL:
-      HandleMainMenu_SelectLevel(step, -1);
+      HandleMainMenu_SelectLevel(step, -1, NO_DIRECT_LEVEL_SELECT);
       break;
 
     case SCREEN_CTRL_ID_NEXT_LEVEL:
-      HandleMainMenu_SelectLevel(step, +1);
+      HandleMainMenu_SelectLevel(step, +1, NO_DIRECT_LEVEL_SELECT);
       break;
 
     case SCREEN_CTRL_ID_PREV_PLAYER: