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>
// 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()
{
FreezeTag("InputRecording");
@ -43,9 +38,7 @@ void SaveStateBase::InputRecordingFreeze()
// 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.
if (g_InputRecording.IsInitialLoad())
{
g_InputRecording.SetStartingFrame(g_FrameCount);
}
else if (g_InputRecording.IsActive())
{
// Explicitly set the frame change tracking variable as to not
@ -53,28 +46,21 @@ void SaveStateBase::InputRecordingFreeze()
g_InputRecordingControls.SetFrameCountTracker(g_FrameCount);
if (IsLoading())
{
g_InputRecording.SetFrameCounter(g_FrameCount);
}
}
#endif
}
#ifndef DISABLE_RECORDING
// 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 Pcsx2App::RecordingReset()
InputRecording g_InputRecording;
void InputRecording::RecordingReset()
{
// Booting is an asynchronous task. If we are playing a recording
// that starts from power-on and the starting (pcsx2 internal) frame
// marker has not been set, we initialize it.
if (g_InputRecording.IsInitialLoad())
{
g_InputRecording.SetStartingFrame(0);
}
else if (g_InputRecording.IsActive())
{
g_InputRecording.SetFrameCounter(0);
@ -84,8 +70,6 @@ void Pcsx2App::RecordingReset()
g_InputRecordingControls.Resume();
}
InputRecording g_InputRecording;
void InputRecording::ControllerInterrupt(u8 &data, u8 &port, u16 &bufCount, u8 buf[])
{
// 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
*/
if (bufCount == 1)
{
fInterruptFrame = data == 0x42;
}
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
*/
if (buf[bufCount] != 0x5A)
{
fInterruptFrame = false;
}
} // 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)
}
// 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 && frameCounter < INT_MAX)
{
// Read or Write
if (state == InputRecordingMode::Recording)
@ -131,9 +112,7 @@ void InputRecording::ControllerInterrupt(u8 &data, u8 &port, u16 &bufCount, u8 b
{
u8 tmp = 0;
if (inputRecordingData.ReadKeyBuffer(tmp, frameCounter, port, bufCount - 3))
{
buf[bufCount] = tmp;
}
}
}
}
@ -156,9 +135,9 @@ u32 InputRecording::GetStartingFrame()
void InputRecording::IncrementFrameCounter()
{
frameCounter++;
if (state == InputRecordingMode::Recording && frameCounter > 0)
if (state == InputRecordingMode::Recording)
{
GetInputRecordingData().SetTotalFrames((u32)frameCounter);
GetInputRecordingData().SetTotalFrames(frameCounter);
if (frameCounter == inputRecordingData.GetTotalFrames())
incrementUndo = false;
}
@ -195,13 +174,10 @@ wxString InputRecording::RecordingModeTitleSegment()
{
case InputRecordingMode::Recording:
return wxString("Recording");
break;
case InputRecordingMode::Replaying:
return wxString("Replaying");
break;
default:
return wxString("No Movie");
break;
}
}
@ -219,15 +195,13 @@ void InputRecording::SetToReplayMode()
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]: Savestate's framecount has been ignored.\n");
frameCounter = g_InputRecording.GetInputRecordingData().GetTotalFrames();
if (state == InputRecordingMode::Replaying)
{
SetToRecordMode();
}
incrementUndo = false;
}
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");
if (state == InputRecordingMode::Recording)
{
SetToReplayMode();
}
}
else if (newGFrameCount == 0 && state == InputRecordingMode::Recording)
{
SetToReplayMode();
}
frameCounter = static_cast<s32>(newGFrameCount - startingFrame);
incrementUndo = true;
}
@ -252,11 +222,9 @@ void InputRecording::SetFrameCounter(u32 newGFrameCount)
void InputRecording::SetStartingFrame(u32 newStartingFrame)
{
startingFrame = newStartingFrame;
// TODO - make a function of my own to simplify working with the logging macros
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));
}
frameCounter = 0;
initialLoad = false;
g_InputRecordingControls.Lock(startingFrame, inputRecordingData.FromSaveState());
@ -267,40 +235,30 @@ void InputRecording::Stop()
state = InputRecordingMode::NotActive;
incrementUndo = false;
if (inputRecordingData.Close())
{
recordingConLog(L"[REC]: InputRecording Recording Stopped.\n");
}
}
bool InputRecording::Create(wxString FileName, bool fromSaveState, wxString authorName)
{
if (!inputRecordingData.OpenNew(FileName, fromSaveState))
{
return false;
}
initialLoad = true;
if (fromSaveState)
{
if (wxFileExists(FileName + "_SaveState.p2s"))
{
wxCopyFile(FileName + "_SaveState.p2s", FileName + "_SaveState.p2s.bak", true);
}
StateCopy_SaveToFile(FileName + "_SaveState.p2s");
}
else
{
sApp.SysExecute(g_Conf->CdvdSource);
}
// Set emulator version
inputRecordingData.GetHeader().SetEmulatorVersion();
// Set author name
if (!authorName.IsEmpty())
{
inputRecordingData.GetHeader().SetAuthor(authorName);
}
// Set Game Name
inputRecordingData.GetHeader().SetGameName(resolveGameName());
@ -317,9 +275,7 @@ bool InputRecording::Play(wxString fileName)
Stop();
if (!inputRecordingData.OpenExisting(fileName))
{
return false;
}
// Either load the savestate, or restart the game
if (inputRecordingData.FromSaveState())
@ -332,7 +288,8 @@ bool InputRecording::Play(wxString fileName)
}
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();
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
if (!g_Conf->CurrentIso.IsEmpty())
{
if (resolveGameName() != inputRecordingData.GetHeader().gameName)
{
recordingConLog(L"[REC]: Recording was possibly constructed for a different game.\n");
}
}
incrementUndo = true;
state = InputRecordingMode::Replaying;

