mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-11-10 13:44:17 +00:00
SDL_HapticRumblePlay rumble for gamepad without SDL_HAPTIC_LEFTRIGHT support (#181)
This commit is contained in:
parent
e5a8b49c93
commit
e32bc1a0a3
2 changed files with 49 additions and 17 deletions
|
@ -775,9 +775,21 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve
|
|||
state->jsId = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(state->controller));
|
||||
state->haptic = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(state->controller));
|
||||
state->hapticEffectId = -1;
|
||||
if (state->haptic != nullptr && (SDL_HapticQuery(state->haptic) & SDL_HAPTIC_LEFTRIGHT) == 0) {
|
||||
SDL_HapticClose(state->haptic);
|
||||
state->haptic = nullptr;
|
||||
state->hapticMethod = GAMEPAD_HAPTIC_METHOD_NONE;
|
||||
if (state->haptic != nullptr) {
|
||||
if ((SDL_HapticQuery(state->haptic) & SDL_HAPTIC_LEFTRIGHT) == 0) {
|
||||
if (SDL_HapticRumbleSupported(state->haptic)) {
|
||||
if (SDL_HapticRumbleInit(state->haptic) == 0) {
|
||||
state->hapticMethod = GAMEPAD_HAPTIC_METHOD_SIMPLERUMBLE;
|
||||
}
|
||||
}
|
||||
if (state->hapticMethod == GAMEPAD_HAPTIC_METHOD_NONE) {
|
||||
SDL_HapticClose(state->haptic);
|
||||
state->haptic = nullptr;
|
||||
}
|
||||
} else {
|
||||
state->hapticMethod = GAMEPAD_HAPTIC_METHOD_LEFTRIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(state->controller)),
|
||||
|
@ -883,8 +895,12 @@ void SdlInputHandler::rumble(unsigned short controllerNumber, unsigned short low
|
|||
}
|
||||
|
||||
// Stop the last effect we played
|
||||
if (m_GamepadState[controllerNumber].hapticEffectId >= 0) {
|
||||
SDL_HapticDestroyEffect(haptic, m_GamepadState[controllerNumber].hapticEffectId);
|
||||
if (m_GamepadState[controllerNumber].hapticMethod == GAMEPAD_HAPTIC_METHOD_LEFTRIGHT) {
|
||||
if (m_GamepadState[controllerNumber].hapticEffectId >= 0) {
|
||||
SDL_HapticDestroyEffect(haptic, m_GamepadState[controllerNumber].hapticEffectId);
|
||||
}
|
||||
} else if (m_GamepadState[controllerNumber].hapticMethod == GAMEPAD_HAPTIC_METHOD_SIMPLERUMBLE) {
|
||||
SDL_HapticRumbleStop(haptic);
|
||||
}
|
||||
|
||||
// If this callback is telling us to stop both motors, don't bother queuing a new effect
|
||||
|
@ -892,22 +908,30 @@ void SdlInputHandler::rumble(unsigned short controllerNumber, unsigned short low
|
|||
return;
|
||||
}
|
||||
|
||||
SDL_HapticEffect effect;
|
||||
SDL_memset(&effect, 0, sizeof(effect));
|
||||
effect.type = SDL_HAPTIC_LEFTRIGHT;
|
||||
if (m_GamepadState[controllerNumber].hapticMethod == GAMEPAD_HAPTIC_METHOD_LEFTRIGHT) {
|
||||
SDL_HapticEffect effect;
|
||||
SDL_memset(&effect, 0, sizeof(effect));
|
||||
effect.type = SDL_HAPTIC_LEFTRIGHT;
|
||||
|
||||
// The effect should last until we are instructed to stop or change it
|
||||
effect.leftright.length = SDL_HAPTIC_INFINITY;
|
||||
// The effect should last until we are instructed to stop or change it
|
||||
effect.leftright.length = SDL_HAPTIC_INFINITY;
|
||||
|
||||
// SDL haptics range from 0-32767 but XInput uses 0-65535, so divide by 2 to correct for SDL's scaling
|
||||
effect.leftright.large_magnitude = lowFreqMotor / 2;
|
||||
effect.leftright.small_magnitude = highFreqMotor / 2;
|
||||
// SDL haptics range from 0-32767 but XInput uses 0-65535, so divide by 2 to correct for SDL's scaling
|
||||
effect.leftright.large_magnitude = lowFreqMotor / 2;
|
||||
effect.leftright.small_magnitude = highFreqMotor / 2;
|
||||
|
||||
// Play the new effect
|
||||
m_GamepadState[controllerNumber].hapticEffectId = SDL_HapticNewEffect(haptic, &effect);
|
||||
if (m_GamepadState[controllerNumber].hapticEffectId >= 0) {
|
||||
SDL_HapticRunEffect(haptic, m_GamepadState[controllerNumber].hapticEffectId, 1);
|
||||
// Play the new effect
|
||||
m_GamepadState[controllerNumber].hapticEffectId = SDL_HapticNewEffect(haptic, &effect);
|
||||
if (m_GamepadState[controllerNumber].hapticEffectId >= 0) {
|
||||
SDL_HapticRunEffect(haptic, m_GamepadState[controllerNumber].hapticEffectId, 1);
|
||||
}
|
||||
} else if (m_GamepadState[controllerNumber].hapticMethod == GAMEPAD_HAPTIC_METHOD_SIMPLERUMBLE) {
|
||||
SDL_HapticRumblePlay(haptic,
|
||||
std::min(1.0, (GAMEPAD_HAPTIC_SIMPLE_HIFREQ_MOTOR_WEIGHT*highFreqMotor +
|
||||
GAMEPAD_HAPTIC_SIMPLE_LOWFREQ_MOTOR_WEIGHT*lowFreqMotor) / 65535.0),
|
||||
SDL_HAPTIC_INFINITY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SdlInputHandler::handleTouchFingerEvent(SDL_TouchFingerEvent* event)
|
||||
|
|
|
@ -9,6 +9,7 @@ struct GamepadState {
|
|||
SDL_GameController* controller;
|
||||
SDL_JoystickID jsId;
|
||||
SDL_Haptic* haptic;
|
||||
int hapticMethod;
|
||||
int hapticEffectId;
|
||||
short index;
|
||||
|
||||
|
@ -21,6 +22,13 @@ struct GamepadState {
|
|||
#define MAX_GAMEPADS 4
|
||||
#define MAX_FINGERS 2
|
||||
|
||||
#define GAMEPAD_HAPTIC_METHOD_NONE 0
|
||||
#define GAMEPAD_HAPTIC_METHOD_LEFTRIGHT 1
|
||||
#define GAMEPAD_HAPTIC_METHOD_SIMPLERUMBLE 2
|
||||
|
||||
#define GAMEPAD_HAPTIC_SIMPLE_HIFREQ_MOTOR_WEIGHT 0.33
|
||||
#define GAMEPAD_HAPTIC_SIMPLE_LOWFREQ_MOTOR_WEIGHT 0.8
|
||||
|
||||
class SdlInputHandler
|
||||
{
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue