recording: Rearrangements + Formatting

* RecordingReset is now a function of the InputRecording class
* TotalFrames is now signed
* InputRecordingControls refactor, IsRecordingPaused -> IsPaused
* Add check to keep frameCounter from overflowing (not like someone is gonna record a year's worth of inputs though).

* Code Formatting adjustments (more to do in a separate PR)
This commit is contained in:
sonicfind 2020-09-15 22:00:48 -05:00 committed by refractionpcsx2
parent f881bd9bd6
commit 23dba26ba3
10 changed files with 63 additions and 106 deletions

View File

@ -28,11 +28,6 @@
#include <vector> #include <vector>
// Save or load PCSX2's global frame counter (g_FrameCount) along with each savestate
//
// This is to prevent any inaccuracy issues caused by having a different
// internal emulation frame count than what it was at the beginning of the
// original recording
void SaveStateBase::InputRecordingFreeze() void SaveStateBase::InputRecordingFreeze()
{ {
FreezeTag("InputRecording"); FreezeTag("InputRecording");
@ -43,9 +38,7 @@ void SaveStateBase::InputRecordingFreeze()
// that starts from a savestate (not power-on) and the starting (pcsx2 internal) frame // that starts from a savestate (not power-on) and the starting (pcsx2 internal) frame
// 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.SetStartingFrame(g_FrameCount); g_InputRecording.SetStartingFrame(g_FrameCount);
}
else if (g_InputRecording.IsActive()) else if (g_InputRecording.IsActive())
{ {
// Explicitly set the frame change tracking variable as to not // Explicitly set the frame change tracking variable as to not
@ -53,28 +46,21 @@ void SaveStateBase::InputRecordingFreeze()
g_InputRecordingControls.SetFrameCountTracker(g_FrameCount); g_InputRecordingControls.SetFrameCountTracker(g_FrameCount);
if (IsLoading()) if (IsLoading())
{
g_InputRecording.SetFrameCounter(g_FrameCount); g_InputRecording.SetFrameCounter(g_FrameCount);
}
} }
#endif #endif
} }
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
// Save or load PCSX2's global frame counter (g_FrameCount) along with each full/fast boot InputRecording g_InputRecording;
//
// This is to prevent any inaccuracy issues caused by having a different void InputRecording::RecordingReset()
// internal emulation frame count than what it was at the beginning of the
// original recording
void Pcsx2App::RecordingReset()
{ {
// Booting is an asynchronous task. If we are playing a recording // Booting is an asynchronous task. If we are playing a recording
// that starts from power-on and the starting (pcsx2 internal) frame // that starts from power-on and the starting (pcsx2 internal) frame
// marker has not been set, we initialize it. // marker has not been set, we initialize it.
if (g_InputRecording.IsInitialLoad()) if (g_InputRecording.IsInitialLoad())
{
g_InputRecording.SetStartingFrame(0); g_InputRecording.SetStartingFrame(0);
}
else if (g_InputRecording.IsActive()) else if (g_InputRecording.IsActive())
{ {
g_InputRecording.SetFrameCounter(0); g_InputRecording.SetFrameCounter(0);
@ -84,8 +70,6 @@ void Pcsx2App::RecordingReset()
g_InputRecordingControls.Resume(); g_InputRecordingControls.Resume();
} }
InputRecording g_InputRecording;
void InputRecording::ControllerInterrupt(u8 &data, u8 &port, u16 &bufCount, u8 buf[]) void InputRecording::ControllerInterrupt(u8 &data, u8 &port, u16 &bufCount, u8 buf[])
{ {
// TODO - Multi-Tap Support // TODO - Multi-Tap Support
@ -99,9 +83,7 @@ void InputRecording::ControllerInterrupt(u8 &data, u8 &port, u16 &bufCount, u8 b
0x42 is the magic number for the default read query 0x42 is the magic number for the default read query
*/ */
if (bufCount == 1) if (bufCount == 1)
{
fInterruptFrame = data == 0x42; fInterruptFrame = data == 0x42;
}
else if (bufCount == 2) else if (bufCount == 2)
{ {
/* /*
@ -111,11 +93,10 @@ void InputRecording::ControllerInterrupt(u8 &data, u8 &port, u16 &bufCount, u8 b
query is executed, this looks like a sanity check query is executed, this looks like a sanity check
*/ */
if (buf[bufCount] != 0x5A) if (buf[bufCount] != 0x5A)
{
fInterruptFrame = false; fInterruptFrame = false;
} }
} // We do not want to record or save the first two bytes in the data returned from the PAD plugin // We do not want to record or save the first two bytes in the data returned from the PAD plugin
else if (fInterruptFrame && bufCount >= 3 && frameCounter >= 0) else if (fInterruptFrame && bufCount >= 3 && frameCounter >= 0 && frameCounter < INT_MAX)
{ {
// Read or Write // Read or Write
if (state == InputRecordingMode::Recording) if (state == InputRecordingMode::Recording)
@ -131,9 +112,7 @@ void InputRecording::ControllerInterrupt(u8 &data, u8 &port, u16 &bufCount, u8 b
{ {
u8 tmp = 0; u8 tmp = 0;
if (inputRecordingData.ReadKeyBuffer(tmp, frameCounter, port, bufCount - 3)) if (inputRecordingData.ReadKeyBuffer(tmp, frameCounter, port, bufCount - 3))
{
buf[bufCount] = tmp; buf[bufCount] = tmp;
}
} }
} }
} }
@ -156,9 +135,9 @@ u32 InputRecording::GetStartingFrame()
void InputRecording::IncrementFrameCounter() void InputRecording::IncrementFrameCounter()
{ {
frameCounter++; frameCounter++;
if (state == InputRecordingMode::Recording && frameCounter > 0) if (state == InputRecordingMode::Recording)
{ {
GetInputRecordingData().SetTotalFrames((u32)frameCounter); GetInputRecordingData().SetTotalFrames(frameCounter);
if (frameCounter == inputRecordingData.GetTotalFrames()) if (frameCounter == inputRecordingData.GetTotalFrames())
incrementUndo = false; incrementUndo = false;
} }
@ -195,13 +174,10 @@ wxString InputRecording::RecordingModeTitleSegment()
{ {
case InputRecordingMode::Recording: case InputRecordingMode::Recording:
return wxString("Recording"); return wxString("Recording");
break;
case InputRecordingMode::Replaying: case InputRecordingMode::Replaying:
return wxString("Replaying"); return wxString("Replaying");
break;
default: default:
return wxString("No Movie"); return wxString("No Movie");
break;
} }
} }
@ -219,15 +195,13 @@ void InputRecording::SetToReplayMode()
void InputRecording::SetFrameCounter(u32 newGFrameCount) void InputRecording::SetFrameCounter(u32 newGFrameCount)
{ {
if (newGFrameCount > startingFrame + g_InputRecording.GetInputRecordingData().GetTotalFrames()) if (newGFrameCount > startingFrame + (u32)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"); recordingConLog(L"[REC]: Warning, you've loaded PCSX2 emulation to a point after the end of the original recording. This should be avoided.\n");
recordingConLog(L"[REC]: Savestate's framecount has been ignored.\n"); recordingConLog(L"[REC]: Savestate's framecount has been ignored.\n");
frameCounter = g_InputRecording.GetInputRecordingData().GetTotalFrames(); frameCounter = g_InputRecording.GetInputRecordingData().GetTotalFrames();
if (state == InputRecordingMode::Replaying) if (state == InputRecordingMode::Replaying)
{
SetToRecordMode(); SetToRecordMode();
}
incrementUndo = false; incrementUndo = false;
} }
else else
@ -236,14 +210,10 @@ void InputRecording::SetFrameCounter(u32 newGFrameCount)
{ {
recordingConLog(L"[REC]: Warning, you've loaded PCSX2 emulation to a point before the start of the original recording. This should be avoided.\n"); recordingConLog(L"[REC]: Warning, you've loaded PCSX2 emulation to a point before the start of the original recording. This should be avoided.\n");
if (state == InputRecordingMode::Recording) if (state == InputRecordingMode::Recording)
{
SetToReplayMode(); SetToReplayMode();
}
} }
else if (newGFrameCount == 0 && state == InputRecordingMode::Recording) else if (newGFrameCount == 0 && state == InputRecordingMode::Recording)
{
SetToReplayMode(); SetToReplayMode();
}
frameCounter = static_cast<s32>(newGFrameCount - startingFrame); frameCounter = static_cast<s32>(newGFrameCount - startingFrame);
incrementUndo = true; incrementUndo = true;
} }
@ -252,11 +222,9 @@ void InputRecording::SetFrameCounter(u32 newGFrameCount)
void InputRecording::SetStartingFrame(u32 newStartingFrame) void InputRecording::SetStartingFrame(u32 newStartingFrame)
{ {
startingFrame = newStartingFrame; startingFrame = newStartingFrame;
// TODO - make a function of my own to simplify working with the logging macros
if (inputRecordingData.FromSaveState()) if (inputRecordingData.FromSaveState())
{
// TODO - make a function of my own to simplify working with the logging macros
recordingConLog(wxString::Format(L"[REC]: Internal Starting Frame: %d\n", startingFrame)); recordingConLog(wxString::Format(L"[REC]: Internal Starting Frame: %d\n", startingFrame));
}
frameCounter = 0; frameCounter = 0;
initialLoad = false; initialLoad = false;
g_InputRecordingControls.Lock(startingFrame, inputRecordingData.FromSaveState()); g_InputRecordingControls.Lock(startingFrame, inputRecordingData.FromSaveState());
@ -267,40 +235,30 @@ void InputRecording::Stop()
state = InputRecordingMode::NotActive; state = InputRecordingMode::NotActive;
incrementUndo = false; incrementUndo = false;
if (inputRecordingData.Close()) if (inputRecordingData.Close())
{
recordingConLog(L"[REC]: InputRecording Recording Stopped.\n"); recordingConLog(L"[REC]: InputRecording Recording Stopped.\n");
}
} }
bool InputRecording::Create(wxString FileName, bool fromSaveState, wxString authorName) bool InputRecording::Create(wxString FileName, bool fromSaveState, wxString authorName)
{ {
if (!inputRecordingData.OpenNew(FileName, fromSaveState)) if (!inputRecordingData.OpenNew(FileName, fromSaveState))
{
return false; return false;
}
initialLoad = true; initialLoad = true;
if (fromSaveState) if (fromSaveState)
{ {
if (wxFileExists(FileName + "_SaveState.p2s")) if (wxFileExists(FileName + "_SaveState.p2s"))
{
wxCopyFile(FileName + "_SaveState.p2s", FileName + "_SaveState.p2s.bak", true); wxCopyFile(FileName + "_SaveState.p2s", FileName + "_SaveState.p2s.bak", true);
}
StateCopy_SaveToFile(FileName + "_SaveState.p2s"); StateCopy_SaveToFile(FileName + "_SaveState.p2s");
} }
else else
{
sApp.SysExecute(g_Conf->CdvdSource); sApp.SysExecute(g_Conf->CdvdSource);
}
// Set emulator version // Set emulator version
inputRecordingData.GetHeader().SetEmulatorVersion(); inputRecordingData.GetHeader().SetEmulatorVersion();
// Set author name // Set author name
if (!authorName.IsEmpty()) if (!authorName.IsEmpty())
{
inputRecordingData.GetHeader().SetAuthor(authorName); inputRecordingData.GetHeader().SetAuthor(authorName);
}
// Set Game Name // Set Game Name
inputRecordingData.GetHeader().SetGameName(resolveGameName()); inputRecordingData.GetHeader().SetGameName(resolveGameName());
@ -317,9 +275,7 @@ bool InputRecording::Play(wxString fileName)
Stop(); Stop();
if (!inputRecordingData.OpenExisting(fileName)) if (!inputRecordingData.OpenExisting(fileName))
{
return false; return false;
}
// Either load the savestate, or restart the game // Either load the savestate, or restart the game
if (inputRecordingData.FromSaveState()) if (inputRecordingData.FromSaveState())
@ -332,7 +288,8 @@ bool InputRecording::Play(wxString fileName)
} }
if (!wxFileExists(inputRecordingData.GetFilename() + "_SaveState.p2s")) if (!wxFileExists(inputRecordingData.GetFilename() + "_SaveState.p2s"))
{ {
recordingConLog(wxString::Format("[REC]: Could not locate savestate file at location - %s_SaveState.p2s\n", inputRecordingData.GetFilename())); recordingConLog(wxString::Format("[REC]: Could not locate savestate file at location - %s_SaveState.p2s\n",
inputRecordingData.GetFilename()));
inputRecordingData.Close(); inputRecordingData.Close();
return false; return false;
} }
@ -347,12 +304,8 @@ bool InputRecording::Play(wxString fileName)
// Check if the current game matches with the one used to make the original recording // Check if the current game matches with the one used to make the original recording
if (!g_Conf->CurrentIso.IsEmpty()) if (!g_Conf->CurrentIso.IsEmpty())
{
if (resolveGameName() != inputRecordingData.GetHeader().gameName) if (resolveGameName() != inputRecordingData.GetHeader().gameName)
{
recordingConLog(L"[REC]: Recording was possibly constructed for a different game.\n"); recordingConLog(L"[REC]: Recording was possibly constructed for a different game.\n");
}
}
incrementUndo = true; incrementUndo = true;
state = InputRecordingMode::Replaying; state = InputRecordingMode::Replaying;

View File

@ -22,6 +22,13 @@
class InputRecording class InputRecording
{ {
public: public:
// Save or load PCSX2's global frame counter (g_FrameCount) along with each full/fast boot
//
// This is to prevent any inaccuracy issues caused by having a different
// internal emulation frame count than what it was at the beginning of the
// original recording
void RecordingReset();
// Main handler for ingesting input data and either saving it to the recording file (recording) // Main handler for ingesting input data and either saving it to the recording file (recording)
// or mutating it to the contents of the recording file (replaying) // or mutating it to the contents of the recording file (replaying)
void ControllerInterrupt(u8 &data, u8 &port, u16 &BufCount, u8 buf[]); void ControllerInterrupt(u8 &data, u8 &port, u16 &BufCount, u8 buf[]);

View File

@ -60,7 +60,8 @@ void InputRecordingControls::HandleFrameAdvanceAndPausing()
else if (frameCountTracker != g_FrameCount) else if (frameCountTracker != g_FrameCount)
{ {
frameCountTracker = g_FrameCount; frameCountTracker = g_FrameCount;
g_InputRecording.IncrementFrameCounter(); if (g_InputRecording.GetFrameCounter() < INT_MAX)
g_InputRecording.IncrementFrameCounter();
} }
else else
{ {
@ -78,13 +79,13 @@ void InputRecordingControls::HandleFrameAdvanceAndPausing()
switchToReplay = false; switchToReplay = false;
} }
if (g_InputRecording.IsReplaying() && g_InputRecording.GetFrameCounter() >= (s32)g_InputRecording.GetInputRecordingData().GetTotalFrames()) if (g_InputRecording.IsReplaying()
{ && g_InputRecording.GetFrameCounter() >= g_InputRecording.GetInputRecordingData().GetTotalFrames())
pauseEmulation = true; pauseEmulation = true;
}
// If we havn't yet advanced atleast a single frame from when we paused, setup things to be paused // If we havn't yet advanced atleast a single frame from when we paused, setup things to be paused
if (frameAdvancing && frameAdvanceMarker < g_InputRecording.GetFrameCounter()) if (frameAdvancing
&& (frameAdvanceMarker < g_InputRecording.GetFrameCounter() || g_InputRecording.GetFrameCounter() == INT_MAX))
{ {
frameAdvancing = false; frameAdvancing = false;
pauseEmulation = true; pauseEmulation = true;
@ -110,7 +111,8 @@ void InputRecordingControls::ResumeCoreThreadIfStarted()
void InputRecordingControls::FrameAdvance() void InputRecordingControls::FrameAdvance()
{ {
if (g_InputRecording.IsReplaying() && g_InputRecording.GetFrameCounter() >= (s32)g_InputRecording.GetInputRecordingData().GetTotalFrames()) if (g_InputRecording.IsReplaying()
&& g_InputRecording.GetFrameCounter() >= g_InputRecording.GetInputRecordingData().GetTotalFrames())
{ {
g_InputRecording.SetToRecordMode(); g_InputRecording.SetToRecordMode();
return; return;
@ -120,7 +122,7 @@ void InputRecordingControls::FrameAdvance()
Resume(); Resume();
} }
bool InputRecordingControls::IsRecordingPaused() bool InputRecordingControls::IsPaused()
{ {
return (emulationCurrentlyPaused && CoreThread.IsOpen() && CoreThread.IsPaused()); return (emulationCurrentlyPaused && CoreThread.IsOpen() && CoreThread.IsPaused());
} }
@ -134,9 +136,7 @@ void InputRecordingControls::Pause()
void InputRecordingControls::PauseImmediately() void InputRecordingControls::PauseImmediately()
{ {
if (CoreThread.IsPaused()) if (CoreThread.IsPaused())
{
return; return;
}
Pause(); Pause();
if (CoreThread.IsOpen() && CoreThread.IsRunning()) if (CoreThread.IsOpen() && CoreThread.IsRunning())
{ {
@ -147,7 +147,8 @@ void InputRecordingControls::PauseImmediately()
void InputRecordingControls::Resume() void InputRecordingControls::Resume()
{ {
if (g_InputRecording.IsReplaying() && g_InputRecording.GetFrameCounter() >= (s32)g_InputRecording.GetInputRecordingData().GetTotalFrames()) if (g_InputRecording.IsReplaying()
&& g_InputRecording.GetFrameCounter() >= g_InputRecording.GetInputRecordingData().GetTotalFrames())
{ {
g_InputRecording.SetToRecordMode(); g_InputRecording.SetToRecordMode();
return; return;
@ -163,7 +164,8 @@ void InputRecordingControls::SetFrameCountTracker(u32 newFrame)
void InputRecordingControls::TogglePause() void InputRecordingControls::TogglePause()
{ {
if (pauseEmulation && g_InputRecording.IsReplaying() && g_InputRecording.GetFrameCounter() >= (s32)g_InputRecording.GetInputRecordingData().GetTotalFrames()) if (pauseEmulation && g_InputRecording.IsReplaying()
&& g_InputRecording.GetFrameCounter() >= g_InputRecording.GetInputRecordingData().GetTotalFrames())
{ {
g_InputRecording.SetToRecordMode(); g_InputRecording.SetToRecordMode();
return; return;
@ -174,16 +176,13 @@ void InputRecordingControls::TogglePause()
void InputRecordingControls::RecordModeToggle() void InputRecordingControls::RecordModeToggle()
{ {
if (IsRecordingPaused() || g_InputRecording.IsReplaying() || g_InputRecording.GetFrameCounter() < (s32)g_InputRecording.GetInputRecordingData().GetTotalFrames()) if (IsPaused() || g_InputRecording.IsReplaying()
|| g_InputRecording.GetFrameCounter() < g_InputRecording.GetInputRecordingData().GetTotalFrames())
{ {
if (g_InputRecording.IsReplaying()) if (g_InputRecording.IsReplaying())
{
g_InputRecording.SetToRecordMode(); g_InputRecording.SetToRecordMode();
}
else if (g_InputRecording.IsRecording()) else if (g_InputRecording.IsRecording())
{
g_InputRecording.SetToReplayMode(); g_InputRecording.SetToReplayMode();
}
} }
else if (g_InputRecording.IsRecording()) else if (g_InputRecording.IsRecording())
switchToReplay = true; switchToReplay = true;
@ -193,10 +192,8 @@ void InputRecordingControls::Lock(u32 frame, bool savestate)
{ {
frameLock = true; frameLock = true;
frameCountTracker = frame; frameCountTracker = frame;
//Ensures that g_frameCount can be used to resume emulation after a fast/full boot
if (!savestate) if (!savestate)
{
//Ensures that g_frameCount can be used to resume emulation after a fast/full boot
g_FrameCount = frame + 1; g_FrameCount = frame + 1;
}
} }
#endif #endif

View File

@ -40,8 +40,8 @@ public:
void FrameAdvance(); void FrameAdvance();
// Returns true if the input recording has been paused, which can occur: // Returns true if the input recording has been paused, which can occur:
// - After a single frame has passed after InputRecordingControls::FrameAdvance // - After a single frame has passed after InputRecordingControls::FrameAdvance
// - Explicitly paused via InputRecordingControls::TogglePause // - Explicitly paused via an InputRecordingControls function
bool IsRecordingPaused(); bool IsPaused();
// Pause emulation at the next available Vsync // Pause emulation at the next available Vsync
void Pause(); void Pause();
// Pause emulation immediately, not waiting for the next Vsync // Pause emulation immediately, not waiting for the next Vsync

View File

@ -55,12 +55,12 @@ void InputRecordingFileHeader::SetGameName(wxString _gameName)
bool InputRecordingFile::Close() bool InputRecordingFile::Close()
{ {
if (recordingFile == NULL) if (recordingFile == nullptr)
{ {
return false; return false;
} }
fclose(recordingFile); fclose(recordingFile);
recordingFile = NULL; recordingFile = nullptr;
filename = ""; filename = "";
return true; return true;
} }
@ -75,7 +75,7 @@ InputRecordingFileHeader &InputRecordingFile::GetHeader()
return header; return header;
} }
unsigned long &InputRecordingFile::GetTotalFrames() long &InputRecordingFile::GetTotalFrames()
{ {
return totalFrames; return totalFrames;
} }
@ -93,7 +93,7 @@ bool InputRecordingFile::FromSaveState()
void InputRecordingFile::IncrementUndoCount() void InputRecordingFile::IncrementUndoCount()
{ {
undoCount++; undoCount++;
if (recordingFile == NULL) if (recordingFile == nullptr)
{ {
return; return;
} }
@ -160,7 +160,7 @@ bool InputRecordingFile::OpenExisting(const wxString path)
bool InputRecordingFile::ReadKeyBuffer(u8 &result, const uint &frame, const uint port, const uint bufIndex) bool InputRecordingFile::ReadKeyBuffer(u8 &result, const uint &frame, const uint port, const uint bufIndex)
{ {
if (recordingFile == NULL) if (recordingFile == nullptr)
{ {
return false; return false;
} }
@ -174,9 +174,9 @@ bool InputRecordingFile::ReadKeyBuffer(u8 &result, const uint &frame, const uint
return true; return true;
} }
void InputRecordingFile::SetTotalFrames(unsigned long frame) void InputRecordingFile::SetTotalFrames(long frame)
{ {
if (recordingFile == NULL || totalFrames >= frame) if (recordingFile == nullptr || totalFrames >= frame)
{ {
return; return;
} }
@ -187,7 +187,7 @@ void InputRecordingFile::SetTotalFrames(unsigned long frame)
bool InputRecordingFile::WriteHeader() bool InputRecordingFile::WriteHeader()
{ {
if (recordingFile == NULL) if (recordingFile == nullptr)
{ {
return false; return false;
} }
@ -204,7 +204,7 @@ bool InputRecordingFile::WriteHeader()
bool InputRecordingFile::WriteKeyBuffer(const uint &frame, const uint port, const uint bufIndex, const u8 &buf) bool InputRecordingFile::WriteKeyBuffer(const uint &frame, const uint port, const uint bufIndex, const u8 &buf)
{ {
if (recordingFile == NULL) if (recordingFile == nullptr)
{ {
return false; return false;
} }
@ -227,7 +227,7 @@ long InputRecordingFile::getRecordingBlockSeekPoint(const long &frame)
bool InputRecordingFile::verifyRecordingFileHeader() bool InputRecordingFile::verifyRecordingFileHeader()
{ {
if (recordingFile == NULL) if (recordingFile == nullptr)
{ {
return false; return false;
} }

View File

@ -59,7 +59,7 @@ public:
// Retrieve the input recording's header which contains high-level metadata on the recording // Retrieve the input recording's header which contains high-level metadata on the recording
InputRecordingFileHeader &GetHeader(); InputRecordingFileHeader &GetHeader();
// The maximum number of frames, or in other words, the length of the recording // The maximum number of frames, or in other words, the length of the recording
unsigned long &GetTotalFrames(); long &GetTotalFrames();
// The number of times a save-state has been loaded while recording this movie // The number of times a save-state has been loaded while recording this movie
// this is also often referred to as a "re-record" // this is also often referred to as a "re-record"
unsigned long &GetUndoCount(); unsigned long &GetUndoCount();
@ -76,7 +76,7 @@ public:
// the current frame's value from the emulator // the current frame's value from the emulator
bool ReadKeyBuffer(u8 &result, const uint &frame, const uint port, const uint bufIndex); bool ReadKeyBuffer(u8 &result, const uint &frame, const uint port, const uint bufIndex);
// Updates the total frame counter and commit it to the recording file // Updates the total frame counter and commit it to the recording file
void SetTotalFrames(unsigned long frames); void SetTotalFrames(long frames);
// Persist the input recording file header's current state to the file // Persist the input recording file header's current state to the file
bool WriteHeader(); bool WriteHeader();
// Writes the current frame's input data to the file so it can be replayed // Writes the current frame's input data to the file so it can be replayed
@ -99,11 +99,11 @@ private:
InputRecordingFileHeader header; InputRecordingFileHeader header;
wxString filename = ""; wxString filename = "";
FILE * recordingFile = NULL; FILE* recordingFile = nullptr;
InputRecordingSavestate savestate; InputRecordingSavestate savestate;
// An unsigned 32-bit frame limit is equivalent to 2.25 years of continuous 60fps footage // An signed 32-bit frame limit is equivalent to 1.13 years of continuous 60fps footage
unsigned long totalFrames = 0; long totalFrames = 0;
unsigned long undoCount = 0; unsigned long undoCount = 0;
// Calculates the position of the current frame in the input recording // Calculates the position of the current frame in the input recording

View File

@ -154,6 +154,11 @@ protected:
void deci2Freeze(); void deci2Freeze();
// Save or load PCSX2's global frame counter (g_FrameCount) along with each savestate
//
// This is to prevent any inaccuracy issues caused by having a different
// internal emulation frame count than what it was at the beginning of the
// original recording
void InputRecordingFreeze(); void InputRecordingFreeze();
}; };

View File

@ -561,11 +561,6 @@ public:
void SysExecute(); void SysExecute();
void SysExecute( CDVD_SourceType cdvdsrc, const wxString& elf_override=wxEmptyString ); void SysExecute( CDVD_SourceType cdvdsrc, const wxString& elf_override=wxEmptyString );
void LogicalVsync(); void LogicalVsync();
#ifndef DISABLE_RECORDING
void RecordingReset();
#endif
SysMainMemory& GetVmReserve(); SysMainMemory& GetVmReserve();

View File

@ -620,7 +620,7 @@ void Pcsx2App::HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent&
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
if (g_Conf->EmuOptions.EnableRecordingTools) if (g_Conf->EmuOptions.EnableRecordingTools)
{ {
if (g_InputRecordingControls.IsRecordingPaused()) if (g_InputRecordingControls.IsPaused())
{ {
// When the GSFrame CoreThread is paused, so is the logical VSync // When the GSFrame CoreThread is paused, so is the logical VSync
// Meaning that we have to grab the user-input through here to potentially // Meaning that we have to grab the user-input through here to potentially
@ -1153,7 +1153,7 @@ void Pcsx2App::SysExecute( CDVD_SourceType cdvdsrc, const wxString& elf_override
{ {
SysExecutorThread.PostEvent( new SysExecEvent_Execute(cdvdsrc, elf_override) ); SysExecutorThread.PostEvent( new SysExecEvent_Execute(cdvdsrc, elf_override) );
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
RecordingReset(); g_InputRecording.RecordingReset();
#endif #endif
} }

View File

@ -542,7 +542,7 @@ void MainEmuFrame::Menu_EnableRecordingTools_Click(wxCommandEvent& event)
viewport->InitDefaultAccelerators(); viewport->InitDefaultAccelerators();
} }
} }
if (g_InputRecordingControls.IsRecordingPaused()) if (g_InputRecordingControls.IsPaused())
g_InputRecordingControls.Resume(); g_InputRecordingControls.Resume();
} }
@ -688,7 +688,7 @@ void MainEmuFrame::Menu_ConfigPlugin_Click(wxCommandEvent& event)
// If the CoreThread is paused prior to opening the PAD plugin settings then when the settings // If the CoreThread is paused prior to opening the PAD plugin settings then when the settings
// are closed the PAD will not re-open. To avoid this, we resume emulation prior to the plugins // are closed the PAD will not re-open. To avoid this, we resume emulation prior to the plugins
// configuration handler doing so. // configuration handler doing so.
if (g_Conf->EmuOptions.EnableRecordingTools && g_InputRecordingControls.IsRecordingPaused()) if (g_Conf->EmuOptions.EnableRecordingTools && g_InputRecordingControls.IsPaused())
{ {
g_InputRecordingControls.Resume(); g_InputRecordingControls.Resume();
GetCorePlugins().Configure(pid); GetCorePlugins().Configure(pid);
@ -872,7 +872,7 @@ void MainEmuFrame::Menu_Capture_Screenshot_Screenshot_Click(wxCommandEvent & eve
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
void MainEmuFrame::Menu_Recording_New_Click(wxCommandEvent &event) void MainEmuFrame::Menu_Recording_New_Click(wxCommandEvent &event)
{ {
const bool initiallyPaused = g_InputRecordingControls.IsRecordingPaused(); const bool initiallyPaused = g_InputRecordingControls.IsPaused();
if (!initiallyPaused) if (!initiallyPaused)
g_InputRecordingControls.PauseImmediately(); g_InputRecordingControls.PauseImmediately();
NewRecordingFrame* newRecordingFrame = wxGetApp().GetNewRecordingFramePtr(); NewRecordingFrame* newRecordingFrame = wxGetApp().GetNewRecordingFramePtr();
@ -899,7 +899,7 @@ void MainEmuFrame::Menu_Recording_New_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_Recording_Play_Click(wxCommandEvent &event) void MainEmuFrame::Menu_Recording_Play_Click(wxCommandEvent &event)
{ {
const bool initiallyPaused = g_InputRecordingControls.IsRecordingPaused(); const bool initiallyPaused = g_InputRecordingControls.IsPaused();
if (!initiallyPaused) if (!initiallyPaused)
g_InputRecordingControls.PauseImmediately(); g_InputRecordingControls.PauseImmediately();
wxFileDialog openFileDialog(this, _("Select P2M2 record file."), L"", L"", wxFileDialog openFileDialog(this, _("Select P2M2 record file."), L"", L"",