recording: Complete separation of pasuing execution

Unhooks the execution of emulation pausing from pre-set static frame counts
This commit is contained in:
sonicfind 2020-12-18 12:42:58 -06:00 committed by refractionpcsx2
parent b5b74388f4
commit d49acfc087
4 changed files with 20 additions and 54 deletions

View File

@ -482,7 +482,7 @@ static __fi void VSyncStart(u32 sCycle)
{ {
// It is imperative that any frame locking that must happen occurs before Vsync is started // It is imperative that any frame locking that must happen occurs before Vsync is started
// Not doing so would sacrifice a frame of a savestate-based recording when loading any savestate // Not doing so would sacrifice a frame of a savestate-based recording when loading any savestate
g_InputRecordingControls.HandleFrameCountLocking(); g_InputRecordingControls.HandlePausingAndLocking();
} }
#endif #endif
@ -543,7 +543,7 @@ static __fi void VSyncEnd(u32 sCycle)
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
if (g_Conf->EmuOptions.EnableRecordingTools) if (g_Conf->EmuOptions.EnableRecordingTools)
{ {
g_InputRecordingControls.HandleFrameAdvanceAndPausing(); g_InputRecordingControls.CheckPauseStatus();
} }
#endif #endif

View File

@ -46,15 +46,8 @@ void SaveStateBase::InputRecordingFreeze()
// 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.IsInitialLoad()) if (g_InputRecording.IsInitialLoad())
g_InputRecording.SetupInitialState(g_FrameCount); g_InputRecording.SetupInitialState(g_FrameCount);
else if (g_InputRecording.IsActive()) else if (g_InputRecording.IsActive() && IsLoading())
{ g_InputRecording.SetFrameCounter(g_FrameCount);
// Explicitly set the frame change tracking variable as to not
// detect saving or loading a savestate as a frame being drawn
g_InputRecordingControls.SetFrameCountTracker(g_FrameCount);
if (IsLoading())
g_InputRecording.SetFrameCounter(g_FrameCount);
}
} }
#endif #endif
} }
@ -186,7 +179,7 @@ void InputRecording::IncrementFrameCounter()
switch (state) switch (state)
{ {
case InputRecordingMode::Recording: case InputRecordingMode::Recording:
GetInputRecordingData().SetTotalFrames(frameCounter); inputRecordingData.SetTotalFrames(frameCounter);
[[fallthrough]]; [[fallthrough]];
case InputRecordingMode::Replaying: case InputRecordingMode::Replaying:
if (frameCounter == inputRecordingData.GetTotalFrames()) if (frameCounter == inputRecordingData.GetTotalFrames())
@ -264,11 +257,11 @@ void InputRecording::SetToReplayMode()
void InputRecording::SetFrameCounter(u32 newGFrameCount) void InputRecording::SetFrameCounter(u32 newGFrameCount)
{ {
if (newGFrameCount > startingFrame + (u32)g_InputRecording.GetInputRecordingData().GetTotalFrames()) if (newGFrameCount > startingFrame + (u32)inputRecordingData.GetTotalFrames())
{ {
inputRec::consoleLog("Warning, you've loaded PCSX2 emulation to a point after the end of the original recording. This should be avoided."); inputRec::consoleLog("Warning, you've loaded PCSX2 emulation to a point after the end of the original recording. This should be avoided.");
inputRec::consoleLog("Savestate's framecount has been ignored."); inputRec::consoleLog("Savestate's framecount has been ignored.");
frameCounter = g_InputRecording.GetInputRecordingData().GetTotalFrames(); frameCounter = inputRecordingData.GetTotalFrames();
if (state == InputRecordingMode::Replaying) if (state == InputRecordingMode::Replaying)
SetToRecordMode(); SetToRecordMode();
incrementUndo = false; incrementUndo = false;
@ -283,7 +276,7 @@ void InputRecording::SetFrameCounter(u32 newGFrameCount)
} }
else if (newGFrameCount == 0 && state == InputRecordingMode::Recording) else if (newGFrameCount == 0 && state == InputRecordingMode::Recording)
SetToReplayMode(); SetToReplayMode();
frameCounter = static_cast<s32>(newGFrameCount - startingFrame); frameCounter = newGFrameCount - (s32)startingFrame;
incrementUndo = true; incrementUndo = true;
} }
} }
@ -316,7 +309,6 @@ void InputRecording::SetupInitialState(u32 newStartingFrame)
SetToReplayMode(); SetToReplayMode();
} }
g_InputRecordingControls.DisableFrameAdvance();
if (inputRecordingData.FromSaveState()) if (inputRecordingData.FromSaveState())
inputRec::consoleLog(fmt::format("Internal Starting Frame: {}", startingFrame)); inputRec::consoleLog(fmt::format("Internal Starting Frame: {}", startingFrame));
frameCounter = 0; frameCounter = 0;

