diff --git a/Utilities/rFile.cpp b/Utilities/rFile.cpp index 169c12a4c6..706dae3750 100644 --- a/Utilities/rFile.cpp +++ b/Utilities/rFile.cpp @@ -15,7 +15,7 @@ std::unique_ptr ConvertUTF8ToWChar(const std::string& source) { const size_t length = source.size() + 1; // size + null terminator - const int size = length && length <= INT_MAX ? static_cast(length) : throw std::length_error(__FUNCTION__); + const int size = source.size() < INT_MAX ? static_cast(length) : throw std::length_error(__FUNCTION__); std::unique_ptr buffer(new wchar_t[length]); // allocate buffer assuming that length is the max possible size diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index 9a00011942..0edd41d0c0 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -450,7 +450,7 @@ namespace vm }; // vm::null is convertible to any vm::ptr type as null pointer in virtual memory - static const null_t null; + static null_t null; } namespace fmt diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp index 7b96cefec4..f8c1b9ef0e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp @@ -5,52 +5,32 @@ #include "Emu/SysCalls/Callback.h" #include "Emu/SysCalls/CB_FUNC.h" -#include "Utilities/Log.h" -#include "Utilities/rMsgBox.h" #include "Emu/SysCalls/lv2/sys_time.h" #include "cellSysutil.h" #include "cellMsgDialog.h" extern Module cellSysutil; -enum MsgDialogState +std::unique_ptr g_msg_dialog; + +MsgDialogInstance::MsgDialogInstance() + : state(msgDialogNone) { - msgDialogNone, - msgDialogOpen, - msgDialogClose, - msgDialogAbort, -}; - -std::atomic g_msg_dialog_state(msgDialogNone); -u64 g_msg_dialog_status; -u64 g_msg_dialog_wait_until; -u32 g_msg_dialog_progress_bar_count; - -MsgDialogCreateCb MsgDialogCreate = nullptr; -MsgDialogDestroyCb MsgDialogDestroy = nullptr; -MsgDialogProgressBarSetMsgCb MsgDialogProgressBarSetMsg = nullptr; -MsgDialogProgressBarResetCb MsgDialogProgressBarReset = nullptr; -MsgDialogProgressBarIncCb MsgDialogProgressBarInc = nullptr; - -void SetMsgDialogCallbacks(MsgDialogCreateCb ccb, MsgDialogDestroyCb dcb, MsgDialogProgressBarSetMsgCb pbscb, MsgDialogProgressBarResetCb pbrcb, MsgDialogProgressBarIncCb pbicb) -{ - MsgDialogCreate = ccb; - MsgDialogDestroy = dcb; - MsgDialogProgressBarSetMsg = pbscb; - MsgDialogProgressBarReset = pbrcb; - MsgDialogProgressBarInc = pbicb; } -void MsgDialogClose() +MsgDialogInstance::~MsgDialogInstance() { - g_msg_dialog_state = msgDialogClose; - g_msg_dialog_wait_until = get_system_time(); } -s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr callback, u32 userData, u32 extParam) +void MsgDialogInstance::Close() { - cellSysutil.Warning("cellMsgDialogOpen2(type=0x%x, msgString_addr=0x%x, callback_addr=0x%x, userData=0x%x, extParam=0x%x)", - type, msgString.addr(), callback.addr(), userData, extParam); + state = msgDialogClose; + wait_until = get_system_time(); +} + +s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr callback, vm::ptr userData, vm::ptr extParam) +{ + cellSysutil.Warning("cellMsgDialogOpen2(type=0x%x, msgString=*0x%x, callback=*0x%x, userData=*0x%x, extParam=*0x%x)", type, msgString, callback, userData, extParam); if (!msgString || strlen(msgString.get_ptr()) >= 0x200 || type & -0x33f8) { @@ -107,18 +87,24 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptrstate.compare_exchange_strong(old, msgDialogOpen)) { return CELL_SYSUTIL_ERROR_BUSY; } - g_msg_dialog_wait_until = get_system_time() + 31536000000000ull; // some big value + g_msg_dialog->wait_until = get_system_time() + 31536000000000ull; // some big value switch (type & CELL_MSGDIALOG_TYPE_PROGRESSBAR) { - case CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE: g_msg_dialog_progress_bar_count = 2; break; - case CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE: g_msg_dialog_progress_bar_count = 1; break; - default: g_msg_dialog_progress_bar_count = 0; break; + case CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE: g_msg_dialog->progress_bar_count = 2; break; + case CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE: g_msg_dialog->progress_bar_count = 1; break; + default: g_msg_dialog->progress_bar_count = 0; break; + } + + switch (type & CELL_MSGDIALOG_TYPE_SE_MUTE) // TODO + { + case CELL_MSGDIALOG_TYPE_SE_MUTE_OFF: break; + case CELL_MSGDIALOG_TYPE_SE_MUTE_ON: break; } std::string msg = msgString.get_ptr(); @@ -127,24 +113,18 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptrstatus = CELL_MSGDIALOG_BUTTON_NONE; volatile bool m_signal = false; CallAfter([type, msg, &m_signal]() { if (Emu.IsStopped()) return; - MsgDialogCreate(type, msg.c_str(), g_msg_dialog_status); + g_msg_dialog->Create(type, msg.c_str()); m_signal = true; }); @@ -159,20 +139,21 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptrstate == msgDialogOpen || (s64)(get_system_time() - g_msg_dialog->wait_until) < 0) { if (Emu.IsStopped()) { - g_msg_dialog_state = msgDialogAbort; + g_msg_dialog->state = msgDialogAbort; break; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack } - if (callback && (g_msg_dialog_state != msgDialogAbort)) + if (callback && (g_msg_dialog->state != msgDialogAbort)) { - const s32 status = (s32)g_msg_dialog_status; - Emu.GetCallbackManager().Register([callback, userData, status](PPUThread& PPU) -> s32 + const s32 status = g_msg_dialog->status; + + Emu.GetCallbackManager().Register([=](PPUThread& PPU) -> s32 { callback(PPU, status, userData); return CELL_OK; @@ -181,116 +162,93 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptrDestroy(); + g_msg_dialog->state = msgDialogNone; }); }); return CELL_OK; } -s32 cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr callback, u32 userData, u32 extParam) +s32 cellMsgDialogOpenErrorCode(PPUThread& CPU, u32 errorCode, vm::ptr callback, vm::ptr userData, vm::ptr extParam) { - cellSysutil.Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback_addr=0x%x, userData=0x%x, extParam=%d)", - errorCode, callback.addr(), userData, extParam); + cellSysutil.Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback=*0x%x, userData=*0x%x, extParam=*0x%x)", errorCode, callback, userData, extParam); + + std::string error; - std::string errorMessage; switch (errorCode) { - // Generic errors - case 0x80010001: errorMessage = "The resource is temporarily unavailable."; break; - case 0x80010002: errorMessage = "Invalid argument or flag."; break; - case 0x80010003: errorMessage = "The feature is not yet implemented."; break; - case 0x80010004: errorMessage = "Memory allocation failed."; break; - case 0x80010005: errorMessage = "The resource with the specified identifier does not exist."; break; - case 0x80010006: errorMessage = "The file does not exist."; break; - case 0x80010007: errorMessage = "The file is in unrecognized format / The file is not a valid ELF file."; break; - case 0x80010008: errorMessage = "Resource deadlock is avoided."; break; - case 0x80010009: errorMessage = "Operation not permitted."; break; - case 0x8001000A: errorMessage = "The device or resource is busy."; break; - case 0x8001000B: errorMessage = "The operation is timed out."; break; - case 0x8001000C: errorMessage = "The operation is aborted."; break; - case 0x8001000D: errorMessage = "Invalid memory access."; break; - case 0x8001000F: errorMessage = "State of the target thread is invalid."; break; - case 0x80010010: errorMessage = "Alignment is invalid."; break; - case 0x80010011: errorMessage = "Shortage of the kernel resources."; break; - case 0x80010012: errorMessage = "The file is a directory."; break; - case 0x80010013: errorMessage = "Operation cancelled."; break; - case 0x80010014: errorMessage = "Entry already exists."; break; - case 0x80010015: errorMessage = "Port is already connected."; break; - case 0x80010016: errorMessage = "Port is not connected."; break; - case 0x80010017: errorMessage = "Failure in authorizing SELF. Program authentication fail."; break; - case 0x80010018: errorMessage = "The file is not MSELF."; break; - case 0x80010019: errorMessage = "System version error."; break; - case 0x8001001A: errorMessage = "Fatal system error occurred while authorizing SELF. SELF auth failure."; break; - case 0x8001001B: errorMessage = "Math domain violation."; break; - case 0x8001001C: errorMessage = "Math range violation."; break; - case 0x8001001D: errorMessage = "Illegal multi-byte sequence in input."; break; - case 0x8001001E: errorMessage = "File position error."; break; - case 0x8001001F: errorMessage = "Syscall was interrupted."; break; - case 0x80010020: errorMessage = "File too large."; break; - case 0x80010021: errorMessage = "Too many links."; break; - case 0x80010022: errorMessage = "File table overflow."; break; - case 0x80010023: errorMessage = "No space left on device."; break; - case 0x80010024: errorMessage = "Not a TTY."; break; - case 0x80010025: errorMessage = "Broken pipe."; break; - case 0x80010026: errorMessage = "Read-only filesystem."; break; - case 0x80010027: errorMessage = "Illegal seek."; break; - case 0x80010028: errorMessage = "Arg list too long."; break; - case 0x80010029: errorMessage = "Access violation."; break; - case 0x8001002A: errorMessage = "Invalid file descriptor."; break; - case 0x8001002B: errorMessage = "Filesystem mounting failed."; break; - case 0x8001002C: errorMessage = "Too many files open."; break; - case 0x8001002D: errorMessage = "No device."; break; - case 0x8001002E: errorMessage = "Not a directory."; break; - case 0x8001002F: errorMessage = "No such device or IO."; break; - case 0x80010030: errorMessage = "Cross-device link error."; break; - case 0x80010031: errorMessage = "Bad Message."; break; - case 0x80010032: errorMessage = "In progress."; break; - case 0x80010033: errorMessage = "Message size error."; break; - case 0x80010034: errorMessage = "Name too long."; break; - case 0x80010035: errorMessage = "No lock."; break; - case 0x80010036: errorMessage = "Not empty."; break; - case 0x80010037: errorMessage = "Not supported."; break; - case 0x80010038: errorMessage = "File-system specific error."; break; - case 0x80010039: errorMessage = "Overflow occured."; break; - case 0x8001003A: errorMessage = "Filesystem not mounted."; break; - case 0x8001003B: errorMessage = "Not SData."; break; - case 0x8001003C: errorMessage = "Incorrect version in sys_load_param."; break; - case 0x8001003D: errorMessage = "Pointer is null."; break; - case 0x8001003E: errorMessage = "Pointer is null."; break; - default: errorMessage = "An error has occurred."; break; + case 0x80010001: error = "The resource is temporarily unavailable."; break; + case 0x80010002: error = "Invalid argument or flag."; break; + case 0x80010003: error = "The feature is not yet implemented."; break; + case 0x80010004: error = "Memory allocation failed."; break; + case 0x80010005: error = "The resource with the specified identifier does not exist."; break; + case 0x80010006: error = "The file does not exist."; break; + case 0x80010007: error = "The file is in unrecognized format / The file is not a valid ELF file."; break; + case 0x80010008: error = "Resource deadlock is avoided."; break; + case 0x80010009: error = "Operation not permitted."; break; + case 0x8001000A: error = "The device or resource is busy."; break; + case 0x8001000B: error = "The operation is timed out."; break; + case 0x8001000C: error = "The operation is aborted."; break; + case 0x8001000D: error = "Invalid memory access."; break; + case 0x8001000F: error = "State of the target thread is invalid."; break; + case 0x80010010: error = "Alignment is invalid."; break; + case 0x80010011: error = "Shortage of the kernel resources."; break; + case 0x80010012: error = "The file is a directory."; break; + case 0x80010013: error = "Operation cancelled."; break; + case 0x80010014: error = "Entry already exists."; break; + case 0x80010015: error = "Port is already connected."; break; + case 0x80010016: error = "Port is not connected."; break; + case 0x80010017: error = "Failure in authorizing SELF. Program authentication fail."; break; + case 0x80010018: error = "The file is not MSELF."; break; + case 0x80010019: error = "System version error."; break; + case 0x8001001A: error = "Fatal system error occurred while authorizing SELF. SELF auth failure."; break; + case 0x8001001B: error = "Math domain violation."; break; + case 0x8001001C: error = "Math range violation."; break; + case 0x8001001D: error = "Illegal multi-byte sequence in input."; break; + case 0x8001001E: error = "File position error."; break; + case 0x8001001F: error = "Syscall was interrupted."; break; + case 0x80010020: error = "File too large."; break; + case 0x80010021: error = "Too many links."; break; + case 0x80010022: error = "File table overflow."; break; + case 0x80010023: error = "No space left on device."; break; + case 0x80010024: error = "Not a TTY."; break; + case 0x80010025: error = "Broken pipe."; break; + case 0x80010026: error = "Read-only filesystem."; break; + case 0x80010027: error = "Illegal seek."; break; + case 0x80010028: error = "Arg list too long."; break; + case 0x80010029: error = "Access violation."; break; + case 0x8001002A: error = "Invalid file descriptor."; break; + case 0x8001002B: error = "Filesystem mounting failed."; break; + case 0x8001002C: error = "Too many files open."; break; + case 0x8001002D: error = "No device."; break; + case 0x8001002E: error = "Not a directory."; break; + case 0x8001002F: error = "No such device or IO."; break; + case 0x80010030: error = "Cross-device link error."; break; + case 0x80010031: error = "Bad Message."; break; + case 0x80010032: error = "In progress."; break; + case 0x80010033: error = "Message size error."; break; + case 0x80010034: error = "Name too long."; break; + case 0x80010035: error = "No lock."; break; + case 0x80010036: error = "Not empty."; break; + case 0x80010037: error = "Not supported."; break; + case 0x80010038: error = "File-system specific error."; break; + case 0x80010039: error = "Overflow occured."; break; + case 0x8001003A: error = "Filesystem not mounted."; break; + case 0x8001003B: error = "Not SData."; break; + case 0x8001003C: error = "Incorrect version in sys_load_param."; break; + case 0x8001003D: error = "Pointer is null."; break; + case 0x8001003E: error = "Pointer is null."; break; + default: error = "An error has occurred."; break; } - char errorCodeHex[12]; -#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE - sprintf_s(errorCodeHex, "\n(%08x)", errorCode); -#else - sprintf(errorCodeHex, "\n(%08x)", errorCode); -#endif - errorMessage.append(errorCodeHex); + error.append(fmt::format("\n(%08x)", errorCode)); - u64 status; - int res = rMessageBox(errorMessage, "Error", rICON_ERROR | rOK); - switch (res) - { - case rOK: status = CELL_MSGDIALOG_BUTTON_OK; break; - default: - if (res) - { - status = CELL_MSGDIALOG_BUTTON_INVALID; - break; - } + vm::stackvar message(CPU, error.size() + 1); - status = CELL_MSGDIALOG_BUTTON_NONE; - break; - } + memcpy(message.get_ptr(), error.c_str(), message.size()); - if (callback) - callback((s32)status, userData); - - return CELL_OK; + return cellMsgDialogOpen2(CELL_MSGDIALOG_DIALOG_TYPE_ERROR | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK, message, callback, userData, extParam); } s32 cellMsgDialogClose(float delay) @@ -298,7 +256,8 @@ s32 cellMsgDialogClose(float delay) cellSysutil.Warning("cellMsgDialogClose(delay=%f)", delay); MsgDialogState old = msgDialogOpen; - if (!g_msg_dialog_state.compare_exchange_strong(old, msgDialogClose)) + + if (!g_msg_dialog->state.compare_exchange_strong(old, msgDialogClose)) { if (old == msgDialogNone) { @@ -310,8 +269,7 @@ s32 cellMsgDialogClose(float delay) } } - if (delay < 0.0f) delay = 0.0f; - g_msg_dialog_wait_until = get_system_time() + (u64)(delay * 1000); + g_msg_dialog->wait_until = get_system_time() + static_cast(std::max(delay, 0.0f) * 1000); return CELL_OK; } @@ -320,7 +278,8 @@ s32 cellMsgDialogAbort() cellSysutil.Warning("cellMsgDialogAbort()"); MsgDialogState old = msgDialogOpen; - if (!g_msg_dialog_state.compare_exchange_strong(old, msgDialogAbort)) + + if (!g_msg_dialog->state.compare_exchange_strong(old, msgDialogAbort)) { if (old == msgDialogNone) { @@ -332,21 +291,21 @@ s32 cellMsgDialogAbort() } } - g_msg_dialog_wait_until = get_system_time(); + g_msg_dialog->wait_until = get_system_time(); + return CELL_OK; } s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr msgString) { - cellSysutil.Warning("cellMsgDialogProgressBarSetMsg(progressBarIndex=%d, msgString_addr=0x%x ['%s'])", - progressBarIndex, msgString.addr(), msgString.get_ptr()); + cellSysutil.Warning("cellMsgDialogProgressBarSetMsg(progressBarIndex=%d, msgString=*0x%x)", progressBarIndex, msgString); - if (g_msg_dialog_state != msgDialogOpen) + if (g_msg_dialog->state != msgDialogOpen) { return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED; } - if (progressBarIndex >= g_msg_dialog_progress_bar_count) + if (progressBarIndex >= g_msg_dialog->progress_bar_count) { return CELL_MSGDIALOG_ERROR_PARAM; } @@ -355,8 +314,9 @@ s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr msg CallAfter([text, progressBarIndex]() { - MsgDialogProgressBarSetMsg(progressBarIndex, text.c_str()); + g_msg_dialog->ProgressBarSetMsg(progressBarIndex, text.c_str()); }); + return CELL_OK; } @@ -364,20 +324,21 @@ s32 cellMsgDialogProgressBarReset(u32 progressBarIndex) { cellSysutil.Warning("cellMsgDialogProgressBarReset(progressBarIndex=%d)", progressBarIndex); - if (g_msg_dialog_state != msgDialogOpen) + if (g_msg_dialog->state != msgDialogOpen) { return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED; } - if (progressBarIndex >= g_msg_dialog_progress_bar_count) + if (progressBarIndex >= g_msg_dialog->progress_bar_count) { return CELL_MSGDIALOG_ERROR_PARAM; } CallAfter([=]() { - MsgDialogProgressBarReset(progressBarIndex); + g_msg_dialog->ProgressBarReset(progressBarIndex); }); + return CELL_OK; } @@ -385,19 +346,31 @@ s32 cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta) { cellSysutil.Warning("cellMsgDialogProgressBarInc(progressBarIndex=%d, delta=%d)", progressBarIndex, delta); - if (g_msg_dialog_state != msgDialogOpen) + if (g_msg_dialog->state != msgDialogOpen) { return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED; } - if (progressBarIndex >= g_msg_dialog_progress_bar_count) + if (progressBarIndex >= g_msg_dialog->progress_bar_count) { return CELL_MSGDIALOG_ERROR_PARAM; } CallAfter([=]() { - MsgDialogProgressBarInc(progressBarIndex, delta); + g_msg_dialog->ProgressBarInc(progressBarIndex, delta); }); + return CELL_OK; } + +void cellSysutil_MsgDialog_init() +{ + REG_FUNC(cellSysutil, cellMsgDialogOpen2); + REG_FUNC(cellSysutil, cellMsgDialogOpenErrorCode); + REG_FUNC(cellSysutil, cellMsgDialogProgressBarSetMsg); + REG_FUNC(cellSysutil, cellMsgDialogProgressBarReset); + REG_FUNC(cellSysutil, cellMsgDialogProgressBarInc); + REG_FUNC(cellSysutil, cellMsgDialogClose); + REG_FUNC(cellSysutil, cellMsgDialogAbort); +} diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h index 3ce4d78e0b..6b2a3e1527 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h @@ -6,7 +6,7 @@ enum CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED = 0x8002b302, }; -enum CellMsgDialogType +enum CellMsgDialogType : u32 { CELL_MSGDIALOG_DIALOG_TYPE_ERROR = 0x00000000, CELL_MSGDIALOG_DIALOG_TYPE_NORMAL = 0x00000001, @@ -16,28 +16,28 @@ enum CellMsgDialogType CELL_MSGDIALOG_DEFAULT_CURSOR_NO = 0x00000100, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_SE_TYPE = 0x1, CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR = 0 << 0, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL = 1 << 0, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_SE_MUTE = 0x2, CELL_MSGDIALOG_TYPE_SE_MUTE_OFF = 0 << 1, CELL_MSGDIALOG_TYPE_SE_MUTE_ON = 1 << 1, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_BG = 0x4, CELL_MSGDIALOG_TYPE_BG_VISIBLE = 0 << 2, CELL_MSGDIALOG_TYPE_BG_INVISIBLE = 1 << 2, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_BUTTON_TYPE = 0x70, CELL_MSGDIALOG_TYPE_BUTTON_TYPE_NONE = 0 << 4, @@ -45,14 +45,14 @@ enum CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK = 2 << 4, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_DISABLE_CANCEL = 0x80, CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_OFF = 0 << 7, CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_ON = 1 << 7, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR = 0x300, CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_NONE = 0 << 8, @@ -61,7 +61,7 @@ enum CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_OK = 0 << 8, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_PROGRESSBAR = 0x3000, CELL_MSGDIALOG_TYPE_PROGRESSBAR_NONE = 0 << 12, @@ -69,7 +69,8 @@ enum CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE = 2 << 12, }; -enum +// MsgDialog Button Type +enum : s32 { CELL_MSGDIALOG_BUTTON_NONE = -1, CELL_MSGDIALOG_BUTTON_INVALID = 0, @@ -79,22 +80,32 @@ enum CELL_MSGDIALOG_BUTTON_ESCAPE = 3, }; -typedef void(CellMsgDialogCallback)(s32 buttonType, u32 userData); +typedef void(CellMsgDialogCallback)(s32 buttonType, vm::ptr userData); -s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr callback, u32 userData, u32 extParam); -s32 cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr callback, u32 userData, u32 extParam); +enum MsgDialogState +{ + msgDialogNone, + msgDialogOpen, + msgDialogClose, + msgDialogAbort, +}; -s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr msgString); -s32 cellMsgDialogProgressBarReset(u32 progressBarIndex); -s32 cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta); -s32 cellMsgDialogClose(float delay); -s32 cellMsgDialogAbort(); +struct MsgDialogInstance +{ + std::atomic state; -typedef void(*MsgDialogCreateCb)(u32 type, const char* msg, u64& status); -typedef void(*MsgDialogDestroyCb)(); -typedef void(*MsgDialogProgressBarSetMsgCb)(u32 progressBarIndex, const char* msg); -typedef void(*MsgDialogProgressBarResetCb)(u32 progressBarIndex); -typedef void(*MsgDialogProgressBarIncCb)(u32 progressBarIndex, u32 delta); + s32 status = 0; + u64 wait_until = 0; + u32 progress_bar_count = 0; -void SetMsgDialogCallbacks(MsgDialogCreateCb ccb, MsgDialogDestroyCb dcb, MsgDialogProgressBarSetMsgCb pbscb, MsgDialogProgressBarResetCb pbrcb, MsgDialogProgressBarIncCb pbicb); -void MsgDialogClose(); + MsgDialogInstance(); + virtual ~MsgDialogInstance(); + + virtual void Close(); + + virtual void Create(u32 type, const char* msg) = 0; + virtual void Destroy() = 0; + virtual void ProgressBarSetMsg(u32 progressBarIndex, const char* msg) = 0; + virtual void ProgressBarReset(u32 progressBarIndex) = 0; + virtual void ProgressBarInc(u32 progressBarIndex, u32 delta) = 0; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index ca4b7bb6cd..74c23480c6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -764,6 +764,7 @@ int cellWebBrowserEstimate2(const vm::ptr config, v extern void cellSysutil_SaveData_init(); extern void cellSysutil_GameData_init(); +extern void cellSysutil_MsgDialog_init(); Module cellSysutil("cellSysutil", []() { @@ -775,6 +776,7 @@ Module cellSysutil("cellSysutil", []() cellSysutil_SaveData_init(); // cellSaveData functions cellSysutil_GameData_init(); // cellGameData, cellHddGame functions + cellSysutil_MsgDialog_init(); // cellMsgDialog functions REG_FUNC(cellSysutil, cellSysutilGetSystemParamInt); REG_FUNC(cellSysutil, cellSysutilGetSystemParamString); @@ -791,14 +793,6 @@ Module cellSysutil("cellSysutil", []() REG_FUNC(cellSysutil, cellSysutilRegisterCallback); REG_FUNC(cellSysutil, cellSysutilUnregisterCallback); - REG_FUNC(cellSysutil, cellMsgDialogOpen2); - REG_FUNC(cellSysutil, cellMsgDialogOpenErrorCode); - REG_FUNC(cellSysutil, cellMsgDialogProgressBarSetMsg); - REG_FUNC(cellSysutil, cellMsgDialogProgressBarReset); - REG_FUNC(cellSysutil, cellMsgDialogProgressBarInc); - REG_FUNC(cellSysutil, cellMsgDialogClose); - REG_FUNC(cellSysutil, cellMsgDialogAbort); - REG_FUNC(cellSysutil, cellAudioOutGetState); REG_FUNC(cellSysutil, cellAudioOutConfigure); REG_FUNC(cellSysutil, cellAudioOutGetSoundAvailability); diff --git a/rpcs3/Gui/MsgDialog.cpp b/rpcs3/Gui/MsgDialog.cpp index e45519f40d..c9d6c3bf05 100644 --- a/rpcs3/Gui/MsgDialog.cpp +++ b/rpcs3/Gui/MsgDialog.cpp @@ -2,36 +2,29 @@ #include "Emu/Memory/Memory.h" #include "Emu/SysCalls/lv2/sys_time.h" -#include "Emu/SysCalls/Modules/cellMsgDialog.h" #include "MsgDialog.h" -wxDialog* m_dialog = nullptr; -wxGauge* m_gauge1 = nullptr; -wxGauge* m_gauge2 = nullptr; -wxStaticText* m_text1 = nullptr; -wxStaticText* m_text2 = nullptr; - -void MsgDialogCreate(u32 type, const char* msg, u64& status) +void MsgDialogFrame::Create(u32 type, const char* msg) { - wxWindow* parent = nullptr; // TODO: align it better + wxWindow* parent = nullptr; // TODO: align the window better m_gauge1 = nullptr; m_gauge2 = nullptr; m_text1 = nullptr; m_text2 = nullptr; - wxButton* m_button_ok = nullptr; - wxButton* m_button_yes = nullptr; - wxButton* m_button_no = nullptr; + m_button_ok = nullptr; + 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->SetExtraStyle(m_dialog->GetExtraStyle() | wxWS_EX_TRANSIENT); m_dialog->SetTransparent(127 + (type & CELL_MSGDIALOG_TYPE_BG) * (128 / CELL_MSGDIALOG_TYPE_BG_INVISIBLE)); - wxSizer* sizer1 = new wxBoxSizer(wxVERTICAL); + m_sizer1 = new wxBoxSizer(wxVERTICAL); - wxStaticText* m_text = new wxStaticText(m_dialog, wxID_ANY, wxString(msg, wxConvUTF8)); - sizer1->Add(m_text, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); + m_text = new wxStaticText(m_dialog, wxID_ANY, wxString(msg, wxConvUTF8)); + m_sizer1->Add(m_text, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); switch (type & CELL_MSGDIALOG_TYPE_PROGRESSBAR) { @@ -49,14 +42,14 @@ void MsgDialogCreate(u32 type, const char* msg, u64& status) if (m_gauge1) { - sizer1->Add(m_text1, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 8); - sizer1->Add(m_gauge1, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, 16); + m_sizer1->Add(m_text1, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 8); + m_sizer1->Add(m_gauge1, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, 16); m_gauge1->SetValue(0); } if (m_gauge2) { - sizer1->Add(m_text2, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 8); - sizer1->Add(m_gauge2, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, 16); + m_sizer1->Add(m_text2, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 8); + m_sizer1->Add(m_gauge2, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, 16); m_gauge2->SetValue(0); } @@ -78,7 +71,7 @@ void MsgDialogCreate(u32 type, const char* msg, u64& status) m_button_yes->SetFocus(); } - sizer1->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); + m_sizer1->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); break; case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK: @@ -89,22 +82,22 @@ void MsgDialogCreate(u32 type, const char* msg, u64& status) m_button_ok->SetFocus(); } - sizer1->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); + m_sizer1->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); break; } - sizer1->AddSpacer(16); + m_sizer1->AddSpacer(16); - m_dialog->SetSizerAndFit(sizer1); + m_dialog->SetSizerAndFit(m_sizer1); m_dialog->Centre(wxBOTH); m_dialog->Show(); m_dialog->Enable(); m_dialog->Bind(wxEVT_BUTTON, [&](wxCommandEvent& event) { - status = (event.GetId() == wxID_NO) ? CELL_MSGDIALOG_BUTTON_NO : CELL_MSGDIALOG_BUTTON_YES /* OK */; - m_dialog->Hide(); - MsgDialogClose(); + this->status = (event.GetId() == wxID_NO) ? CELL_MSGDIALOG_BUTTON_NO : CELL_MSGDIALOG_BUTTON_YES /* OK */; + this->m_dialog->Hide(); + this->Close(); }); @@ -115,20 +108,20 @@ void MsgDialogCreate(u32 type, const char* msg, u64& status) } else { - status = CELL_MSGDIALOG_BUTTON_ESCAPE; - m_dialog->Hide(); - MsgDialogClose(); + this->status = CELL_MSGDIALOG_BUTTON_ESCAPE; + this->m_dialog->Hide(); + this->Close(); } }); } -void MsgDialogDestroy() +void MsgDialogFrame::Destroy() { delete m_dialog; m_dialog = nullptr; } -void MsgDialogProgressBarSetMsg(u32 index, const char* msg) +void MsgDialogFrame::ProgressBarSetMsg(u32 index, const char* msg) { if (m_dialog) { @@ -139,7 +132,7 @@ void MsgDialogProgressBarSetMsg(u32 index, const char* msg) } } -void MsgDialogProgressBarReset(u32 index) +void MsgDialogFrame::ProgressBarReset(u32 index) { if (m_dialog) { @@ -148,7 +141,7 @@ void MsgDialogProgressBarReset(u32 index) } } -void MsgDialogProgressBarInc(u32 index, u32 delta) +void MsgDialogFrame::ProgressBarInc(u32 index, u32 delta) { if (m_dialog) { diff --git a/rpcs3/Gui/MsgDialog.h b/rpcs3/Gui/MsgDialog.h index 2f669b9736..bcb282ad95 100644 --- a/rpcs3/Gui/MsgDialog.h +++ b/rpcs3/Gui/MsgDialog.h @@ -1,7 +1,24 @@ #pragma once -void MsgDialogCreate(u32 type, const char* msg, u64& status); -void MsgDialogDestroy(); -void MsgDialogProgressBarSetMsg(u32 index, const char* msg); -void MsgDialogProgressBarReset(u32 index); -void MsgDialogProgressBarInc(u32 index, u32 delta); +#include "Emu/SysCalls/Modules/cellMsgDialog.h" + +class MsgDialogFrame : public MsgDialogInstance +{ + wxDialog* m_dialog; + wxGauge* m_gauge1; + wxGauge* m_gauge2; + wxStaticText* m_text1; + wxStaticText* m_text2; + wxButton* m_button_ok; + wxButton* m_button_yes; + wxButton* m_button_no; + wxStaticText* m_text; + wxSizer* m_sizer1; + +public: + virtual void Create(u32 type, const char* msg) override; + virtual void Destroy() override; + virtual void ProgressBarSetMsg(u32 progressBarIndex, const char* msg) override; + virtual void ProgressBarReset(u32 progressBarIndex) override; + virtual void ProgressBarInc(u32 progressBarIndex, u32 delta) override; +}; diff --git a/rpcs3/rpcs3.cpp b/rpcs3/rpcs3.cpp index c13b8465e1..c457b915f1 100644 --- a/rpcs3/rpcs3.cpp +++ b/rpcs3/rpcs3.cpp @@ -43,6 +43,8 @@ Rpcs3App* TheApp; std::string simplify_path(const std::string& path, bool is_dir); +extern std::unique_ptr g_msg_dialog; + bool Rpcs3App::OnInit() { static const wxCmdLineEntryDesc desc[] @@ -134,7 +136,7 @@ bool Rpcs3App::OnInit() return new GLGSFrame(); }); - SetMsgDialogCallbacks(MsgDialogCreate, MsgDialogDestroy, MsgDialogProgressBarSetMsg, MsgDialogProgressBarReset, MsgDialogProgressBarInc); + g_msg_dialog.reset(new MsgDialogFrame); TheApp = this; SetAppName(_PRGNAME_);