From b2484838418a523c6f8791b316eb1d56e937d461 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 26 Aug 2023 10:07:28 +0200 Subject: [PATCH] input: implement pressure intensity deadzone --- rpcs3/Emu/Io/PadHandler.cpp | 13 ++++- rpcs3/Emu/Io/pad_config.h | 1 + rpcs3/Emu/Io/pad_types.cpp | 2 +- rpcs3/Emu/Io/pad_types.h | 2 +- rpcs3/Input/evdev_joystick_handler.cpp | 13 ++++- rpcs3/Input/keyboard_pad_handler.cpp | 23 ++++++-- rpcs3/Input/keyboard_pad_handler.h | 3 +- rpcs3/rpcs3qt/pad_settings_dialog.cpp | 8 +++ rpcs3/rpcs3qt/pad_settings_dialog.ui | 72 ++++++++++++++++---------- rpcs3/rpcs3qt/tooltips.h | 1 + 10 files changed, 98 insertions(+), 40 deletions(-) diff --git a/rpcs3/Emu/Io/PadHandler.cpp b/rpcs3/Emu/Io/PadHandler.cpp index b04e2b6f79..af344da494 100644 --- a/rpcs3/Emu/Io/PadHandler.cpp +++ b/rpcs3/Emu/Io/PadHandler.cpp @@ -578,7 +578,8 @@ void PadHandlerBase::get_mapping(const pad_ensemble& binding) // Find out if special buttons are pressed (introduced by RPCS3). // These buttons will have a delay of one cycle, but whatever. - const bool adjust_pressure = pad->get_pressure_intensity_enabled(cfg->pressure_intensity_toggle_mode.get()); + const bool adjust_pressure = pad->get_pressure_intensity_button_active(cfg->pressure_intensity_toggle_mode.get()); + const u32 pressure_intensity_deadzone = cfg->pressure_intensity_deadzone.get(); // Translate any corresponding keycodes to our normal DS3 buttons and triggers for (Button& button : pad->m_buttons) @@ -600,9 +601,17 @@ void PadHandlerBase::get_mapping(const pad_ensemble& binding) { val = pad->m_pressure_intensity; } + else if (pressure_intensity_deadzone > 0) + { + // Ignore triggers, since they have their own deadzones + if (!get_is_left_trigger(device, code) && !get_is_right_trigger(device, code)) + { + val = NormalizeDirectedInput(val, pressure_intensity_deadzone, 255); + } + } value = std::max(value, val); - pressed = true; + pressed = value > 0; } } diff --git a/rpcs3/Emu/Io/pad_config.h b/rpcs3/Emu/Io/pad_config.h index bf9bcf7e91..614b394237 100644 --- a/rpcs3/Emu/Io/pad_config.h +++ b/rpcs3/Emu/Io/pad_config.h @@ -62,6 +62,7 @@ struct cfg_pad final : cfg::node cfg::string pressure_intensity_button{ this, "Pressure Intensity Button", "" }; cfg::uint<0, 100> pressure_intensity{ this, "Pressure Intensity Percent", 50 }; cfg::_bool pressure_intensity_toggle_mode{ this, "Pressure Intensity Toggle Mode", false }; + cfg::uint<0, 255> pressure_intensity_deadzone{ this, "Pressure Intensity Deadzone", 0 }; cfg::uint<0, 200> lstickmultiplier{ this, "Left Stick Multiplier", 100 }; cfg::uint<0, 200> rstickmultiplier{ this, "Right Stick Multiplier", 100 }; diff --git a/rpcs3/Emu/Io/pad_types.cpp b/rpcs3/Emu/Io/pad_types.cpp index b62fee2f57..43ab5ffcb7 100644 --- a/rpcs3/Emu/Io/pad_types.cpp +++ b/rpcs3/Emu/Io/pad_types.cpp @@ -132,7 +132,7 @@ u32 get_axis_keycode(u32 offset, u16 value) } } -bool Pad::get_pressure_intensity_enabled(bool is_toggle_mode) +bool Pad::get_pressure_intensity_button_active(bool is_toggle_mode) { if (m_pressure_intensity_button_index < 0) { diff --git a/rpcs3/Emu/Io/pad_types.h b/rpcs3/Emu/Io/pad_types.h index 916f30a559..abc7dac077 100644 --- a/rpcs3/Emu/Io/pad_types.h +++ b/rpcs3/Emu/Io/pad_types.h @@ -430,7 +430,7 @@ struct Pad bool m_pressure_intensity_toggled{}; // Whether the sensitivity is toggled on or off. u8 m_pressure_intensity{127}; // 0-255 bool m_adjust_pressure_last{}; // only used in keyboard_pad_handler - bool get_pressure_intensity_enabled(bool is_toggle_mode); + bool get_pressure_intensity_button_active(bool is_toggle_mode); // Cable State: 0 - 1 plugged in ? u8 m_cable_state{0}; diff --git a/rpcs3/Input/evdev_joystick_handler.cpp b/rpcs3/Input/evdev_joystick_handler.cpp index 474c92ed3e..c0f616aa3b 100644 --- a/rpcs3/Input/evdev_joystick_handler.cpp +++ b/rpcs3/Input/evdev_joystick_handler.cpp @@ -1079,7 +1079,8 @@ void evdev_joystick_handler::apply_input_events(const std::shared_ptr& pad) // Find out if special buttons are pressed (introduced by RPCS3). // These buttons will have a delay of one cycle, but whatever. - const bool adjust_pressure = pad->get_pressure_intensity_enabled(cfg->pressure_intensity_toggle_mode.get()); + const bool adjust_pressure = pad->get_pressure_intensity_button_active(cfg->pressure_intensity_toggle_mode.get()); + const u32 pressure_intensity_deadzone = cfg->pressure_intensity_deadzone.get(); const auto update_values = [&](bool& pressed, u16& final_value, bool is_stick_value, u32 code, u16 val) { @@ -1095,10 +1096,18 @@ void evdev_joystick_handler::apply_input_events(const std::shared_ptr& pad) { val = pad->m_pressure_intensity; } + else if (pressure_intensity_deadzone > 0) + { + // Ignore triggers, since they have their own deadzones + if (!get_is_left_trigger(m_dev, code) && !get_is_right_trigger(m_dev, code)) + { + val = NormalizeDirectedInput(val, pressure_intensity_deadzone, 255); + } + } } - pressed = true; final_value = std::max(final_value, val); + pressed = final_value > 0; } }; diff --git a/rpcs3/Input/keyboard_pad_handler.cpp b/rpcs3/Input/keyboard_pad_handler.cpp index 713162d4fa..a341b50532 100644 --- a/rpcs3/Input/keyboard_pad_handler.cpp +++ b/rpcs3/Input/keyboard_pad_handler.cpp @@ -112,7 +112,7 @@ void keyboard_pad_handler::Key(const u32 code, bool pressed, u16 value) } } - const bool adjust_pressure = pad.get_pressure_intensity_enabled(m_pressure_intensity_toggle_mode); + const bool adjust_pressure = pad.get_pressure_intensity_button_active(m_pressure_intensity_toggle_mode); const bool adjust_pressure_changed = pad.m_adjust_pressure_last != adjust_pressure; if (adjust_pressure_changed) @@ -153,16 +153,28 @@ void keyboard_pad_handler::Key(const u32 code, bool pressed, u16 value) if (update_button) { - button.m_pressed = button.m_actual_value > 0; - - if (button.m_pressed) + if (button.m_actual_value > 0) { // Modify pressure if necessary if the button was pressed - button.m_value = adjust_pressure ? pad.m_pressure_intensity : button.m_actual_value; + if (adjust_pressure) + { + button.m_value = pad.m_pressure_intensity; + } + else if (m_pressure_intensity_deadzone > 0) + { + button.m_value = NormalizeDirectedInput(button.m_actual_value, m_pressure_intensity_deadzone, 255); + } + else + { + button.m_value = button.m_actual_value; + } + + button.m_pressed = button.m_value > 0; } else { button.m_value = 0; + button.m_pressed = false; } } } @@ -886,6 +898,7 @@ bool keyboard_pad_handler::bindPadToDevice(std::shared_ptr pad, u8 player_i m_l_stick_multiplier = cfg->lstickmultiplier; m_r_stick_multiplier = cfg->rstickmultiplier; m_pressure_intensity_toggle_mode = cfg->pressure_intensity_toggle_mode.get(); + m_pressure_intensity_deadzone = cfg->pressure_intensity_deadzone.get(); const auto find_keys = [this](const cfg::string& name) { diff --git a/rpcs3/Input/keyboard_pad_handler.h b/rpcs3/Input/keyboard_pad_handler.h index 444b772bd4..60ea9c57f6 100644 --- a/rpcs3/Input/keyboard_pad_handler.h +++ b/rpcs3/Input/keyboard_pad_handler.h @@ -116,7 +116,8 @@ private: steady_clock::time_point m_button_time; f32 m_analog_lerp_factor = 1.0f; f32 m_trigger_lerp_factor = 1.0f; - bool m_pressure_intensity_toggle_mode{}; + bool m_pressure_intensity_toggle_mode = false; + u32 m_pressure_intensity_deadzone = 0; // Stick Movements steady_clock::time_point m_stick_time; diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.cpp b/rpcs3/rpcs3qt/pad_settings_dialog.cpp index 717ca4c8b6..88545214b1 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/pad_settings_dialog.cpp @@ -1178,6 +1178,11 @@ void pad_settings_dialog::UpdateLabels(bool is_reset) // Update pressure sensitivity toggle mode ui->cb_pressure_intensity_toggle_mode->setChecked(cfg.pressure_intensity_toggle_mode.get()); + // Update pressure sensitivity deadzone + range = cfg.pressure_intensity_deadzone.to_list(); + ui->pressure_intensity_deadzone->setRange(std::stoi(range.front()), std::stoi(range.back())); + ui->pressure_intensity_deadzone->setValue(cfg.pressure_intensity_deadzone.get()); + // Apply stored/default LED settings to the device m_enable_led = m_handler->has_led(); SetPadData(0, 0); @@ -1813,6 +1818,8 @@ void pad_settings_dialog::ApplyCurrentPlayerConfig(int new_player_id) cfg.pressure_intensity_toggle_mode.set(ui->cb_pressure_intensity_toggle_mode->isChecked()); } + cfg.pressure_intensity_deadzone.set(ui->pressure_intensity_deadzone->value()); + if (m_handler->m_type == pad_handler::keyboard) { const int mouse_move_mode = ui->mouse_movement->currentData().toInt(); @@ -1961,6 +1968,7 @@ void pad_settings_dialog::SubscribeTooltips() const Tooltips tooltips; SubscribeTooltip(ui->gb_pressure_intensity, tooltips.gamepad_settings.pressure_intensity); + SubscribeTooltip(ui->gb_pressure_intensity_deadzone, tooltips.gamepad_settings.pressure_deadzone); SubscribeTooltip(ui->gb_squircle, tooltips.gamepad_settings.squircle_factor); SubscribeTooltip(ui->gb_stick_multi, tooltips.gamepad_settings.stick_multiplier); SubscribeTooltip(ui->gb_kb_stick_multi, tooltips.gamepad_settings.stick_multiplier); diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.ui b/rpcs3/rpcs3qt/pad_settings_dialog.ui index 6000014044..b7c698ced7 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.ui +++ b/rpcs3/rpcs3qt/pad_settings_dialog.ui @@ -717,6 +717,22 @@ + + + + Pressure Sensitivity Deadzone + + + + + + Qt::Horizontal + + + + + + @@ -850,34 +866,6 @@ - - - - Stick Preview - - - - 5 - - - 5 - - - 5 - - - 5 - - - - - Show Emulated Values - - - - - - @@ -2369,6 +2357,34 @@ + + + + Stick Preview + + + + 5 + + + 5 + + + 5 + + + 5 + + + + + Show Emulated Values + + + + + + diff --git a/rpcs3/rpcs3qt/tooltips.h b/rpcs3/rpcs3qt/tooltips.h index 7850177f9e..1982a108e0 100644 --- a/rpcs3/rpcs3qt/tooltips.h +++ b/rpcs3/rpcs3qt/tooltips.h @@ -270,6 +270,7 @@ public: const QString sdl = tr("The SDL handler supports a variety of controllers across different platforms."); const QString pressure_intensity = tr("Controls the intensity of pressure sensitive buttons while this special button is pressed.
Enable \"Toggle\" if you want to toggle the intensity on button press instead.
Use the percentage to change how hard you want to press a button."); + const QString pressure_deadzone = tr("Controls the deadzone of pressure sensitive buttons. It determines how far the button has to be pressed until it is recognized by the game. The resulting range will be projected onto the full button sensitivity range."); const QString squircle_factor = tr("The actual DualShock 3's stick range is not circular but formed like a rounded square (or squircle) which represents the maximum range of the emulated sticks. You can use the squircle values to modify the stick input if your sticks can't reach the corners of that range. A value of 0 does not apply any so called squircling. A value of 8000 is usually recommended."); const QString stick_multiplier = tr("The stick multipliers can be used to change the sensitivity of your stick movements.
The default setting is 1 and represents normal input."); const QString stick_deadzones = tr("A stick's deadzone determines how far the stick has to be moved until it is fully recognized by the game. The resulting range will be projected onto the full input range in order to give you a smooth experience. Movement inside the deadzone is actually simulated as a real DualShock 3's deadzone of ~13%, so don't worry if there is still movement shown in the emulated stick preview.");