overlays: add stick input to native dialogs

This commit is contained in:
Megamouse 2021-11-15 22:21:21 +01:00
parent 44b42f68fd
commit f6e04ffdd2
5 changed files with 111 additions and 38 deletions

View file

@ -437,6 +437,7 @@ namespace rsx
break; break;
} }
case pad_button::dpad_right: case pad_button::dpad_right:
case pad_button::ls_right:
{ {
u32 current_index = (selected_y * num_columns) + selected_x; u32 current_index = (selected_y * num_columns) + selected_x;
while (true) while (true)
@ -459,6 +460,7 @@ namespace rsx
break; break;
} }
case pad_button::dpad_left: case pad_button::dpad_left:
case pad_button::ls_left:
{ {
u32 current_index = (selected_y * num_columns) + selected_x; u32 current_index = (selected_y * num_columns) + selected_x;
while (current_index > 0) while (current_index > 0)
@ -483,6 +485,7 @@ namespace rsx
break; break;
} }
case pad_button::dpad_down: case pad_button::dpad_down:
case pad_button::ls_down:
{ {
u32 current_index = (selected_y * num_columns) + selected_x; u32 current_index = (selected_y * num_columns) + selected_x;
while (true) while (true)
@ -503,6 +506,7 @@ namespace rsx
break; break;
} }
case pad_button::dpad_up: case pad_button::dpad_up:
case pad_button::ls_up:
{ {
u32 current_index = (selected_y * num_columns) + selected_x; u32 current_index = (selected_y * num_columns) + selected_x;
while (current_index >= num_columns) while (current_index >= num_columns)

View file

@ -129,9 +129,11 @@ namespace rsx
close(true, true); close(true, true);
return; return;
case pad_button::dpad_up: case pad_button::dpad_up:
case pad_button::ls_up:
m_list->select_previous(); m_list->select_previous();
break; break;
case pad_button::dpad_down: case pad_button::dpad_down:
case pad_button::ls_down:
m_list->select_next(); m_list->select_next();
break; break;
case pad_button::L1: case pad_button::L1:

View file

@ -107,9 +107,11 @@ namespace rsx
close(true, true); close(true, true);
return; return;
case pad_button::dpad_up: case pad_button::dpad_up:
case pad_button::ls_up:
m_list->select_previous(); m_list->select_previous();
break; break;
case pad_button::dpad_down: case pad_button::dpad_down:
case pad_button::ls_down:
m_list->select_next(); m_list->select_next();
break; break;
case pad_button::L1: case pad_button::L1:

View file

@ -67,6 +67,51 @@ namespace rsx
input::SetIntercepted(true); 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<pad_button>(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<pad_button>(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) while (!exit)
{ {
if (Emu.IsStopped()) 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) case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
{ button_id = (stick.m_value <= 128) ? pad_button::ls_left : pad_button::ls_right;
const bool is_auto_repeat_button = auto_repeat_buttons.contains(button_id); release_id = (stick.m_value > 128) ? pad_button::ls_left : pad_button::ls_right;
break;
if (!last_button_state[pad_index][button_id]) case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
{ button_id = (stick.m_value <= 128) ? pad_button::ls_up : pad_button::ls_down;
// The button was not pressed before, so this is a new button press. Reset auto-repeat. release_id = (stick.m_value > 128) ? pad_button::ls_up : pad_button::ls_down;
timestamp[pad_index] = steady_clock::now(); break;
initial_timestamp[pad_index] = timestamp[pad_index]; case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
last_auto_repeat_button[pad_index] = is_auto_repeat_button ? button_id : pad_button::pad_button_max_enum; button_id = (stick.m_value <= 128) ? pad_button::rs_left : pad_button::rs_right;
on_button_pressed(static_cast<pad_button>(button_id)); release_id = (stick.m_value > 128) ? pad_button::rs_left : pad_button::rs_right;
} break;
else if (is_auto_repeat_button) case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
{ button_id = (stick.m_value <= 128) ? pad_button::rs_up : pad_button::rs_down;
if (last_auto_repeat_button[pad_index] == button_id release_id = (stick.m_value > 128) ? pad_button::rs_up : pad_button::rs_down;
&& input_timer.GetMsSince(initial_timestamp[pad_index]) > ms_threshold break;
&& input_timer.GetMsSince(timestamp[pad_index]) > ms_interval) default:
{ break;
// 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<pad_button>(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;
} }
// 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) if (exit)
break; break;
} }

View file

@ -68,12 +68,30 @@ namespace rsx
L3, L3,
R3, R3,
ls_up,
ls_down,
ls_left,
ls_right,
rs_up,
rs_down,
rs_left,
rs_right,
pad_button_max_enum pad_button_max_enum
}; };
protected: protected:
Timer input_timer; Timer input_timer;
std::set<u8> auto_repeat_buttons = { pad_button::dpad_up, pad_button::dpad_down, pad_button::dpad_left, pad_button::dpad_right }; std::set<u8> 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<bool> exit = false; atomic_t<bool> exit = false;
atomic_t<bool> m_interactive = false; atomic_t<bool> m_interactive = false;
atomic_t<bool> m_stop_pad_interception = false; atomic_t<bool> m_stop_pad_interception = false;