fixed (not) resuming game from hall of fame after playing
[rocksndiamonds.git] / src / screens.c
index 048359fe13c54e0ed4b59a0dfd9938651bb544fa..7fed3310e23c45aea463bdf95a64130003b76e3b 100644 (file)
@@ -302,7 +302,7 @@ static void UnmapScreenTreeGadgets(void);
 
 static void UpdateScreenMenuGadgets(int, boolean);
 static void AdjustScoreInfoButtons_SelectScore(int, int, int);
-static void AdjustScoreInfoButtons_PlayTape(int, int);
+static void AdjustScoreInfoButtons_PlayTape(int, int, boolean);
 
 static boolean OfferUploadTapes(void);
 static void execOfferUploadTapes(void);
@@ -312,6 +312,8 @@ static void HandleHallOfFame_SelectLevel(int, int);
 static char *getHallOfFameRankText(int, int);
 static char *getHallOfFameScoreText(int, int);
 
+static struct TokenInfo *getSetupInfoFinal(struct TokenInfo *);
+
 static struct GadgetInfo *screen_gadget[NUM_SCREEN_GADGETS];
 
 static int info_mode = INFO_MODE_MAIN;
@@ -1693,6 +1695,18 @@ void DrawMainMenu(void)
     return;
   }
 
+  // needed if last screen was the playing screen, invoked from hall of fame
+  if (score_info_tape_play)
+  {
+    CloseDoor(DOOR_CLOSE_ALL);
+
+    SetGameStatus(GAME_MODE_SCOREINFO);
+
+    DrawScoreInfo(scores.last_entry_nr);
+
+    return;
+  }
+
   // leveldir_current may be invalid (level group, parent link, node copy)
   leveldir_current = getValidLevelSeries(leveldir_current, leveldir_last_valid);
 
@@ -2545,6 +2559,9 @@ static void DrawInfoScreen_Main(void)
 
   info_info = info_info_main;
 
+  // use modified info screen info without info screen entries marked as hidden
+  info_info = getSetupInfoFinal(info_info);
+
   // determine maximal number of info entries that can be displayed on screen
   num_info_info = 0;
   for (i = 0; info_info[i].type != 0 && i < NUM_MENU_ENTRIES_ON_SCREEN; i++)
