X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftape.c;h=ff0da179bf632f0185b8fd056201079c4a257180;hb=02ff4fe225b552d69ddd7ba7d51787f473389dd3;hp=cd07263f007f2e4842c1395e13a5c17f6d6adecf;hpb=d0c35d05e88d7c3761c074135af990fc14302ace;p=rocksndiamonds.git diff --git a/src/tape.c b/src/tape.c index cd07263f..ff0da179 100644 --- a/src/tape.c +++ b/src/tape.c @@ -629,6 +629,30 @@ static void CloseTapeLogfile(void) // tape control functions // ============================================================================ +void TapeSetDateFromIsoDateString(char *date) +{ + int i; + + // check ISO date string for correct length + if (strlen(date) != 10) + return; + + // check ISO date string for correct format + for (i = 0; i < strlen(date); i++) + if (((i != 4 && i != 7) && (date[i] < '0' || date[i] > '9')) || + ((i == 4 || i == 7) && (date[i] != '-'))) + return; + + int yy = (date[2] - '0') * 10 + (date[3] - '0'); + int mm = (date[5] - '0') * 10 + (date[6] - '0'); + int dd = (date[8] - '0') * 10 + (date[9] - '0'); + + if (mm < 1 || mm > 12 || dd < 1 || dd > 31) + return; + + tape.date = 10000 * yy + 100 * (mm - 1) + dd; +} + void TapeSetDateFromEpochSeconds(time_t epoch_seconds) { struct tm *lt = localtime(&epoch_seconds); @@ -664,6 +688,7 @@ void TapeErase(void) tape.level_nr = level_nr; tape.pos[tape.counter].delay = 0; tape.changed = TRUE; + tape.solved = FALSE; tape.random_seed = InitRND(level.random_seed); @@ -673,6 +698,8 @@ void TapeErase(void) tape.property_bits = TAPE_PROPERTY_NONE; + tape.bd_replay = FALSE; + TapeSetDateFromNow(); for (i = 0; i < MAX_PLAYERS; i++) @@ -760,6 +787,7 @@ static void TapeAppendRecording(void) // start recording tape.recording = TRUE; tape.changed = TRUE; + tape.solved = FALSE; // set current delay (for last played move) tape.pos[tape.counter].delay = tape.delay_played; @@ -777,7 +805,9 @@ static void TapeAppendRecording(void) void TapeHaltRecording(void) { - tape.counter++; + // only advance tape counter if any input events have been recorded + if (tape.pos[tape.counter].delay > 0) + tape.counter++; // initialize delay for next tape entry (to be able to continue recording) if (tape.counter < MAX_TAPE_LEN) @@ -832,6 +862,8 @@ boolean TapeAddAction(byte action[MAX_TAPE_ACTIONS]) tape.pos[tape.counter].delay++; } + tape.changed = TRUE; + return TRUE; } @@ -843,6 +875,9 @@ void TapeRecordAction(byte action_raw[MAX_TAPE_ACTIONS]) if (!tape.recording) // (record action even when tape is paused) return; + if (!checkGameRunning()) + return; + for (i = 0; i < MAX_TAPE_ACTIONS; i++) action[i] = action_raw[i]; @@ -930,6 +965,10 @@ void TapeTogglePause(boolean toggle_mode) ModifyPauseButtons(); } + + // stop tape when leaving auto-pause after completely replaying tape + if (tape.playing && !tape.pausing && tape.counter >= tape.length) + TapeStop(); } void TapeStartPlaying(void) @@ -974,7 +1013,7 @@ void TapeStopPlaying(void) MapTapeEjectButton(); } -byte *TapePlayAction(void) +byte *TapePlayActionExt(boolean bd_replay) { int update_delay = FRAMES_PER_SECOND / 2; boolean update_video_display = (FrameCounter % update_delay == 0); @@ -985,6 +1024,12 @@ byte *TapePlayAction(void) if (!tape.playing || tape.pausing) return NULL; + if (!checkGameRunning()) + return NULL; + + if (tape.bd_replay && !bd_replay) + return NULL; + if (tape.pause_before_end) // stop some seconds before end of tape { if (TapeTime > (int)tape.length_seconds - TAPE_PAUSE_SECONDS_BEFORE_DEATH) @@ -992,16 +1037,22 @@ byte *TapePlayAction(void) TapeStopWarpForward(); TapeTogglePause(TAPE_TOGGLE_MANUAL); + if (setup.autorecord_after_replay) + TapeAppendRecording(); + return NULL; } } if (tape.counter >= tape.length) // end of tape reached { - if (tape.warp_forward && !tape.auto_play) + if (!tape.auto_play) { TapeStopWarpForward(); TapeTogglePause(TAPE_TOGGLE_MANUAL); + + if (setup.autorecord_after_replay) + TapeAppendRecording(); } else { @@ -1057,7 +1108,7 @@ byte *TapePlayAction(void) } tape.delay_played++; - if (tape.delay_played >= tape.pos[tape.counter].delay) + if (tape.delay_played >= tape.pos[tape.counter].delay || tape.bd_replay) { tape.counter++; tape.delay_played = 0; @@ -1072,6 +1123,34 @@ byte *TapePlayAction(void) return action; } +byte *TapePlayAction_BD(void) +{ + return TapePlayActionExt(TRUE); +} + +byte *TapePlayAction(void) +{ + return TapePlayActionExt(FALSE); +} + +byte *TapeCorrectAction_BD(byte *action) +{ + if (tape.playing) + { + // only read next tape action if not playing native BD replay + if (!TapeIsPlaying_ReplayBD()) + action = TapePlayAction(); + } + else if (tape.recording) + { + byte tape_action[MAX_TAPE_ACTIONS] = { action[0] }; + + TapeRecordAction(tape_action); + } + + return action; +} + void TapeStop(void) { if (tape.pausing) @@ -1177,22 +1256,25 @@ static void TapeSingleStep(void) void TapeQuickSave(void) { - if (game_status == GAME_MODE_MAIN) + if (game_status != GAME_MODE_PLAYING) { - Request("No game that can be saved!", REQ_CONFIRM); + Request("No game that could be saved!", REQ_CONFIRM); return; } - if (game_status != GAME_MODE_PLAYING) + if (!tape.recording) + { + Request("No recording that could be saved!", REQ_CONFIRM); + return; + } - if (tape.recording) - TapeHaltRecording(); // prepare tape for saving on-the-fly + TapeHaltRecording(); // prepare tape for saving on-the-fly if (TAPE_IS_EMPTY(tape)) { - Request("No tape that can be saved!", REQ_CONFIRM); + Request("No tape that could be saved!", REQ_CONFIRM); return; } @@ -1304,6 +1386,10 @@ void TapeRestartGame(void) if (!checkRestartGame("Restart game?")) return; + // when using BD game engine, cover screen before fading out + if (level.game_engine_type == GAME_ENGINE_TYPE_BD) + game_bd.cover_screen = TRUE; + StartGameActions(network.enabled, setup.autorecord, level.random_seed); } @@ -1330,11 +1416,18 @@ void TapeReplayAndPauseBeforeEnd(void) tape.quick_resume = TRUE; } +boolean TapeIsPlaying_ReplayBD(void) +{ + return (tape.playing && tape.bd_replay); +} + boolean hasSolutionTape(void) { boolean tape_file_exists = fileExists(getSolutionTapeFilename(level_nr)); - boolean level_has_tape = (level.game_engine_type == GAME_ENGINE_TYPE_SP && - level.native_sp_level->demo.is_available); + boolean level_has_tape = ((level.game_engine_type == GAME_ENGINE_TYPE_BD && + level.native_bd_level->replay != NULL) || + (level.game_engine_type == GAME_ENGINE_TYPE_SP && + level.native_sp_level->demo.is_available)); return (tape_file_exists || level_has_tape); } @@ -1380,15 +1473,14 @@ boolean PlaySolutionTape(void) static boolean PlayScoreTape_WaitForDownload(void) { - unsigned int download_delay = 0; - unsigned int download_delay_value = 10000; + DelayCounter download_delay = { 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)) + if (DelayReached(&download_delay)) return FALSE; UPDATE_BUSY_STATE_NOT_LOADING(); @@ -1578,15 +1670,14 @@ static void AutoPlayTapes_SetScoreEntry(int score, int time) static boolean AutoPlayTapes_WaitForUpload(void) { - unsigned int upload_delay = 0; - unsigned int upload_delay_value = 10000; + DelayCounter upload_delay = { 10000 }; ResetDelayCounter(&upload_delay); // wait for score tape to be successfully uploaded (and fail on timeout) while (!server_scores.uploaded) { - if (DelayReached(&upload_delay, upload_delay_value)) + if (DelayReached(&upload_delay)) { PrintNoLog("\r"); Print("- uploading score tape to score server - TIMEOUT.\n");