|
|
|
@ -5,6 +5,7 @@ |
|
|
|
#include <algorithm>
|
|
|
|
#include <array>
|
|
|
|
#include <atomic>
|
|
|
|
#include <chrono>
|
|
|
|
#include <cmath>
|
|
|
|
#include <functional>
|
|
|
|
#include <mutex>
|
|
|
|
@ -78,6 +79,33 @@ public: |
|
|
|
return state.axes.at(axis) / (32767.0f * range); |
|
|
|
} |
|
|
|
|
|
|
|
bool RumblePlay(f32 amp_low, f32 amp_high, int time) { |
|
|
|
const u16 raw_amp_low = static_cast<u16>(amp_low * 0xFFFF); |
|
|
|
const u16 raw_amp_high = static_cast<u16>(amp_high * 0xFFFF); |
|
|
|
// Lower drastically the number of state changes
|
|
|
|
if (raw_amp_low >> 11 == last_state_rumble_low >> 11 && |
|
|
|
raw_amp_high >> 11 == last_state_rumble_high >> 11) { |
|
|
|
if (raw_amp_low + raw_amp_high != 0 || |
|
|
|
last_state_rumble_low + last_state_rumble_high == 0) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
// Don't change state if last vibration was < 20ms
|
|
|
|
const auto now = std::chrono::system_clock::now(); |
|
|
|
if (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_vibration) < |
|
|
|
std::chrono::milliseconds(20)) { |
|
|
|
return raw_amp_low + raw_amp_high == 0; |
|
|
|
} |
|
|
|
|
|
|
|
last_vibration = now; |
|
|
|
last_state_rumble_low = raw_amp_low; |
|
|
|
last_state_rumble_high = raw_amp_high; |
|
|
|
if (sdl_joystick) { |
|
|
|
SDL_JoystickRumble(sdl_joystick.get(), raw_amp_low, raw_amp_high, time); |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
std::tuple<float, float> GetAnalog(int axis_x, int axis_y, float range) const { |
|
|
|
float x = GetAxis(axis_x, range); |
|
|
|
float y = GetAxis(axis_y, range); |
|
|
|
@ -139,6 +167,9 @@ private: |
|
|
|
} state; |
|
|
|
std::string guid; |
|
|
|
int port; |
|
|
|
u16 last_state_rumble_high; |
|
|
|
u16 last_state_rumble_low; |
|
|
|
std::chrono::time_point<std::chrono::system_clock> last_vibration; |
|
|
|
std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; |
|
|
|
std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; |
|
|
|
mutable std::mutex mutex; |
|
|
|
@ -207,7 +238,7 @@ void SDLState::InitJoystick(int joystick_index) { |
|
|
|
sdl_gamecontroller = SDL_GameControllerOpen(joystick_index); |
|
|
|
} |
|
|
|
if (!sdl_joystick) { |
|
|
|
LOG_ERROR(Input, "failed to open joystick {}", joystick_index); |
|
|
|
LOG_ERROR(Input, "Failed to open joystick {}", joystick_index); |
|
|
|
return; |
|
|
|
} |
|
|
|
const std::string guid = GetGUID(sdl_joystick); |
|
|
|
@ -303,6 +334,12 @@ public: |
|
|
|
return joystick->GetButton(button); |
|
|
|
} |
|
|
|
|
|
|
|
bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const override { |
|
|
|
const f32 new_amp_low = pow(amp_low, 0.5f) * (3.0f - 2.0f * pow(amp_low, 0.15f)); |
|
|
|
const f32 new_amp_high = pow(amp_high, 0.5f) * (3.0f - 2.0f * pow(amp_high, 0.15f)); |
|
|
|
return joystick->RumblePlay(new_amp_low, new_amp_high, 250); |
|
|
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
std::shared_ptr<SDLJoystick> joystick; |
|
|
|
int button; |
|
|
|
|