recording: Handle Boots & Savestates similarly

* Replaces the savestate load flag with a more general initial load flag to be used by full/fast boots and savestates.
* Have the Pcsx2App::ResetRecordingCounter() method mirror the similar method of the savestate class.
This commit is contained in:
sonicfind 2020-09-13 11:48:12 -05:00 committed by refractionpcsx2
parent b591c5e9ab
commit 975a37f209
5 changed files with 50 additions and 52 deletions

View File

@ -39,10 +39,10 @@ void SaveStateBase::InputRecordingFreeze()
Freeze(g_FrameCount); Freeze(g_FrameCount);
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
// Loading a save-state is an asynchronous task, if we are playing a recording // Loading a save-state is an asynchronous task. If we are playing a recording
// that starts from a savestate (not power-on) and the starting (pcsx2 internal) frame // that starts from a savestate (not power-on) and the starting (pcsx2 internal) frame
// marker has not been set (which comes from the save-state), we initialize it. // marker has not been set (which comes from the save-state), we initialize it.
if (g_InputRecording.IsSavestateInitializing()) if (g_InputRecording.IsInitialLoad())
{ {
g_InputRecording.SetStartingFrame(g_FrameCount); g_InputRecording.SetStartingFrame(g_FrameCount);
} }
@ -52,12 +52,7 @@ void SaveStateBase::InputRecordingFreeze()
// detect loading a savestate as a frame being drawn // detect loading a savestate as a frame being drawn
g_InputRecordingControls.SetFrameCountTracker(g_FrameCount); g_InputRecordingControls.SetFrameCountTracker(g_FrameCount);
// If the starting savestate has been loaded (on a current-frame recording) and a save-state is loaded while recording if (IsLoading())
// or replaying the movie it is an undo operation that needs to be tracked.
//
// The reason it's also an undo operation when replaying is because the user can switch modes at any time
// and begin undoing. While this isn't impossible to resolve, it's a separate issue and not of the utmost importance (this is just interesting metadata)
if (IsLoading() && !g_InputRecording.IsSavestateInitializing())
{ {
g_InputRecording.SetFrameCounter(g_FrameCount); g_InputRecording.SetFrameCounter(g_FrameCount);
} }
@ -66,6 +61,28 @@ void SaveStateBase::InputRecordingFreeze()
} }
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
// Save or load PCSX2's global frame counter (g_FrameCount) along with each full/fast boot
//
// This is to prevent any inaccuracy issues caused by having a different
// internal emulation frame count than what it was at the beginning of the
// original recording
void Pcsx2App::RecordingReset()
{
// Booting is an asynchronous task. If we are playing a recording
// that starts from power-on and the starting (pcsx2 internal) frame
// marker has not been set, we initialize it.
if (g_InputRecording.IsInitialLoad())
{
g_InputRecording.SetStartingFrame(0);
}
else if (g_InputRecording.IsActive())
{
// Explicitly set the frame change tracking variable as to not
// detect rebooting as a frame being drawn
g_InputRecordingControls.SetFrameCountTracker(g_FrameCount);
g_InputRecording.SetFrameCounter(0);
}
}
InputRecording g_InputRecording; InputRecording g_InputRecording;
@ -157,9 +174,9 @@ bool InputRecording::IsActive()
return state != InputRecordingMode::NotActive; return state != InputRecordingMode::NotActive;
} }
bool InputRecording::IsSavestateInitializing() bool InputRecording::IsInitialLoad()
{ {
return savestateInitializing; return initialLoad;
} }
bool InputRecording::IsReplaying() bool InputRecording::IsReplaying()
@ -212,11 +229,6 @@ void InputRecording::RecordModeToggle()
} }
} }
void InputRecording::SavestateInitialized()
{
savestateInitializing = false;
}
void InputRecording::SetFrameCounter(u32 newGFrameCount) void InputRecording::SetFrameCounter(u32 newGFrameCount)
{ {
// Forces inputRecording to wait for a confirmed pause before resetting // Forces inputRecording to wait for a confirmed pause before resetting
@ -256,13 +268,13 @@ void InputRecording::SetFrameCounter(u32 newGFrameCount)
void InputRecording::SetStartingFrame(u32 newStartingFrame) void InputRecording::SetStartingFrame(u32 newStartingFrame)
{ {
startingFrame = newStartingFrame; startingFrame = newStartingFrame;
if (savestateInitializing) if (inputRecordingData.FromSaveState())
{ {
// TODO - make a function of my own to simplify working with the logging macros // TODO - make a function of my own to simplify working with the logging macros
recordingConLog(wxString::Format(L"[REC]: Internal Starting Frame: %d\n", startingFrame)); recordingConLog(wxString::Format(L"[REC]: Internal Starting Frame: %d\n", startingFrame));
savestateInitializing = false;
} }
frameCounter = 0; frameCounter = 0;
initialLoad = false;
} }
void InputRecording::Stop() void InputRecording::Stop()
@ -277,15 +289,22 @@ void InputRecording::Stop()
bool InputRecording::Create(wxString FileName, bool fromSaveState, wxString authorName) bool InputRecording::Create(wxString FileName, bool fromSaveState, wxString authorName)
{ {
savestateInitializing = fromSaveState;
if (!inputRecordingData.OpenNew(FileName, fromSaveState)) if (!inputRecordingData.OpenNew(FileName, fromSaveState))
{ {
return false; return false;
} }
if (!fromSaveState) initialLoad = true;
if (fromSaveState)
{
if (wxFileExists(FileName + "_SaveState.p2s"))
{
wxCopyFile(FileName + "_SaveState.p2s", FileName + "_SaveState.p2s.bak", true);
}
StateCopy_SaveToFile(FileName + "_SaveState.p2s");
}
else
{ {
SetStartingFrame(0);
sApp.SysExecute(g_Conf->CdvdSource); sApp.SysExecute(g_Conf->CdvdSource);
} }
@ -332,13 +351,12 @@ bool InputRecording::Play(wxString fileName)
inputRecordingData.Close(); inputRecordingData.Close();
return false; return false;
} }
savestateInitializing = true; initialLoad = true;
StateCopy_LoadFromFile(inputRecordingData.GetFilename() + "_SaveState.p2s"); StateCopy_LoadFromFile(inputRecordingData.GetFilename() + "_SaveState.p2s");
} }
else else
{ {
savestateInitializing = false; initialLoad = true;
SetStartingFrame(0);
sApp.SysExecute(g_Conf->CdvdSource); sApp.SysExecute(g_Conf->CdvdSource);
} }

