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.
This commit is contained in:
Sam Lantinga 2016-10-04 03:50:28 -07:00
parent 1051dceb14
commit a21a227a87

View File

@ -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);