added adjusting input setup menu according to configured screen size
[rocksndiamonds.git] / src / screens.c
index 58a2ecba14946dcfb4b470592fb5177e42dfbd67..026dfe0da833d47a2be776f27ecfdc56a8a1db94 100644 (file)
 
 /* for input setup functions */
 #define SETUPINPUT_SCREEN_POS_START    0
-#define SETUPINPUT_SCREEN_POS_END      (SCR_FIELDY - 4)
-#define SETUPINPUT_SCREEN_POS_EMPTY1   (SETUPINPUT_SCREEN_POS_START + 3)
-#define SETUPINPUT_SCREEN_POS_EMPTY2   (SETUPINPUT_SCREEN_POS_END - 1)
+#define SETUPINPUT_SCREEN_POS_EMPTY1   3
+#define SETUPINPUT_SCREEN_POS_EMPTY2   12
+#define SETUPINPUT_SCREEN_POS_END      13
 
 #define MENU_SETUP_FONT_TITLE          FONT_TEXT_1
 #define MENU_SETUP_FONT_TEXT           FONT_TITLE_2
 #define MENU_INFO_FONT_TEXT            FONT_TEXT_3
 #define MENU_INFO_FONT_FOOT            FONT_TEXT_4
 #define MENU_INFO_SPACE_HEAD           (menu.headline2_spacing_info[info_mode])
-#define MENU_SCREEN_INFO_XSTART                16
-#define MENU_SCREEN_INFO_YSTART1       100
+#define MENU_SCREEN_INFO_SPACE_LEFT    (menu.left_spacing_info[info_mode])
+#define MENU_SCREEN_INFO_SPACE_RIGHT   (menu.right_spacing_info[info_mode])
+#define MENU_SCREEN_INFO_SPACE_TOP     (menu.top_spacing_info[info_mode])
+#define MENU_SCREEN_INFO_SPACE_BOTTOM  (menu.bottom_spacing_info[info_mode])
+#define MENU_SCREEN_INFO_YSTART1       MENU_SCREEN_INFO_SPACE_TOP
 #define MENU_SCREEN_INFO_YSTART2       (MENU_SCREEN_INFO_YSTART1 +            \
                                         getMenuTextStep(MENU_INFO_SPACE_HEAD, \
                                                         MENU_INFO_FONT_TITLE))
 #define MENU_SCREEN_INFO_YSTEP         (TILEY + 4)
-#define MENU_SCREEN_INFO_YBOTTOM       (SYSIZE - 20)
+#define MENU_SCREEN_INFO_YBOTTOM       (SYSIZE - MENU_SCREEN_INFO_SPACE_BOTTOM)
 #define MENU_SCREEN_INFO_YSIZE         (MENU_SCREEN_INFO_YBOTTOM -     \
                                         MENU_SCREEN_INFO_YSTART2 -     \
                                         TILEY / 2)