View File

@ -43,10 +43,10 @@ public:
// If there is currently an input recording being played back or actively being recorded // If there is currently an input recording being played back or actively being recorded
bool IsActive(); bool IsActive();
// Whether or not the recording's initial save state has yet to be loaded or saved and // Whether or not the recording's initial state has yet to be loaded or saved and
// the rest of the recording can be initialized // the rest of the recording can be initialized
// This is not applicable to recordings from a "power-on" state // This is not applicable to recordings from a "power-on" state
bool IsSavestateInitializing(); bool IsInitialLoad();
// If there is currently an input recording being played back // If there is currently an input recording being played back
bool IsReplaying(); bool IsReplaying();
@ -66,9 +66,6 @@ public:
// Switches between recording and replaying the active input recording file // Switches between recording and replaying the active input recording file
void RecordModeToggle(); void RecordModeToggle();
// Mark the recording's initial savestate as having been loaded or saved successfully
void SavestateInitialized();
// Set the running frame counter for the input recording to an arbitrary value // Set the running frame counter for the input recording to an arbitrary value
void SetFrameCounter(u32 newGFrameCount); void SetFrameCounter(u32 newGFrameCount);
@ -95,7 +92,7 @@ private:
// DEPRECATED: Slated for removal // DEPRECATED: Slated for removal
bool fInterruptFrame = false; bool fInterruptFrame = false;
InputRecordingFile inputRecordingData; InputRecordingFile inputRecordingData;
bool savestateInitializing = false; bool initialLoad = false;
u32 startingFrame = 0; u32 startingFrame = 0;
s32 frameCounter = 0; s32 frameCounter = 0;
bool incrementUndo = false; bool incrementUndo = false;

View File

@ -138,11 +138,6 @@ bool InputRecordingFile::OpenNew(const wxString path, bool fromSavestate)
if (open(path, true)) if (open(path, true))
{ {
savestate.fromSavestate = true; savestate.fromSavestate = true;
if (wxFileExists(path + "_SaveState.p2s"))
{
wxCopyFile(path + "_SaveState.p2s", path + "_SaveState.p2s.bak", true);
}
StateCopy_SaveToFile(path + "_SaveState.p2s");
return true; return true;
} }
} }

View File

@ -561,6 +561,11 @@ public:
void SysExecute(); void SysExecute();
void SysExecute( CDVD_SourceType cdvdsrc, const wxString& elf_override=wxEmptyString ); void SysExecute( CDVD_SourceType cdvdsrc, const wxString& elf_override=wxEmptyString );
void LogicalVsync(); void LogicalVsync();
#ifndef DISABLE_RECORDING
void RecordingReset();
#endif
SysMainMemory& GetVmReserve(); SysMainMemory& GetVmReserve();
@ -641,10 +646,6 @@ public:
bool OnCmdLineError( wxCmdLineParser& parser ); bool OnCmdLineError( wxCmdLineParser& parser );
bool ParseOverrides( wxCmdLineParser& parser ); bool ParseOverrides( wxCmdLineParser& parser );
#ifndef DISABLE_RECORDING
void ResetRecordingCounter();
#endif
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
void OnAssertFailure( const wxChar *file, int line, const wxChar *func, const wxChar *cond, const wxChar *msg ); void OnAssertFailure( const wxChar *file, int line, const wxChar *func, const wxChar *cond, const wxChar *msg );
#endif #endif

View File

@ -1153,23 +1153,10 @@ void Pcsx2App::SysExecute( CDVD_SourceType cdvdsrc, const wxString& elf_override
{ {
SysExecutorThread.PostEvent( new SysExecEvent_Execute(cdvdsrc, elf_override) ); SysExecutorThread.PostEvent( new SysExecEvent_Execute(cdvdsrc, elf_override) );
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
ResetRecordingCounter(); RecordingReset();
#endif #endif
} }
#ifndef DISABLE_RECORDING
// Sets the frame counter for a running input recording file to the proper displacement
// from the recording's starting frame to the g_framecount of a fresh emulation boot/reboot
// Simply: frameCounter = -startingFrame
void Pcsx2App::ResetRecordingCounter()
{
if (g_InputRecording.IsActive())
{
g_InputRecording.SetFrameCounter(0);
}
}
#endif
// Returns true if there is a "valid" virtual machine state from the user's perspective. This // Returns true if there is a "valid" virtual machine state from the user's perspective. This
// means the user has started the emulator and not issued a full reset. // means the user has started the emulator and not issued a full reset.
// Thread Safety: The state of the system can change in parallel to execution of the // Thread Safety: The state of the system can change in parallel to execution of the