diff --git a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp index 00167e1034..8d43acefde 100644 --- a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp @@ -10,7 +10,9 @@ LOG_CHANNEL(cellOskDialog); +static CellOskDialogInputFieldResult s_osk_input_result; static char16_t s_osk_text[CELL_OSKDIALOG_STRING_SIZE]; +static char16_t s_osk_text_old[CELL_OSKDIALOG_STRING_SIZE]; s32 cellOskDialogLoadAsync(u32 container, vm::ptr dialogParam, vm::ptr inputFieldInfo) { @@ -18,11 +20,18 @@ s32 cellOskDialogLoadAsync(u32 container, vm::ptr dialogPara u32 maxLength = (inputFieldInfo->limit_length >= 512) ? 511 : (u32)inputFieldInfo->limit_length; + s_osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK; std::memset(s_osk_text, 0, sizeof(s_osk_text)); + std::memset(s_osk_text_old, 0, sizeof(s_osk_text_old)); if (inputFieldInfo->init_text.addr() != 0) + { for (u32 i = 0; (i < maxLength) && (inputFieldInfo->init_text[i] != 0); i++) + { s_osk_text[i] = inputFieldInfo->init_text[i]; + s_osk_text_old[i] = inputFieldInfo->init_text[i]; + } + } const auto osk = fxm::import(Emu.GetCallbacks().get_msg_dialog); @@ -42,7 +51,11 @@ s32 cellOskDialogLoadAsync(u32 container, vm::ptr dialogPara fxm::remove(); } - if (status != CELL_MSGDIALOG_BUTTON_OK) sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED, 0); + if (status != CELL_MSGDIALOG_BUTTON_OK) + { + s_osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_CANCELED; + sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED, 0); + } sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0); pad::SetIntercepted(false); @@ -71,14 +84,37 @@ s32 cellOskDialogLoadAsync(u32 container, vm::ptr dialogPara return CELL_OK; } -s32 cellOskDialogUnloadAsync(vm::ptr OutputInfo) +s32 getText(vm::ptr OutputInfo, bool is_unload) { - cellOskDialog.warning("cellOskDialogUnloadAsync(OutputInfo=*0x%x)", OutputInfo); - OutputInfo->result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK; - - for (int i = 0; i < OutputInfo->numCharsResultString; i++) + if (!OutputInfo || OutputInfo->numCharsResultString < 0) { - OutputInfo->pResultString[i] = s_osk_text[i]; + return CELL_OSKDIALOG_ERROR_PARAM; + } + + if (is_unload) + { + OutputInfo->result = s_osk_input_result; + } + else + { + if (memcmp(s_osk_text_old, s_osk_text, sizeof(s_osk_text)) == 0) + { + OutputInfo->result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_NO_INPUT_TEXT; + } + else + { + OutputInfo->result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK; + } + } + + for (s32 i = 0; i < sizeof(s_osk_text); i++) + { + s_osk_text_old[i] = s_osk_text[i]; + + if (i < OutputInfo->numCharsResultString && (is_unload || OutputInfo->result != CELL_OSKDIALOG_INPUT_FIELD_RESULT_NO_INPUT_TEXT)) + { + OutputInfo->pResultString[i] = s_osk_text[i]; + } } sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_UNLOADED, 0); @@ -86,6 +122,12 @@ s32 cellOskDialogUnloadAsync(vm::ptr OutputInf return CELL_OK; } +s32 cellOskDialogUnloadAsync(vm::ptr OutputInfo) +{ + cellOskDialog.warning("cellOskDialogUnloadAsync(OutputInfo=*0x%x)", OutputInfo); + return getText(OutputInfo, true); +} + s32 cellOskDialogGetSize(vm::ptr width, vm::ptr height, vm::ptr dialogType) { cellOskDialog.warning("cellOskDialogGetSize(width=*0x%x, height=*0x%x, dialogType=*0x%x)", width, height, dialogType); @@ -110,6 +152,8 @@ s32 cellOskDialogAbort() return CELL_SYSUTIL_ERROR_BUSY; } + s_osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_ABORT; + verify(HERE), fxm::remove(); sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0); @@ -167,7 +211,7 @@ s32 cellOskDialogSetLayoutMode(s32 layoutMode) s32 cellOskDialogGetInputText(vm::ptr OutputInfo) { cellOskDialog.warning("cellOskDialogGetInputText(OutputInfo=*0x%x)", OutputInfo); - return cellOskDialogUnloadAsync(OutputInfo); // Same but for use with cellOskDialogSetSeparateWindowOption(). TODO. + return getText(OutputInfo, false); } s32 cellOskDialogExtInputDeviceUnlock()