input-rec: cleanup irrelevant input recording controls

This commit is contained in:
Tyler Wilding 2022-06-15 20:46:41 -04:00 committed by refractionpcsx2
parent c5298cf12d
commit c98b90a4e2
2 changed files with 72 additions and 235 deletions

View File

@ -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

View File

@ -101,85 +101,32 @@ extern InputRecordingControls g_InputRecordingControls;
#else
#include <queue>
// 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<std::function<void()>> m_controlQueue;
};
extern InputRecordingControls g_InputRecordingControls;
#endif