diff options
| -rw-r--r-- | src/common/input.h | 1 | ||||
| -rw-r--r-- | src/core/hid/emulated_controller.cpp | 34 | ||||
| -rw-r--r-- | src/input_common/drivers/sdl_driver.cpp | 23 | ||||
| -rw-r--r-- | src/input_common/drivers/sdl_driver.h | 12 |
4 files changed, 63 insertions, 7 deletions
diff --git a/src/common/input.h b/src/common/input.h index 54fcb24b0..bb42aaacc 100644 --- a/src/common/input.h +++ b/src/common/input.h | |||
| @@ -72,6 +72,7 @@ enum class PollingError { | |||
| 72 | enum class VibrationAmplificationType { | 72 | enum class VibrationAmplificationType { |
| 73 | Linear, | 73 | Linear, |
| 74 | Exponential, | 74 | Exponential, |
| 75 | Test, | ||
| 75 | }; | 76 | }; |
| 76 | 77 | ||
| 77 | // Analog properties for calibration | 78 | // Analog properties for calibration |
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index ba1dcd171..bd2384515 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp | |||
| @@ -884,18 +884,42 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v | |||
| 884 | } | 884 | } |
| 885 | 885 | ||
| 886 | bool EmulatedController::TestVibration(std::size_t device_index) { | 886 | bool EmulatedController::TestVibration(std::size_t device_index) { |
| 887 | static constexpr VibrationValue test_vibration = { | 887 | if (device_index >= output_devices.size()) { |
| 888 | return false; | ||
| 889 | } | ||
| 890 | if (!output_devices[device_index]) { | ||
| 891 | return false; | ||
| 892 | } | ||
| 893 | |||
| 894 | const auto player_index = NpadIdTypeToIndex(npad_id_type); | ||
| 895 | const auto& player = Settings::values.players.GetValue()[player_index]; | ||
| 896 | |||
| 897 | if (!player.vibration_enabled) { | ||
| 898 | return false; | ||
| 899 | } | ||
| 900 | |||
| 901 | const Common::Input::VibrationStatus test_vibration = { | ||
| 888 | .low_amplitude = 0.001f, | 902 | .low_amplitude = 0.001f, |
| 889 | .low_frequency = 160.0f, | 903 | .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency, |
| 890 | .high_amplitude = 0.001f, | 904 | .high_amplitude = 0.001f, |
| 891 | .high_frequency = 320.0f, | 905 | .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency, |
| 906 | .type = Common::Input::VibrationAmplificationType::Test, | ||
| 907 | }; | ||
| 908 | |||
| 909 | const Common::Input::VibrationStatus zero_vibration = { | ||
| 910 | .low_amplitude = DEFAULT_VIBRATION_VALUE.low_amplitude, | ||
| 911 | .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency, | ||
| 912 | .high_amplitude = DEFAULT_VIBRATION_VALUE.high_amplitude, | ||
| 913 | .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency, | ||
| 914 | .type = Common::Input::VibrationAmplificationType::Test, | ||
| 892 | }; | 915 | }; |
| 893 | 916 | ||
| 894 | // Send a slight vibration to test for rumble support | 917 | // Send a slight vibration to test for rumble support |
| 895 | SetVibration(device_index, test_vibration); | 918 | output_devices[device_index]->SetVibration(test_vibration); |
| 896 | 919 | ||
| 897 | // Stop any vibration and return the result | 920 | // Stop any vibration and return the result |
| 898 | return SetVibration(device_index, DEFAULT_VIBRATION_VALUE); | 921 | return output_devices[device_index]->SetVibration(zero_vibration) == |
| 922 | Common::Input::VibrationError::None; | ||
| 899 | } | 923 | } |
| 900 | 924 | ||
| 901 | bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) { | 925 | bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) { |
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index a5c63e74a..1a14ef10b 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp | |||
| @@ -434,6 +434,7 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en | |||
| 434 | using namespace std::chrono_literals; | 434 | using namespace std::chrono_literals; |
| 435 | while (initialized) { | 435 | while (initialized) { |
| 436 | SDL_PumpEvents(); | 436 | SDL_PumpEvents(); |
| 437 | SendVibrations(); | ||
| 437 | std::this_thread::sleep_for(1ms); | 438 | std::this_thread::sleep_for(1ms); |
| 438 | } | 439 | } |
| 439 | }); | 440 | }); |
| @@ -531,13 +532,31 @@ Common::Input::VibrationError SDLDriver::SetRumble( | |||
| 531 | .type = Common::Input::VibrationAmplificationType::Exponential, | 532 | .type = Common::Input::VibrationAmplificationType::Exponential, |
| 532 | }; | 533 | }; |
| 533 | 534 | ||
| 534 | if (!joystick->RumblePlay(new_vibration)) { | 535 | if (vibration.type == Common::Input::VibrationAmplificationType::Test) { |
| 535 | return Common::Input::VibrationError::Unknown; | 536 | if (!joystick->RumblePlay(new_vibration)) { |
| 537 | return Common::Input::VibrationError::Unknown; | ||
| 538 | } | ||
| 539 | return Common::Input::VibrationError::None; | ||
| 536 | } | 540 | } |
| 537 | 541 | ||
| 542 | vibration_queue.Push(VibrationRequest{ | ||
| 543 | .identifier = identifier, | ||
| 544 | .vibration = new_vibration, | ||
| 545 | }); | ||
| 546 | |||
| 538 | return Common::Input::VibrationError::None; | 547 | return Common::Input::VibrationError::None; |
| 539 | } | 548 | } |
| 540 | 549 | ||
| 550 | void SDLDriver::SendVibrations() { | ||
| 551 | while (!vibration_queue.Empty()) { | ||
| 552 | VibrationRequest request; | ||
| 553 | vibration_queue.Pop(request); | ||
| 554 | const auto joystick = GetSDLJoystickByGUID(request.identifier.guid.RawString(), | ||
| 555 | static_cast<int>(request.identifier.port)); | ||
| 556 | joystick->RumblePlay(request.vibration); | ||
| 557 | } | ||
| 558 | } | ||
| 559 | |||
| 541 | Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid, | 560 | Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid, |
| 542 | s32 axis, float value) const { | 561 | s32 axis, float value) const { |
| 543 | Common::ParamPackage params{}; | 562 | Common::ParamPackage params{}; |
diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h index dcd0d1e64..c82632506 100644 --- a/src/input_common/drivers/sdl_driver.h +++ b/src/input_common/drivers/sdl_driver.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <SDL.h> | 12 | #include <SDL.h> |
| 13 | 13 | ||
| 14 | #include "common/common_types.h" | 14 | #include "common/common_types.h" |
| 15 | #include "common/threadsafe_queue.h" | ||
| 15 | #include "input_common/input_engine.h" | 16 | #include "input_common/input_engine.h" |
| 16 | 17 | ||
| 17 | union SDL_Event; | 18 | union SDL_Event; |
| @@ -64,12 +65,20 @@ public: | |||
| 64 | const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; | 65 | const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; |
| 65 | 66 | ||
| 66 | private: | 67 | private: |
| 68 | struct VibrationRequest { | ||
| 69 | PadIdentifier identifier; | ||
| 70 | Common::Input::VibrationStatus vibration; | ||
| 71 | }; | ||
| 72 | |||
| 67 | void InitJoystick(int joystick_index); | 73 | void InitJoystick(int joystick_index); |
| 68 | void CloseJoystick(SDL_Joystick* sdl_joystick); | 74 | void CloseJoystick(SDL_Joystick* sdl_joystick); |
| 69 | 75 | ||
| 70 | /// Needs to be called before SDL_QuitSubSystem. | 76 | /// Needs to be called before SDL_QuitSubSystem. |
| 71 | void CloseJoysticks(); | 77 | void CloseJoysticks(); |
| 72 | 78 | ||
| 79 | /// Takes all vibrations from the queue and sends the command to the controller | ||
| 80 | void SendVibrations(); | ||
| 81 | |||
| 73 | Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis, | 82 | Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis, |
| 74 | float value = 0.1f) const; | 83 | float value = 0.1f) const; |
| 75 | Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, | 84 | Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, |
| @@ -107,6 +116,9 @@ private: | |||
| 107 | /// Returns true if the button is on the left joycon | 116 | /// Returns true if the button is on the left joycon |
| 108 | bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const; | 117 | bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const; |
| 109 | 118 | ||
| 119 | /// Queue of vibration request to controllers | ||
| 120 | Common::SPSCQueue<VibrationRequest> vibration_queue; | ||
| 121 | |||
| 110 | /// Map of GUID of a list of corresponding virtual Joysticks | 122 | /// Map of GUID of a list of corresponding virtual Joysticks |
| 111 | std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map; | 123 | std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map; |
| 112 | std::mutex joystick_map_mutex; | 124 | std::mutex joystick_map_mutex; |