View File

@ -22,6 +22,13 @@
class InputRecording
{
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)
// or mutating it to the contents of the recording file (replaying)
void ControllerInterrupt(u8 &data, u8 &port, u16 &BufCount, u8 buf[]);

View File

@ -60,7 +60,8 @@ void InputRecordingControls::HandleFrameAdvanceAndPausing()
else if (frameCountTracker != g_FrameCount)
{
frameCountTracker = g_FrameCount;
g_InputRecording.IncrementFrameCounter();
if (g_InputRecording.GetFrameCounter() < INT_MAX)
g_InputRecording.IncrementFrameCounter();
}
else
{
@ -78,13 +79,13 @@ void InputRecordingControls::HandleFrameAdvanceAndPausing()
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;
}
// 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;
pauseEmulation = true;
@ -110,7 +111,8 @@ void InputRecordingControls::ResumeCoreThreadIfStarted()
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();
return;
@ -120,7 +122,7 @@ void InputRecordingControls::FrameAdvance()
Resume();
}
bool InputRecordingControls::IsRecordingPaused()
bool InputRecordingControls::IsPaused()
{
return (emulationCurrentlyPaused && CoreThread.IsOpen() && CoreThread.IsPaused());
}
@ -134,9 +136,7 @@ void InputRecordingControls::Pause()
void InputRecordingControls::PauseImmediately()
{
if (CoreThread.IsPaused())
{
return;
}
Pause();
if (CoreThread.IsOpen() && CoreThread.IsRunning())
{
@ -147,7 +147,8 @@ void InputRecordingControls::PauseImmediately()
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();
return;
@ -163,7 +164,8 @@ void InputRecordingControls::SetFrameCountTracker(u32 newFrame)
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();
return;
@ -174,16 +176,13 @@ void InputRecordingControls::TogglePause()
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())
{
g_InputRecording.SetToRecordMode();
}
else if (g_InputRecording.IsRecording())
{
g_InputRecording.SetToReplayMode();
}
}
else if (g_InputRecording.IsRecording())
switchToReplay = true;
@ -193,10 +192,8 @@ void InputRecordingControls::Lock(u32 frame, bool savestate)
{
frameLock = true;
frameCountTracker = frame;
//Ensures that g_frameCount can be used to resume emulation after a fast/full boot
if (!savestate)
{
//Ensures that g_frameCount can be used to resume emulation after a fast/full boot
g_FrameCount = frame + 1;
}
}
#endif

View File

@ -40,8 +40,8 @@ public:
void FrameAdvance();
// Returns true if the input recording has been paused, which can occur:
// - After a single frame has passed after InputRecordingControls::FrameAdvance
// - Explicitly paused via InputRecordingControls::TogglePause
bool IsRecordingPaused();
// - 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

View File

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

View File

@ -59,7 +59,7 @@ public:
// Retrieve the input recording's header which contains high-level metadata on the recording
InputRecordingFileHeader &GetHeader();
// 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
// this is also often referred to as a "re-record"
unsigned long &GetUndoCount();
@ -76,7 +76,7 @@ public:
// the current frame's value from the emulator
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
void SetTotalFrames(unsigned long frames);
void SetTotalFrames(long frames);
// Persist the input recording file header's current state to the file
bool WriteHeader();
// Writes the current frame's input data to the file so it can be replayed
@ -99,11 +99,11 @@ private:
InputRecordingFileHeader header;
wxString filename = "";
FILE * recordingFile = NULL;
FILE* recordingFile = nullptr;
InputRecordingSavestate savestate;
// An unsigned 32-bit frame limit is equivalent to 2.25 years of continuous 60fps footage
unsigned long totalFrames = 0;
// An signed 32-bit frame limit is equivalent to 1.13 years of continuous 60fps footage
long totalFrames = 0;
unsigned long undoCount = 0;
// Calculates the position of the current frame in the input recording

View File

@ -154,6 +154,11 @@ protected:
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();
};

View File

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

View File

@ -620,7 +620,7 @@ void Pcsx2App::HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent&
#ifndef DISABLE_RECORDING
if (g_Conf->EmuOptions.EnableRecordingTools)
{
if (g_InputRecordingControls.IsRecordingPaused())
if (g_InputRecordingControls.IsPaused())
{
// When the GSFrame CoreThread is paused, so is the logical VSync
// 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) );
#ifndef DISABLE_RECORDING
RecordingReset();
g_InputRecording.RecordingReset();
#endif
}

View File

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