From 8fff57db8c57d616f832440ab95a64246f26c06b Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 10 Feb 2024 14:58:53 +0100 Subject: [PATCH] overlays/input: allow ldd pad input --- rpcs3/Emu/RSX/Overlays/overlays.cpp | 78 ++++++++++++++++++++++++++++- rpcs3/Input/pad_thread.cpp | 3 +- 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/RSX/Overlays/overlays.cpp b/rpcs3/Emu/RSX/Overlays/overlays.cpp index b4aa2a8872d7..db63d24862e7 100644 --- a/rpcs3/Emu/RSX/Overlays/overlays.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlays.cpp @@ -198,6 +198,9 @@ namespace rsx const bool ignore_gamepad_input = (!rinfo.now_connect || !input::g_pads_intercepted); + const pad_button cross_button = g_cfg.sys.enter_button_assignment == enter_button_assign::circle ? pad_button::circle : pad_button::cross; + const pad_button circle_button = g_cfg.sys.enter_button_assignment == enter_button_assign::circle ? pad_button::cross : pad_button::circle; + m_keyboard_pad_handler_active = false; int pad_index = -1; @@ -243,6 +246,77 @@ namespace rsx continue; } + if (pad->ldd) + { + // LDD pads get passed input data from the game itself. + + if (pad->ldd_data.len > CELL_PAD_BTN_OFFSET_DIGITAL1) + { + const u16 digital1 = pad->ldd_data.button[CELL_PAD_BTN_OFFSET_DIGITAL1]; + + handle_button_press(pad_button::dpad_left, !!(digital1 & CELL_PAD_CTRL_LEFT), pad_index); + handle_button_press(pad_button::dpad_right, !!(digital1 & CELL_PAD_CTRL_RIGHT), pad_index); + handle_button_press(pad_button::dpad_down, !!(digital1 & CELL_PAD_CTRL_DOWN), pad_index); + handle_button_press(pad_button::dpad_up, !!(digital1 & CELL_PAD_CTRL_UP), pad_index); + handle_button_press(pad_button::L3, !!(digital1 & CELL_PAD_CTRL_L3), pad_index); + handle_button_press(pad_button::R3, !!(digital1 & CELL_PAD_CTRL_R3), pad_index); + handle_button_press(pad_button::select, !!(digital1 & CELL_PAD_CTRL_SELECT), pad_index); + handle_button_press(pad_button::start, !!(digital1 & CELL_PAD_CTRL_START), pad_index); + } + + if (pad->ldd_data.len > CELL_PAD_BTN_OFFSET_DIGITAL2) + { + const u16 digital2 = pad->ldd_data.button[CELL_PAD_BTN_OFFSET_DIGITAL2]; + + handle_button_press(pad_button::triangle, !!(digital2 & CELL_PAD_CTRL_TRIANGLE), pad_index); + handle_button_press(circle_button, !!(digital2 & CELL_PAD_CTRL_CIRCLE), pad_index); + handle_button_press(pad_button::square, !!(digital2 & CELL_PAD_CTRL_SQUARE), pad_index); + handle_button_press(cross_button, !!(digital2 & CELL_PAD_CTRL_CROSS), pad_index); + handle_button_press(pad_button::L1, !!(digital2 & CELL_PAD_CTRL_L1), pad_index); + handle_button_press(pad_button::R1, !!(digital2 & CELL_PAD_CTRL_R1), pad_index); + handle_button_press(pad_button::L2, !!(digital2 & CELL_PAD_CTRL_L2), pad_index); + handle_button_press(pad_button::R2, !!(digital2 & CELL_PAD_CTRL_R2), pad_index); + handle_button_press(pad_button::ps, !!(digital2 & CELL_PAD_CTRL_PS), pad_index); + } + + const auto handle_ldd_stick_input = [&](s32 offset, pad_button id_small, pad_button id_large) + { + if (pad->ldd_data.len <= offset) + { + return; + } + + constexpr u16 threshold = 20; // Let's be careful and use some threshold here + const u16 value = pad->ldd_data.button[offset]; + + if (value <= (128 - threshold)) + { + // Release other direction on the same axis first + handle_button_press(id_large, false, pad_index); + handle_button_press(id_small, true, pad_index); + } + else if (value > (128 + threshold)) + { + // Release other direction on the same axis first + handle_button_press(id_small, false, pad_index); + handle_button_press(id_large, true, pad_index); + } + else + { + // Release both directions on the same axis + handle_button_press(id_small, false, pad_index); + handle_button_press(id_large, false, pad_index); + } + }; + + handle_ldd_stick_input(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X, pad_button::rs_left, pad_button::rs_right); + handle_ldd_stick_input(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y, pad_button::rs_down, pad_button::rs_up); + handle_ldd_stick_input(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X, pad_button::ls_left, pad_button::ls_right); + handle_ldd_stick_input(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y, pad_button::ls_down, pad_button::ls_up); + + continue; + } + for (const Button& button : pad->m_buttons) { pad_button button_id = pad_button::pad_button_max_enum; @@ -286,13 +360,13 @@ namespace rsx button_id = pad_button::triangle; break; case CELL_PAD_CTRL_CIRCLE: - button_id = g_cfg.sys.enter_button_assignment == enter_button_assign::circle ? pad_button::cross : pad_button::circle; + button_id = circle_button; break; case CELL_PAD_CTRL_SQUARE: button_id = pad_button::square; break; case CELL_PAD_CTRL_CROSS: - button_id = g_cfg.sys.enter_button_assignment == enter_button_assign::circle ? pad_button::circle : pad_button::cross; + button_id = cross_button; break; case CELL_PAD_CTRL_L1: button_id = pad_button::L1; diff --git a/rpcs3/Input/pad_thread.cpp b/rpcs3/Input/pad_thread.cpp index 34e6796c8a4e..f7a9b7c427e2 100644 --- a/rpcs3/Input/pad_thread.cpp +++ b/rpcs3/Input/pad_thread.cpp @@ -399,9 +399,8 @@ void pad_thread::operator()() if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED)) continue; - // TODO: this keeps opening the home menu. Find out how to do it properly. // Check if an LDD pad pressed the PS button (bit 0 of the first button) - if (false && pad->ldd && !!(pad->ldd_data.button[0] & CELL_PAD_CTRL_LDD_PS)) + if (pad->ldd && pad->ldd_data.len >= 1 && !!(pad->ldd_data.button[0] & CELL_PAD_CTRL_LDD_PS)) { ps_button_pressed = true; break;