Add OSK GUI (#2275)

* Initial commit of OSK GUI

Also handles character encoding, you can for instance input in Chinese.

* Fixes for osk gui
This commit is contained in:
al0xf 2017-01-23 18:14:12 +01:00 committed by Ivan
parent 78ecb115f3
commit aa357b9ae8
5 changed files with 101 additions and 4 deletions

View file

@ -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;

View file

@ -2,13 +2,46 @@
#include "Emu/Cell/PPUModule.h"
#include "cellSysutil.h"
#include "cellOskDialog.h"
#include "cellMsgDialog.h"
#include <thread>
#include "Emu/System.h"
logs::channel cellOskDialog("cellOskDialog", logs::level::notice);
char16_t* osk_text;
s32 cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dialogParam, vm::ptr<CellOskDialogInputFieldInfo> 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<CellOskDialogCallbackReturnParam> OutputInf
cellOskDialog.warning("cellOskDialogUnloadAsync(OutputInfo=*0x%x)", OutputInfo);
OutputInfo->result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK;
be_t<u16> 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<u16>)*(osk_text + i);
}
return CELL_OSKDIALOG_OK;
}
@ -33,7 +67,8 @@ s32 cellOskDialogGetSize(vm::ptr<u16> width, vm::ptr<u16> height, vm::ptr<CellOs
s32 cellOskDialogAbort()
{
cellOskDialog.todo("cellOskDialogAbort()");
cellOskDialog.warning("cellOskDialogAbort()");
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0);
return CELL_OSKDIALOG_OK;
}

View file

@ -93,6 +93,11 @@ enum CellOskDialogType
CELL_OSKDIALOG_TYPE_SEPARATE_CANDIDATE_WINDOW = 8,
};
enum
{
CELL_OSKDIALOG_STRING_SIZE = 512, //Theroretical maxium for osk input, games can specify a lower limit
};
struct CellOskDialogInputFieldInfo
{
vm::bptr<u16> message;
@ -151,3 +156,4 @@ struct CellOskDialogImeDictionaryInfo
be_t<u32> targetLanguage;
vm::bcptr<char> dictionaryPath;
};

View file

@ -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;

51
rpcs3/Gui/OskDialog.cpp Normal file
View file

@ -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);
});
}