diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index 0a4ad6b0d..05ed473d2 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -851,6 +851,9 @@ SDL_GameControllerOpen(int device_index) SDL_GameController *gamecontroller; SDL_GameController *gamecontrollerlist; ControllerMapping_t *pSupportedController = NULL; +#ifdef SDL_JOYSTICK_DINPUT + SDL_bool bIsXinputDevice; +#endif if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) { SDL_SetError("There are %d joysticks available", SDL_NumJoysticks()); @@ -883,6 +886,11 @@ SDL_GameControllerOpen(int device_index) return NULL; } +#ifdef SDL_JOYSTICK_DINPUT + /* check if we think we should open this device in XInput mode */ + bIsXinputDevice = SDL_SYS_IsXInputDeviceIndex(device_index); +#endif + SDL_memset(gamecontroller, 0, (sizeof *gamecontroller)); gamecontroller->joystick = SDL_JoystickOpen(device_index); if ( !gamecontroller->joystick ) { @@ -890,6 +898,19 @@ SDL_GameControllerOpen(int device_index) return NULL; } +#ifdef SDL_JOYSTICK_DINPUT + if ( !SDL_SYS_IsXInputJoystick( gamecontroller->joystick ) && bIsXinputDevice ) + { + /* we tried to open the controller in XInput mode and failed, so get the mapping again for the direct input variant if possible */ + SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID( device_index ); + pSupportedController = SDL_PrivateGetControllerMappingForGUID(&jGUID); + if ( !pSupportedController ) { + SDL_SetError("Failed to open device in XInput mode (%d)", device_index ); + return (NULL); + } + } +#endif + SDL_PrivateLoadButtonMapping( &gamecontroller->mapping, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping ); /* Add joystick to list */ diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 4a5019e73..3aeaf0821 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -111,6 +111,7 @@ extern SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick); #ifdef SDL_JOYSTICK_DINPUT /* Function to get the current instance id of the joystick located at device_index */ extern SDL_bool SDL_SYS_IsXInputDeviceIndex( int device_index ); +extern SDL_bool SDL_SYS_IsXInputJoystick(SDL_Joystick * joystick); #endif /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/joystick/windows/SDL_dxjoystick.c b/src/joystick/windows/SDL_dxjoystick.c index d85ff18a4..eb4ab2a3a 100644 --- a/src/joystick/windows/SDL_dxjoystick.c +++ b/src/joystick/windows/SDL_dxjoystick.c @@ -1776,6 +1776,12 @@ SDL_bool SDL_SYS_IsXInputDeviceIndex(int device_index) return device->bXInputDevice; } +/* return SDL_TRUE if this device was opened with XInput */ +SDL_bool SDL_SYS_IsXInputJoystick(SDL_Joystick * joystick) +{ + return joystick->hwdata->bXInputDevice; +} + #endif /* SDL_JOYSTICK_DINPUT */ /* vi: set ts=4 sw=4 expandtab: */