View File

@ -29,7 +29,7 @@
InputRecordingControls g_InputRecordingControls; InputRecordingControls g_InputRecordingControls;
void InputRecordingControls::HandleFrameAdvanceAndPausing() void InputRecordingControls::CheckPauseStatus()
{ {
// We do not want to increment/advance anything while the frame lock mechanism is active // We do not want to increment/advance anything while the frame lock mechanism is active
if (frameLock) if (frameLock)
@ -58,21 +58,14 @@ void InputRecordingControls::HandleFrameAdvanceAndPausing()
pauseEmulation = true; pauseEmulation = true;
} }
} }
// Pause emulation if we need to (either due to frame advancing, or pause has been explicitly toggled on)
if (pauseEmulation && CoreThread.IsOpen() && CoreThread.IsRunning())
{
emulationCurrentlyPaused = true;
CoreThread.PauseSelf();
}
} }
void InputRecordingControls::HandleFrameCountLocking() void InputRecordingControls::HandlePausingAndLocking()
{ {
// Explicit frame locking // Explicit frame locking
if (frameLock) if (frameLock)
{ {
if (g_FrameCount == frameCountTracker) if (g_FrameCount == frameLockTracker)
{ {
frameLock = false; frameLock = false;
Resume(); Resume();
@ -83,11 +76,7 @@ void InputRecordingControls::HandleFrameCountLocking()
CoreThread.PauseSelf(); CoreThread.PauseSelf();
} }
} }
// Soft frame locking due to a savestate else if (pauseEmulation && CoreThread.IsOpen() && CoreThread.IsRunning())
//
// This must be done here and not somewhere else as emulation would advance a single frame
// after loading a savestate even with emulation already paused
else if (g_FrameCount == frameCountTracker && pauseEmulation)
{ {
emulationCurrentlyPaused = true; emulationCurrentlyPaused = true;
CoreThread.PauseSelf(); CoreThread.PauseSelf();
@ -156,16 +145,6 @@ void InputRecordingControls::Resume()
resumeEmulation = true; resumeEmulation = true;
} }
void InputRecordingControls::SetFrameCountTracker(u32 newFrame)
{
frameCountTracker = newFrame;
}
void InputRecordingControls::DisableFrameAdvance()
{
frameAdvancing = false;
}
void InputRecordingControls::TogglePause() void InputRecordingControls::TogglePause()
{ {
if (pauseEmulation && if (pauseEmulation &&
@ -198,7 +177,8 @@ void InputRecordingControls::RecordModeToggle()
void InputRecordingControls::Lock(u32 frame) void InputRecordingControls::Lock(u32 frame)
{ {
frameLock = true; frameLock = true;
frameCountTracker = frame; frameLockTracker = frame;
frameAdvancing = false;
//Ensures that g_frameCount can be used to resume emulation after a fast/full boot //Ensures that g_frameCount can be used to resume emulation after a fast/full boot
if (!g_InputRecording.GetInputRecordingData().FromSaveState()) if (!g_InputRecording.GetInputRecordingData().FromSaveState())
g_FrameCount = frame + 1; g_FrameCount = frame + 1;

View File

@ -22,18 +22,18 @@ class InputRecordingControls
public: public:
// Intended to be called at the end of each frame, but will no-op if frame lock is active // Intended to be called at the end of each frame, but will no-op if frame lock is active
// //
// Will pause emulation if: // Will set the pausing parameters for emulation if:
// - The InputRecordingControls::FrameAdvance was hit on the previous frame // - The InputRecordingControls::FrameAdvance was hit on the previous frame
// - Emulation was explicitly paused using InputRecordingControls::TogglePause // - Emulation was explicitly paused using InputRecordingControls::TogglePause
// - We are replaying an input recording and have hit the end // - We are replaying an input recording and have hit the end
void HandleFrameAdvanceAndPausing(); void CheckPauseStatus();
// When loading a recording file or booting with a recording active, lock will be enabled. // When loading a recording file or booting with a recording active, lock will be enabled.
// Emulation will be forced into and remain in a paused state until the transition in progress // Emulation will be forced into and remain in a paused state until the transition in progress
// has completed - signaled when g_framecount and frameCountTracker are equal // has completed - signaled when g_framecount and frameCountTracker are equal
// //
// Additonally, this function will ensure emulation stays paused after loading a savestate // This function also handles actually pausing emulation when told to
void HandleFrameCountLocking(); void HandlePausingAndLocking();
// Called much more frequently than HandleFrameAdvanceAndPausing, instead of being per frame // Called much more frequently than HandleFrameAdvanceAndPausing, instead of being per frame
// this hooks into pcsx2's main App event handler as it has to be able to resume emulation // this hooks into pcsx2's main App event handler as it has to be able to resume emulation
@ -58,10 +58,6 @@ public:
void PauseImmediately(); void PauseImmediately();
// Resume emulation when the next pcsx2 App event is handled // Resume emulation when the next pcsx2 App event is handled
void Resume(); void Resume();
void SetFrameCountTracker(u32 newFrame);
// Sets frameAdvancing variable to false
// Used to restrict a frameAdvanceTracker value from transferring between recordings
void DisableFrameAdvance();
// Alternates emulation between a paused and unpaused state // Alternates emulation between a paused and unpaused state
void TogglePause(); void TogglePause();
// Switches between recording and replaying the active input recording file // Switches between recording and replaying the active input recording file
@ -77,10 +73,6 @@ private:
// Indicates on the next VSync if we are frame advancing, this value // Indicates on the next VSync if we are frame advancing, this value
// and should be cleared once a single frame has passed // and should be cleared once a single frame has passed
bool frameAdvancing = false; bool frameAdvancing = false;
// The input recording frame that frame advancing began on
s32 frameAdvanceMarker = 0;
// Used to detect if the internal PCSX2 g_FrameCount has changed
u32 frameCountTracker = -1;
// Indicates if we intend to call CoreThread.PauseSelf() on the current or next available vsync // Indicates if we intend to call CoreThread.PauseSelf() on the current or next available vsync
bool pauseEmulation = false; bool pauseEmulation = false;
// Indicates if we intend to call CoreThread.Resume() when the next pcsx2 App event is handled // Indicates if we intend to call CoreThread.Resume() when the next pcsx2 App event is handled
@ -89,6 +81,8 @@ private:
bool switchToReplay = false; bool switchToReplay = false;
// Used to stop recording frames from incrementing during a reset // Used to stop recording frames from incrementing during a reset
bool frameLock = false; bool frameLock = false;
// The frame value to use as the frame lock reset point
u32 frameLockTracker = 0;
}; };
extern InputRecordingControls g_InputRecordingControls; extern InputRecordingControls g_InputRecordingControls;