From: Tomasz Pakuła tomasz.pakula.oficjalny@gmail.com
Wine will now create PID axes in the virtual descriptor based on the haptic axes found in the SDL joystick.
With the recent SDL hint SDL_JOYSTICK_HAPTIC_AXES, it's possible to limit the exposed FFB axes to just one, even if device presents more. This, in turn fixes force feedback in Richard Burns Rally which includes all ffb axes on effect creation, but then updates this effec with only the steering axis. Changing cAxes and rgdwAxes after effect creation is forbidden and renders force feedback broken.
This issue is not wine-specific as the same thing happens on Windows for all steering wheels which define more than one FFB axis. On windows, this can be worked around with registry hacks which remove DIDFT_FFACTUATOR and DIDOI_FFACTUATOR from second axis dwType and dwFlags.
SDL_HapticNumAxes() was available since SDL 2.0 --- dlls/winebus.sys/bus_sdl.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 29a0d2cf8d2..f96ab1c3885 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -96,6 +96,7 @@ MAKE_FUNCPTR(SDL_HapticClose); MAKE_FUNCPTR(SDL_HapticDestroyEffect); MAKE_FUNCPTR(SDL_HapticGetEffectStatus); MAKE_FUNCPTR(SDL_HapticNewEffect); +MAKE_FUNCPTR(SDL_HapticNumAxes); MAKE_FUNCPTR(SDL_HapticOpenFromJoystick); MAKE_FUNCPTR(SDL_HapticPause); MAKE_FUNCPTR(SDL_HapticQuery); @@ -226,6 +227,8 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl, BOOL force)
if ((impl->effect_support & EFFECT_SUPPORT_PHYSICAL)) { + LONG num_axes; + /* SDL_HAPTIC_SQUARE doesn't exist */ if (force || (impl->effect_support & SDL_HAPTIC_SINE)) usages[count++] = PID_USAGE_ET_SINE; if (force || (impl->effect_support & SDL_HAPTIC_TRIANGLE)) usages[count++] = PID_USAGE_ET_TRIANGLE; @@ -238,7 +241,13 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl, BOOL force) if (force || (impl->effect_support & SDL_HAPTIC_CONSTANT)) usages[count++] = PID_USAGE_ET_CONSTANT_FORCE; if (force || (impl->effect_support & SDL_HAPTIC_RAMP)) usages[count++] = PID_USAGE_ET_RAMP;
- if (!hid_device_add_physical(&impl->unix_device, usages, count, 2)) + /* Get the number of FFB-enabled axes and hardcode to 2 in case of error. + * (previously hardcoded number of FFB axes) */ + num_axes = pSDL_HapticNumAxes(impl->sdl_haptic); + if (num_axes < 0) + num_axes = 2; + + if (!hid_device_add_physical(&impl->unix_device, usages, count, num_axes)) return FALSE; }
@@ -1122,6 +1131,7 @@ NTSTATUS sdl_bus_init(void *args) LOAD_FUNCPTR(SDL_HapticDestroyEffect); LOAD_FUNCPTR(SDL_HapticGetEffectStatus); LOAD_FUNCPTR(SDL_HapticNewEffect); + LOAD_FUNCPTR(SDL_HapticNumAxes); LOAD_FUNCPTR(SDL_HapticOpenFromJoystick); LOAD_FUNCPTR(SDL_HapticPause); LOAD_FUNCPTR(SDL_HapticQuery);