diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp index 485635e15d..37e4a94844 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp @@ -14,7 +14,6 @@ extern u64 get_system_time(); std::unique_ptr g_msg_dialog; MsgDialogInstance::MsgDialogInstance() - : state(msgDialogNone) { } @@ -83,7 +82,7 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr msgString, vm::ptrstate.compare_exchange_strong(old, msgDialogOpen)) + if (!g_msg_dialog->state.compare_exchange_strong(old, msgDialogInit)) { return CELL_SYSUTIL_ERROR_BUSY; } @@ -105,33 +104,45 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr msgString, vm::ptrstatus = CELL_MSGDIALOG_BUTTON_NONE; + + CallAfter([type, msg]() + { + if (Emu.IsStopped()) + { + g_msg_dialog->state.exchange(msgDialogNone); + + return; + } + + g_msg_dialog->Create(type, msg); + + g_msg_dialog->state.exchange(msgDialogOpen); + }); + + while (g_msg_dialog->state == msgDialogInit) + { + if (Emu.IsStopped()) + { + if (g_msg_dialog->state != msgDialogNone) + { + break; + } + + CHECK_EMU_STATUS; + } + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + } + thread_t(WRAP_EXPR("MsgDialog Thread"), [=]() { - switch (type & CELL_MSGDIALOG_TYPE_SE_TYPE) - { - case CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL: cellSysutil.Warning("%s", msg); break; - case CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR: cellSysutil.Error("%s", msg); break; - } - - g_msg_dialog->status = CELL_MSGDIALOG_BUTTON_NONE; - - volatile bool m_signal = false; - CallAfter([type, msg, &m_signal]() - { - if (Emu.IsStopped()) return; - - g_msg_dialog->Create(type, msg); - - m_signal = true; - }); - - while (!m_signal) - { - CHECK_EMU_STATUS; - - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - } - while (g_msg_dialog->state == msgDialogOpen || (s64)(get_system_time() - g_msg_dialog->wait_until) < 0) { if (Emu.IsStopped()) @@ -142,7 +153,7 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr msgString, vm::ptrstate != msgDialogAbort)) + if (callback && g_msg_dialog->state != msgDialogAbort) { const s32 status = g_msg_dialog->status; @@ -350,6 +361,8 @@ s32 cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta) void cellSysutil_MsgDialog_init() { + g_msg_dialog->state = msgDialogNone; + REG_FUNC(cellSysutil, cellMsgDialogOpen2); REG_FUNC(cellSysutil, cellMsgDialogOpenErrorCode); REG_FUNC(cellSysutil, cellMsgDialogProgressBarSetMsg); diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h index f861c054af..41664c1b96 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h @@ -82,11 +82,12 @@ enum : s32 CELL_MSGDIALOG_BUTTON_ESCAPE = 3, }; -typedef void(CellMsgDialogCallback)(s32 buttonType, vm::ptr userData); +using CellMsgDialogCallback = void(s32 buttonType, vm::ptr userData); enum MsgDialogState { msgDialogNone, + msgDialogInit, msgDialogOpen, msgDialogClose, msgDialogAbort, @@ -96,9 +97,9 @@ struct MsgDialogInstance { std::atomic state; - s32 status = 0; - u64 wait_until = 0; - u32 progress_bar_count = 0; + s32 status; + u64 wait_until; + u32 progress_bar_count; MsgDialogInstance(); virtual ~MsgDialogInstance() = default; diff --git a/rpcs3/Gui/MsgDialog.cpp b/rpcs3/Gui/MsgDialog.cpp index 6a713908d8..b58d01b595 100644 --- a/rpcs3/Gui/MsgDialog.cpp +++ b/rpcs3/Gui/MsgDialog.cpp @@ -17,27 +17,27 @@ void MsgDialogFrame::Create(u32 type, std::string msg) m_button_yes = nullptr; m_button_no = nullptr; - m_dialog = new wxDialog(parent, wxID_ANY, type & CELL_MSGDIALOG_TYPE_SE_TYPE ? "" : "Error", wxDefaultPosition, wxDefaultSize); + m_dialog = std::make_unique(parent, wxID_ANY, type & CELL_MSGDIALOG_TYPE_SE_TYPE ? "" : "Error", wxDefaultPosition, wxDefaultSize); m_dialog->SetExtraStyle(m_dialog->GetExtraStyle() | wxWS_EX_TRANSIENT); m_dialog->SetTransparent(127 + (type & CELL_MSGDIALOG_TYPE_BG) * (128 / CELL_MSGDIALOG_TYPE_BG_INVISIBLE)); m_sizer1 = new wxBoxSizer(wxVERTICAL); - m_text = new wxStaticText(m_dialog, wxID_ANY, wxString(msg.c_str(), wxConvUTF8)); + m_text = new wxStaticText(m_dialog.get(), wxID_ANY, wxString(msg.c_str(), wxConvUTF8)); m_sizer1->Add(m_text, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); switch (type & CELL_MSGDIALOG_TYPE_PROGRESSBAR) { case CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE: - m_gauge2 = new wxGauge(m_dialog, wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH); - m_text2 = new wxStaticText(m_dialog, wxID_ANY, ""); + m_gauge2 = new wxGauge(m_dialog.get(), wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH); + m_text2 = new wxStaticText(m_dialog.get(), wxID_ANY, ""); m_text2->SetAutoLayout(true); // fallthrough case CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE: - m_gauge1 = new wxGauge(m_dialog, wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH); - m_text1 = new wxStaticText(m_dialog, wxID_ANY, ""); + m_gauge1 = new wxGauge(m_dialog.get(), wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH); + m_text1 = new wxStaticText(m_dialog.get(), wxID_ANY, ""); m_text1->SetAutoLayout(true); } @@ -59,9 +59,9 @@ void MsgDialogFrame::Create(u32 type, std::string msg) if (type & CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO) { - m_button_yes = new wxButton(m_dialog, wxID_YES); + m_button_yes = new wxButton(m_dialog.get(), wxID_YES); m_buttons->Add(m_button_yes, 0, wxALIGN_CENTER_HORIZONTAL | wxRIGHT, 8); - m_button_no = new wxButton(m_dialog, wxID_NO); + m_button_no = new wxButton(m_dialog.get(), wxID_NO); m_buttons->Add(m_button_no, 0, wxALIGN_CENTER_HORIZONTAL, 16); if ((type & CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR) == CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_NO) @@ -78,7 +78,7 @@ void MsgDialogFrame::Create(u32 type, std::string msg) if (type & CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK) { - m_button_ok = new wxButton(m_dialog, wxID_OK); + m_button_ok = new wxButton(m_dialog.get(), wxID_OK); m_buttons->Add(m_button_ok, 0, wxALIGN_CENTER_HORIZONTAL, 16); if ((type & CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR) == CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_OK) @@ -119,8 +119,7 @@ void MsgDialogFrame::Create(u32 type, std::string msg) void MsgDialogFrame::Destroy() { - delete m_dialog; - m_dialog = nullptr; + m_dialog.reset(); } void MsgDialogFrame::ProgressBarSetMsg(u32 index, std::string msg) diff --git a/rpcs3/Gui/MsgDialog.h b/rpcs3/Gui/MsgDialog.h index 413e4efe4e..84fcb23799 100644 --- a/rpcs3/Gui/MsgDialog.h +++ b/rpcs3/Gui/MsgDialog.h @@ -4,7 +4,7 @@ class MsgDialogFrame : public MsgDialogInstance { - wxDialog* m_dialog; + std::unique_ptr m_dialog; wxGauge* m_gauge1; wxGauge* m_gauge2; wxStaticText* m_text1;