input-recording: Wait for savestate confirmation on initial load

* Required splitting some recording menu-related code into separate public functions to work most efficiently.
This commit is contained in:
sonicfind 2020-12-26 00:01:39 -06:00 committed by refractionpcsx2
parent c9a5443539
commit 7431a18bbe
6 changed files with 88 additions and 60 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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();
}
// ----------------------------------------------------------------------------

View File

@ -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:

View File

@ -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)