From: Tyson Whitehead twhitehead@gmail.com
Programs should check and/or set DIPROP_AUTOCENTER to ensure it is the value they want. Likely some do not though if the developers never tested on devices where the Windows' default wasn't correct for them.
These programs will be broken under Wine if the Wine default is different than the Windows. This commit adds an 'Autocenter' appkey (to the existing 'Joysticks' and 'MouseWarpOverride' keys) so users can override the DIPROP_AUTOCENTER default in this case.
The Wine default is currently always DIPROPAUTOCENTER_ON, which is the correct Windows default for the MS Sidewinder 2. I don't know any other correct defaults as this is the only FF device I have to test. I started a project to collect defaults (and verify operations) for other devices though
https://github.com/twhitehead/issue-wine-ff-autocenter
so hopefully a good heuristic and a more comprehensive set of defaults can be implemented at some point. --- dlls/dinput/device.c | 56 ++++++++++++++++++++++++++++++++++++-- dlls/dinput/joystick_hid.c | 3 +- 2 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 31240d03f65..2aa50a844f1 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -145,6 +145,59 @@ DWORD get_config_key( HKEY defkey, HKEY appkey, const WCHAR *name, WCHAR *buffer return ERROR_FILE_NOT_FOUND; }
+static BOOL device_instance_autocenter_initial( DIDEVICEINSTANCEW *instance ) +{ + static const WCHAR on_str[] = {'o', 'n', 0}; + static const WCHAR off_str[] = {'o', 'f', 'f', 0}; + static const WCHAR joystick_key[] = {'A', 'u', 't', 'o', 'c', 'e', 'n', 't', 'e', 'r', 0}; + WCHAR buffer[MAX_PATH]; + HKEY hkey, appkey, temp; + BOOL autocenter = DIPROPAUTOCENTER_ON; /* MS Sidewinder 2 initial value. No others known yet. There is + a project to collect other device defaults to improved this + https://github.com/twhitehead/issue-wine-ff-autocenter */ + + get_app_key( &hkey, &appkey ); + + /* Autocenter settings are in the 'Autocenter' subkey */ + if (appkey) + { + if (RegOpenKeyW( appkey, joystick_key, &temp )) temp = 0; + RegCloseKey( appkey ); + appkey = temp; + } + + if (hkey) + { + if (RegOpenKeyW( hkey, joystick_key, &temp )) temp = 0; + RegCloseKey( hkey ); + hkey = temp; + } + + /* Look for the "controllername"="on"/"off" key */ + if (!get_config_key( hkey, appkey, instance->tszInstanceName, buffer, sizeof(buffer) )) + { + if (!wcscmp( on_str, buffer )) + { + TRACE( "Joystick '%s' autocenter on based on registry key.\n", debugstr_w(instance->tszInstanceName) ); + autocenter = DIPROPAUTOCENTER_ON; + } + else if (!wcscmp( off_str, buffer )) + { + TRACE( "Joystick '%s' autocenter off based on registry key.\n", debugstr_w(instance->tszInstanceName) ); + autocenter = DIPROPAUTOCENTER_OFF; + } + else + { + WARN( "Joystick '%s' autocenter registry key invalid (can only be 'on' or 'off').\n", debugstr_w(instance->tszInstanceName) ); + } + } + + if (appkey) RegCloseKey( appkey ); + if (hkey) RegCloseKey( hkey ); + + return autocenter; +} + BOOL device_instance_is_disabled( DIDEVICEINSTANCEW *instance, BOOL *override ) { static const WCHAR disabled_str[] = {'d', 'i', 's', 'a', 'b', 'l', 'e', 'd', 0}; @@ -2153,9 +2206,8 @@ void dinput_device_init( struct dinput_device *device, const struct dinput_devic device->caps.dwSize = sizeof(DIDEVCAPS); device->caps.dwFlags = DIDC_ATTACHED | DIDC_EMULATED; device->device_gain = 10000; - device->autocenter = DIPROPAUTOCENTER_ON; + device->autocenter = device_instance_autocenter_initial( &device->instance ); device->force_feedback_state = DIGFFS_STOPPED | DIGFFS_EMPTY; - InitializeCriticalSectionEx( &device->crit, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO ); dinput_internal_addref( (device->dinput = dinput) ); device->vtbl = vtbl;
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 27d08fd2af2..dc7f8b25f70 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -2036,7 +2036,7 @@ HRESULT hid_joystick_create_device( struct dinput *dinput, const GUID *guid, IDi *out = NULL;
if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY; - dinput_device_init( &impl->base, &hid_joystick_vtbl, guid, dinput ); + InitializeCriticalSectionEx( &impl->base.crit, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO ); impl->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": hid_joystick.base.crit"); impl->base.dwCoopLevel = DISCL_NONEXCLUSIVE | DISCL_BACKGROUND; impl->base.read_event = CreateEventW( NULL, TRUE, FALSE, NULL ); @@ -2050,6 +2050,7 @@ HRESULT hid_joystick_create_device( struct dinput *dinput, const GUID *guid, IDi hr = hid_joystick_device_try_open( impl->device_path, &impl->device, &impl->preparsed, &attrs, &impl->caps, &impl->base.instance, dinput->dwVersion ); } + dinput_device_init( &impl->base, &hid_joystick_vtbl, guid, dinput ); if (hr != DI_OK) goto failed;
impl->base.caps.dwDevType = impl->base.instance.dwDevType;