* Taseditor: added "Ungreenzone" item to context menu
* Taseditor: added "Config->Enable Greenzoning" * Taseditor: playback/greenzone cleanup * Taseditor: fixed bug when opening TAS Editor in MOVIE_FINISHED mode
This commit is contained in:
parent
42b35b5e23
commit
4c0f74d022
|
@ -353,6 +353,7 @@ static CFGSTRUCT fceuconfig[] = {
|
|||
AC(taseditor_config.findnote_matchcase),
|
||||
AC(taseditor_config.findnote_search_up),
|
||||
AC(taseditor_config.draw_input),
|
||||
AC(taseditor_config.enable_greenzoning),
|
||||
AC(taseditor_config.silent_autosave),
|
||||
AC(taseditor_config.autopause_at_finish),
|
||||
AC(taseditor_config.tooltips),
|
||||
|
|
|
@ -276,6 +276,7 @@ BEGIN
|
|||
MENUITEM "Set max Undo levels", ID_CONFIG_SETMAXUNDOLEVELS,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM "Set Autosave period", ID_CONFIG_SETAUTOSAVEPERIOD,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM MFT_SEPARATOR
|
||||
MENUITEM "Enable Greenzoning", ID_CONFIG_ENABLEGREENZONING,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM "Silent Autosave", ID_CONFIG_SILENTAUTOSAVE,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM "Autofire Pattern skips Lag", ID_CONFIG_PATTERNSKIPSLAG,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM "Auto-adjust Input according to Lag", ID_CONFIG_ADJUSTLAG,MFT_STRING,MFS_ENABLED
|
||||
|
@ -386,6 +387,8 @@ BEGIN
|
|||
MENUITEM "Deselect", ID_SELECTED_DESELECT
|
||||
MENUITEM "Select between Markers\tCtrl+A", ID_SELECTED_SELECTMIDMARKERS
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Ungreenzone", ID_SELECTED_UNGREENZONE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Clear\tDel", ID_CONTEXT_SELECTED_CLEARFRAMES
|
||||
MENUITEM "Delete\tCtrl+Del", ID_CONTEXT_SELECTED_DELETEFRAMES
|
||||
MENUITEM "Clone\tCtrl+Ins", ID_SELECTED_CLONE
|
||||
|
|
|
@ -1141,6 +1141,9 @@
|
|||
#define ID_CONFIG_PATTERNSKIPSLAG 40568
|
||||
#define CLEAR_LOG 40569
|
||||
#define CLOSE_LOG 40570
|
||||
#define ID_SELECTED_UNGREENZONE 40571
|
||||
#define ID_SELECTED_F 40572
|
||||
#define ID_CONFIG_ENABLEGREENZONING 40573
|
||||
#define IDC_DEBUGGER_ICONTRAY 55535
|
||||
#define MW_ValueLabel2 65423
|
||||
#define MW_ValueLabel1 65426
|
||||
|
@ -1151,7 +1154,7 @@
|
|||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 289
|
||||
#define _APS_NEXT_COMMAND_VALUE 40571
|
||||
#define _APS_NEXT_COMMAND_VALUE 40574
|
||||
#define _APS_NEXT_CONTROL_VALUE 1282
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
|
|
|
@ -116,7 +116,7 @@ bool EnterTasEditor()
|
|||
history.init();
|
||||
taseditor_lua.init();
|
||||
// either start new movie or use current movie
|
||||
if (FCEUMOV_Mode(MOVIEMODE_INACTIVE) || currMovieData.savestate.size() != 0)
|
||||
if (!FCEUMOV_Mode(MOVIEMODE_RECORD|MOVIEMODE_PLAY) || currMovieData.savestate.size() != 0)
|
||||
{
|
||||
if (currMovieData.savestate.size() != 0)
|
||||
FCEUD_PrintError("This version of TAS Editor doesn't work with movies starting from savestate.");
|
||||
|
@ -131,6 +131,9 @@ bool EnterTasEditor()
|
|||
FCEUI_StopMovie();
|
||||
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, currFrameCounter - ((int)currMovieData.records.size() - 1));
|
||||
// ensure that movie has correct set of ports/fourscore
|
||||
SetInputType(currMovieData, GetInputType(currMovieData));
|
||||
// force the input configuration stored in the movie to apply to FCEUX config
|
||||
|
|
|
@ -451,7 +451,7 @@ void BOOKMARKS::deploy(int slot)
|
|||
// jump to the target (bookmarked frame)
|
||||
if (greenzone.SavestateIsEmpty(keyframe))
|
||||
greenzone.WriteSavestate(keyframe, bookmarks_array[slot].savestate);
|
||||
playback.jump(keyframe);
|
||||
playback.jump(keyframe, true);
|
||||
// switch current branch to this branch
|
||||
int old_current_branch = branches.GetCurrentBranch();
|
||||
branches.HandleBookmarkDeploy(slot);
|
||||
|
|
|
@ -59,30 +59,20 @@ void GREENZONE::reset()
|
|||
}
|
||||
void GREENZONE::update()
|
||||
{
|
||||
// keep collecting savestates, this function must be called at the end of every frame
|
||||
CollectCurrentState();
|
||||
// keep collecting savestates, this code must be executed at the end of every frame
|
||||
if (taseditor_config.enable_greenzoning)
|
||||
{
|
||||
CollectCurrentState();
|
||||
} else
|
||||
{
|
||||
// just update Greenzone upper limit
|
||||
if (greenZoneCount <= currFrameCounter)
|
||||
greenZoneCount = currFrameCounter + 1;
|
||||
}
|
||||
|
||||
// run cleaning from time to time
|
||||
if (clock() > next_cleaning_time)
|
||||
RunGreenzoneCleaning();
|
||||
}
|
||||
|
||||
void GREENZONE::CollectCurrentState()
|
||||
{
|
||||
// update Greenzone upper limit if needed
|
||||
if (greenZoneCount <= currFrameCounter)
|
||||
greenZoneCount = currFrameCounter + 1;
|
||||
|
||||
if ((int)savestates.size() < greenZoneCount)
|
||||
savestates.resize(greenZoneCount);
|
||||
|
||||
// if frame is not saved - log savestate
|
||||
if (!savestates[currFrameCounter].size())
|
||||
{
|
||||
EMUFILE_MEMORY ms(&savestates[currFrameCounter]);
|
||||
FCEUSS_SaveMS(&ms, Z_DEFAULT_COMPRESSION);
|
||||
ms.trim();
|
||||
}
|
||||
|
||||
// also log lag frames
|
||||
if (currFrameCounter > 0)
|
||||
|
@ -111,21 +101,33 @@ void GREENZONE::CollectCurrentState()
|
|||
}
|
||||
}
|
||||
|
||||
bool GREENZONE::loadTasSavestate(int frame)
|
||||
void GREENZONE::CollectCurrentState()
|
||||
{
|
||||
if (frame < 0 || frame >= currMovieData.getNumRecords())
|
||||
return false;
|
||||
if ((int)savestates.size() <= frame || !savestates[frame].size())
|
||||
return false;
|
||||
if ((int)savestates.size() <= currFrameCounter)
|
||||
savestates.resize(currFrameCounter + 1);
|
||||
// if frame is not saved - log savestate
|
||||
if (!savestates[currFrameCounter].size())
|
||||
{
|
||||
EMUFILE_MEMORY ms(&savestates[currFrameCounter]);
|
||||
FCEUSS_SaveMS(&ms, Z_DEFAULT_COMPRESSION);
|
||||
ms.trim();
|
||||
}
|
||||
if (greenZoneCount <= currFrameCounter)
|
||||
greenZoneCount = currFrameCounter + 1;
|
||||
}
|
||||
|
||||
bool GREENZONE::LoadSavestate(unsigned int frame)
|
||||
{
|
||||
if (frame >= savestates.size() || !savestates[frame].size())
|
||||
return false;
|
||||
EMUFILE_MEMORY ms(&savestates[frame]);
|
||||
return FCEUSS_LoadFP(&ms, SSLOADPARAM_NOBACKUP);
|
||||
}
|
||||
|
||||
void GREENZONE::RunGreenzoneCleaning()
|
||||
{
|
||||
int i = currFrameCounter - taseditor_config.greenzone_capacity;
|
||||
bool changed = false;
|
||||
int i = currFrameCounter - taseditor_config.greenzone_capacity;
|
||||
if (i <= 0) goto finish; // zeroth frame should not be cleaned
|
||||
int limit;
|
||||
// 2x of 1/2
|
||||
|
@ -133,11 +135,8 @@ void GREENZONE::RunGreenzoneCleaning()
|
|||
if (limit < 0) limit = 0;
|
||||
for (; i > limit; i--)
|
||||
{
|
||||
if ((i & 0x1) && savestates[i].size())
|
||||
{
|
||||
ClearSavestateAndFreeMemory(i);
|
||||
changed = true;
|
||||
}
|
||||
if (i & 0x1)
|
||||
changed = changed | ClearSavestateAndFreeMemory(i);
|
||||
}
|
||||
if (i < 0) goto finish;
|
||||
// 4x of 1/4
|
||||
|
@ -145,11 +144,8 @@ void GREENZONE::RunGreenzoneCleaning()
|
|||
if (limit < 0) limit = 0;
|
||||
for (; i > limit; i--)
|
||||
{
|
||||
if ((i & 0x3) && savestates[i].size())
|
||||
{
|
||||
ClearSavestateAndFreeMemory(i);
|
||||
changed = true;
|
||||
}
|
||||
if (i & 0x3)
|
||||
changed = changed | ClearSavestateAndFreeMemory(i);
|
||||
}
|
||||
if (i < 0) goto finish;
|
||||
// 8x of 1/8
|
||||
|
@ -157,11 +153,8 @@ void GREENZONE::RunGreenzoneCleaning()
|
|||
if (limit < 0) limit = 0;
|
||||
for (; i > limit; i--)
|
||||
{
|
||||
if ((i & 0x7) && savestates[i].size())
|
||||
{
|
||||
ClearSavestateAndFreeMemory(i);
|
||||
changed = true;
|
||||
}
|
||||
if (i & 0x7)
|
||||
changed = changed | ClearSavestateAndFreeMemory(i);
|
||||
}
|
||||
if (i < 0) goto finish;
|
||||
// 16x of 1/16
|
||||
|
@ -169,20 +162,13 @@ void GREENZONE::RunGreenzoneCleaning()
|
|||
if (limit < 0) limit = 0;
|
||||
for (; i > limit; i--)
|
||||
{
|
||||
if ((i & 0xF) && savestates[i].size())
|
||||
{
|
||||
ClearSavestateAndFreeMemory(i);
|
||||
changed = true;
|
||||
}
|
||||
if (i & 0xF)
|
||||
changed = changed | ClearSavestateAndFreeMemory(i);
|
||||
}
|
||||
// clear all remaining
|
||||
for (; i > 0; i--)
|
||||
{
|
||||
if (savestates[i].size())
|
||||
{
|
||||
ClearSavestateAndFreeMemory(i);
|
||||
changed = true;
|
||||
}
|
||||
changed = changed | ClearSavestateAndFreeMemory(i);
|
||||
}
|
||||
finish:
|
||||
if (changed)
|
||||
|
@ -194,14 +180,48 @@ finish:
|
|||
next_cleaning_time = clock() + TIME_BETWEEN_CLEANINGS;
|
||||
}
|
||||
|
||||
void GREENZONE::ClearSavestate(int index)
|
||||
// returns true if actually cleared savestate data
|
||||
bool GREENZONE::ClearSavestate(unsigned int index)
|
||||
{
|
||||
savestates[index].resize(0);
|
||||
if (index < savestates.size() && savestates[index].size())
|
||||
{
|
||||
savestates[index].resize(0);
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void GREENZONE::ClearSavestateAndFreeMemory(int index)
|
||||
bool GREENZONE::ClearSavestateAndFreeMemory(unsigned int index)
|
||||
{
|
||||
savestates[index].swap(std::vector<uint8>());
|
||||
if (index < savestates.size() && savestates[index].size())
|
||||
{
|
||||
savestates[index].swap(std::vector<uint8>());
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void GREENZONE::UnGreenzoneSelectedFrames()
|
||||
{
|
||||
SelectionFrames* current_selection = selection.MakeStrobe();
|
||||
if (current_selection->size() == 0) return;
|
||||
bool changed = false;
|
||||
int size = savestates.size();
|
||||
int start_index = *current_selection->begin();
|
||||
int end_index = *current_selection->rbegin();
|
||||
SelectionFrames::reverse_iterator current_selection_rend = current_selection->rend();
|
||||
// degreenzone frames, going backwards
|
||||
for (SelectionFrames::reverse_iterator it(current_selection->rbegin()); it != current_selection_rend; it++)
|
||||
changed = changed | ClearSavestateAndFreeMemory(*it);
|
||||
if (changed)
|
||||
{
|
||||
piano_roll.RedrawList();
|
||||
bookmarks.RedrawBookmarksList();
|
||||
}
|
||||
}
|
||||
|
||||
void GREENZONE::save(EMUFILE *os, bool really_save)
|
||||
|
@ -216,10 +236,12 @@ void GREENZONE::save(EMUFILE *os, bool really_save)
|
|||
write32le(greenZoneCount, os);
|
||||
// write Playback cursor position
|
||||
write32le(currFrameCounter, os);
|
||||
CollectCurrentState();
|
||||
// write savestates
|
||||
int frame, size;
|
||||
int last_tick = 0;
|
||||
RunGreenzoneCleaning();
|
||||
if (greenZoneCount > (int)savestates.size()) greenZoneCount = savestates.size();
|
||||
for (frame = 0; frame < greenZoneCount; ++frame)
|
||||
{
|
||||
// update TASEditor progressbar from time to time
|
||||
|
@ -248,6 +270,7 @@ void GREENZONE::save(EMUFILE *os, bool really_save)
|
|||
if (currFrameCounter > 0)
|
||||
{
|
||||
// write ONE savestate for currFrameCounter
|
||||
CollectCurrentState();
|
||||
int size = savestates[currFrameCounter].size();
|
||||
write32le(size, os);
|
||||
os->fwrite(&savestates[currFrameCounter][0], size);
|
||||
|
@ -291,7 +314,7 @@ bool GREENZONE::load(EMUFILE *is, unsigned int offset)
|
|||
savestates[frame].resize(size);
|
||||
if (is->fread(&savestates[frame][0], size) == size)
|
||||
{
|
||||
if (loadTasSavestate(currFrameCounter))
|
||||
if (LoadSavestate(currFrameCounter))
|
||||
{
|
||||
FCEU_printf("No Greenzone in the file\n");
|
||||
return false;
|
||||
|
@ -359,12 +382,12 @@ bool GREENZONE::load(EMUFILE *is, unsigned int offset)
|
|||
if (prev_frame+1 == greenZoneCount)
|
||||
{
|
||||
// everything went fine - load savestate at cursor position
|
||||
if (loadTasSavestate(currFrameCounter))
|
||||
if (LoadSavestate(currFrameCounter))
|
||||
return false;
|
||||
}
|
||||
// uh, okay, but maybe we managed to read at least something useful from the file
|
||||
// first see if original position of currFrameCounter was read successfully
|
||||
if (loadTasSavestate(currFrameCounter))
|
||||
if (LoadSavestate(currFrameCounter))
|
||||
{
|
||||
greenZoneCount = prev_frame+1; // cut greenZoneCount to last good frame
|
||||
FCEU_printf("Greenzone loaded partially\n");
|
||||
|
@ -373,7 +396,7 @@ bool GREENZONE::load(EMUFILE *is, unsigned int offset)
|
|||
// then at least jump to some frame that was read successfully
|
||||
for (; prev_frame >= 0; prev_frame--)
|
||||
{
|
||||
if (loadTasSavestate(prev_frame))
|
||||
if (LoadSavestate(prev_frame))
|
||||
{
|
||||
currFrameCounter = prev_frame;
|
||||
greenZoneCount = prev_frame+1; // cut greenZoneCount to this good frame
|
||||
|
@ -425,7 +448,7 @@ void GREENZONE::AdjustUp()
|
|||
Invalidate(first_input_changes);
|
||||
bool emu_was_paused = (FCEUI_EmulationPaused() != 0);
|
||||
int saved_pause_frame = playback.GetPauseFrame();
|
||||
playback.jump(first_input_changes);
|
||||
playback.EnsurePlaybackIsInsideGreenzone();
|
||||
if (saved_pause_frame >= 0)
|
||||
playback.SeekingStart(saved_pause_frame);
|
||||
if (emu_was_paused)
|
||||
|
@ -462,7 +485,7 @@ void GREENZONE::AdjustDown()
|
|||
Invalidate(first_input_chanes);
|
||||
bool emu_was_paused = (FCEUI_EmulationPaused() != 0);
|
||||
int saved_pause_frame = playback.GetPauseFrame();
|
||||
playback.jump(first_input_chanes);
|
||||
playback.EnsurePlaybackIsInsideGreenzone();
|
||||
if (saved_pause_frame >= 0)
|
||||
playback.SeekingStart(saved_pause_frame);
|
||||
if (emu_was_paused)
|
||||
|
@ -483,17 +506,14 @@ void GREENZONE::InvalidateAndCheck(int after)
|
|||
{
|
||||
if (after >= currMovieData.getNumRecords())
|
||||
after = currMovieData.getNumRecords() - 1;
|
||||
// clear all savestates that became irrelevant
|
||||
for (int i = savestates.size() - 1; i > after; i--)
|
||||
ClearSavestate(i);
|
||||
if (greenZoneCount > after + 1 || currFrameCounter > after)
|
||||
{
|
||||
// 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
|
||||
// either set Playback cursor to be inside the Greenzone or run seeking to restore Playback cursor position
|
||||
if (currFrameCounter >= greenZoneCount)
|
||||
{
|
||||
if (playback.GetPauseFrame() >= 0 && !FCEUI_EmulationPaused())
|
||||
|
@ -504,10 +524,10 @@ void GREENZONE::InvalidateAndCheck(int after)
|
|||
{
|
||||
playback.SetLostPosition(currFrameCounter);
|
||||
if (taseditor_config.restore_position)
|
||||
// start seeking
|
||||
// start seeking to the green arrow
|
||||
playback.jump(playback.GetLostPosition());
|
||||
else
|
||||
playback.jump(greenZoneCount - 1);
|
||||
playback.EnsurePlaybackIsInsideGreenzone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -523,14 +543,11 @@ void GREENZONE::Invalidate(int after)
|
|||
{
|
||||
if (after >= currMovieData.getNumRecords())
|
||||
after = currMovieData.getNumRecords() - 1;
|
||||
// clear all savestates that became irrelevant
|
||||
for (int i = savestates.size() - 1; i > after; i--)
|
||||
ClearSavestate(i);
|
||||
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++;
|
||||
}
|
||||
|
@ -568,9 +585,9 @@ void GREENZONE::WriteSavestate(int frame, std::vector<uint8>& savestate)
|
|||
greenZoneCount = frame + 1;
|
||||
}
|
||||
|
||||
bool GREENZONE::SavestateIsEmpty(int frame)
|
||||
bool GREENZONE::SavestateIsEmpty(unsigned int frame)
|
||||
{
|
||||
if (frame < greenZoneCount && frame < (int)savestates.size() && savestates[frame].size())
|
||||
if ((int)frame < greenZoneCount && frame < savestates.size() && savestates[frame].size())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
|
|
@ -25,14 +25,11 @@ public:
|
|||
void save(EMUFILE *os, bool really_save = true);
|
||||
bool load(EMUFILE *is, unsigned int offset);
|
||||
|
||||
void AdjustUp();
|
||||
void AdjustDown();
|
||||
|
||||
bool loadTasSavestate(int frame);
|
||||
bool LoadSavestate(unsigned int frame);
|
||||
|
||||
void RunGreenzoneCleaning();
|
||||
void ClearSavestate(int index);
|
||||
void ClearSavestateAndFreeMemory(int index);
|
||||
|
||||
void UnGreenzoneSelectedFrames();
|
||||
|
||||
void InvalidateAndCheck(int after);
|
||||
void Invalidate(int after);
|
||||
|
@ -42,13 +39,18 @@ public:
|
|||
int GetSize();
|
||||
std::vector<uint8>& GetSavestate(int frame);
|
||||
void WriteSavestate(int frame, std::vector<uint8>& savestate);
|
||||
bool SavestateIsEmpty(int frame);
|
||||
bool SavestateIsEmpty(unsigned int frame);
|
||||
|
||||
// saved data
|
||||
LAGLOG laglog;
|
||||
|
||||
private:
|
||||
void CollectCurrentState();
|
||||
bool ClearSavestate(unsigned int index);
|
||||
bool ClearSavestateAndFreeMemory(unsigned int index);
|
||||
|
||||
void AdjustUp();
|
||||
void AdjustDown();
|
||||
|
||||
// saved data
|
||||
int greenZoneCount;
|
||||
|
|
|
@ -240,7 +240,7 @@ void PLAYBACK::update()
|
|||
}
|
||||
|
||||
// called after saving the project, because saving uses the progressbar for itself
|
||||
void PLAYBACK::updateProgressbar()
|
||||
void PLAYBACK::UpdateProgressbar()
|
||||
{
|
||||
if (pause_frame)
|
||||
{
|
||||
|
@ -438,11 +438,10 @@ void PLAYBACK::StartFromZero()
|
|||
currMovieData.insertEmpty(-1, 1);
|
||||
}
|
||||
|
||||
// external interface for sending Playback cursor
|
||||
void PLAYBACK::jump(int frame, bool execute_lua, bool follow_cursor)
|
||||
void PLAYBACK::EnsurePlaybackIsInsideGreenzone(bool execute_lua, bool follow_cursor)
|
||||
{
|
||||
if (frame < 0) return;
|
||||
if (JumpToFrame(frame))
|
||||
// set the Playback cursor to the frame or at least above the frame
|
||||
if (SetPlaybackAboveOrToFrame(greenzone.GetSize() - 1))
|
||||
{
|
||||
// since the game state was changed by this jump, we must update possible Lua callbacks and other tools that would normally only update in FCEUI_Emulate
|
||||
if (execute_lua)
|
||||
|
@ -452,44 +451,63 @@ void PLAYBACK::jump(int frame, bool execute_lua, bool follow_cursor)
|
|||
Update_RAM_Search(); // Update_RAM_Watch() is also called.
|
||||
}
|
||||
}
|
||||
// internal interface
|
||||
// returns true if the game state was changed (loaded)
|
||||
bool PLAYBACK::JumpToFrame(int index)
|
||||
|
||||
// an interface for sending Playback cursor to any frame
|
||||
void PLAYBACK::jump(int frame, bool force_reload, bool execute_lua, bool follow_cursor)
|
||||
{
|
||||
if (index >= greenzone.GetSize())
|
||||
if (frame < 0) return;
|
||||
|
||||
// 1 - set the Playback cursor to the frame or at least above the frame
|
||||
if (SetPlaybackAboveOrToFrame(frame, force_reload))
|
||||
{
|
||||
// make jump outside Greenzone
|
||||
if (currFrameCounter == greenzone.GetSize() - 1)
|
||||
// since the game state was changed by this jump, we must update possible Lua callbacks and other tools that would normally only update in FCEUI_Emulate
|
||||
if (execute_lua)
|
||||
ForceExecuteLuaFrameFunctions();
|
||||
if (follow_cursor)
|
||||
piano_roll.FollowPlaybackIfNeeded();
|
||||
Update_RAM_Search(); // Update_RAM_Watch() is also called.
|
||||
}
|
||||
|
||||
// 2 - seek from the current frame if we still aren't at the needed frame
|
||||
if (frame > currFrameCounter)
|
||||
{
|
||||
SeekingStart(frame);
|
||||
} else
|
||||
{
|
||||
// the Playback is already at the needed frame
|
||||
if (pause_frame) // if Playback was seeking, pause emulation right here
|
||||
SeekingStop();
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if the game state was changed (loaded)
|
||||
bool PLAYBACK::SetPlaybackAboveOrToFrame(int frame, bool force_reload)
|
||||
{
|
||||
bool state_changed = false;
|
||||
// search backwards for an earlier frame with valid savestate
|
||||
int i = greenzone.GetSize() - 1;
|
||||
if (i > frame)
|
||||
i = frame;
|
||||
for (; i >= 0; i--)
|
||||
{
|
||||
if (!force_reload && !state_changed && i == currFrameCounter)
|
||||
{
|
||||
// seek there from the end of Greenzone
|
||||
SeekingStart(index);
|
||||
return false; // game state was not changed
|
||||
} else if (JumpToFrame(greenzone.GetSize() - 1))
|
||||
// we can remain at current game state
|
||||
break;
|
||||
} else if (!greenzone.SavestateIsEmpty(i))
|
||||
{
|
||||
// seek there from the end of Greenzone
|
||||
SeekingStart(index);
|
||||
return true; // game state was loaded
|
||||
state_changed = true; // after we once tried loading a savestate, we cannot use currFrameCounter state anymore, because the game state might have been corrupted by this loading attempt
|
||||
if (greenzone.LoadSavestate(i))
|
||||
break;
|
||||
}
|
||||
}
|
||||
// make jump inside greenzone
|
||||
if (greenzone.loadTasSavestate(index))
|
||||
{
|
||||
// successfully restored emulator state at this frame
|
||||
// if Playback was seeking, pause emulation right here
|
||||
if (pause_frame)
|
||||
SeekingStop();
|
||||
return true;
|
||||
}
|
||||
// search for an earlier frame with savestate
|
||||
int i = (index > 0) ? index-1 : 0;
|
||||
for (; i >= 0; i--)
|
||||
if (greenzone.loadTasSavestate(i)) break;
|
||||
if (i < 0)
|
||||
StartFromZero(); // couldn't find a savestate
|
||||
// continue from the frame
|
||||
if (index != currFrameCounter)
|
||||
SeekingStart(index);
|
||||
return true;
|
||||
{
|
||||
// couldn't find a savestate
|
||||
StartFromZero();
|
||||
state_changed = true;
|
||||
}
|
||||
return state_changed;
|
||||
}
|
||||
|
||||
void PLAYBACK::SetLostPosition(int frame)
|
||||
|
|
|
@ -16,9 +16,10 @@ public:
|
|||
void reset();
|
||||
void update();
|
||||
|
||||
void jump(int frame, bool execute_lua = true, bool follow_cursor = true);
|
||||
void EnsurePlaybackIsInsideGreenzone(bool execute_lua = true, bool follow_cursor = true);
|
||||
void jump(int frame, bool force_reload = false, bool execute_lua = true, bool follow_cursor = true);
|
||||
|
||||
void updateProgressbar();
|
||||
void UpdateProgressbar();
|
||||
|
||||
void SeekingStart(int finish_frame);
|
||||
void SeekingStop();
|
||||
|
@ -55,7 +56,7 @@ public:
|
|||
HWND hwndPlaybackMarker, hwndPlaybackMarkerEdit;
|
||||
|
||||
private:
|
||||
bool JumpToFrame(int index);
|
||||
bool SetPlaybackAboveOrToFrame(int frame, bool force_reload = false);
|
||||
|
||||
int pause_frame;
|
||||
int lost_position_frame;
|
||||
|
|
|
@ -68,6 +68,7 @@ TASEDITOR_CONFIG::TASEDITOR_CONFIG()
|
|||
findnote_search_up = false;
|
||||
enable_auto_function = true;
|
||||
draw_input = true;
|
||||
enable_greenzoning = true;
|
||||
silent_autosave = true;
|
||||
autopause_at_finish = true;
|
||||
tooltips = true;
|
||||
|
|
|
@ -66,6 +66,7 @@ public:
|
|||
bool findnote_search_up;
|
||||
bool enable_auto_function;
|
||||
bool draw_input;
|
||||
bool enable_greenzoning;
|
||||
bool silent_autosave;
|
||||
bool autopause_at_finish;
|
||||
bool tooltips;
|
||||
|
|
|
@ -243,7 +243,9 @@ int TASEDITOR_LUA::getplaybacktarget()
|
|||
void TASEDITOR_LUA::setplayback(int frame)
|
||||
{
|
||||
if (FCEUMOV_Mode(MOVIEMODE_TASEDITOR))
|
||||
playback.jump(frame, false, true);
|
||||
// force reload if sending to the same frame as current frame
|
||||
// but don't trigger lua registered functions
|
||||
playback.jump(frame, true, false, true);
|
||||
}
|
||||
|
||||
// taseditor.stopseeking()
|
||||
|
|
|
@ -167,7 +167,7 @@ bool TASEDITOR_PROJECT::save(const char* different_name, bool save_binary, bool
|
|||
write32le(selection_offset, ofs);
|
||||
// finish
|
||||
delete ofs;
|
||||
playback.updateProgressbar();
|
||||
playback.UpdateProgressbar();
|
||||
// also set project.changed to false, unless it was SaveCompact
|
||||
if (!different_name)
|
||||
reset();
|
||||
|
|
|
@ -564,6 +564,7 @@ void TASEDITOR_WINDOW::UpdateCheckedItems()
|
|||
CheckMenuItem(hmenu, ID_VIEW_ENABLEHOTCHANGES, taseditor_config.enable_hot_changes?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_VIEW_JUMPWHENMAKINGUNDO, taseditor_config.jump_to_undo?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_VIEW_FOLLOWMARKERNOTECONTEXT, taseditor_config.follow_note_context?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_ENABLEGREENZONING, taseditor_config.enable_greenzoning?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_SILENTAUTOSAVE, taseditor_config.silent_autosave?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_PATTERNSKIPSLAG, taseditor_config.pattern_skips_lag?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_ADJUSTLAG, taseditor_config.adjust_input_due_to_lag?MF_CHECKED : MF_UNCHECKED);
|
||||
|
@ -923,6 +924,12 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
|
|||
else if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
|
||||
selection.SelectAll();
|
||||
break;
|
||||
case ID_SELECTED_UNGREENZONE:
|
||||
if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
|
||||
{
|
||||
greenzone.UnGreenzoneSelectedFrames();
|
||||
}
|
||||
break;
|
||||
case ACCEL_CTRL_X:
|
||||
case ID_EDIT_CUT:
|
||||
if (markers_manager.marker_note_edit == MARKER_NOTE_EDIT_UPPER)
|
||||
|
@ -1089,6 +1096,14 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
|
|||
}
|
||||
break;
|
||||
}
|
||||
case ID_CONFIG_ENABLEGREENZONING:
|
||||
taseditor_config.enable_greenzoning ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
break;
|
||||
case ID_CONFIG_SILENTAUTOSAVE:
|
||||
taseditor_config.silent_autosave ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
break;
|
||||
case ID_CONFIG_BRANCHESRESTOREFULLMOVIE:
|
||||
taseditor_config.branch_full_movie ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
|
@ -1131,10 +1146,6 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
|
|||
taseditor_config.draw_input ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
break;
|
||||
case ID_CONFIG_SILENTAUTOSAVE:
|
||||
taseditor_config.silent_autosave ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
break;
|
||||
case ID_CONFIG_AUTOPAUSEATTHEENDOFMOVIE:
|
||||
taseditor_config.autopause_at_finish ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
//#define PUBLIC_RELEASE // uncommend this when making a public release, but comment back before committing
|
||||
|
||||
#ifndef __FCEU_VERSION
|
||||
#define __FCEU_VERSION
|
||||
|
||||
|
|
Loading…
Reference in New Issue