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)
// 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);
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)
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?");
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;
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;
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);
static void DrawScoreInfo(int entry_nr)
{
scores.last_entry_nr = entry_nr;
+ score_info_tape_play = FALSE;
SetMainBackgroundImageIfDefined(IMG_BACKGROUND_SCOREINFO);
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)
#include "files.h"
#include "network.h"
#include "anim.h"
+#include "api.h"
+
#define DEBUG_TAPE_WHEN_PLAYING FALSE
static void TapeStopGameOrTape(boolean stop_game)
{
- if (!tape.playing && stop_game)
+ if (score_info_tape_play || (!tape.playing && stop_game))
RequestQuitGame(FALSE);
else
TapeStop();
void TapeRestartGame(void)
{
+ if (score_info_tape_play)
+ {
+ TapeStartGamePlaying();
+
+ return;
+ }
+
if (!checkRestartGame("Restart game?"))
return;
void TapeReplayAndPauseBeforeEnd(void)
{
+ if (score_info_tape_play)
+ return;
+
if (TAPE_IS_EMPTY(tape) && !tape.recording)
{
Request("No tape for this level!", REQ_CONFIRM);
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) &&
boolean hasSolutionTape(void);
boolean InsertSolutionTape(void);
boolean PlaySolutionTape(void);
+boolean PlayScoreTape(int);
void UndoTape(void);
void FixTape_ForceSinglePlayer(void);