diff options
Diffstat (limited to 'src/input_common/sdl/sdl_impl.cpp')
| -rw-r--r-- | src/input_common/sdl/sdl_impl.cpp | 114 |
1 files changed, 62 insertions, 52 deletions
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index c8d9eb2bc..a9e676f4b 100644 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <array> | ||
| 6 | #include <atomic> | 7 | #include <atomic> |
| 7 | #include <cmath> | 8 | #include <cmath> |
| 8 | #include <functional> | 9 | #include <functional> |
| @@ -358,7 +359,7 @@ public: | |||
| 358 | return std::make_tuple(x / r * (r - deadzone) / (1 - deadzone), | 359 | return std::make_tuple(x / r * (r - deadzone) / (1 - deadzone), |
| 359 | y / r * (r - deadzone) / (1 - deadzone)); | 360 | y / r * (r - deadzone) / (1 - deadzone)); |
| 360 | } | 361 | } |
| 361 | return std::make_tuple<float, float>(0.0f, 0.0f); | 362 | return {}; |
| 362 | } | 363 | } |
| 363 | 364 | ||
| 364 | bool GetAnalogDirectionStatus(Input::AnalogDirection direction) const override { | 365 | bool GetAnalogDirectionStatus(Input::AnalogDirection direction) const override { |
| @@ -574,10 +575,10 @@ std::vector<Common::ParamPackage> SDLState::GetInputDevices() { | |||
| 574 | 575 | ||
| 575 | namespace { | 576 | namespace { |
| 576 | Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, u8 axis, | 577 | Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, u8 axis, |
| 577 | float value = 0.1) { | 578 | float value = 0.1f) { |
| 578 | Common::ParamPackage params({{"engine", "sdl"}}); | 579 | Common::ParamPackage params({{"engine", "sdl"}}); |
| 579 | params.Set("port", port); | 580 | params.Set("port", port); |
| 580 | params.Set("guid", guid); | 581 | params.Set("guid", std::move(guid)); |
| 581 | params.Set("axis", axis); | 582 | params.Set("axis", axis); |
| 582 | if (value > 0) { | 583 | if (value > 0) { |
| 583 | params.Set("direction", "+"); | 584 | params.Set("direction", "+"); |
| @@ -592,7 +593,7 @@ Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid | |||
| 592 | Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, u8 button) { | 593 | Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, u8 button) { |
| 593 | Common::ParamPackage params({{"engine", "sdl"}}); | 594 | Common::ParamPackage params({{"engine", "sdl"}}); |
| 594 | params.Set("port", port); | 595 | params.Set("port", port); |
| 595 | params.Set("guid", guid); | 596 | params.Set("guid", std::move(guid)); |
| 596 | params.Set("button", button); | 597 | params.Set("button", button); |
| 597 | return params; | 598 | return params; |
| 598 | } | 599 | } |
| @@ -601,7 +602,7 @@ Common::ParamPackage BuildHatParamPackageForButton(int port, std::string guid, u | |||
| 601 | Common::ParamPackage params({{"engine", "sdl"}}); | 602 | Common::ParamPackage params({{"engine", "sdl"}}); |
| 602 | 603 | ||
| 603 | params.Set("port", port); | 604 | params.Set("port", port); |
| 604 | params.Set("guid", guid); | 605 | params.Set("guid", std::move(guid)); |
| 605 | params.Set("hat", hat); | 606 | params.Set("hat", hat); |
| 606 | switch (value) { | 607 | switch (value) { |
| 607 | case SDL_HAT_UP: | 608 | case SDL_HAT_UP: |
| @@ -670,55 +671,62 @@ Common::ParamPackage BuildParamPackageForAnalog(int port, const std::string& gui | |||
| 670 | } // Anonymous namespace | 671 | } // Anonymous namespace |
| 671 | 672 | ||
| 672 | ButtonMapping SDLState::GetButtonMappingForDevice(const Common::ParamPackage& params) { | 673 | ButtonMapping SDLState::GetButtonMappingForDevice(const Common::ParamPackage& params) { |
| 673 | // This list is missing ZL/ZR since those are not considered buttons in SDL GameController. | ||
| 674 | // We will add those afterwards | ||
| 675 | // This list also excludes Screenshot since theres not really a mapping for that | ||
| 676 | std::unordered_map<Settings::NativeButton::Values, SDL_GameControllerButton> | ||
| 677 | switch_to_sdl_button = { | ||
| 678 | {Settings::NativeButton::A, SDL_CONTROLLER_BUTTON_B}, | ||
| 679 | {Settings::NativeButton::B, SDL_CONTROLLER_BUTTON_A}, | ||
| 680 | {Settings::NativeButton::X, SDL_CONTROLLER_BUTTON_Y}, | ||
| 681 | {Settings::NativeButton::Y, SDL_CONTROLLER_BUTTON_X}, | ||
| 682 | {Settings::NativeButton::LStick, SDL_CONTROLLER_BUTTON_LEFTSTICK}, | ||
| 683 | {Settings::NativeButton::RStick, SDL_CONTROLLER_BUTTON_RIGHTSTICK}, | ||
| 684 | {Settings::NativeButton::L, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, | ||
| 685 | {Settings::NativeButton::R, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER}, | ||
| 686 | {Settings::NativeButton::Plus, SDL_CONTROLLER_BUTTON_START}, | ||
| 687 | {Settings::NativeButton::Minus, SDL_CONTROLLER_BUTTON_BACK}, | ||
| 688 | {Settings::NativeButton::DLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT}, | ||
| 689 | {Settings::NativeButton::DUp, SDL_CONTROLLER_BUTTON_DPAD_UP}, | ||
| 690 | {Settings::NativeButton::DRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT}, | ||
| 691 | {Settings::NativeButton::DDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN}, | ||
| 692 | {Settings::NativeButton::SL, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, | ||
| 693 | {Settings::NativeButton::SR, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER}, | ||
| 694 | {Settings::NativeButton::Home, SDL_CONTROLLER_BUTTON_GUIDE}, | ||
| 695 | }; | ||
| 696 | if (!params.Has("guid") || !params.Has("port")) { | 674 | if (!params.Has("guid") || !params.Has("port")) { |
| 697 | return {}; | 675 | return {}; |
| 698 | } | 676 | } |
| 699 | const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); | 677 | const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); |
| 700 | auto controller = joystick->GetSDLGameController(); | 678 | auto* controller = joystick->GetSDLGameController(); |
| 701 | if (!controller) { | 679 | if (controller == nullptr) { |
| 702 | return {}; | 680 | return {}; |
| 703 | } | 681 | } |
| 704 | 682 | ||
| 705 | ButtonMapping mapping{}; | 683 | // This list is missing ZL/ZR since those are not considered buttons in SDL GameController. |
| 684 | // We will add those afterwards | ||
| 685 | // This list also excludes Screenshot since theres not really a mapping for that | ||
| 686 | using ButtonBindings = | ||
| 687 | std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerButton>, 17>; | ||
| 688 | static constexpr ButtonBindings switch_to_sdl_button{{ | ||
| 689 | {Settings::NativeButton::A, SDL_CONTROLLER_BUTTON_B}, | ||
| 690 | {Settings::NativeButton::B, SDL_CONTROLLER_BUTTON_A}, | ||
| 691 | {Settings::NativeButton::X, SDL_CONTROLLER_BUTTON_Y}, | ||
| 692 | {Settings::NativeButton::Y, SDL_CONTROLLER_BUTTON_X}, | ||
| 693 | {Settings::NativeButton::LStick, SDL_CONTROLLER_BUTTON_LEFTSTICK}, | ||
| 694 | {Settings::NativeButton::RStick, SDL_CONTROLLER_BUTTON_RIGHTSTICK}, | ||
| 695 | {Settings::NativeButton::L, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, | ||
| 696 | {Settings::NativeButton::R, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER}, | ||
| 697 | {Settings::NativeButton::Plus, SDL_CONTROLLER_BUTTON_START}, | ||
| 698 | {Settings::NativeButton::Minus, SDL_CONTROLLER_BUTTON_BACK}, | ||
| 699 | {Settings::NativeButton::DLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT}, | ||
| 700 | {Settings::NativeButton::DUp, SDL_CONTROLLER_BUTTON_DPAD_UP}, | ||
| 701 | {Settings::NativeButton::DRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT}, | ||
| 702 | {Settings::NativeButton::DDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN}, | ||
| 703 | {Settings::NativeButton::SL, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, | ||
| 704 | {Settings::NativeButton::SR, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER}, | ||
| 705 | {Settings::NativeButton::Home, SDL_CONTROLLER_BUTTON_GUIDE}, | ||
| 706 | }}; | ||
| 707 | |||
| 708 | // Add the missing bindings for ZL/ZR | ||
| 709 | using ZBindings = | ||
| 710 | std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerAxis>, 2>; | ||
| 711 | static constexpr ZBindings switch_to_sdl_axis{{ | ||
| 712 | {Settings::NativeButton::ZL, SDL_CONTROLLER_AXIS_TRIGGERLEFT}, | ||
| 713 | {Settings::NativeButton::ZR, SDL_CONTROLLER_AXIS_TRIGGERRIGHT}, | ||
| 714 | }}; | ||
| 715 | |||
| 716 | ButtonMapping mapping; | ||
| 717 | mapping.reserve(switch_to_sdl_button.size() + switch_to_sdl_axis.size()); | ||
| 718 | |||
| 706 | for (const auto& [switch_button, sdl_button] : switch_to_sdl_button) { | 719 | for (const auto& [switch_button, sdl_button] : switch_to_sdl_button) { |
| 707 | const auto& binding = SDL_GameControllerGetBindForButton(controller, sdl_button); | 720 | const auto& binding = SDL_GameControllerGetBindForButton(controller, sdl_button); |
| 708 | mapping[switch_button] = | 721 | mapping.insert_or_assign( |
| 709 | BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding); | 722 | switch_button, |
| 723 | BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding)); | ||
| 710 | } | 724 | } |
| 711 | |||
| 712 | // Add the missing bindings for ZL/ZR | ||
| 713 | std::unordered_map<Settings::NativeButton::Values, SDL_GameControllerAxis> switch_to_sdl_axis = | ||
| 714 | { | ||
| 715 | {Settings::NativeButton::ZL, SDL_CONTROLLER_AXIS_TRIGGERLEFT}, | ||
| 716 | {Settings::NativeButton::ZR, SDL_CONTROLLER_AXIS_TRIGGERRIGHT}, | ||
| 717 | }; | ||
| 718 | for (const auto& [switch_button, sdl_axis] : switch_to_sdl_axis) { | 725 | for (const auto& [switch_button, sdl_axis] : switch_to_sdl_axis) { |
| 719 | const auto& binding = SDL_GameControllerGetBindForAxis(controller, sdl_axis); | 726 | const auto& binding = SDL_GameControllerGetBindForAxis(controller, sdl_axis); |
| 720 | mapping[switch_button] = | 727 | mapping.insert_or_assign( |
| 721 | BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding); | 728 | switch_button, |
| 729 | BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding)); | ||
| 722 | } | 730 | } |
| 723 | 731 | ||
| 724 | return mapping; | 732 | return mapping; |
| @@ -729,8 +737,8 @@ AnalogMapping SDLState::GetAnalogMappingForDevice(const Common::ParamPackage& pa | |||
| 729 | return {}; | 737 | return {}; |
| 730 | } | 738 | } |
| 731 | const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); | 739 | const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); |
| 732 | auto controller = joystick->GetSDLGameController(); | 740 | auto* controller = joystick->GetSDLGameController(); |
| 733 | if (!controller) { | 741 | if (controller == nullptr) { |
| 734 | return {}; | 742 | return {}; |
| 735 | } | 743 | } |
| 736 | 744 | ||
| @@ -739,16 +747,18 @@ AnalogMapping SDLState::GetAnalogMappingForDevice(const Common::ParamPackage& pa | |||
| 739 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); | 747 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); |
| 740 | const auto& binding_left_y = | 748 | const auto& binding_left_y = |
| 741 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); | 749 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); |
| 742 | mapping[Settings::NativeAnalog::LStick] = | 750 | mapping.insert_or_assign(Settings::NativeAnalog::LStick, |
| 743 | BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(), | 751 | BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(), |
| 744 | binding_left_x.value.axis, binding_left_y.value.axis); | 752 | binding_left_x.value.axis, |
| 753 | binding_left_y.value.axis)); | ||
| 745 | const auto& binding_right_x = | 754 | const auto& binding_right_x = |
| 746 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); | 755 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); |
| 747 | const auto& binding_right_y = | 756 | const auto& binding_right_y = |
| 748 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY); | 757 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY); |
| 749 | mapping[Settings::NativeAnalog::RStick] = | 758 | mapping.insert_or_assign(Settings::NativeAnalog::RStick, |
| 750 | BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(), | 759 | BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(), |
| 751 | binding_right_x.value.axis, binding_right_y.value.axis); | 760 | binding_right_x.value.axis, |
| 761 | binding_right_y.value.axis)); | ||
| 752 | return mapping; | 762 | return mapping; |
| 753 | } | 763 | } |
| 754 | 764 | ||
| @@ -784,7 +794,7 @@ public: | |||
| 784 | } | 794 | } |
| 785 | return {}; | 795 | return {}; |
| 786 | } | 796 | } |
| 787 | std::optional<Common::ParamPackage> FromEvent(const SDL_Event& event) { | 797 | [[nodiscard]] std::optional<Common::ParamPackage> FromEvent(const SDL_Event& event) const { |
| 788 | switch (event.type) { | 798 | switch (event.type) { |
| 789 | case SDL_JOYAXISMOTION: | 799 | case SDL_JOYAXISMOTION: |
| 790 | if (std::abs(event.jaxis.value / 32767.0) < 0.5) { | 800 | if (std::abs(event.jaxis.value / 32767.0) < 0.5) { |
| @@ -795,7 +805,7 @@ public: | |||
| 795 | case SDL_JOYHATMOTION: | 805 | case SDL_JOYHATMOTION: |
| 796 | return {SDLEventToButtonParamPackage(state, event)}; | 806 | return {SDLEventToButtonParamPackage(state, event)}; |
| 797 | } | 807 | } |
| 798 | return {}; | 808 | return std::nullopt; |
| 799 | } | 809 | } |
| 800 | }; | 810 | }; |
| 801 | 811 | ||