diff --git a/src/drivers/win/taseditor/greenzone.cpp b/src/drivers/win/taseditor/greenzone.cpp index 4ed90ee4..30df6d08 100644 --- a/src/drivers/win/taseditor/greenzone.cpp +++ b/src/drivers/win/taseditor/greenzone.cpp @@ -94,11 +94,11 @@ void GREENZONE::CollectCurrentState() { if ((old_lagFlag == LAGGED_YES) && !lagFlag) { - // there's no more lag on previous frame - shift Input up + // there's no more lag on previous frame - shift Input up 1 or more frames AdjustUp(); } else if ((old_lagFlag == LAGGED_NO) && lagFlag) { - // there's new lag on previous frame - shift Input down + // there's new lag on previous frame - shift Input down 1 frame AdjustDown(); } } else @@ -135,7 +135,7 @@ void GREENZONE::RunGreenzoneCleaning() { if ((i & 0x1) && savestates[i].size()) { - ClearSavestate(i); + ClearSavestateAndFreeMemory(i); changed = true; } } @@ -147,7 +147,7 @@ void GREENZONE::RunGreenzoneCleaning() { if ((i & 0x3) && savestates[i].size()) { - ClearSavestate(i); + ClearSavestateAndFreeMemory(i); changed = true; } } @@ -159,7 +159,7 @@ void GREENZONE::RunGreenzoneCleaning() { if ((i & 0x7) && savestates[i].size()) { - ClearSavestate(i); + ClearSavestateAndFreeMemory(i); changed = true; } } @@ -171,7 +171,7 @@ void GREENZONE::RunGreenzoneCleaning() { if ((i & 0xF) && savestates[i].size()) { - ClearSavestate(i); + ClearSavestateAndFreeMemory(i); changed = true; } } @@ -180,7 +180,7 @@ void GREENZONE::RunGreenzoneCleaning() { if (savestates[i].size()) { - ClearSavestate(i); + ClearSavestateAndFreeMemory(i); changed = true; } } @@ -199,6 +199,11 @@ void GREENZONE::ClearSavestate(int index) savestates[index].resize(0); } +void GREENZONE::ClearSavestateAndFreeMemory(int index) +{ + savestates[index].swap(std::vector()); +} + void GREENZONE::save(EMUFILE *os, bool really_save) { if (really_save) @@ -385,42 +390,51 @@ error: void GREENZONE::AdjustUp() { int at = currFrameCounter - 1; // at = the frame above currFrameCounter - bool markers_changed = false; - // delete one frame of lag - currMovieData.records.erase(currMovieData.records.begin() + at); - laglog.EraseFrame(at); - if (taseditor_config.bind_markers) + // find how many consequent lag frames there are + int num_frames_to_erase = 0; + while (laglog.GetLagInfoAtFrame(at++) == LAGGED_YES) + num_frames_to_erase++; + + if (num_frames_to_erase > 0) { - if (markers_manager.EraseMarker(at)) - markers_changed = true; + bool markers_changed = false; + // delete these frames of lag + currMovieData.records.erase(currMovieData.records.begin() + (currFrameCounter - 1), currMovieData.records.begin() + (currFrameCounter - 1 + num_frames_to_erase)); + laglog.EraseFrame(currFrameCounter - 1, num_frames_to_erase); + if (taseditor_config.bind_markers) + { + if (markers_manager.EraseMarker(currFrameCounter - 1, num_frames_to_erase)) + markers_changed = true; + } + // update movie data size, because Playback cursor must always be inside the movie + // if movie length is less or equal to currFrame, pad it with empty frames + if (((int)currMovieData.records.size() - 1) <= currFrameCounter) + currMovieData.insertEmpty(-1, currFrameCounter - ((int)currMovieData.records.size() - 1)); + // update Piano Roll (reduce it if needed) + piano_roll.UpdateItemCount(); + // register changes + int first_input_changes = history.RegisterAdjustLag(currFrameCounter - 1, 0 - num_frames_to_erase); + // if Input in the frame above currFrameCounter has changed then invalidate Greenzone (rewind 1 frame back) + // also if the frame above currFrameCounter is lag frame then rewind 1 frame (invalidate Greenzone), because maybe this frame also needs lag removal + if ((first_input_changes >= 0 && first_input_changes < currFrameCounter) || (laglog.GetLagInfoAtFrame(currFrameCounter - 1) != LAGGED_NO)) + { + // custom invalidation procedure, not retriggering LostPosition/PauseFrame + Invalidate(first_input_changes); + bool emu_was_paused = (FCEUI_EmulationPaused() != 0); + int saved_pause_frame = playback.GetPauseFrame(); + playback.jump(first_input_changes); + if (saved_pause_frame >= 0) + playback.SeekingStart(saved_pause_frame); + if (emu_was_paused) + playback.PauseEmulation(); + } else + { + // just invalidate Greenzone after currFrameCounter (this is necessary in order to force user to re-emulate everything after the point, because the lag log data after the currFrameCounter is now in unknown state and it should be collected again) + Invalidate(currFrameCounter); + } + if (markers_changed) + selection.must_find_current_marker = playback.must_find_current_marker = true; } - // check if user deleted all frames - if (!currMovieData.getNumRecords()) - playback.StartFromZero(); - // reduce Piano Roll - piano_roll.UpdateItemCount(); - // register changes - int first_input_changes = history.RegisterAdjustLag(at, -1); - // if Input in the frame above currFrameCounter has changed then invalidate Greenzone (rewind 1 frame back) - // also if the frame above currFrameCounter is lag frame then rewind 1 frame (invalidate Greenzone), because maybe this frame also needs lag removal - if ((first_input_changes >= 0 && first_input_changes < currFrameCounter) || (laglog.GetLagInfoAtFrame(at) != LAGGED_NO)) - { - // custom invalidation procedure, not retriggering LostPosition/PauseFrame - Invalidate(at); - bool emu_was_paused = (FCEUI_EmulationPaused() != 0); - int saved_pause_frame = playback.GetPauseFrame(); - playback.jump(at); - if (saved_pause_frame >= 0) - playback.SeekingStart(saved_pause_frame); - if (emu_was_paused) - playback.PauseEmulation(); - } else - { - // just invalidate Greenzone after currFrameCounter - Invalidate(currFrameCounter); - } - if (markers_changed) - selection.must_find_current_marker = playback.must_find_current_marker = true; } void GREENZONE::AdjustDown() { @@ -436,14 +450,16 @@ void GREENZONE::AdjustDown() } // register changes int first_input_chanes = history.RegisterAdjustLag(at, +1); - // if Input in the frame above currFrameCounter has changed then invalidate Greenzone (rewind 1 frame back) + // If Input in the frame above currFrameCounter has changed then invalidate Greenzone (rewind 1 frame back) + // This should never actually happen, because we clone the frame, so the Input doesn't change + // But the check should remain, in case we decide to insert blank frame instead of cloning if (first_input_chanes >= 0 && first_input_chanes < currFrameCounter) { // custom invalidation procedure, not retriggering LostPosition/PauseFrame - Invalidate(at); + Invalidate(first_input_chanes); bool emu_was_paused = (FCEUI_EmulationPaused() != 0); int saved_pause_frame = playback.GetPauseFrame(); - playback.jump(at); + playback.jump(first_input_chanes); if (saved_pause_frame >= 0) playback.SeekingStart(saved_pause_frame); if (emu_was_paused) diff --git a/src/drivers/win/taseditor/greenzone.h b/src/drivers/win/taseditor/greenzone.h index 89d9ae24..dafd3268 100644 --- a/src/drivers/win/taseditor/greenzone.h +++ b/src/drivers/win/taseditor/greenzone.h @@ -32,6 +32,7 @@ public: void RunGreenzoneCleaning(); void ClearSavestate(int index); + void ClearSavestateAndFreeMemory(int index); void InvalidateAndCheck(int after); void Invalidate(int after); diff --git a/src/drivers/win/taseditor/history.cpp b/src/drivers/win/taseditor/history.cpp index c9f3e01e..34f7706a 100644 --- a/src/drivers/win/taseditor/history.cpp +++ b/src/drivers/win/taseditor/history.cpp @@ -665,7 +665,7 @@ int HISTORY::RegisterAdjustLag(int start, int size) { if (size < 0) // it was Adjust Up - snap.inputlog.inheritHotChanges_DeleteNum(&snapshots[real_pos].inputlog, start, 1, false); + snap.inputlog.inheritHotChanges_DeleteNum(&snapshots[real_pos].inputlog, start, 0 - size, false); else // it was Adjust Down snap.inputlog.inheritHotChanges_InsertNum(&snapshots[real_pos].inputlog, start, 1, false); diff --git a/src/drivers/win/taseditor/laglog.cpp b/src/drivers/win/taseditor/laglog.cpp index 51a7a2ad..ed93484d 100644 --- a/src/drivers/win/taseditor/laglog.cpp +++ b/src/drivers/win/taseditor/laglog.cpp @@ -134,12 +134,24 @@ void LAGLOG::SetLagInfo(int frame, bool lagFlag) already_compressed = false; } -void LAGLOG::EraseFrame(int frame) +void LAGLOG::EraseFrame(int frame, int frames) { if (frame < (int)lag_log.size()) - lag_log.erase(lag_log.begin() + frame); - - already_compressed = false; + { + if (frames == 1) + { + // erase 1 frame + lag_log.erase(lag_log.begin() + frame); + already_compressed = false; + } else if (frames > 1) + { + // erase many frames + if (frame + frames > (int)lag_log.size()) + frames = (int)lag_log.size() - frame; + lag_log.erase(lag_log.begin() + frame, lag_log.begin() + (frame + frames)); + already_compressed = false; + } + } } void LAGLOG::InsertFrame(int frame, bool lagFlag, int frames) { diff --git a/src/drivers/win/taseditor/laglog.h b/src/drivers/win/taseditor/laglog.h index 75802d88..1180a60a 100644 --- a/src/drivers/win/taseditor/laglog.h +++ b/src/drivers/win/taseditor/laglog.h @@ -21,7 +21,7 @@ public: void InvalidateFrom(int frame); void SetLagInfo(int frame, bool lagFlag); - void EraseFrame(int frame); + void EraseFrame(int frame, int frames = 1); void InsertFrame(int frame, bool lagFlag, int frames = 1); int GetSize(); diff --git a/src/drivers/win/taseditor/markers_manager.cpp b/src/drivers/win/taseditor/markers_manager.cpp index 264a486b..06595e11 100644 --- a/src/drivers/win/taseditor/markers_manager.cpp +++ b/src/drivers/win/taseditor/markers_manager.cpp @@ -212,22 +212,43 @@ void MARKERS_MANAGER::ToggleMarker(int frame) } } -bool MARKERS_MANAGER::EraseMarker(int frame) +bool MARKERS_MANAGER::EraseMarker(int frame, int frames) { bool markers_changed = false; if (frame < (int)markers.markers_array.size()) { - // if there's a Marker, first clear it - if (markers.markers_array[frame]) + if (frames == 1) { - ClearMarker(frame); - markers_changed = true; + // erase 1 frame + // if there's a Marker, first clear it + if (markers.markers_array[frame]) + { + ClearMarker(frame); + markers_changed = true; + } + // erase 1 frame + markers.markers_array.erase(markers.markers_array.begin() + frame); + } else + { + // erase many frames + if (frame + frames > (int)markers.markers_array.size()) + frames = (int)markers.markers_array.size() - frame; + // if there are Markers at those frames, first clear them + for (int i = frame; i < (frame + frames); ++i) + { + if (markers.markers_array[i]) + { + ClearMarker(i); + markers_changed = true; + } + } + // erase frames + markers.markers_array.erase(markers.markers_array.begin() + frame, markers.markers_array.begin() + (frame + frames)); } - // erase 1 frame - markers.markers_array.erase(markers.markers_array.begin() + frame); + // check if there were some Markers after this frame + // since these Markers were shifted, markers_changed should be set to true if (!markers_changed) { - // check if there were some Markers after this frame for (int i = markers.markers_array.size() - 1; i >= frame; i--) { if (markers.markers_array[i]) diff --git a/src/drivers/win/taseditor/markers_manager.h b/src/drivers/win/taseditor/markers_manager.h index 8e47a10e..adb560cb 100644 --- a/src/drivers/win/taseditor/markers_manager.h +++ b/src/drivers/win/taseditor/markers_manager.h @@ -46,7 +46,7 @@ public: void ClearMarker(int frame); void ToggleMarker(int frame); - bool EraseMarker(int frame); + bool EraseMarker(int frame, int frames = 1); bool insertEmpty(int at, int frames); int GetNotesSize(); diff --git a/src/movie.cpp b/src/movie.cpp index 8bfa3c6a..6ff19d03 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -965,11 +965,11 @@ void FCEUI_SaveMovie(const char *fname, EMOVIE_FLAG flags, std::wstring author) void FCEUMOV_AddInputState() { #ifdef _WIN32 - if(movieMode == MOVIEMODE_TASEDITOR) + if (movieMode == MOVIEMODE_TASEDITOR) { // if movie length is less or equal to currFrame, pad it with empty frames - if((int)currMovieData.records.size()-1 <= currFrameCounter) - currMovieData.insertEmpty(-1, 2 + currFrameCounter - (int)currMovieData.records.size()); + if (((int)currMovieData.records.size() - 1) < (currFrameCounter + 1)) + currMovieData.insertEmpty(-1, (currFrameCounter + 1) - ((int)currMovieData.records.size() - 1)); MovieRecord* mr = &currMovieData.records[currFrameCounter]; if (TaseditorIsRecording())