HostInterface: Add helpers for resume save state
This commit is contained in:
parent
5f3be68028
commit
e738b87a25
|
@ -432,7 +432,7 @@ bool HostInterface::LoadState(const char* filename)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HostInterface::LoadState(bool global, u32 slot)
|
bool HostInterface::LoadState(bool global, s32 slot)
|
||||||
{
|
{
|
||||||
if (!global && (!m_system || m_system->GetRunningCode().empty()))
|
if (!global && (!m_system || m_system->GetRunningCode().empty()))
|
||||||
{
|
{
|
||||||
|
@ -468,7 +468,7 @@ bool HostInterface::SaveState(const char* filename)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HostInterface::SaveState(bool global, u32 slot)
|
bool HostInterface::SaveState(bool global, s32 slot)
|
||||||
{
|
{
|
||||||
const std::string& code = m_system->GetRunningCode();
|
const std::string& code = m_system->GetRunningCode();
|
||||||
if (!global && code.empty())
|
if (!global && code.empty())
|
||||||
|
@ -481,6 +481,48 @@ bool HostInterface::SaveState(bool global, u32 slot)
|
||||||
return SaveState(save_path.c_str());
|
return SaveState(save_path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HostInterface::ResumeSystemFromState(const char* filename, bool boot_on_failure)
|
||||||
|
{
|
||||||
|
if (!BootSystemFromFile(filename))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const bool global = m_system->GetRunningCode().empty();
|
||||||
|
const std::string path =
|
||||||
|
global ? GetGlobalSaveStateFileName(-1) : GetGameSaveStateFileName(m_system->GetRunningCode().c_str(), -1);
|
||||||
|
if (FileSystem::FileExists(path.c_str()))
|
||||||
|
{
|
||||||
|
if (!LoadState(path.c_str()) && !boot_on_failure)
|
||||||
|
{
|
||||||
|
DestroySystem();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReportFormattedError("Resume save state not found for '%s' ('%s').", m_system->GetRunningCode().c_str(),
|
||||||
|
m_system->GetRunningTitle().c_str());
|
||||||
|
if (!boot_on_failure)
|
||||||
|
{
|
||||||
|
DestroySystem();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HostInterface::ResumeSystemFromMostRecentState()
|
||||||
|
{
|
||||||
|
const std::string path = GetMostRecentResumeSaveStatePath();
|
||||||
|
if (path.empty())
|
||||||
|
{
|
||||||
|
ReportError("No resume save state found.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LoadState(path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
void HostInterface::UpdateSpeedLimiterState()
|
void HostInterface::UpdateSpeedLimiterState()
|
||||||
{
|
{
|
||||||
m_speed_limiter_enabled = m_settings.speed_limiter_enabled && !m_speed_limiter_temp_disabled;
|
m_speed_limiter_enabled = m_settings.speed_limiter_enabled && !m_speed_limiter_temp_disabled;
|
||||||
|
@ -660,7 +702,7 @@ std::vector<HostInterface::SaveStateInfo> HostInterface::GetAvailableSaveStates(
|
||||||
std::vector<SaveStateInfo> si;
|
std::vector<SaveStateInfo> si;
|
||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
auto add_path = [&si](std::string path, s32 slot, bool global) {
|
auto add_path = [&si](const std::string& path, s32 slot, bool global) {
|
||||||
FILESYSTEM_STAT_DATA sd;
|
FILESYSTEM_STAT_DATA sd;
|
||||||
if (!FileSystem::StatFile(path.c_str(), &sd))
|
if (!FileSystem::StatFile(path.c_str(), &sd))
|
||||||
return;
|
return;
|
||||||
|
@ -670,6 +712,7 @@ std::vector<HostInterface::SaveStateInfo> HostInterface::GetAvailableSaveStates(
|
||||||
|
|
||||||
if (game_code && std::strlen(game_code) > 0)
|
if (game_code && std::strlen(game_code) > 0)
|
||||||
{
|
{
|
||||||
|
add_path(GetGameSaveStateFileName(game_code, -1), -1, false);
|
||||||
for (s32 i = 1; i <= PER_GAME_SAVE_STATE_SLOTS; i++)
|
for (s32 i = 1; i <= PER_GAME_SAVE_STATE_SLOTS; i++)
|
||||||
add_path(GetGameSaveStateFileName(game_code, i), i, false);
|
add_path(GetGameSaveStateFileName(game_code, i), i, false);
|
||||||
}
|
}
|
||||||
|
@ -680,6 +723,26 @@ std::vector<HostInterface::SaveStateInfo> HostInterface::GetAvailableSaveStates(
|
||||||
return si;
|
return si;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string HostInterface::GetMostRecentResumeSaveStatePath() const
|
||||||
|
{
|
||||||
|
std::vector<FILESYSTEM_FIND_DATA> files;
|
||||||
|
if (!FileSystem::FindFiles(GetUserDirectoryRelativePath("savestates").c_str(), "*resume.sav", FILESYSTEM_FIND_FILES,
|
||||||
|
&files) ||
|
||||||
|
files.empty())
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
FILESYSTEM_FIND_DATA* most_recent = &files[0];
|
||||||
|
for (FILESYSTEM_FIND_DATA& file : files)
|
||||||
|
{
|
||||||
|
if (file.ModificationTime > most_recent->ModificationTime)
|
||||||
|
most_recent = &file;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(most_recent->FileName);
|
||||||
|
}
|
||||||
|
|
||||||
void HostInterface::SetDefaultSettings()
|
void HostInterface::SetDefaultSettings()
|
||||||
{
|
{
|
||||||
m_settings.region = ConsoleRegion::Auto;
|
m_settings.region = ConsoleRegion::Auto;
|
||||||
|
@ -856,3 +919,12 @@ void HostInterface::SetTimerResolutionIncreased(bool enabled)
|
||||||
timeEndPeriod(1);
|
timeEndPeriod(1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HostInterface::SaveResumeSaveState()
|
||||||
|
{
|
||||||
|
if (!m_system)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const bool global = m_system->GetRunningCode().empty();
|
||||||
|
return SaveState(global, -1);
|
||||||
|
}
|
||||||
|
|
|
@ -46,13 +46,23 @@ public:
|
||||||
void DestroySystem();
|
void DestroySystem();
|
||||||
|
|
||||||
/// Loads the current emulation state from file. Specifying a slot of -1 loads the "resume" game state.
|
/// Loads the current emulation state from file. Specifying a slot of -1 loads the "resume" game state.
|
||||||
bool LoadState(bool global, u32 slot);
|
bool LoadState(bool global, s32 slot);
|
||||||
bool LoadState(const char* filename);
|
bool LoadState(const char* filename);
|
||||||
|
|
||||||
/// Saves the current emulation state to a file. Specifying a slot of -1 saves the "resume" save state.
|
/// Saves the current emulation state to a file. Specifying a slot of -1 saves the "resume" save state.
|
||||||
bool SaveState(bool global, u32 slot);
|
bool SaveState(bool global, s32 slot);
|
||||||
bool SaveState(const char* filename);
|
bool SaveState(const char* filename);
|
||||||
|
|
||||||
|
/// Loads the resume save state for the given game. Optionally boots the game anyway if loading fails.
|
||||||
|
bool ResumeSystemFromState(const char* filename, bool boot_on_failure);
|
||||||
|
|
||||||
|
/// Loads the most recent resume save state. This may be global or per-game.
|
||||||
|
bool ResumeSystemFromMostRecentState();
|
||||||
|
|
||||||
|
/// Saves the resume save state, call when shutting down. Not called automatically on DestroySystem() since that can
|
||||||
|
/// be called as a result of an error.
|
||||||
|
bool SaveResumeSaveState();
|
||||||
|
|
||||||
virtual void ReportError(const char* message);
|
virtual void ReportError(const char* message);
|
||||||
virtual void ReportMessage(const char* message);
|
virtual void ReportMessage(const char* message);
|
||||||
|
|
||||||
|
@ -135,6 +145,9 @@ protected:
|
||||||
/// Returns a list of save states for the specified game code.
|
/// Returns a list of save states for the specified game code.
|
||||||
std::vector<SaveStateInfo> GetAvailableSaveStates(const char* game_code) const;
|
std::vector<SaveStateInfo> GetAvailableSaveStates(const char* game_code) const;
|
||||||
|
|
||||||
|
/// Returns the most recent resume save state.
|
||||||
|
std::string GetMostRecentResumeSaveStatePath() const;
|
||||||
|
|
||||||
/// Loads the BIOS image for the specified region.
|
/// Loads the BIOS image for the specified region.
|
||||||
std::optional<std::vector<u8>> GetBIOSImage(ConsoleRegion region);
|
std::optional<std::vector<u8>> GetBIOSImage(ConsoleRegion region);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue