From 0ff293707aaa26087a9a94ad427397aec50acc9e Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 19 Apr 2022 22:30:20 +0200 Subject: [PATCH] OSK: allow device input during interception --- rpcs3/Emu/Cell/Modules/cellKb.cpp | 16 ++++- rpcs3/Emu/Cell/Modules/cellMouse.cpp | 32 ++++++++- rpcs3/Emu/Cell/Modules/cellOskDialog.cpp | 1 + rpcs3/Emu/Io/KeyboardHandler.h | 31 ++------- rpcs3/Emu/Io/MouseHandler.h | 88 ++++++++---------------- rpcs3/Emu/Io/Null/NullKeyboardHandler.h | 1 + rpcs3/Emu/Io/Null/NullMouseHandler.h | 1 + rpcs3/Emu/RSX/Overlays/overlays.cpp | 4 +- rpcs3/Emu/RSX/Overlays/overlays.h | 2 +- rpcs3/Input/basic_keyboard_handler.cpp | 4 +- rpcs3/Input/basic_mouse_handler.cpp | 2 +- 11 files changed, 89 insertions(+), 93 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellKb.cpp b/rpcs3/Emu/Cell/Modules/cellKb.cpp index 44d3505c53..99e62b96ff 100644 --- a/rpcs3/Emu/Cell/Modules/cellKb.cpp +++ b/rpcs3/Emu/Cell/Modules/cellKb.cpp @@ -304,9 +304,19 @@ error_code cellKbRead(u32 port_no, vm::ptr data) return CELL_KB_ERROR_NO_DEVICE; KbData& current_data = handler.GetData(port_no); - data->led = current_data.led; - data->mkey = current_data.mkey; - data->len = std::min(CELL_KB_MAX_KEYCODES, current_data.len); + + if (current_info.is_null_handler || (current_info.info & CELL_KB_INFO_INTERCEPTED)) + { + data->led = 0; + data->mkey = 0; + data->len = 0; + } + else + { + data->led = current_data.led; + data->mkey = current_data.mkey; + data->len = std::min(CELL_KB_MAX_KEYCODES, current_data.len); + } if (current_data.len > 0) { diff --git a/rpcs3/Emu/Cell/Modules/cellMouse.cpp b/rpcs3/Emu/Cell/Modules/cellMouse.cpp index 7a1f19204a..c3d54d9a64 100644 --- a/rpcs3/Emu/Cell/Modules/cellMouse.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMouse.cpp @@ -209,8 +209,9 @@ error_code cellMouseGetData(u32 port_no, vm::ptr data) MouseDataList& data_list = handler.GetDataList(port_no); - if (data_list.empty()) + if (data_list.empty() || current_info.is_null_handler || (current_info.info & CELL_MOUSE_INFO_INTERCEPTED)) { + data_list.clear(); return CELL_OK; } @@ -252,9 +253,18 @@ error_code cellMouseGetDataList(u32 port_no, vm::ptr data) return CELL_MOUSE_ERROR_NO_DEVICE; } + std::memset(data.get_ptr(), 0, data.size()); + // TODO: check if (current_info.mode[port_no] != CELL_MOUSE_INFO_TABLET_MOUSE_MODE) has any impact auto& list = handler.GetDataList(port_no); + + if (list.empty() || current_info.is_null_handler || (current_info.info & CELL_MOUSE_INFO_INTERCEPTED)) + { + list.clear(); + return CELL_OK; + } + data->list_num = std::min(CELL_MOUSE_MAX_DATA_LIST_NUM, static_cast(list.size())); int i = 0; @@ -332,10 +342,19 @@ error_code cellMouseGetTabletDataList(u32 port_no, vm::ptrlist_num = std::min(CELL_MOUSE_MAX_DATA_LIST_NUM, static_cast(list.size())); int i = 0; @@ -351,6 +370,8 @@ error_code cellMouseGetTabletDataList(u32 port_no, vm::ptr data) return CELL_MOUSE_ERROR_NO_DEVICE; } + std::memset(data.get_ptr(), 0, data.size()); + // TODO: decr tests show that CELL_MOUSE_ERROR_DATA_READ_FAILED is returned when a mouse is connected // TODO: check if (current_info.mode[port_no] != CELL_MOUSE_INFO_TABLET_MOUSE_MODE) has any impact MouseRawData& current_data = handler.GetRawData(port_no); + + if (current_info.is_null_handler || (current_info.info & CELL_MOUSE_INFO_INTERCEPTED)) + { + current_data = {}; + return CELL_OK; + } + data->len = current_data.len; current_data.len = 0; diff --git a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp index 8fc7137a59..e2d78b0438 100644 --- a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp @@ -612,6 +612,7 @@ error_code cellOskDialogSetInitialInputDevice(u32 inputDevice) g_fxo->get().initial_input_device = static_cast(inputDevice); // TODO: use value + // TODO: Signal CELL_SYSUTIL_OSKDIALOG_INPUT_DEVICE_CHANGED if the input device changed (probably only when the dialog is already open) return CELL_OK; } diff --git a/rpcs3/Emu/Io/KeyboardHandler.h b/rpcs3/Emu/Io/KeyboardHandler.h index ddce53009e..fc3d0c5b15 100644 --- a/rpcs3/Emu/Io/KeyboardHandler.h +++ b/rpcs3/Emu/Io/KeyboardHandler.h @@ -27,6 +27,7 @@ struct KbInfo u32 max_connect = 0; u32 now_connect = 0; u32 info = 0; + bool is_null_handler = false; std::array status{}; }; @@ -47,31 +48,17 @@ struct KbButton struct KbData { - u32 led; // Active led lights - u32 mkey; // Active key modifiers - s32 len; // Number of key codes (0 means no data available) + u32 led = 0; // Active led lights TODO: Set initial state of led + u32 mkey = 0; // Active key modifiers + s32 len = 0; // Number of key codes (0 means no data available) std::array buttons{}; - - KbData() - : led(0) - , mkey(0) - , len(0) - { // (TODO: Set initial state of led) - } }; struct KbConfig { - u32 arrange; - u32 read_mode; - u32 code_type; - - KbConfig() - : arrange(CELL_KB_MAPPING_101) - , read_mode(CELL_KB_RMODE_INPUTCHAR) - , code_type(CELL_KB_CODETYPE_ASCII) - { - } + u32 arrange = CELL_KB_MAPPING_101; + u32 read_mode = CELL_KB_RMODE_INPUTCHAR; + u32 code_type = CELL_KB_CODETYPE_ASCII; }; struct Keyboard @@ -80,10 +67,6 @@ struct Keyboard KbData m_data{}; KbConfig m_config{}; std::vector m_buttons; - - Keyboard() - { - } }; class KeyboardHandlerBase diff --git a/rpcs3/Emu/Io/MouseHandler.h b/rpcs3/Emu/Io/MouseHandler.h index 12dd31a10a..ec7a41c300 100644 --- a/rpcs3/Emu/Io/MouseHandler.h +++ b/rpcs3/Emu/Io/MouseHandler.h @@ -54,58 +54,37 @@ static const u32 MOUSE_MAX_CODES = 64; struct MouseInfo { - u32 max_connect; - u32 now_connect; - u32 info; - u32 mode[MAX_MICE]; // TODO: tablet support - u32 tablet_is_supported[MAX_MICE]; // TODO: tablet support - u16 vendor_id[MAX_MICE]; - u16 product_id[MAX_MICE]; - u8 status[MAX_MICE]; + u32 max_connect = 0; + u32 now_connect = 0; + u32 info = 0; + u32 mode[MAX_MICE]{}; // TODO: tablet support + u32 tablet_is_supported[MAX_MICE]{}; // TODO: tablet support + u16 vendor_id[MAX_MICE]{}; + u16 product_id[MAX_MICE]{}; + u8 status[MAX_MICE]{}; + bool is_null_handler = false; }; struct MouseRawData { - s32 len; - u8 data[MOUSE_MAX_CODES]; - - MouseRawData() - : len(0) - , data() - { - } + s32 len = 0; + u8 data[MOUSE_MAX_CODES]{}; }; struct MouseData { - u8 update; - u8 buttons; - s8 x_axis; - s8 y_axis; - s8 wheel; - s8 tilt; // (TODO) - - MouseData() - : update(0) - , buttons(0) - , x_axis(0) - , y_axis(0) - , wheel(0) - , tilt(0) - { - } + u8 update = 0; + u8 buttons = 0; + s8 x_axis = 0; + s8 y_axis = 0; + s8 wheel = 0; + s8 tilt = 0; // (TODO) }; struct MouseTabletData { - s32 len; - u8 data[MOUSE_MAX_CODES]; - - MouseTabletData() - : len(0) - , data() - { - } + s32 len = 0; + u8 data[MOUSE_MAX_CODES]{}; }; using MouseTabletDataList = std::list; @@ -113,32 +92,23 @@ using MouseDataList = std::list; struct Mouse { - s32 x_pos; - s32 y_pos; - s32 x_max; - s32 y_max; - u8 buttons; // actual mouse button positions + s32 x_pos = 0; + s32 y_pos = 0; + s32 x_max = 0; + s32 y_max = 0; + u8 buttons = 0; // actual mouse button positions - MouseTabletDataList m_tablet_datalist; - MouseDataList m_datalist; - MouseRawData m_rawdata; - - Mouse() - : x_pos(0) - , y_pos(0) - , x_max(0) - , y_max(0) - , buttons(0) - { - } + MouseTabletDataList m_tablet_datalist{}; + MouseDataList m_datalist{}; + MouseRawData m_rawdata{}; }; class MouseHandlerBase { protected: - MouseInfo m_info; + MouseInfo m_info{}; std::vector m_mice; - steady_clock::time_point last_update; + steady_clock::time_point last_update{}; bool is_time_for_update(double elapsed_time = 10.0) // 4-10 ms, let's use 10 for now { diff --git a/rpcs3/Emu/Io/Null/NullKeyboardHandler.h b/rpcs3/Emu/Io/Null/NullKeyboardHandler.h index 31ac520063..9bdb8bba2d 100644 --- a/rpcs3/Emu/Io/Null/NullKeyboardHandler.h +++ b/rpcs3/Emu/Io/Null/NullKeyboardHandler.h @@ -9,6 +9,7 @@ public: { m_info = {}; m_info.max_connect = max_connect; + m_info.is_null_handler = true; m_keyboards.clear(); for (u32 i = 0; i < max_connect; i++) { diff --git a/rpcs3/Emu/Io/Null/NullMouseHandler.h b/rpcs3/Emu/Io/Null/NullMouseHandler.h index 1c451fa4c0..357d956d30 100644 --- a/rpcs3/Emu/Io/Null/NullMouseHandler.h +++ b/rpcs3/Emu/Io/Null/NullMouseHandler.h @@ -9,6 +9,7 @@ public: { m_info = {}; m_info.max_connect = max_connect; + m_info.is_null_handler = true; m_mice.clear(); } }; diff --git a/rpcs3/Emu/RSX/Overlays/overlays.cpp b/rpcs3/Emu/RSX/Overlays/overlays.cpp index af611d386d..d3a07964d7 100644 --- a/rpcs3/Emu/RSX/Overlays/overlays.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlays.cpp @@ -125,7 +125,7 @@ namespace rsx continue; // Get keyboard input - if (m_keyboard_input_enabled) + if (m_keyboard_input_enabled && input::g_keyboards_intercepted) { auto& handler = g_fxo->get(); std::lock_guard lock(handler.m_mutex); @@ -173,7 +173,7 @@ namespace rsx const auto handler = pad::get_current_handler(); const PadInfo& rinfo = handler->GetInfo(); - if (!rinfo.now_connect) + if (!rinfo.now_connect || !input::g_pads_intercepted) { refresh(); continue; diff --git a/rpcs3/Emu/RSX/Overlays/overlays.h b/rpcs3/Emu/RSX/Overlays/overlays.h index d699eee79a..e0c40ab78e 100644 --- a/rpcs3/Emu/RSX/Overlays/overlays.h +++ b/rpcs3/Emu/RSX/Overlays/overlays.h @@ -96,7 +96,7 @@ namespace rsx atomic_t m_interactive = false; atomic_t m_stop_pad_interception = false; atomic_t thread_bits = 0; - bool m_keyboard_input_enabled = false; + bool m_keyboard_input_enabled = false; // Allow keyboard events static thread_local u64 g_thread_bit; diff --git a/rpcs3/Input/basic_keyboard_handler.cpp b/rpcs3/Input/basic_keyboard_handler.cpp index 98de1e0854..883ac0f410 100644 --- a/rpcs3/Input/basic_keyboard_handler.cpp +++ b/rpcs3/Input/basic_keyboard_handler.cpp @@ -15,7 +15,7 @@ void basic_keyboard_handler::Init(const u32 max_connect) { for (u32 i = 0; i < max_connect; i++) { - Keyboard kb; + Keyboard kb{}; kb.m_config.arrange = g_cfg.sys.keyboard_type; @@ -53,7 +53,7 @@ void basic_keyboard_handler::SetTargetWindow(QWindow* target) bool basic_keyboard_handler::eventFilter(QObject* watched, QEvent* event) { - if (!event || input::g_keyboards_intercepted) + if (!event) { return false; } diff --git a/rpcs3/Input/basic_mouse_handler.cpp b/rpcs3/Input/basic_mouse_handler.cpp index 1535e0fb74..0ea7e02c2f 100644 --- a/rpcs3/Input/basic_mouse_handler.cpp +++ b/rpcs3/Input/basic_mouse_handler.cpp @@ -50,7 +50,7 @@ void basic_mouse_handler::SetTargetWindow(QWindow* target) bool basic_mouse_handler::eventFilter(QObject* target, QEvent* ev) { - if (!ev || input::g_mice_intercepted) + if (!ev) { return false; }