mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-01-18 06:25:37 +00:00
FullscreenUI: Add undo load state to load menu
This commit is contained in:
parent
921c5cdfbf
commit
ab9109f3b1
|
@ -746,7 +746,7 @@ bool CommonHostInterface::SaveUndoLoadState()
|
|||
m_undo_load_state.reset();
|
||||
|
||||
m_undo_load_state = ByteStream_CreateGrowableMemoryStream(nullptr, System::MAX_SAVE_STATE_SIZE);
|
||||
if (!System::SaveState(m_undo_load_state.get(), 0))
|
||||
if (!System::SaveState(m_undo_load_state.get()))
|
||||
{
|
||||
AddOSDMessage(TranslateStdString("OSDMessage", "Failed to save undo load state."), 15.0f);
|
||||
m_undo_load_state.reset();
|
||||
|
@ -2836,30 +2836,13 @@ std::optional<CommonHostInterface::SaveStateInfo> CommonHostInterface::GetSaveSt
|
|||
}
|
||||
|
||||
std::optional<CommonHostInterface::ExtendedSaveStateInfo>
|
||||
CommonHostInterface::GetExtendedSaveStateInfo(const char* game_code, s32 slot)
|
||||
CommonHostInterface::GetExtendedSaveStateInfo(ByteStream* stream)
|
||||
{
|
||||
const bool global = (!game_code || game_code[0] == 0);
|
||||
std::string path = global ? GetGlobalSaveStateFileName(slot) : GetGameSaveStateFileName(game_code, slot);
|
||||
|
||||
FILESYSTEM_STAT_DATA sd;
|
||||
if (!FileSystem::StatFile(path.c_str(), &sd))
|
||||
return std::nullopt;
|
||||
|
||||
std::unique_ptr<ByteStream> stream =
|
||||
FileSystem::OpenFile(path.c_str(), BYTESTREAM_OPEN_READ | BYTESTREAM_OPEN_SEEKABLE);
|
||||
if (!stream)
|
||||
return std::nullopt;
|
||||
|
||||
SAVE_STATE_HEADER header;
|
||||
if (!stream->Read(&header, sizeof(header)) || header.magic != SAVE_STATE_MAGIC)
|
||||
return std::nullopt;
|
||||
|
||||
ExtendedSaveStateInfo ssi;
|
||||
ssi.path = std::move(path);
|
||||
ssi.timestamp = sd.ModificationTime.AsUnixTimestamp();
|
||||
ssi.slot = slot;
|
||||
ssi.global = global;
|
||||
|
||||
if (header.version < SAVE_STATE_MINIMUM_VERSION || header.version > SAVE_STATE_VERSION)
|
||||
{
|
||||
ssi.title = StringUtil::StdStringFromFormat(
|
||||
|
@ -2902,6 +2885,53 @@ CommonHostInterface::GetExtendedSaveStateInfo(const char* game_code, s32 slot)
|
|||
return ssi;
|
||||
}
|
||||
|
||||
std::optional<CommonHostInterface::ExtendedSaveStateInfo>
|
||||
CommonHostInterface::GetExtendedSaveStateInfo(const char* game_code, s32 slot)
|
||||
{
|
||||
const bool global = (!game_code || game_code[0] == 0);
|
||||
std::string path = global ? GetGlobalSaveStateFileName(slot) : GetGameSaveStateFileName(game_code, slot);
|
||||
|
||||
FILESYSTEM_STAT_DATA sd;
|
||||
if (!FileSystem::StatFile(path.c_str(), &sd))
|
||||
return std::nullopt;
|
||||
|
||||
std::unique_ptr<ByteStream> stream =
|
||||
FileSystem::OpenFile(path.c_str(), BYTESTREAM_OPEN_READ | BYTESTREAM_OPEN_SEEKABLE);
|
||||
if (!stream)
|
||||
return std::nullopt;
|
||||
|
||||
std::optional<ExtendedSaveStateInfo> ssi = GetExtendedSaveStateInfo(stream.get());
|
||||
if (!ssi)
|
||||
return std::nullopt;
|
||||
|
||||
ssi->path = std::move(path);
|
||||
ssi->timestamp = sd.ModificationTime.AsUnixTimestamp();
|
||||
ssi->slot = slot;
|
||||
ssi->global = global;
|
||||
|
||||
return ssi;
|
||||
}
|
||||
|
||||
std::optional<CommonHostInterface::ExtendedSaveStateInfo> CommonHostInterface::GetUndoSaveStateInfo()
|
||||
{
|
||||
std::optional<ExtendedSaveStateInfo> ssi;
|
||||
if (m_undo_load_state)
|
||||
{
|
||||
m_undo_load_state->SeekAbsolute(0);
|
||||
ssi = GetExtendedSaveStateInfo(m_undo_load_state.get());
|
||||
m_undo_load_state->SeekAbsolute(0);
|
||||
|
||||
if (ssi)
|
||||
{
|
||||
ssi->timestamp = 0;
|
||||
ssi->slot = 0;
|
||||
ssi->global = false;
|
||||
}
|
||||
}
|
||||
|
||||
return ssi;
|
||||
}
|
||||
|
||||
void CommonHostInterface::DeleteSaveStates(const char* game_code, bool resume)
|
||||
{
|
||||
const std::vector<SaveStateInfo> states(GetAvailableSaveStates(game_code));
|
||||
|
|
|
@ -209,9 +209,15 @@ public:
|
|||
/// Returns save state info if present. If game_code is null or empty, assumes global state.
|
||||
std::optional<SaveStateInfo> GetSaveStateInfo(const char* game_code, s32 slot);
|
||||
|
||||
/// Returns save state info from opened save state stream.
|
||||
std::optional<ExtendedSaveStateInfo> GetExtendedSaveStateInfo(ByteStream* stream);
|
||||
|
||||
/// Returns save state info if present. If game_code is null or empty, assumes global state.
|
||||
std::optional<ExtendedSaveStateInfo> GetExtendedSaveStateInfo(const char* game_code, s32 slot);
|
||||
|
||||
/// Returns save state info for the undo slot, if present.
|
||||
std::optional<ExtendedSaveStateInfo> GetUndoSaveStateInfo();
|
||||
|
||||
/// Deletes save states for the specified game code. If resume is set, the resume state is deleted too.
|
||||
void DeleteSaveStates(const char* game_code, bool resume);
|
||||
|
||||
|
|
|
@ -2785,6 +2785,7 @@ void InitializeSaveStateListEntry(SaveStateListEntry* li, CommonHostInterface::E
|
|||
li->summary =
|
||||
StringUtil::StdStringFromFormat("%s - Saved %s", ssi->game_code.c_str(),
|
||||
Timestamp::FromUnixTimestamp(ssi->timestamp).ToString("%c").GetCharArray());
|
||||
|
||||
li->slot = ssi->slot;
|
||||
li->global = ssi->global;
|
||||
li->path = std::move(ssi->path);
|
||||
|
@ -2812,6 +2813,19 @@ void PopulateSaveStateListEntries()
|
|||
{
|
||||
s_save_state_selector_slots.clear();
|
||||
|
||||
if (s_save_state_selector_loading)
|
||||
{
|
||||
std::optional<CommonHostInterface::ExtendedSaveStateInfo> ssi = s_host_interface->GetUndoSaveStateInfo();
|
||||
if (ssi)
|
||||
{
|
||||
SaveStateListEntry li;
|
||||
InitializeSaveStateListEntry(&li, &ssi.value());
|
||||
li.title = "Undo Load State";
|
||||
li.summary = "Restores the state of the system prior to the last state loaded.";
|
||||
s_save_state_selector_slots.push_back(std::move(li));
|
||||
}
|
||||
}
|
||||
|
||||
if (!System::GetRunningCode().empty())
|
||||
{
|
||||
for (s32 i = 1; i <= CommonHostInterface::PER_GAME_SAVE_STATE_SLOTS; i++)
|
||||
|
@ -3025,7 +3039,11 @@ void DrawSaveStateSelector(bool is_loading, bool fullscreen)
|
|||
{
|
||||
const std::string& path = entry.path;
|
||||
s_host_interface->RunLater([path]() {
|
||||
s_host_interface->LoadState(path.c_str());
|
||||
if (path.empty())
|
||||
s_host_interface->UndoLoadState();
|
||||
else
|
||||
s_host_interface->LoadState(path.c_str());
|
||||
|
||||
CloseSaveStateSelector();
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue