Ver código fonte

Added SDL_GameControllerTypeForIndex() and SDL_GameControllerGetType() to return the type of controller attached.

Sam Lantinga 5 anos atrás
pai
commit
b5aff9d7c3

+ 20 - 0
include/SDL_gamecontroller.h

@@ -57,6 +57,15 @@ extern "C" {
 struct _SDL_GameController;
 typedef struct _SDL_GameController SDL_GameController;
 
+typedef enum
+{
+    SDL_CONTROLLER_TYPE_UNKNOWN = 0,
+    SDL_CONTROLLER_TYPE_XBOX360,
+    SDL_CONTROLLER_TYPE_XBOXONE,
+    SDL_CONTROLLER_TYPE_PS3,
+    SDL_CONTROLLER_TYPE_PS4,
+    SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO,
+} SDL_GameControllerType;
 
 typedef enum
 {
@@ -175,6 +184,12 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index);
  */
 extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index);
 
+/**
+ *  Get the type of a game controller.
+ *  This can be called before any controllers are opened.
+ */
+extern DECLSPEC SDL_GameControllerType SDLCALL SDL_GameControllerTypeForIndex(int joystick_index);
+
 /**
  *  Get the mapping of a game controller.
  *  This can be called before any controllers are opened.
@@ -204,6 +219,11 @@ extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL
  */
 extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller);
 
+/**
+ *  Return the type of this currently opened controller
+ */
+extern DECLSPEC SDL_GameControllerType SDLCALL SDL_GameControllerGetType(SDL_GameController *gamecontroller);
+
 /**
  *  Get the player index of an opened game controller, or -1 if it's not available
  *

+ 2 - 0
src/dynapi/SDL_dynapi_overrides.h

@@ -731,3 +731,5 @@
 #define SDL_strtokr SDL_strtokr_REAL
 #define SDL_wcsstr SDL_wcsstr_REAL
 #define SDL_wcsncmp SDL_wcsncmp_REAL
+#define SDL_GameControllerTypeForIndex SDL_GameControllerTypeForIndex_REAL
+#define SDL_GameControllerGetType SDL_GameControllerGetType_REAL

+ 2 - 0
src/dynapi/SDL_dynapi_procs.h

@@ -787,3 +787,5 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_HasARMSIMD,(void),(),return)
 SDL_DYNAPI_PROC(char*,SDL_strtokr,(char *a, const char *b, char **c),(a,b,c),return)
 SDL_DYNAPI_PROC(wchar_t*,SDL_wcsstr,(const wchar_t *a, const wchar_t *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_wcsncmp,(const wchar_t *a, const wchar_t *b, size_t c),(a,b,c),return)
+SDL_DYNAPI_PROC(SDL_GameControllerType,SDL_GameControllerTypeForIndex,(int a),(a),return)
+SDL_DYNAPI_PROC(SDL_GameControllerType,SDL_GameControllerGetType,(SDL_GameController *a),(a),return)

+ 20 - 0
src/joystick/SDL_gamecontroller.c

@@ -1412,6 +1412,17 @@ SDL_GameControllerNameForIndex(int device_index)
 }
 
 
+/**
+ *  Get the type of a game controller.
+ */
+SDL_GameControllerType
+SDL_GameControllerTypeForIndex(int joystick_index)
+{
+    SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(joystick_index);
+    return SDL_GetGameControllerTypeFromGUID(guid);
+}
+
+
 /**
  *  Get the mapping of a game controller.
  *  This can be called before any controllers are opened.
@@ -1743,6 +1754,15 @@ SDL_GameControllerName(SDL_GameController * gamecontroller)
     }
 }
 
+SDL_GameControllerType
+SDL_GameControllerGetType(SDL_GameController *gamecontroller)
+{
+    if (!gamecontroller) {
+        return SDL_CONTROLLER_TYPE_UNKNOWN;
+    }
+    return SDL_GetGameControllerTypeFromGUID(gamecontroller->joystick->guid);
+}
+
 int
 SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller)
 {

+ 45 - 25
src/joystick/SDL_joystick.c

@@ -1158,12 +1158,6 @@ void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *prod
     }
 }
 
-SDL_bool
-SDL_IsJoystickPS4(Uint16 vendor, Uint16 product)
-{
-    return (GuessControllerType(vendor, product) == k_eControllerType_PS4Controller);
-}
-
 SDL_bool
 SDL_IsJoystickNintendoSwitchPro(Uint16 vendor, Uint16 product)
 {
@@ -1172,38 +1166,64 @@ SDL_IsJoystickNintendoSwitchPro(Uint16 vendor, Uint16 product)
             eType == k_eControllerType_SwitchInputOnlyController);
 }
 
-SDL_bool
-SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor, Uint16 product)
+SDL_GameControllerType
+SDL_GetGameControllerTypeFromGUID(SDL_JoystickGUID guid)
 {
-    EControllerType eType = GuessControllerType(vendor, product);
-    return (eType == k_eControllerType_SwitchInputOnlyController);
-}
+    SDL_GameControllerType type;
+    Uint16 vendor, product;
 
-SDL_bool
-SDL_IsJoystickSteamController(Uint16 vendor, Uint16 product)
-{
-    EControllerType eType = GuessControllerType(vendor, product);
-    return (eType == k_eControllerType_SteamController ||
-            eType == k_eControllerType_SteamControllerV2);
+    SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
+    type = SDL_GetGameControllerType(vendor, product);
+    if (type == SDL_CONTROLLER_TYPE_UNKNOWN) {
+        if (SDL_IsJoystickXInput(guid)) {
+            /* This is probably an Xbox One controller */
+            return SDL_CONTROLLER_TYPE_XBOXONE;
+        }
+    }
+    return type;
 }
 