@@ -303,7 +306,7 @@ static struct
   char *text;
 } scaling_types_list[] =
 {
-  {    SCALING_QUALITY_NEAREST, "None"         },
+  {    SCALING_QUALITY_NEAREST, "Off"          },
   {    SCALING_QUALITY_LINEAR,  "Linear"       },
   {    SCALING_QUALITY_BEST,    "Anisotropic"  },
 
@@ -421,6 +424,7 @@ static struct
   char *text;
 } touch_controls_list[] =
 {
+  {    TOUCH_CONTROL_OFF,              "Off"                   },
   {    TOUCH_CONTROL_VIRTUAL_BUTTONS,  "Virtual Buttons"       },
   {    TOUCH_CONTROL_WIPE_GESTURES,    "Wipe Gestures"         },
   {    TOUCH_CONTROL_FOLLOW_FINGER,    "Follow Finger"         },
@@ -581,6 +585,9 @@ static char *main_text_level_year           = NULL;
 static char *main_text_level_imported_from     = NULL;
 static char *main_text_level_imported_by       = NULL;
 static char *main_text_level_tested_by         = NULL;
+static char *main_text_title_1                 = NULL;
+static char *main_text_title_2                 = NULL;
+static char *main_text_title_3                 = NULL;
 
 struct MainControlInfo
 {
@@ -730,19 +737,19 @@ static struct MainControlInfo main_controls[] =
   {
     MAIN_CONTROL_TITLE_1,
     NULL,                              -1,
-    &menu.main.text.title_1,           &setup.internal.program_title,
+    &menu.main.text.title_1,           &main_text_title_1,
     NULL,                              NULL,
   },
   {
     MAIN_CONTROL_TITLE_2,
     NULL,                              -1,
-    &menu.main.text.title_2,           &setup.internal.program_copyright,
+    &menu.main.text.title_2,           &main_text_title_2,
     NULL,                              NULL,
   },
   {
     MAIN_CONTROL_TITLE_3,
     NULL,                              -1,
-    &menu.main.text.title_3,           &setup.internal.program_company,
+    &menu.main.text.title_3,           &main_text_title_3,
     NULL,                              NULL,
   },
 
@@ -1014,6 +1021,10 @@ static void InitializeMainControls()
   main_text_level_imported_by  = leveldir_current->imported_by;
   main_text_level_tested_by    = leveldir_current->tested_by;
 
+  main_text_title_1 = getConfigProgramTitleString();
+  main_text_title_2 = getConfigProgramCopyrightString();
+  main_text_title_3 = getConfigProgramCompanyString();
+
   /* set main control screen positions to dynamically determined values */
   for (i = 0; main_controls[i].nr != -1; i++)
   {
@@ -1322,9 +1333,8 @@ static void drawChooseTreeCursor(int ypos, boolean active)
 
 void DrawHeadline()
 {
-  DrawTextSCentered(MENU_TITLE1_YPOS, FONT_TITLE_1, getProgramTitleString());
-  DrawTextSCentered(MENU_TITLE2_YPOS, FONT_TITLE_2,
-                   setup.internal.program_copyright);
+  DrawTextSCentered(MENU_TITLE1_YPOS, FONT_TITLE_1, main_text_title_1);
+  DrawTextSCentered(MENU_TITLE2_YPOS, FONT_TITLE_2, main_text_title_2);
 }
 
 void DrawTitleScreenImage(int nr, boolean initial)
@@ -2135,7 +2145,7 @@ static void DrawCursorAndText_Menu_Ext(struct TokenInfo *token_info,
   int ypos = MENU_SCREEN_START_YPOS + screen_pos;
   int font_nr = getMenuTextFont(ti->type);
 
-  if (token_info == setup_info_input)
+  if (setup_mode == SETUP_MODE_INPUT)
     font_nr = FONT_MENU_1;
 
   if (active)
@@ -2593,9 +2603,9 @@ void DrawInfoScreen_NotAvailable(char *text_title, char *text_error)
   int font_foot  = MENU_INFO_FONT_FOOT;
   int spacing_title = menu.headline1_spacing_info[info_mode];
   int ystep_title = getMenuTextStep(spacing_title, font_title);
-  int ystart1 = mSY - SY + 100;
+  int ystart1 = mSY - SY + MENU_SCREEN_INFO_YSTART1;
   int ystart2 = ystart1 + ystep_title;
-  int ybottom = mSY - SY + SYSIZE - 20;
+  int ybottom = mSY - SY + MENU_SCREEN_INFO_YBOTTOM;
 
   SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO);
 
@@ -2619,7 +2629,7 @@ void DrawInfoScreen_HelpAnim(int start, int max_anims, boolean init)
   static int infoscreen_frame[MAX_INFO_ELEMENTS_ON_SCREEN];
   int font_title = MENU_INFO_FONT_TITLE;
   int font_foot  = MENU_INFO_FONT_FOOT;
-  int xstart = mSX + MENU_SCREEN_INFO_XSTART;
+  int xstart  = mSX + MENU_SCREEN_INFO_SPACE_LEFT;
   int ystart1 = mSY - SY + MENU_SCREEN_INFO_YSTART1;
   int ystart2 = mSY + MENU_SCREEN_INFO_YSTART2;
   int ybottom = mSY - SY + MENU_SCREEN_INFO_YBOTTOM;
@@ -2749,11 +2759,12 @@ void DrawInfoScreen_HelpText(int element, int action, int direction, int ypos)
   int font_width = getFontWidth(font_nr);
   int font_height = getFontHeight(font_nr);
   int yoffset = (TILEX - 2 * font_height) / 2;
-  int xstart = mSX + MINI_TILEX + TILEX + MINI_TILEX;
+  int xstart = mSX + MENU_SCREEN_INFO_SPACE_LEFT + TILEX + MINI_TILEX;
   int ystart = mSY + MENU_SCREEN_INFO_YSTART2 + yoffset;
   int ystep = TILEY + 4;
-  int pad_x = xstart - SX;
-  int max_chars_per_line = (SXSIZE - pad_x - MINI_TILEX) / font_width;
+  int pad_left = xstart - SX;
+  int pad_right = MENU_SCREEN_INFO_SPACE_RIGHT;
+  int max_chars_per_line = (SXSIZE - pad_left - pad_right) / font_width;
   int max_lines_per_text = 2;    
   char *text = NULL;
 
@@ -2912,8 +2923,8 @@ void HandleInfoScreen_Music(int button)
   int spacing_head  = menu.headline2_spacing_info[info_mode];
   int ystep_title = getMenuTextStep(spacing_title, font_title);
   int ystep_head  = getMenuTextStep(spacing_head,  font_head);
-  int ystart = mSY - SY + 100;
-  int ybottom = mSY - SY + SYSIZE - 20;
+  int ystart  = mSY - SY + MENU_SCREEN_INFO_YSTART1;
+  int ybottom = mSY - SY + MENU_SCREEN_INFO_YBOTTOM;
 
   if (button == MB_MENU_INITIALIZE)
   {
@@ -3074,8 +3085,8 @@ static void DrawInfoScreen_CreditsScreen(int screen_nr)
   int ystep_head  = getMenuTextStep(spacing_head,  font_head);
   int ystep_para  = getMenuTextStep(spacing_para,  font_text);
   int ystep_line  = getMenuTextStep(spacing_line,  font_text);
-  int ystart = mSY - SY + 100;
-  int ybottom = mSY - SY + SYSIZE - 20;
+  int ystart  = mSY - SY + MENU_SCREEN_INFO_YSTART1;
+  int ybottom = mSY - SY + MENU_SCREEN_INFO_YBOTTOM;
 
   ClearField();
   DrawHeadline();
@@ -3375,8 +3386,8 @@ void DrawInfoScreen_Program()
   int ystep_head  = getMenuTextStep(spacing_head,  font_head);
   int ystep_para  = getMenuTextStep(spacing_para,  font_text);
   int ystep_line  = getMenuTextStep(spacing_line,  font_text);
-  int ystart = mSY - SY + 100;
-  int ybottom = mSY - SY + SYSIZE - 20;
+  int ystart  = mSY - SY + MENU_SCREEN_INFO_YSTART1;
+  int ybottom = mSY - SY + MENU_SCREEN_INFO_YBOTTOM;
 
   SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_PROGRAM);
 
@@ -3461,8 +3472,8 @@ void DrawInfoScreen_Version()
   int ystep_head  = getMenuTextStep(spacing_head,  font_head);
   int ystep_para  = getMenuTextStep(spacing_para,  font_text);
   int ystep_line  = getMenuTextStep(spacing_line,  font_text);
-  int ystart  = mSY - SY + 100;
-  int ybottom = mSY - SY + SYSIZE - 20;
+  int ystart  = mSY - SY + MENU_SCREEN_INFO_YSTART1;
+  int ybottom = mSY - SY + MENU_SCREEN_INFO_YBOTTOM;
   int xstart1 = mSX - SX + 2 * xstep;
   int xstart2 = mSX - SX + 18 * xstep;
   int xstart3 = mSX - SX + 28 * xstep;
@@ -3648,8 +3659,8 @@ void DrawInfoScreen_LevelSet()
   struct TitleMessageInfo *tmi = &readme;
   char *filename = getLevelSetInfoFilename();
   char *title = "Level Set Information:";
-  int ystart = mSY - SY + 100;
-  int ybottom = mSY - SY + SYSIZE - 20;
+  int ystart  = mSY - SY + MENU_SCREEN_INFO_YSTART1;
+  int ybottom = mSY - SY + MENU_SCREEN_INFO_YBOTTOM;
 
   if (filename == NULL)
   {
@@ -3681,7 +3692,7 @@ void DrawInfoScreen_LevelSet()
 
   /* if height set to "-1", automatically determine by playfield height */
   if (tmi->height == -1)
-    tmi->height = SYSIZE - 20 - tmi->y - 10;
+    tmi->height = MENU_SCREEN_INFO_YBOTTOM - tmi->y - 10;
 
   /* if chars set to "-1", automatically determine by text and font width */
   if (tmi->chars == -1)
@@ -5646,6 +5657,7 @@ static struct TokenInfo setup_info_input[] =
   { TYPE_SWITCH,       NULL,                   "Player:"               },
   { TYPE_SWITCH,       NULL,                   "Device:"               },
   { TYPE_SWITCH,       NULL,                   ""                      },
+  { TYPE_SKIPPABLE,    NULL,                   ""                      },
   { TYPE_EMPTY,                NULL,                   ""                      },
   { TYPE_EMPTY,                NULL,                   ""                      },
   { TYPE_EMPTY,                NULL,                   ""                      },
@@ -5654,8 +5666,7 @@ static struct TokenInfo setup_info_input[] =
   { TYPE_EMPTY,                NULL,                   ""                      },
   { TYPE_EMPTY,                NULL,                   ""                      },
   { TYPE_EMPTY,                NULL,                   ""                      },
-  { TYPE_EMPTY,                NULL,                   ""                      },
-  { TYPE_EMPTY,                NULL,                   ""                      },
+  { TYPE_SKIPPABLE,    NULL,                   ""                      },
   { TYPE_LEAVE_MENU,   execSetupMain,          "Back"                  },
 
   { 0,                 NULL,                   NULL                    }
@@ -6023,8 +6034,18 @@ static struct TokenInfo *getSetupInfoFinal(struct TokenInfo *setup_info_orig)
 
   /* copy setup info list without setup entries marked as hidden */
   for (i = 0; setup_info_orig[i].type != 0; i++)
-    if (!hideSetupEntry(setup_info_orig[i].value))
-      setup_info_hide[list_pos++] = setup_info_orig[i];
+  {
+    /* skip setup entries configured to be hidden */
+    if (hideSetupEntry(setup_info_orig[i].value))
+      continue;
+
+    /* skip skippable setup entries if screen is lower than usual */
+    if (SCR_FIELDY < SCR_FIELDY_DEFAULT &&
+       setup_info_orig[i].type == TYPE_SKIPPABLE)
+      continue;
+
+    setup_info_hide[list_pos++] = setup_info_orig[i];
+  }
 
   return setup_info_hide;
 }
@@ -6171,11 +6192,11 @@ void DrawSetupScreen_Input()
 
   ClearField();
 
-  setup_info = setup_info_input;
+  setup_info = getSetupInfoFinal(setup_info_input);
 
   DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, STR_SETUP_INPUT);
 
-  for (i = 0; setup_info[i].type != 0 && i < MAX_MENU_ENTRIES_ON_SCREEN; i++)
+  for (i = 0; setup_info[i].type != 0; i++)
   {
     if (setup_info[i].type & (TYPE_ENTER_MENU|TYPE_ENTER_LIST))
       initCursor(i, IMG_MENU_BUTTON_ENTER_MENU);
@@ -6244,7 +6265,19 @@ static void drawPlayerSetupInputInfo(int player_nr, boolean active)
     "Joystick3",
     "Joystick4"
   };
-  int text_font_nr = (active ? FONT_MENU_1_ACTIVE : FONT_MENU_1);
+  int font_nr_menu = (active ? FONT_MENU_1_ACTIVE : FONT_MENU_1);
+  int font_nr_info = FONT_MENU_1;
+  int font_nr_name = FONT_VALUE_OLD;
+  int font_nr_on   = FONT_VALUE_1;
+  int font_nr_off  = FONT_VALUE_OLD;
+  int pos = 4;
+
+  if (SCR_FIELDX < SCR_FIELDX_DEFAULT)
+  {
+    font_nr_info = FONT_MENU_2;
+    font_nr_on   = FONT_VALUE_NARROW;
+    font_nr_off  = FONT_VALUE_OLD_NARROW;
+  }
 
   custom_key = setup.input[player_nr].key;
 
@@ -6262,41 +6295,44 @@ static void drawPlayerSetupInputInfo(int player_nr, boolean active)
     int joystick_nr = getJoystickNrFromDeviceName(device_name);
     boolean joystick_active = CheckJoystickOpened(joystick_nr);
     char *text = joystick_name[joystick_nr];
-    int font_nr = (joystick_active ? FONT_VALUE_1 : FONT_VALUE_OLD);
+    int font_nr = (joystick_active ? font_nr_on : font_nr_off);
 
     DrawText(mSX + 8 * 32, mSY + 3 * 32, text, font_nr);
-    DrawText(mSX + 32, mSY + 4 * 32, "Configure", text_font_nr);
+    DrawText(mSX + 32, mSY + 4 * 32, "Configure", font_nr_menu);
   }
   else
   {
-    DrawText(mSX + 8 * 32, mSY + 3 * 32, "Keyboard ", FONT_VALUE_1);
-    DrawText(mSX + 1 * 32, mSY + 4 * 32, "Customize", text_font_nr);
+    DrawText(mSX + 8 * 32, mSY + 3 * 32, "Keyboard ", font_nr_on);
+    DrawText(mSX + 1 * 32, mSY + 4 * 32, "Customize", font_nr_menu);
   }
 
-  DrawText(mSX + 32, mSY + 5 * 32, "Actual Settings:", FONT_MENU_1);
+  if (SCR_FIELDY >= SCR_FIELDY_DEFAULT)
+    DrawText(mSX + 32, mSY + 5 * 32, "Actual Settings:", font_nr_info);
+  else
+    pos = 3;
 
-  drawCursorXY(1, 4, IMG_MENU_BUTTON_LEFT);
-  drawCursorXY(1, 5, IMG_MENU_BUTTON_RIGHT);
-  drawCursorXY(1, 6, IMG_MENU_BUTTON_UP);
-  drawCursorXY(1, 7, IMG_MENU_BUTTON_DOWN);
+  drawCursorXY(1, pos + 0, IMG_MENU_BUTTON_LEFT);
+  drawCursorXY(1, pos + 1, IMG_MENU_BUTTON_RIGHT);
+  drawCursorXY(1, pos + 2, IMG_MENU_BUTTON_UP);
+  drawCursorXY(1, pos + 3, IMG_MENU_BUTTON_DOWN);
 
-  DrawText(mSX + 2 * 32, mSY +  6 * 32, ":", FONT_VALUE_OLD);
-  DrawText(mSX + 2 * 32, mSY +  7 * 32, ":", FONT_VALUE_OLD);
-  DrawText(mSX + 2 * 32, mSY +  8 * 32, ":", FONT_VALUE_OLD);
-  DrawText(mSX + 2 * 32, mSY +  9 * 32, ":", FONT_VALUE_OLD);
-  DrawText(mSX + 1 * 32, mSY + 10 * 32, "Snap Field:", FONT_VALUE_OLD);
-  DrawText(mSX + 1 * 32, mSY + 12 * 32, "Drop Element:", FONT_VALUE_OLD);
+  DrawText(mSX + 2 * 32, mSY + (pos + 2) * 32, ":", font_nr_name);
+  DrawText(mSX + 2 * 32, mSY + (pos + 3) * 32, ":", font_nr_name);
+  DrawText(mSX + 2 * 32, mSY + (pos + 4) * 32, ":", font_nr_name);
+  DrawText(mSX + 2 * 32, mSY + (pos + 5) * 32, ":", font_nr_name);
+  DrawText(mSX + 1 * 32, mSY + (pos + 6) * 32, "Snap Field:", font_nr_name);
+  DrawText(mSX + 1 * 32, mSY + (pos + 8) * 32, "Drop Element:", font_nr_name);
 
   for (i = 0; i < 6; i++)
   {
-    int ypos = 6 + i + (i > 3 ? i-3 : 0);
+    int ypos = (pos + 2) + i + (i > 3 ? i - 3 : 0);
 
     DrawText(mSX + 3 * 32, mSY + ypos * 32,
-            "              ", FONT_VALUE_1);
+            "              ", font_nr_on);
     DrawText(mSX + 3 * 32, mSY + ypos * 32,
             (setup.input[player_nr].use_joystick ?
              custom[i].text :
-             getKeyNameFromKey(*custom[i].key)), FONT_VALUE_1);
+             getKeyNameFromKey(*custom[i].key)), font_nr_on);
   }
 }
 
