From 20c69a0e3e053f093def5b3f5b4fbfb96139c781 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Mon, 12 Apr 2021 23:09:23 +0200 Subject: [PATCH] overlays: make auto-repeat buttons configurable and properly reset the auto-repeat timer whenever a new button was pressed --- rpcs3/Emu/RSX/Overlays/overlay_osk.cpp | 9 ++++ rpcs3/Emu/RSX/Overlays/overlay_osk.h | 2 +- rpcs3/Emu/RSX/Overlays/overlays.cpp | 61 ++++++++++++++++---------- rpcs3/Emu/RSX/Overlays/overlays.h | 2 + 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp index f3c1874694..947e317d88 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp @@ -10,6 +10,15 @@ namespace rsx { namespace overlays { + osk_dialog::osk_dialog() + { + auto_repeat_buttons.insert(pad_button::L1); + auto_repeat_buttons.insert(pad_button::R1); + auto_repeat_buttons.insert(pad_button::cross); + auto_repeat_buttons.insert(pad_button::triangle); + auto_repeat_buttons.insert(pad_button::square); + } + void osk_dialog::Close(bool ok) { fade_animation.current = color4f(1.f); diff --git a/rpcs3/Emu/RSX/Overlays/overlay_osk.h b/rpcs3/Emu/RSX/Overlays/overlay_osk.h index 231026abcf..a90488d549 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_osk.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_osk.h @@ -78,7 +78,7 @@ namespace rsx std::vector m_panels; usz m_panel_index = 0; - osk_dialog() = default; + osk_dialog(); ~osk_dialog() override = default; void Create(const std::string& title, const std::u16string& message, char16_t* init_text, u32 charlimit, u32 prohibit_flags, u32 panel_flag, u32 first_view_panel) override; diff --git a/rpcs3/Emu/RSX/Overlays/overlays.cpp b/rpcs3/Emu/RSX/Overlays/overlays.cpp index 12c95e43d5..8ed0e31614 100644 --- a/rpcs3/Emu/RSX/Overlays/overlays.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlays.cpp @@ -51,10 +51,13 @@ namespace rsx std::array initial_timestamp; initial_timestamp.fill(steady_clock::now()); - std::array, CELL_PAD_MAX_PORT_NUM> button_state; - for (auto& state : button_state) + std::array last_auto_repeat_button; + last_auto_repeat_button.fill(pad_button::pad_button_max_enum); + + std::array, CELL_PAD_MAX_PORT_NUM> last_button_state; + for (auto& state : last_button_state) { - state.fill(true); + state.fill(false); } input_timer.Start(); @@ -90,7 +93,7 @@ namespace rsx for (auto &button : pad->m_buttons) { - u8 button_id = 255; + u8 button_id = pad_button::pad_button_max_enum; if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1) { switch (button.m_outKeyCode) @@ -148,34 +151,44 @@ namespace rsx } } - if (button_id < 255) + if (button_id < pad_button::pad_button_max_enum) { if (button.m_pressed) { - if (button_id < 4) // d-pad button + const bool is_auto_repeat_button = auto_repeat_buttons.contains(button_id); + + if (!last_button_state[pad_index][button_id]) { - if (!button_state[pad_index][button_id]) - { - // the d-pad button was not pressed before, so this is a new button press - timestamp[pad_index] = steady_clock::now(); - initial_timestamp[pad_index] = timestamp[pad_index]; - on_button_pressed(static_cast(button_id)); - } - else if (input_timer.GetMsSince(initial_timestamp[pad_index]) > ms_threshold && input_timer.GetMsSince(timestamp[pad_index]) > ms_interval) - { - // the d-pad 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 (!button_state[pad_index][button_id]) - { - // the button was not pressed before, so this is a new button press + // 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; } - button_state[pad_index][button_id] = button.m_pressed; + last_button_state[pad_index][button_id] = button.m_pressed; } if (exit) diff --git a/rpcs3/Emu/RSX/Overlays/overlays.h b/rpcs3/Emu/RSX/Overlays/overlays.h index 71877c740a..b54ff2dc13 100644 --- a/rpcs3/Emu/RSX/Overlays/overlays.h +++ b/rpcs3/Emu/RSX/Overlays/overlays.h @@ -8,6 +8,7 @@ #include "Utilities/Timer.h" #include +#include // Definition of user interface implementations @@ -69,6 +70,7 @@ namespace rsx 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 }; atomic_t exit = false; atomic_t thread_bits = 0;