mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 12:12:50 +01:00
Merge pull request #390 from Nekotekina/master
cellMsgDialog functions improved
This commit is contained in:
commit
072dfc600c
@ -962,20 +962,20 @@ template<typename T, typename AT = u32> class mem_func_beptr_t : public mem_func
|
||||
template<typename RT, typename AT>
|
||||
class mem_func_ptr_t<RT (*)(), AT> : public mem_base_t<u64, AT>
|
||||
{
|
||||
__forceinline void call_func(bool is_async)
|
||||
__forceinline RT call_func(bool is_async) const
|
||||
{
|
||||
Callback cb;
|
||||
cb.SetAddr(this->m_addr);
|
||||
cb.Branch(!is_async);
|
||||
return (RT)cb.Branch(!is_async);
|
||||
}
|
||||
|
||||
public:
|
||||
__forceinline void operator()()
|
||||
__forceinline RT operator()() const
|
||||
{
|
||||
call_func(false);
|
||||
return call_func(false);
|
||||
}
|
||||
|
||||
__forceinline void async()
|
||||
__forceinline void async() const
|
||||
{
|
||||
call_func(true);
|
||||
}
|
||||
@ -984,21 +984,21 @@ public:
|
||||
template<typename AT, typename RT, typename ...T>
|
||||
class mem_func_ptr_t<RT(*)(T...), AT> : public mem_base_t<u64, AT>
|
||||
{
|
||||
__forceinline void call_func(bool is_async, T... args)
|
||||
__forceinline RT call_func(bool is_async, T... args) const
|
||||
{
|
||||
Callback cb;
|
||||
cb.SetAddr(this->m_addr);
|
||||
cb.Handle(_func_arg<T>::get_value(args)...);
|
||||
cb.Branch(!is_async);
|
||||
return (RT)cb.Branch(!is_async);
|
||||
}
|
||||
|
||||
public:
|
||||
__forceinline void operator()(T... args)
|
||||
__forceinline RT operator()(T... args) const
|
||||
{
|
||||
call_func(false, args...);
|
||||
return call_func(false, args...);
|
||||
}
|
||||
|
||||
__forceinline void async(T... args)
|
||||
__forceinline void async(T... args) const
|
||||
{
|
||||
call_func(true, args...);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ void Callback::Handle(u64 _a1, u64 _a2, u64 _a3, u64 _a4)
|
||||
m_has_data = true;
|
||||
}
|
||||
|
||||
void Callback::Branch(bool wait)
|
||||
u64 Callback::Branch(bool wait)
|
||||
{
|
||||
m_has_data = false;
|
||||
|
||||
@ -67,7 +67,7 @@ again:
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
LOG_WARNING(HLE, "Callback::Branch() aborted");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
@ -81,7 +81,7 @@ again:
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
LOG_WARNING(HLE, "Callback::Branch() aborted");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
thr.Stop();
|
||||
@ -102,7 +102,7 @@ again:
|
||||
|
||||
if (!wait)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (thr.IsAlive())
|
||||
@ -110,10 +110,12 @@ again:
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
LOG_WARNING(HLE, "Callback::Branch(true) aborted (end)");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
return thr.GetExitStatus();
|
||||
}
|
||||
|
||||
void Callback::SetName(const std::string& name)
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
|
||||
Callback(u32 slot = 0, u64 addr = 0);
|
||||
void Handle(u64 a1 = 0, u64 a2 = 0, u64 a3 = 0, u64 a4 = 0);
|
||||
void Branch(bool wait);
|
||||
u64 Branch(bool wait);
|
||||
void SetName(const std::string& name);
|
||||
|
||||
operator bool() const;
|
||||
|
445
rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp
Normal file
445
rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp
Normal file
@ -0,0 +1,445 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Log.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
#include "Emu/SysCalls/Modules.h"
|
||||
|
||||
#include "cellSysutil.h"
|
||||
#include "cellMsgDialog.h"
|
||||
|
||||
extern Module *cellSysutil;
|
||||
|
||||
enum MsgDialogState
|
||||
{
|
||||
msgDialogNone,
|
||||
msgDialogOpen,
|
||||
msgDialogClose,
|
||||
msgDialogAbort,
|
||||
};
|
||||
|
||||
std::atomic<MsgDialogState> g_msg_dialog_state(msgDialogNone);
|
||||
wxDialog* g_msg_dialog = nullptr;
|
||||
wxGauge* m_gauge1 = nullptr;
|
||||
wxGauge* m_gauge2 = nullptr;
|
||||
wxStaticText* m_text1 = nullptr;
|
||||
wxStaticText* m_text2 = nullptr;
|
||||
u64 m_wait_until;
|
||||
|
||||
int cellMsgDialogOpen2(u32 type, mem_list_ptr_t<u8> msgString, mem_func_ptr_t<CellMsgDialogCallback> callback, u32 userData, u32 extParam)
|
||||
{
|
||||
cellSysutil->Warning("cellMsgDialogOpen2(type=0x%x, msgString_addr=0x%x, callback_addr=0x%x, userData=0x%x, extParam=0x%x)",
|
||||
type, msgString.GetAddr(), callback.GetAddr(), userData, extParam);
|
||||
|
||||
if (!msgString.IsGood() || !callback.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
//type |= CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE;
|
||||
//type |= CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO;
|
||||
|
||||
MsgDialogState old = msgDialogNone;
|
||||
if (!g_msg_dialog_state.compare_exchange_strong(old, msgDialogOpen))
|
||||
{
|
||||
return CELL_SYSUTIL_ERROR_BUSY;
|
||||
}
|
||||
|
||||
thread t("MsgDialog thread", [=]()
|
||||
{
|
||||
switch (type & CELL_MSGDIALOG_TYPE_SE_TYPE)
|
||||
{
|
||||
case CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL: LOG_WARNING(Log::HLE, "%s", msgString.GetString()); break;
|
||||
case CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR: LOG_ERROR(Log::HLE, "%s", msgString.GetString()); 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;
|
||||
}
|
||||
|
||||
switch (type & CELL_MSGDIALOG_TYPE_BG) // TODO
|
||||
{
|
||||
case CELL_MSGDIALOG_TYPE_BG_INVISIBLE: break;
|
||||
case CELL_MSGDIALOG_TYPE_BG_VISIBLE: break;
|
||||
}
|
||||
|
||||
switch (type & CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR) // TODO
|
||||
{
|
||||
case CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_NO: break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
u64 status = CELL_MSGDIALOG_BUTTON_NONE;
|
||||
|
||||
volatile bool m_signal = false;
|
||||
wxGetApp().CallAfter([&]()
|
||||
{
|
||||
wxWindow* parent = nullptr; // TODO: align it 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;
|
||||
|
||||
g_msg_dialog = new wxDialog(parent, wxID_ANY, type & CELL_MSGDIALOG_TYPE_SE_TYPE ? "" : "Error", wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
g_msg_dialog->SetExtraStyle(g_msg_dialog->GetExtraStyle() | wxWS_EX_TRANSIENT);
|
||||
|
||||
wxSizer* sizer1 = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxStaticText* m_text = new wxStaticText(g_msg_dialog, wxID_ANY, wxString(msgString.GetString(), wxConvUTF8));
|
||||
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(g_msg_dialog, wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH);
|
||||
m_text2 = new wxStaticText(g_msg_dialog, wxID_ANY, "");
|
||||
m_text2->SetAutoLayout(true);
|
||||
|
||||
case CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE:
|
||||
m_gauge1 = new wxGauge(g_msg_dialog, wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH);
|
||||
m_text1 = new wxStaticText(g_msg_dialog, wxID_ANY, "");
|
||||
m_text1->SetAutoLayout(true);
|
||||
|
||||
case CELL_MSGDIALOG_TYPE_PROGRESSBAR_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
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_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_gauge2->SetValue(0);
|
||||
}
|
||||
|
||||
wxBoxSizer* buttons = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
switch (type & CELL_MSGDIALOG_TYPE_BUTTON_TYPE)
|
||||
{
|
||||
case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_NONE:
|
||||
break;
|
||||
|
||||
case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO:
|
||||
m_button_yes = new wxButton(g_msg_dialog, wxID_YES);
|
||||
buttons->Add(m_button_yes, 0, wxALIGN_CENTER_HORIZONTAL | wxRIGHT, 8);
|
||||
m_button_no = new wxButton(g_msg_dialog, wxID_NO);
|
||||
buttons->Add(m_button_no, 0, wxALIGN_CENTER_HORIZONTAL, 16);
|
||||
|
||||
sizer1->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16);
|
||||
break;
|
||||
|
||||
case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK:
|
||||
m_button_ok = new wxButton(g_msg_dialog, wxID_OK);
|
||||
buttons->Add(m_button_ok, 0, wxALIGN_CENTER_HORIZONTAL, 16);
|
||||
|
||||
sizer1->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16);
|
||||
break;
|
||||
}
|
||||
|
||||
sizer1->AddSpacer(16);
|
||||
|
||||
g_msg_dialog->SetSizerAndFit(sizer1);
|
||||
g_msg_dialog->Centre(wxBOTH);
|
||||
g_msg_dialog->Show();
|
||||
g_msg_dialog->Enable();
|
||||
|
||||
g_msg_dialog->Bind(wxEVT_BUTTON, [&](wxCommandEvent& event)
|
||||
{
|
||||
status = (event.GetId() == wxID_NO) ? CELL_MSGDIALOG_BUTTON_NO : CELL_MSGDIALOG_BUTTON_YES /* OK */;
|
||||
g_msg_dialog->Hide();
|
||||
m_wait_until = get_system_time();
|
||||
g_msg_dialog_state = msgDialogClose;
|
||||
});
|
||||
|
||||
|
||||
g_msg_dialog->Bind(wxEVT_CLOSE_WINDOW, [&](wxCloseEvent& event)
|
||||
{
|
||||
if (type & CELL_MSGDIALOG_TYPE_DISABLE_CANCEL)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
status = CELL_MSGDIALOG_BUTTON_ESCAPE;
|
||||
g_msg_dialog->Hide();
|
||||
m_wait_until = get_system_time();
|
||||
g_msg_dialog_state = msgDialogClose;
|
||||
}
|
||||
});
|
||||
|
||||
m_signal = true;
|
||||
});
|
||||
|
||||
while (!m_signal)
|
||||
{
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
while (g_msg_dialog_state == msgDialogOpen || get_system_time() < m_wait_until)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
g_msg_dialog_state = msgDialogAbort;
|
||||
break;
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
if (callback && (g_msg_dialog_state != msgDialogAbort))
|
||||
callback.async(status, userData);
|
||||
|
||||
wxGetApp().CallAfter([&]()
|
||||
{
|
||||
delete g_msg_dialog;
|
||||
g_msg_dialog = nullptr;
|
||||
});
|
||||
|
||||
g_msg_dialog_state = msgDialogNone;
|
||||
});
|
||||
t.detach();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellMsgDialogOpenErrorCode(u32 errorCode, mem_func_ptr_t<CellMsgDialogCallback> callback, mem_ptr_t<void> userData, u32 extParam)
|
||||
{
|
||||
cellSysutil->Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback_addr=0x%x, userData=%d, extParam=%d)",
|
||||
errorCode, callback.GetAddr(), userData, extParam);
|
||||
|
||||
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 bus."; break;
|
||||
case 0x8001000B: errorMessage = "The operation is timed ou."; break;
|
||||
case 0x8001000C: errorMessage = "The operation is aborte."; 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 canceled."; 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;
|
||||
}
|
||||
|
||||
char errorCodeHex[9];
|
||||
sprintf(errorCodeHex, "%08x", errorCode);
|
||||
errorMessage.append("\n(");
|
||||
errorMessage.append(errorCodeHex);
|
||||
errorMessage.append(")\n");
|
||||
|
||||
u64 status;
|
||||
int res = rMessageBox(errorMessage, rGetApp().GetAppName(), rICON_ERROR | rOK);
|
||||
switch (res)
|
||||
{
|
||||
case rOK: status = CELL_MSGDIALOG_BUTTON_OK; break;
|
||||
default:
|
||||
if (res)
|
||||
{
|
||||
status = CELL_MSGDIALOG_BUTTON_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
status = CELL_MSGDIALOG_BUTTON_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (callback)
|
||||
callback(status, userData);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellMsgDialogClose(float delay)
|
||||
{
|
||||
cellSysutil->Warning("cellMsgDialogClose(delay=%f)", delay);
|
||||
|
||||
MsgDialogState old = msgDialogOpen;
|
||||
if (!g_msg_dialog_state.compare_exchange_strong(old, msgDialogClose))
|
||||
{
|
||||
if (old == msgDialogNone)
|
||||
{
|
||||
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CELL_SYSUTIL_ERROR_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
if (delay < 0.0f) delay = 0.0f;
|
||||
m_wait_until = get_system_time() + (u64)(delay * 1000);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellMsgDialogAbort()
|
||||
{
|
||||
cellSysutil->Warning("cellMsgDialogAbort()");
|
||||
|
||||
MsgDialogState old = msgDialogOpen;
|
||||
if (!g_msg_dialog_state.compare_exchange_strong(old, msgDialogAbort))
|
||||
{
|
||||
if (old == msgDialogNone)
|
||||
{
|
||||
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CELL_SYSUTIL_ERROR_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
m_wait_until = get_system_time();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, mem_list_ptr_t<u8> msgString)
|
||||
{
|
||||
if (!msgString.IsGood())
|
||||
{
|
||||
cellSysutil->Error("cellMsgDialogProgressBarSetMsg(progressBarIndex=%d, msgString_addr=0x%x): CELL_EFAULT",
|
||||
progressBarIndex, msgString.GetAddr());
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
cellSysutil->Warning("cellMsgDialogProgressBarSetMsg(progressBarIndex=%d, msgString_addr=0x%x): '%s'",
|
||||
progressBarIndex, msgString.GetAddr(), msgString.GetString());
|
||||
|
||||
if (g_msg_dialog_state != msgDialogOpen)
|
||||
{
|
||||
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (progressBarIndex >= (u32)(bool)m_gauge1 + (u32)(bool)m_gauge2)
|
||||
{
|
||||
return CELL_MSGDIALOG_ERROR_PARAM;
|
||||
}
|
||||
|
||||
std::string text(msgString.GetString());
|
||||
|
||||
wxGetApp().CallAfter([text, progressBarIndex]()
|
||||
{
|
||||
if (g_msg_dialog && !Emu.IsStopped())
|
||||
{
|
||||
if (progressBarIndex == 0 && m_text1) m_text1->SetLabelText(fmt::FromUTF8(text));
|
||||
if (progressBarIndex == 1 && m_text2) m_text2->SetLabelText(fmt::FromUTF8(text));
|
||||
g_msg_dialog->Layout();
|
||||
g_msg_dialog->Fit();
|
||||
}
|
||||
});
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellMsgDialogProgressBarReset(u32 progressBarIndex)
|
||||
{
|
||||
cellSysutil->Warning("cellMsgDialogProgressBarReset(progressBarIndex=%d)", progressBarIndex);
|
||||
|
||||
if (g_msg_dialog_state != msgDialogOpen)
|
||||
{
|
||||
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (progressBarIndex >= (u32)(bool)m_gauge1 + (u32)(bool)m_gauge2)
|
||||
{
|
||||
return CELL_MSGDIALOG_ERROR_PARAM;
|
||||
}
|
||||
|
||||
wxGetApp().CallAfter([=]()
|
||||
{
|
||||
if (g_msg_dialog)
|
||||
{
|
||||
if (progressBarIndex == 0 && m_gauge1) m_gauge1->SetValue(0);
|
||||
if (progressBarIndex == 1 && m_gauge2) m_gauge2->SetValue(0);
|
||||
}
|
||||
});
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta)
|
||||
{
|
||||
cellSysutil->Warning("cellMsgDialogProgressBarInc(progressBarIndex=%d, delta=%d)", progressBarIndex, delta);
|
||||
|
||||
if (g_msg_dialog_state != msgDialogOpen)
|
||||
{
|
||||
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (progressBarIndex >= (u32)(bool)m_gauge1 + (u32)(bool)m_gauge2)
|
||||
{
|
||||
return CELL_MSGDIALOG_ERROR_PARAM;
|
||||
}
|
||||
|
||||
wxGetApp().CallAfter([=]()
|
||||
{
|
||||
if (g_msg_dialog)
|
||||
{
|
||||
if (progressBarIndex == 0 && m_gauge1) m_gauge1->SetValue(m_gauge1->GetValue() + delta);
|
||||
if (progressBarIndex == 1 && m_gauge2) m_gauge2->SetValue(m_gauge2->GetValue() + delta);
|
||||
}
|
||||
});
|
||||
return CELL_OK;
|
||||
}
|
91
rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h
Normal file
91
rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h
Normal file
@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_MSGDIALOG_ERROR_PARAM = 0x8002b301,
|
||||
CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED = 0x8002b302,
|
||||
};
|
||||
|
||||
enum CellMsgDialogType
|
||||
{
|
||||
CELL_MSGDIALOG_DIALOG_TYPE_ERROR = 0x00000000,
|
||||
CELL_MSGDIALOG_DIALOG_TYPE_NORMAL = 0x00000001,
|
||||
CELL_MSGDIALOG_BUTTON_TYPE_NONE = 0x00000000,
|
||||
CELL_MSGDIALOG_BUTTON_TYPE_YESNO = 0x00000010,
|
||||
CELL_MSGDIALOG_DEFAULT_CURSOR_YES = 0x00000000,
|
||||
CELL_MSGDIALOG_DEFAULT_CURSOR_NO = 0x00000100,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_MSGDIALOG_TYPE_SE_TYPE = 1 << 0,
|
||||
CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR = 0 << 0,
|
||||
CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL = 1 << 0,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_MSGDIALOG_TYPE_SE_MUTE = 1 << 1,
|
||||
CELL_MSGDIALOG_TYPE_SE_MUTE_OFF = 0 << 1,
|
||||
CELL_MSGDIALOG_TYPE_SE_MUTE_ON = 1 << 1,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_MSGDIALOG_TYPE_BG = 1 << 2,
|
||||
CELL_MSGDIALOG_TYPE_BG_VISIBLE = 0 << 2,
|
||||
CELL_MSGDIALOG_TYPE_BG_INVISIBLE = 1 << 2,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_MSGDIALOG_TYPE_BUTTON_TYPE = 3 << 4,
|
||||
CELL_MSGDIALOG_TYPE_BUTTON_TYPE_NONE = 0 << 4,
|
||||
CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO = 1 << 4,
|
||||
CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK = 2 << 4,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_MSGDIALOG_TYPE_DISABLE_CANCEL = 1 << 7,
|
||||
CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_OFF = 0 << 7,
|
||||
CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_ON = 1 << 7,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR = 1 << 8,
|
||||
CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_NONE = 0 << 8,
|
||||
CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_YES = 0 << 8,
|
||||
CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_NO = 1 << 8,
|
||||
CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_OK = 0 << 8,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_MSGDIALOG_TYPE_PROGRESSBAR = 3 << 12,
|
||||
CELL_MSGDIALOG_TYPE_PROGRESSBAR_NONE = 0 << 12,
|
||||
CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE = 1 << 12,
|
||||
CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE = 2 << 12,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_MSGDIALOG_BUTTON_NONE = -1,
|
||||
CELL_MSGDIALOG_BUTTON_INVALID = 0,
|
||||
CELL_MSGDIALOG_BUTTON_OK = 1,
|
||||
CELL_MSGDIALOG_BUTTON_YES = 1,
|
||||
CELL_MSGDIALOG_BUTTON_NO = 2,
|
||||
CELL_MSGDIALOG_BUTTON_ESCAPE = 3,
|
||||
};
|
||||
|
||||
typedef void(*CellMsgDialogCallback)(int buttonType, u32 userData);
|
||||
|
||||
int cellMsgDialogOpen2(u32 type, mem_list_ptr_t<u8> msgString, mem_func_ptr_t<CellMsgDialogCallback> callback, u32 userData, u32 extParam);
|
||||
int cellMsgDialogOpenErrorCode(u32 errorCode, mem_func_ptr_t<CellMsgDialogCallback> callback, mem_ptr_t<void> userData, u32 extParam);
|
||||
|
||||
int cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, mem_list_ptr_t<u8> msgString);
|
||||
int cellMsgDialogProgressBarReset(u32 progressBarIndex);
|
||||
int cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta);
|
||||
int cellMsgDialogClose(float delay);
|
||||
int cellMsgDialogAbort();
|
@ -10,11 +10,11 @@
|
||||
|
||||
#include "cellSysutil.h"
|
||||
#include "cellSysutil_SaveData.h"
|
||||
#include "cellMsgDialog.h"
|
||||
#include "cellGame.h"
|
||||
|
||||
#include "Loader/PSF.h"
|
||||
|
||||
typedef void (*CellMsgDialogCallback)(int buttonType, mem_ptr_t<void> userData);
|
||||
typedef void (*CellHddGameStatCallback)(mem_ptr_t<CellHddGameCBResult> cbResult, mem_ptr_t<CellHddGameStatGet> get, mem_ptr_t<CellHddGameStatSet> set);
|
||||
|
||||
|
||||
@ -381,160 +381,6 @@ int cellSysutilUnregisterCallback(int slot)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellMsgDialogOpen2(u32 type, mem_list_ptr_t<u8> msgString, mem_func_ptr_t<CellMsgDialogCallback> callback, mem_ptr_t<void> userData, u32 extParam)
|
||||
{
|
||||
cellSysutil->Warning("cellMsgDialogOpen2(type=0x%x, msgString_addr=0x%x, callback_addr=0x%x, userData=0x%x, extParam=0x%x)",
|
||||
type, msgString.GetAddr(), callback.GetAddr(), userData.GetAddr(), extParam);
|
||||
|
||||
long style = 0;
|
||||
|
||||
if(type & CELL_MSGDIALOG_DIALOG_TYPE_NORMAL)
|
||||
{
|
||||
style |= rICON_EXCLAMATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
style |= rICON_ERROR;
|
||||
}
|
||||
|
||||
if(type & CELL_MSGDIALOG_BUTTON_TYPE_YESNO)
|
||||
{
|
||||
style |= rYES_NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
style |= rOK;
|
||||
}
|
||||
|
||||
int res = rMessageBox(std::string(msgString.GetString()), rGetApp().GetAppName(), style);
|
||||
|
||||
u64 status;
|
||||
|
||||
switch(res)
|
||||
{
|
||||
case rOK: status = CELL_MSGDIALOG_BUTTON_OK; break;
|
||||
case rYES: status = CELL_MSGDIALOG_BUTTON_YES; break;
|
||||
case rNO: status = CELL_MSGDIALOG_BUTTON_NO; break;
|
||||
|
||||
default:
|
||||
if(res)
|
||||
{
|
||||
status = CELL_MSGDIALOG_BUTTON_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
status = CELL_MSGDIALOG_BUTTON_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
if(callback)
|
||||
callback(status, userData);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellMsgDialogOpenErrorCode(u32 errorCode, mem_func_ptr_t<CellMsgDialogCallback> callback, mem_ptr_t<void> userData, u32 extParam)
|
||||
{
|
||||
cellSysutil->Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback_addr=0x%x, userData=%d, extParam=%d)",
|
||||
errorCode, callback.GetAddr(), userData, extParam);
|
||||
|
||||
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 bus."; break;
|
||||
case 0x8001000B: errorMessage = "The operation is timed ou."; break;
|
||||
case 0x8001000C: errorMessage = "The operation is aborte."; 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 canceled."; 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;
|
||||
}
|
||||
|
||||
char errorCodeHex [9];
|
||||
sprintf(errorCodeHex, "%08x", errorCode);
|
||||
errorMessage.append("\n(");
|
||||
errorMessage.append(errorCodeHex);
|
||||
errorMessage.append(")\n");
|
||||
|
||||
u64 status;
|
||||
int res = rMessageBox(errorMessage, rGetApp().GetAppName(), rICON_ERROR | rOK);
|
||||
switch(res)
|
||||
{
|
||||
case rOK: status = CELL_MSGDIALOG_BUTTON_OK; break;
|
||||
default:
|
||||
if(res)
|
||||
{
|
||||
status = CELL_MSGDIALOG_BUTTON_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
status = CELL_MSGDIALOG_BUTTON_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
if(callback)
|
||||
callback(status, userData);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option)
|
||||
{
|
||||
cellSysutil->Warning("cellAudioOutGetSoundAvailability(audioOut=%d, type=%d, fs=0x%x, option=%d)",
|
||||
@ -1023,6 +869,11 @@ void cellSysutil_init()
|
||||
|
||||
cellSysutil->AddFunc(0x7603d3db, cellMsgDialogOpen2);
|
||||
cellSysutil->AddFunc(0x3e22cb4b, cellMsgDialogOpenErrorCode);
|
||||
cellSysutil->AddFunc(0x9d6af72a, cellMsgDialogProgressBarSetMsg);
|
||||
cellSysutil->AddFunc(0x7bc2c8a8, cellMsgDialogProgressBarReset);
|
||||
cellSysutil->AddFunc(0x94862702, cellMsgDialogProgressBarInc);
|
||||
cellSysutil->AddFunc(0x20543730, cellMsgDialogClose);
|
||||
cellSysutil->AddFunc(0x62b0f803, cellMsgDialogAbort);
|
||||
|
||||
cellSysutil->AddFunc(0xf4e3caa0, cellAudioOutGetState);
|
||||
cellSysutil->AddFunc(0x4692ab35, cellAudioOutConfigure);
|
||||
|
@ -1,5 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_SYSUTIL_ERROR_TYPE = 0x8002b101,
|
||||
CELL_SYSUTIL_ERROR_VALUE = 0x8002b102,
|
||||
CELL_SYSUTIL_ERROR_SIZE = 0x8002b103,
|
||||
CELL_SYSUTIL_ERROR_NUM = 0x8002b104,
|
||||
CELL_SYSUTIL_ERROR_BUSY = 0x8002b105,
|
||||
CELL_SYSUTIL_ERROR_STATUS = 0x8002b106,
|
||||
CELL_SYSUTIL_ERROR_MEMORY = 0x8002b107,
|
||||
};
|
||||
|
||||
// Parameter IDs
|
||||
enum
|
||||
{
|
||||
@ -103,17 +114,6 @@ enum
|
||||
CELL_SYSUTIL_PAD_RUMBLE_ON = 1,
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_MSGDIALOG_BUTTON_NONE = -1,
|
||||
CELL_MSGDIALOG_BUTTON_INVALID = 0,
|
||||
CELL_MSGDIALOG_BUTTON_OK = 1,
|
||||
CELL_MSGDIALOG_BUTTON_YES = 1,
|
||||
CELL_MSGDIALOG_BUTTON_NO = 2,
|
||||
CELL_MSGDIALOG_BUTTON_ESCAPE = 3,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_SYSCACHE_RET_OK_CLEARED = 0,
|
||||
@ -129,19 +129,6 @@ enum
|
||||
CELL_SYSCACHE_ERROR_NOTMOUNTED = 0x8002bc04, // We don't really need to simulate the mounting, so this is probably useless
|
||||
};
|
||||
|
||||
enum CellMsgDialogType
|
||||
{
|
||||
CELL_MSGDIALOG_DIALOG_TYPE_ERROR = 0x00000000,
|
||||
CELL_MSGDIALOG_DIALOG_TYPE_NORMAL = 0x00000001,
|
||||
|
||||
CELL_MSGDIALOG_BUTTON_TYPE_NONE = 0x00000000,
|
||||
CELL_MSGDIALOG_BUTTON_TYPE_YESNO = 0x00000010,
|
||||
|
||||
CELL_MSGDIALOG_DEFAULT_CURSOR_YES = 0x00000000,
|
||||
CELL_MSGDIALOG_DEFAULT_CURSOR_NO = 0x00000100,
|
||||
};
|
||||
|
||||
|
||||
// cellSysutil: cellHddGame
|
||||
enum
|
||||
{
|
||||
|
@ -144,6 +144,7 @@
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellL10n.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellLv2dbg.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellMic.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellMsgDialog.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellMusicDecode.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellMusicExport.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellNetCtl.cpp" />
|
||||
@ -342,6 +343,7 @@
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellGame.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellGifDec.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellJpgDec.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellMsgDialog.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellPamf.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellPngDec.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellResc.h" />
|
||||
|
@ -587,6 +587,9 @@
|
||||
<ClCompile Include="..\Utilities\Log.cpp">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellMsgDialog.cpp">
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Crypto\aes.h">
|
||||
@ -1075,5 +1078,8 @@
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellGame.h">
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellMsgDialog.h">
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user