@@ -6331,8 +6367,27 @@ void HandleSetupScreen_Input(int mx, int my, int dx, int dy, int button)
   int pos_empty2 = SETUPINPUT_SCREEN_POS_EMPTY2;
   int pos_end    = SETUPINPUT_SCREEN_POS_END;
 
+  if (SCR_FIELDY < SCR_FIELDY_DEFAULT)
+  {
+    int i;
+
+    for (i = 0; setup_info_input[i].type != 0; i++)
+    {
+      /* adjust menu structure according to skipped setup entries */
+      if (setup_info_input[i].type == TYPE_SKIPPABLE)
+      {
+       pos_empty2--;
+       pos_end--;
+      }
+    }
+  }
+
   if (button == MB_MENU_INITIALIZE)
   {
+    /* input setup menu may have changed size due to graphics configuration */
+    if (choice >= pos_empty1)
+      choice = pos_end;
+
     drawPlayerSetupInputInfo(input_player_nr, (choice == 2));
 
     DrawCursorAndText_Setup(choice, -1, TRUE);
@@ -6433,7 +6488,7 @@ void HandleSetupScreen_Input(int mx, int my, int dx, int dy, int button)
   }
 }
 
-void CustomizeKeyboard(int player_nr)
+static boolean CustomizeKeyboardMain(int player_nr)
 {
   int i;
   int step_nr;
@@ -6452,6 +6507,15 @@ void CustomizeKeyboard(int player_nr)
     { &custom_key.snap,  "Snap Field"  },
     { &custom_key.drop,  "Drop Element"        }
   };
