From c6298dd0e3b2a2b5868067aca2159db55c49a49d Mon Sep 17 00:00:00 2001 From: NicknineTheEagle Date: Fri, 29 May 2026 05:12:13 +0300 Subject: [PATCH] [XAM] Implemented game exit behavior in XamLoaderTerminateTitle --- src/xenia/kernel/xam/xam_info.cc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/xenia/kernel/xam/xam_info.cc b/src/xenia/kernel/xam/xam_info.cc index 48be467fe..24491fddc 100644 --- a/src/xenia/kernel/xam/xam_info.cc +++ b/src/xenia/kernel/xam/xam_info.cc @@ -342,6 +342,32 @@ void XamLoaderLaunchTitle_entry(lpstring_t raw_name_ptr, dword_t flags) { DECLARE_XAM_EXPORT1(XamLoaderLaunchTitle, kNone, kSketchy); void XamLoaderTerminateTitle_entry() { + std::string title = "Title terminated"; + std::string message = "Game requested exit to dashboard."; + assert_always("Game requested exit to dashboard via XamLoaderTerminateTitle"); + + auto display_window = kernel_state()->emulator()->display_window(); + auto imgui_drawer = kernel_state()->emulator()->imgui_drawer(); + + if (display_window && imgui_drawer) { + display_window->app_context().CallInUIThreadSynchronous( + [imgui_drawer, title, message]() { + auto dialog = xe::ui::ImGuiDialog::ShowMessageBox( + imgui_drawer, title.c_str(), message.c_str()); + + std::jthread([dialog]() { + while (!dialog->IsClosing()) { + std::this_thread::yield(); + } + + config::SaveConfig(); + xe::FlushLog(); + + std::quick_exit(0); + }).detach(); + }); + } + // This function does not return. kernel_state()->TerminateTitle(); }