diff --git a/Core/Config.cpp b/Core/Config.cpp index 42bed7e5aad7..d019ae7bfbba 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -533,6 +533,8 @@ static ConfigSetting generalSettings[] = { ConfigSetting("StateSlot", &g_Config.iCurrentStateSlot, 0, true, true), ConfigSetting("EnableStateUndo", &g_Config.bEnableStateUndo, &DefaultEnableStateUndo, true, true), ConfigSetting("StateLoadUndoGame", &g_Config.sStateLoadUndoGame, "NA", true, false), + ConfigSetting("StateUndoLastSaveGame", &g_Config.sStateUndoLastSaveGame, "NA", true, false), + ConfigSetting("StateUndoLastSaveSlot", &g_Config.iStateUndoLastSaveSlot, -5, true, false), // Start with an "invalid" value ConfigSetting("RewindFlipFrequency", &g_Config.iRewindFlipFrequency, 0, true, true), ConfigSetting("ShowOnScreenMessage", &g_Config.bShowOnScreenMessages, true, true, false), diff --git a/Core/Config.h b/Core/Config.h index a19d3541cbee..4ddde8b525b5 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -210,6 +210,8 @@ struct Config { bool bUISound; bool bEnableStateUndo; std::string sStateLoadUndoGame; + std::string sStateUndoLastSaveGame; + int iStateUndoLastSaveSlot; int iAutoLoadSaveState; // 0 = off, 1 = oldest, 2 = newest, >2 = slot number + 3 bool bEnableCheats; bool bReloadCheats; diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 568a1269d6ad..ac6fbf13a76e 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -531,6 +531,8 @@ namespace SaveState if (g_Config.bEnableStateUndo) { DeleteIfExists(fnUndo); RenameIfExists(fn, fnUndo); + g_Config.sStateUndoLastSaveGame = GenerateFullDiscId(gameFilename); + g_Config.iStateUndoLastSaveSlot = slot; } else { DeleteIfExists(fn); } @@ -571,6 +573,14 @@ namespace SaveState return false; } + + bool UndoLastSave(const Path &gameFilename) { + if (g_Config.sStateUndoLastSaveGame != GenerateFullDiscId(gameFilename)) + return false; + + return UndoSaveSlot(gameFilename, g_Config.iStateUndoLastSaveSlot); + } + bool HasSaveInSlot(const Path &gameFilename, int slot) { Path fn = GenerateSaveSlotFilename(gameFilename, slot, STATE_EXTENSION); @@ -583,6 +593,14 @@ namespace SaveState return File::Exists(fn); } + bool HasUndoLastSave(const Path &gameFilename) + { + if (g_Config.sStateUndoLastSaveGame != GenerateFullDiscId(gameFilename)) + return false; + + return HasUndoSaveInSlot(gameFilename, g_Config.iStateUndoLastSaveSlot); + } + bool HasScreenshotInSlot(const Path &gameFilename, int slot) { Path fn = GenerateSaveSlotFilename(gameFilename, slot, SCREENSHOT_EXTENSION); diff --git a/Core/SaveState.h b/Core/SaveState.h index 40d72ca10913..7cd9f0e09697 100644 --- a/Core/SaveState.h +++ b/Core/SaveState.h @@ -47,10 +47,12 @@ namespace SaveState void SaveSlot(const Path &gameFilename, int slot, Callback callback, void *cbUserData = 0); void LoadSlot(const Path &gameFilename, int slot, Callback callback, void *cbUserData = 0); bool UndoSaveSlot(const Path &gameFilename, int slot); + bool UndoLastSave(const Path &gameFilename); bool UndoLoad(const Path &gameFilename, Callback callback, void *cbUserData = 0); // Checks whether there's an existing save in the specified slot. bool HasSaveInSlot(const Path &gameFilename, int slot); bool HasUndoSaveInSlot(const Path &gameFilename, int slot); + bool HasUndoLastSave(const Path &gameFilename); bool HasUndoLoad(const Path &gameFilename); bool HasScreenshotInSlot(const Path &gameFilename, int slot); diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 961d6b054aac..ce700f32a801 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -392,9 +392,13 @@ void GamePauseScreen::CreateViews() { LinearLayout *buttonRow = leftColumnItems->Add(new LinearLayout(ORIENT_HORIZONTAL)); if (g_Config.bEnableStateUndo) { - UI::Choice *loadUndoButton = buttonRow->Add(new Choice(pa->T("Undo last state load"))); + UI::Choice *loadUndoButton = buttonRow->Add(new Choice(pa->T("Undo last load"))); loadUndoButton->SetEnabled(SaveState::HasUndoLoad(gamePath_)); loadUndoButton->OnClick.Handle(this, &GamePauseScreen::OnLoadUndo); + + UI::Choice *saveUndoButton = buttonRow->Add(new Choice(pa->T("Undo last save"))); + saveUndoButton->SetEnabled(SaveState::HasUndoLastSave(gamePath_)); + saveUndoButton->OnClick.Handle(this, &GamePauseScreen::OnLastSaveUndo); } if (g_Config.iRewindFlipFrequency > 0) { @@ -506,6 +510,13 @@ UI::EventReturn GamePauseScreen::OnLoadUndo(UI::EventParams &e) { return UI::EVENT_DONE; } +UI::EventReturn GamePauseScreen::OnLastSaveUndo(UI::EventParams &e) { + SaveState::UndoLastSave(gamePath_); + + RecreateViews(); + return UI::EVENT_DONE; +} + UI::EventReturn GamePauseScreen::OnCwCheat(UI::EventParams &e) { screenManager()->push(new CwCheatScreen(gamePath_)); return UI::EVENT_DONE; diff --git a/UI/PauseScreen.h b/UI/PauseScreen.h index 6d4acbd96136..15b22174e2ea 100644 --- a/UI/PauseScreen.h +++ b/UI/PauseScreen.h @@ -45,6 +45,7 @@ class GamePauseScreen : public UIDialogScreenWithGameBackground { UI::EventReturn OnRewind(UI::EventParams &e); UI::EventReturn OnLoadUndo(UI::EventParams &e); + UI::EventReturn OnLastSaveUndo(UI::EventParams &e); UI::EventReturn OnScreenshotClicked(UI::EventParams &e); UI::EventReturn OnCwCheat(UI::EventParams &e);