From a8ac58854901c62d91e01e9d6957af1e2e02fe1d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 7 Mar 2018 13:30:40 -0800 Subject: [PATCH] Added SDL_GameControllerMappingForDeviceIndex() to get the mapping for a controller before it's opened --- WhatsNew.txt | 8 ++++ include/SDL_gamecontroller.h | 8 ++++ src/dynapi/SDL_dynapi_overrides.h | 1 + src/dynapi/SDL_dynapi_procs.h | 1 + src/joystick/SDL_gamecontroller.c | 45 ++++++++++++++++++++--- src/joystick/SDL_sysjoystick.h | 5 --- src/joystick/windows/SDL_xinputjoystick.c | 12 ------ 7 files changed, 58 insertions(+), 22 deletions(-) diff --git a/WhatsNew.txt b/WhatsNew.txt index c574946c0979a..0cd283e535115 100644 --- a/WhatsNew.txt +++ b/WhatsNew.txt @@ -1,6 +1,14 @@ This is a list of major changes in SDL's version history. +--------------------------------------------------------------------------- +2.0.9: +--------------------------------------------------------------------------- + +General: +* Added SDL_GameControllerMappingForDeviceIndex() to get the mapping for a controller before it's opened + + --------------------------------------------------------------------------- 2.0.8: --------------------------------------------------------------------------- diff --git a/include/SDL_gamecontroller.h b/include/SDL_gamecontroller.h index 2e024be650634..f7e03cdacac49 100644 --- a/include/SDL_gamecontroller.h +++ b/include/SDL_gamecontroller.h @@ -175,6 +175,14 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index); */ extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index); +/** + * Get the mapping of a game controller. + * This can be called before any controllers are opened. + * + * \return the mapping string. Must be freed with SDL_free(). Returns NULL if no mapping is available + */ +extern DECLSPEC char *SDLCALL SDL_GameControllerMappingForDeviceIndex(int joystick_index); + /** * Open a game controller for use. * The index passed as an argument refers to the N'th game controller on the system. diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 1ec2eaffd7278..77a73e52c282f 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -669,3 +669,4 @@ #define SDL_WinRTGetDeviceFamily SDL_WinRTGetDeviceFamily_REAL #define SDL_log10 SDL_log10_REAL #define SDL_log10f SDL_log10f_REAL +#define SDL_GameControllerMappingForDeviceIndex SDL_GameControllerMappingForDeviceIndex_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index b715d33ced74e..1b57a2a0519e5 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -707,3 +707,4 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_IsAndroidTV,(void),(),return) #endif SDL_DYNAPI_PROC(double,SDL_log10,(double a),(a),return) SDL_DYNAPI_PROC(float,SDL_log10f,(float a),(a),return) +SDL_DYNAPI_PROC(char*,SDL_GameControllerMappingForDeviceIndex,(int a),(a),return) diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index 68ac762378ae9..3326c466fed68 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -425,6 +425,12 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickG } pSupportedController = pSupportedController->next; } +#if SDL_JOYSTICK_XINPUT + if (guid->data[14] == 'x') { + /* This is an XInput device */ + return s_pXInputMapping; + } +#endif return NULL; } @@ -1033,11 +1039,6 @@ static ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index) name = SDL_JoystickNameForIndex(device_index); guid = SDL_JoystickGetDeviceGUID(device_index); mapping = SDL_PrivateGetControllerMappingForNameAndGUID(name, guid); -#if SDL_JOYSTICK_XINPUT - if (!mapping && SDL_SYS_IsXInputGamepad_DeviceIndex(device_index)) { - mapping = s_pXInputMapping; - } -#endif SDL_UnlockJoysticks(); return mapping; } @@ -1374,6 +1375,40 @@ SDL_GameControllerNameForIndex(int device_index) } +/** + * Get the mapping of a game controller. + * This can be called before any controllers are opened. + * If no mapping can be found, this function returns NULL. + */ +char * +SDL_GameControllerMappingForDeviceIndex(int joystick_index) +{ + char *pMappingString = NULL; + ControllerMapping_t *mapping; + + SDL_LockJoysticks(); + mapping = SDL_PrivateGetControllerMapping(joystick_index); + if (mapping) { + SDL_JoystickGUID guid; + char pchGUID[33]; + size_t needed; + guid = SDL_JoystickGetDeviceGUID(joystick_index); + SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID)); + /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */ + needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1; + pMappingString = SDL_malloc(needed); + if (!pMappingString) { + SDL_OutOfMemory(); + SDL_UnlockJoysticks(); + return NULL; + } + SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping); + } + SDL_UnlockJoysticks(); + return pMappingString; +} + + /* * Return 1 if the joystick with this name and GUID is a supported controller */ diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 6f7ed3a4d0176..0ce31154b0db8 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -121,11 +121,6 @@ extern SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index); /* Function to return the stable GUID for a opened joystick */ extern SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick); -#if SDL_JOYSTICK_XINPUT -/* Function returns SDL_TRUE if this device is an XInput gamepad */ -extern SDL_bool SDL_SYS_IsXInputGamepad_DeviceIndex(int device_index); -#endif - #endif /* SDL_sysjoystick_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c index 823e7674f5bb0..977a36bb3fe33 100644 --- a/src/joystick/windows/SDL_xinputjoystick.c +++ b/src/joystick/windows/SDL_xinputjoystick.c @@ -464,18 +464,6 @@ SDL_XINPUT_JoystickQuit(void) } } -SDL_bool -SDL_SYS_IsXInputGamepad_DeviceIndex(int device_index) -{ - JoyStick_DeviceData *device = SYS_Joystick; - int index; - - for (index = device_index; index > 0; index--) - device = device->pNext; - - return device->bXInputDevice; -} - #else /* !SDL_JOYSTICK_XINPUT */ typedef struct JoyStick_DeviceData JoyStick_DeviceData;