Procházet zdrojové kódy

input_common: Add multiple vibration curves

german77 před 4 roky
rodič
revize
7348e205d9

+ 9 - 1
src/core/hid/emulated_controller.cpp

@@ -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;

+ 19 - 14
src/input_common/drivers/sdl_driver.cpp

@@ -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) {
-        return (amplitude + std::pow(amplitude, 0.3f)) * 0.5f * 0xFFFF;
+    const auto process_amplitude_exp = [](f32 amplitude, f32 factor) {
+        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;
     }
     }