@@ -4761,6 +4778,8 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
 
   if (mx || my)                // mouse input
   {
+    scores.was_just_playing = FALSE;
+
     x = (mx - amSX) / 32;
     y = (my - amSY) / 32 - MENU_SCREEN_START_YPOS;
 
@@ -4769,6 +4788,8 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
   }
   else if (dx || dy)   // keyboard or scrollbar/scrollbutton input
   {
+    scores.was_just_playing = FALSE;
+
     // move cursor instead of scrolling when already at start/end of list
     if (dy == -1 * SCROLL_LINE && ti->cl_first == 0)
       dy = -1;
@@ -5037,16 +5058,16 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
          }
          else if (game_status == GAME_MODE_SCORES)
          {
-           if (game_status_last_screen == GAME_MODE_PLAYING &&
-               setup.auto_play_next_level && setup.increment_levels &&
+           if (setup.auto_play_next_level && setup.increment_levels &&
                scores.last_level_nr < leveldir_current->last_level &&
+               scores.was_just_playing &&
                !network_playing)
            {
              StartGameActions(network.enabled, setup.autorecord,
                               level.random_seed);
              return;
            }
-           else
+           else if (!scores.was_just_playing)
            {
              SetGameStatus(GAME_MODE_SCOREINFO);
 
@@ -5246,6 +5267,7 @@ static void DrawHallOfFame_setScoreEntries(void)
 void DrawHallOfFame(int level_nr)
 {
   scores.last_level_nr = level_nr;
+  scores.was_just_playing = (game_status_last_screen == GAME_MODE_PLAYING);
 
   // (this is needed when called from GameEnd() after winning a game)
   KeyboardAutoRepeatOn();
@@ -5374,6 +5396,7 @@ static void DrawScoreInfo_Content(int entry_nr)
   int select_y1, select_y2;
   int play_x, play_y;
   int play_height = screen_gadget[SCREEN_CTRL_ID_PLAY_TAPE]->height;
+  boolean play_visible = (entry->id != -1);
   int font_width = getFontWidth(font_text);
   int font_height = getFontHeight(font_text);
   int tape_date_width  = getTextWidth(entry->tape_date, font_text);
@@ -5472,12 +5495,13 @@ static void DrawScoreInfo_Content(int entry_nr)
   DrawTextSCentered(ybottom, font_foot, "Press any key or button to go back");
 
   AdjustScoreInfoButtons_SelectScore(select_x, select_y1, select_y2);
-  AdjustScoreInfoButtons_PlayTape(play_x, play_y);
+  AdjustScoreInfoButtons_PlayTape(play_x, play_y, play_visible);
 }
 
 static void DrawScoreInfo(int entry_nr)
 {
   scores.last_entry_nr = entry_nr;
+  score_info_tape_play = FALSE;
 
   SetMainBackgroundImageIfDefined(IMG_BACKGROUND_SCOREINFO);
 
@@ -5485,6 +5509,9 @@ static void DrawScoreInfo(int entry_nr)
 
   FadeOut(REDRAW_FIELD);
 
+  // needed if different viewport properties defined after playing score tape
+  ChangeViewportPropertiesIfNeeded();
+
   DrawScoreInfo_Content(entry_nr);
 
   // map gadgets for score info screen
@@ -5515,6 +5542,12 @@ static void HandleScoreInfo_SelectScore(int step, int direction)
 
 static void HandleScoreInfo_PlayTape(void)
 {
+  if (!PlayScoreTape(scores.last_entry_nr))
+  {
+    DrawScoreInfo_Content(scores.last_entry_nr);
+
+    FadeIn(REDRAW_FIELD);
+  }
 }
 
 void HandleScoreInfo(int mx, int my, int dx, int dy, int button)
@@ -5541,7 +5574,7 @@ void HandleScoreInfo(int mx, int my, int dx, int dy, int button)
 
     SetGameStatus(GAME_MODE_SCORES);
 
-    DrawHallOfFame(level_nr);
+    DrawHallOfFame(scores.last_level_nr);
   }
   else if (dx)
   {
@@ -7133,6 +7166,15 @@ static struct
   { &setup.internal.menu_exit,         execExitSetup                   },
   { &setup.internal.menu_save_and_exit,        execSaveAndExitSetup            },
 
+  { &setup.internal.info_title,                execInfoTitleScreen             },
+  { &setup.internal.info_elements,     execInfoElements                },
+  { &setup.internal.info_music,                execInfoMusic                   },
+  { &setup.internal.info_credits,      execInfoCredits                 },
+  { &setup.internal.info_program,      execInfoProgram                 },
+  { &setup.internal.info_version,      execInfoVersion                 },
+  { &setup.internal.info_levelset,     execInfoLevelSet                },
+  { &setup.internal.info_exit,         execExitInfo                    },
+
   { NULL,                              NULL                            }
 };
 
@@ -9997,13 +10039,17 @@ static void AdjustScoreInfoButtons_SelectScore(int x, int y1, int y2)
     ModifyGadget(gi_2, GDI_X, x, GDI_Y, y2, GDI_END);
 }
 
-static void AdjustScoreInfoButtons_PlayTape(int x, int y)
+static void AdjustScoreInfoButtons_PlayTape(int x, int y, boolean visible)
 {
   struct GadgetInfo *gi = screen_gadget[SCREEN_CTRL_ID_PLAY_TAPE];
   struct MenuPosInfo *pos = menubutton_info[SCREEN_CTRL_ID_PLAY_TAPE].pos;
 
-  if (pos->x == -1 && pos->y == -1)
-    ModifyGadget(gi, GDI_X, x, GDI_Y, y, GDI_END);
+  // set gadget position dynamically, pre-defined or off-screen
+  int xx = (visible ? (pos->x == -1 ? x : pos->x) : POS_OFFSCREEN);
+  int yy = (visible ? (pos->y == -1 ? y : pos->y) : POS_OFFSCREEN);
+
+  ModifyGadget(gi, GDI_X, xx, GDI_Y, yy, GDI_END);
+  MapGadget(gi);       // (needed if deactivated on last score page)
 }
 
 static void HandleScreenGadgets(struct GadgetInfo *gi)