From c98b90a4e217da7403fbfcf5046494d97c4e5c5f Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Wed, 15 Jun 2022 20:46:41 -0400 Subject: [PATCH] input-rec: cleanup irrelevant input recording controls --- pcsx2/Recording/InputRecordingControls.cpp | 218 +++++---------------- pcsx2/Recording/InputRecordingControls.h | 89 ++------- 2 files changed, 72 insertions(+), 235 deletions(-) diff --git a/pcsx2/Recording/InputRecordingControls.cpp b/pcsx2/Recording/InputRecordingControls.cpp index 58194de794..4e3e7d8131 100644 --- a/pcsx2/Recording/InputRecordingControls.cpp +++ b/pcsx2/Recording/InputRecordingControls.cpp @@ -218,7 +218,6 @@ void InputRecordingControls::StopCapture() const #else -#include "Counters.h" #include "DebugTools/Debug.h" #include "MemoryTypes.h" @@ -228,196 +227,87 @@ void InputRecordingControls::StopCapture() const #include "VMManager.h" -InputRecordingControls g_InputRecordingControls; - -void InputRecordingControls::CheckPauseStatus() +void InputRecordingControls::toggleRecordMode() { - frame_advance_frame_counter++; - if (frameAdvancing && frame_advance_frame_counter >= frames_per_frame_advance) + // TODO - this needs to be fixed + // NOTE - delete logic here that prevented switching to replay immediately until frame was complete + // Has to be a better new way to do such a thing + // + // Set a lambda (or list of lambdas) to be executed on the next vsync perhaps? + if (isReplaying()) { - frameAdvancing = false; - pauseEmulation = true; - } - - if (g_InputRecording.IsActive()) - { - g_InputRecording.IncrementFrameCounter(); - - if (switchToReplay) - { - g_InputRecording.SetToReplayMode(); - switchToReplay = false; - } - - if (IsFinishedReplaying() || g_InputRecording.GetFrameCounter() == INT_MAX) - { - if (!pauseEmulation) - pauseEmulation = true; - StopCapture(); - } - } - g_InputRecording.LogAndRedraw(); -} - -void InputRecordingControls::HandlePausingAndLocking() -{ - // Explicit frame locking - if (frameLock) - { - if (g_FrameCount == frameLockTracker) - { - frameLock = false; - Resume(); - } - else if (!emulationCurrentlyPaused && (VMManager::GetState() == VMState::Running || VMManager::GetState() != VMState::Paused)) - { - emulationCurrentlyPaused = true; - VMManager::SetPaused(true); - } - } - else if (pauseEmulation && (VMManager::GetState() == VMState::Running || VMManager::GetState() != VMState::Paused)) - { - emulationCurrentlyPaused = true; - VMManager::SetPaused(true); - } -} - -void InputRecordingControls::ResumeCoreThreadIfStarted() -{ - if (resumeEmulation && (VMManager::GetState() == VMState::Running || VMManager::GetState() == VMState::Paused)) - { - VMManager::SetPaused(false); - resumeEmulation = false; - emulationCurrentlyPaused = false; - } -} - -void InputRecordingControls::FrameAdvance() -{ - if (!IsFinishedReplaying()) - { - frameAdvancing = true; - frame_advance_frame_counter = 0; - Resume(); + setRecordMode(); } else { - g_InputRecording.SetToRecordMode(); + setReplayMode(); } } -void InputRecordingControls::setFrameAdvanceAmount(int amount) -{ - frames_per_frame_advance = amount; -} - -bool InputRecordingControls::IsFrameAdvancing() -{ - return frameAdvancing; -} - -bool InputRecordingControls::IsPaused() -{ - return emulationCurrentlyPaused && VMManager::GetState() == VMState::Paused; -} - -void InputRecordingControls::Pause() -{ - pauseEmulation = true; - resumeEmulation = false; -} - -void InputRecordingControls::PauseImmediately() -{ - if (VMManager::GetState() != VMState::Paused) - { - Pause(); - if ((VMManager::GetState() == VMState::Running || VMManager::GetState() == VMState::Paused)) - { - emulationCurrentlyPaused = true; - VMManager::SetPaused(true); - } - } -} - -void InputRecordingControls::Resume() -{ - if (!IsFinishedReplaying()) - { - pauseEmulation = false; - resumeEmulation = true; - } - else - g_InputRecording.SetToRecordMode(); -} - -void InputRecordingControls::ResumeImmediately() +void InputRecordingControls::setRecordMode() { if (VMManager::GetState() == VMState::Paused) { - Resume(); - if ((VMManager::GetState() == VMState::Running || VMManager::GetState() == VMState::Paused)) - { - emulationCurrentlyPaused = false; - VMManager::SetPaused(false); - } - } -} - -void InputRecordingControls::TogglePause() -{ - if (!pauseEmulation || !IsFinishedReplaying()) - { - resumeEmulation = pauseEmulation; - pauseEmulation = !pauseEmulation; - inputRec::log(pauseEmulation ? "Paused Emulation" : "Resumed Emulation"); + m_state = Mode::Recording; + InputRec::log("Record mode ON"); } else - g_InputRecording.SetToRecordMode(); -} - -void InputRecordingControls::RecordModeToggle() -{ - if (g_InputRecording.IsReplaying()) - g_InputRecording.SetToRecordMode(); - else if (g_InputRecording.IsRecording()) { - if (IsPaused() || g_InputRecording.GetFrameCounter() < g_InputRecording.GetInputRecordingData().GetTotalFrames()) - g_InputRecording.SetToReplayMode(); - else - switchToReplay = true; + m_controlQueue.push([&]() { + m_state = Mode::Recording; + InputRec::log("Record mode ON"); + }); } } -void InputRecordingControls::Lock(u32 frame) +void InputRecordingControls::setReplayMode() { - frameLock = true; - frameLockTracker = frame; - frameAdvancing = false; - // Ensures that g_frameCount can be used to resume emulation after a fast/full boot - if (!g_InputRecording.GetInputRecordingData().FromSaveState()) + if (VMManager::GetState() == VMState::Paused) { - g_FrameCount = frame + 1; + m_state = Mode::Replaying; + InputRec::log("Replay mode ON"); + } + else + { + m_controlQueue.push([&]() { + m_state = Mode::Replaying; + InputRec::log("Replay mode ON"); + }); } } -bool InputRecordingControls::IsFinishedReplaying() const +bool InputRecordingControls::isReplaying() const { - return g_InputRecording.IsReplaying() && - g_InputRecording.GetFrameCounter() >= g_InputRecording.GetInputRecordingData().GetTotalFrames(); + return m_state == Mode::Replaying; } -void InputRecordingControls::StopCapture() const +void InputRecordingControls::processControlQueue() { - // TODO - Vaser - Is capturing supported in Qt yet - Check - /*if (MainEmuFrame* mainFrame = GetMainFramePtr()) + while (!m_controlQueue.empty()) { - if (mainFrame->IsCapturing()) - { - mainFrame->VideoCaptureToggle(); - inputRec::log("Capture completed"); - } - }*/ + m_controlQueue.front()(); + m_controlQueue.pop(); + } } +bool InputRecordingControls::isRecording() const +{ + return m_state == Mode::Recording; +} + + +// TODO - Once there is GS Capture support again +//void InputRecordingControls::StopCapture() const +//{ +// // TODO - Vaser - Is capturing supported in Qt yet - Check +// /*if (MainEmuFrame* mainFrame = GetMainFramePtr()) +// { +// if (mainFrame->IsCapturing()) +// { +// mainFrame->VideoCaptureToggle(); +// inputRec::log("Capture completed"); +// } +// }*/ +//} + #endif \ No newline at end of file diff --git a/pcsx2/Recording/InputRecordingControls.h b/pcsx2/Recording/InputRecordingControls.h index bacff89e20..6fb1b1818d 100644 --- a/pcsx2/Recording/InputRecordingControls.h +++ b/pcsx2/Recording/InputRecordingControls.h @@ -101,85 +101,32 @@ extern InputRecordingControls g_InputRecordingControls; #else +#include + +// TODO: +// - configure frame advance amount + class InputRecordingControls { public: - // Intended to be called at the end of each frame, but will no-op if frame lock is active - // - // 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 CheckPauseStatus(); + enum class Mode + { + Recording, + Replaying, + }; - // 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 - // - // This function also handles actually pausing emulation when told to - void HandlePausingAndLocking(); + void toggleRecordMode(); + void setRecordMode(); + void setReplayMode(); - // 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 - // when drawing frames has compltely stopped - // - // Resumes emulation if: - // - CoreThread is currently open and paused - // - We've signaled emulation to be resumed via TogglePause or FrameAdvancing - void ResumeCoreThreadIfStarted(); + bool isRecording() const; + bool isReplaying() const; - // Resume emulation (incase the emulation is currently paused) and pause after a single frame has passed - void FrameAdvance(); - void setFrameAdvanceAmount(int amount); - // Returns true if emulation is currently set up to frame advance. - bool IsFrameAdvancing(); - // Returns true if the input recording has been paused, which can occur: - // - After a single frame has passed after InputRecordingControls::FrameAdvance - // - Explicitly paused via an InputRecordingControls function - bool IsPaused(); - // Pause emulation at the next available Vsync - void Pause(); - // Pause emulation immediately, not waiting for the next Vsync - void PauseImmediately(); - // Resume emulation when the next pcsx2 App event is handled - void Resume(); - /** - * @brief Resumes emulation immediately, don't wait until the next VSync - */ - void ResumeImmediately(); - // Alternates emulation between a paused and unpaused state - void TogglePause(); - // Switches between recording and replaying the active input recording file - void RecordModeToggle(); - // Enables the frame locking mechanism so that when recordings are loaded - // or when processing a reboot with a recording active that no frames are - // lost in prior emulation - void Lock(u32 frame); + void processControlQueue(); private: - // Indicates if the input recording controls have explicitly paused emulation or not - bool emulationCurrentlyPaused = false; - // 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; - u32 frame_advance_frame_counter = 0; - u32 frames_per_frame_advance = 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 - bool resumeEmulation = false; - // Indicates to switch to replay mode after the next vsync - 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; - - bool IsFinishedReplaying() const; - // Calls mainEmuFrame's videoCaptureToggle to end a capture if active - void StopCapture() const; + Mode m_state = Mode::Replaying; + std::queue> m_controlQueue; }; -extern InputRecordingControls g_InputRecordingControls; - #endif