-SDL_bool
-SDL_IsJoystickXbox360(Uint16 vendor, Uint16 product)
+SDL_GameControllerType
+SDL_GetGameControllerType(Uint16 vendor, Uint16 product)
 {
     /* Filter out some bogus values here */
     if (vendor == 0x0000 && product == 0x0000) {
-        return SDL_FALSE;
+        return SDL_CONTROLLER_TYPE_UNKNOWN;
     }
     if (vendor == 0x0001 && product == 0x0001) {
-        return SDL_FALSE;
+        return SDL_CONTROLLER_TYPE_UNKNOWN;
+    }
+
+    switch (GuessControllerType(vendor, product)) {
+    case k_eControllerType_XBox360Controller:
+        return SDL_CONTROLLER_TYPE_XBOX360;
+    case k_eControllerType_XBoxOneController:
+        return SDL_CONTROLLER_TYPE_XBOXONE;
+    case k_eControllerType_PS3Controller:
+        return SDL_CONTROLLER_TYPE_PS3;
+    case k_eControllerType_PS4Controller:
+        return SDL_CONTROLLER_TYPE_PS4;
+    case k_eControllerType_SwitchProController:
+    case k_eControllerType_SwitchInputOnlyController:
+        return SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
+    default:
+        return SDL_CONTROLLER_TYPE_UNKNOWN;
     }
-    return (GuessControllerType(vendor, product) == k_eControllerType_XBox360Controller);
 }
 
 SDL_bool
-SDL_IsJoystickXboxOne(Uint16 vendor, Uint16 product)
+SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor, Uint16 product)
 {
-    return (GuessControllerType(vendor, product) == k_eControllerType_XBoxOneController);
+    EControllerType eType = GuessControllerType(vendor, product);
+    return (eType == k_eControllerType_SwitchInputOnlyController);
+}
+
+SDL_bool
+SDL_IsJoystickSteamController(Uint16 vendor, Uint16 product)
+{
+    EControllerType eType = GuessControllerType(vendor, product);
+    return (eType == k_eControllerType_SteamController ||
+            eType == k_eControllerType_SteamControllerV2);
 }
 
 SDL_bool
@@ -1481,7 +1501,7 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
         }
     }
 
