mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Avoid getting stuck in a load-loop when auto-loading a bad savestate. Make some code clearer.
This commit is contained in:
+3
-6
@@ -1139,15 +1139,12 @@ double g_lastSaveTime = -1.0;
|
||||
lastSaveDataGeneration = saveDataGeneration;
|
||||
}
|
||||
|
||||
void Cleanup() {
|
||||
// TODO: Handle this better.
|
||||
bool PollRestartNeeded() {
|
||||
if (needsRestart) {
|
||||
std::string error_string;
|
||||
PSP_Reboot(&error_string);
|
||||
System_Notify(SystemNotification::BOOT_DONE);
|
||||
System_Notify(SystemNotification::DISASSEMBLY);
|
||||
needsRestart = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Init()
|
||||
|
||||
+2
-2
@@ -108,8 +108,8 @@ namespace SaveState {
|
||||
// Notify save state code that new save data has been written.
|
||||
void NotifySaveData();
|
||||
|
||||
// Cleanup by triggering a restart if needed.
|
||||
void Cleanup();
|
||||
// Checks whether a bad load required the caller to trigger a restart (and if returns true, resets the flag internally).
|
||||
bool PollRestartNeeded();
|
||||
|
||||
// Returns the time since last save. -1 if N/A.
|
||||
double SecondsSinceLastSavestate();
|
||||
|
||||
@@ -702,19 +702,6 @@ BootState PSP_Reboot(std::string *error_string) {
|
||||
return PSP_Init(PSP_CoreParameter(), error_string);
|
||||
}
|
||||
|
||||
void PSP_BeginHostFrame() {
|
||||
if (gpu) {
|
||||
gpu->BeginHostFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void PSP_EndHostFrame() {
|
||||
if (gpu) {
|
||||
gpu->EndHostFrame();
|
||||
}
|
||||
SaveState::Cleanup();
|
||||
}
|
||||
|
||||
void PSP_RunLoopWhileState() {
|
||||
// We just run the CPU until we get to vblank. This will quickly sync up pretty nicely.
|
||||
// The actual number of cycles doesn't matter so much here as we will break due to CORE_NEXTFRAME, most of the time hopefully...
|
||||
|
||||
+1
-3
@@ -102,12 +102,10 @@ BootState PSP_Reboot(std::string *error_string);
|
||||
|
||||
FileLoader *PSP_LoadedFile();
|
||||
|
||||
void PSP_BeginHostFrame();
|
||||
void PSP_EndHostFrame();
|
||||
void PSP_RunLoopWhileState();
|
||||
void PSP_RunLoopFor(int cycles);
|
||||
|
||||
// Call before PSP_BeginHostFrame() in order to not miss any GPU stats.
|
||||
// Call before gpu->BeginHostFrame() in order to not miss any GPU stats.
|
||||
void PSP_UpdateDebugStats(bool collectStats);
|
||||
// Increments or decrements an internal counter. Intended to be used by debuggers.
|
||||
void PSP_ForceDebugStats(bool enable);
|
||||
|
||||
+55
-25
@@ -545,6 +545,7 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) {
|
||||
RecreateViews();
|
||||
_dbg_assert_(coreState == CORE_POWERDOWN);
|
||||
if (!PSP_InitStart(PSP_CoreParameter())) {
|
||||
bootPending_ = false;
|
||||
WARN_LOG(Log::Loader, "Error resetting");
|
||||
screenManager()->switchScreen(new MainScreen());
|
||||
return;
|
||||
@@ -773,17 +774,6 @@ void EmuScreen::onVKey(VirtKey virtualKeyCode, bool down) {
|
||||
}
|
||||
break;
|
||||
|
||||
case VIRTKEY_PAUSE_NO_MENU:
|
||||
if (down && !NetworkWarnUserIfOnlineAndCantSpeed()) {
|
||||
// We re-use debug break/resume to implement pause/resume without a menu.
|
||||
if (coreState == CORE_STEPPING_CPU) { // should we check reason?
|
||||
Core_Resume();
|
||||
} else {
|
||||
Core_Break(BreakReason::UIPause);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VIRTKEY_RESET_EMULATION:
|
||||
if (down) {
|
||||
System_PostUIMessage(UIMessage::REQUEST_GAME_RESET);
|
||||
@@ -812,15 +802,6 @@ void EmuScreen::onVKey(VirtKey virtualKeyCode, bool down) {
|
||||
break;
|
||||
#endif
|
||||
|
||||
case VIRTKEY_REWIND:
|
||||
if (down && !Achievements::WarnUserIfHardcoreModeActive(false) && !NetworkWarnUserIfOnlineAndCantSavestate() && !bootPending_) {
|
||||
if (SaveState::CanRewind()) {
|
||||
SaveState::Rewind(&AfterSaveStateAction);
|
||||
} else {
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, sc->T("norewind", "No rewind save states available"), 2.0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VIRTKEY_SAVE_STATE:
|
||||
if (down && !Achievements::WarnUserIfHardcoreModeActive(true) && !NetworkWarnUserIfOnlineAndCantSavestate() && !bootPending_) {
|
||||
SaveState::SaveSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction);
|
||||
@@ -964,6 +945,27 @@ void EmuScreen::ProcessVKey(VirtKey virtKey) {
|
||||
}
|
||||
break;
|
||||
|
||||
case VIRTKEY_REWIND:
|
||||
if (!Achievements::WarnUserIfHardcoreModeActive(false) && !NetworkWarnUserIfOnlineAndCantSavestate() && !bootPending_) {
|
||||
if (SaveState::CanRewind()) {
|
||||
SaveState::Rewind(&AfterSaveStateAction);
|
||||
} else {
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, sc->T("norewind", "No rewind save states available"), 2.0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VIRTKEY_PAUSE_NO_MENU:
|
||||
if (!NetworkWarnUserIfOnlineAndCantSpeed()) {
|
||||
// We re-use debug break/resume to implement pause/resume without a menu.
|
||||
if (coreState == CORE_STEPPING_CPU) { // should we check reason?
|
||||
Core_Resume();
|
||||
} else {
|
||||
Core_Break(BreakReason::UIPause);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VIRTKEY_EXIT_APP:
|
||||
{
|
||||
std::string confirmExitMessage = GetConfirmExitMessage();
|
||||
@@ -1578,9 +1580,9 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) {
|
||||
// Just to make sure.
|
||||
if (PSP_IsInited() && !skipBufferEffects) {
|
||||
_dbg_assert_(gpu);
|
||||
PSP_BeginHostFrame();
|
||||
gpu->BeginHostFrame();
|
||||
gpu->CopyDisplayToOutput(true);
|
||||
PSP_EndHostFrame();
|
||||
gpu->EndHostFrame();
|
||||
}
|
||||
if (gpu && gpu->PresentedThisFrame()) {
|
||||
framebufferBound = true;
|
||||
@@ -1644,7 +1646,9 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) {
|
||||
bool blockedExecution = Achievements::IsBlockingExecution();
|
||||
uint32_t clearColor = 0;
|
||||
if (!blockedExecution) {
|
||||
PSP_BeginHostFrame();
|
||||
if (gpu) {
|
||||
gpu->BeginHostFrame();
|
||||
}
|
||||
if (SaveState::Process()) {
|
||||
// We might have lost the framebuffer bind if we had one, due to a readback.
|
||||
if (framebufferBound) {
|
||||
@@ -1697,7 +1701,24 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) {
|
||||
break;
|
||||
}
|
||||
|
||||
PSP_EndHostFrame();
|
||||
if (gpu) {
|
||||
gpu->EndHostFrame();
|
||||
}
|
||||
|
||||
if (SaveState::PollRestartNeeded() && !bootPending_) {
|
||||
PSP_Shutdown(true);
|
||||
Achievements::UnloadGame();
|
||||
|
||||
// Restart the boot process
|
||||
bootPending_ = true;
|
||||
RecreateViews();
|
||||
_dbg_assert_(coreState == CORE_POWERDOWN);
|
||||
if (!PSP_InitStart(PSP_CoreParameter())) {
|
||||
bootPending_ = false;
|
||||
WARN_LOG(Log::Loader, "Error resetting");
|
||||
screenManager()->switchScreen(new MainScreen());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (frameStep_) {
|
||||
@@ -1942,6 +1963,10 @@ void EmuScreen::renderUI() {
|
||||
}
|
||||
|
||||
void EmuScreen::AutoLoadSaveState() {
|
||||
if (autoLoadFailed_) {
|
||||
return;
|
||||
}
|
||||
|
||||
int autoSlot = -1;
|
||||
|
||||
//check if save state has save, if so, load
|
||||
@@ -1960,7 +1985,12 @@ void EmuScreen::AutoLoadSaveState() {
|
||||
}
|
||||
|
||||
if (g_Config.iAutoLoadSaveState && autoSlot != -1) {
|
||||
SaveState::LoadSlot(gamePath_, autoSlot, &AfterSaveStateAction);
|
||||
SaveState::LoadSlot(gamePath_, autoSlot, [this](SaveState::Status status, std::string_view message) {
|
||||
AfterSaveStateAction(status, message);
|
||||
if (status == SaveState::Status::FAILURE) {
|
||||
autoLoadFailed_ = true;
|
||||
}
|
||||
});
|
||||
g_Config.iCurrentStateSlot = autoSlot;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +155,7 @@ private:
|
||||
#ifndef MOBILE_DEVICE
|
||||
bool startDumping_ = false;
|
||||
#endif
|
||||
bool autoLoadFailed_ = false; // to prevent repeat reloads
|
||||
};
|
||||
|
||||
bool MustRunBehind();
|
||||
|
||||
@@ -127,8 +127,6 @@ bool RunTests() {
|
||||
return false;
|
||||
}
|
||||
|
||||
PSP_BeginHostFrame();
|
||||
|
||||
// Run the emu until the test exits
|
||||
INFO_LOG(Log::System, "Test: Entering runloop.");
|
||||
while (true) {
|
||||
@@ -145,7 +143,6 @@ bool RunTests() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
PSP_EndHostFrame();
|
||||
|
||||
std::string expect_results;
|
||||
if (!File::ReadTextFileToString(expectedFile, &expect_results)) {
|
||||
|
||||
@@ -215,10 +215,13 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, const
|
||||
|
||||
PSP_UpdateDebugStats((DebugOverlay)g_Config.iDebugOverlay == DebugOverlay::DEBUG_STATS || g_Config.bLogFrameDrops);
|
||||
|
||||
PSP_BeginHostFrame();
|
||||
if (gpu) {
|
||||
gpu->BeginHostFrame();
|
||||
}
|
||||
Draw::DrawContext *draw = coreParameter.graphicsContext ? coreParameter.graphicsContext->GetDrawContext() : nullptr;
|
||||
if (draw)
|
||||
if (draw) {
|
||||
draw->BeginFrame(Draw::DebugFlags::NONE);
|
||||
}
|
||||
|
||||
bool passed = true;
|
||||
double deadline = time_now_d() + opt.timeout;
|
||||
@@ -255,7 +258,9 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, const
|
||||
Core_Stop();
|
||||
}
|
||||
}
|
||||
PSP_EndHostFrame();
|
||||
if (gpu) {
|
||||
gpu->EndHostFrame();
|
||||
}
|
||||
|
||||
if (draw) {
|
||||
draw->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "Headless");
|
||||
|
||||
Reference in New Issue
Block a user