added playing score tape from score info page
authorHolger Schemel <info@artsoft.org>
Wed, 6 Apr 2022 13:01:24 +0000 (15:01 +0200)
committerHolger Schemel <info@artsoft.org>
Wed, 6 Apr 2022 13:01:24 +0000 (15:01 +0200)
src/game.c
src/main.c
src/main.h
src/screens.c
src/tape.c
src/tape.h

index f7392fe400f49bdc4b3b47b8cae54a7c01b98851..726e60ac26faff6f70a5331e8e73f5a092ddf67e 100644 (file)
@@ -4997,7 +4997,7 @@ void GameEnd(void)
 
   game.LevelSolved_GameEnd = TRUE;
 
-  if (game.LevelSolved_SaveTape)
+  if (game.LevelSolved_SaveTape && !score_info_tape_play)
   {
     // make sure that request dialog to save tape does not open door again
     if (!global.use_envelope_request)
@@ -5013,7 +5013,7 @@ void GameEnd(void)
   // if no tape is to be saved, close both doors simultaneously
   CloseDoor(DOOR_CLOSE_ALL);
 
-  if (level_editor_test_game)
+  if (level_editor_test_game || score_info_tape_play)
   {
     SetGameStatus(GAME_MODE_MAIN);
 
@@ -15679,7 +15679,7 @@ void RequestQuitGameExt(boolean skip_request, boolean quick_quit, char *message)
       SetOverlayActive(FALSE);
 
       // door may still be open due to skipped or envelope style request
-      CloseDoor(DOOR_CLOSE_1);
+      CloseDoor(score_info_tape_play ? DOOR_CLOSE_ALL : DOOR_CLOSE_1);
     }
 
     if (network.enabled)
@@ -15712,7 +15712,7 @@ void RequestQuitGame(boolean escape_key_pressed)
   boolean quick_quit = ((escape_key_pressed && !ask_on_escape) ||
                        level_editor_test_game);
   boolean skip_request = (game.all_players_gone || !setup.ask_on_quit_game ||
-                         quick_quit);
+                         quick_quit || score_info_tape_play);
 
   RequestQuitGameExt(skip_request, quick_quit,
                     "Do you really want to quit the game?");
index a5e8a58e8ddcf06878c005a70662557871080a2d..0788345993944f363825f4ca4744ae852812f5b8 100644 (file)
@@ -32,6 +32,7 @@ DrawBuffer           *drawto_field;
 int                    game_status = -1;
 int                    game_status_last_screen = -1;
 boolean                        level_editor_test_game = FALSE;
+boolean                        score_info_tape_play = FALSE;
 boolean                        network_playing = FALSE;
 
 int                    key_joystick_mapping = 0;
index 00ce3cd258883d8ec0e909b5417fee53e7ef8692..cd272322f63e9d67f5f2de45922a2a3617bf8e98 100644 (file)
@@ -3762,6 +3762,7 @@ extern DrawBuffer        *drawto_field;
 extern int                     game_status;
 extern int                     game_status_last_screen;
 extern boolean                 level_editor_test_game;
+extern boolean                 score_info_tape_play;
 extern boolean                 network_playing;
 
 extern int                     key_joystick_mapping;
index 92a9466ca0053ae1eb96454d031ec07cabb9510c..3f0186216a765e9d257aeba3212b58d67933e1ce 100644 (file)
@@ -1693,6 +1693,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);
 
@@ -5479,6 +5491,7 @@ static void DrawScoreInfo_Content(int entry_nr)
 static void DrawScoreInfo(int entry_nr)
 {
   scores.last_entry_nr = entry_nr;
+  score_info_tape_play = FALSE;
 
   SetMainBackgroundImageIfDefined(IMG_BACKGROUND_SCOREINFO);
 
@@ -5516,6 +5529,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)
index d93c6632a97e7f2112db654aec44c700f6987b6a..e0491485339bab365025f3fc24363b5c6c656eb7 100644 (file)
@@ -18,6 +18,8 @@
 #include "files.h"
 #include "network.h"
 #include "anim.h"
+#include "api.h"
+
 
 #define DEBUG_TAPE_WHEN_PLAYING                        FALSE
 
