summaryrefslogtreecommitdiff
path: root/src/input_common/sdl/sdl_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/sdl/sdl_impl.cpp')
-rw-r--r--src/input_common/sdl/sdl_impl.cpp39
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
314private: 351private:
315 std::shared_ptr<SDLJoystick> joystick; 352 std::shared_ptr<SDLJoystick> joystick;
316 int button; 353 int button;