From aa357b9ae8e73b40793dbbd8f5a68d6b871bb432 Mon Sep 17 00:00:00 2001 From: al0xf Date: Mon, 23 Jan 2017 18:14:12 +0100 Subject: [PATCH] Add OSK GUI (#2275) * Initial commit of OSK GUI Also handles character encoding, you can for instance input in Chinese. * Fixes for osk gui --- rpcs3/Emu/Cell/Modules/cellMsgDialog.h | 1 + rpcs3/Emu/Cell/Modules/cellOskDialog.cpp | 43 ++++++++++++++++++-- rpcs3/Emu/Cell/Modules/cellOskDialog.h | 6 +++ rpcs3/Gui/MsgDialog.h | 4 ++ rpcs3/Gui/OskDialog.cpp | 51 ++++++++++++++++++++++++ 5 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 rpcs3/Gui/OskDialog.cpp diff --git a/rpcs3/Emu/Cell/Modules/cellMsgDialog.h b/rpcs3/Emu/Cell/Modules/cellMsgDialog.h index 3ddfc52e0a..81d3f3e363 100644 --- a/rpcs3/Emu/Cell/Modules/cellMsgDialog.h +++ b/rpcs3/Emu/Cell/Modules/cellMsgDialog.h @@ -82,6 +82,7 @@ public: virtual ~MsgDialogBase() = default; virtual void Create(const std::string& msg) = 0; + virtual void CreateOsk(const std::string& msg, char16_t* osk_text) = 0; virtual void ProgressBarSetMsg(u32 progressBarIndex, const std::string& msg) = 0; virtual void ProgressBarReset(u32 progressBarIndex) = 0; virtual void ProgressBarInc(u32 progressBarIndex, u32 delta) = 0; diff --git a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp index 1105cf9a41..960bdf149b 100644 --- a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp @@ -2,13 +2,46 @@ #include "Emu/Cell/PPUModule.h" #include "cellSysutil.h" #include "cellOskDialog.h" +#include "cellMsgDialog.h" +#include +#include "Emu/System.h" logs::channel cellOskDialog("cellOskDialog", logs::level::notice); +char16_t* osk_text; + s32 cellOskDialogLoadAsync(u32 container, vm::ptr dialogParam, vm::ptr inputFieldInfo) { cellOskDialog.warning("cellOskDialogLoadAsync(container=0x%x, dialogParam=*0x%x, inputFieldInfo=*0x%x)", container, dialogParam, inputFieldInfo); - sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0); //Immediately signal that input is finished. TODO: Get actual input. + + osk_text = new char16_t[CELL_OSKDIALOG_STRING_SIZE]; + std::memset(osk_text, 0, sizeof(osk_text)); + + const auto osk = Emu.GetCallbacks().get_msg_dialog(); + bool result = false; + + osk->on_close = [&](s32 status) + { + if (status == 1) { + sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0); + } + else { + sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED, 0); + } + result = true; + }; + + Emu.CallAfter([&]() + { + osk->CreateOsk("On Screen Keyboard", osk_text); + }); + + while (!result) + { + CHECK_EMU_STATUS; + std::this_thread::sleep_for(1ms); + } + return CELL_OSKDIALOG_OK; } @@ -17,8 +50,9 @@ s32 cellOskDialogUnloadAsync(vm::ptr OutputInf cellOskDialog.warning("cellOskDialogUnloadAsync(OutputInfo=*0x%x)", OutputInfo); OutputInfo->result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK; - be_t input[6] = { 'r', 'p', 'c', 's', '3', 0x0 }; //TODO: Get actual input instead. - std::memcpy(OutputInfo->pResultString.get_ptr(), input, sizeof(input)); + for (int i = 0; i < OutputInfo->numCharsResultString; i++) { + *(OutputInfo->pResultString + i) = (be_t)*(osk_text + i); + } return CELL_OSKDIALOG_OK; } @@ -33,7 +67,8 @@ s32 cellOskDialogGetSize(vm::ptr width, vm::ptr height, vm::ptr message; @@ -151,3 +156,4 @@ struct CellOskDialogImeDictionaryInfo be_t targetLanguage; vm::bcptr dictionaryPath; }; + diff --git a/rpcs3/Gui/MsgDialog.h b/rpcs3/Gui/MsgDialog.h index 94b4579a23..e593d5e4fd 100644 --- a/rpcs3/Gui/MsgDialog.h +++ b/rpcs3/Gui/MsgDialog.h @@ -15,10 +15,14 @@ class MsgDialogFrame : public MsgDialogBase wxStaticText* m_text; wxSizer* m_sizer1; wxSizer* m_buttons; + wxButton* osk_button_ok; + wxTextCtrl* osk_text_input; + char16_t* osk_text_return; public: virtual ~MsgDialogFrame() override; virtual void Create(const std::string& msg) override; + virtual void CreateOsk(const std::string& msg, char16_t* osk_text); virtual void ProgressBarSetMsg(u32 progressBarIndex, const std::string& msg) override; virtual void ProgressBarReset(u32 progressBarIndex) override; virtual void ProgressBarInc(u32 progressBarIndex, u32 delta) override; diff --git a/rpcs3/Gui/OskDialog.cpp b/rpcs3/Gui/OskDialog.cpp new file mode 100644 index 0000000000..f3149ed436 --- /dev/null +++ b/rpcs3/Gui/OskDialog.cpp @@ -0,0 +1,51 @@ +#include "stdafx.h" +#include "stdafx_gui.h" +#include "rpcs3.h" +#include "Emu/System.h" +#include "Emu/Memory/Memory.h" +#include "wx/ustring.h" +#include "Emu/Cell/lv2/sys_time.h" +#include "MsgDialog.h" + +void MsgDialogFrame::CreateOsk(const std::string& msg, char16_t* osk_text) +{ + if (m_dialog) m_dialog->Destroy(); + osk_button_ok = nullptr; + osk_text_input = nullptr; + osk_text_return = osk_text; + + m_dialog = new wxDialog(nullptr, wxID_ANY, msg, wxDefaultPosition, wxDefaultSize); + wxSizer* osk_dialog_sizer = new wxBoxSizer(wxVERTICAL); + wxSizer* osk_text_sizer = new wxBoxSizer(wxHORIZONTAL); + wxSizer* osk_button_sizer = new wxBoxSizer(wxHORIZONTAL); + + osk_text_input = new wxTextCtrl(m_dialog, wxID_OK, wxEmptyString, wxDefaultPosition, wxSize(200, -1)); + osk_text_sizer->Add(osk_text_input, 0, wxALL, 4); + if (type.default_cursor == 0) + { + osk_text_input->SetFocus(); + } + + osk_button_ok = new wxButton(m_dialog, wxID_OK); + osk_button_sizer->Add(osk_button_ok, 0, wxLEFT | wxRIGHT | wxBOTTOM, 4); + + osk_dialog_sizer->Add(osk_text_sizer, 0, wxCENTER); + osk_dialog_sizer->Add(osk_button_sizer, 0, wxCENTER); + + m_dialog->SetSizerAndFit(osk_dialog_sizer); + m_dialog->Centre(wxBOTH); + m_dialog->Show(); + m_dialog->Enable(); + + m_dialog->Bind(wxEVT_BUTTON, [&](wxCommandEvent& event) + { + wxUString wx_osk_string = osk_text_input->GetValue(); + std::memcpy(osk_text_return, wx_osk_string.utf16_str(), sizeof(wx_osk_string)); + on_close(CELL_MSGDIALOG_BUTTON_OK); + }); + + m_dialog->Bind(wxEVT_CLOSE_WINDOW, [on_close = on_close](wxCloseEvent& event) + { + on_close(CELL_MSGDIALOG_BUTTON_ESCAPE); + }); +}