X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Ftape.c;h=f75bc897e6f4579f1908050253b3ce1c0c2c3f01;hp=71addab34829a8c1eab0a7152e98c384df1a35e7;hb=d0a7080670f9a2fa96138cf1c06708016a42d615;hpb=714fef0f666caf3561dfa0f7de5522f89e943e73 diff --git a/src/tape.c b/src/tape.c index 71addab3..f75bc897 100644 --- a/src/tape.c +++ b/src/tape.c @@ -28,8 +28,10 @@ #define TAPE_CTRL_ID_PAUSE 3 #define TAPE_CTRL_ID_RECORD 4 #define TAPE_CTRL_ID_PLAY 5 +#define TAPE_CTRL_ID_INSERT_SOLUTION 6 +#define TAPE_CTRL_ID_PLAY_SOLUTION 7 -#define NUM_TAPE_BUTTONS 6 +#define NUM_TAPE_BUTTONS 8 /* values for tape handling */ #define TAPE_PAUSE_SECONDS_BEFORE_DEATH 5 @@ -37,6 +39,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]; @@ -484,11 +487,13 @@ void PrintTapeReplayProgress(boolean replay_finished) } 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, + (float)counter / tape_length_seconds / 10, tape.auto_play_level_solved ? "solved" : "NOT SOLVED"); counter_last = -1; @@ -541,6 +546,8 @@ void TapeErase() tape.centered_player_nr_next = -1; tape.set_centered_player = FALSE; + + tape.use_mouse = (level.game_engine_type == GAME_ENGINE_TYPE_MM); } static void TapeRewind() @@ -593,18 +600,7 @@ void TapeStartRecording(int random_seed) static void TapeStartGameRecording() { - TapeStartRecording(level.random_seed); - -#if defined(NETWORK_AVALIABLE) - if (options.network) - { - SendToServer_StartPlaying(); - - return; - } -#endif - - InitGame(); + StartGameActions(options.network, TRUE, level.random_seed); } static void TapeAppendRecording() @@ -637,11 +633,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(); @@ -650,7 +646,8 @@ void TapeHaltRecording() void TapeStopRecording() { - TapeHaltRecording(); + if (tape.recording) + TapeHaltRecording(); tape.recording = FALSE; tape.pausing = FALSE; @@ -659,33 +656,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; @@ -696,6 +670,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; } @@ -710,6 +687,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.use_mouse && 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) @@ -876,16 +880,19 @@ byte *TapePlayAction() tape.set_centered_player = FALSE; tape.centered_player_nr_next = -999; - for (i = 0; i < MAX_PLAYERS; i++) + if (!tape.use_mouse) { - if (action[i] & KEY_SET_FOCUS) + for (i = 0; i < MAX_PLAYERS; i++) { - tape.set_centered_player = TRUE; - tape.centered_player_nr_next = - (tape.centered_player_nr_next == -999 ? i : -1); - } + if (action[i] & KEY_SET_FOCUS) + { + tape.set_centered_player = TRUE; + tape.centered_player_nr_next = + (tape.centered_player_nr_next == -999 ? i : -1); + } - action[i] &= ~KEY_SET_FOCUS; + action[i] &= ~KEY_SET_FOCUS; + } } tape.delay_played++; @@ -903,6 +910,9 @@ byte *TapePlayAction() void TapeStop() { + if (tape.pausing) + TapeTogglePause(TAPE_TOGGLE_MANUAL); + TapeStopRecording(); TapeStopPlaying(); @@ -935,6 +945,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); @@ -1064,7 +1079,7 @@ void TapeQuickLoad() } } -void InsertSolutionTape() +boolean InsertSolutionTape() { boolean level_has_tape = (level.game_engine_type == GAME_ENGINE_TYPE_SP && level.native_sp_level->demo.is_available); @@ -1073,18 +1088,37 @@ void InsertSolutionTape() { Request("No solution tape for this level!", REQ_CONFIRM); - return; + return FALSE; } + if (!TAPE_IS_STOPPED(tape)) + TapeStop(); + // if tape recorder already contains a tape, remove it without asking TapeErase(); LoadSolutionTape(level_nr); + DrawCompleteVideoDisplay(); + if (TAPE_IS_EMPTY(tape)) + { Request("Loading solution tape for this level failed!", REQ_CONFIRM); - DrawCompleteVideoDisplay(); + return FALSE; + } + + return TRUE; +} + +boolean PlaySolutionTape() +{ + if (!InsertSolutionTape()) + return FALSE; + + TapeStartGamePlaying(); + + return TRUE; } @@ -1260,6 +1294,14 @@ static struct { IMG_GFX_TAPE_BUTTON_PLAY, &tape.button.play, TAPE_CTRL_ID_PLAY, "play tape" + }, + { + IMG_GFX_TAPE_BUTTON_INSERT_SOLUTION,&tape.button.insert_solution, + TAPE_CTRL_ID_INSERT_SOLUTION, "insert solution tape" + }, + { + IMG_GFX_TAPE_BUTTON_PLAY_SOLUTION, &tape.button.play_solution, + TAPE_CTRL_ID_PLAY_SOLUTION, "play solution tape" } }; @@ -1269,7 +1311,8 @@ void CreateTapeButtons() for (i = 0; i < NUM_TAPE_BUTTONS; i++) { - struct GraphicInfo *gfx = &graphic_info[tapebutton_info[i].graphic]; + int graphic = tapebutton_info[i].graphic; + struct GraphicInfo *gfx = &graphic_info[graphic]; struct XY *pos = tapebutton_info[i].pos; struct GadgetInfo *gi; int gd_x = gfx->src_x; @@ -1279,6 +1322,7 @@ void CreateTapeButtons() int id = i; gi = CreateGadget(GDI_CUSTOM_ID, id, + GDI_IMAGE_ID, graphic, GDI_INFO_TEXT, tapebutton_info[i].infotext, GDI_X, VX + pos->x, GDI_Y, VY + pos->y, @@ -1332,7 +1376,7 @@ void MapTapeButtons() MapTapeWarpButton(); if (tape.show_game_buttons) - MapGameButtons(); + MapGameButtonsOnTape(); } void UnmapTapeButtons() @@ -1343,7 +1387,7 @@ void UnmapTapeButtons() UnmapGadget(tape_gadget[i]); if (tape.show_game_buttons) - UnmapGameButtons(); + UnmapGameButtonsOnTape(); } void RedrawTapeButtons() @@ -1354,7 +1398,7 @@ void RedrawTapeButtons() RedrawGadget(tape_gadget[i]); if (tape.show_game_buttons) - RedrawGameButtons(); + RedrawGameButtonsOnTape(); // RedrawGadget() may have set REDRAW_ALL if buttons are defined off-area redraw_mask &= ~REDRAW_ALL; @@ -1394,7 +1438,7 @@ static void HandleTapeButtonsExt(int id) else { if (tape.changed) - SaveTapeChecked(tape.level_nr); + SaveTapeChecked(level_nr); TapeErase(); } @@ -1490,6 +1534,16 @@ static void HandleTapeButtonsExt(int id) break; + case TAPE_CTRL_ID_INSERT_SOLUTION: + InsertSolutionTape(); + + break; + + case TAPE_CTRL_ID_PLAY_SOLUTION: + PlaySolutionTape(); + + break; + default: break; }