From 61df7ea54126ad2f4cb912e047db31f8d2e30288 Mon Sep 17 00:00:00 2001 From: ansstuff Date: Sat, 11 Aug 2012 19:53:56 +0000 Subject: [PATCH] * Taseditor: fixed bug with history undo not setting "project changed" flag * Taseditor: Greenzone invalidation actually clears irrelevant savestates * Taseditor: fixed checkMarkersDiff, removed unused code from MARKERS_MANAGER::RestoreFromCopy * Taseditor: when snapshots sizes differ, findFirstChange returns size instead of last frame --- src/drivers/win/taseditor/bookmarks.cpp | 3 +- src/drivers/win/taseditor/greenzone.cpp | 93 ++++++++------- src/drivers/win/taseditor/greenzone.h | 4 +- src/drivers/win/taseditor/history.cpp | 5 +- src/drivers/win/taseditor/markers_manager.cpp | 108 +++++------------- src/drivers/win/taseditor/markers_manager.h | 3 +- src/drivers/win/taseditor/snapshot.cpp | 18 +-- src/drivers/win/taseditor/snapshot.h | 4 +- 8 files changed, 91 insertions(+), 147 deletions(-) diff --git a/src/drivers/win/taseditor/bookmarks.cpp b/src/drivers/win/taseditor/bookmarks.cpp index e9eaeca4..075262cc 100644 --- a/src/drivers/win/taseditor/bookmarks.cpp +++ b/src/drivers/win/taseditor/bookmarks.cpp @@ -449,7 +449,8 @@ void BOOKMARKS::deploy(int slot) bookmarks_array[slot].jumped(); } // jump to the target (bookmarked frame) - greenzone.WriteSavestate(jump_frame, bookmarks_array[slot].savestate); + if (greenzone.SavestateIsEmpty(jump_frame)) + greenzone.WriteSavestate(jump_frame, bookmarks_array[slot].savestate); playback.jump(jump_frame); // switch current branch to this branch int old_current_branch = branches.GetCurrentBranch(); diff --git a/src/drivers/win/taseditor/greenzone.cpp b/src/drivers/win/taseditor/greenzone.cpp index adeba0e8..af47523a 100644 --- a/src/drivers/win/taseditor/greenzone.cpp +++ b/src/drivers/win/taseditor/greenzone.cpp @@ -47,11 +47,6 @@ void GREENZONE::init() } void GREENZONE::free() { - int size = savestates.size(); - for (int i = 0; i < size; ++i) - { - ClearSavestate(i); - } savestates.resize(0); greenZoneCount = 0; lag_history.resize(0); @@ -63,7 +58,7 @@ void GREENZONE::reset() void GREENZONE::update() { // keep memorizing savestates, this function should be called at the end of every frame - if (greenZoneCount <= currFrameCounter || (int)savestates.size() <= currFrameCounter || savestates[currFrameCounter].empty() || (int)lag_history.size() <= currFrameCounter) + if (greenZoneCount <= currFrameCounter || (int)savestates.size() <= currFrameCounter || !savestates[currFrameCounter].size() || (int)lag_history.size() <= currFrameCounter) CollectCurrentState(); // run cleaning from time to time @@ -83,7 +78,10 @@ void GREENZONE::CollectCurrentState() lag_history.resize(greenZoneCount, 0); // if frame changed - log savestate - storeTasSavestate(currFrameCounter); + EMUFILE_MEMORY ms(&savestates[currFrameCounter]); + FCEUSS_SaveMS(&ms, Z_DEFAULT_COMPRESSION); + ms.trim(); + // also log lag frames if (currFrameCounter > 0) { @@ -133,23 +131,13 @@ bool GREENZONE::loadTasSavestate(int frame) { if (frame < 0 || frame >= currMovieData.getNumRecords()) return false; - if ((int)savestates.size() <= frame || savestates[frame].empty()) + if ((int)savestates.size() <= frame || !savestates[frame].size()) return false; EMUFILE_MEMORY ms(&savestates[frame]); return FCEUSS_LoadFP(&ms, SSLOADPARAM_NOBACKUP); } -void GREENZONE::storeTasSavestate(int frame) -{ - if ((int)savestates.size() <= frame) - savestates.resize(frame + 1); - - EMUFILE_MEMORY ms(&savestates[frame]); - FCEUSS_SaveMS(&ms, Z_DEFAULT_COMPRESSION); - ms.trim(); -} - void GREENZONE::RunGreenzoneCleaning() { int i = currFrameCounter - taseditor_config.greenzone_capacity; @@ -161,7 +149,7 @@ void GREENZONE::RunGreenzoneCleaning() if (limit < 0) limit = 0; for (; i > limit; i--) { - if ((i & 0x1) && !savestates[i].empty()) + if ((i & 0x1) && savestates[i].size()) { ClearSavestate(i); changed = true; @@ -173,7 +161,7 @@ void GREENZONE::RunGreenzoneCleaning() if (limit < 0) limit = 0; for (; i > limit; i--) { - if ((i & 0x3) && !savestates[i].empty()) + if ((i & 0x3) && savestates[i].size()) { ClearSavestate(i); changed = true; @@ -185,7 +173,7 @@ void GREENZONE::RunGreenzoneCleaning() if (limit < 0) limit = 0; for (; i > limit; i--) { - if ((i & 0x7) && !savestates[i].empty()) + if ((i & 0x7) && savestates[i].size()) { ClearSavestate(i); changed = true; @@ -197,7 +185,7 @@ void GREENZONE::RunGreenzoneCleaning() if (limit < 0) limit = 0; for (; i > limit; i--) { - if ((i & 0xF) && !savestates[i].empty()) + if ((i & 0xF) && savestates[i].size()) { ClearSavestate(i); changed = true; @@ -206,7 +194,7 @@ void GREENZONE::RunGreenzoneCleaning() // clear all remaining for (; i > 0; i--) { - if (!savestates[i].empty()) + if (savestates[i].size()) { ClearSavestate(i); changed = true; @@ -224,23 +212,7 @@ finish: void GREENZONE::ClearSavestate(int index) { - std::vector tmp; - savestates[index].swap(tmp); -} -// this function is used by Bookmark Deploy procedure -void GREENZONE::WriteSavestate(int frame, std::vector& savestate) -{ - if ((int)savestates.size() <= frame) - savestates.resize(frame + 1); - if (greenZoneCount <= frame) - { - // clear old savestates: from current end of Greenzone to new end of Greenzone - for (int i = greenZoneCount; i <= frame; ++i) - ClearSavestate(i); - greenZoneCount = frame + 1; - } - if (savestates[frame].empty()) - savestates[frame] = savestate; + savestates[index].resize(0); } void GREENZONE::save(EMUFILE *os, bool really_save) @@ -274,7 +246,7 @@ void GREENZONE::save(EMUFILE *os, bool really_save) playback.SetProgressbar(frame, greenZoneCount); last_tick = frame / PROGRESSBAR_UPDATE_RATE; } - if (savestates[frame].empty()) continue; + if (!savestates[frame].size()) continue; write32le(frame, os); // write savestate size = savestates[frame].size(); @@ -442,8 +414,16 @@ void GREENZONE::InvalidateAndCheck(int after) { if (after >= 0) { + if (after >= currMovieData.getNumRecords()) + after = currMovieData.getNumRecords() - 1; if (greenZoneCount > after + 1) { + // clear all savestates that became irrelevant + for (int i = greenZoneCount - 1; i > after; i--) + { + if (savestates[i].size()) + ClearSavestate(i); + } greenZoneCount = after + 1; currMovieData.rerecordCount++; // either set Playback cursor to the end of Greenzone or run seeking to restore Playback cursor position @@ -474,8 +454,16 @@ void GREENZONE::Invalidate(int after) { if (after >= 0) { + if (after >= currMovieData.getNumRecords()) + after = currMovieData.getNumRecords() - 1; if (greenZoneCount > after + 1) { + // clear all savestates that became irrelevant + for (int i = greenZoneCount - 1; i > after; i--) + { + if (savestates[i].size()) + ClearSavestate(i); + } greenZoneCount = after + 1; currMovieData.rerecordCount++; } @@ -488,11 +476,10 @@ void GREENZONE::Invalidate(int after) int GREENZONE::FindBeginningOfGreenZone(int starting_index) { for (int i = starting_index; i < greenZoneCount; ++i) - { - if (!savestates[i].empty()) return i; - } - return starting_index; + if (savestates[i].size()) return i; + return -1; // error } + // getters int GREENZONE::GetSize() { @@ -505,14 +492,26 @@ bool GREENZONE::GetLagHistoryAtFrame(int frame) else return false; } + +// this should only be used by Bookmark Set procedure std::vector& GREENZONE::GetSavestate(int frame) { return savestates[frame]; } +// this function should only be used by Bookmark Deploy procedure +void GREENZONE::WriteSavestate(int frame, std::vector& savestate) +{ + if ((int)savestates.size() <= frame) + savestates.resize(frame + 1); + savestates[frame] = savestate; + if (greenZoneCount <= frame) + greenZoneCount = frame + 1; +} + bool GREENZONE::SavestateIsEmpty(int frame) { - if (frame < greenZoneCount && frame < (int)savestates.size()) - return savestates[frame].empty(); + if (frame < greenZoneCount && frame < (int)savestates.size() && savestates[frame].size()) + return false; else return true; } diff --git a/src/drivers/win/taseditor/greenzone.h b/src/drivers/win/taseditor/greenzone.h index 6afbeb34..1eccc55a 100644 --- a/src/drivers/win/taseditor/greenzone.h +++ b/src/drivers/win/taseditor/greenzone.h @@ -28,8 +28,6 @@ public: void RunGreenzoneCleaning(); void ClearSavestate(int index); - void WriteSavestate(int frame, std::vector& savestate); - void InvalidateAndCheck(int after); void Invalidate(int after); @@ -38,11 +36,11 @@ public: int GetSize(); bool GetLagHistoryAtFrame(int frame); std::vector& GetSavestate(int frame); + void WriteSavestate(int frame, std::vector& savestate); bool SavestateIsEmpty(int frame); private: void CollectCurrentState(); - void storeTasSavestate(int frame); // saved data int greenZoneCount; diff --git a/src/drivers/win/taseditor/history.cpp b/src/drivers/win/taseditor/history.cpp index 319972cf..0ca0336b 100644 --- a/src/drivers/win/taseditor/history.cpp +++ b/src/drivers/win/taseditor/history.cpp @@ -383,13 +383,14 @@ int HISTORY::JumpInTime(int new_pos) { snapshots[real_pos].toMovie(currMovieData, first_change); selection.must_find_current_marker = playback.must_find_current_marker = true; - // Piano Roll Redraw and ProjectChanged will be called by Greenzone invalidation + project.SetProjectChanged(); + // Piano Roll Redraw will be called by Greenzone invalidation } else if (markers_changed) { markers_manager.update(); selection.must_find_current_marker = playback.must_find_current_marker = true; - piano_roll.RedrawList(); project.SetProjectChanged(); + piano_roll.RedrawList(); } else if (taseditor_config.enable_hot_changes) { // when using Hot Changes, Piano Roll should be always redrawn, because old changes become less hot diff --git a/src/drivers/win/taseditor/markers_manager.cpp b/src/drivers/win/taseditor/markers_manager.cpp index 1adeb0e1..188c4e81 100644 --- a/src/drivers/win/taseditor/markers_manager.cpp +++ b/src/drivers/win/taseditor/markers_manager.cpp @@ -295,99 +295,45 @@ void MARKERS_MANAGER::MakeCopyTo(MARKERS& destination) destination.notes = markers.notes; destination.Set_already_compressed(false); } -void MARKERS_MANAGER::RestoreFromCopy(MARKERS& source, int until_frame) +void MARKERS_MANAGER::RestoreFromCopy(MARKERS& source) { - if (until_frame >= 0) - { - // restore Markers up to and not including the frame - if ((int)markers.markers_array.size() <= until_frame) - { - // only copy head of source - markers.markers_array = source.markers_array; - markers.markers_array.resize(until_frame); - markers.notes = source.notes; - // find last Marker - int last_marker = GetMarkerUp(until_frame-1); - // delete all notes following the note of the last Marker - markers.notes.resize(last_marker+1); - } else - { - // combine head of source and tail of destination (old Markers) - // 1 - head = part of source Markers - std::vector temp_markers_array; - std::vector temp_notes; - temp_markers_array = source.markers_array; - temp_markers_array.resize(until_frame); - temp_notes = source.notes; - // find last Marker in temp_markers_array - int last_marker, frame; - for (frame = until_frame-1; frame >= 0; frame--) - if (temp_markers_array[frame]) break; - if (frame >= 0) - last_marker = temp_markers_array[frame]; - else - last_marker = 0; - // delete all temp_notes foolowing the note of the last Marker - temp_notes.resize(last_marker+1); - // 2 - tail = part of old (current) Markers - // delete all Markers (and their notes) up to and not including until_frame - //for (int i = until_frame-1; i >= 0; i--) // actually no need for that - // ClearMarker(i); - // 3 - combine head and tail (if there are actually Markers left in the tail) - int size = markers.markers_array.size(); - temp_markers_array.resize(size); - for (int i = until_frame; i < size; ++i) - { - if (markers.markers_array[i]) - { - last_marker++; // make new id for old Marker - temp_markers_array[i] = last_marker; - temp_notes.push_back(markers.notes[markers.markers_array[i]]); // take note from old Markers and add it to the end of the head - } - } - // 4 - save result - markers.markers_array = temp_markers_array; - markers.notes = temp_notes; - } - } else - { - // end frame was not specified, consider this as "copy all" - markers.markers_array = source.markers_array; - markers.notes = source.notes; - } + markers.markers_array = source.markers_array; + markers.notes = source.notes; } -// return true if any difference in markers_array is found, comparing to markers.markers_array +// return true only when difference is found before end frame (not including end frame) bool MARKERS_MANAGER::checkMarkersDiff(MARKERS& their_markers) { - if (GetMarkersSize() != their_markers.markers_array.size()) return true; - if (GetNotesSize() != their_markers.notes.size()) return true; - for (int i = markers.markers_array.size()-1; i >= 0; i--) + int end_my = GetMarkersSize() - 1; + int end_their = their_markers.markers_array.size() - 1; + int min_end = end_my; + int i; + // 1 - check if there are any Markers after min_end + if (end_my < end_their) + { + for (i = end_their; i > min_end; i--) + if (their_markers.markers_array[i]) + return true; + } else if (end_my > end_their) + { + min_end = end_their; + for (i = end_my; i > min_end; i--) + if (markers.markers_array[i]) + return true; + } + // 2 - check if there's any difference before min_end + for (i = min_end; i >= 0; i--) { if (markers.markers_array[i] != their_markers.markers_array[i]) return true; - else if (markers.markers_array[i] && markers.notes[markers.markers_array[i]].compare(their_markers.notes[their_markers.markers_array[i]])) + else if (markers.markers_array[i] && // not empty + markers.notes[markers.markers_array[i]].compare(their_markers.notes[their_markers.markers_array[i]])) // notes differ return true; } - // also check if there's difference between 0th notes + // 3 - check if there's difference between 0th Notes if (markers.notes[0].compare(their_markers.notes[0])) return true; - return false; -} -// return true only when difference is found before end frame (not including end frame) -bool MARKERS_MANAGER::checkMarkersDiff(MARKERS& their_markers, int end) -{ - if (end < 0) - return checkMarkersDiff(their_markers); - - if (markers.markers_array.size() != their_markers.markers_array.size() && ((int)markers.markers_array.size()-1 < end || (int)their_markers.markers_array.size()-1 < end)) return true; - for (int i = end-1; i >= 0; i--) - { - if (markers.markers_array[i] != their_markers.markers_array[i]) - return true; - else if (markers.markers_array[i] && markers.notes[markers.markers_array[i]].compare(their_markers.notes[their_markers.markers_array[i]])) - return true; - } + // no difference found return false; } // ------------------------------------------------------------------------------------ diff --git a/src/drivers/win/taseditor/markers_manager.h b/src/drivers/win/taseditor/markers_manager.h index e6b3739a..8e47a10e 100644 --- a/src/drivers/win/taseditor/markers_manager.h +++ b/src/drivers/win/taseditor/markers_manager.h @@ -55,10 +55,9 @@ public: void SetNote(int index, const char* new_text); void MakeCopyTo(MARKERS& destination); - void RestoreFromCopy(MARKERS& source, int until_frame = -1); + void RestoreFromCopy(MARKERS& source); bool checkMarkersDiff(MARKERS& their_markers); - bool checkMarkersDiff(MARKERS& their_markers, int end); void FindSimilar(); void FindNextSimilar(); diff --git a/src/drivers/win/taseditor/snapshot.cpp b/src/drivers/win/taseditor/snapshot.cpp index e769bd61..eecfaeda 100644 --- a/src/drivers/win/taseditor/snapshot.cpp +++ b/src/drivers/win/taseditor/snapshot.cpp @@ -99,13 +99,13 @@ void SNAPSHOT::init(MovieData& md, bool hotchanges, int force_input_type) strftime(description, 10, "%H:%M:%S", timeinfo); } -bool SNAPSHOT::MarkersDifferFromCurrent(int end) +bool SNAPSHOT::MarkersDifferFromCurrent() { - return markers_manager.checkMarkersDiff(my_markers, end); + return markers_manager.checkMarkersDiff(my_markers); } -void SNAPSHOT::copyToMarkers(int end) +void SNAPSHOT::copyToMarkers() { - markers_manager.RestoreFromCopy(my_markers, end); + markers_manager.RestoreFromCopy(my_markers); } MARKERS& SNAPSHOT::GetMarkers() { @@ -439,8 +439,8 @@ int SNAPSHOT::findFirstChange(SNAPSHOT& snap, int start, int end) break; } } - // if current size is less then previous, return last frame (=size-1) as the frame of difference - if (size < snap_end) return size-1; + // if my_size is less then their_size, return last frame + 1 (= size) as the frame of difference + if (size < snap_end) return size; // no changes were found return -1; } @@ -485,11 +485,11 @@ int SNAPSHOT::findFirstChange(MovieData& md, int start, int end) break; } } - // if sizes differ, return last frame from the lesser of them + // if sizes differ, return last frame + 1 from the lesser of them if (size < md.getNumRecords() && end >= size-1) - return size-1; + return size; else if (size > md.getNumRecords() && end >= md.getNumRecords()-1) - return md.getNumRecords()-1; + return md.getNumRecords(); return -1; // no changes were found } diff --git a/src/drivers/win/taseditor/snapshot.h b/src/drivers/win/taseditor/snapshot.h index 21a94500..9a9d89d1 100644 --- a/src/drivers/win/taseditor/snapshot.h +++ b/src/drivers/win/taseditor/snapshot.h @@ -20,8 +20,8 @@ public: SNAPSHOT(); void init(MovieData& md, bool hotchanges, int force_input_type = -1); - bool MarkersDifferFromCurrent(int end = -1); - void copyToMarkers(int end = -1); + bool MarkersDifferFromCurrent(); + void copyToMarkers(); MARKERS& GetMarkers(); void toMovie(MovieData& md, int start = 0, int end = -1);