From ae4b7983aae8a21f336892abf6e4c38db933acfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 20 Oct 2026 12:12:24 +0200 Subject: [PATCH] Make --pause-menu-exit quit the app whenever the game ends - Fixes #18456 For external launchers (Android handhelds like the Retroid Pocket), which want control back when the game ends. Before, only the pause menu's Exit quit the app; now the game exiting by itself, a stop request and dismissing a load error do too. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/CmdLine.cpp | 2 +- Core/CmdLine.h | 1 + UI/EmuScreen.cpp | 15 ++++++++++++--- UI/EmuScreen.h | 1 + 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Core/CmdLine.cpp b/Core/CmdLine.cpp index f7c17b7d00..960c093909 100644 --- a/Core/CmdLine.cpp +++ b/Core/CmdLine.cpp @@ -189,7 +189,7 @@ static const CommandLineParam g_autoParams[] = { {POFF(fullscreen), CmdParamType::BoolInverse, "windowed", '\0', "Force windowed mode", CmdLineMode::Application}, {POFF(startScreen), CmdParamType::String, "start-screen", '\0', "Start on a specific screen (e.g. 'gamesettings', 'touchscreentest')", CmdLineMode::Application}, {POFF(escapeExit), CmdParamType::Bool, "escape-exit", '\0', "Escape key exits the application", CmdLineMode::Application}, - {POFF(pauseMenuExit), CmdParamType::Bool, "pause-menu-exit", '\0', "Change \"Exit to menu\" in pause menu to \"Exit\"", CmdLineMode::Application}, + {POFF(pauseMenuExit), CmdParamType::Bool, "pause-menu-exit", '\0', "Exit the application when the game ends, instead of returning to the menu", CmdLineMode::Application}, {POFF(appendConfig), CmdParamType::String, "appendconfig", '\0', "Merge config FILE into the current configuration"}, {POFF(root), CmdParamType::String, "root", 'r', "Mount directory as the root of host0:/."}, {POFF(memStick), CmdParamType::String, "memstick", '\0', "Memory stick root directory (contains PSP/GAME etc)"}, diff --git a/Core/CmdLine.h b/Core/CmdLine.h index 12142eb100..7e7a68043a 100644 --- a/Core/CmdLine.h +++ b/Core/CmdLine.h @@ -47,6 +47,7 @@ struct CommandLineOptions { std::optional escapeExit; // Run as if no memory stick were inserted. std::optional memStickInserted; + // Quit the app instead of going to the main menu when the game ends, for external launchers. std::optional pauseMenuExit; // Enables the WebSocket debugger on startup, on this port (0 = pick automatically). diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 7651e3d8ed..c2fec82550 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -516,7 +516,7 @@ void EmuScreen::dialogFinished(const Screen *dialog, DialogResult result) { // DR_CANCEL/DR_BACK means clicked on "continue", DR_OK means clicked on "back to menu", // DR_YES means a message sent to PauseMenu by System_PostUIMessage. if ((result == DR_OK || quit_) && !bootPending_) { - screenManager()->switchScreen(new MainScreen()); + leaveGame(); quit_ = false; } else { RecreateViews(); @@ -563,7 +563,7 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) { INFO_LOG(Log::Loader, "REQUEST_GAME_STOP: running exit callback before shutdown."); } else { // No callback (or already in flight, or core not running) - the destructor will take care of shutting down. - screenManager()->switchScreen(new MainScreen()); + leaveGame(); } } else if (message == UIMessage::REQUEST_GAME_RESET) { if (bootPending_) { @@ -1532,12 +1532,21 @@ bool EmuScreen::checkPowerDown() { // Also for REQUEST_STOP. if (coreState == CORE_POWERDOWN && PSP_GetBootState() == BootState::Complete && !bootPending_) { INFO_LOG(Log::System, "SELF-POWERDOWN!"); - screenManager()->switchScreen(new MainScreen()); + leaveGame(); return true; } return false; } +void EmuScreen::leaveGame() { + // Switch screens even when exiting, so the game gets shut down the usual way. + screenManager()->switchScreen(new MainScreen()); + if (g_Config.bPauseMenuExitsEmulator) { + INFO_LOG(Log::System, "Game ended, exiting (--pause-menu-exit)"); + System_ExitApp(); + } +} + ScreenRenderRole EmuScreen::renderRole(bool isTop) const { auto CanBeBackground = [this, isTop]() -> bool { if (skipBufferEffects_) { diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index ca99064229..790143f27a 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -90,6 +90,7 @@ private: void AutoLoadSaveState(); bool checkPowerDown(); + void leaveGame(); void ProcessQueuedVKeys(); void ProcessVKey(VirtKey vkey, bool down);