X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftape.c;h=2c0661a0871f4f5cbf1d6fc9991f98d500655ca4;hb=ed2846d97bd8b22246cb522d0de1ac73a040b414;hp=5e8746df2384c48d23ad92fba19010b96c4a6eeb;hpb=79ee4446132fd0081c8d78c51c72d8620b5e1e2b;p=rocksndiamonds.git diff --git a/src/tape.c b/src/tape.c index 5e8746df..2c0661a0 100644 --- a/src/tape.c +++ b/src/tape.c @@ -37,6 +37,7 @@ /* forward declaration for internal use */ static void HandleTapeButtons(struct GadgetInfo *); static void TapeStopWarpForward(); +static float GetTapeLengthSecondsFloat(); static struct GadgetInfo *tape_gadget[NUM_TAPE_BUTTONS]; @@ -376,15 +377,18 @@ void DrawVideoDisplayCurrentState() { state |= VIDEO_STATE_PLAY_ON; - if (tape.deactivate_display) - state |= VIDEO_STATE_WARP2_ON; - else if (tape.warp_forward) - state |= VIDEO_STATE_WARP_ON; - else if (tape.fast_forward) - state |= VIDEO_STATE_FFWD_ON; - - if (tape.pause_before_end) - state |= VIDEO_STATE_PBEND_ON; + if (!tape.pausing) + { + if (tape.deactivate_display) + state |= VIDEO_STATE_WARP2_ON; + else if (tape.warp_forward) + state |= VIDEO_STATE_WARP_ON; + else if (tape.fast_forward) + state |= VIDEO_STATE_FFWD_ON; + + if (tape.pause_before_end) + state |= VIDEO_STATE_PBEND_ON; + } } // draw labels and symbols separately to prevent labels overlapping symbols @@ -455,6 +459,46 @@ void TapeDeactivateDisplayOff(boolean redraw_display) } +/* ========================================================================= */ +/* tape logging functions */ +/* ========================================================================= */ + +void PrintTapeReplayProgress(boolean replay_finished) +{ + static unsigned int counter_last = -1; + unsigned int counter = Counter(); + unsigned int counter_seconds = counter / 1000; + + if (!replay_finished) + { + unsigned int counter_delay = 50; + + if (counter > counter_last + counter_delay) + { + PrintNoLog("\r"); + PrintNoLog("Level %03d [%02d:%02d]: [%02d:%02d] - playing tape ... ", + level_nr, tape.length_seconds / 60, tape.length_seconds % 60, + TapeTime / 60, TapeTime % 60); + + counter_last = counter; + } + } + else + { + float tape_length_seconds = GetTapeLengthSecondsFloat(); + + PrintNoLog("\r"); + Print("Level %03d [%02d:%02d]: (%02d:%02d.%03d / %.2f %%) - %s.\n", + level_nr, tape.length_seconds / 60, tape.length_seconds % 60, + counter_seconds / 60, counter_seconds % 60, counter % 1000, + (float)counter / tape_length_seconds / 10, + tape.auto_play_level_solved ? "solved" : "NOT SOLVED"); + + counter_last = -1; + } +} + + /* ========================================================================= */ /* tape control functions */ /* ========================================================================= */ @@ -596,11 +640,11 @@ static void TapeAppendRecording() void TapeHaltRecording() { - if (!tape.recording) - return; - tape.counter++; - tape.pos[tape.counter].delay = 0; + + // initialize delay for next tape entry (to be able to continue recording) + if (tape.counter < MAX_TAPE_LEN) + tape.pos[tape.counter].delay = 0; tape.length = tape.counter; tape.length_frames = GetTapeLengthFrames(); @@ -609,7 +653,8 @@ void TapeHaltRecording() void TapeStopRecording() { - TapeHaltRecording(); + if (tape.recording) + TapeHaltRecording(); tape.recording = FALSE; tape.pausing = FALSE; @@ -618,33 +663,10 @@ void TapeStopRecording() MapTapeEjectButton(); } -void TapeRecordAction(byte action_raw[MAX_PLAYERS]) +boolean TapeAddAction(byte action[MAX_PLAYERS]) { - byte action[MAX_PLAYERS]; int i; - if (!tape.recording) /* (record action even when tape is paused) */ - return; - - if (tape.counter >= MAX_TAPE_LEN - 1) - { - TapeStopRecording(); - return; - } - - for (i = 0; i < MAX_PLAYERS; i++) - action[i] = action_raw[i]; - - if (tape.set_centered_player) - { - for (i = 0; i < MAX_PLAYERS; i++) - if (tape.centered_player_nr_next == i || - tape.centered_player_nr_next == -1) - action[i] |= KEY_SET_FOCUS; - - tape.set_centered_player = FALSE; - } - if (tape.pos[tape.counter].delay > 0) /* already stored action */ { boolean changed_events = FALSE; @@ -655,6 +677,9 @@ void TapeRecordAction(byte action_raw[MAX_PLAYERS]) if (changed_events || tape.pos[tape.counter].delay >= 255) { + if (tape.counter >= MAX_TAPE_LEN - 1) + return FALSE; + tape.counter++; tape.pos[tape.counter].delay = 0; } @@ -669,6 +694,33 @@ void TapeRecordAction(byte action_raw[MAX_PLAYERS]) tape.pos[tape.counter].delay++; } + + return TRUE; +} + +void TapeRecordAction(byte action_raw[MAX_PLAYERS]) +{ + byte action[MAX_PLAYERS]; + int i; + + if (!tape.recording) /* (record action even when tape is paused) */ + return; + + for (i = 0; i < MAX_PLAYERS; i++) + action[i] = action_raw[i]; + + if (tape.set_centered_player) + { + for (i = 0; i < MAX_PLAYERS; i++) + if (tape.centered_player_nr_next == i || + tape.centered_player_nr_next == -1) + action[i] |= KEY_SET_FOCUS; + + tape.set_centered_player = FALSE; + } + + if (!TapeAddAction(action)) + TapeStopRecording(); } void TapeTogglePause(boolean toggle_mode) @@ -710,6 +762,9 @@ void TapeTogglePause(boolean toggle_mode) // restart step/move snapshots after quick loading tape SaveEngineSnapshotToListInitial(); + + // do not map undo/redo buttons after quick loading tape + return; } if (setup.show_snapshot_buttons && @@ -851,6 +906,9 @@ byte *TapePlayAction() tape.delay_played = 0; } + if (tape.auto_play) + PrintTapeReplayProgress(FALSE); + return action; } @@ -888,6 +946,11 @@ unsigned int GetTapeLengthSeconds() return (GetTapeLengthFrames() * GAME_FRAME_DELAY / 1000); } +static float GetTapeLengthSecondsFloat() +{ + return ((float)GetTapeLengthFrames() * GAME_FRAME_DELAY / 1000); +} + static void TapeStartWarpForward(int mode) { tape.fast_forward = (mode & AUTOPLAY_FFWD); @@ -1019,13 +1082,23 @@ void TapeQuickLoad() void InsertSolutionTape() { - if (!TAPE_IS_EMPTY(tape)) + boolean level_has_tape = (level.game_engine_type == GAME_ENGINE_TYPE_SP && + level.native_sp_level->demo.is_available); + + if (!fileExists(getSolutionTapeFilename(level_nr)) && !level_has_tape) + { + Request("No solution tape for this level!", REQ_CONFIRM); + return; + } + + // if tape recorder already contains a tape, remove it without asking + TapeErase(); LoadSolutionTape(level_nr); if (TAPE_IS_EMPTY(tape)) - Request("No solution tape for this level!", REQ_CONFIRM); + Request("Loading solution tape for this level failed!", REQ_CONFIRM); DrawCompleteVideoDisplay(); } @@ -1049,7 +1122,7 @@ void AutoPlayTape() if (autoplay_initialized) { /* just finished auto-playing tape */ - Print("%s.\n", tape.auto_play_level_solved ? "solved" : "NOT SOLVED"); + PrintTapeReplayProgress(TRUE); num_levels_played++; @@ -1106,18 +1179,18 @@ void AutoPlayTape() TapeErase(); - Print("Level %03d: ", level_nr); - LoadLevel(level_nr); - if (level.no_valid_file) + + if (level.no_level_file || level.no_valid_file) { - Print("(no level)\n"); + Print("Level %03d: (no level)\n", level_nr); + continue; } #if 0 /* ACTIVATE THIS FOR LOADING/TESTING OF LEVELS ONLY */ - Print("(only testing level)\n"); + Print("Level %03d: (only testing level)\n", level_nr); continue; #endif @@ -1130,12 +1203,12 @@ void AutoPlayTape() { num_tape_missing++; - Print("(no tape)\n"); + Print("Level %03d: (no tape)\n", level_nr); continue; } - Print("playing tape ... "); + InitCounter(); TapeStartGamePlaying(); TapeStartWarpForward(global.autoplay_mode); @@ -1337,7 +1410,7 @@ static void HandleTapeButtonsExt(int id) else { if (tape.changed) - SaveTapeChecked(tape.level_nr); + SaveTapeChecked(level_nr); TapeErase(); }