Fixed bug 4854 - Add a way to extend the values in controller_type.h Added a hint SDL_HINT_GAMECONTROLLERTYPE to allow overriding the built-in controller type database
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index 04e92e1..a3a5373 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -469,6 +469,24 @@ extern "C" {
#define SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING "SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING"
/**
+ * \brief A variable that overrides the automatic controller type detection
+ *
+ * The variable should be comma separated entries, in the form: VID/PID=type
+ *
+ * The VID and PID should be hexadecimal with exactly 4 digits, e.g. 0x00fd
+ *
+ * The type should be one of:
+ * Xbox360
+ * XboxOne
+ * PS3
+ * PS4
+ * SwitchPro
+ *
+ * This hint affects what driver is used, and must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER)
+ */
+#define SDL_HINT_GAMECONTROLLERTYPE "SDL_GAMECONTROLLERTYPE"
+
+/**
* \brief A variable that lets you manually hint extra gamecontroller db entries.
*
* The variable should be newline delimited rows of gamecontroller config data, see SDL_gamecontroller.h
diff --git a/src/joystick/controller_type.h b/src/joystick/controller_type.h
index a744a2b..0ea1cbf 100644
--- a/src/joystick/controller_type.h
+++ b/src/joystick/controller_type.h
@@ -540,6 +540,30 @@ static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x28de, 0x1202 ), k_eControllerType_SteamControllerV2, NULL }, // Valve Bluetooth Steam Controller (HEADCRAB)
};
+static SDL_INLINE const char *GetControllerTypeOverride( int nVID, int nPID )
+{
+ const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERTYPE);
+ if (hint) {
+ char key[32];
+ const char *spot = NULL;
+
+ SDL_snprintf(key, sizeof(key), "0x%.4x/0x%.4x=", nVID, nPID);
+ spot = SDL_strstr(hint, key);
+ if (!spot) {
+ SDL_snprintf(key, sizeof(key), "0x%.4X/0x%.4X=", nVID, nPID);
+ spot = SDL_strstr(hint, key);
+ }
+ if (spot) {
+ spot += SDL_strlen(key);
+ if (SDL_strncmp(spot, "k_eControllerType_", 18) == 0) {
+ spot += 18;
+ }
+ return spot;
+ }
+ }
+ return NULL;
+}
+
static SDL_INLINE EControllerType GuessControllerType( int nVID, int nPID )
{
#if 0//def _DEBUG
@@ -565,6 +589,37 @@ static SDL_INLINE EControllerType GuessControllerType( int nVID, int nPID )
unsigned int unDeviceID = MAKE_CONTROLLER_ID( nVID, nPID );
int iIndex;
+
+ const char *pszOverride = GetControllerTypeOverride( nVID, nPID );
+ if ( pszOverride )
+ {
+ if ( SDL_strncasecmp( pszOverride, "Xbox360", 7 ) == 0 )
+ {
+ return k_eControllerType_XBox360Controller;
+ }
+ if ( SDL_strncasecmp( pszOverride, "XboxOne", 7 ) == 0 )
+ {
+ return k_eControllerType_XBoxOneController;
+ }
+ if ( SDL_strncasecmp( pszOverride, "PS3", 3 ) == 0 )
+ {
+ return k_eControllerType_PS3Controller;
+ }
+ if ( SDL_strncasecmp( pszOverride, "PS4", 3 ) == 0 )
+ {
+ return k_eControllerType_PS4Controller;
+ }
+ if ( SDL_strncasecmp( pszOverride, "SwitchPro", 9 ) == 0 )
+ {
+ return k_eControllerType_SwitchProController;
+ }
+ if ( SDL_strncasecmp( pszOverride, "Steam", 5 ) == 0 )
+ {
+ return k_eControllerType_SteamController;
+ }
+ return k_eControllerType_UnknownNonSteamController;
+ }
+
for ( iIndex = 0; iIndex < sizeof( arrControllers ) / sizeof( arrControllers[0] ); ++iIndex )
{
if ( unDeviceID == arrControllers[ iIndex ].m_unDeviceID )