diff options
Diffstat (limited to 'src/input_common/sdl/sdl_impl.cpp')
| -rw-r--r-- | src/input_common/sdl/sdl_impl.cpp | 87 |
1 files changed, 63 insertions, 24 deletions
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index 70a0ba09c..f1f950d8a 100644 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp | |||
| @@ -82,6 +82,12 @@ public: | |||
| 82 | state.buttons.insert_or_assign(button, value); | 82 | state.buttons.insert_or_assign(button, value); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | void PreSetButton(int button) { | ||
| 86 | if (!state.buttons.contains(button)) { | ||
| 87 | SetButton(button, false); | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 85 | void SetMotion(SDL_ControllerSensorEvent event) { | 91 | void SetMotion(SDL_ControllerSensorEvent event) { |
| 86 | constexpr float gravity_constant = 9.80665f; | 92 | constexpr float gravity_constant = 9.80665f; |
| 87 | std::lock_guard lock{mutex}; | 93 | std::lock_guard lock{mutex}; |
| @@ -155,9 +161,16 @@ public: | |||
| 155 | state.axes.insert_or_assign(axis, value); | 161 | state.axes.insert_or_assign(axis, value); |
| 156 | } | 162 | } |
| 157 | 163 | ||
| 158 | float GetAxis(int axis, float range) const { | 164 | void PreSetAxis(int axis) { |
| 165 | if (!state.axes.contains(axis)) { | ||
| 166 | SetAxis(axis, 0); | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | float GetAxis(int axis, float range, float offset) const { | ||
| 159 | std::lock_guard lock{mutex}; | 171 | std::lock_guard lock{mutex}; |
| 160 | return static_cast<float>(state.axes.at(axis)) / (32767.0f * range); | 172 | const float value = static_cast<float>(state.axes.at(axis)) / 32767.0f; |
| 173 | return (value + offset) / range; | ||
| 161 | } | 174 | } |
| 162 | 175 | ||
| 163 | bool RumblePlay(u16 amp_low, u16 amp_high) { | 176 | bool RumblePlay(u16 amp_low, u16 amp_high) { |
| @@ -174,9 +187,10 @@ public: | |||
| 174 | return false; | 187 | return false; |
| 175 | } | 188 | } |
| 176 | 189 | ||
| 177 | std::tuple<float, float> GetAnalog(int axis_x, int axis_y, float range) const { | 190 | std::tuple<float, float> GetAnalog(int axis_x, int axis_y, float range, float offset_x, |
| 178 | float x = GetAxis(axis_x, range); | 191 | float offset_y) const { |
| 179 | float y = GetAxis(axis_y, range); | 192 | float x = GetAxis(axis_x, range, offset_x); |
| 193 | float y = GetAxis(axis_y, range, offset_y); | ||
| 180 | y = -y; // 3DS uses an y-axis inverse from SDL | 194 | y = -y; // 3DS uses an y-axis inverse from SDL |
| 181 | 195 | ||
| 182 | // Make sure the coordinates are in the unit circle, | 196 | // Make sure the coordinates are in the unit circle, |
| @@ -483,7 +497,7 @@ public: | |||
| 483 | trigger_if_greater(trigger_if_greater_) {} | 497 | trigger_if_greater(trigger_if_greater_) {} |
| 484 | 498 | ||
| 485 | bool GetStatus() const override { | 499 | bool GetStatus() const override { |
| 486 | const float axis_value = joystick->GetAxis(axis, 1.0f); | 500 | const float axis_value = joystick->GetAxis(axis, 1.0f, 0.0f); |
| 487 | if (trigger_if_greater) { | 501 | if (trigger_if_greater) { |
| 488 | return axis_value > threshold; | 502 | return axis_value > threshold; |
| 489 | } | 503 | } |
| @@ -500,12 +514,14 @@ private: | |||
| 500 | class SDLAnalog final : public Input::AnalogDevice { | 514 | class SDLAnalog final : public Input::AnalogDevice { |
| 501 | public: | 515 | public: |
| 502 | explicit SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_, | 516 | explicit SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_, |
| 503 | bool invert_x_, bool invert_y_, float deadzone_, float range_) | 517 | bool invert_x_, bool invert_y_, float deadzone_, float range_, |
| 518 | float offset_x_, float offset_y_) | ||
| 504 | : joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_), invert_x(invert_x_), | 519 | : joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_), invert_x(invert_x_), |
| 505 | invert_y(invert_y_), deadzone(deadzone_), range(range_) {} | 520 | invert_y(invert_y_), deadzone(deadzone_), range(range_), offset_x(offset_x_), |
| 521 | offset_y(offset_y_) {} | ||
| 506 | 522 | ||
| 507 | std::tuple<float, float> GetStatus() const override { | 523 | std::tuple<float, float> GetStatus() const override { |
| 508 | auto [x, y] = joystick->GetAnalog(axis_x, axis_y, range); | 524 | auto [x, y] = joystick->GetAnalog(axis_x, axis_y, range, offset_x, offset_y); |
| 509 | const float r = std::sqrt((x * x) + (y * y)); | 525 | const float r = std::sqrt((x * x) + (y * y)); |
| 510 | if (invert_x) { | 526 | if (invert_x) { |
| 511 | x = -x; | 527 | x = -x; |
| @@ -522,8 +538,8 @@ public: | |||
| 522 | } | 538 | } |
| 523 | 539 | ||
| 524 | std::tuple<float, float> GetRawStatus() const override { | 540 | std::tuple<float, float> GetRawStatus() const override { |
| 525 | const float x = joystick->GetAxis(axis_x, range); | 541 | const float x = joystick->GetAxis(axis_x, range, offset_x); |
| 526 | const float y = joystick->GetAxis(axis_y, range); | 542 | const float y = joystick->GetAxis(axis_y, range, offset_y); |
| 527 | return {x, -y}; | 543 | return {x, -y}; |
| 528 | } | 544 | } |
| 529 | 545 | ||
| @@ -555,6 +571,8 @@ private: | |||
| 555 | const bool invert_y; | 571 | const bool invert_y; |
| 556 | const float deadzone; | 572 | const float deadzone; |
| 557 | const float range; | 573 | const float range; |
| 574 | const float offset_x; | ||
| 575 | const float offset_y; | ||
| 558 | }; | 576 | }; |
| 559 | 577 | ||
| 560 | class SDLVibration final : public Input::VibrationDevice { | 578 | class SDLVibration final : public Input::VibrationDevice { |
| @@ -621,7 +639,7 @@ public: | |||
| 621 | trigger_if_greater(trigger_if_greater_) {} | 639 | trigger_if_greater(trigger_if_greater_) {} |
| 622 | 640 | ||
| 623 | Input::MotionStatus GetStatus() const override { | 641 | Input::MotionStatus GetStatus() const override { |
| 624 | const float axis_value = joystick->GetAxis(axis, 1.0f); | 642 | const float axis_value = joystick->GetAxis(axis, 1.0f, 0.0f); |
| 625 | bool trigger = axis_value < threshold; | 643 | bool trigger = axis_value < threshold; |
| 626 | if (trigger_if_greater) { | 644 | if (trigger_if_greater) { |
| 627 | trigger = axis_value > threshold; | 645 | trigger = axis_value > threshold; |
| @@ -720,13 +738,13 @@ public: | |||
| 720 | LOG_ERROR(Input, "Unknown direction {}", direction_name); | 738 | LOG_ERROR(Input, "Unknown direction {}", direction_name); |
| 721 | } | 739 | } |
| 722 | // This is necessary so accessing GetAxis with axis won't crash | 740 | // This is necessary so accessing GetAxis with axis won't crash |
| 723 | joystick->SetAxis(axis, 0); | 741 | joystick->PreSetAxis(axis); |
| 724 | return std::make_unique<SDLAxisButton>(joystick, axis, threshold, trigger_if_greater); | 742 | return std::make_unique<SDLAxisButton>(joystick, axis, threshold, trigger_if_greater); |
| 725 | } | 743 | } |
| 726 | 744 | ||
| 727 | const int button = params.Get("button", 0); | 745 | const int button = params.Get("button", 0); |
| 728 | // This is necessary so accessing GetButton with button won't crash | 746 | // This is necessary so accessing GetButton with button won't crash |
| 729 | joystick->SetButton(button, false); | 747 | joystick->PreSetButton(button); |
| 730 | return std::make_unique<SDLButton>(joystick, button, toggle); | 748 | return std::make_unique<SDLButton>(joystick, button, toggle); |
| 731 | } | 749 | } |
| 732 | 750 | ||
| @@ -757,13 +775,15 @@ public: | |||
| 757 | const std::string invert_y_value = params.Get("invert_y", "+"); | 775 | const std::string invert_y_value = params.Get("invert_y", "+"); |
| 758 | const bool invert_x = invert_x_value == "-"; | 776 | const bool invert_x = invert_x_value == "-"; |
| 759 | const bool invert_y = invert_y_value == "-"; | 777 | const bool invert_y = invert_y_value == "-"; |
| 778 | const float offset_x = params.Get("offset_x", 0.0f); | ||
| 779 | const float offset_y = params.Get("offset_y", 0.0f); | ||
| 760 | auto joystick = state.GetSDLJoystickByGUID(guid, port); | 780 | auto joystick = state.GetSDLJoystickByGUID(guid, port); |
| 761 | 781 | ||
| 762 | // This is necessary so accessing GetAxis with axis_x and axis_y won't crash | 782 | // This is necessary so accessing GetAxis with axis_x and axis_y won't crash |
| 763 | joystick->SetAxis(axis_x, 0); | 783 | joystick->PreSetAxis(axis_x); |
| 764 | joystick->SetAxis(axis_y, 0); | 784 | joystick->PreSetAxis(axis_y); |
| 765 | return std::make_unique<SDLAnalog>(joystick, axis_x, axis_y, invert_x, invert_y, deadzone, | 785 | return std::make_unique<SDLAnalog>(joystick, axis_x, axis_y, invert_x, invert_y, deadzone, |
| 766 | range); | 786 | range, offset_x, offset_y); |
| 767 | } | 787 | } |
| 768 | 788 | ||
| 769 | private: | 789 | private: |
| @@ -844,13 +864,13 @@ public: | |||
| 844 | LOG_ERROR(Input, "Unknown direction {}", direction_name); | 864 | LOG_ERROR(Input, "Unknown direction {}", direction_name); |
| 845 | } | 865 | } |
| 846 | // This is necessary so accessing GetAxis with axis won't crash | 866 | // This is necessary so accessing GetAxis with axis won't crash |
| 847 | joystick->SetAxis(axis, 0); | 867 | joystick->PreSetAxis(axis); |
| 848 | return std::make_unique<SDLAxisMotion>(joystick, axis, threshold, trigger_if_greater); | 868 | return std::make_unique<SDLAxisMotion>(joystick, axis, threshold, trigger_if_greater); |
| 849 | } | 869 | } |
| 850 | 870 | ||
| 851 | const int button = params.Get("button", 0); | 871 | const int button = params.Get("button", 0); |
| 852 | // This is necessary so accessing GetButton with button won't crash | 872 | // This is necessary so accessing GetButton with button won't crash |
| 853 | joystick->SetButton(button, false); | 873 | joystick->PreSetButton(button); |
| 854 | return std::make_unique<SDLButtonMotion>(joystick, button); | 874 | return std::make_unique<SDLButtonMotion>(joystick, button); |
| 855 | } | 875 | } |
| 856 | 876 | ||
| @@ -995,6 +1015,7 @@ Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid | |||
| 995 | params.Set("port", port); | 1015 | params.Set("port", port); |
| 996 | params.Set("guid", std::move(guid)); | 1016 | params.Set("guid", std::move(guid)); |
| 997 | params.Set("button", button); | 1017 | params.Set("button", button); |
| 1018 | params.Set("toggle", false); | ||
| 998 | return params; | 1019 | return params; |
| 999 | } | 1020 | } |
| 1000 | 1021 | ||
| @@ -1134,13 +1155,15 @@ Common::ParamPackage BuildParamPackageForBinding(int port, const std::string& gu | |||
| 1134 | } | 1155 | } |
| 1135 | 1156 | ||
| 1136 | Common::ParamPackage BuildParamPackageForAnalog(int port, const std::string& guid, int axis_x, | 1157 | Common::ParamPackage BuildParamPackageForAnalog(int port, const std::string& guid, int axis_x, |
| 1137 | int axis_y) { | 1158 | int axis_y, float offset_x, float offset_y) { |
| 1138 | Common::ParamPackage params; | 1159 | Common::ParamPackage params; |
| 1139 | params.Set("engine", "sdl"); | 1160 | params.Set("engine", "sdl"); |
| 1140 | params.Set("port", port); | 1161 | params.Set("port", port); |
| 1141 | params.Set("guid", guid); | 1162 | params.Set("guid", guid); |
| 1142 | params.Set("axis_x", axis_x); | 1163 | params.Set("axis_x", axis_x); |
| 1143 | params.Set("axis_y", axis_y); | 1164 | params.Set("axis_y", axis_y); |
| 1165 | params.Set("offset_x", offset_x); | ||
| 1166 | params.Set("offset_y", offset_y); | ||
| 1144 | params.Set("invert_x", "+"); | 1167 | params.Set("invert_x", "+"); |
| 1145 | params.Set("invert_y", "+"); | 1168 | params.Set("invert_y", "+"); |
| 1146 | return params; | 1169 | return params; |
| @@ -1342,24 +1365,39 @@ AnalogMapping SDLState::GetAnalogMappingForDevice(const Common::ParamPackage& pa | |||
| 1342 | const auto& binding_left_y = | 1365 | const auto& binding_left_y = |
| 1343 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); | 1366 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); |
| 1344 | if (params.Has("guid2")) { | 1367 | if (params.Has("guid2")) { |
| 1368 | joystick2->PreSetAxis(binding_left_x.value.axis); | ||
| 1369 | joystick2->PreSetAxis(binding_left_y.value.axis); | ||
| 1370 | const auto left_offset_x = -joystick2->GetAxis(binding_left_x.value.axis, 1.0f, 0); | ||
| 1371 | const auto left_offset_y = -joystick2->GetAxis(binding_left_y.value.axis, 1.0f, 0); | ||
| 1345 | mapping.insert_or_assign( | 1372 | mapping.insert_or_assign( |
| 1346 | Settings::NativeAnalog::LStick, | 1373 | Settings::NativeAnalog::LStick, |
| 1347 | BuildParamPackageForAnalog(joystick2->GetPort(), joystick2->GetGUID(), | 1374 | BuildParamPackageForAnalog(joystick2->GetPort(), joystick2->GetGUID(), |
| 1348 | binding_left_x.value.axis, binding_left_y.value.axis)); | 1375 | binding_left_x.value.axis, binding_left_y.value.axis, |
| 1376 | left_offset_x, left_offset_y)); | ||
| 1349 | } else { | 1377 | } else { |
| 1378 | joystick->PreSetAxis(binding_left_x.value.axis); | ||
| 1379 | joystick->PreSetAxis(binding_left_y.value.axis); | ||
| 1380 | const auto left_offset_x = -joystick->GetAxis(binding_left_x.value.axis, 1.0f, 0); | ||
| 1381 | const auto left_offset_y = -joystick->GetAxis(binding_left_y.value.axis, 1.0f, 0); | ||
| 1350 | mapping.insert_or_assign( | 1382 | mapping.insert_or_assign( |
| 1351 | Settings::NativeAnalog::LStick, | 1383 | Settings::NativeAnalog::LStick, |
| 1352 | BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(), | 1384 | BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(), |
| 1353 | binding_left_x.value.axis, binding_left_y.value.axis)); | 1385 | binding_left_x.value.axis, binding_left_y.value.axis, |
| 1386 | left_offset_x, left_offset_y)); | ||
| 1354 | } | 1387 | } |
| 1355 | const auto& binding_right_x = | 1388 | const auto& binding_right_x = |
| 1356 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); | 1389 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); |
| 1357 | const auto& binding_right_y = | 1390 | const auto& binding_right_y = |
| 1358 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY); | 1391 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY); |
| 1392 | joystick->PreSetAxis(binding_right_x.value.axis); | ||
| 1393 | joystick->PreSetAxis(binding_right_y.value.axis); | ||
| 1394 | const auto right_offset_x = -joystick->GetAxis(binding_right_x.value.axis, 1.0f, 0); | ||
| 1395 | const auto right_offset_y = -joystick->GetAxis(binding_right_y.value.axis, 1.0f, 0); | ||
| 1359 | mapping.insert_or_assign(Settings::NativeAnalog::RStick, | 1396 | mapping.insert_or_assign(Settings::NativeAnalog::RStick, |
| 1360 | BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(), | 1397 | BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(), |
| 1361 | binding_right_x.value.axis, | 1398 | binding_right_x.value.axis, |
| 1362 | binding_right_y.value.axis)); | 1399 | binding_right_y.value.axis, right_offset_x, |
| 1400 | right_offset_y)); | ||
| 1363 | return mapping; | 1401 | return mapping; |
| 1364 | } | 1402 | } |
| 1365 | 1403 | ||
| @@ -1563,8 +1601,9 @@ public: | |||
| 1563 | } | 1601 | } |
| 1564 | 1602 | ||
| 1565 | if (const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which)) { | 1603 | if (const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which)) { |
| 1604 | // Set offset to zero since the joystick is not on center | ||
| 1566 | auto params = BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(), | 1605 | auto params = BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(), |
| 1567 | first_axis, axis); | 1606 | first_axis, axis, 0, 0); |
| 1568 | first_axis = -1; | 1607 | first_axis = -1; |
| 1569 | return params; | 1608 | return params; |
| 1570 | } | 1609 | } |