diff options
Diffstat (limited to 'src/input_common/sdl/sdl_impl.cpp')
| -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 0b0095978..bd480570a 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> |
| @@ -79,6 +80,33 @@ public: | |||
| 79 | return state.axes.at(axis) / (32767.0f * range); | 80 | return state.axes.at(axis) / (32767.0f * range); |
| 80 | } | 81 | } |
| 81 | 82 | ||
| 83 | bool RumblePlay(f32 amp_low, f32 amp_high, int time) { | ||
| 84 | const u16 raw_amp_low = static_cast<u16>(amp_low * 0xFFFF); | ||
| 85 | const u16 raw_amp_high = static_cast<u16>(amp_high * 0xFFFF); | ||
| 86 | // Lower drastically the number of state changes | ||
| 87 | if (raw_amp_low >> 11 == last_state_rumble_low >> 11 && | ||
| 88 | raw_amp_high >> 11 == last_state_rumble_high >> 11) { | ||
| 89 | if (raw_amp_low + raw_amp_high != 0 || | ||
| 90 | last_state_rumble_low + last_state_rumble_high == 0) { | ||
| 91 | return false; | ||
| 92 | } | ||
| 93 | } | ||
| 94 | // Don't change state if last vibration was < 20ms | ||
| 95 | const auto now = std::chrono::system_clock::now(); | ||
| 96 | if (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_vibration) < | ||
| 97 | std::chrono::milliseconds(20)) { | ||
| 98 | return raw_amp_low + raw_amp_high == 0; | ||
| 99 | } | ||
| 100 | |||
| 101 | last_vibration = now; | ||
| 102 | last_state_rumble_low = raw_amp_low; | ||
| 103 | last_state_rumble_high = raw_amp_high; | ||
| 104 | if (sdl_joystick) { | ||
| 105 | SDL_JoystickRumble(sdl_joystick.get(), raw_amp_low, raw_amp_high, time); | ||
| 106 | } | ||
| 107 | return false; | ||
| 108 | } | ||
| 109 | |||
| 82 | std::tuple<float, float> GetAnalog(int axis_x, int axis_y, float range) const { | 110 | std::tuple<float, float> GetAnalog(int axis_x, int axis_y, float range) const { |
| 83 | float x = GetAxis(axis_x, range); | 111 | float x = GetAxis(axis_x, range); |
| 84 | float y = GetAxis(axis_y, range); | 112 | float y = GetAxis(axis_y, range); |
| @@ -144,6 +172,9 @@ private: | |||
| 144 | } state; | 172 | } state; |
| 145 | std::string guid; | 173 | std::string guid; |
| 146 | int port; | 174 | int port; |
| 175 | u16 last_state_rumble_high; | ||
| 176 | u16 last_state_rumble_low; | ||
| 177 | std::chrono::time_point<std::chrono::system_clock> last_vibration; | ||
| 147 | std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; | 178 | std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; |
| 148 | std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; | 179 | std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; |
| 149 | mutable std::mutex mutex; | 180 | mutable std::mutex mutex; |
| @@ -215,7 +246,7 @@ void SDLState::InitJoystick(int joystick_index) { | |||
| 215 | sdl_gamecontroller = SDL_GameControllerOpen(joystick_index); | 246 | sdl_gamecontroller = SDL_GameControllerOpen(joystick_index); |
| 216 | } | 247 | } |
| 217 | if (!sdl_joystick) { | 248 | if (!sdl_joystick) { |
| 218 | LOG_ERROR(Input, "failed to open joystick {}", joystick_index); | 249 | LOG_ERROR(Input, "Failed to open joystick {}", joystick_index); |
| 219 | return; | 250 | return; |
| 220 | } | 251 | } |
| 221 | const std::string guid = GetGUID(sdl_joystick); | 252 | const std::string guid = GetGUID(sdl_joystick); |
| @@ -311,6 +342,12 @@ public: | |||
| 311 | return joystick->GetButton(button); | 342 | return joystick->GetButton(button); |
| 312 | } | 343 | } |
| 313 | 344 | ||
| 345 | bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const override { | ||
| 346 | const f32 new_amp_low = pow(amp_low, 0.5f) * (3.0f - 2.0f * pow(amp_low, 0.15f)); | ||
| 347 | const f32 new_amp_high = pow(amp_high, 0.5f) * (3.0f - 2.0f * pow(amp_high, 0.15f)); | ||
| 348 | return joystick->RumblePlay(new_amp_low, new_amp_high, 250); | ||
| 349 | } | ||
| 350 | |||
| 314 | private: | 351 | private: |
| 315 | std::shared_ptr<SDLJoystick> joystick; | 352 | std::shared_ptr<SDLJoystick> joystick; |
| 316 | int button; | 353 | int button; |