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);
#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
// 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);
}
@ -52,12 +52,7 @@ void SaveStateBase::InputRecordingFreeze()
// detect loading a savestate as a frame being drawn
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
// 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())
if (IsLoading())
{
g_InputRecording.SetFrameCounter(g_FrameCount);
}
@ -66,6 +61,28 @@ void SaveStateBase::InputRecordingFreeze()
}
#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;
@ -157,9 +174,9 @@ bool InputRecording::IsActive()
return state != InputRecordingMode::NotActive;
}
bool InputRecording::IsSavestateInitializing()
bool InputRecording::IsInitialLoad()
{
return savestateInitializing;
return initialLoad;
}
bool InputRecording::IsReplaying()
@ -212,11 +229,6 @@ void InputRecording::RecordModeToggle()
}
}
void InputRecording::SavestateInitialized()
{
savestateInitializing = false;
}
void InputRecording::SetFrameCounter(u32 newGFrameCount)
{
// Forces inputRecording to wait for a confirmed pause before resetting
@ -256,13 +268,13 @@ void InputRecording::SetFrameCounter(u32 newGFrameCount)
void InputRecording::SetStartingFrame(u32 newStartingFrame)
{
startingFrame = newStartingFrame;
if (savestateInitializing)
if (inputRecordingData.FromSaveState())
{
// 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));
savestateInitializing = false;
}
frameCounter = 0;
initialLoad = false;
}
void InputRecording::Stop()
@ -277,15 +289,22 @@ void InputRecording::Stop()
bool InputRecording::Create(wxString FileName, bool fromSaveState, wxString authorName)
{
savestateInitializing = fromSaveState;
if (!inputRecordingData.OpenNew(FileName, fromSaveState))
{
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);
}
@ -332,13 +351,12 @@ bool InputRecording::Play(wxString fileName)
inputRecordingData.Close();
return false;
}
savestateInitializing = true;
initialLoad = true;
StateCopy_LoadFromFile(inputRecordingData.GetFilename() + "_SaveState.p2s");
}
else
{
savestateInitializing = false;
SetStartingFrame(0);
initialLoad = true;
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
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
// 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
bool IsReplaying();
@ -66,9 +66,6 @@ public:
// Switches between recording and replaying the active input recording file
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
void SetFrameCounter(u32 newGFrameCount);
@ -95,7 +92,7 @@ private:
// DEPRECATED: Slated for removal
bool fInterruptFrame = false;
InputRecordingFile inputRecordingData;
bool savestateInitializing = false;
bool initialLoad = false;
u32 startingFrame = 0;
s32 frameCounter = 0;
bool incrementUndo = false;

View File

@ -138,11 +138,6 @@ bool InputRecordingFile::OpenNew(const wxString path, bool fromSavestate)
if (open(path, 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;
}
}

View File

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