summaryrefslogtreecommitdiff
path: root/src/input_common/sdl
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/sdl')
-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 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
306private: 343private:
307 std::shared_ptr<SDLJoystick> joystick; 344 std::shared_ptr<SDLJoystick> joystick;
308 int button; 345 int button;