input_common: Add multiple vibration curves
This commit is contained in:
		| @@ -251,7 +251,8 @@ void EmulatedController::RestoreConfig() { | |||||||
|     ReloadFromSettings(); |     ReloadFromSettings(); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::vector<Common::ParamPackage> EmulatedController::GetMappedDevices(DeviceIndex device_index) const { | std::vector<Common::ParamPackage> EmulatedController::GetMappedDevices( | ||||||
|  |     DeviceIndex device_index) const { | ||||||
|     std::vector<Common::ParamPackage> devices; |     std::vector<Common::ParamPackage> devices; | ||||||
|     for (const auto& param : button_params) { |     for (const auto& param : button_params) { | ||||||
|         if (!param.Has("engine")) { |         if (!param.Has("engine")) { | ||||||
| @@ -658,6 +659,10 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v | |||||||
|     const auto& player = Settings::values.players.GetValue()[player_index]; |     const auto& player = Settings::values.players.GetValue()[player_index]; | ||||||
|     const f32 strength = static_cast<f32>(player.vibration_strength) / 100.0f; |     const f32 strength = static_cast<f32>(player.vibration_strength) / 100.0f; | ||||||
|  |  | ||||||
|  |     if (!player.vibration_enabled) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Exponential amplification is too strong at low amplitudes. Switch to a linear |     // Exponential amplification is too strong at low amplitudes. Switch to a linear | ||||||
|     // amplification if strength is set below 0.7f |     // amplification if strength is set below 0.7f | ||||||
|     const Input::VibrationAmplificationType type = |     const Input::VibrationAmplificationType type = | ||||||
| @@ -860,6 +865,9 @@ AnalogSticks EmulatedController::GetSticks() const { | |||||||
|     } |     } | ||||||
|     // Some drivers like stick from buttons need constant refreshing |     // Some drivers like stick from buttons need constant refreshing | ||||||
|     for (auto& device : stick_devices) { |     for (auto& device : stick_devices) { | ||||||
|  |         if (!device) { | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|         device->SoftUpdate(); |         device->SoftUpdate(); | ||||||
|     } |     } | ||||||
|     return controller.analog_stick_state; |     return controller.analog_stick_state; | ||||||
|   | |||||||
| @@ -94,7 +94,6 @@ public: | |||||||
|  |  | ||||||
|     bool RumblePlay(const Input::VibrationStatus vibration) { |     bool RumblePlay(const Input::VibrationStatus vibration) { | ||||||
|         constexpr u32 rumble_max_duration_ms = 1000; |         constexpr u32 rumble_max_duration_ms = 1000; | ||||||
|  |  | ||||||
|         if (sdl_controller) { |         if (sdl_controller) { | ||||||
|             return SDL_GameControllerRumble( |             return SDL_GameControllerRumble( | ||||||
|                        sdl_controller.get(), static_cast<u16>(vibration.low_amplitude), |                        sdl_controller.get(), static_cast<u16>(vibration.low_amplitude), | ||||||
| @@ -520,25 +519,31 @@ Input::VibrationError SDLDriver::SetRumble(const PadIdentifier& identifier, | |||||||
|                                            const Input::VibrationStatus vibration) { |                                            const Input::VibrationStatus vibration) { | ||||||
|     const auto joystick = |     const auto joystick = | ||||||
|         GetSDLJoystickByGUID(identifier.guid.Format(), static_cast<int>(identifier.port)); |         GetSDLJoystickByGUID(identifier.guid.Format(), static_cast<int>(identifier.port)); | ||||||
|     const auto process_amplitude = [](f32 amplitude) { |     const auto process_amplitude_exp = [](f32 amplitude, f32 factor) { | ||||||
|         return (amplitude + std::pow(amplitude, 0.3f)) * 0.5f * 0xFFFF; |         return (amplitude + std::pow(amplitude, factor)) * 0.5f * 0xFFFF; | ||||||
|     }; |     }; | ||||||
|     const Input::VibrationStatus exponential_vibration{ |  | ||||||
|         .low_amplitude = process_amplitude(vibration.low_amplitude), |     // Default exponential curve for rumble | ||||||
|  |     f32 factor = 0.35f; | ||||||
|  |  | ||||||
|  |     // If vibration is set as a linear output use a flatter value | ||||||
|  |     if (vibration.type == Input::VibrationAmplificationType::Linear) { | ||||||
|  |         factor = 0.5f; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Amplitude for HD rumble needs no modification | ||||||
|  |     if (joystick->HasHDRumble()) { | ||||||
|  |         factor = 1.0f; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const Input::VibrationStatus new_vibration{ | ||||||
|  |         .low_amplitude = process_amplitude_exp(vibration.low_amplitude, factor), | ||||||
|         .low_frequency = vibration.low_frequency, |         .low_frequency = vibration.low_frequency, | ||||||
|         .high_amplitude = process_amplitude(vibration.high_amplitude), |         .high_amplitude = process_amplitude_exp(vibration.high_amplitude, factor), | ||||||
|         .high_frequency = vibration.high_frequency, |         .high_frequency = vibration.high_frequency, | ||||||
|         .type = Input::VibrationAmplificationType::Exponential, |         .type = Input::VibrationAmplificationType::Exponential, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     Input::VibrationStatus new_vibration{}; |  | ||||||
|  |  | ||||||
|     if (vibration.type == Input::VibrationAmplificationType::Linear || joystick->HasHDRumble()) { |  | ||||||
|         new_vibration = vibration; |  | ||||||
|     } else { |  | ||||||
|         new_vibration = exponential_vibration; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (!joystick->RumblePlay(new_vibration)) { |     if (!joystick->RumblePlay(new_vibration)) { | ||||||
|         return Input::VibrationError::Unknown; |         return Input::VibrationError::Unknown; | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user