diff --git a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp index 5e866d1366..df69691b1c 100644 --- a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp @@ -12,8 +12,6 @@ #include "cellMsgDialog.h" #include "cellImeJp.h" -#include "util/init_mutex.hpp" - #include LOG_CHANNEL(cellOskDialog); @@ -52,137 +50,73 @@ void fmt_class_string::format(std::string& out, u64 }); } -atomic_t g_osk_pointer_enabled = false; -atomic_t g_osk_pointer_x = 0.0f; -atomic_t g_osk_pointer_y = 0.0f; - -OskDialogBase::~OskDialogBase() +void osk_info::reset() { + std::lock_guard lock(text_mtx); + + dlg.reset(); + valid_text = {}; + use_separate_windows = false; + lock_ext_input = false; + device_mask = 0; + input_field_window_width = 0; + input_field_background_transparency = 0.0f; + input_field_layout_info = {}; + input_panel_layout_info = {}; + key_layout_options = CELL_OSKDIALOG_10KEY_PANEL; + initial_key_layout = CELL_OSKDIALOG_INITIAL_PANEL_LAYOUT_SYSTEM; + initial_input_device = CELL_OSKDIALOG_INPUT_DEVICE_PAD; + clipboard_enabled = false; + half_byte_kana_enabled = false; + supported_languages = 0; + dimmer_enabled = true; + base_color = OskDialogBase::color{ 0.2f, 0.2f, 0.2f, 1.0f }; + pointer_enabled = false; + pointer_x = 0.0f; + pointer_y = 0.0f; + initial_scale = 1.0f; + layout = {}; + osk_continuous_mode = CELL_OSKDIALOG_CONTINUOUS_MODE_NONE; + last_dialog_state = CELL_SYSUTIL_OSKDIALOG_UNLOADED; + osk_confirm_callback.store({}); + osk_force_finish_callback.store({}); + osk_hardware_keyboard_event_hook_callback.store({}); + hook_event_mode.store(0); } -struct osk_window_layout +// Align horizontally +u32 osk_info::get_aligned_x(u32 layout_mode) { - u32 layout_mode = CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT | CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP; - u32 x_align = CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT; - u32 y_align = CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP; - f32 x_offset = 0.0f; - f32 y_offset = 0.0f; - - std::string to_string() const + // Let's prefer a centered alignment. + if (layout_mode & CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_CENTER) { - return fmt::format("{ layout_mode=0x%x, x_align=0x%x, y_align=0x%x, x_offset=%.2f, y_offset=%.2f }", layout_mode, x_align, y_align, x_offset, y_offset); + return CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_CENTER; } -}; -struct osk_info + if (layout_mode & CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT) + { + return CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT; + } + + return CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_RIGHT; +} + +// Align vertically +u32 osk_info::get_aligned_y(u32 layout_mode) { - std::shared_ptr dlg; - - std::array valid_text{}; - shared_mutex text_mtx; - - atomic_t use_separate_windows = false; - - atomic_t lock_ext_input = false; - atomic_t device_mask = 0; // OSK ignores input from the specified devices. 0 means all devices can influence the OSK - atomic_t input_field_window_width = 0; - atomic_t input_field_background_transparency = 0.0f; - osk_window_layout input_field_layout_info{}; - osk_window_layout input_panel_layout_info{}; - atomic_t key_layout_options = CELL_OSKDIALOG_10KEY_PANEL; - atomic_t initial_key_layout = CELL_OSKDIALOG_INITIAL_PANEL_LAYOUT_SYSTEM; // TODO: use - atomic_t initial_input_device = CELL_OSKDIALOG_INPUT_DEVICE_PAD; // OSK at first only receives input from the initial device - - atomic_t clipboard_enabled = false; // For copy and paste - atomic_t half_byte_kana_enabled = false; - atomic_t supported_languages = 0; // Used to enable non-default languages in the OSK - - atomic_t dimmer_enabled = true; - atomic_t base_color = OskDialogBase::color{ 0.2f, 0.2f, 0.2f, 1.0f }; - - atomic_t pointer_enabled = false; - CellOskDialogPoint pointer_pos{0.0f, 0.0f}; - atomic_t initial_scale = 1.0f; - - osk_window_layout layout = {}; - - atomic_t osk_continuous_mode = CELL_OSKDIALOG_CONTINUOUS_MODE_NONE; - atomic_t last_dialog_state = CELL_SYSUTIL_OSKDIALOG_UNLOADED; // Used for continuous seperate window dialog - - atomic_t> osk_confirm_callback{}; - atomic_t> osk_force_finish_callback{}; - atomic_t> osk_hardware_keyboard_event_hook_callback{}; - atomic_t hook_event_mode{0}; - - stx::init_mutex init; - - void reset() + // Let's prefer a centered alignment. + if (layout_mode & CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_CENTER) { - std::lock_guard lock(text_mtx); - - dlg.reset(); - valid_text = {}; - use_separate_windows = false; - lock_ext_input = false; - device_mask = 0; - input_field_window_width = 0; - input_field_background_transparency = 0.0f; - input_field_layout_info = {}; - input_panel_layout_info = {}; - key_layout_options = CELL_OSKDIALOG_10KEY_PANEL; - initial_key_layout = CELL_OSKDIALOG_INITIAL_PANEL_LAYOUT_SYSTEM; - initial_input_device = CELL_OSKDIALOG_INPUT_DEVICE_PAD; - clipboard_enabled = false; - half_byte_kana_enabled = false; - supported_languages = 0; - dimmer_enabled = true; - base_color = OskDialogBase::color{ 0.2f, 0.2f, 0.2f, 1.0f }; - pointer_enabled = false; - pointer_pos = {0.0f, 0.0f}; - initial_scale = 1.0f; - layout = {}; - osk_continuous_mode = CELL_OSKDIALOG_CONTINUOUS_MODE_NONE; - last_dialog_state = CELL_SYSUTIL_OSKDIALOG_UNLOADED; - osk_confirm_callback.store({}); - osk_force_finish_callback.store({}); - osk_hardware_keyboard_event_hook_callback.store({}); - hook_event_mode.store(0); + return CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_CENTER; } - // Align horizontally - static u32 get_aligned_x(u32 layout_mode) + if (layout_mode & CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP) { - // Let's prefer a centered alignment. - if (layout_mode & CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_CENTER) - { - return CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_CENTER; - } - - if (layout_mode & CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT) - { - return CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT; - } - - return CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_RIGHT; + return CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP; } - // Align vertically - static u32 get_aligned_y(u32 layout_mode) - { - // Let's prefer a centered alignment. - if (layout_mode & CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_CENTER) - { - return CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_CENTER; - } - - if (layout_mode & CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP) - { - return CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP; - } - - return CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_BOTTOM; - } -}; + return CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_BOTTOM; +} // TODO: don't use this function std::shared_ptr _get_osk_dialog(bool create) @@ -597,11 +531,6 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr dia Emu.BlockingCallFromMainThread([=, &info]() { - // Make sure to always have the latest pointer params - g_osk_pointer_enabled = info.pointer_enabled.load(); - g_osk_pointer_x = info.pointer_pos.x; - g_osk_pointer_y = info.pointer_pos.y; - osk->Create({ .title = get_localized_string(localized_string_id::CELL_OSK_DIALOG_TITLE), .message = message, @@ -1197,20 +1126,19 @@ error_code cellOskDialogExtSetPointerEnable(b8 enable) cellOskDialog.warning("cellOskDialogExtSetPointerEnable(enable=%d)", enable); g_fxo->get().pointer_enabled = enable; - g_osk_pointer_enabled = enable; return CELL_OK; } error_code cellOskDialogExtUpdatePointerDisplayPos(vm::cptr pos) { - cellOskDialog.warning("cellOskDialogExtUpdatePointerDisplayPos(pos=0x%x, posX=%f, posY=%f)", pos->x, pos->y); + cellOskDialog.warning("cellOskDialogExtUpdatePointerDisplayPos(pos=0x%x, posX=%f, posY=%f)", pos, pos->x, pos->y); if (pos) { - g_fxo->get().pointer_pos = *pos; - g_osk_pointer_x = pos->x; - g_osk_pointer_y = pos->y; + osk_info& osk = g_fxo->get(); + osk.pointer_x = pos->x; + osk.pointer_y = pos->y; } return CELL_OK; diff --git a/rpcs3/Emu/Cell/Modules/cellOskDialog.h b/rpcs3/Emu/Cell/Modules/cellOskDialog.h index e68809a9b4..b3b3f3ddd6 100644 --- a/rpcs3/Emu/Cell/Modules/cellOskDialog.h +++ b/rpcs3/Emu/Cell/Modules/cellOskDialog.h @@ -2,6 +2,8 @@ #include "util/types.hpp" #include "util/atomic.hpp" +#include "util/init_mutex.hpp" +#include "Utilities/mutex.h" #include "Emu/Memory/vm_ptr.h" #include #include @@ -242,6 +244,20 @@ using cellOskDialogConfirmWordFilterCallback = int(vm::ptr pConfirmString, using cellOskDialogHardwareKeyboardEventHookCallback = class b8(vm::ptr keyMessage, vm::ptr action, vm::ptr pActionInfo); using cellOskDialogForceFinishCallback = class b8(); +struct osk_window_layout +{ + u32 layout_mode = CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT | CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP; + u32 x_align = CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT; + u32 y_align = CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP; + f32 x_offset = 0.0f; + f32 y_offset = 0.0f; + + std::string to_string() const + { + return fmt::format("{ layout_mode=0x%x, x_align=0x%x, y_align=0x%x, x_offset=%.2f, y_offset=%.2f }", layout_mode, x_align, y_align, x_offset, y_offset); + } +}; + enum class OskDialogState { Unloaded, @@ -287,7 +303,7 @@ public: // Set status to CELL_OSKDIALOG_CLOSE_CONFIRM or CELL_OSKDIALOG_CLOSE_CANCEL for user input. // Set status to -1 if closed by the game or system. virtual void Close(s32 status) = 0; - virtual ~OskDialogBase(); + virtual ~OskDialogBase() {}; std::function on_osk_close; std::function on_osk_key_input_entered; @@ -301,3 +317,55 @@ public: atomic_t osk_input_result{ CellOskDialogInputFieldResult::CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK }; char16_t osk_text[CELL_OSKDIALOG_STRING_SIZE]{}; }; + +struct osk_info +{ + std::shared_ptr dlg; + + std::array valid_text{}; + shared_mutex text_mtx; + + atomic_t use_separate_windows = false; + + atomic_t lock_ext_input = false; + atomic_t device_mask = 0; // OSK ignores input from the specified devices. 0 means all devices can influence the OSK + atomic_t input_field_window_width = 0; + atomic_t input_field_background_transparency = 0.0f; + osk_window_layout input_field_layout_info{}; + osk_window_layout input_panel_layout_info{}; + atomic_t key_layout_options = CELL_OSKDIALOG_10KEY_PANEL; + atomic_t initial_key_layout = CELL_OSKDIALOG_INITIAL_PANEL_LAYOUT_SYSTEM; // TODO: use + atomic_t initial_input_device = CELL_OSKDIALOG_INPUT_DEVICE_PAD; // OSK at first only receives input from the initial device + + atomic_t clipboard_enabled = false; // For copy and paste + atomic_t half_byte_kana_enabled = false; + atomic_t supported_languages = 0; // Used to enable non-default languages in the OSK + + atomic_t dimmer_enabled = true; + atomic_t base_color = OskDialogBase::color{ 0.2f, 0.2f, 0.2f, 1.0f }; + + atomic_t pointer_enabled = false; + atomic_t pointer_x = 0.0f; + atomic_t pointer_y = 0.0f; + atomic_t initial_scale = 1.0f; + + osk_window_layout layout = {}; + + atomic_t osk_continuous_mode = CELL_OSKDIALOG_CONTINUOUS_MODE_NONE; + atomic_t last_dialog_state = CELL_SYSUTIL_OSKDIALOG_UNLOADED; // Used for continuous seperate window dialog + + atomic_t> osk_confirm_callback{}; + atomic_t> osk_force_finish_callback{}; + atomic_t> osk_hardware_keyboard_event_hook_callback{}; + atomic_t hook_event_mode{0}; + + stx::init_mutex init; + + void reset(); + + // Align horizontally + static u32 get_aligned_x(u32 layout_mode); + + // Align vertically + static u32 get_aligned_y(u32 layout_mode); +}; diff --git a/rpcs3/Emu/RSX/Overlays/overlay_media_list_dialog.cpp b/rpcs3/Emu/RSX/Overlays/overlay_media_list_dialog.cpp index ecfd0b1dbf..c6686452ac 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_media_list_dialog.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_media_list_dialog.cpp @@ -45,12 +45,12 @@ namespace rsx if (convert_ratio > 1.0f) { - const u16 new_padding = (target_height - target_height / convert_ratio) / 2; + const u16 new_padding = static_cast(target_height - target_height / convert_ratio) / 2; image->set_padding(image->padding_left, image->padding_right, new_padding + image->padding_top, new_padding + image->padding_bottom); } else if (convert_ratio < 1.0f) { - const u16 new_padding = (target_width - target_width * convert_ratio) / 2; + const u16 new_padding = static_cast(target_width - target_width * convert_ratio) / 2; image->set_padding(image->padding_left + new_padding, image->padding_right + new_padding, image->padding_top, image->padding_bottom); } } @@ -329,7 +329,7 @@ namespace rsx if (new_entry.type != media_list_dialog::media_type::invalid) { new_entry.parent = ¤t_entry; - new_entry.index = current_entry.children.size(); + new_entry.index = ::narrow(current_entry.children.size()); current_entry.children.emplace_back(std::move(new_entry)); } } diff --git a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp index 7c0c11cb7e..3f0ce62273 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp @@ -7,10 +7,6 @@ LOG_CHANNEL(osk, "OSK"); -extern atomic_t g_osk_pointer_enabled; -extern atomic_t g_osk_pointer_x; -extern atomic_t g_osk_pointer_y; - namespace rsx { namespace overlays @@ -937,14 +933,16 @@ namespace rsx m_update = true; } - if (g_osk_pointer_enabled != m_pointer.visible()) + osk_info& info = g_fxo->get(); + + if (const bool pointer_enabled = info.pointer_enabled; pointer_enabled != m_pointer.visible()) { - m_pointer.set_expiration(g_osk_pointer_enabled ? u64{umax} : 0); + m_pointer.set_expiration(pointer_enabled ? u64{umax} : 0); m_pointer.update_visibility(get_system_time()); m_update = true; } - if (m_pointer.visible() && m_pointer.set_position(static_cast(g_osk_pointer_x), static_cast(g_osk_pointer_y))) + if (m_pointer.visible() && m_pointer.set_position(static_cast(info.pointer_x), static_cast(info.pointer_y))) { m_update = true; }