-    if (SDL_IsJoystickPS4(vendor, product) && SDL_IsPS4RemapperRunning()) {
+    if (SDL_GetGameControllerType(vendor, product) == SDL_CONTROLLER_TYPE_PS4 && SDL_IsPS4RemapperRunning()) {
         return SDL_TRUE;
     }
 

+ 4 - 9
src/joystick/SDL_joystick_c.h

@@ -25,6 +25,7 @@
 #include "../SDL_internal.h"
 
 /* Useful functions and variables from SDL_joystick.c */
+#include "SDL_gamecontroller.h"
 #include "SDL_joystick.h"
 
 struct _SDL_JoystickDriver;
@@ -51,22 +52,16 @@ extern int SDL_JoystickGetDeviceIndexFromInstanceID(SDL_JoystickID instance_id);
 /* Function to extract information from an SDL joystick GUID */
 extern void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version);
 
-/* Function to return whether a joystick is a PS4 controller */
-extern SDL_bool SDL_IsJoystickPS4(Uint16 vendor_id, Uint16 product_id);
+/* Function to return the type of a controller */
+extern SDL_GameControllerType SDL_GetGameControllerTypeFromGUID(SDL_JoystickGUID guid);
+extern SDL_GameControllerType SDL_GetGameControllerType(Uint16 vendor, Uint16 product);
 
 /* Function to return whether a joystick is a Nintendo Switch Pro controller */
-extern SDL_bool SDL_IsJoystickNintendoSwitchPro( Uint16 vendor_id, Uint16 product_id );
 extern SDL_bool SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor_id, Uint16 product_id);
 
 /* Function to return whether a joystick is a Steam Controller */
 extern SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id);
 
-/* Function to return whether a joystick is an Xbox 360 controller */
-extern SDL_bool SDL_IsJoystickXbox360(Uint16 vendor_id, Uint16 product_id);
-
-/* Function to return whether a joystick is an Xbox One controller */
-extern SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor_id, Uint16 product_id);
-
 /* Function to return whether a joystick guid comes from the XInput driver */
 extern SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid);
 

+ 1 - 1
src/joystick/hidapi/SDL_hidapi_ps4.c

@@ -141,7 +141,7 @@ static Uint32 crc32(Uint32 crc, const void *data, int count)
 static SDL_bool
 HIDAPI_DriverPS4_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, const char *name)
 {
-    return SDL_IsJoystickPS4(vendor_id, product_id);
+    return (SDL_GetGameControllerType(vendor_id, product_id) == SDL_CONTROLLER_TYPE_PS4);
 }
 
 static const char *

+ 4 - 2
src/joystick/hidapi/SDL_hidapi_xbox360.c

@@ -249,6 +249,8 @@ HIDAPI_DriverXbox360_QuitWindowsGamingInput(SDL_DriverXbox360_Context *ctx)
 static SDL_bool
 HIDAPI_DriverXbox360_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, const char *name)
 {
+    SDL_GameControllerType type = SDL_GameControllerType(vendor_id, product_id);
+
 #if defined(__MACOSX__) || defined(__WIN32__)
     if (vendor_id == 0x045e && product_id == 0x028e && version == 1) {
         /* This is the Steam Virtual Gamepad, which isn't supported by this driver */
@@ -258,9 +260,9 @@ HIDAPI_DriverXbox360_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint
         /* This is the old Bluetooth Xbox One S firmware, which isn't supported by this driver */
         return SDL_FALSE;
     }
-    return SDL_IsJoystickXbox360(vendor_id, product_id) || SDL_IsJoystickXboxOne(vendor_id, product_id);
+    return (type == SDL_CONTROLLER_TYPE_XBOX360 || type == SDL_CONTROLLER_TYPE_XBOXONE);
 #else
-    return SDL_IsJoystickXbox360(vendor_id, product_id);
+    return (type == SDL_CONTROLLER_TYPE_XBOX360);
 #endif
 }
 

+ 1 - 1
src/joystick/hidapi/SDL_hidapi_xboxone.c

@@ -197,7 +197,7 @@ HIDAPI_DriverXboxOne_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint
         return SDL_FALSE;
     }
 #endif
-    return SDL_IsJoystickXboxOne(vendor_id, product_id);
+    return (SDL_GetGameControllerType(vendor_id, product_id) == SDL_CONTROLLER_TYPE_XBOXONE);
 }
 
 static const char *

+ 124 - 122
src/joystick/windows/SDL_dinputjoystick.c

@@ -246,139 +246,141 @@ static const IID IID_IWbemLocator = { 0xdc12a687, 0x737f, 0x11cf,{ 0x88, 0x4d, 0
 static SDL_bool
 WIN_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
 {
-	IWbemLocator*           pIWbemLocator = NULL;
-	IEnumWbemClassObject*   pEnumDevices = NULL;
-	IWbemClassObject*       pDevices[20];
-	IWbemServices*          pIWbemServices = NULL;
-	BSTR                    bstrNamespace = NULL;
-	BSTR                    bstrDeviceID = NULL;
-	BSTR                    bstrClassName = NULL;
-	DWORD                   uReturned = 0;
-	SDL_bool                bIsXinputDevice = SDL_FALSE;
-	UINT                    iDevice = 0;
-	VARIANT                 var;
-	HRESULT                 hr;
-
-	SDL_zero(pDevices);
-
-	// Create WMI
-	hr = CoCreateInstance(&CLSID_WbemLocator,
-		NULL,
-		CLSCTX_INPROC_SERVER,
-		&IID_IWbemLocator,
-		(LPVOID*)&pIWbemLocator);
-	if (FAILED(hr) || pIWbemLocator == NULL)
-		goto LCleanup;
-
-	bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == NULL) goto LCleanup;
-	bstrClassName = SysAllocString(L"Win32_PNPEntity");   if (bstrClassName == NULL) goto LCleanup;
-	bstrDeviceID = SysAllocString(L"DeviceID");          if (bstrDeviceID == NULL)  goto LCleanup;
-
-	// Connect to WMI 
-	hr = IWbemLocator_ConnectServer(pIWbemLocator, bstrNamespace, NULL, NULL, 0L,
-		0L, NULL, NULL, &pIWbemServices);
-	if (FAILED(hr) || pIWbemServices == NULL) {
-		goto LCleanup;
-    }
-
-	// Switch security level to IMPERSONATE. 
-	CoSetProxyBlanket((IUnknown *)pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
-		RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
-
-	hr = IWbemServices_CreateInstanceEnum(pIWbemServices, bstrClassName, 0, NULL, &pEnumDevices);
-	if (FAILED(hr) || pEnumDevices == NULL)
-		goto LCleanup;
-
-	// Loop over all devices
-	for (;;) {
-		// Get 20 at a time
-		hr = IEnumWbemClassObject_Next(pEnumDevices, 10000, SDL_arraysize(pDevices), pDevices, &uReturned);
-		if (FAILED(hr)) {
-			goto LCleanup;
+    IWbemLocator*           pIWbemLocator = NULL;
+    IEnumWbemClassObject*   pEnumDevices = NULL;
+    IWbemClassObject*       pDevices[20];
+    IWbemServices*          pIWbemServices = NULL;
+    BSTR                    bstrNamespace = NULL;
+    BSTR                    bstrDeviceID = NULL;
+    BSTR                    bstrClassName = NULL;
+    DWORD                   uReturned = 0;
+    SDL_bool                bIsXinputDevice = SDL_FALSE;
+    UINT                    iDevice = 0;
+    VARIANT                 var;
+    HRESULT                 hr;
+
+    SDL_zero(pDevices);
+
+    // Create WMI
+    hr = CoCreateInstance(&CLSID_WbemLocator,
+        NULL,
+        CLSCTX_INPROC_SERVER,
+        &IID_IWbemLocator,
+        (LPVOID*)&pIWbemLocator);
+    if (FAILED(hr) || pIWbemLocator == NULL)
+        goto LCleanup;
+
+    bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == NULL) goto LCleanup;
+    bstrClassName = SysAllocString(L"Win32_PNPEntity");   if (bstrClassName == NULL) goto LCleanup;
+    bstrDeviceID = SysAllocString(L"DeviceID");          if (bstrDeviceID == NULL)  goto LCleanup;
+
+    // Connect to WMI 
+    hr = IWbemLocator_ConnectServer(pIWbemLocator, bstrNamespace, NULL, NULL, 0L,
+        0L, NULL, NULL, &pIWbemServices);
+    if (FAILED(hr) || pIWbemServices == NULL) {
+        goto LCleanup;
+    }
+
+    // Switch security level to IMPERSONATE. 
+    CoSetProxyBlanket((IUnknown *)pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
+        RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
+
+    hr = IWbemServices_CreateInstanceEnum(pIWbemServices, bstrClassName, 0, NULL, &pEnumDevices);
+    if (FAILED(hr) || pEnumDevices == NULL)
+        goto LCleanup;
+
+    // Loop over all devices
+    for (;;) {
+        // Get 20 at a time
+        hr = IEnumWbemClassObject_Next(pEnumDevices, 10000, SDL_arraysize(pDevices), pDevices, &uReturned);
+        if (FAILED(hr)) {
+            goto LCleanup;
         }
-		if (uReturned == 0) {
-			break;
+        if (uReturned == 0) {
+            break;
         }
 
-		for (iDevice = 0; iDevice < uReturned; iDevice++) {
-			// For each device, get its device ID
-			hr = IWbemClassObject_Get(pDevices[iDevice], bstrDeviceID, 0L, &var, NULL, NULL);
-			if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL) {
-				// Check if the device ID contains "IG_".  If it does, then it's an XInput device
-				// This information can not be found from DirectInput 
-				if (SDL_wcsstr(var.bstrVal, L"IG_")) {
-					char *bstrVal = WIN_StringToUTF8(var.bstrVal);
-
-					// If it does, then get the VID/PID from var.bstrVal
-					DWORD dwPid = 0, dwVid = 0, dwVidPid;
-					const char *strVid, *strPid;
-					strVid = SDL_strstr(bstrVal, "VID_");
-					if (strVid && SDL_sscanf(strVid, "VID_%4X", &dwVid) != 1)
-						dwVid = 0;
-					strPid = SDL_strstr(bstrVal, "PID_");
-					if (strPid && SDL_sscanf(strPid, "PID_%4X", &dwPid) != 1)
-						dwPid = 0;
-
-					SDL_free(bstrVal);
-
-					// Compare the VID/PID to the DInput device
-					dwVidPid = MAKELONG(dwVid, dwPid);
-					if (dwVidPid == pGuidProductFromDirectInput->Data1) {
-						bIsXinputDevice = SDL_TRUE;
-						goto LCleanup;
-					}
-				}
-			}
-			IWbemClassObject_Release(pDevices[iDevice]);
-		}
-	}
+        for (iDevice = 0; iDevice < uReturned; iDevice++) {
+            // For each device, get its device ID
+            hr = IWbemClassObject_Get(pDevices[iDevice], bstrDeviceID, 0L, &var, NULL, NULL);
+            if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL) {
+                // Check if the device ID contains "IG_".  If it does, then it's an XInput device
+                // This information can not be found from DirectInput 
+                if (SDL_wcsstr(var.bstrVal, L"IG_")) {
+                    char *bstrVal = WIN_StringToUTF8(var.bstrVal);
+
+                    // If it does, then get the VID/PID from var.bstrVal
+                    DWORD dwPid = 0, dwVid = 0, dwVidPid;
+                    const char *strVid, *strPid;
+                    strVid = SDL_strstr(bstrVal, "VID_");
+                    if (strVid && SDL_sscanf(strVid, "VID_%4X", &dwVid) != 1)
+                        dwVid = 0;
+                    strPid = SDL_strstr(bstrVal, "PID_");
+                    if (strPid && SDL_sscanf(strPid, "PID_%4X", &dwPid) != 1)
+                        dwPid = 0;
+
+                    SDL_free(bstrVal);
+
+                    // Compare the VID/PID to the DInput device
+                    dwVidPid = MAKELONG(dwVid, dwPid);
+                    if (dwVidPid == pGuidProductFromDirectInput->Data1) {
+                        bIsXinputDevice = SDL_TRUE;
+                        goto LCleanup;
+                    }
+                }
+            }
+            IWbemClassObject_Release(pDevices[iDevice]);
+        }
+    }
 
 LCleanup:
-	if (bstrNamespace) {
-		SysFreeString(bstrNamespace);
-    }
-	if (bstrDeviceID) {
-		SysFreeString(bstrDeviceID);
-    }
-	if (bstrClassName) {
-		SysFreeString(bstrClassName);
-    }
-	for (iDevice = 0; iDevice < SDL_arraysize(pDevices); iDevice++) {
-		if (pDevices[iDevice]) {
-			IWbemClassObject_Release(pDevices[iDevice]);
-		}
-	}
-	if (pEnumDevices) {
-		IEnumWbemClassObject_Release(pEnumDevices);
-	}
-	if (pIWbemLocator) {
-		IWbemLocator_Release(pIWbemLocator);
-	}
-	if (pIWbemServices) {
-		IWbemServices_Release(pIWbemServices);
-	}
-
-	return bIsXinputDevice;
+    if (bstrNamespace) {
+        SysFreeString(bstrNamespace);
+    }
+    if (bstrDeviceID) {
+        SysFreeString(bstrDeviceID);
+    }
+    if (bstrClassName) {
+        SysFreeString(bstrClassName);
+    }
+    for (iDevice = 0; iDevice < SDL_arraysize(pDevices); iDevice++) {
+        if (pDevices[iDevice]) {
+            IWbemClassObject_Release(pDevices[iDevice]);
+        }
+    }
+    if (pEnumDevices) {
+        IEnumWbemClassObject_Release(pEnumDevices);
+    }
+    if (pIWbemLocator) {
+        IWbemLocator_Release(pIWbemLocator);
+    }
+    if (pIWbemServices) {
+        IWbemServices_Release(pIWbemServices);
+    }
+
+    return bIsXinputDevice;
 }
 #endif /* 0 */
 
 static SDL_bool
 SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
 {
-	UINT i;
-
-	if (!SDL_XINPUT_Enabled()) {
-		return SDL_FALSE;
-	}
-
-	if (SDL_memcmp(&pGuidProductFromDirectInput->Data4[2], "PIDVID", 6) == 0) {
-		Uint16 vendor_id = (Uint16)LOWORD(pGuidProductFromDirectInput->Data1);
-		Uint16 product_id = (Uint16)HIWORD(pGuidProductFromDirectInput->Data1);
-		if (SDL_IsJoystickXbox360(vendor_id, product_id) || SDL_IsJoystickXboxOne(vendor_id, product_id) ||
-			(vendor_id == 0x28DE && product_id == 0x11FF)) {
-			return SDL_TRUE;
-		}
-	}
+    UINT i;
+
+    if (!SDL_XINPUT_Enabled()) {
+        return SDL_FALSE;
+    }
+
+    if (SDL_memcmp(&pGuidProductFromDirectInput->Data4[2], "PIDVID", 6) == 0) {
+        Uint16 vendor_id = (Uint16)LOWORD(pGuidProductFromDirectInput->Data1);
+        Uint16 product_id = (Uint16)HIWORD(pGuidProductFromDirectInput->Data1);
+        SDL_GameControllerType type = SDL_GetGameControllerType(vendor_id, product_id);
+        if (type == SDL_CONTROLLER_TYPE_XBOX360 ||
+            type == SDL_CONTROLLER_TYPE_XBOXONE ||
+            (vendor_id == 0x28DE && product_id == 0x11FF)) {
+            return SDL_TRUE;
+        }
+    }
 
     /* Go through RAWINPUT (WinXP and later) to find HID devices. */
     /* Cache this if we end up using it. */

+ 20 - 1
test/testgamecontroller.c

@@ -292,7 +292,26 @@ main(int argc, char *argv[])
         {
             nController++;
             name = SDL_GameControllerNameForIndex(i);
-            description = "Controller";
+            switch (SDL_GameControllerTypeForIndex(i)) {
+            case SDL_CONTROLLER_TYPE_XBOX360:
+                description = "XBox 360 Controller";
+                break;
+            case SDL_CONTROLLER_TYPE_XBOXONE:
+                description = "XBox One Controller";
+                break;
+            case SDL_CONTROLLER_TYPE_PS3:
+                description = "PS3 Controller";
+                break;
+            case SDL_CONTROLLER_TYPE_PS4:
+                description = "PS4 Controller";
+                break;
+            case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
+                description = "Nintendo Switch Pro Controller";
+                break;
+            default:
+                description = "Game Controller";
+                break;
+            }
         } else {
             name = SDL_JoystickNameForIndex(i);
             description = "Joystick";