diff --git a/pcsx2/Recording/InputRecording.cpp b/pcsx2/Recording/InputRecording.cpp index b3483f015d..52ced8803b 100644 --- a/pcsx2/Recording/InputRecording.cpp +++ b/pcsx2/Recording/InputRecording.cpp @@ -45,7 +45,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); + g_InputRecording.SetupInitialState(g_FrameCount); else if (g_InputRecording.IsActive()) { // Explicitly set the frame change tracking variable as to not @@ -81,7 +81,7 @@ void InputRecording::RecordingReset() // 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); + g_InputRecording.SetupInitialState(0); else if (g_InputRecording.IsActive()) { g_InputRecording.SetFrameCounter(0); @@ -259,9 +259,34 @@ void InputRecording::SetFrameCounter(u32 newGFrameCount) } } -void InputRecording::SetStartingFrame(u32 newStartingFrame) +void InputRecording::SetupInitialState(u32 newStartingFrame) { startingFrame = newStartingFrame; + if (state != InputRecordingMode::Replaying) + { + inputRec::log("Started new input recording"); + inputRec::consoleLog(fmt::format("Filename {}", std::string(inputRecordingData.GetFilename()))); + SetToRecordMode(); + } + else + { + // 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) + inputRec::consoleLog("Input recording was possibly constructed for a different game."); + + incrementUndo = true; + inputRec::consoleMultiLog({fmt::format("Replaying input recording - [{}]", std::string(inputRecordingData.GetFilename())), + fmt::format("PCSX2 Version Used: {}", std::string(inputRecordingData.GetHeader().emu)), + fmt::format("Recording File Version: {}", inputRecordingData.GetHeader().version), + fmt::format("Associated Game Name or ISO Filename: {}", std::string(inputRecordingData.GetHeader().gameName)), + fmt::format("Author: {}", inputRecordingData.GetHeader().author), + fmt::format("Total Frames: {}", inputRecordingData.GetTotalFrames()), + fmt::format("Undo Count: {}", inputRecordingData.GetUndoCount())}); + SetToReplayMode(); + } + + g_InputRecordingControls.DisableFrameAdvance(); if (inputRecordingData.FromSaveState()) inputRec::consoleLog(fmt::format("Internal Starting Frame: {}", startingFrame)); frameCounter = 0; @@ -269,6 +294,16 @@ void InputRecording::SetStartingFrame(u32 newStartingFrame) g_InputRecordingControls.Lock(startingFrame); } +void InputRecording::FailedSavestate() +{ + inputRec::consoleLog(fmt::format("{}_SaveState.p2s is not compatible with this version of PCSX2", inputRecordingData.GetFilename())); + inputRec::consoleLog(fmt::format("Original PCSX2 version used: {}", inputRecordingData.GetHeader().emu)); + inputRecordingData.Close(); + initialLoad = false; + state = InputRecordingMode::NotActive; + g_InputRecordingControls.Resume(); +} + void InputRecording::Stop() { state = InputRecordingMode::NotActive; @@ -285,6 +320,7 @@ bool InputRecording::Create(wxString FileName, bool fromSaveState, wxString auth return false; initialLoad = true; + state = InputRecordingMode::Recording; if (fromSaveState) { if (wxFileExists(FileName + "_SaveState.p2s")) @@ -305,21 +341,15 @@ bool InputRecording::Create(wxString FileName, bool fromSaveState, wxString auth inputRecordingData.GetHeader().SetGameName(resolveGameName()); // Write header contents inputRecordingData.WriteHeader(); - SetToRecordMode(); - g_InputRecordingControls.DisableFrameAdvance(); - inputRec::log("Started new input recording"); - inputRec::consoleLog(fmt::format("Filename {}", std::string(FileName))); return true; } bool InputRecording::Play(wxString fileName) { - if (IsActive()) - Stop(); - if (!inputRecordingData.OpenExisting(fileName)) return false; + state = InputRecordingMode::Replaying; // Either load the savestate, or restart the game if (inputRecordingData.FromSaveState()) { @@ -344,23 +374,6 @@ bool InputRecording::Play(wxString fileName) initialLoad = true; sApp.SysExecute(g_Conf->CdvdSource); } - - // 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) - inputRec::consoleLog("Input recording was possibly constructed for a different game."); - - incrementUndo = true; - SetToReplayMode(); - inputRec::log("Playing input recording"); - g_InputRecordingControls.DisableFrameAdvance(); - inputRec::consoleMultiLog({fmt::format("Replaying input recording - [{}]", std::string(inputRecordingData.GetFilename())), - fmt::format("PCSX2 Version Used: {}", std::string(inputRecordingData.GetHeader().emu)), - fmt::format("Recording File Version: {}", inputRecordingData.GetHeader().version), - fmt::format("Associated Game Name or ISO Filename: {}", std::string(inputRecordingData.GetHeader().gameName)), - fmt::format("Author: {}", inputRecordingData.GetHeader().author), - fmt::format("Total Frames: {}", inputRecordingData.GetTotalFrames()), - fmt::format("Undo Count: {}", inputRecordingData.GetUndoCount())}); return true; } diff --git a/pcsx2/Recording/InputRecording.h b/pcsx2/Recording/InputRecording.h index 9b659c6698..b881a342bf 100644 --- a/pcsx2/Recording/InputRecording.h +++ b/pcsx2/Recording/InputRecording.h @@ -76,8 +76,8 @@ public: // Set the running frame counter for the input recording to an arbitrary value void SetFrameCounter(u32 newGFrameCount); - // Store the starting internal PCSX2 g_FrameCount value - void SetStartingFrame(u32 newStartingFrame); + // Sets up all values and prints console logs pertaining to the start of a recording + void SetupInitialState(u32 newStartingFrame); /// Functions called from GUI @@ -89,6 +89,8 @@ public: void Stop(); // Initialze VirtualPad window void setVirtualPadPtr(VirtualPad* ptr, int const port); + // Resets a recording if the base savestate could not be loaded at the start + void FailedSavestate(); private: enum class InputRecordingMode diff --git a/pcsx2/Recording/InputRecordingControls.cpp b/pcsx2/Recording/InputRecordingControls.cpp index d764ba8b1e..f91a0a38d0 100644 --- a/pcsx2/Recording/InputRecordingControls.cpp +++ b/pcsx2/Recording/InputRecordingControls.cpp @@ -20,7 +20,7 @@ #include "App.h" #include "Counters.h" #include "DebugTools/Debug.h" -#include "GSFrame.h" +#include "MainFrame.h" #include "MemoryTypes.h" #include "InputRecording.h" @@ -209,5 +209,7 @@ void InputRecordingControls::Lock(u32 frame) //Ensures that g_frameCount can be used to resume emulation after a fast/full boot if (!g_InputRecording.GetInputRecordingData().FromSaveState()) g_FrameCount = frame + 1; + else + sMainFrame.StartInputRecording(); } #endif diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index 4992af621a..67e807c47b 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -662,6 +662,11 @@ void Pcsx2App::HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& // Saved state load failed prior to the system getting corrupted (ie, file not found // or some zipfile error) -- so log it and resume emulation. Console.Warning( ex.FormatDiagnosticMessage() ); +#ifndef DISABLE_RECORDING + if (g_InputRecording.IsInitialLoad()) + g_InputRecording.FailedSavestate(); +#endif + CoreThread.Resume(); } // ---------------------------------------------------------------------------- diff --git a/pcsx2/gui/MainFrame.h b/pcsx2/gui/MainFrame.h index 7553615442..75b5ddc26e 100644 --- a/pcsx2/gui/MainFrame.h +++ b/pcsx2/gui/MainFrame.h @@ -174,6 +174,8 @@ public: #ifndef DISABLE_RECORDING void initializeRecordingMenuItem(MenuIdentifiers menuId, wxString keyCodeStr, bool enable = true); void enableRecordingMenuItem(MenuIdentifiers menuId, bool enable); + void StartInputRecording(); + void StopInputRecording(); #endif protected: diff --git a/pcsx2/gui/MainMenuClicks.cpp b/pcsx2/gui/MainMenuClicks.cpp index 92f8e23c6e..1af058638b 100644 --- a/pcsx2/gui/MainMenuClicks.cpp +++ b/pcsx2/gui/MainMenuClicks.cpp @@ -612,8 +612,7 @@ void MainEmuFrame::Menu_EnableRecordingTools_Click(wxCommandEvent& event) else { //Properly close any currently loaded recording file before disabling - if (g_InputRecording.IsActive()) - Menu_Recording_Stop_Click(event); + StopInputRecording(); GetMenuBar()->Remove(TopLevelMenu_InputRecording); // Always turn controller logs off, but never turn it on by default SysConsole.controlInfo.Enabled = checked; @@ -954,22 +953,19 @@ void MainEmuFrame::Menu_Recording_New_Click(wxCommandEvent& event) NewRecordingFrame* newRecordingFrame = wxGetApp().GetNewRecordingFramePtr(); if (newRecordingFrame) { - if (newRecordingFrame->ShowModal() == wxID_CANCEL) + if (newRecordingFrame->ShowModal() != wxID_CANCEL) { - if (!initiallyPaused) - g_InputRecordingControls.Resume(); - return; - } - if (!g_InputRecording.Create(newRecordingFrame->GetFile(), !newRecordingFrame->GetFrom(), newRecordingFrame->GetAuthor())) - { - if (!initiallyPaused) - g_InputRecordingControls.Resume(); - return; + if (g_InputRecording.Create(newRecordingFrame->GetFile(), !newRecordingFrame->GetFrom(), newRecordingFrame->GetAuthor())) + { + if (!g_InputRecording.GetInputRecordingData().FromSaveState()) + StartInputRecording(); + return; + } } + + if (!initiallyPaused) + g_InputRecordingControls.Resume(); } - m_menuRecording.FindChildItem(MenuId_Recording_New)->Enable(false); - m_menuRecording.FindChildItem(MenuId_Recording_Stop)->Enable(true); - sMainFrame.enableRecordingMenuItem(MenuId_Recording_ToggleRecordingMode, g_InputRecording.IsActive()); } void MainEmuFrame::Menu_Recording_Play_Click(wxCommandEvent& event) @@ -986,30 +982,38 @@ void MainEmuFrame::Menu_Recording_Play_Click(wxCommandEvent& event) return; } - wxString path = openFileDialog.GetPath(); - const bool recordingLoaded = g_InputRecording.IsActive(); - if (!g_InputRecording.Play(path)) + StopInputRecording(); + if (!g_InputRecording.Play(openFileDialog.GetPath())) { - if (recordingLoaded) - Menu_Recording_Stop_Click(event); if (!initiallyPaused) g_InputRecordingControls.Resume(); return; } - if (!recordingLoaded) - { - m_menuRecording.FindChildItem(MenuId_Recording_New)->Enable(false); - m_menuRecording.FindChildItem(MenuId_Recording_Stop)->Enable(true); - } - sMainFrame.enableRecordingMenuItem(MenuId_Recording_ToggleRecordingMode, g_InputRecording.IsActive()); + if (!g_InputRecording.GetInputRecordingData().FromSaveState()) + StartInputRecording(); } void MainEmuFrame::Menu_Recording_Stop_Click(wxCommandEvent& event) { - g_InputRecording.Stop(); - m_menuRecording.FindChildItem(MenuId_Recording_New)->Enable(true); - m_menuRecording.FindChildItem(MenuId_Recording_Stop)->Enable(false); - sMainFrame.enableRecordingMenuItem(MenuId_Recording_ToggleRecordingMode, g_InputRecording.IsActive()); + StopInputRecording(); +} + +void MainEmuFrame::StartInputRecording() +{ + m_menuRecording.FindChildItem(MenuId_Recording_New)->Enable(false); + m_menuRecording.FindChildItem(MenuId_Recording_Stop)->Enable(true); + m_menuRecording.FindChildItem(MenuId_Recording_ToggleRecordingMode)->Enable(true); +} + +void MainEmuFrame::StopInputRecording() +{ + if (g_InputRecording.IsActive()) + { + g_InputRecording.Stop(); + m_menuRecording.FindChildItem(MenuId_Recording_New)->Enable(true); + m_menuRecording.FindChildItem(MenuId_Recording_Stop)->Enable(false); + m_menuRecording.FindChildItem(MenuId_Recording_ToggleRecordingMode)->Enable(false); + } } void MainEmuFrame::Menu_Recording_TogglePause_Click(wxCommandEvent& event)