* 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
This commit is contained in:
ansstuff 2012-08-11 19:53:56 +00:00
parent b63ad04f84
commit 61df7ea541
8 changed files with 91 additions and 147 deletions

View File

@ -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();

View File

@ -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<uint8> tmp;
savestates[index].swap(tmp);
}
// this function is used by Bookmark Deploy procedure
void GREENZONE::WriteSavestate(int frame, std::vector<uint8>& 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<uint8>& GREENZONE::GetSavestate(int frame)
{
return savestates[frame];
}
// this function should only be used by Bookmark Deploy procedure
void GREENZONE::WriteSavestate(int frame, std::vector<uint8>& 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;
}

View File

@ -28,8 +28,6 @@ public:
void RunGreenzoneCleaning();
void ClearSavestate(int index);
void WriteSavestate(int frame, std::vector<uint8>& savestate);
void InvalidateAndCheck(int after);
void Invalidate(int after);
@ -38,11 +36,11 @@ public:
int GetSize();
bool GetLagHistoryAtFrame(int frame);
std::vector<uint8>& GetSavestate(int frame);
void WriteSavestate(int frame, std::vector<uint8>& savestate);
bool SavestateIsEmpty(int frame);
private:
void CollectCurrentState();
void storeTasSavestate(int frame);
// saved data
int greenZoneCount;

View File

@ -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

View File

@ -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<int> temp_markers_array;
std::vector<std::string> 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;
}
// ------------------------------------------------------------------------------------

View File

@ -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();

View File

@ -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
}

View File

@ -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);