From fe79e541dd4a8026df18daed17ab4f9e82ef6735 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sun, 20 Jan 2019 22:57:51 +0100 Subject: [PATCH] cellGame: improve exit functions --- rpcs3/Emu/Cell/Modules/cellGame.cpp | 47 +++++++------------ rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp | 57 ++++++++++++++++++++++++ rpcs3/Emu/Cell/Modules/cellMsgDialog.h | 1 + 3 files changed, 73 insertions(+), 32 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellGame.cpp b/rpcs3/Emu/Cell/Modules/cellGame.cpp index dd731365d0..800e82c7cf 100644 --- a/rpcs3/Emu/Cell/Modules/cellGame.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGame.cpp @@ -1,4 +1,4 @@ -#include "stdafx.h" +#include "stdafx.h" #include "Emu/System.h" #include "Emu/IdManager.h" #include "Emu/Cell/PPUModule.h" @@ -253,17 +253,7 @@ error_code cellHddGameSetSystemVer(vm::cptr systemVersion) error_code cellHddGameExitBroken() { cellGame.warning("cellHddGameExitBroken()"); - - s32 res = open_msg_dialog(CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK | CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_ON, - vm::make_str("There has been an error!\n\nPlease reinstall the HDD boot game.")); - - if (res != CELL_OK) - { - return CELL_HDDGAME_ERROR_INTERNAL; - } - - sysutil_send_system_cmd(CELL_SYSUTIL_REQUEST_EXITGAME, 0); - return CELL_OK; + return open_exit_dialog("There has been an error!\n\nPlease reinstall the HDD boot game.", true); } error_code cellGameDataGetSizeKB(vm::ptr size) @@ -302,17 +292,7 @@ error_code cellGameDataSetSystemVer(vm::cptr systemVersion) error_code cellGameDataExitBroken() { cellGame.warning("cellGameDataExitBroken()"); - - s32 res = open_msg_dialog(CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK | CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_ON, - vm::make_str("There has been an error!\n\nPlease delete the game's game data.")); - - if (res != CELL_OK) - { - return CELL_GAMEDATA_ERROR_INTERNAL; - } - - sysutil_send_system_cmd(CELL_SYSUTIL_REQUEST_EXITGAME, 0); - return CELL_OK; + return open_exit_dialog("There has been an error!\n\nPlease delete the game's game data.", true); } error_code cellGameBootCheck(vm::ptr type, vm::ptr attributes, vm::ptr size, vm::ptr dirName) @@ -904,12 +884,12 @@ error_code cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::cptr CELL_GAME_ERRDIALOG_NOSPACE); } s32 cellGameThemeInstall(vm::cptr usrdirPath, vm::cptr fileName, u32 option) diff --git a/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp b/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp index 015b5b6254..c7977354c2 100644 --- a/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp @@ -40,6 +40,60 @@ error_code open_msg_dialog(u32 type, vm::cptr msgString, vm::ptr/* userData*/) +{ + sysutil_send_system_cmd(CELL_SYSUTIL_REQUEST_EXITGAME, 0); +} + +error_code open_exit_dialog(const std::string& message, bool is_exit_requested) +{ + cellSysutil.warning("open_exit_dialog(message=%s, is_exit_requested=%d)", message, is_exit_requested); + + vm::bptr callback = vm::null; + + if (is_exit_requested) + { + callback.set(ppu_function_manager::addr + 8 * FIND_FUNC(exit_game)); + } + + const error_code res = cellMsgDialogOpen2 + ( + CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK | CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_ON, + vm::make_str(message), callback, vm::null, vm::null + ); + + if (res != CELL_OK) + { + // Something went wrong, exit anyway + if (is_exit_requested) + { + sysutil_send_system_cmd(CELL_SYSUTIL_REQUEST_EXITGAME, 0); + } + return CELL_OK; + } + + if (auto manager = fxm::get()) + { + while (auto dlg = manager->get()) + { + dlg->refresh(); + } + } + else + { + while (auto dlg = fxm::get()) + { + if (dlg->state != MsgDialogState::Open) + { + break; + } + std::this_thread::yield(); + } + } + + return CELL_OK; +} + error_code cellMsgDialogOpen2(u32 type, vm::cptr msgString, vm::ptr callback, vm::ptr userData, vm::ptr extParam) { cellSysutil.warning("cellMsgDialogOpen2(type=0x%x, msgString=%s, callback=*0x%x, userData=*0x%x, extParam=*0x%x)", type, msgString, callback, userData, extParam); @@ -462,4 +516,7 @@ void cellSysutil_MsgDialog_init() REG_FUNC(cellSysutil, cellMsgDialogProgressBarInc); REG_FUNC(cellSysutil, cellMsgDialogClose); REG_FUNC(cellSysutil, cellMsgDialogAbort); + + // Helper Function + REG_FUNC(cellSysutil, exit_game); } diff --git a/rpcs3/Emu/Cell/Modules/cellMsgDialog.h b/rpcs3/Emu/Cell/Modules/cellMsgDialog.h index 5e7df5416f..97e48bdbfc 100644 --- a/rpcs3/Emu/Cell/Modules/cellMsgDialog.h +++ b/rpcs3/Emu/Cell/Modules/cellMsgDialog.h @@ -83,6 +83,7 @@ enum class MsgDialogState }; error_code open_msg_dialog(u32 type, vm::cptr msgString, vm::ptr callback = vm::null, vm::ptr userData = vm::null, vm::ptr extParam = vm::null); +error_code open_exit_dialog(const std::string& message, bool is_exit_requested); class MsgDialogBase {