diff options
| author | 2020-07-10 21:20:50 -0500 | |
|---|---|---|
| committer | 2020-09-29 10:38:25 -0400 | |
| commit | ab88c2f6112edba35bfa91ee8864e760728d16e8 (patch) | |
| tree | 4c7647f97153276733896cbc6e35d929db926b82 /src/input_common/sdl/sdl_impl.cpp | |
| parent | Merge pull request #4719 from lioncash/audio-warn (diff) | |
| download | yuzu-ab88c2f6112edba35bfa91ee8864e760728d16e8.tar.gz yuzu-ab88c2f6112edba35bfa91ee8864e760728d16e8.tar.xz yuzu-ab88c2f6112edba35bfa91ee8864e760728d16e8.zip | |
First implementation of controller rumble
Diffstat (limited to '')
| -rw-r--r-- | src/input_common/sdl/sdl_impl.cpp | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index a9e676f4b..27a96c18b 100644 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <array> | 6 | #include <array> |
| 7 | #include <atomic> | 7 | #include <atomic> |
| 8 | #include <chrono> | ||
| 8 | #include <cmath> | 9 | #include <cmath> |
| 9 | #include <functional> | 10 | #include <functional> |
| 10 | #include <mutex> | 11 | #include <mutex> |
| @@ -78,6 +79,33 @@ public: | |||
| 78 | return state.axes.at(axis) / (32767.0f * range); | 79 | return state.axes.at(axis) / (32767.0f * range); |
| 79 | } | 80 | } |
| 80 | 81 | ||
| 82 | bool RumblePlay(f32 amp_low, f32 amp_high, int time) { | ||
| 83 | const u16 raw_amp_low = static_cast<u16>(amp_low * 0xFFFF); | ||
| 84 | const u16 raw_amp_high = static_cast<u16>(amp_high * 0xFFFF); | ||
| 85 | // Lower drastically the number of state changes | ||
| 86 | if (raw_amp_low >> 11 == last_state_rumble_low >> 11 && | ||
| 87 | raw_amp_high >> 11 == last_state_rumble_high >> 11) { | ||
| 88 | if (raw_amp_low + raw_amp_high != 0 || | ||
| 89 | last_state_rumble_low + last_state_rumble_high == 0) { | ||
| 90 | return false; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | // Don't change state if last vibration was < 20ms | ||
| 94 | const auto now = std::chrono::system_clock::now(); | ||
| 95 | if (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_vibration) < | ||
| 96 | std::chrono::milliseconds(20)) { | ||
| 97 | return raw_amp_low + raw_amp_high == 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | last_vibration = now; | ||
| 101 | last_state_rumble_low = raw_amp_low; | ||
| 102 | last_state_rumble_high = raw_amp_high; | ||
| 103 | if (sdl_joystick) { | ||
| 104 | SDL_JoystickRumble(sdl_joystick.get(), raw_amp_low, raw_amp_high, time); | ||
| 105 | } | ||
| 106 | return false; | ||
| 107 | } | ||
| 108 | |||
| 81 | std::tuple<float, float> GetAnalog(int axis_x, int axis_y, float range) const { | 109 | std::tuple<float, float> GetAnalog(int axis_x, int axis_y, float range) const { |
| 82 | float x = GetAxis(axis_x, range); | 110 | float x = GetAxis(axis_x, range); |
| 83 | float y = GetAxis(axis_y, range); | 111 | float y = GetAxis(axis_y, range); |
| @@ -139,6 +167,9 @@ private: | |||
| 139 | } state; | 167 | } state; |
| 140 | std::string guid; | 168 | std::string guid; |
| 141 | int port; | 169 | int port; |
| 170 | u16 last_state_rumble_high; | ||
| 171 | u16 last_state_rumble_low; | ||
| 172 | std::chrono::time_point<std::chrono::system_clock> last_vibration; | ||
| 142 | std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; | 173 | std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; |
| 143 | std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; | 174 | std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; |
| 144 | mutable std::mutex mutex; | 175 | mutable std::mutex mutex; |
| @@ -207,7 +238,7 @@ void SDLState::InitJoystick(int joystick_index) { | |||
| 207 | sdl_gamecontroller = SDL_GameControllerOpen(joystick_index); | 238 | sdl_gamecontroller = SDL_GameControllerOpen(joystick_index); |
| 208 | } | 239 | } |
| 209 | if (!sdl_joystick) { | 240 | if (!sdl_joystick) { |
| 210 | LOG_ERROR(Input, "failed to open joystick {}", joystick_index); | 241 | LOG_ERROR(Input, "Failed to open joystick {}", joystick_index); |
| 211 | return; | 242 | return; |
| 212 | } | 243 | } |
| 213 | const std::string guid = GetGUID(sdl_joystick); | 244 | const std::string guid = GetGUID(sdl_joystick); |
| @@ -303,6 +334,12 @@ public: | |||
| 303 | return joystick->GetButton(button); | 334 | return joystick->GetButton(button); |
| 304 | } | 335 | } |
| 305 | 336 | ||
| 337 | bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const override { | ||
| 338 | const f32 new_amp_low = pow(amp_low, 0.5f) * (3.0f - 2.0f * pow(amp_low, 0.15f)); | ||
| 339 | const f32 new_amp_high = pow(amp_high, 0.5f) * (3.0f - 2.0f * pow(amp_high, 0.15f)); | ||
| 340 | return joystick->RumblePlay(new_amp_low, new_amp_high, 250); | ||
| 341 | } | ||
| 342 | |||
| 306 | private: | 343 | private: |
| 307 | std::shared_ptr<SDLJoystick> joystick; | 344 | std::shared_ptr<SDLJoystick> joystick; |
| 308 | int button; | 345 | int button; |