diff --git a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp index 0655ae5efb..4c1fdeffba 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp @@ -437,6 +437,7 @@ namespace rsx break; } case pad_button::dpad_right: + case pad_button::ls_right: { u32 current_index = (selected_y * num_columns) + selected_x; while (true) @@ -459,6 +460,7 @@ namespace rsx break; } case pad_button::dpad_left: + case pad_button::ls_left: { u32 current_index = (selected_y * num_columns) + selected_x; while (current_index > 0) @@ -483,6 +485,7 @@ namespace rsx break; } case pad_button::dpad_down: + case pad_button::ls_down: { u32 current_index = (selected_y * num_columns) + selected_x; while (true) @@ -503,6 +506,7 @@ namespace rsx break; } case pad_button::dpad_up: + case pad_button::ls_up: { u32 current_index = (selected_y * num_columns) + selected_x; while (current_index >= num_columns) diff --git a/rpcs3/Emu/RSX/Overlays/overlay_save_dialog.cpp b/rpcs3/Emu/RSX/Overlays/overlay_save_dialog.cpp index bce94818da..df8d397dcc 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_save_dialog.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_save_dialog.cpp @@ -129,9 +129,11 @@ namespace rsx close(true, true); return; case pad_button::dpad_up: + case pad_button::ls_up: m_list->select_previous(); break; case pad_button::dpad_down: + case pad_button::ls_down: m_list->select_next(); break; case pad_button::L1: diff --git a/rpcs3/Emu/RSX/Overlays/overlay_user_list_dialog.cpp b/rpcs3/Emu/RSX/Overlays/overlay_user_list_dialog.cpp index c89101fe01..81d0c42e08 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_user_list_dialog.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_user_list_dialog.cpp @@ -107,9 +107,11 @@ namespace rsx close(true, true); return; case pad_button::dpad_up: + case pad_button::ls_up: m_list->select_previous(); break; case pad_button::dpad_down: + case pad_button::ls_down: m_list->select_next(); break; case pad_button::L1: diff --git a/rpcs3/Emu/RSX/Overlays/overlays.cpp b/rpcs3/Emu/RSX/Overlays/overlays.cpp index a6cf5e9848..d6f98905b4 100644 --- a/rpcs3/Emu/RSX/Overlays/overlays.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlays.cpp @@ -67,6 +67,51 @@ namespace rsx input::SetIntercepted(true); + const auto handle_button_press = [&](u8 button_id, bool pressed, int pad_index) + { + if (button_id >= pad_button::pad_button_max_enum) + { + return; + } + + if (pressed) + { + const bool is_auto_repeat_button = auto_repeat_buttons.contains(button_id); + + if (!last_button_state[pad_index][button_id]) + { + // The button was not pressed before, so this is a new button press. Reset auto-repeat. + timestamp[pad_index] = steady_clock::now(); + initial_timestamp[pad_index] = timestamp[pad_index]; + last_auto_repeat_button[pad_index] = is_auto_repeat_button ? button_id : pad_button::pad_button_max_enum; + on_button_pressed(static_cast(button_id)); + } + else if (is_auto_repeat_button) + { + if (last_auto_repeat_button[pad_index] == button_id + && input_timer.GetMsSince(initial_timestamp[pad_index]) > ms_threshold + && input_timer.GetMsSince(timestamp[pad_index]) > ms_interval) + { + // The auto-repeat button was pressed for at least the given threshold in ms and will trigger at an interval. + timestamp[pad_index] = steady_clock::now(); + on_button_pressed(static_cast(button_id)); + } + else if (last_auto_repeat_button[pad_index] == pad_button::pad_button_max_enum) + { + // An auto-repeat button was already pressed before and will now start triggering again after the next threshold. + last_auto_repeat_button[pad_index] = button_id; + } + } + } + else if (last_button_state[pad_index][button_id] && last_auto_repeat_button[pad_index] == button_id) + { + // We stopped pressing an auto-repeat button, so re-enable auto-repeat for other buttons. + last_auto_repeat_button[pad_index] = pad_button::pad_button_max_enum; + } + + last_button_state[pad_index][button_id] = pressed; + }; + while (!exit) { if (Emu.IsStopped()) @@ -179,46 +224,48 @@ namespace rsx } } - if (button_id < pad_button::pad_button_max_enum) + handle_button_press(button_id, button.m_pressed, pad_index); + + if (exit) + break; + } + + for (const AnalogStick& stick : pad->m_sticks) + { + u8 button_id = pad_button::pad_button_max_enum; + u8 release_id = pad_button::pad_button_max_enum; + + // Let's say sticks are only pressed if they are almost completely tilted. Otherwise navigation feels really wacky. + const bool pressed = stick.m_value < 30 || stick.m_value > 225; + + switch (stick.m_offset) { - if (button.m_pressed) - { - const bool is_auto_repeat_button = auto_repeat_buttons.contains(button_id); - - if (!last_button_state[pad_index][button_id]) - { - // The button was not pressed before, so this is a new button press. Reset auto-repeat. - timestamp[pad_index] = steady_clock::now(); - initial_timestamp[pad_index] = timestamp[pad_index]; - last_auto_repeat_button[pad_index] = is_auto_repeat_button ? button_id : pad_button::pad_button_max_enum; - on_button_pressed(static_cast(button_id)); - } - else if (is_auto_repeat_button) - { - if (last_auto_repeat_button[pad_index] == button_id - && input_timer.GetMsSince(initial_timestamp[pad_index]) > ms_threshold - && input_timer.GetMsSince(timestamp[pad_index]) > ms_interval) - { - // The auto-repeat button was pressed for at least the given threshold in ms and will trigger at an interval. - timestamp[pad_index] = steady_clock::now(); - on_button_pressed(static_cast(button_id)); - } - else if (last_auto_repeat_button[pad_index] == pad_button::pad_button_max_enum) - { - // An auto-repeat button was already pressed before and will now start triggering again after the next threshold. - last_auto_repeat_button[pad_index] = button_id; - } - } - } - else if (last_button_state[pad_index][button_id] && last_auto_repeat_button[pad_index] == button_id) - { - // We stopped pressing an auto-repeat button, so re-enable auto-repeat for other buttons. - last_auto_repeat_button[pad_index] = pad_button::pad_button_max_enum; - } - - last_button_state[pad_index][button_id] = button.m_pressed; + case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: + button_id = (stick.m_value <= 128) ? pad_button::ls_left : pad_button::ls_right; + release_id = (stick.m_value > 128) ? pad_button::ls_left : pad_button::ls_right; + break; + case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: + button_id = (stick.m_value <= 128) ? pad_button::ls_up : pad_button::ls_down; + release_id = (stick.m_value > 128) ? pad_button::ls_up : pad_button::ls_down; + break; + case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: + button_id = (stick.m_value <= 128) ? pad_button::rs_left : pad_button::rs_right; + release_id = (stick.m_value > 128) ? pad_button::rs_left : pad_button::rs_right; + break; + case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: + button_id = (stick.m_value <= 128) ? pad_button::rs_up : pad_button::rs_down; + release_id = (stick.m_value > 128) ? pad_button::rs_up : pad_button::rs_down; + break; + default: + break; } + // Release other direction on the same axis first + handle_button_press(release_id, false, pad_index); + + // Handle currently pressed stick direction + handle_button_press(button_id, pressed, pad_index); + if (exit) break; } diff --git a/rpcs3/Emu/RSX/Overlays/overlays.h b/rpcs3/Emu/RSX/Overlays/overlays.h index 2c8e577d25..75c897ef82 100644 --- a/rpcs3/Emu/RSX/Overlays/overlays.h +++ b/rpcs3/Emu/RSX/Overlays/overlays.h @@ -68,12 +68,30 @@ namespace rsx L3, R3, + ls_up, + ls_down, + ls_left, + ls_right, + rs_up, + rs_down, + rs_left, + rs_right, + pad_button_max_enum }; protected: Timer input_timer; - std::set auto_repeat_buttons = { pad_button::dpad_up, pad_button::dpad_down, pad_button::dpad_left, pad_button::dpad_right }; + std::set auto_repeat_buttons = { + pad_button::dpad_up, + pad_button::dpad_down, + pad_button::dpad_left, + pad_button::dpad_right, + pad_button::ls_up, + pad_button::ls_down, + pad_button::ls_left, + pad_button::ls_right + }; atomic_t exit = false; atomic_t m_interactive = false; atomic_t m_stop_pad_interception = false;