From a21a227a87556158926277cd23c53c4100334ce7 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 4 Oct 2016 03:50:28 -0700 Subject: [PATCH] Fixed bug 3021 - HapticOpenFromJoystick() problems Joe Thompson With Direct Input device (MOMO Steering Wheel w/FF) with SDL 2.0.3, SDL_HapticOpenFromJoystick() would fail. (Can't set exclusive mode) Now with 2.0.4 rc1, SDL_HapticOpenFromJoystick() succeeds but the the returned SDL_Haptic* cannot be used. Calls to SDL_HapticNewEffect() fail with "Haptic error Unable to create effect" If SDL_HapticOpen() is used instead of HapticOpenFromJoystick(), the device is usable. Calls to HapticNewEffect() succeed with the exact same parameters as the previous failing call. I have attached a proposed patch for this issue. When using SDL_HapticOpenFromJoystick(), the original code did not (re)enumerate the axes. This returned a new haptic device with 0 axes. Later, when a new effect is created, SDL_SYS_SetDirection() would set the flags to include DIEFF_SPHERICAL, regardless of what the caller actually set. (see Line 566 in SDL_dinputhaptic.c). This would cause the SDL_HapticNewEffect() to fail (or interpret the coordinates incorreclty.) The patch moves the call to IDirectInputDevice8_EnumObjects() outside of the if() block so that the axes are (re)enumerated for the new haptic device. Note: For steering wheels it is common for the joystick to have multiple axes (ie steering, throttle, brake), but the haptic portion of the joystick usually only applies to steering. --- src/haptic/windows/SDL_dinputhaptic.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/haptic/windows/SDL_dinputhaptic.c b/src/haptic/windows/SDL_dinputhaptic.c index 0c9d9ec1df3f5..c81432c26e6e4 100644 --- a/src/haptic/windows/SDL_dinputhaptic.c +++ b/src/haptic/windows/SDL_dinputhaptic.c @@ -331,14 +331,6 @@ SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device goto acquire_err; } - /* Get number of axes. */ - ret = IDirectInputDevice8_EnumObjects(haptic->hwdata->device, - DI_DeviceObjectCallback, - haptic, DIDFT_AXIS); - if (FAILED(ret)) { - DI_SetError("Getting device axes", ret); - goto acquire_err; - } /* Acquire the device. */ ret = IDirectInputDevice8_Acquire(haptic->hwdata->device); @@ -348,6 +340,15 @@ SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device } } + /* Get number of axes. */ + ret = IDirectInputDevice8_EnumObjects(haptic->hwdata->device, + DI_DeviceObjectCallback, + haptic, DIDFT_AXIS); + if (FAILED(ret)) { + DI_SetError("Getting device axes", ret); + goto acquire_err; + } + /* Reset all actuators - just in case. */ ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device, DISFFC_RESET);