From 6f9caa6b12b48dbbf3c11b544fd77dd2e2ebe39b Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 11 Jan 2025 18:52:16 +1000 Subject: [PATCH] InputManager: Add proper binds for vibration motors Instead of the janky "vibration capabilities" flag. Fixes the "Clear Mappings" button not applying to vibration motors. --- src/core/analog_controller.cpp | 11 ++- src/core/analog_joystick.cpp | 3 +- src/core/controller.cpp | 9 +-- src/core/controller.h | 9 --- src/core/digital_controller.cpp | 21 ++---- src/core/guncon.cpp | 4 +- src/core/input_types.h | 2 +- src/core/jogcon.cpp | 7 +- src/core/justifier.cpp | 18 ++--- src/core/negcon.cpp | 4 +- src/core/negcon_rumble.cpp | 11 ++- src/core/playstation_mouse.cpp | 3 +- .../controllerbindingwidgets.cpp | 71 +++--------------- src/util/imgui_glyph_ranges.inl | 2 +- src/util/input_manager.cpp | 74 ++++++++----------- 15 files changed, 81 insertions(+), 168 deletions(-) diff --git a/src/core/analog_controller.cpp b/src/core/analog_controller.cpp index f0a917259..8cf9cf145 100644 --- a/src/core/analog_controller.cpp +++ b/src/core/analog_controller.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin and contributors. +// SPDX-FileCopyrightText: 2019-2025 Connor McLaughlin and contributors. // SPDX-License-Identifier: CC-BY-NC-ND-4.0 #include "analog_controller.h" @@ -757,6 +757,8 @@ static const Controller::ControllerBindingInfo s_binding_info[] = { static_cast(AnalogController::Button::Count) + static_cast(halfaxis), \ InputBindingInfo::Type::HalfAxis, \ genb} +#define MOTOR(name, display_name, icon_name, index, genb) \ + {name, display_name, icon_name, index, InputBindingInfo::Type::Motor, genb} // clang-format off BUTTON("Up", TRANSLATE_NOOP("AnalogController", "D-Pad Up"), ICON_PF_DPAD_UP, AnalogController::Button::Up, GenericInputBinding::DPadUp), @@ -785,8 +787,12 @@ static const Controller::ControllerBindingInfo s_binding_info[] = { AXIS("RRight", TRANSLATE_NOOP("AnalogController", "Right Stick Right"), ICON_PF_RIGHT_ANALOG_RIGHT, AnalogController::HalfAxis::RRight, GenericInputBinding::RightStickRight), AXIS("RDown", TRANSLATE_NOOP("AnalogController", "Right Stick Down"), ICON_PF_RIGHT_ANALOG_DOWN, AnalogController::HalfAxis::RDown, GenericInputBinding::RightStickDown), AXIS("RUp", TRANSLATE_NOOP("AnalogController", "Right Stick Up"), ICON_PF_RIGHT_ANALOG_UP, AnalogController::HalfAxis::RUp, GenericInputBinding::RightStickUp), + + MOTOR("LargeMotor", TRANSLATE_NOOP("AnalogController", "Large Motor"), ICON_PF_GEARS_OPTIONS_SETTINGS, 0, GenericInputBinding::LargeMotor), + MOTOR("SmallMotor", TRANSLATE_NOOP("AnalogController", "Small Motor"), ICON_PF_GEARS_OPTIONS_SETTINGS, 1, GenericInputBinding::SmallMotor), // clang-format on +#undef MOTOR #undef AXIS #undef BUTTON }; @@ -844,8 +850,7 @@ const Controller::ControllerInfo AnalogController::INFO = {ControllerType::Analo TRANSLATE_NOOP("ControllerType", "Analog Controller"), ICON_PF_GAMEPAD_ALT, s_binding_info, - s_settings, - Controller::VibrationCapabilities::LargeSmallMotors}; + s_settings}; void AnalogController::LoadSettings(const SettingsInterface& si, const char* section, bool initial) { diff --git a/src/core/analog_joystick.cpp b/src/core/analog_joystick.cpp index 204af5af7..ac87d5540 100644 --- a/src/core/analog_joystick.cpp +++ b/src/core/analog_joystick.cpp @@ -412,8 +412,7 @@ const Controller::ControllerInfo AnalogJoystick::INFO = {ControllerType::AnalogJ TRANSLATE_NOOP("ControllerType", "Analog Joystick"), ICON_PF_GAMEPAD, s_binding_info, - s_settings, - Controller::VibrationCapabilities::NoVibration}; + s_settings}; void AnalogJoystick::LoadSettings(const SettingsInterface& si, const char* section, bool initial) { diff --git a/src/core/controller.cpp b/src/core/controller.cpp index a7f106fa2..1218dbd1c 100644 --- a/src/core/controller.cpp +++ b/src/core/controller.cpp @@ -19,13 +19,8 @@ #include "fmt/format.h" -static const Controller::ControllerInfo s_none_info = {ControllerType::None, - "None", - TRANSLATE_NOOP("ControllerType", "Not Connected"), - nullptr, - {}, - {}, - Controller::VibrationCapabilities::NoVibration}; +static const Controller::ControllerInfo s_none_info = { + ControllerType::None, "None", TRANSLATE_NOOP("ControllerType", "Not Connected"), nullptr, {}, {}}; static const Controller::ControllerInfo* s_controller_info[] = { &s_none_info, diff --git a/src/core/controller.h b/src/core/controller.h index 9ff91a88c..0d3e8df27 100644 --- a/src/core/controller.h +++ b/src/core/controller.h @@ -23,14 +23,6 @@ class HostInterface; class Controller { public: - enum class VibrationCapabilities : u8 - { - NoVibration, - LargeSmallMotors, - SingleMotor, - Count - }; - struct ControllerBindingInfo { const char* name; @@ -49,7 +41,6 @@ public: const char* icon_name; std::span bindings; std::span settings; - VibrationCapabilities vibration_caps; /// Returns localized controller type name. const char* GetDisplayName() const; diff --git a/src/core/digital_controller.cpp b/src/core/digital_controller.cpp index 1a4a11f6a..cc5384cba 100644 --- a/src/core/digital_controller.cpp +++ b/src/core/digital_controller.cpp @@ -164,9 +164,7 @@ std::unique_ptr DigitalController::Create(u32 index, Controll static const Controller::ControllerBindingInfo s_binding_info[] = { #define BUTTON(name, display_name, icon_name, button, genb) \ - { \ - name, display_name, icon_name, static_cast(button), InputBindingInfo::Type::Button, genb \ - } + {name, display_name, icon_name, static_cast(button), InputBindingInfo::Type::Button, genb} // clang-format off BUTTON("Up", TRANSLATE_NOOP("DigitalController", "D-Pad Up"), ICON_PF_DPAD_UP, DigitalController::Button::Up, GenericInputBinding::DPadUp), @@ -193,14 +191,11 @@ const Controller::ControllerInfo DigitalController::INFO = {ControllerType::Digi TRANSLATE_NOOP("ControllerType", "Digital Controller"), ICON_PF_GAMEPAD_ALT, s_binding_info, - {}, - Controller::VibrationCapabilities::NoVibration}; + {}}; static const Controller::ControllerBindingInfo s_popn_binding_info[] = { #define BUTTON(name, display_name, icon_name, button, genb) \ - { \ - name, display_name, icon_name, static_cast(button), InputBindingInfo::Type::Button, genb \ - } + {name, display_name, icon_name, static_cast(button), InputBindingInfo::Type::Button, genb} // clang-format off BUTTON("LeftWhite", TRANSLATE_NOOP("PopnController", "Left White"), ICON_PF_BUTTON_TRIANGLE, DigitalController::Button::Triangle, GenericInputBinding::Triangle), @@ -222,14 +217,11 @@ const Controller::ControllerInfo DigitalController::INFO_POPN = {ControllerType: TRANSLATE_NOOP("ControllerType", "Pop'n Controller"), ICON_PF_GAMEPAD_ALT, s_popn_binding_info, - {}, - Controller::VibrationCapabilities::NoVibration}; + {}}; static const Controller::ControllerBindingInfo s_ddgo_binding_info[] = { #define BUTTON(name, display_name, icon_name, button, genb) \ - { \ - name, display_name, icon_name, static_cast(button), InputBindingInfo::Type::Button, genb \ - } + {name, display_name, icon_name, static_cast(button), InputBindingInfo::Type::Button, genb} // clang-format off BUTTON("Select", TRANSLATE_NOOP("DDGoController", "Select"), ICON_PF_SELECT_SHARE, DigitalController::Button::Select, GenericInputBinding::Select), @@ -255,5 +247,4 @@ const Controller::ControllerInfo DigitalController::INFO_DDGO = { TRANSLATE_NOOP("ControllerType", "Densha de Go! Controller"), ICON_PF_GAMEPAD_ALT, s_ddgo_binding_info, - {}, - Controller::VibrationCapabilities::NoVibration}; + {}}; diff --git a/src/core/guncon.cpp b/src/core/guncon.cpp index 88ef2ede7..45d870b2b 100644 --- a/src/core/guncon.cpp +++ b/src/core/guncon.cpp @@ -304,8 +304,8 @@ static const SettingInfo s_settings[] = { "%.0f%%", nullptr, 100.0f}}; const Controller::ControllerInfo GunCon::INFO = { - ControllerType::GunCon, "GunCon", TRANSLATE_NOOP("ControllerType", "GunCon"), ICON_PF_LIGHT_GUN, - s_binding_info, s_settings, Controller::VibrationCapabilities::NoVibration}; + ControllerType::GunCon, "GunCon", TRANSLATE_NOOP("ControllerType", "GunCon"), + ICON_PF_LIGHT_GUN, s_binding_info, s_settings}; void GunCon::LoadSettings(const SettingsInterface& si, const char* section, bool initial) { diff --git a/src/core/input_types.h b/src/core/input_types.h index 0e805759e..9bead60a7 100644 --- a/src/core/input_types.h +++ b/src/core/input_types.h @@ -65,8 +65,8 @@ enum class GenericInputBinding : u8 R1, // RB on XBox pads. R2, // Right trigger on Xbox pads. - SmallMotor, // High frequency vibration. LargeMotor, // Low frequency vibration. + SmallMotor, // High frequency vibration. Count, }; diff --git a/src/core/jogcon.cpp b/src/core/jogcon.cpp index 391833218..ab236a395 100644 --- a/src/core/jogcon.cpp +++ b/src/core/jogcon.cpp @@ -632,6 +632,9 @@ static const Controller::ControllerBindingInfo s_binding_info[] = { // clang-format on + {"Motor", TRANSLATE_NOOP("JogCon", "Vibration Motor"), nullptr, 0u, InputBindingInfo::Type::Motor, + GenericInputBinding::LargeMotor}, + {"ForceFeedbackDevice", TRANSLATE_NOOP("JogCon", "Force Feedback Device"), nullptr, static_cast(JogCon::Button::MaxCount) + static_cast(JogCon::HalfAxis::MaxCount), InputBindingInfo::Type::Device, GenericInputBinding::Unknown}, @@ -661,5 +664,5 @@ static const SettingInfo s_settings[] = { }; const Controller::ControllerInfo JogCon::INFO = { - ControllerType::JogCon, "JogCon", TRANSLATE_NOOP("ControllerType", "JogCon"), ICON_PF_STEERING_WHEEL, - s_binding_info, s_settings, Controller::VibrationCapabilities::SingleMotor}; + ControllerType::JogCon, "JogCon", TRANSLATE_NOOP("ControllerType", "JogCon"), + ICON_PF_STEERING_WHEEL, s_binding_info, s_settings}; diff --git a/src/core/justifier.cpp b/src/core/justifier.cpp index 3c85a9254..211b394c7 100644 --- a/src/core/justifier.cpp +++ b/src/core/justifier.cpp @@ -327,13 +327,9 @@ std::unique_ptr Justifier::Create(u32 index) static const Controller::ControllerBindingInfo s_binding_info[] = { #define BUTTON(name, display_name, icon_name, binding, genb) \ - { \ - name, display_name, icon_name, static_cast(binding), InputBindingInfo::Type::Button, genb \ - } + {name, display_name, icon_name, static_cast(binding), InputBindingInfo::Type::Button, genb} #define HALFAXIS(name, display_name, icon_name, binding, genb) \ - { \ - name, display_name, icon_name, static_cast(binding), InputBindingInfo::Type::HalfAxis, genb \ - } + {name, display_name, icon_name, static_cast(binding), InputBindingInfo::Type::HalfAxis, genb} // clang-format off {"Pointer", TRANSLATE_NOOP("Justifier", "Pointer/Aiming"), ICON_PF_MOUSE, static_cast(Justifier::Binding::ButtonCount), InputBindingInfo::Type::Pointer, GenericInputBinding::Unknown}, @@ -394,13 +390,9 @@ static const SettingInfo s_settings[] = { "5", "0", "80", "1", "%u", nullptr, 0.0f}, }; -const Controller::ControllerInfo Justifier::INFO = {ControllerType::Justifier, - "Justifier", - TRANSLATE_NOOP("ControllerType", "Justifier"), - ICON_PF_LIGHT_GUN, - s_binding_info, - s_settings, - Controller::VibrationCapabilities::NoVibration}; +const Controller::ControllerInfo Justifier::INFO = { + ControllerType::Justifier, "Justifier", TRANSLATE_NOOP("ControllerType", "Justifier"), + ICON_PF_LIGHT_GUN, s_binding_info, s_settings}; void Justifier::LoadSettings(const SettingsInterface& si, const char* section, bool initial) { diff --git a/src/core/negcon.cpp b/src/core/negcon.cpp index 544c8d923..1f01553eb 100644 --- a/src/core/negcon.cpp +++ b/src/core/negcon.cpp @@ -343,8 +343,8 @@ static const SettingInfo s_settings[] = { }; const Controller::ControllerInfo NeGcon::INFO = { - ControllerType::NeGcon, "NeGcon", TRANSLATE_NOOP("ControllerType", "NeGcon"), ICON_PF_GAMEPAD, - s_binding_info, s_settings, Controller::VibrationCapabilities::NoVibration}; + ControllerType::NeGcon, "NeGcon", TRANSLATE_NOOP("ControllerType", "NeGcon"), + ICON_PF_GAMEPAD, s_binding_info, s_settings}; void NeGcon::LoadSettings(const SettingsInterface& si, const char* section, bool initial) { diff --git a/src/core/negcon_rumble.cpp b/src/core/negcon_rumble.cpp index 246a9ddb9..83a2c555f 100644 --- a/src/core/negcon_rumble.cpp +++ b/src/core/negcon_rumble.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin and contributors. +// SPDX-FileCopyrightText: 2019-2025 Connor McLaughlin and contributors. // SPDX-License-Identifier: CC-BY-NC-ND-4.0 #include "negcon_rumble.h" @@ -718,6 +718,8 @@ static const Controller::ControllerBindingInfo s_binding_info[] = { static_cast(NeGconRumble::Button::Count) + static_cast(halfaxis), \ InputBindingInfo::Type::HalfAxis, \ genb} +#define MOTOR(name, display_name, icon_name, index, genb) \ + {name, display_name, icon_name, index, InputBindingInfo::Type::Motor, genb} // clang-format off BUTTON("Up", TRANSLATE_NOOP("NeGconRumble", "D-Pad Up"), ICON_PF_DPAD_UP, NeGconRumble::Button::Up, GenericInputBinding::DPadUp), @@ -734,8 +736,12 @@ static const Controller::ControllerBindingInfo s_binding_info[] = { AXIS("SteeringLeft", TRANSLATE_NOOP("NeGconRumble", "Steering (Twist) Left"), ICON_PF_LEFT_ANALOG_LEFT, NeGconRumble::HalfAxis::SteeringLeft, GenericInputBinding::LeftStickLeft), AXIS("SteeringRight", TRANSLATE_NOOP("NeGconRumble", "Steering (Twist) Right"), ICON_PF_LEFT_ANALOG_LEFT, NeGconRumble::HalfAxis::SteeringRight, GenericInputBinding::LeftStickRight), BUTTON("Analog", TRANSLATE_NOOP("NeGconRumble", "Analog Toggle"), ICON_PF_ANALOG_LEFT_RIGHT, NeGconRumble::Button::Analog, GenericInputBinding::System), + + MOTOR("LargeMotor", TRANSLATE_NOOP("AnalogController", "Large Motor"), ICON_PF_GEARS_OPTIONS_SETTINGS, 0, GenericInputBinding::LargeMotor), + MOTOR("SmallMotor", TRANSLATE_NOOP("AnalogController", "Small Motor"), ICON_PF_GEARS_OPTIONS_SETTINGS, 1, GenericInputBinding::SmallMotor), // clang-format on +#undef MOTOR #undef AXIS #undef BUTTON }; @@ -764,8 +770,7 @@ const Controller::ControllerInfo NeGconRumble::INFO = {ControllerType::NeGconRum TRANSLATE_NOOP("ControllerType", "NeGcon (Rumble)"), ICON_PF_GAMEPAD, s_binding_info, - s_settings, - Controller::VibrationCapabilities::LargeSmallMotors}; + s_settings}; void NeGconRumble::LoadSettings(const SettingsInterface& si, const char* section, bool initial) { diff --git a/src/core/playstation_mouse.cpp b/src/core/playstation_mouse.cpp index 5bc385f60..4e71e4e8d 100644 --- a/src/core/playstation_mouse.cpp +++ b/src/core/playstation_mouse.cpp @@ -220,5 +220,4 @@ const Controller::ControllerInfo PlayStationMouse::INFO = {ControllerType::PlayS TRANSLATE_NOOP("ControllerType", "Mouse"), ICON_PF_MOUSE, s_binding_info, - s_settings, - Controller::VibrationCapabilities::NoVibration}; \ No newline at end of file + s_settings}; \ No newline at end of file diff --git a/src/duckstation-qt/controllerbindingwidgets.cpp b/src/duckstation-qt/controllerbindingwidgets.cpp index 03e32af86..b03c4d886 100644 --- a/src/duckstation-qt/controllerbindingwidgets.cpp +++ b/src/duckstation-qt/controllerbindingwidgets.cpp @@ -401,7 +401,7 @@ void ControllerBindingWidget::createBindingWidgets(QWidget* parent) { if (bi.type == InputBindingInfo::Type::Axis || bi.type == InputBindingInfo::Type::HalfAxis || bi.type == InputBindingInfo::Type::Pointer || bi.type == InputBindingInfo::Type::RelativePointer || - bi.type == InputBindingInfo::Type::Device) + bi.type == InputBindingInfo::Type::Device || bi.type == InputBindingInfo::Type::Motor) { if (!axis_gbox) { @@ -411,7 +411,12 @@ void ControllerBindingWidget::createBindingWidgets(QWidget* parent) QGroupBox* gbox = new QGroupBox(QString::fromUtf8(m_controller_info->GetBindingDisplayName(bi)), axis_gbox); QVBoxLayout* temp = new QVBoxLayout(gbox); - InputBindingWidget* widget = new InputBindingWidget(gbox, sif, bi.type, getConfigSection(), bi.name); + QWidget* widget; + if (bi.type != InputBindingInfo::Type::Motor) + widget = new InputBindingWidget(gbox, sif, bi.type, getConfigSection(), bi.name); + else + widget = new InputVibrationBindingWidget(gbox, getDialog(), getConfigSection(), bi.name); + temp->addWidget(widget); axis_layout->addWidget(gbox, row, column); if ((++column) == NUM_AXIS_COLUMNS) @@ -421,41 +426,7 @@ void ControllerBindingWidget::createBindingWidgets(QWidget* parent) } } } - if (m_controller_info->vibration_caps != Controller::VibrationCapabilities::NoVibration) - { - const bool dual_motors = (m_controller_info->vibration_caps == Controller::VibrationCapabilities::LargeSmallMotors); - if (!axis_gbox) - { - axis_gbox = new QGroupBox(tr("Axes"), scrollarea_widget); - axis_layout = new QGridLayout(axis_gbox); - } - QGroupBox* gbox = new QGroupBox(dual_motors ? tr("Large Motor") : tr("Vibration"), axis_gbox); - QVBoxLayout* temp = new QVBoxLayout(gbox); - InputVibrationBindingWidget* widget = - new InputVibrationBindingWidget(gbox, getDialog(), getConfigSection(), dual_motors ? "LargeMotor" : "Motor"); - temp->addWidget(widget); - axis_layout->addWidget(gbox, row, column); - if ((++column) == NUM_AXIS_COLUMNS) - { - column = 0; - row++; - } - - if (m_controller_info->vibration_caps == Controller::VibrationCapabilities::LargeSmallMotors) - { - gbox = new QGroupBox(tr("Small Motor"), axis_gbox); - temp = new QVBoxLayout(gbox); - widget = new InputVibrationBindingWidget(gbox, getDialog(), getConfigSection(), "SmallMotor"); - temp->addWidget(widget); - axis_layout->addWidget(gbox, row, column); - if ((++column) == NUM_AXIS_COLUMNS) - { - column = 0; - row++; - } - } - } if (axis_gbox) axis_layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding), ++row, 0); @@ -526,34 +497,12 @@ void ControllerBindingWidget::bindBindingWidgets(QWidget* parent) widget->initialize(sif, bi.type, config_section, bi.name); } - } - - switch (m_controller_info->vibration_caps) - { - case Controller::VibrationCapabilities::LargeSmallMotors: + else if (bi.type == InputBindingInfo::Type::Motor) { - InputVibrationBindingWidget* widget = - parent->findChild(QStringLiteral("LargeMotor")); + InputVibrationBindingWidget* widget = parent->findChild(QString::fromUtf8(bi.name)); if (widget) - widget->setKey(getDialog(), config_section, "LargeMotor"); - - widget = parent->findChild(QStringLiteral("SmallMotor")); - if (widget) - widget->setKey(getDialog(), config_section, "SmallMotor"); + widget->setKey(getDialog(), config_section, bi.name); } - break; - - case Controller::VibrationCapabilities::SingleMotor: - { - InputVibrationBindingWidget* widget = parent->findChild(QStringLiteral("Motor")); - if (widget) - widget->setKey(getDialog(), config_section, "Motor"); - } - break; - - case Controller::VibrationCapabilities::NoVibration: - default: - break; } } diff --git a/src/util/imgui_glyph_ranges.inl b/src/util/imgui_glyph_ranges.inl index 1add3d507..a259bf29c 100644 --- a/src/util/imgui_glyph_ranges.inl +++ b/src/util/imgui_glyph_ranges.inl @@ -3,6 +3,6 @@ static constexpr ImWchar FA_ICON_RANGE[] = { 0xe06f,0xe070,0xe086,0xe086,0xf002,0xf002,0xf005,0xf005,0xf007,0xf007,0xf00c,0xf00e,0xf011,0xf013,0xf017,0xf017,0xf019,0xf019,0xf01c,0xf01c,0xf021,0xf021,0xf023,0xf023,0xf025,0xf026,0xf028,0xf028,0xf02e,0xf02e,0xf030,0xf030,0xf03a,0xf03a,0xf03d,0xf03d,0xf04a,0xf04c,0xf050,0xf050,0xf056,0xf056,0xf05e,0xf05e,0xf062,0xf063,0xf065,0xf067,0xf071,0xf071,0xf075,0xf075,0xf077,0xf078,0xf07b,0xf07c,0xf083,0xf085,0xf091,0xf091,0xf0ac,0xf0ae,0xf0b2,0xf0b2,0xf0c3,0xf0c3,0xf0c5,0xf0c5,0xf0c7,0xf0c9,0xf0cb,0xf0cb,0xf0d0,0xf0d0,0xf0dc,0xf0dc,0xf0e0,0xf0e0,0xf0e2,0xf0e2,0xf0e7,0xf0e8,0xf0eb,0xf0eb,0xf0f1,0xf0f1,0xf0f3,0xf0f3,0xf0fe,0xf0fe,0xf110,0xf110,0xf11b,0xf11c,0xf140,0xf140,0xf144,0xf144,0xf146,0xf146,0xf14a,0xf14a,0xf15b,0xf15d,0xf191,0xf192,0xf1ab,0xf1ab,0xf1c0,0xf1c0,0xf1c5,0xf1c5,0xf1de,0xf1de,0xf1e6,0xf1e6,0xf1eb,0xf1eb,0xf1f8,0xf1f8,0xf1fb,0xf1fc,0xf201,0xf201,0xf240,0xf240,0xf242,0xf242,0xf245,0xf245,0xf26c,0xf26c,0xf279,0xf279,0xf2c1,0xf2c1,0xf2d0,0xf2d0,0xf2db,0xf2db,0xf2f1,0xf2f2,0xf302,0xf302,0xf31e,0xf31e,0xf338,0xf338,0xf35d,0xf35d,0xf360,0xf360,0xf362,0xf362,0xf3fd,0xf3fd,0xf410,0xf410,0xf422,0xf422,0xf424,0xf424,0xf462,0xf462,0xf466,0xf466,0xf4ce,0xf4ce,0xf500,0xf500,0xf51f,0xf51f,0xf538,0xf538,0xf53f,0xf53f,0xf545,0xf545,0xf547,0xf548,0xf54c,0xf54c,0xf55b,0xf55b,0xf55d,0xf55d,0xf565,0xf565,0xf56e,0xf570,0xf575,0xf575,0xf5a2,0xf5a2,0xf5aa,0xf5aa,0xf5ae,0xf5ae,0xf5c7,0xf5c7,0xf5cb,0xf5cb,0xf5e7,0xf5e7,0xf5ee,0xf5ee,0xf61f,0xf61f,0xf65d,0xf65e,0xf6a9,0xf6a9,0xf6cf,0xf6cf,0xf70c,0xf70c,0xf70e,0xf70e,0xf78c,0xf78c,0xf794,0xf794,0xf7a0,0xf7a0,0xf7a4,0xf7a5,0xf7c2,0xf7c2,0xf807,0xf807,0xf815,0xf815,0xf818,0xf818,0xf84c,0xf84c,0xf87d,0xf87d,0xf8cc,0xf8cc,0x0,0x0 }; -static constexpr ImWchar PF_ICON_RANGE[] = { 0x2196,0x2199,0x219e,0x21a3,0x21b0,0x21b3,0x21ba,0x21c3,0x21c7,0x21ca,0x21d0,0x21d4,0x21e0,0x21e3,0x21e6,0x21e8,0x21ed,0x21ee,0x21f7,0x21f8,0x21fa,0x21fb,0x227a,0x227f,0x2284,0x2284,0x2349,0x2349,0x235e,0x235e,0x2360,0x2361,0x2364,0x2366,0x23b2,0x23b4,0x23ce,0x23ce,0x23f4,0x23f7,0x2427,0x243a,0x243c,0x243e,0x2460,0x246b,0x248f,0x248f,0x24f5,0x24fd,0x24ff,0x24ff,0x2717,0x2717,0x278a,0x278e,0x27fc,0x27fc,0xe000,0xe001,0xff21,0xff3a,0x1f52b,0x1f52b,0x1f578,0x1f578,0x0,0x0 }; +static constexpr ImWchar PF_ICON_RANGE[] = { 0x2196,0x2199,0x219e,0x21a3,0x21b0,0x21b3,0x21ba,0x21c3,0x21c7,0x21ca,0x21d0,0x21d4,0x21e0,0x21e3,0x21e6,0x21e8,0x21ed,0x21ee,0x21f7,0x21f8,0x21fa,0x21fb,0x227a,0x227f,0x2284,0x2284,0x2349,0x2349,0x235e,0x235e,0x2360,0x2361,0x2364,0x2366,0x23b2,0x23b4,0x23ce,0x23ce,0x23f4,0x23f7,0x2427,0x243a,0x243c,0x243e,0x2460,0x246b,0x248f,0x248f,0x24f5,0x24fd,0x24ff,0x24ff,0x2699,0x2699,0x2717,0x2717,0x278a,0x278e,0x27fc,0x27fc,0xe000,0xe001,0xff21,0xff3a,0x1f52b,0x1f52b,0x1f578,0x1f578,0x0,0x0 }; static constexpr ImWchar EMOJI_ICON_RANGE[] = { 0x2139,0x2139,0x23e9,0x23ea,0x23f8,0x23f8,0x26a0,0x26a0,0x1f4be,0x1f4be,0x1f4c2,0x1f4c2,0x1f4f7,0x1f4f8,0x1f504,0x1f504,0x1f507,0x1f507,0x1f509,0x1f50a,0x1f50d,0x1f50d,0x1f513,0x1f513,0x0,0x0 }; diff --git a/src/util/input_manager.cpp b/src/util/input_manager.cpp index 191879f42..798302e84 100644 --- a/src/util/input_manager.cpp +++ b/src/util/input_manager.cpp @@ -837,6 +837,10 @@ void InputManager::AddHotkeyBindings(const SettingsInterface& si) void InputManager::AddPadBindings(const SettingsInterface& si, const std::string& section, u32 pad_index, const Controller::ControllerInfo* cinfo) { + bool vibration_binding_valid = false; + PadVibrationBinding vibration_binding = {}; + vibration_binding.pad_index = pad_index; + for (const Controller::ControllerBindingInfo& bi : cinfo->bindings) { const std::vector bindings(si.GetStringList(section.c_str(), bi.name)); @@ -896,6 +900,21 @@ void InputManager::AddPadBindings(const SettingsInterface& si, const std::string } break; + case InputBindingInfo::Type::Motor: + { + DebugAssert(bi.bind_index < std::size(vibration_binding.motors)); + if (bindings.empty()) + continue; + + if (bindings.size() > 1) + WARNING_LOG("More than one vibration motor binding for {}:{}", pad_index, bi.name); + + vibration_binding_valid |= + ParseBindingAndGetSource(bindings.front(), &vibration_binding.motors[bi.bind_index].binding, + &vibration_binding.motors[bi.bind_index].source); + } + break; + case InputBindingInfo::Type::Pointer: case InputBindingInfo::Type::Device: // handled in device @@ -907,6 +926,9 @@ void InputManager::AddPadBindings(const SettingsInterface& si, const std::string } } + if (vibration_binding_valid) + s_pad_vibration_array.push_back(std::move(vibration_binding)); + for (u32 macro_button_index = 0; macro_button_index < NUM_MACRO_BUTTONS_PER_CONTROLLER; macro_button_index++) { const std::vector bindings( @@ -943,38 +965,6 @@ void InputManager::AddPadBindings(const SettingsInterface& si, const std::string } } } - - if (cinfo->vibration_caps != Controller::VibrationCapabilities::NoVibration) - { - PadVibrationBinding vib; - vib.pad_index = pad_index; - - bool has_any_bindings = false; - switch (cinfo->vibration_caps) - { - case Controller::VibrationCapabilities::LargeSmallMotors: - { - if (const std::string large_binding(si.GetStringValue(section.c_str(), "LargeMotor")); !large_binding.empty()) - has_any_bindings |= ParseBindingAndGetSource(large_binding, &vib.motors[0].binding, &vib.motors[0].source); - if (const std::string small_binding(si.GetStringValue(section.c_str(), "SmallMotor")); !small_binding.empty()) - has_any_bindings |= ParseBindingAndGetSource(small_binding, &vib.motors[1].binding, &vib.motors[1].source); - } - break; - - case Controller::VibrationCapabilities::SingleMotor: - { - if (const std::string binding(si.GetStringValue(section.c_str(), "Motor")); !binding.empty()) - has_any_bindings |= ParseBindingAndGetSource(binding, &vib.motors[0].binding, &vib.motors[0].source); - } - break; - - default: - break; - } - - if (has_any_bindings) - s_pad_vibration_array.push_back(std::move(vib)); - } } // ------------------------------------------------------------------------ @@ -1580,19 +1570,13 @@ bool InputManager::MapController(SettingsInterface& si, u32 controller, if (bi.generic_mapping == GenericInputBinding::Unknown) continue; - num_mappings += TryMapGenericMapping(si, section, mapping, bi.generic_mapping, bi.name); - } - if (info->vibration_caps == Controller::VibrationCapabilities::LargeSmallMotors) - { - num_mappings += TryMapGenericMapping(si, section, mapping, GenericInputBinding::SmallMotor, "SmallMotor"); - num_mappings += TryMapGenericMapping(si, section, mapping, GenericInputBinding::LargeMotor, "LargeMotor"); - } - else if (info->vibration_caps == Controller::VibrationCapabilities::SingleMotor) - { - if (TryMapGenericMapping(si, section, mapping, GenericInputBinding::LargeMotor, "Motor") == 0) - num_mappings += TryMapGenericMapping(si, section, mapping, GenericInputBinding::SmallMotor, "Motor"); - else - num_mappings++; + u32 mappings_added = TryMapGenericMapping(si, section, mapping, bi.generic_mapping, bi.name); + + // try to map to small motor if we tried big motor + if (mappings_added == 0 && bi.generic_mapping == GenericInputBinding::LargeMotor) + mappings_added += TryMapGenericMapping(si, section, mapping, GenericInputBinding::SmallMotor, bi.name); + + num_mappings += mappings_added; } return (num_mappings > 0);