@@ -1090,7 +1092,7 @@ void TapeStop(void)
 
 static void TapeStopGameOrTape(boolean stop_game)
 {
-  if (!tape.playing && stop_game)
+  if (score_info_tape_play || (!tape.playing && stop_game))
     RequestQuitGame(FALSE);
   else
     TapeStop();
@@ -1292,6 +1294,13 @@ static boolean checkRestartGame(char *message)
 
 void TapeRestartGame(void)
 {
+  if (score_info_tape_play)
+  {
+    TapeStartGamePlaying();
+
+    return;
+  }
+
   if (!checkRestartGame("Restart game?"))
     return;
 
@@ -1300,6 +1309,9 @@ void TapeRestartGame(void)
 
 void TapeReplayAndPauseBeforeEnd(void)
 {
+  if (score_info_tape_play)
+    return;
+
   if (TAPE_IS_EMPTY(tape) && !tape.recording)
   {
     Request("No tape for this level!", REQ_CONFIRM);
@@ -1366,6 +1378,93 @@ boolean PlaySolutionTape(void)
   return TRUE;
 }
 
+static void PlayScoreTape_UpdateBusyState(void)
+{
+  int game_status_last = game_status;
+
+  SetGameStatus(GAME_MODE_LOADING);
+
+  UPDATE_BUSY_STATE();
+
+  SetGameStatus(game_status_last);
+}
+
+static boolean PlayScoreTape_WaitForDownload(void)
+{
+  unsigned int download_delay = 0;
+  unsigned int download_delay_value = 10000;
+
+  ResetDelayCounter(&download_delay);
+
+  // wait for score tape to be successfully downloaded (and fail on timeout)
+  while (!server_scores.tape_downloaded)
+  {
+    if (DelayReached(&download_delay, download_delay_value))
+      return FALSE;
+
+    PlayScoreTape_UpdateBusyState();
+
+    Delay(20);
+  }
+
+  return TRUE;
+}
+
+boolean PlayScoreTape(int entry_nr)
+{
+  struct ScoreEntry *entry = &scores.entry[entry_nr];
+  char *tape_filename = getScoreTapeFilename(entry->tape_basename, level_nr);
+  boolean download_tape = (!fileExists(tape_filename));
+
+  if (entry->id == -1)
+    return FALSE;
+
+  server_scores.tape_downloaded = FALSE;
+
+  if (download_tape)
+    ApiGetScoreTapeAsThread(level_nr, entry->id, entry->tape_basename);
+
+  SetGameStatus(GAME_MODE_PLAYING);
+
+  FadeOut(REDRAW_FIELD);
+
+  if (download_tape && !PlayScoreTape_WaitForDownload())
+  {
+    SetGameStatus(GAME_MODE_SCOREINFO);
+    ClearField();
+
+    Request("Cannot download score tape from score server!", REQ_CONFIRM);
+
+    return FALSE;
+  }
+
+  if (!TAPE_IS_STOPPED(tape))
+    TapeStop();
+
+  // if tape recorder already contains a tape, remove it without asking
+  TapeErase();
+
+  LoadScoreTape(entry->tape_basename, level_nr);
+
+  if (TAPE_IS_EMPTY(tape))
+  {
+    SetGameStatus(GAME_MODE_SCOREINFO);
+    ClearField();
+
+    Request("Cannot load score tape for this level!", REQ_CONFIRM);
+
+    return FALSE;
+  }
+
+  FadeSkipNextFadeOut();
+
+  TapeStartGamePlaying();
+
+  score_info_tape_play = TRUE;
+
+  return TRUE;
+}
+
 static boolean checkTapesFromSameLevel(struct TapeInfo *t1, struct TapeInfo *t2)
 {
   return (strEqual(t1->level_identifier, t2->level_identifier) &&
index b418ea33058a111bc78c92618c181bd4e6ef31a0..c3b3a6deaab4af8452a12521572b5d73159c4f90 100644 (file)
@@ -276,6 +276,7 @@ void TapeReplayAndPauseBeforeEnd(void);
 boolean hasSolutionTape(void);
 boolean InsertSolutionTape(void);
 boolean PlaySolutionTape(void);
+boolean PlayScoreTape(int);
 
 void UndoTape(void);
 void FixTape_ForceSinglePlayer(void);