diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index b95072658c..74a698b58a 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -43,7 +43,6 @@ #include "Core/MIPS/JitCommon/JitBlockCache.h" #include "HW/MemoryStick.h" #include "GPU/GPUState.h" -#include "UI/OnScreenDisplay.h" namespace SaveState { @@ -389,9 +388,8 @@ namespace SaveState Load(fn, callback, cbUserData); } else { I18NCategory *sy = GetI18NCategory("System"); - osm.Show(sy->T("Failed to load state. Error in the file system."), 2.0); if (callback) - callback(false, cbUserData); + callback(false, sy->T("Failed to load state. Error in the file system."), cbUserData); } } @@ -400,7 +398,7 @@ namespace SaveState std::string fn = GenerateSaveSlotFilename(gameFilename, slot, STATE_EXTENSION); std::string shot = GenerateSaveSlotFilename(gameFilename, slot, SCREENSHOT_EXTENSION); if (!fn.empty()) { - auto renameCallback = [=](bool status, void *data) { + auto renameCallback = [=](bool status, const std::string &message, void *data) { if (status) { if (File::Exists(fn)) { File::Delete(fn); @@ -408,17 +406,16 @@ namespace SaveState File::Rename(fn + ".tmp", fn); } if (callback) { - callback(status, data); + callback(status, message, data); } }; // Let's also create a screenshot. SaveScreenshot(shot, Callback(), 0); Save(fn + ".tmp", renameCallback, cbUserData); } else { - I18NCategory *sc = GetI18NCategory("Screen"); - osm.Show("Failed to save state. Error in the file system.", 2.0); + I18NCategory *sy = GetI18NCategory("System"); if (callback) - callback(false, cbUserData); + callback(false, sy->T("Failed to save state. Error in the file system."), cbUserData); } } @@ -564,6 +561,7 @@ namespace SaveState Operation &op = operations[i]; CChunkFileReader::Error result; bool callbackResult; + std::string callbackMessage; std::string reason; I18NCategory *sc = GetI18NCategory("Screen"); @@ -580,16 +578,16 @@ namespace SaveState INFO_LOG(COMMON, "Loading state from %s", op.filename.c_str()); result = CChunkFileReader::Load(op.filename, PPSSPP_GIT_VERSION, state, &reason); if (result == CChunkFileReader::ERROR_NONE) { - osm.Show(sc->T("Loaded State"), 2.0); + callbackMessage = sc->T("Loaded State"); callbackResult = true; hasLoadedState = true; } else if (result == CChunkFileReader::ERROR_BROKEN_STATE) { HandleFailure(); - osm.Show(i18nLoadFailure, 2.0); + callbackMessage = i18nLoadFailure; ERROR_LOG(COMMON, "Load state failure: %s", reason.c_str()); callbackResult = false; } else { - osm.Show(sc->T(reason.c_str(), i18nLoadFailure), 2.0); + callbackMessage = sc->T(reason.c_str(), i18nLoadFailure); callbackResult = false; } break; @@ -598,45 +596,48 @@ namespace SaveState INFO_LOG(COMMON, "Saving state to %s", op.filename.c_str()); result = CChunkFileReader::Save(op.filename, g_paramSFO.GetValueString("TITLE"), PPSSPP_GIT_VERSION, state); if (result == CChunkFileReader::ERROR_NONE) { - - osm.Show(sc->T("Saved State"), 2.0); + callbackMessage = sc->T("Saved State"); callbackResult = true; } else if (result == CChunkFileReader::ERROR_BROKEN_STATE) { HandleFailure(); - osm.Show(i18nSaveFailure, 2.0); + callbackMessage = i18nSaveFailure; ERROR_LOG(COMMON, "Save state failure: %s", reason.c_str()); callbackResult = false; } else { - osm.Show(i18nSaveFailure, 2.0); + callbackMessage = i18nSaveFailure; callbackResult = false; } break; case SAVESTATE_VERIFY: - INFO_LOG(COMMON, "Verifying save state system"); callbackResult = CChunkFileReader::Verify(state) == CChunkFileReader::ERROR_NONE; + if (callbackResult) { + INFO_LOG(COMMON, "Verified save state system"); + } else { + ERROR_LOG(COMMON, "Save state system verification failed"); + } break; case SAVESTATE_REWIND: INFO_LOG(COMMON, "Rewinding to recent savestate snapshot"); result = rewindStates.Restore(); if (result == CChunkFileReader::ERROR_NONE) { - osm.Show(sc->T("Loaded State"), 2.0); + callbackMessage = sc->T("Loaded State"); callbackResult = true; hasLoadedState = true; } else if (result == CChunkFileReader::ERROR_BROKEN_STATE) { // Cripes. Good news is, we might have more. Let's try those too, better than a reset. if (HandleFailure()) { // Well, we did rewind, even if too much... - osm.Show(sc->T("Loaded State"), 2.0); + callbackMessage = sc->T("Loaded State"); callbackResult = true; hasLoadedState = true; } else { - osm.Show(i18nLoadFailure, 2.0); + callbackMessage = i18nLoadFailure; callbackResult = false; } } else { - osm.Show(i18nLoadFailure, 2.0); + callbackMessage = i18nLoadFailure; callbackResult = false; } break; @@ -655,7 +656,7 @@ namespace SaveState } if (op.callback) - op.callback(callbackResult, op.cbUserData); + op.callback(callbackResult, callbackMessage, op.cbUserData); } if (operations.size()) { // Avoid triggering frame skipping due to slowdown diff --git a/Core/SaveState.h b/Core/SaveState.h index fa6220b224..741593bbba 100644 --- a/Core/SaveState.h +++ b/Core/SaveState.h @@ -23,7 +23,7 @@ namespace SaveState { - typedef std::function Callback; + typedef std::function Callback; static const int NUM_SLOTS = 5; static const char *STATE_EXTENSION = "ppst"; diff --git a/Qt/mainwindow.cpp b/Qt/mainwindow.cpp index 8ae678ff14..2f4b139466 100644 --- a/Qt/mainwindow.cpp +++ b/Qt/mainwindow.cpp @@ -178,7 +178,7 @@ void MainWindow::closeAct() SetGameTitle(""); } -void SaveStateActionFinished(bool result, void *userdata) +void SaveStateActionFinished(bool result, const std::string &message, void *userdata) { // TODO: Improve messaging? if (!result) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index b95c4880ed..81669500d5 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -218,7 +218,14 @@ void EmuScreen::dialogFinished(const Screen *dialog, DialogResult result) { RecreateViews(); } -static void AfterStateLoad(bool success, void *ignored) { +static void AfterSaveStateAction(bool success, const std::string &message, void *) { + if (!message.empty()) { + osm.Show(message, 2.0); + } +} + +static void AfterStateBoot(bool success, const std::string &message, void *ignored) { + AfterSaveStateAction(success, message, ignored); Core_EnableStepping(false); host->UpdateDisassembly(); } @@ -252,7 +259,7 @@ void EmuScreen::sendMessage(const char *message, const char *value) { } else if (!strcmp(message, "boot")) { const char *ext = strrchr(value, '.'); if (ext != nullptr && !strcmp(ext, ".ppst")) { - SaveState::Load(value, &AfterStateLoad); + SaveState::Load(value, &AfterStateBoot); } else { PSP_Shutdown(); bootPending_ = true; @@ -385,16 +392,16 @@ void EmuScreen::onVKeyDown(int virtualKeyCode) { case VIRTKEY_REWIND: if (SaveState::CanRewind()) { - SaveState::Rewind(); + SaveState::Rewind(&AfterSaveStateAction); } else { osm.Show(sc->T("norewind", "No rewind save states available"), 2.0); } break; case VIRTKEY_SAVE_STATE: - SaveState::SaveSlot(gamePath_, g_Config.iCurrentStateSlot, SaveState::Callback()); + SaveState::SaveSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction); break; case VIRTKEY_LOAD_STATE: - SaveState::LoadSlot(gamePath_, g_Config.iCurrentStateSlot, SaveState::Callback()); + SaveState::LoadSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction); break; case VIRTKEY_NEXT_SLOT: SaveState::NextSlot(); @@ -1024,7 +1031,7 @@ void EmuScreen::autoLoad() { //check if save state has save, if so, load int lastSlot = SaveState::GetNewestSlot(gamePath_); if (g_Config.bEnableAutoLoad && lastSlot != -1) { - SaveState::LoadSlot(gamePath_, lastSlot, SaveState::Callback(), 0); + SaveState::LoadSlot(gamePath_, lastSlot, &AfterSaveStateAction); g_Config.iCurrentStateSlot = lastSlot; } } diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 1ece9d814b..5e5bbb27fc 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -489,8 +489,13 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch } #endif - if (!boot_filename.empty() && stateToLoad != NULL) - SaveState::Load(stateToLoad); + if (!boot_filename.empty() && stateToLoad != NULL) { + SaveState::Load(stateToLoad, [](bool status, const std::string &message, void *) { + if (!message.empty()) { + osm.Show(message, 2.0); + } + }); + } screenManager = new ScreenManager(); if (skipLogo) { diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 609c5b3aef..6be177c889 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -40,6 +40,7 @@ #include "UI/ReportScreen.h" #include "UI/CwCheatScreen.h" #include "UI/MainScreen.h" +#include "UI/OnScreenDisplay.h" #include "UI/GameInfoCache.h" void AsyncImageFileView::GetContentDimensions(const UIContext &dc, float &w, float &h) const { @@ -224,9 +225,15 @@ void SaveSlotView::Draw(UIContext &dc) { UI::LinearLayout::Draw(dc); } +static void AfterSaveStateAction(bool status, const std::string &message, void *) { + if (!message.empty()) { + osm.Show(message, 2.0); + } +} + UI::EventReturn SaveSlotView::OnLoadState(UI::EventParams &e) { g_Config.iCurrentStateSlot = slot_; - SaveState::LoadSlot(gamePath_, slot_, SaveState::Callback(), 0); + SaveState::LoadSlot(gamePath_, slot_, &AfterSaveStateAction); UI::EventParams e2; e2.v = this; OnStateLoaded.Trigger(e2); @@ -235,7 +242,7 @@ UI::EventReturn SaveSlotView::OnLoadState(UI::EventParams &e) { UI::EventReturn SaveSlotView::OnSaveState(UI::EventParams &e) { g_Config.iCurrentStateSlot = slot_; - SaveState::SaveSlot(gamePath_, slot_, SaveState::Callback(), 0); + SaveState::SaveSlot(gamePath_, slot_, &AfterSaveStateAction); UI::EventParams e2; e2.v = this; OnStateSaved.Trigger(e2); @@ -389,7 +396,7 @@ UI::EventReturn GamePauseScreen::OnReportFeedback(UI::EventParams &e) { } UI::EventReturn GamePauseScreen::OnRewind(UI::EventParams &e) { - SaveState::Rewind(SaveState::Callback(), 0); + SaveState::Rewind(&AfterSaveStateAction); screenManager()->finishDialog(this, DR_CANCEL); return UI::EVENT_DONE; diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 133dafee32..c70e7f72de 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -400,7 +400,10 @@ namespace MainWindow { g_Config.iInternalScreenRotation = rotation; } - static void SaveStateActionFinished(bool result, void *userdata) { + static void SaveStateActionFinished(bool result, const std::string &message, void *userdata) { + if (!message.empty()) { + osm.Show(message, 2.0); + } PostMessage(MainWindow::GetHWND(), WM_USER_SAVESTATE_FINISH, 0, 0); }