Browse Source

SDL
- detect that you tried to open a gamecontroller in xinput mode and failed, then re-get the mapping for the dinput variant you did open (and most likely now just fail the open)

CR: SamL

Sam Lantinga 11 years ago
parent
commit
9faefccd48

+ 21 - 0
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 */

+ 1 - 0
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: */

+ 6 - 0
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: */