diff --git a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp index 65382906f8..cdefea158b 100644 --- a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp @@ -247,7 +247,7 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr dia // Get init text and prepare return value osk->osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK; - std::memset(osk->osk_text, 0, sizeof(osk->osk_text)); + osk->osk_text = {}; // Also clear the info text just to be sure (it should be zeroed at this point anyway) { @@ -605,7 +605,7 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr dia osk->Create({ .title = get_localized_string(localized_string_id::CELL_OSK_DIALOG_TITLE), .message = message, - .init_text = osk->osk_text, + .init_text = osk->osk_text.data(), .charlimit = maxLength, .prohibit_flags = prohibitFlgs, .panel_flag = allowOskPanelFlg, @@ -741,8 +741,14 @@ error_code getText(vm::ptr OutputInfo, bool is case CELL_SYSUTIL_OSKDIALOG_UNLOADED: case CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED: case CELL_SYSUTIL_OSKDIALOG_INPUT_ENTERED: + { + auto& info = g_fxo->get(); + std::lock_guard lock(info.text_mtx); + info.valid_text = {}; + osk->Clear(); break; + } default: break; } diff --git a/rpcs3/Emu/Cell/Modules/cellOskDialog.h b/rpcs3/Emu/Cell/Modules/cellOskDialog.h index 682b195589..579f681e23 100644 --- a/rpcs3/Emu/Cell/Modules/cellOskDialog.h +++ b/rpcs3/Emu/Cell/Modules/cellOskDialog.h @@ -301,6 +301,7 @@ public: }; virtual void Create(const osk_params& params) = 0; + virtual void Clear() = 0; // Closes the dialog. // Set status to CELL_OSKDIALOG_CLOSE_CONFIRM or CELL_OSKDIALOG_CLOSE_CANCEL for user input. @@ -321,7 +322,7 @@ public: atomic_t ignore_device_events{ false }; // Determines if the OSK ignores device events. atomic_t osk_input_result{ CellOskDialogInputFieldResult::CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK }; - char16_t osk_text[CELL_OSKDIALOG_STRING_SIZE]{}; + std::array osk_text{}; }; struct osk_info diff --git a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp index 39b245071a..7d761bc918 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp @@ -69,6 +69,15 @@ namespace rsx fade_animation.active = true; } + void osk_dialog::Clear() + { + std::lock_guard lock(m_preview_mutex); + + m_preview.caret_position = 0; + m_preview.value.clear(); + on_text_changed(); + } + void osk_dialog::add_panel(const osk_panel& panel) { // On PS3 apparently only 7 panels are added, the rest is ignored @@ -582,6 +591,8 @@ namespace rsx update_panel(); } + std::lock_guard lock(m_preview_mutex); + const u32 grid_size = num_columns * num_rows; const auto on_accept = [this]() @@ -943,8 +954,8 @@ namespace rsx void osk_dialog::on_text_changed() { const auto ws = u32string_to_utf16(m_preview.value); - const auto length = (ws.length() + 1) * sizeof(char16_t); - memcpy(osk_text, ws.c_str(), length); + const usz length = std::min(osk_text.size(), ws.length() + 1) * sizeof(char16_t); + memcpy(osk_text.data(), ws.c_str(), length); // Muted contrast for placeholder text m_preview.fore_color.a = m_preview.value.empty() ? 0.5f : 1.f; diff --git a/rpcs3/Emu/RSX/Overlays/overlay_osk.h b/rpcs3/Emu/RSX/Overlays/overlay_osk.h index 5ce6ce50c8..5c647b1d0b 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_osk.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_osk.h @@ -38,6 +38,9 @@ namespace rsx callback_t callback; }; + // Mutex for interaction between overlay and cellOskDialog + shared_mutex m_preview_mutex; + // Base UI configuration bool m_use_separate_windows = false; bool m_show_panel = true; @@ -104,6 +107,7 @@ namespace rsx void Create(const osk_params& params) override; void Close(s32 status) override; + void Clear() override; void initialize_layout(const std::u32string& title, const std::u32string& initial_text); void add_panel(const osk_panel& panel); diff --git a/rpcs3/rpcs3qt/osk_dialog_frame.cpp b/rpcs3/rpcs3qt/osk_dialog_frame.cpp index 0598f38ff1..eb10b86b18 100644 --- a/rpcs3/rpcs3qt/osk_dialog_frame.cpp +++ b/rpcs3/rpcs3qt/osk_dialog_frame.cpp @@ -182,7 +182,7 @@ void osk_dialog_frame::Create(const osk_params& params) void osk_dialog_frame::SetOskText(const QString& text) { - std::memcpy(osk_text, utils::bless(text.constData()), (text.size() + 1u) * sizeof(char16_t)); + std::memcpy(osk_text.data(), utils::bless(text.constData()), std::min(osk_text.size(), text.size() + 1ull) * sizeof(char16_t)); } void osk_dialog_frame::Close(s32 status) @@ -203,3 +203,11 @@ void osk_dialog_frame::Close(s32 status) } } } + +void osk_dialog_frame::Clear() +{ + if (m_dialog) + { + SetOskText(""); + } +} diff --git a/rpcs3/rpcs3qt/osk_dialog_frame.h b/rpcs3/rpcs3qt/osk_dialog_frame.h index 68febef5ef..b3948159d3 100644 --- a/rpcs3/rpcs3qt/osk_dialog_frame.h +++ b/rpcs3/rpcs3qt/osk_dialog_frame.h @@ -18,6 +18,7 @@ public: ~osk_dialog_frame(); void Create(const osk_params& params) override; void Close(s32 status) override; + void Clear() override; private: void SetOskText(const QString& text);