Commit 9faefccd48bc37492c146c8f521c8a08de1b05c9

Sam Lantinga 2013-08-21T10:32:04

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

diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c
index 0a4ad6b..05ed473 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 4a5019e..3aeaf08 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 d85ff18..eb4ab2a 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: */