input_common: cache vibration tests
This commit is contained in:
		| @@ -100,7 +100,6 @@ enum class CameraError { | |||||||
| enum class VibrationAmplificationType { | enum class VibrationAmplificationType { | ||||||
|     Linear, |     Linear, | ||||||
|     Exponential, |     Exponential, | ||||||
|     Test, |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // Analog properties for calibration | // Analog properties for calibration | ||||||
| @@ -325,6 +324,10 @@ public: | |||||||
|         return VibrationError::NotSupported; |         return VibrationError::NotSupported; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     virtual bool IsVibrationEnabled() { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) { |     virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) { | ||||||
|         return PollingError::NotSupported; |         return PollingError::NotSupported; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -970,14 +970,7 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v | |||||||
|            Common::Input::VibrationError::None; |            Common::Input::VibrationError::None; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool EmulatedController::TestVibration(std::size_t device_index) { | bool EmulatedController::IsVibrationEnabled(std::size_t device_index) { | ||||||
|     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_index = NpadIdTypeToIndex(npad_id_type); | ||||||
|     const auto& player = Settings::values.players.GetValue()[player_index]; |     const auto& player = Settings::values.players.GetValue()[player_index]; | ||||||
|  |  | ||||||
| @@ -985,31 +978,15 @@ bool EmulatedController::TestVibration(std::size_t device_index) { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const Common::Input::VibrationStatus test_vibration = { |     if (device_index >= output_devices.size()) { | ||||||
|         .low_amplitude = 0.001f, |         return false; | ||||||
|         .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency, |     } | ||||||
|         .high_amplitude = 0.001f, |  | ||||||
|         .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency, |  | ||||||
|         .type = Common::Input::VibrationAmplificationType::Test, |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     const Common::Input::VibrationStatus zero_vibration = { |     if (!output_devices[device_index]) { | ||||||
|         .low_amplitude = DEFAULT_VIBRATION_VALUE.low_amplitude, |         return false; | ||||||
|         .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 |     return output_devices[device_index]->IsVibrationEnabled(); | ||||||
|     output_devices[device_index]->SetVibration(test_vibration); |  | ||||||
|  |  | ||||||
|     // Wait for about 15ms to ensure the controller is ready for the stop command |  | ||||||
|     std::this_thread::sleep_for(std::chrono::milliseconds(15)); |  | ||||||
|  |  | ||||||
|     // Stop any vibration and return the result |  | ||||||
|     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) { | ||||||
| @@ -1234,12 +1211,6 @@ bool EmulatedController::IsConnected(bool get_temporary_value) const { | |||||||
|     return is_connected; |     return is_connected; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool EmulatedController::IsVibrationEnabled() const { |  | ||||||
|     const auto player_index = NpadIdTypeToIndex(npad_id_type); |  | ||||||
|     const auto& player = Settings::values.players.GetValue()[player_index]; |  | ||||||
|     return player.vibration_enabled; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| NpadIdType EmulatedController::GetNpadIdType() const { | NpadIdType EmulatedController::GetNpadIdType() const { | ||||||
|     std::scoped_lock lock{mutex}; |     std::scoped_lock lock{mutex}; | ||||||
|     return npad_id_type; |     return npad_id_type; | ||||||
|   | |||||||
| @@ -206,9 +206,6 @@ public: | |||||||
|      */ |      */ | ||||||
|     bool IsConnected(bool get_temporary_value = false) const; |     bool IsConnected(bool get_temporary_value = false) const; | ||||||
|  |  | ||||||
|     /// Returns true if vibration is enabled |  | ||||||
|     bool IsVibrationEnabled() const; |  | ||||||
|  |  | ||||||
|     /// Removes all callbacks created from input devices |     /// Removes all callbacks created from input devices | ||||||
|     void UnloadInput(); |     void UnloadInput(); | ||||||
|  |  | ||||||
| @@ -339,7 +336,7 @@ public: | |||||||
|      * Sends a small vibration to the output device |      * Sends a small vibration to the output device | ||||||
|      * @return true if SetVibration was successfull |      * @return true if SetVibration was successfull | ||||||
|      */ |      */ | ||||||
|     bool TestVibration(std::size_t device_index); |     bool IsVibrationEnabled(std::size_t device_index); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Sets the desired data to be polled from a controller |      * Sets the desired data to be polled from a controller | ||||||
|   | |||||||
| @@ -867,7 +867,7 @@ bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (!controller.device->IsVibrationEnabled()) { |     if (!controller.device->IsVibrationEnabled(device_index)) { | ||||||
|         if (controller.vibration[device_index].latest_vibration_value.low_amplitude != 0.0f || |         if (controller.vibration[device_index].latest_vibration_value.low_amplitude != 0.0f || | ||||||
|             controller.vibration[device_index].latest_vibration_value.high_amplitude != 0.0f) { |             controller.vibration[device_index].latest_vibration_value.high_amplitude != 0.0f) { | ||||||
|             // Send an empty vibration to stop any vibrations. |             // Send an empty vibration to stop any vibrations. | ||||||
| @@ -1000,7 +1000,7 @@ void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npa | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     controller.vibration[device_index].device_mounted = |     controller.vibration[device_index].device_mounted = | ||||||
|         controller.device->TestVibration(device_index); |         controller.device->IsVibrationEnabled(device_index); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) { | void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) { | ||||||
|   | |||||||
| @@ -324,7 +324,7 @@ bool GCAdapter::GetGCEndpoint(libusb_device* device) { | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| Common::Input::VibrationError GCAdapter::SetRumble( | Common::Input::VibrationError GCAdapter::SetVibration( | ||||||
|     const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) { |     const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) { | ||||||
|     const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f; |     const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f; | ||||||
|     const auto processed_amplitude = |     const auto processed_amplitude = | ||||||
| @@ -338,6 +338,10 @@ Common::Input::VibrationError GCAdapter::SetRumble( | |||||||
|     return Common::Input::VibrationError::None; |     return Common::Input::VibrationError::None; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool GCAdapter::IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) { | ||||||
|  |     return rumble_enabled; | ||||||
|  | } | ||||||
|  |  | ||||||
| void GCAdapter::UpdateVibrations() { | void GCAdapter::UpdateVibrations() { | ||||||
|     // Use 8 states to keep the switching between on/off fast enough for |     // Use 8 states to keep the switching between on/off fast enough for | ||||||
|     // a human to feel different vibration strenght |     // a human to feel different vibration strenght | ||||||
|   | |||||||
| @@ -25,9 +25,11 @@ public: | |||||||
|     explicit GCAdapter(std::string input_engine_); |     explicit GCAdapter(std::string input_engine_); | ||||||
|     ~GCAdapter() override; |     ~GCAdapter() override; | ||||||
|  |  | ||||||
|     Common::Input::VibrationError SetRumble( |     Common::Input::VibrationError SetVibration( | ||||||
|         const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; |         const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; | ||||||
|  |  | ||||||
|  |     bool IsVibrationEnabled(const PadIdentifier& identifier) override; | ||||||
|  |  | ||||||
|     /// Used for automapping features |     /// Used for automapping features | ||||||
|     std::vector<Common::ParamPackage> GetInputDevices() const override; |     std::vector<Common::ParamPackage> GetInputDevices() const override; | ||||||
|     ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override; |     ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override; | ||||||
|   | |||||||
| @@ -114,6 +114,20 @@ public: | |||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     void EnableVibration(bool is_enabled) { | ||||||
|  |         has_vibration = is_enabled; | ||||||
|  |         is_vibration_tested = true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     bool HasVibration() const { | ||||||
|  |         return has_vibration; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     bool IsVibrationTested() const { | ||||||
|  |         return is_vibration_tested; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * The Pad identifier of the joystick |      * The Pad identifier of the joystick | ||||||
|      */ |      */ | ||||||
| @@ -236,6 +250,8 @@ private: | |||||||
|     u64 last_motion_update{}; |     u64 last_motion_update{}; | ||||||
|     bool has_gyro{false}; |     bool has_gyro{false}; | ||||||
|     bool has_accel{false}; |     bool has_accel{false}; | ||||||
|  |     bool has_vibration{false}; | ||||||
|  |     bool is_vibration_tested{false}; | ||||||
|     BasicMotion motion; |     BasicMotion motion; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -517,7 +533,7 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const { | |||||||
|     return devices; |     return devices; | ||||||
| } | } | ||||||
|  |  | ||||||
| Common::Input::VibrationError SDLDriver::SetRumble( | Common::Input::VibrationError SDLDriver::SetVibration( | ||||||
|     const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) { |     const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) { | ||||||
|     const auto joystick = |     const auto joystick = | ||||||
|         GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port)); |         GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port)); | ||||||
| @@ -546,13 +562,6 @@ Common::Input::VibrationError SDLDriver::SetRumble( | |||||||
|         .type = Common::Input::VibrationAmplificationType::Exponential, |         .type = Common::Input::VibrationAmplificationType::Exponential, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if (vibration.type == Common::Input::VibrationAmplificationType::Test) { |  | ||||||
|         if (!joystick->RumblePlay(new_vibration)) { |  | ||||||
|             return Common::Input::VibrationError::Unknown; |  | ||||||
|         } |  | ||||||
|         return Common::Input::VibrationError::None; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     vibration_queue.Push(VibrationRequest{ |     vibration_queue.Push(VibrationRequest{ | ||||||
|         .identifier = identifier, |         .identifier = identifier, | ||||||
|         .vibration = new_vibration, |         .vibration = new_vibration, | ||||||
| @@ -561,6 +570,45 @@ Common::Input::VibrationError SDLDriver::SetRumble( | |||||||
|     return Common::Input::VibrationError::None; |     return Common::Input::VibrationError::None; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) { | ||||||
|  |     const auto joystick = | ||||||
|  |         GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port)); | ||||||
|  |  | ||||||
|  |     constexpr Common::Input::VibrationStatus test_vibration{ | ||||||
|  |         .low_amplitude = 1, | ||||||
|  |         .low_frequency = 160.0f, | ||||||
|  |         .high_amplitude = 1, | ||||||
|  |         .high_frequency = 320.0f, | ||||||
|  |         .type = Common::Input::VibrationAmplificationType::Exponential, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     constexpr Common::Input::VibrationStatus zero_vibration{ | ||||||
|  |         .low_amplitude = 0, | ||||||
|  |         .low_frequency = 160.0f, | ||||||
|  |         .high_amplitude = 0, | ||||||
|  |         .high_frequency = 320.0f, | ||||||
|  |         .type = Common::Input::VibrationAmplificationType::Exponential, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     if (joystick->IsVibrationTested()) { | ||||||
|  |         return joystick->HasVibration(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // First vibration might fail | ||||||
|  |     joystick->RumblePlay(test_vibration); | ||||||
|  |  | ||||||
|  |     // Wait for about 15ms to ensure the controller is ready for the stop command | ||||||
|  |     std::this_thread::sleep_for(std::chrono::milliseconds(15)); | ||||||
|  |  | ||||||
|  |     if (!joystick->RumblePlay(zero_vibration)) { | ||||||
|  |         joystick->EnableVibration(false); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     joystick->EnableVibration(true); | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
| void SDLDriver::SendVibrations() { | void SDLDriver::SendVibrations() { | ||||||
|     while (!vibration_queue.Empty()) { |     while (!vibration_queue.Empty()) { | ||||||
|         VibrationRequest request; |         VibrationRequest request; | ||||||
|   | |||||||
| @@ -61,9 +61,11 @@ public: | |||||||
|  |  | ||||||
|     bool IsStickInverted(const Common::ParamPackage& params) override; |     bool IsStickInverted(const Common::ParamPackage& params) override; | ||||||
|  |  | ||||||
|     Common::Input::VibrationError SetRumble( |     Common::Input::VibrationError SetVibration( | ||||||
|         const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; |         const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; | ||||||
|  |  | ||||||
|  |     bool IsVibrationEnabled(const PadIdentifier& identifier) override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     struct VibrationRequest { |     struct VibrationRequest { | ||||||
|         PadIdentifier identifier; |         PadIdentifier identifier; | ||||||
|   | |||||||
| @@ -108,12 +108,17 @@ public: | |||||||
|                          [[maybe_unused]] const Common::Input::LedStatus& led_status) {} |                          [[maybe_unused]] const Common::Input::LedStatus& led_status) {} | ||||||
|  |  | ||||||
|     // Sets rumble to a controller |     // Sets rumble to a controller | ||||||
|     virtual Common::Input::VibrationError SetRumble( |     virtual Common::Input::VibrationError SetVibration( | ||||||
|         [[maybe_unused]] const PadIdentifier& identifier, |         [[maybe_unused]] const PadIdentifier& identifier, | ||||||
|         [[maybe_unused]] const Common::Input::VibrationStatus& vibration) { |         [[maybe_unused]] const Common::Input::VibrationStatus& vibration) { | ||||||
|         return Common::Input::VibrationError::NotSupported; |         return Common::Input::VibrationError::NotSupported; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // Returns true if device supports vibrations | ||||||
|  |     virtual bool IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Sets polling mode to a controller |     // Sets polling mode to a controller | ||||||
|     virtual Common::Input::PollingError SetPollingMode( |     virtual Common::Input::PollingError SetPollingMode( | ||||||
|         [[maybe_unused]] const PadIdentifier& identifier, |         [[maybe_unused]] const PadIdentifier& identifier, | ||||||
|   | |||||||
| @@ -763,7 +763,11 @@ public: | |||||||
|  |  | ||||||
|     Common::Input::VibrationError SetVibration( |     Common::Input::VibrationError SetVibration( | ||||||
|         const Common::Input::VibrationStatus& vibration_status) override { |         const Common::Input::VibrationStatus& vibration_status) override { | ||||||
|         return input_engine->SetRumble(identifier, vibration_status); |         return input_engine->SetVibration(identifier, vibration_status); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     bool IsVibrationEnabled() override { | ||||||
|  |         return input_engine->IsVibrationEnabled(identifier); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Common::Input::PollingError SetPollingMode(Common::Input::PollingMode polling_mode) override { |     Common::Input::PollingError SetPollingMode(Common::Input::PollingMode polling_mode) override { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user