diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index bf75a483bb..e0864e1c86 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -160,6 +160,32 @@ void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer em_address) +{ + if (!em_address.IsValid()) + { + _string = L""; + return; + } + const size_t maxLength = 2048; + + wchar_t stringBuffer[maxLength]; + wchar_t *string = stringBuffer; + + auto input = em_address; + int c; + u32 count = 0; + while ((c = *input++) != 0) + { + if ( !(++count >= maxLength) ) + *string++ = c; + else + break; + } + *string++ = '\0'; + _string = stringBuffer; +} + void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const wchar_t *input) { char stringBuffer[2048]; @@ -742,7 +768,7 @@ void PSPOskDialog::RenderKeyboard() // TODO: Use a wstring to allow Japanese/Russian/etc.. on _WIN32(others?) int PSPOskDialog::NativeKeyboard() { - char *input = new char[FieldMaxLength()]; + wchar_t *input = new wchar_t[FieldMaxLength()]; memset(input, 0, sizeof(input)); if (status == SCE_UTILITY_STATUS_INITIALIZE) @@ -752,37 +778,35 @@ int PSPOskDialog::NativeKeyboard() else if (status == SCE_UTILITY_STATUS_RUNNING) { - - std::string initial_text; - ConvertUCS2ToUTF8(initial_text, oskParams->fields[0].intext); + std::wstring titleText; + GetWideStringFromPSPPointer(titleText, oskParams->fields[0].desc); - const size_t defaultText_len = 512; - char defaultText[defaultText_len]; + std::wstring defaultText; + GetWideStringFromPSPPointer(defaultText, oskParams->fields[0].intext); - memset(defaultText, 0, sizeof(defaultText)); + if(defaultText.length() <= 0) + defaultText.assign(L"VALUE"); - if(initial_text.length() < defaultText_len) - strncat(defaultText, initial_text.c_str(), strlen(initial_text.c_str())); - else { - ERROR_LOG(HLE, "NativeKeyboard: initial text length is too long"); - strncat(defaultText, "VALUE", strlen("VALUE")); + std::wstring inputWide; + + if(!host->InputBoxGetWString(titleText.c_str(), defaultText, inputWide)) + { + wcsncat(input, L"", wcslen(L"")); } + else + { + size_t maxInputLength = FieldMaxLength(); - char windowTitle[defaultText_len]; - memset(windowTitle, 0, sizeof(windowTitle)); - - std::string description_text; - ConvertUCS2ToUTF8(description_text, oskParams->fields[0].desc); - - if(description_text.length() < defaultText_len) - strncat(windowTitle, description_text.c_str(), strlen(description_text.c_str())); - - size_t maxInputLength = FieldMaxLength(); - - if(host->InputBoxGetString(windowTitle, defaultText, input, maxInputLength)) { - strncat(input, "", strlen("")); + if(inputWide.length() < maxInputLength) + { + wcsncat(input, inputWide.c_str(), inputWide.length()); + } + else + { + ERROR_LOG(HLE, "NativeKeyboard: input text too long(%d characters/glyphs max), truncating to game-requested length.", maxInputLength); + wcsncat(input, inputWide.c_str(), maxInputLength); + } } - status = SCE_UTILITY_STATUS_FINISHED; } else if (status == SCE_UTILITY_STATUS_FINISHED) diff --git a/Core/Host.h b/Core/Host.h index 457bd782c2..f13f378a5a 100644 --- a/Core/Host.h +++ b/Core/Host.h @@ -68,6 +68,7 @@ public: #ifdef _WIN32 // Implement this on your platform to grab text input from the user for whatever purpose. virtual bool InputBoxGetString(char *title, const char *defaultValue, char *outValue, size_t outlength) { return false; } + virtual bool InputBoxGetWString(const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue) { return false; } #endif // Used for headless. diff --git a/Windows/InputBox.cpp b/Windows/InputBox.cpp index 9f7d0b9459..7d24b4f2b4 100644 --- a/Windows/InputBox.cpp +++ b/Windows/InputBox.cpp @@ -85,6 +85,28 @@ bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, con return false; } +bool InputBox_GetWString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::wstring &defaultValue, std::wstring &outvalue) +{ + const wchar_t *defaultTitle = L"Input value"; + defaultSelected = true; + + textBoxContents = defaultValue; + + if (title && wcslen(title) <= 0) + windowTitle = defaultTitle; + else if (title && wcslen(title) < 255) + windowTitle = title; + else + windowTitle = defaultTitle; + + if (IDOK == DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc)) { + outvalue = out; + return true; + } + else + return false; +} + bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t *title, u32 defaultvalue, u32 &outvalue) { wchar_t temp[256]; diff --git a/Windows/InputBox.h b/Windows/InputBox.h index 673ffe3c65..fdfc1ebd6b 100644 --- a/Windows/InputBox.h +++ b/Windows/InputBox.h @@ -8,4 +8,5 @@ // All I/O is in UTF-8 bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultvalue, std::string &outvalue, bool selected); bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultvalue, std::string &outvalue); +bool InputBox_GetWString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue); bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t *title, u32 defaultvalue, u32 &outvalue); diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 1baac21b85..76acb3a272 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -309,6 +309,15 @@ bool WindowsHost::InputBoxGetString(char *title, const char *defaultValue, char } } +bool WindowsHost::InputBoxGetWString(const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue) +{ + if (InputBox_GetWString(MainWindow::GetHInstance(), MainWindow::GetHWND(), title, defaultvalue, outvalue)) { + return true; + } else { + return false; + } +} + // http://msdn.microsoft.com/en-us/library/aa969393.aspx HRESULT CreateLink(LPCWSTR lpszPathObj, LPCWSTR lpszArguments, LPCWSTR lpszPathLink, LPCWSTR lpszDesc) { diff --git a/Windows/WindowsHost.h b/Windows/WindowsHost.h index 20b3e91dff..2c4d5c463a 100644 --- a/Windows/WindowsHost.h +++ b/Windows/WindowsHost.h @@ -59,7 +59,7 @@ public: virtual bool CreateDesktopShortcut(std::string argumentPath, std::string title); bool InputBoxGetString(char *title, const char *defaultValue, char *outValue, size_t outlength); - + bool InputBoxGetWString(const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue); std::shared_ptr keyboard; private: