mirror of https://github.com/PCSX2/pcsx2.git
recording: Lock frameCounter incrementation on initial recording file load or during full/fast boot
Ensures that no frames of input are skipped over on the initial load of a recording file or during a fast/full boot when a recording file is active. Improved consistency.
This commit is contained in:
parent
5c5d3a770f
commit
f881bd9bd6
|
@ -49,7 +49,7 @@ void SaveStateBase::InputRecordingFreeze()
|
|||
else if (g_InputRecording.IsActive())
|
||||
{
|
||||
// Explicitly set the frame change tracking variable as to not
|
||||
// detect loading a savestate as a frame being drawn
|
||||
// detect saving or loading a savestate as a frame being drawn
|
||||
g_InputRecordingControls.SetFrameCountTracker(g_FrameCount);
|
||||
|
||||
if (IsLoading())
|
||||
|
@ -77,11 +77,11 @@ void Pcsx2App::RecordingReset()
|
|||
}
|
||||
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);
|
||||
g_InputRecordingControls.Lock(0, false);
|
||||
}
|
||||
else
|
||||
g_InputRecordingControls.Resume();
|
||||
}
|
||||
|
||||
InputRecording g_InputRecording;
|
||||
|
@ -138,7 +138,7 @@ void InputRecording::ControllerInterrupt(u8 &data, u8 &port, u16 &bufCount, u8 b
|
|||
}
|
||||
}
|
||||
|
||||
u32 InputRecording::GetFrameCounter()
|
||||
s32 InputRecording::GetFrameCounter()
|
||||
{
|
||||
return frameCounter;
|
||||
}
|
||||
|
@ -218,13 +218,7 @@ void InputRecording::SetToReplayMode()
|
|||
}
|
||||
|
||||
void InputRecording::SetFrameCounter(u32 newGFrameCount)
|
||||
{
|
||||
// Forces inputRecording to wait for a confirmed pause before resetting
|
||||
// frameCounter to the proper value. Ensures that any lingering emulation
|
||||
// before the load doesn't increment the already reset value
|
||||
const bool initiallyPaused = g_InputRecordingControls.IsRecordingPaused();
|
||||
if (!initiallyPaused)
|
||||
g_InputRecordingControls.PauseImmediately();
|
||||
{
|
||||
if (newGFrameCount > startingFrame + g_InputRecording.GetInputRecordingData().GetTotalFrames())
|
||||
{
|
||||
recordingConLog(L"[REC]: Warning, you've loaded PCSX2 emulation to a point after the end of the original recording. This should be avoided.\n");
|
||||
|
@ -246,10 +240,12 @@ void InputRecording::SetFrameCounter(u32 newGFrameCount)
|
|||
SetToReplayMode();
|
||||
}
|
||||
}
|
||||
else if (newGFrameCount == 0 && state == InputRecordingMode::Recording)
|
||||
{
|
||||
SetToReplayMode();
|
||||
}
|
||||
frameCounter = static_cast<s32>(newGFrameCount - startingFrame);
|
||||
incrementUndo = true;
|
||||
if (!initiallyPaused)
|
||||
g_InputRecordingControls.Resume();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,6 +259,7 @@ void InputRecording::SetStartingFrame(u32 newStartingFrame)
|
|||
}
|
||||
frameCounter = 0;
|
||||
initialLoad = false;
|
||||
g_InputRecordingControls.Lock(startingFrame, inputRecordingData.FromSaveState());
|
||||
}
|
||||
|
||||
void InputRecording::Stop()
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
void ControllerInterrupt(u8 &data, u8 &port, u16 &BufCount, u8 buf[]);
|
||||
|
||||
// The running frame counter for the input recording
|
||||
u32 GetFrameCounter();
|
||||
s32 GetFrameCounter();
|
||||
|
||||
InputRecordingFile &GetInputRecordingData();
|
||||
|
||||
|
|
|
@ -36,10 +36,28 @@ void InputRecordingControls::HandleFrameAdvanceAndPausing()
|
|||
// often this is twice per frame but this may vary as Counters.cpp mentions the
|
||||
// vsync timing can change.
|
||||
//
|
||||
// When loading a recording file or rebooting 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.
|
||||
if (frameLock)
|
||||
{
|
||||
if (!emulationCurrentlyPaused && CoreThread.IsOpen() && CoreThread.IsRunning())
|
||||
{
|
||||
pauseEmulation = true;
|
||||
emulationCurrentlyPaused = true;
|
||||
CoreThread.PauseSelf();
|
||||
}
|
||||
else if (g_FrameCount == frameCountTracker)
|
||||
{
|
||||
frameLock = false;
|
||||
g_InputRecordingControls.Resume();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// As a safeguard, use the global g_FrameCount to know when the frame counter has truly changed.
|
||||
//
|
||||
//
|
||||
// NOTE - Do not mutate g_FrameCount or use it's value to set the input recording's internal frame counter
|
||||
if (frameCountTracker != g_FrameCount)
|
||||
else if (frameCountTracker != g_FrameCount)
|
||||
{
|
||||
frameCountTracker = g_FrameCount;
|
||||
g_InputRecording.IncrementFrameCounter();
|
||||
|
@ -60,7 +78,7 @@ void InputRecordingControls::HandleFrameAdvanceAndPausing()
|
|||
switchToReplay = false;
|
||||
}
|
||||
|
||||
if (g_InputRecording.IsReplaying() && g_InputRecording.GetFrameCounter() >= g_InputRecording.GetInputRecordingData().GetTotalFrames())
|
||||
if (g_InputRecording.IsReplaying() && g_InputRecording.GetFrameCounter() >= (s32)g_InputRecording.GetInputRecordingData().GetTotalFrames())
|
||||
{
|
||||
pauseEmulation = true;
|
||||
}
|
||||
|
@ -92,7 +110,7 @@ void InputRecordingControls::ResumeCoreThreadIfStarted()
|
|||
|
||||
void InputRecordingControls::FrameAdvance()
|
||||
{
|
||||
if (g_InputRecording.IsReplaying() && g_InputRecording.GetFrameCounter() >= g_InputRecording.GetInputRecordingData().GetTotalFrames())
|
||||
if (g_InputRecording.IsReplaying() && g_InputRecording.GetFrameCounter() >= (s32)g_InputRecording.GetInputRecordingData().GetTotalFrames())
|
||||
{
|
||||
g_InputRecording.SetToRecordMode();
|
||||
return;
|
||||
|
@ -120,7 +138,7 @@ void InputRecordingControls::PauseImmediately()
|
|||
return;
|
||||
}
|
||||
Pause();
|
||||
if (pauseEmulation && CoreThread.IsOpen() && CoreThread.IsRunning())
|
||||
if (CoreThread.IsOpen() && CoreThread.IsRunning())
|
||||
{
|
||||
emulationCurrentlyPaused = true;
|
||||
CoreThread.PauseSelf();
|
||||
|
@ -129,7 +147,7 @@ void InputRecordingControls::PauseImmediately()
|
|||
|
||||
void InputRecordingControls::Resume()
|
||||
{
|
||||
if (g_InputRecording.IsReplaying() && g_InputRecording.GetFrameCounter() >= g_InputRecording.GetInputRecordingData().GetTotalFrames())
|
||||
if (g_InputRecording.IsReplaying() && g_InputRecording.GetFrameCounter() >= (s32)g_InputRecording.GetInputRecordingData().GetTotalFrames())
|
||||
{
|
||||
g_InputRecording.SetToRecordMode();
|
||||
return;
|
||||
|
@ -145,7 +163,7 @@ void InputRecordingControls::SetFrameCountTracker(u32 newFrame)
|
|||
|
||||
void InputRecordingControls::TogglePause()
|
||||
{
|
||||
if (pauseEmulation && g_InputRecording.IsReplaying() && g_InputRecording.GetFrameCounter() >= g_InputRecording.GetInputRecordingData().GetTotalFrames())
|
||||
if (pauseEmulation && g_InputRecording.IsReplaying() && g_InputRecording.GetFrameCounter() >= (s32)g_InputRecording.GetInputRecordingData().GetTotalFrames())
|
||||
{
|
||||
g_InputRecording.SetToRecordMode();
|
||||
return;
|
||||
|
@ -156,7 +174,7 @@ void InputRecordingControls::TogglePause()
|
|||
|
||||
void InputRecordingControls::RecordModeToggle()
|
||||
{
|
||||
if (IsRecordingPaused() || g_InputRecording.IsReplaying() || g_InputRecording.GetFrameCounter() < g_InputRecording.GetInputRecordingData().GetTotalFrames())
|
||||
if (IsRecordingPaused() || g_InputRecording.IsReplaying() || g_InputRecording.GetFrameCounter() < (s32)g_InputRecording.GetInputRecordingData().GetTotalFrames())
|
||||
{
|
||||
if (g_InputRecording.IsReplaying())
|
||||
{
|
||||
|
@ -170,4 +188,15 @@ void InputRecordingControls::RecordModeToggle()
|
|||
else if (g_InputRecording.IsRecording())
|
||||
switchToReplay = true;
|
||||
}
|
||||
|
||||
void InputRecordingControls::Lock(u32 frame, bool savestate)
|
||||
{
|
||||
frameLock = true;
|
||||
frameCountTracker = frame;
|
||||
if (!savestate)
|
||||
{
|
||||
//Ensures that g_frameCount can be used to resume emulation after a fast/full boot
|
||||
g_FrameCount = frame + 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -53,6 +53,10 @@ public:
|
|||
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, bool savestate);
|
||||
|
||||
private:
|
||||
// Indicates if the input recording controls have explicitly paused emulation or not
|
||||
|
@ -61,7 +65,7 @@ private:
|
|||
// and should be cleared once a single frame has passed
|
||||
bool frameAdvancing = false;
|
||||
// The input recording frame that frame advancing began on
|
||||
u32 frameAdvanceMarker = 0;
|
||||
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
|
||||
|
@ -70,6 +74,8 @@ private:
|
|||
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;
|
||||
};
|
||||
|
||||
extern InputRecordingControls g_InputRecordingControls;
|
||||
|
|
|
@ -926,7 +926,6 @@ void MainEmuFrame::Menu_Recording_Play_Click(wxCommandEvent &event)
|
|||
m_menuRecording.FindChildItem(MenuId_Recording_New)->Enable(false);
|
||||
m_menuRecording.FindChildItem(MenuId_Recording_Stop)->Enable(true);
|
||||
}
|
||||
g_InputRecordingControls.Resume();
|
||||
}
|
||||
|
||||
void MainEmuFrame::Menu_Recording_Stop_Click(wxCommandEvent &event)
|
||||
|
|
Loading…
Reference in New Issue