Merge pull request #8374 from german77/asnycvibrations
input_common: Make vibration request async
This commit is contained in:
		| @@ -72,6 +72,7 @@ enum class PollingError { | |||||||
| enum class VibrationAmplificationType { | enum class VibrationAmplificationType { | ||||||
|     Linear, |     Linear, | ||||||
|     Exponential, |     Exponential, | ||||||
|  |     Test, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // Analog properties for calibration | // Analog properties for calibration | ||||||
|   | |||||||
| @@ -884,18 +884,42 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v | |||||||
| } | } | ||||||
|  |  | ||||||
| bool EmulatedController::TestVibration(std::size_t device_index) { | bool EmulatedController::TestVibration(std::size_t device_index) { | ||||||
|     static constexpr VibrationValue test_vibration = { |     if (device_index >= output_devices.size()) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |     if (!output_devices[device_index]) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const auto player_index = NpadIdTypeToIndex(npad_id_type); | ||||||
|  |     const auto& player = Settings::values.players.GetValue()[player_index]; | ||||||
|  |  | ||||||
|  |     if (!player.vibration_enabled) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const Common::Input::VibrationStatus test_vibration = { | ||||||
|         .low_amplitude = 0.001f, |         .low_amplitude = 0.001f, | ||||||
|         .low_frequency = 160.0f, |         .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency, | ||||||
|         .high_amplitude = 0.001f, |         .high_amplitude = 0.001f, | ||||||
|         .high_frequency = 320.0f, |         .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency, | ||||||
|  |         .type = Common::Input::VibrationAmplificationType::Test, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     const Common::Input::VibrationStatus zero_vibration = { | ||||||
|  |         .low_amplitude = DEFAULT_VIBRATION_VALUE.low_amplitude, | ||||||
|  |         .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency, | ||||||
|  |         .high_amplitude = DEFAULT_VIBRATION_VALUE.high_amplitude, | ||||||
|  |         .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency, | ||||||
|  |         .type = Common::Input::VibrationAmplificationType::Test, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     // Send a slight vibration to test for rumble support |     // Send a slight vibration to test for rumble support | ||||||
|     SetVibration(device_index, test_vibration); |     output_devices[device_index]->SetVibration(test_vibration); | ||||||
|  |  | ||||||
|     // Stop any vibration and return the result |     // Stop any vibration and return the result | ||||||
|     return SetVibration(device_index, DEFAULT_VIBRATION_VALUE); |     return output_devices[device_index]->SetVibration(zero_vibration) == | ||||||
|  |            Common::Input::VibrationError::None; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) { | bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) { | ||||||
|   | |||||||
| @@ -434,6 +434,7 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en | |||||||
|             using namespace std::chrono_literals; |             using namespace std::chrono_literals; | ||||||
|             while (initialized) { |             while (initialized) { | ||||||
|                 SDL_PumpEvents(); |                 SDL_PumpEvents(); | ||||||
|  |                 SendVibrations(); | ||||||
|                 std::this_thread::sleep_for(1ms); |                 std::this_thread::sleep_for(1ms); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
| @@ -531,13 +532,31 @@ Common::Input::VibrationError SDLDriver::SetRumble( | |||||||
|         .type = Common::Input::VibrationAmplificationType::Exponential, |         .type = Common::Input::VibrationAmplificationType::Exponential, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if (!joystick->RumblePlay(new_vibration)) { |     if (vibration.type == Common::Input::VibrationAmplificationType::Test) { | ||||||
|         return Common::Input::VibrationError::Unknown; |         if (!joystick->RumblePlay(new_vibration)) { | ||||||
|  |             return Common::Input::VibrationError::Unknown; | ||||||
|  |         } | ||||||
|  |         return Common::Input::VibrationError::None; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     vibration_queue.Push(VibrationRequest{ | ||||||
|  |         .identifier = identifier, | ||||||
|  |         .vibration = new_vibration, | ||||||
|  |     }); | ||||||
|  |  | ||||||
|     return Common::Input::VibrationError::None; |     return Common::Input::VibrationError::None; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void SDLDriver::SendVibrations() { | ||||||
|  |     while (!vibration_queue.Empty()) { | ||||||
|  |         VibrationRequest request; | ||||||
|  |         vibration_queue.Pop(request); | ||||||
|  |         const auto joystick = GetSDLJoystickByGUID(request.identifier.guid.RawString(), | ||||||
|  |                                                    static_cast<int>(request.identifier.port)); | ||||||
|  |         joystick->RumblePlay(request.vibration); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid, | Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid, | ||||||
|                                                                  s32 axis, float value) const { |                                                                  s32 axis, float value) const { | ||||||
|     Common::ParamPackage params{}; |     Common::ParamPackage params{}; | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ | |||||||
| #include <SDL.h> | #include <SDL.h> | ||||||
|  |  | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
|  | #include "common/threadsafe_queue.h" | ||||||
| #include "input_common/input_engine.h" | #include "input_common/input_engine.h" | ||||||
|  |  | ||||||
| union SDL_Event; | union SDL_Event; | ||||||
| @@ -64,12 +65,20 @@ public: | |||||||
|         const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; |         const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|  |     struct VibrationRequest { | ||||||
|  |         PadIdentifier identifier; | ||||||
|  |         Common::Input::VibrationStatus vibration; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|     void InitJoystick(int joystick_index); |     void InitJoystick(int joystick_index); | ||||||
|     void CloseJoystick(SDL_Joystick* sdl_joystick); |     void CloseJoystick(SDL_Joystick* sdl_joystick); | ||||||
|  |  | ||||||
|     /// Needs to be called before SDL_QuitSubSystem. |     /// Needs to be called before SDL_QuitSubSystem. | ||||||
|     void CloseJoysticks(); |     void CloseJoysticks(); | ||||||
|  |  | ||||||
|  |     /// Takes all vibrations from the queue and sends the command to the controller | ||||||
|  |     void SendVibrations(); | ||||||
|  |  | ||||||
|     Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis, |     Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis, | ||||||
|                                                           float value = 0.1f) const; |                                                           float value = 0.1f) const; | ||||||
|     Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, |     Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, | ||||||
| @@ -107,6 +116,9 @@ private: | |||||||
|     /// Returns true if the button is on the left joycon |     /// Returns true if the button is on the left joycon | ||||||
|     bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const; |     bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const; | ||||||
|  |  | ||||||
|  |     /// Queue of vibration request to controllers | ||||||
|  |     Common::SPSCQueue<VibrationRequest> vibration_queue; | ||||||
|  |  | ||||||
|     /// Map of GUID of a list of corresponding virtual Joysticks |     /// Map of GUID of a list of corresponding virtual Joysticks | ||||||
|     std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map; |     std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map; | ||||||
|     std::mutex joystick_map_mutex; |     std::mutex joystick_map_mutex; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user