mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 23:55:40 +00:00
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;
|
||||
}
|
||||
|
||||
bool HostInterface::LoadState(bool global, u32 slot)
|
||||
bool HostInterface::LoadState(bool global, s32 slot)
|
||||
{
|
||||
if (!global && (!m_system || m_system->GetRunningCode().empty()))
|
||||
{
|
||||
|
@ -468,7 +468,7 @@ bool HostInterface::SaveState(const char* filename)
|
|||
return result;
|
||||
}
|
||||
|
||||
bool HostInterface::SaveState(bool global, u32 slot)
|
||||
bool HostInterface::SaveState(bool global, s32 slot)
|
||||
{
|
||||
const std::string& code = m_system->GetRunningCode();
|
||||
if (!global && code.empty())
|
||||
|
@ -481,6 +481,48 @@ bool HostInterface::SaveState(bool global, u32 slot)
|
|||
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()
|
||||
{
|
||||
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::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;
|
||||
if (!FileSystem::StatFile(path.c_str(), &sd))
|
||||
return;
|
||||
|
@ -670,6 +712,7 @@ std::vector<HostInterface::SaveStateInfo> HostInterface::GetAvailableSaveStates(
|
|||
|
||||
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++)
|
||||
add_path(GetGameSaveStateFileName(game_code, i), i, false);
|
||||
}
|
||||
|
@ -680,6 +723,26 @@ std::vector<HostInterface::SaveStateInfo> HostInterface::GetAvailableSaveStates(
|
|||
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()
|
||||
{
|
||||
m_settings.region = ConsoleRegion::Auto;
|
||||
|
@ -856,3 +919,12 @@ void HostInterface::SetTimerResolutionIncreased(bool enabled)
|
|||
timeEndPeriod(1);
|
||||
#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();
|
||||
|
||||
/// 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);
|
||||
|
||||
/// 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);
|
||||
|
||||
/// 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 ReportMessage(const char* message);
|
||||
|
||||
|
@ -135,6 +145,9 @@ protected:
|
|||
/// Returns a list of save states for the specified game code.
|
||||
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.
|
||||
std::optional<std::vector<u8>> GetBIOSImage(ConsoleRegion region);
|
||||
|
||||
|
|
Loading…
Reference in a new issue