+  int font_nr_old = FONT_VALUE_OLD;
+  int font_nr_new = FONT_VALUE_1;
+  int success = FALSE;
+
+  if (SCR_FIELDX < SCR_FIELDX_DEFAULT)
+  {
+    font_nr_old = FONT_VALUE_OLD_NARROW;
+    font_nr_new = FONT_VALUE_NARROW;
+  }
 
   /* read existing key bindings from player setup */
   custom_key = setup.input[player_nr].key;
@@ -6469,7 +6533,7 @@ void CustomizeKeyboard(int player_nr)
   DrawText(mSX, mSY + (2 + 2 * step_nr + 1) * 32,
           "Key:", FONT_INPUT_1_ACTIVE);
   DrawText(mSX + 4 * 32, mSY + (2 + 2 * step_nr + 1) * 32,
-          getKeyNameFromKey(*customize_step[step_nr].key), FONT_VALUE_OLD);
+          getKeyNameFromKey(*customize_step[step_nr].key), font_nr_old);
 
   FadeIn(REDRAW_FIELD);
 
@@ -6485,18 +6549,15 @@ void CustomizeKeyboard(int player_nr)
          {
            Key key = GetEventKey((KeyEvent *)&event, FALSE);
 
-           if (key == KSYM_Escape || (key == KSYM_Return && step_nr == 6))
+           /* press 'Escape' to abort and keep the old key bindings */
+           if (key == KSYM_Escape)
            {
-             if (key == KSYM_Escape)
-               FadeSkipNextFadeIn();
+             FadeSkipNextFadeIn();
 
              finished = TRUE;
-             break;
-           }
 
-           /* all keys configured -- wait for "Escape" or "Return" key */
-           if (step_nr == 6)
              break;
+           }
 
            /* press 'Enter' to keep the existing key binding */
            if (key == KSYM_Return)
@@ -6512,9 +6573,9 @@ void CustomizeKeyboard(int player_nr)
            /* got new key binding */
            *customize_step[step_nr].key = key;
            DrawText(mSX + 4 * 32, mSY + (2 + 2 * step_nr + 1) * 32,
-                    "             ", FONT_VALUE_1);
+                    "             ", font_nr_new);
            DrawText(mSX + 4 * 32, mSY + (2 + 2 * step_nr + 1) * 32,
-                    getKeyNameFromKey(key), FONT_VALUE_1);
+                    getKeyNameFromKey(key), font_nr_new);
            step_nr++;
 
            /* un-highlight last query */
@@ -6523,11 +6584,12 @@ void CustomizeKeyboard(int player_nr)
            DrawText(mSX, mSY + (2 + 2 * (step_nr - 1) + 1) * 32,
                     "Key:", FONT_MENU_1);
 
-           /* press 'Enter' to leave */
+           /* all keys configured */
            if (step_nr == 6)
            {
-             DrawText(mSX + 16, mSY + 15 * 32 + 16,
-                      "Press Enter", FONT_TITLE_1);
+             finished = TRUE;
+             success = TRUE;
+
              break;
            }
 
@@ -6538,7 +6600,7 @@ void CustomizeKeyboard(int player_nr)
                     "Key:", FONT_INPUT_1_ACTIVE);
            DrawText(mSX + 4 * 32, mSY + (2 + 2 * step_nr + 1) * 32,
                     getKeyNameFromKey(*customize_step[step_nr].key),
-                    FONT_VALUE_OLD);
+                    font_nr_old);
          }
          break;
 
