Description
I'm starting work on updating/extending Linux force feedback API and one of my goals is to expose the number and an array that contains the device's ffb-enabled axes. As I'm mainly working with USB PID driver, I already have a POC of obtaining this data.
What prompted this is that currently, there's no way in Linux to actually get FFB axis information. One could maybe read it from USB PID descriptor, but that wouldn't work for devices with custom protocols. This causes issues with Richard Burns Rally, as this game incorrectly initializes a CONSTANT_FORCE
effect with all the FFB axes that contain FFB_ACTUATOR
flag and then trycing to update cAxes
value which leads to DIERR_INVALIDPARAM
.
Now, this flag is set by wine while enumerating virtual device's axes and while an axis index is < number of FFB axes, flag is applied.
Here comes the SDL part. Currently, because of this omission in Linux ff api, SDL_SYS_HapticOpenFromFD
(source) handles it like that:
// Set the data.
haptic->hwdata->fd = fd;
haptic->supported = EV_IsHaptic(fd);
haptic->naxes = 2; // Hardcoded for now, not sure if it's possible to find out.
This means, that every device which has FFB functionality and at least two axes, will report FFB on X
, Y
.
While updated API would mean a lot of steering wheels would correctly report only 1 axis, a lot of USB PID wheels still include X
and Y
in their DIRECTION_ENABLE
usage. This, again, would lead to broken FFB.
On windows, there's a possibility of overwriting some joystick capabilities with registry entries, which ends up removing FFB_ACTUATOR
flag from a selected axis. This doesn't work in wine.
My idea would be to introduce SDL_HINT_JOYSTICK_HAPTIC_AXES
(subject to change) that could overwrite haptic->naxes
for a given VID:PID
similar to SDL_HINT_JOYSTICK_DEVICE
but with added naxes
value.
Ideally, I'd like if this value could have some kind of "wildcard" use with maybe 0xFFFF/0xFFFF/0x1
entry that would limit haptic->naxes
for every discovered FFB device. This way, it could be used as a simple proton fix. I think if just checking against VIDPIDs, this could easily fit with the current usage of const char *SDL_GetHint(const char *name)
because the matching could be performed after device init in the global bool SDL_SYS_HapticOpen(SDL_Haptic *haptic)
(not platform-specific).
I can implement this myself but wanted to better explain myself before opening up a PR and maybe getting some more ideas and comments before starting work on this.
Activity