On 1/1/24 17:38, Tyson Whitehead wrote:
Would like to get disabling force feedback auto-centering working so that trimming will work properly with force feedback devices in flight simulators.
Currently the call to disable it is a stub
static HRESULT dinput_device_set_property( IDirectInputDevice8W *iface, const GUID *guid, const DIPROPHEADER *header ) { ... case (DWORD_PTR)DIPROP_AUTOCENTER: { const DIPROPDWORD *value = (const DIPROPDWORD *)header; if (!(impl->caps.dwFlags & DIDC_FORCEFEEDBACK)) return DIERR_UNSUPPORTED; if ( header->dwHow != DIPH_DEVICE) return DIERR_INVALIDPARAM; impl->vtbl->set_property( iface, FIXME( "DIPROP_AUTOCENTER stub!\n" ); impl->autocenter = value->dwData; return DI_OK; } ... }
After having looked through the wine, SDL, and kernel code and read up on the force feedback HID physical interface device (PID) usage table reports, I am guessing this was left as a stub because it doesn't fit in with the current design of dipnut communicating with the backend via HID reports. The issue being that auto centering, unlike everything else, isn't part of the PID specification, so there isn't a predefined report that can be used for this (see table 0x0f)
https://www.usb.org/document-library/hid-usage-tables-14
Although I am no wine or Windows code expert, I am guess this leaves the following options
- leave it disabled in the backend and emulate it via a frontend spring effect
- abuse an existing HID report to communicate it
- add a WINE specific HID report to communicate it
- add a WINE specific IOCTL to communicate it
For the first option, I mean have the winebus backends disable it via the kernel or an SDL call and then have the dinput layer enable simulate it by adding a default spring effect. This then lets the dinput frontend disable it again by removing or disabling its spring effect. For the second one I mean something like reserve an effect ID for specifying auto centering.
It would be nice to figure how Windows does it, and do the same. The idea is that we should be able to communicate to HID PID devices directly for when the hidraw is used.
There are tests in dinput/tests that emulate a virtual HID PID device with various custom HID device descriptors. It can be a bit tedious and difficult to figure, but if you can find an actual HID PID device which has dinput auto-center support on Windows, using its descriptor could be a good starting point to figure the required HID features. Some people have also been successfully using Wireshark to monitor HID reports over USB with HID PID devices to figure the expected report sequences.
Also, maybe Windows also supports some kind of fallback (or maybe it just works like that), as long as spring effects are available, in which case we should do the same.
Both of these are inspired by the fact that from the kernel code, it seems auto centering for HID devices is an undocumented use of the first effect ID for a spring effect
https://github.com/torvalds/linux/blob/610a9b8f/drivers/hid/usbhid/hid-pidff... https://github.com/torvalds/linux/blob/610a9b8f/drivers/hid/usbhid/hid-pidff...
Maybe doing something similar in dinput is the way to go if that's truly how it works, although that is only going to work with device-managed effect ids (which I don't think we do with SDL / evdev backends). The spring effect fallback is probably a good solution (even a primary solution if figuring how native works proves too difficult).
Cheers,