@@ -6555,8 +6617,38 @@ void CustomizeKeyboard(int player_nr)
     BackToFront();
   }
 
-  /* write new key bindings back to player setup */
-  setup.input[player_nr].key = custom_key;
+  /* write new key bindings back to player setup, if successfully finished */
+  if (success)
+    setup.input[player_nr].key = custom_key;
+
+  return success;
+}
+
+void CustomizeKeyboard(int player_nr)
+{
+  boolean success = CustomizeKeyboardMain(player_nr);
+
+  if (success)
+  {
+    int font_nr = FONT_TITLE_1;
+    int font_height = getFontHeight(font_nr);
+    int ypos1 = SYSIZE / 2 - font_height * 2;
+    int ypos2 = SYSIZE / 2 - font_height * 1;
+    unsigned int wait_frame_delay = 0;
+    unsigned int wait_frame_delay_value = 2000;
+
+    ResetDelayCounter(&wait_frame_delay);
+
+    ClearField();
+
+    DrawTextSCentered(ypos1, font_nr, "Keyboard");
+    DrawTextSCentered(ypos2, font_nr, "configured!");
+
+    while (!DelayReached(&wait_frame_delay, wait_frame_delay_value))
+      BackToFront();
+
+    ClearEventQueue();
+  }
 
   DrawSetupScreen_Input();
 }
