From: Holger Schemel Date: Wed, 6 Apr 2022 13:01:24 +0000 (+0200) Subject: added playing score tape from score info page X-Git-Tag: 4.3.2.0~38 X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=commitdiff_plain;h=84b4d1874b7dfed42ace079941a65baea0ac4ff6 added playing score tape from score info page --- diff --git a/src/game.c b/src/game.c index f7392fe4..726e60ac 100644 --- a/src/game.c +++ b/src/game.c @@ -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?"); diff --git a/src/main.c b/src/main.c index a5e8a58e..07883459 100644 --- a/src/main.c +++ b/src/main.c @@ -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; diff --git a/src/main.h b/src/main.h index 00ce3cd2..cd272322 100644 --- a/src/main.h +++ b/src/main.h @@ -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; diff --git a/src/screens.c b/src/screens.c index 92a9466c..3f018621 100644 --- a/src/screens.c +++ b/src/screens.c @@ -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) diff --git a/src/tape.c b/src/tape.c index d93c6632..e0491485 100644 --- a/src/tape.c +++ b/src/tape.c @@ -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) && diff --git a/src/tape.h b/src/tape.h index b418ea33..c3b3a6de 100644 --- a/src/tape.h +++ b/src/tape.h @@ -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);