From f5d64239cbc5afa89addc0caa281a50558661865 Mon Sep 17 00:00:00 2001 From: kalaposfos13 <153381648+kalaposfos13@users.noreply.github.com> Date: Wed, 5 Feb 2025 16:26:14 +0100 Subject: [PATCH] Add outer deadzone config (#2348) * Add outer deadzone * Documentation * Add max outer deadzone to the controller remapping GUI * Fix init values * fix GUI saving syntax --- src/common/config.cpp | 4 +- src/input/input_handler.cpp | 73 ++++++++++++++++++++++----------- src/qt_gui/control_settings.cpp | 4 +- src/qt_gui/kbm_help_dialog.h | 7 ++-- 4 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/common/config.cpp b/src/common/config.cpp index d9dfb861f..86e28285d 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -1008,8 +1008,8 @@ axis_right_x = axis_right_x axis_right_y = axis_right_y # Range of deadzones: 1 (almost none) to 127 (max) -analog_deadzone = leftjoystick, 2 -analog_deadzone = rightjoystick, 2 +analog_deadzone = leftjoystick, 2, 127 +analog_deadzone = rightjoystick, 2, 127 )"; } std::filesystem::path GetFoolproofKbmConfigFile(const std::string& game_id) { diff --git a/src/input/input_handler.cpp b/src/input/input_handler.cpp index 5394e4818..9c51ec8be 100644 --- a/src/input/input_handler.cpp +++ b/src/input/input_handler.cpp @@ -55,7 +55,8 @@ Don't be an idiot and test only the changed part expecting everything else to no */ bool leftjoystick_halfmode = false, rightjoystick_halfmode = false; -int leftjoystick_deadzone, rightjoystick_deadzone, lefttrigger_deadzone, righttrigger_deadzone; +std::pair leftjoystick_deadzone, rightjoystick_deadzone, lefttrigger_deadzone, + righttrigger_deadzone; std::list> pressed_keys; std::list toggled_keys; @@ -208,10 +209,10 @@ void ParseInputConfig(const std::string game_id = "") { float mouse_speed = 1; float mouse_speed_offset = 0.125; - leftjoystick_deadzone = 1; - rightjoystick_deadzone = 1; - lefttrigger_deadzone = 1; - righttrigger_deadzone = 1; + leftjoystick_deadzone = {1, 127}; + rightjoystick_deadzone = {1, 127}; + lefttrigger_deadzone = {1, 127}; + righttrigger_deadzone = {1, 127}; int lineCount = 0; @@ -298,26 +299,45 @@ void ParseInputConfig(const std::string game_id = "") { continue; } else if (output_string == "analog_deadzone") { std::stringstream ss(input_string); - std::string device; - int deadzone; - std::getline(ss, device, ','); - ss >> deadzone; - if (ss.fail()) { - LOG_WARNING(Input, "Failed to parse deadzone config from line: {}", line); + std::string device, inner_deadzone_str, outer_deadzone_str; + + if (!std::getline(ss, device, ',') || !std::getline(ss, inner_deadzone_str, ',') || + !std::getline(ss, outer_deadzone_str)) { + LOG_WARNING(Input, "Malformed deadzone config at line {}: \"{}\"", lineCount, line); continue; - } else { - LOG_DEBUG(Input, "Parsed deadzone: {} {}", device, deadzone); } - if (device == "leftjoystick") { - leftjoystick_deadzone = deadzone; - } else if (device == "rightjoystick") { - rightjoystick_deadzone = deadzone; - } else if (device == "l2") { - lefttrigger_deadzone = deadzone; - } else if (device == "r2") { - righttrigger_deadzone = deadzone; + + auto parseInt = [](const std::string& s) -> std::optional { + try { + return std::stoi(s); + } catch (...) { + return std::nullopt; + } + }; + + auto inner_deadzone = parseInt(inner_deadzone_str); + auto outer_deadzone = parseInt(outer_deadzone_str); + + if (!inner_deadzone || !outer_deadzone) { + LOG_WARNING(Input, "Invalid deadzone values at line {}: \"{}\"", lineCount, line); + continue; + } + + std::pair deadzone = {*inner_deadzone, *outer_deadzone}; + + static std::unordered_map&> deadzone_map = { + {"leftjoystick", leftjoystick_deadzone}, + {"rightjoystick", rightjoystick_deadzone}, + {"l2", lefttrigger_deadzone}, + {"r2", righttrigger_deadzone}, + }; + + if (auto it = deadzone_map.find(device); it != deadzone_map.end()) { + it->second = deadzone; + LOG_DEBUG(Input, "Parsed deadzone: {} {} {}", device, inner_deadzone_str, + outer_deadzone_str); } else { - LOG_WARNING(Input, "Invalid axis name at line: {}, data: \"{}\", skipping line.", + LOG_WARNING(Input, "Invalid axis name at line {}: \"{}\", skipping line.", lineCount, line); } continue; @@ -493,9 +513,14 @@ void ControllerOutput::FinalizeUpdate() { // avoid double-updating axes, but don't skip directional button bindings float multiplier = 1.0; int deadzone = 0; - auto ApplyDeadzone = [](s16* value, int deadzone) { - if (std::abs(*value) <= deadzone) { + auto ApplyDeadzone = [](s16* value, std::pair deadzone) { + if (std::abs(*value) <= deadzone.first || deadzone.first == deadzone.second) { *value = 0; + } else { + *value = (*value >= 0 ? 1 : -1) * + std::clamp((int)((128.0 * (std::abs(*value) - deadzone.first)) / + (float)(deadzone.second - deadzone.first)), + 0, 128); } }; Axis c_axis = GetAxisFromSDLAxis(axis); diff --git a/src/qt_gui/control_settings.cpp b/src/qt_gui/control_settings.cpp index 0374d2049..a07d36292 100644 --- a/src/qt_gui/control_settings.cpp +++ b/src/qt_gui/control_settings.cpp @@ -220,10 +220,10 @@ void ControlSettings::SaveControllerConfig(bool CloseOnSave) { lines.push_back("# Range of deadzones: 1 (almost none) to 127 (max)"); std::string deadzonevalue = std::to_string(ui->LeftDeadzoneSlider->value()); - lines.push_back("analog_deadzone = leftjoystick, " + deadzonevalue); + lines.push_back("analog_deadzone = leftjoystick, " + deadzonevalue + ", 127"); deadzonevalue = std::to_string(ui->RightDeadzoneSlider->value()); - lines.push_back("analog_deadzone = rightjoystick, " + deadzonevalue); + lines.push_back("analog_deadzone = rightjoystick, " + deadzonevalue + ", 127"); std::vector save; bool CurrentLineEmpty = false, LastLineEmpty = false; diff --git a/src/qt_gui/kbm_help_dialog.h b/src/qt_gui/kbm_help_dialog.h index c482d2b5c..3e39d4397 100644 --- a/src/qt_gui/kbm_help_dialog.h +++ b/src/qt_gui/kbm_help_dialog.h @@ -167,9 +167,10 @@ You can find these here, with detailed comments, examples and suggestions for mo You can make an input toggleable with this, for example: Let's say we want to be able to toggle l1 with t. You can then bind l1 to a key you won't use, like kpenter, then bind t to toggle that, so you will end up with this: l1 = kpenter; key_toggle = t, kpenter; -'analog_deadzone' = , ; - value goes from 1 to 127 (no deadzone to max deadzone) - devices: leftjoystick, rightjoystick, l2, r2 +'analog_deadzone' = , , ; + Values go from 1 to 127 (no deadzone to max deadzone), first is the inner, second is the outer deadzone + If you only want inner or outer deadzone, set the other to 1 or 127, respectively + Devices: leftjoystick, rightjoystick, l2, r2 )"; } }; \ No newline at end of file