@@ -6968,11 +7060,14 @@ void ConfigureJoystick(int player_nr)
   if (state != JOYSTICK_NOT_CONFIGURED)
   {
     boolean success = (state == JOYSTICK_CONFIGURED);
-    char *message = (success ? " IS CONFIGURED! " : " NOT AVAILABLE! ");
+    char message1[MAX_OUTPUT_LINESIZE + 1];
+    char *message2 = (success ? "configured!" : "not available!");
     char *device_name = setup.input[player_nr].joy.device_name;
     int nr = getJoystickNrFromDeviceName(device_name) + 1;
-    int xpos = mSX - SX;
-    int ypos = mSY - SY;
+    int font_nr = FONT_TITLE_1;
+    int font_height = getFontHeight(font_nr);
+    int ypos1 = SYSIZE / 2 - font_height * 2;
+    int ypos2 = SYSIZE / 2 - font_height * 1;
     unsigned int wait_frame_delay = 0;
     unsigned int wait_frame_delay_value = 2000;
 
@@ -6980,8 +7075,10 @@ void ConfigureJoystick(int player_nr)
 
     ClearField();
 
-    DrawTextF(xpos + 16, ypos + 6 * 32, FONT_TITLE_1, "   JOYSTICK %d   ", nr);
-    DrawTextF(xpos + 16, ypos + 7 * 32, FONT_TITLE_1, message);
+    sprintf(message1, "Joystick %d", nr);
+
+    DrawTextSCentered(ypos1, font_nr, message1);
+    DrawTextSCentered(ypos2, font_nr, message2);
 
     while (!DelayReached(&wait_frame_delay, wait_frame_delay_value))
       BackToFront();
@@ -7084,6 +7181,9 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button)
 
 void HandleGameActions()
 {
+  if (game.restart_game_message != NULL)
+    RequestRestartGame(game.restart_game_message);
+
   if (game_status != GAME_MODE_PLAYING)
     return;