diff --git a/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp b/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp index b564251c45..b87fb4747a 100644 --- a/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp @@ -137,19 +137,21 @@ struct msg_dlg_thread_info using msg_dlg_thread = named_thread; -// variable used to immediately get the response from auxiliary message dialogs (callbacks would be async) -atomic_t g_last_user_response = CELL_MSGDIALOG_BUTTON_NONE; - // forward declaration for open_msg_dialog error_code cellMsgDialogOpen2(u32 type, vm::cptr msgString, vm::ptr callback, vm::ptr userData, vm::ptr extParam); // wrapper to call for other hle dialogs -error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr msgString, vm::ptr callback, vm::ptr userData, vm::ptr extParam) +error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr msgString, vm::ptr callback, vm::ptr userData, vm::ptr extParam, s32* return_code) { - cellSysutil.notice("open_msg_dialog(is_blocking=%d, type=0x%x, msgString=%s, callback=*0x%x, userData=*0x%x, extParam=*0x%x)", is_blocking, type, msgString, callback, userData, extParam); + cellSysutil.notice("open_msg_dialog(is_blocking=%d, type=0x%x, msgString=%s, callback=*0x%x, userData=*0x%x, extParam=*0x%x, return_code=*0x%x)", is_blocking, type, msgString, callback, userData, extParam, return_code); const MsgDialogType _type{ type }; + if (return_code) + { + *return_code = CELL_MSGDIALOG_BUTTON_NONE; + } + if (auto manager = g_fxo->try_get()) { if (manager->get()) @@ -162,10 +164,15 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr msgString, return CellSysutilError{ret + 0u}; } - g_last_user_response = CELL_MSGDIALOG_BUTTON_NONE; + const auto notify = std::make_shared>(false); - const auto res = manager->create()->show(is_blocking, msgString.get_ptr(), _type, [callback, userData](s32 status) + const auto res = manager->create()->show(is_blocking, msgString.get_ptr(), _type, [callback, userData, &return_code, is_blocking, ¬ify](s32 status) { + if (return_code) + { + *return_code = status; + } + sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0); if (callback) @@ -176,8 +183,20 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr msgString, return CELL_OK; }); } + + if (is_blocking && notify) + { + *notify = true; + notify->notify_one(); + } }); + // Wait for on_close + while (is_blocking && !Emu.IsStopped() && !*notify) + { + notify->wait(false, atomic_wait_timeout{1'000'000}); + } + return res; } @@ -195,8 +214,13 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr msgString, dlg->type = _type; - dlg->on_close = [callback, userData, wptr = std::weak_ptr(dlg)](s32 status) + dlg->on_close = [callback, userData, &return_code, wptr = std::weak_ptr(dlg)](s32 status) { + if (return_code) + { + *return_code = status; + } + const auto dlg = wptr.lock(); if (dlg && dlg->state.compare_and_swap_test(MsgDialogState::Open, MsgDialogState::Close)) @@ -230,7 +254,6 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr msgString, // Run asynchronously in GUI thread Emu.CallFromMainThread([&, msg_string = std::move(msg_string)]() { - g_last_user_response = CELL_MSGDIALOG_BUTTON_NONE; dlg->Create(msg_string); lv2_obj::awake(&ppu); }); diff --git a/rpcs3/Emu/Cell/Modules/cellMsgDialog.h b/rpcs3/Emu/Cell/Modules/cellMsgDialog.h index 208702cc05..727d0f0cdd 100644 --- a/rpcs3/Emu/Cell/Modules/cellMsgDialog.h +++ b/rpcs3/Emu/Cell/Modules/cellMsgDialog.h @@ -89,10 +89,8 @@ enum class MsgDialogState Close, }; -extern atomic_t g_last_user_response; - void close_msg_dialog(); -error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr msgString, vm::ptr callback = vm::null, vm::ptr userData = vm::null, vm::ptr extParam = vm::null); +error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr msgString, vm::ptr callback = vm::null, vm::ptr userData = vm::null, vm::ptr extParam = vm::null, s32* return_code = nullptr); error_code open_exit_dialog(const std::string& message, bool is_exit_requested); class MsgDialogBase diff --git a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp index cb0c99675b..591c8a1a9d 100644 --- a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp @@ -319,7 +319,8 @@ static error_code select_and_delete(ppu_thread& ppu) lv2_obj::sleep(ppu); // Get user confirmation by opening a blocking dialog - error_code res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO, vm::make_str(msg)); + s32 return_code = CELL_MSGDIALOG_BUTTON_NONE; + error_code res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO, vm::make_str(msg), vm::null, vm::null, vm::null, &return_code); // Reschedule after a blocking dialog returns if (ppu.check_state()) @@ -332,7 +333,7 @@ static error_code select_and_delete(ppu_thread& ppu) return CELL_SAVEDATA_ERROR_INTERNAL; } - if (g_last_user_response.load() == CELL_MSGDIALOG_BUTTON_YES) + if (return_code == CELL_MSGDIALOG_BUTTON_YES) { // Remove directory const std::string path = base_dir + save_entries[selected].escaped; @@ -1157,7 +1158,8 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v lv2_obj::sleep(ppu); // Get user confirmation by opening a blocking dialog - error_code res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO, vm::make_str(message)); + s32 return_code = CELL_MSGDIALOG_BUTTON_NONE; + error_code res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO, vm::make_str(message), vm::null, vm::null, vm::null, &return_code); // Reschedule after a blocking dialog returns if (ppu.check_state()) @@ -1170,7 +1172,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v return CELL_SAVEDATA_ERROR_INTERNAL; } - if (g_last_user_response != CELL_MSGDIALOG_BUTTON_YES) + if (return_code != CELL_MSGDIALOG_BUTTON_YES) { if (selected >= 0) { @@ -1287,7 +1289,8 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v lv2_obj::sleep(ppu); // Get user confirmation by opening a blocking dialog - error_code res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO, vm::make_str(message)); + s32 return_code = CELL_MSGDIALOG_BUTTON_NONE; + error_code res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO, vm::make_str(message), vm::null, vm::null, vm::null, &return_code); // Reschedule after a blocking dialog returns if (ppu.check_state()) @@ -1300,7 +1303,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v return CELL_SAVEDATA_ERROR_INTERNAL; } - if (g_last_user_response != CELL_MSGDIALOG_BUTTON_YES) + if (return_code != CELL_MSGDIALOG_BUTTON_YES) { return CELL_CANCEL; } diff --git a/rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp b/rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp index b21184c836..b76009af99 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp @@ -279,8 +279,6 @@ namespace rsx } return error; } - - g_last_user_response = return_code; } else { diff --git a/rpcs3/Emu/RSX/Overlays/overlays.cpp b/rpcs3/Emu/RSX/Overlays/overlays.cpp index 912c1b53d3..d53c7c3cdf 100644 --- a/rpcs3/Emu/RSX/Overlays/overlays.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlays.cpp @@ -398,7 +398,6 @@ namespace rsx if (on_close && use_callback) { - g_last_user_response = return_code; on_close(return_code); } diff --git a/rpcs3/rpcs3qt/msg_dialog_frame.cpp b/rpcs3/rpcs3qt/msg_dialog_frame.cpp index d46ed721d4..e05c1f87e0 100644 --- a/rpcs3/rpcs3qt/msg_dialog_frame.cpp +++ b/rpcs3/rpcs3qt/msg_dialog_frame.cpp @@ -85,14 +85,12 @@ void msg_dialog_frame::Create(const std::string& msg, const std::string& title) connect(m_button_yes, &QAbstractButton::clicked, [this]() { - g_last_user_response = CELL_MSGDIALOG_BUTTON_YES; if (on_close) on_close(CELL_MSGDIALOG_BUTTON_YES); m_dialog->accept(); }); connect(m_button_no, &QAbstractButton::clicked, [this]() { - g_last_user_response = CELL_MSGDIALOG_BUTTON_NO; if (on_close) on_close(CELL_MSGDIALOG_BUTTON_NO); m_dialog->accept(); }); @@ -117,7 +115,6 @@ void msg_dialog_frame::Create(const std::string& msg, const std::string& title) connect(m_button_ok, &QAbstractButton::clicked, [this]() { - g_last_user_response = CELL_MSGDIALOG_BUTTON_OK; if (on_close) on_close(CELL_MSGDIALOG_BUTTON_OK); m_dialog->accept(); }); @@ -129,7 +126,6 @@ void msg_dialog_frame::Create(const std::string& msg, const std::string& title) { if (!type.disable_cancel) { - g_last_user_response = CELL_MSGDIALOG_BUTTON_ESCAPE; if (on_close) on_close(CELL_MSGDIALOG_BUTTON_ESCAPE); } });