diff --git a/pcsx2/Counters.cpp b/pcsx2/Counters.cpp index f181d0c8db..e282e7edef 100644 --- a/pcsx2/Counters.cpp +++ b/pcsx2/Counters.cpp @@ -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 // Not doing so would sacrifice a frame of a savestate-based recording when loading any savestate - g_InputRecordingControls.HandleFrameCountLocking(); + g_InputRecordingControls.HandlePausingAndLocking(); } #endif @@ -543,7 +543,7 @@ static __fi void VSyncEnd(u32 sCycle) #ifndef DISABLE_RECORDING if (g_Conf->EmuOptions.EnableRecordingTools) { - g_InputRecordingControls.HandleFrameAdvanceAndPausing(); + g_InputRecordingControls.CheckPauseStatus(); } #endif diff --git a/pcsx2/Recording/InputRecording.cpp b/pcsx2/Recording/InputRecording.cpp index 9d8e4bfd5b..b56b389f4f 100644 --- a/pcsx2/Recording/InputRecording.cpp +++ b/pcsx2/Recording/InputRecording.cpp @@ -46,15 +46,8 @@ void SaveStateBase::InputRecordingFreeze() // marker has not been set (which comes from the save-state), we initialize it. if (g_InputRecording.IsInitialLoad()) g_InputRecording.SetupInitialState(g_FrameCount); - else if (g_InputRecording.IsActive()) - { - // 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); - } + else if (g_InputRecording.IsActive() && IsLoading()) + g_InputRecording.SetFrameCounter(g_FrameCount); } #endif } @@ -186,7 +179,7 @@ void InputRecording::IncrementFrameCounter() switch (state) { case InputRecordingMode::Recording: - GetInputRecordingData().SetTotalFrames(frameCounter); + inputRecordingData.SetTotalFrames(frameCounter); [[fallthrough]]; case InputRecordingMode::Replaying: if (frameCounter == inputRecordingData.GetTotalFrames()) @@ -264,11 +257,11 @@ void InputRecording::SetToReplayMode() 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("Savestate's framecount has been ignored."); - frameCounter = g_InputRecording.GetInputRecordingData().GetTotalFrames(); + frameCounter = inputRecordingData.GetTotalFrames(); if (state == InputRecordingMode::Replaying) SetToRecordMode(); incrementUndo = false; @@ -283,7 +276,7 @@ void InputRecording::SetFrameCounter(u32 newGFrameCount) } else if (newGFrameCount == 0 && state == InputRecordingMode::Recording) SetToReplayMode(); - frameCounter = static_cast(newGFrameCount - startingFrame); + frameCounter = newGFrameCount - (s32)startingFrame; incrementUndo = true; } } @@ -316,7 +309,6 @@ void InputRecording::SetupInitialState(u32 newStartingFrame) SetToReplayMode(); } - g_InputRecordingControls.DisableFrameAdvance(); if (inputRecordingData.FromSaveState()) inputRec::consoleLog(fmt::format("Internal Starting Frame: {}", startingFrame)); frameCounter = 0; diff --git a/pcsx2/Recording/InputRecordingControls.cpp b/pcsx2/Recording/InputRecordingControls.cpp index fdf8e39421..89e79a18de 100644 --- a/pcsx2/Recording/InputRecordingControls.cpp +++ b/pcsx2/Recording/InputRecordingControls.cpp @@ -29,7 +29,7 @@ InputRecordingControls g_InputRecordingControls; -void InputRecordingControls::HandleFrameAdvanceAndPausing() +void InputRecordingControls::CheckPauseStatus() { // We do not want to increment/advance anything while the frame lock mechanism is active if (frameLock) @@ -58,21 +58,14 @@ void InputRecordingControls::HandleFrameAdvanceAndPausing() 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 if (frameLock) { - if (g_FrameCount == frameCountTracker) + if (g_FrameCount == frameLockTracker) { frameLock = false; Resume(); @@ -83,11 +76,7 @@ void InputRecordingControls::HandleFrameCountLocking() CoreThread.PauseSelf(); } } - // Soft frame locking due to a savestate - // - // 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) + else if (pauseEmulation && CoreThread.IsOpen() && CoreThread.IsRunning()) { emulationCurrentlyPaused = true; CoreThread.PauseSelf(); @@ -156,16 +145,6 @@ void InputRecordingControls::Resume() resumeEmulation = true; } -void InputRecordingControls::SetFrameCountTracker(u32 newFrame) -{ - frameCountTracker = newFrame; -} - -void InputRecordingControls::DisableFrameAdvance() -{ - frameAdvancing = false; -} - void InputRecordingControls::TogglePause() { if (pauseEmulation && @@ -198,7 +177,8 @@ void InputRecordingControls::RecordModeToggle() void InputRecordingControls::Lock(u32 frame) { frameLock = true; - frameCountTracker = frame; + frameLockTracker = frame; + frameAdvancing = false; //Ensures that g_frameCount can be used to resume emulation after a fast/full boot if (!g_InputRecording.GetInputRecordingData().FromSaveState()) g_FrameCount = frame + 1; diff --git a/pcsx2/Recording/InputRecordingControls.h b/pcsx2/Recording/InputRecordingControls.h index 6e0a55fd4b..e1dcea0bff 100644 --- a/pcsx2/Recording/InputRecordingControls.h +++ b/pcsx2/Recording/InputRecordingControls.h @@ -22,18 +22,18 @@ class InputRecordingControls public: // 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 // - Emulation was explicitly paused using InputRecordingControls::TogglePause // - 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. // 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 // - // Additonally, this function will ensure emulation stays paused after loading a savestate - void HandleFrameCountLocking(); + // This function also handles actually pausing emulation when told to + void HandlePausingAndLocking(); // 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 @@ -58,10 +58,6 @@ public: void PauseImmediately(); // Resume emulation when the next pcsx2 App event is handled 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 void TogglePause(); // 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 // and should be cleared once a single frame has passed 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 bool pauseEmulation = false; // Indicates if we intend to call CoreThread.Resume() when the next pcsx2 App event is handled @@ -89,6 +81,8 @@ private: bool switchToReplay = false; // Used to stop recording frames from incrementing during a reset bool frameLock = false; + // The frame value to use as the frame lock reset point + u32 frameLockTracker = 0; }; extern InputRecordingControls g_InputRecordingControls;