From 23dba26ba3f29642c2fa7bf247389e4b52840cb3 Mon Sep 17 00:00:00 2001 From: sonicfind <52436993+sonicfind@users.noreply.github.com> Date: Tue, 15 Sep 2020 22:00:48 -0500 Subject: [PATCH] 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) --- pcsx2/Recording/InputRecording.cpp | 71 ++++------------------ pcsx2/Recording/InputRecording.h | 7 +++ pcsx2/Recording/InputRecordingControls.cpp | 35 +++++------ pcsx2/Recording/InputRecordingControls.h | 4 +- pcsx2/Recording/InputRecordingFile.cpp | 20 +++--- pcsx2/Recording/InputRecordingFile.h | 10 +-- pcsx2/SaveState.h | 5 ++ pcsx2/gui/App.h | 5 -- pcsx2/gui/AppMain.cpp | 4 +- pcsx2/gui/MainMenuClicks.cpp | 8 +-- 10 files changed, 63 insertions(+), 106 deletions(-) diff --git a/pcsx2/Recording/InputRecording.cpp b/pcsx2/Recording/InputRecording.cpp index 4a55c86ae0..56eecb2054 100644 --- a/pcsx2/Recording/InputRecording.cpp +++ b/pcsx2/Recording/InputRecording.cpp @@ -28,11 +28,6 @@ #include -// 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(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; diff --git a/pcsx2/Recording/InputRecording.h b/pcsx2/Recording/InputRecording.h index d786bb6cea..9cf8e52bb6 100644 --- a/pcsx2/Recording/InputRecording.h +++ b/pcsx2/Recording/InputRecording.h @@ -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[]); diff --git a/pcsx2/Recording/InputRecordingControls.cpp b/pcsx2/Recording/InputRecordingControls.cpp index 975a4c4b73..f706796076 100644 --- a/pcsx2/Recording/InputRecordingControls.cpp +++ b/pcsx2/Recording/InputRecordingControls.cpp @@ -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 diff --git a/pcsx2/Recording/InputRecordingControls.h b/pcsx2/Recording/InputRecordingControls.h index 88b355ad7a..56f4ea09d0 100644 --- a/pcsx2/Recording/InputRecordingControls.h +++ b/pcsx2/Recording/InputRecordingControls.h @@ -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 diff --git a/pcsx2/Recording/InputRecordingFile.cpp b/pcsx2/Recording/InputRecordingFile.cpp index fe5177bf2a..c36f0524ca 100644 --- a/pcsx2/Recording/InputRecordingFile.cpp +++ b/pcsx2/Recording/InputRecordingFile.cpp @@ -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; } diff --git a/pcsx2/Recording/InputRecordingFile.h b/pcsx2/Recording/InputRecordingFile.h index 9bf1c6e7eb..4272191890 100644 --- a/pcsx2/Recording/InputRecordingFile.h +++ b/pcsx2/Recording/InputRecordingFile.h @@ -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 diff --git a/pcsx2/SaveState.h b/pcsx2/SaveState.h index e05af23a41..ea6dd74853 100644 --- a/pcsx2/SaveState.h +++ b/pcsx2/SaveState.h @@ -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(); }; diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index 99ca9c4391..6f38f6e15a 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -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(); diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index 0794f7741a..ee7f6c1b5a 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -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 } diff --git a/pcsx2/gui/MainMenuClicks.cpp b/pcsx2/gui/MainMenuClicks.cpp index 7c5c42bb43..70dce5efb0 100644 --- a/pcsx2/gui/MainMenuClicks.cpp +++ b/pcsx2/gui/MainMenuClicks.cpp @@ -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"",