From d140d88744d9b88d1946556753f7333e932f851e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 16 Nov 2020 17:36:47 -0800 Subject: [PATCH] Added SDL_JoystickGetSerial() and SDL_GameControllerGetSerial() --- include/SDL_gamecontroller.h | 15 +++-- include/SDL_joystick.h | 63 ++++++++++-------- src/dynapi/SDL_dynapi_overrides.h | 2 + src/dynapi/SDL_dynapi_procs.h | 2 + src/joystick/SDL_gamecontroller.c | 39 ++++++----- src/joystick/SDL_joystick.c | 77 ++++++++++++---------- src/joystick/SDL_sysjoystick.h | 15 +++-- src/joystick/hidapi/SDL_hidapi_ps4.c | 60 +++++++++-------- src/joystick/hidapi/SDL_hidapi_ps5.c | 20 +++--- src/joystick/hidapi/SDL_hidapijoystick.c | 58 +++++++++------- src/joystick/hidapi/SDL_hidapijoystick_c.h | 1 + test/testgamecontroller.c | 8 ++- 12 files changed, 210 insertions(+), 150 deletions(-) diff --git a/include/SDL_gamecontroller.h b/include/SDL_gamecontroller.h index 8498e89ee..ee7ef6475 100644 --- a/include/SDL_gamecontroller.h +++ b/include/SDL_gamecontroller.h @@ -172,7 +172,7 @@ extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForGUID(SDL_JoystickGUID * * \return the mapping string. Must be freed with SDL_free(). Returns NULL if no mapping is available */ -extern DECLSPEC char * SDLCALL SDL_GameControllerMapping(SDL_GameController * gamecontroller); +extern DECLSPEC char * SDLCALL SDL_GameControllerMapping(SDL_GameController *gamecontroller); /** * Is the joystick on this index supported by the game controller interface? @@ -247,19 +247,26 @@ extern DECLSPEC void SDLCALL SDL_GameControllerSetPlayerIndex(SDL_GameController * Get the USB vendor ID of an opened controller, if available. * If the vendor ID isn't available this function returns 0. */ -extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetVendor(SDL_GameController * gamecontroller); +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetVendor(SDL_GameController *gamecontroller); /** * Get the USB product ID of an opened controller, if available. * If the product ID isn't available this function returns 0. */ -extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProduct(SDL_GameController * gamecontroller); +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProduct(SDL_GameController *gamecontroller); /** * Get the product version of an opened controller, if available. * If the product version isn't available this function returns 0. */ -extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProductVersion(SDL_GameController * gamecontroller); +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProductVersion(SDL_GameController *gamecontroller); + +/** + * Get the serial number of an opened controller, if available. + * + * Returns the serial number of the controller, or NULL if it is not available. + */ +extern DECLSPEC const char * SDLCALL SDL_GameControllerGetSerial(SDL_GameController *gamecontroller); /** * Returns SDL_TRUE if the controller has been opened and currently connected, diff --git a/include/SDL_joystick.h b/include/SDL_joystick.h index be844e1c3..4d9ffd6e4 100644 --- a/include/SDL_joystick.h +++ b/include/SDL_joystick.h @@ -230,55 +230,62 @@ extern DECLSPEC SDL_bool SDLCALL SDL_JoystickIsVirtual(int device_index); * * Returns 0 on success, -1 on error. */ -extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualAxis(SDL_Joystick * joystick, int axis, Sint16 value); -extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualButton(SDL_Joystick * joystick, int button, Uint8 value); -extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualHat(SDL_Joystick * joystick, int hat, Uint8 value); +extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualAxis(SDL_Joystick *joystick, int axis, Sint16 value); +extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualButton(SDL_Joystick *joystick, int button, Uint8 value); +extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualHat(SDL_Joystick *joystick, int hat, Uint8 value); /** * Return the name for this currently opened joystick. * If no name can be found, this function returns NULL. */ -extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick * joystick); +extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick *joystick); /** * Get the player index of an opened joystick, or -1 if it's not available * * For XInput controllers this returns the XInput user index. */ -extern DECLSPEC int SDLCALL SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick); +extern DECLSPEC int SDLCALL SDL_JoystickGetPlayerIndex(SDL_Joystick *joystick); /** * Set the player index of an opened joystick */ -extern DECLSPEC void SDLCALL SDL_JoystickSetPlayerIndex(SDL_Joystick * joystick, int player_index); +extern DECLSPEC void SDLCALL SDL_JoystickSetPlayerIndex(SDL_Joystick *joystick, int player_index); /** * Return the GUID for this opened joystick */ -extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUID(SDL_Joystick * joystick); +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUID(SDL_Joystick *joystick); /** * Get the USB vendor ID of an opened joystick, if available. * If the vendor ID isn't available this function returns 0. */ -extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetVendor(SDL_Joystick * joystick); +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetVendor(SDL_Joystick *joystick); /** * Get the USB product ID of an opened joystick, if available. * If the product ID isn't available this function returns 0. */ -extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProduct(SDL_Joystick * joystick); +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProduct(SDL_Joystick *joystick); /** * Get the product version of an opened joystick, if available. * If the product version isn't available this function returns 0. */ -extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProductVersion(SDL_Joystick * joystick); +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProductVersion(SDL_Joystick *joystick); + +/** + * Get the serial number of an opened joystick, if available. + * + * Returns the serial number of the joystick, or NULL if it is not available. + */ +extern DECLSPEC const char * SDLCALL SDL_JoystickGetSerial(SDL_Joystick *joystick); /** * Get the type of an opened joystick. */ -extern DECLSPEC SDL_JoystickType SDLCALL SDL_JoystickGetType(SDL_Joystick * joystick); +extern DECLSPEC SDL_JoystickType SDLCALL SDL_JoystickGetType(SDL_Joystick *joystick); /** * Return a string representation for this guid. pszGUID must point to at least 33 bytes @@ -294,17 +301,17 @@ extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUIDFromString(const cha /** * Returns SDL_TRUE if the joystick has been opened and currently connected, or SDL_FALSE if it has not. */ -extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAttached(SDL_Joystick * joystick); +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAttached(SDL_Joystick *joystick); /** * Get the instance ID of an opened joystick or -1 if the joystick is invalid. */ -extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickInstanceID(SDL_Joystick * joystick); +extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickInstanceID(SDL_Joystick *joystick); /** * Get the number of general axis controls on a joystick. */ -extern DECLSPEC int SDLCALL SDL_JoystickNumAxes(SDL_Joystick * joystick); +extern DECLSPEC int SDLCALL SDL_JoystickNumAxes(SDL_Joystick *joystick); /** * Get the number of trackballs on a joystick. @@ -312,17 +319,17 @@ extern DECLSPEC int SDLCALL SDL_JoystickNumAxes(SDL_Joystick * joystick); * Joystick trackballs have only relative motion events associated * with them and their state cannot be polled. */ -extern DECLSPEC int SDLCALL SDL_JoystickNumBalls(SDL_Joystick * joystick); +extern DECLSPEC int SDLCALL SDL_JoystickNumBalls(SDL_Joystick *joystick); /** * Get the number of POV hats on a joystick. */ -extern DECLSPEC int SDLCALL SDL_JoystickNumHats(SDL_Joystick * joystick); +extern DECLSPEC int SDLCALL SDL_JoystickNumHats(SDL_Joystick *joystick); /** * Get the number of buttons on a joystick. */ -extern DECLSPEC int SDLCALL SDL_JoystickNumButtons(SDL_Joystick * joystick); +extern DECLSPEC int SDLCALL SDL_JoystickNumButtons(SDL_Joystick *joystick); /** * Update the current state of the open joysticks. @@ -352,7 +359,7 @@ extern DECLSPEC int SDLCALL SDL_JoystickEventState(int state); * * The axis indices start at index 0. */ -extern DECLSPEC Sint16 SDLCALL SDL_JoystickGetAxis(SDL_Joystick * joystick, +extern DECLSPEC Sint16 SDLCALL SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis); /** @@ -364,7 +371,7 @@ extern DECLSPEC Sint16 SDLCALL SDL_JoystickGetAxis(SDL_Joystick * joystick, * * \return SDL_TRUE if this axis has any initial value, or SDL_FALSE if not. */ -extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAxisInitialState(SDL_Joystick * joystick, +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAxisInitialState(SDL_Joystick *joystick, int axis, Sint16 *state); /** @@ -398,7 +405,7 @@ extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAxisInitialState(SDL_Joystick * * - ::SDL_HAT_LEFTUP * - ::SDL_HAT_LEFTDOWN */ -extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetHat(SDL_Joystick * joystick, +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetHat(SDL_Joystick *joystick, int hat); /** @@ -408,7 +415,7 @@ extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetHat(SDL_Joystick * joystick, * * The ball indices start at index 0. */ -extern DECLSPEC int SDLCALL SDL_JoystickGetBall(SDL_Joystick * joystick, +extern DECLSPEC int SDLCALL SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy); /** @@ -416,7 +423,7 @@ extern DECLSPEC int SDLCALL SDL_JoystickGetBall(SDL_Joystick * joystick, * * The button indices start at index 0. */ -extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick * joystick, +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick *joystick, int button); /** @@ -430,7 +437,7 @@ extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick * joystick, * * \return 0, or -1 if rumble isn't supported on this joystick */ -extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); +extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); /** * Start a rumble effect in the joystick's triggers @@ -443,7 +450,7 @@ extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 l * * \return 0, or -1 if trigger rumble isn't supported on this joystick */ -extern DECLSPEC int SDLCALL SDL_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms); +extern DECLSPEC int SDLCALL SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms); /** * Return whether a joystick has an LED @@ -452,7 +459,7 @@ extern DECLSPEC int SDLCALL SDL_JoystickRumbleTriggers(SDL_Joystick * joystick, * * \return SDL_TRUE, or SDL_FALSE if this joystick does not have a modifiable LED */ -extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasLED(SDL_Joystick * joystick); +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasLED(SDL_Joystick *joystick); /** * Update a joystick's LED color. @@ -464,17 +471,17 @@ extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasLED(SDL_Joystick * joystick); * * \return 0, or -1 if this joystick does not have a modifiable LED */ -extern DECLSPEC int SDLCALL SDL_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue); +extern DECLSPEC int SDLCALL SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue); /** * Close a joystick previously opened with SDL_JoystickOpen(). */ -extern DECLSPEC void SDLCALL SDL_JoystickClose(SDL_Joystick * joystick); +extern DECLSPEC void SDLCALL SDL_JoystickClose(SDL_Joystick *joystick); /** * Return the battery level of this joystick */ -extern DECLSPEC SDL_JoystickPowerLevel SDLCALL SDL_JoystickCurrentPowerLevel(SDL_Joystick * joystick); +extern DECLSPEC SDL_JoystickPowerLevel SDLCALL SDL_JoystickCurrentPowerLevel(SDL_Joystick *joystick); /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 8532a36b8..278bbdff9 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -780,3 +780,5 @@ #define SDL_GameControllerGetNumTouchpadFingers SDL_GameControllerGetNumTouchpadFingers_REAL #define SDL_GameControllerGetTouchpadFinger SDL_GameControllerGetTouchpadFinger_REAL #define SDL_crc32 SDL_crc32_REAL +#define SDL_GameControllerGetSerial SDL_GameControllerGetSerial_REAL +#define SDL_JoystickGetSerial SDL_JoystickGetSerial_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index c165f8b38..8847a9ff4 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -841,3 +841,5 @@ SDL_DYNAPI_PROC(int,SDL_GameControllerGetNumTouchpads,(SDL_GameController *a),(a SDL_DYNAPI_PROC(int,SDL_GameControllerGetNumTouchpadFingers,(SDL_GameController *a, int b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_GameControllerGetTouchpadFinger,(SDL_GameController *a, int b, int c, Uint8 *d, float *e, float *f, float *g),(a,b,c,d,e,f,g),return) SDL_DYNAPI_PROC(Uint32,SDL_crc32,(Uint32 a, const void *b, size_t c),(a,b,c),return) +SDL_DYNAPI_PROC(const char*,SDL_GameControllerGetSerial,(SDL_GameController *a),(a),return) +SDL_DYNAPI_PROC(const char*,SDL_JoystickGetSerial,(SDL_Joystick *a),(a),return) diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index f5d18eaec..89a216467 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -194,8 +194,8 @@ SDL_GameControllerIgnoreDevicesExceptChanged(void *userdata, const char *name, c } static ControllerMapping_t *SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing, SDL_ControllerMappingPriority priority); -static int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value); -static int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state); +static int SDL_PrivateGameControllerAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, Sint16 value); +static int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, Uint8 state); /* * If there is an existing add event in the queue, it needs to be modified @@ -1517,7 +1517,7 @@ SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid) * Get the mapping string for this device */ char * -SDL_GameControllerMapping(SDL_GameController * gamecontroller) +SDL_GameControllerMapping(SDL_GameController *gamecontroller) { if (!gamecontroller) { return NULL; @@ -1888,7 +1888,7 @@ SDL_GameControllerHasAxis(SDL_GameController *gamecontroller, SDL_GameController * Get the current state of an axis control on a controller */ Sint16 -SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis) +SDL_GameControllerGetAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis) { int i; @@ -1957,7 +1957,7 @@ SDL_GameControllerHasButton(SDL_GameController *gamecontroller, SDL_GameControll * Get the current state of a button on a controller */ Uint8 -SDL_GameControllerGetButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button) +SDL_GameControllerGetButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button) { int i; @@ -2060,7 +2060,7 @@ SDL_GameControllerGetTouchpadFinger(SDL_GameController *gamecontroller, int touc } const char * -SDL_GameControllerName(SDL_GameController * gamecontroller) +SDL_GameControllerName(SDL_GameController *gamecontroller) { if (!gamecontroller) return NULL; @@ -2094,29 +2094,35 @@ SDL_GameControllerSetPlayerIndex(SDL_GameController *gamecontroller, int player_ } Uint16 -SDL_GameControllerGetVendor(SDL_GameController * gamecontroller) +SDL_GameControllerGetVendor(SDL_GameController *gamecontroller) { return SDL_JoystickGetVendor(SDL_GameControllerGetJoystick(gamecontroller)); } Uint16 -SDL_GameControllerGetProduct(SDL_GameController * gamecontroller) +SDL_GameControllerGetProduct(SDL_GameController *gamecontroller) { return SDL_JoystickGetProduct(SDL_GameControllerGetJoystick(gamecontroller)); } Uint16 -SDL_GameControllerGetProductVersion(SDL_GameController * gamecontroller) +SDL_GameControllerGetProductVersion(SDL_GameController *gamecontroller) { return SDL_JoystickGetProductVersion(SDL_GameControllerGetJoystick(gamecontroller)); } +const char * +SDL_GameControllerGetSerial(SDL_GameController *gamecontroller) +{ + return SDL_JoystickGetSerial(SDL_GameControllerGetJoystick(gamecontroller)); +} + /* * Return if the controller in question is currently attached to the system, * \return 0 if not plugged in, 1 if still present. */ SDL_bool -SDL_GameControllerGetAttached(SDL_GameController * gamecontroller) +SDL_GameControllerGetAttached(SDL_GameController *gamecontroller) { if (!gamecontroller) return SDL_FALSE; @@ -2127,7 +2133,8 @@ SDL_GameControllerGetAttached(SDL_GameController * gamecontroller) /* * Get the joystick for this controller */ -SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller) +SDL_Joystick * +SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller) { if (!gamecontroller) return NULL; @@ -2174,7 +2181,7 @@ SDL_GameController *SDL_GameControllerFromPlayerIndex(int player_index) /* * Get the SDL joystick layer binding for this controller axis mapping */ -SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis) +SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis) { int i; SDL_GameControllerButtonBind bind; @@ -2206,7 +2213,7 @@ SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController /* * Get the SDL joystick layer binding for this controller button mapping */ -SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button) +SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button) { int i; SDL_GameControllerButtonBind bind; @@ -2259,7 +2266,7 @@ SDL_GameControllerSetLED(SDL_GameController *gamecontroller, Uint8 red, Uint8 gr } void -SDL_GameControllerClose(SDL_GameController * gamecontroller) +SDL_GameControllerClose(SDL_GameController *gamecontroller) { SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev; @@ -2349,7 +2356,7 @@ SDL_GameControllerQuitMappings(void) * Event filter to transform joystick events into appropriate game controller ones */ static int -SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value) +SDL_PrivateGameControllerAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, Sint16 value) { int posted; @@ -2373,7 +2380,7 @@ SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameContr * Event filter to transform joystick events into appropriate game controller ones */ static int -SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state) +SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, Uint8 state) { int posted; #if !SDL_EVENTS_DISABLED diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index f13303fe1..8ee009aac 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -525,7 +525,7 @@ SDL_JoystickIsVirtual(int device_index) } int -SDL_JoystickSetVirtualAxis(SDL_Joystick * joystick, int axis, Sint16 value) +SDL_JoystickSetVirtualAxis(SDL_Joystick *joystick, int axis, Sint16 value) { #if SDL_JOYSTICK_VIRTUAL return SDL_JoystickSetVirtualAxisInner(joystick, axis, value); @@ -535,7 +535,7 @@ SDL_JoystickSetVirtualAxis(SDL_Joystick * joystick, int axis, Sint16 value) } int -SDL_JoystickSetVirtualButton(SDL_Joystick * joystick, int button, Uint8 value) +SDL_JoystickSetVirtualButton(SDL_Joystick *joystick, int button, Uint8 value) { #if SDL_JOYSTICK_VIRTUAL return SDL_JoystickSetVirtualButtonInner(joystick, button, value); @@ -545,7 +545,7 @@ SDL_JoystickSetVirtualButton(SDL_Joystick * joystick, int button, Uint8 value) } int -SDL_JoystickSetVirtualHat(SDL_Joystick * joystick, int hat, Uint8 value) +SDL_JoystickSetVirtualHat(SDL_Joystick *joystick, int hat, Uint8 value) { #if SDL_JOYSTICK_VIRTUAL return SDL_JoystickSetVirtualHatInner(joystick, hat, value); @@ -558,7 +558,7 @@ SDL_JoystickSetVirtualHat(SDL_Joystick * joystick, int hat, Uint8 value) * Checks to make sure the joystick is valid. */ SDL_bool -SDL_PrivateJoystickValid(SDL_Joystick * joystick) +SDL_PrivateJoystickValid(SDL_Joystick *joystick) { SDL_bool valid; @@ -591,7 +591,7 @@ SDL_PrivateJoystickGetAutoGamepadMapping(int device_index, SDL_GamepadMapping * * Get the number of multi-dimensional axis controls on a joystick */ int -SDL_JoystickNumAxes(SDL_Joystick * joystick) +SDL_JoystickNumAxes(SDL_Joystick *joystick) { if (!SDL_PrivateJoystickValid(joystick)) { return -1; @@ -603,7 +603,7 @@ SDL_JoystickNumAxes(SDL_Joystick * joystick) * Get the number of hats on a joystick */ int -SDL_JoystickNumHats(SDL_Joystick * joystick) +SDL_JoystickNumHats(SDL_Joystick *joystick) { if (!SDL_PrivateJoystickValid(joystick)) { return -1; @@ -615,7 +615,7 @@ SDL_JoystickNumHats(SDL_Joystick * joystick) * Get the number of trackballs on a joystick */ int -SDL_JoystickNumBalls(SDL_Joystick * joystick) +SDL_JoystickNumBalls(SDL_Joystick *joystick) { if (!SDL_PrivateJoystickValid(joystick)) { return -1; @@ -627,7 +627,7 @@ SDL_JoystickNumBalls(SDL_Joystick * joystick) * Get the number of buttons on a joystick */ int -SDL_JoystickNumButtons(SDL_Joystick * joystick) +SDL_JoystickNumButtons(SDL_Joystick *joystick) { if (!SDL_PrivateJoystickValid(joystick)) { return -1; @@ -639,7 +639,7 @@ SDL_JoystickNumButtons(SDL_Joystick * joystick) * Get the current state of an axis control on a joystick */ Sint16 -SDL_JoystickGetAxis(SDL_Joystick * joystick, int axis) +SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis) { Sint16 state; @@ -659,7 +659,7 @@ SDL_JoystickGetAxis(SDL_Joystick * joystick, int axis) * Get the initial state of an axis control on a joystick */ SDL_bool -SDL_JoystickGetAxisInitialState(SDL_Joystick * joystick, int axis, Sint16 *state) +SDL_JoystickGetAxisInitialState(SDL_Joystick *joystick, int axis, Sint16 *state) { if (!SDL_PrivateJoystickValid(joystick)) { return SDL_FALSE; @@ -678,7 +678,7 @@ SDL_JoystickGetAxisInitialState(SDL_Joystick * joystick, int axis, Sint16 *state * Get the current state of a hat on a joystick */ Uint8 -SDL_JoystickGetHat(SDL_Joystick * joystick, int hat) +SDL_JoystickGetHat(SDL_Joystick *joystick, int hat) { Uint8 state; @@ -698,7 +698,7 @@ SDL_JoystickGetHat(SDL_Joystick * joystick, int hat) * Get the ball axis change since the last poll */ int -SDL_JoystickGetBall(SDL_Joystick * joystick, int ball, int *dx, int *dy) +SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy) { int retval; @@ -726,7 +726,7 @@ SDL_JoystickGetBall(SDL_Joystick * joystick, int ball, int *dx, int *dy) * Get the current state of a button on a joystick */ Uint8 -SDL_JoystickGetButton(SDL_Joystick * joystick, int button) +SDL_JoystickGetButton(SDL_Joystick *joystick, int button) { Uint8 state; @@ -747,7 +747,7 @@ SDL_JoystickGetButton(SDL_Joystick * joystick, int button) * \return SDL_FALSE if not plugged in, SDL_TRUE if still present. */ SDL_bool -SDL_JoystickGetAttached(SDL_Joystick * joystick) +SDL_JoystickGetAttached(SDL_Joystick *joystick) { if (!SDL_PrivateJoystickValid(joystick)) { return SDL_FALSE; @@ -760,7 +760,7 @@ SDL_JoystickGetAttached(SDL_Joystick * joystick) * Get the instance id for this opened joystick */ SDL_JoystickID -SDL_JoystickInstanceID(SDL_Joystick * joystick) +SDL_JoystickInstanceID(SDL_Joystick *joystick) { if (!SDL_PrivateJoystickValid(joystick)) { return -1; @@ -811,7 +811,7 @@ SDL_JoystickFromPlayerIndex(int player_index) * Get the friendly name of this joystick */ const char * -SDL_JoystickName(SDL_Joystick * joystick) +SDL_JoystickName(SDL_Joystick *joystick) { if (!SDL_PrivateJoystickValid(joystick)) { return NULL; @@ -824,7 +824,7 @@ SDL_JoystickName(SDL_Joystick * joystick) * Get the player index of an opened joystick, or -1 if it's not available */ int -SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick) +SDL_JoystickGetPlayerIndex(SDL_Joystick *joystick) { int player_index; @@ -843,7 +843,7 @@ SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick) * Set the player index of an opened joystick */ void -SDL_JoystickSetPlayerIndex(SDL_Joystick * joystick, int player_index) +SDL_JoystickSetPlayerIndex(SDL_Joystick *joystick, int player_index) { if (!SDL_PrivateJoystickValid(joystick)) { return; @@ -855,7 +855,7 @@ SDL_JoystickSetPlayerIndex(SDL_Joystick * joystick, int player_index) } int -SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) +SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) { int result; @@ -890,7 +890,7 @@ SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 } int -SDL_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms) +SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms) { int result; @@ -924,7 +924,7 @@ SDL_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 r } SDL_bool -SDL_JoystickHasLED(SDL_Joystick * joystick) +SDL_JoystickHasLED(SDL_Joystick *joystick) { SDL_bool result; @@ -942,7 +942,7 @@ SDL_JoystickHasLED(SDL_Joystick * joystick) } int -SDL_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) +SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) { int result; @@ -975,7 +975,7 @@ SDL_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) * Close a joystick previously opened with SDL_JoystickOpen() */ void -SDL_JoystickClose(SDL_Joystick * joystick) +SDL_JoystickClose(SDL_Joystick *joystick) { SDL_Joystick *joysticklist; SDL_Joystick *joysticklistprev; @@ -1025,6 +1025,7 @@ SDL_JoystickClose(SDL_Joystick * joystick) } SDL_free(joystick->name); + SDL_free(joystick->serial); /* Free the data associated with this joystick */ SDL_free(joystick->axes); @@ -1261,7 +1262,7 @@ void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance) } int -SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) +SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value) { int posted; SDL_JoystickAxisInfo *info; @@ -1323,7 +1324,7 @@ SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) } int -SDL_PrivateJoystickHat(SDL_Joystick * joystick, Uint8 hat, Uint8 value) +SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value) { int posted; @@ -1363,7 +1364,7 @@ SDL_PrivateJoystickHat(SDL_Joystick * joystick, Uint8 hat, Uint8 value) } int -SDL_PrivateJoystickBall(SDL_Joystick * joystick, Uint8 ball, +SDL_PrivateJoystickBall(SDL_Joystick *joystick, Uint8 ball, Sint16 xrel, Sint16 yrel) { int posted; @@ -1399,7 +1400,7 @@ SDL_PrivateJoystickBall(SDL_Joystick * joystick, Uint8 ball, } int -SDL_PrivateJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state) +SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state) { int posted; #if !SDL_EVENTS_DISABLED @@ -2317,7 +2318,7 @@ int SDL_JoystickGetDeviceIndexFromInstanceID(SDL_JoystickID instance_id) return device_index; } -SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick * joystick) +SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick *joystick) { if (!SDL_PrivateJoystickValid(joystick)) { SDL_JoystickGUID emptyGUID; @@ -2327,7 +2328,7 @@ SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick * joystick) return joystick->guid; } -Uint16 SDL_JoystickGetVendor(SDL_Joystick * joystick) +Uint16 SDL_JoystickGetVendor(SDL_Joystick *joystick) { Uint16 vendor; SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); @@ -2336,7 +2337,7 @@ Uint16 SDL_JoystickGetVendor(SDL_Joystick * joystick) return vendor; } -Uint16 SDL_JoystickGetProduct(SDL_Joystick * joystick) +Uint16 SDL_JoystickGetProduct(SDL_Joystick *joystick) { Uint16 product; SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); @@ -2345,7 +2346,7 @@ Uint16 SDL_JoystickGetProduct(SDL_Joystick * joystick) return product; } -Uint16 SDL_JoystickGetProductVersion(SDL_Joystick * joystick) +Uint16 SDL_JoystickGetProductVersion(SDL_Joystick *joystick) { Uint16 version; SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); @@ -2354,7 +2355,15 @@ Uint16 SDL_JoystickGetProductVersion(SDL_Joystick * joystick) return version; } -SDL_JoystickType SDL_JoystickGetType(SDL_Joystick * joystick) +const char *SDL_JoystickGetSerial(SDL_Joystick *joystick) +{ + if (!SDL_PrivateJoystickValid(joystick)) { + return NULL; + } + return joystick->serial; +} + +SDL_JoystickType SDL_JoystickGetType(SDL_Joystick *joystick) { SDL_JoystickType type; SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); @@ -2436,13 +2445,13 @@ SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID) } /* update the power level for this joystick */ -void SDL_PrivateJoystickBatteryLevel(SDL_Joystick * joystick, SDL_JoystickPowerLevel ePowerLevel) +void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel) { joystick->epowerlevel = ePowerLevel; } /* return its power level */ -SDL_JoystickPowerLevel SDL_JoystickCurrentPowerLevel(SDL_Joystick * joystick) +SDL_JoystickPowerLevel SDL_JoystickCurrentPowerLevel(SDL_Joystick *joystick) { if (!SDL_PrivateJoystickValid(joystick)) { return SDL_JOYSTICK_POWER_UNKNOWN; diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 02dc71ea2..158bb86cd 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -57,6 +57,7 @@ struct _SDL_Joystick { SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */ char *name; /* Joystick name - system dependent */ + char *serial; /* Joystick serial */ SDL_JoystickGUID guid; /* Joystick guid */ int naxes; /* Number of axis controls on the joystick */ @@ -143,25 +144,25 @@ typedef struct _SDL_JoystickDriver This should fill the nbuttons and naxes fields of the joystick structure. It returns 0, or -1 if there is an error. */ - int (*Open)(SDL_Joystick * joystick, int device_index); + int (*Open)(SDL_Joystick *joystick, int device_index); /* Rumble functionality */ - int (*Rumble)(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); - int (*RumbleTriggers)(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble); + int (*Rumble)(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); + int (*RumbleTriggers)(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble); /* LED functionality */ - SDL_bool (*HasLED)(SDL_Joystick * joystick); - int (*SetLED)(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue); + SDL_bool (*HasLED)(SDL_Joystick *joystick); + int (*SetLED)(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue); /* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events * and update joystick device state. */ - void (*Update)(SDL_Joystick * joystick); + void (*Update)(SDL_Joystick *joystick); /* Function to close a joystick after use */ - void (*Close)(SDL_Joystick * joystick); + void (*Close)(SDL_Joystick *joystick); /* Function to perform any system-specific joystick related cleanup */ void (*Quit)(void); diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c index 529bba759..c7d6e25b0 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps4.c +++ b/src/joystick/hidapi/SDL_hidapi_ps4.c @@ -135,34 +135,11 @@ HIDAPI_DriverPS4_GetDeviceName(Uint16 vendor_id, Uint16 product_id) return NULL; } -static SDL_bool ReadFeatureReport(hid_device *dev, Uint8 report_id, Uint8 *data, size_t size) +static int ReadFeatureReport(hid_device *dev, Uint8 report_id, Uint8 *report, size_t length) { - Uint8 report[USB_PACKET_LENGTH + 1]; - - SDL_memset(report, 0, sizeof(report)); + SDL_memset(report, 0, length); report[0] = report_id; - if (hid_get_feature_report(dev, report, sizeof(report)) < 0) { - return SDL_FALSE; - } - SDL_memcpy(data, report, SDL_min(size, sizeof(report))); - return SDL_TRUE; -} - -static SDL_bool CheckUSBConnected(hid_device *dev) -{ - int i; - Uint8 data[16]; - - /* This will fail if we're on Bluetooth */ - if (ReadFeatureReport(dev, k_ePS4FeatureReportIdSerialNumber, data, sizeof(data))) { - for (i = 0; i < sizeof(data); ++i) { - if (data[i] != 0x00) { - return SDL_TRUE; - } - } - /* Maybe the dongle without a connected controller? */ - } - return SDL_FALSE; + return hid_get_feature_report(dev, report, length); } static SDL_bool HIDAPI_DriverPS4_CanRumble(Uint16 vendor_id, Uint16 product_id) @@ -310,7 +287,36 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) if (ctx->is_dongle) { ctx->is_bluetooth = SDL_FALSE; } else if (device->vendor_id == USB_VENDOR_SONY) { - ctx->is_bluetooth = !CheckUSBConnected(device->dev); + int i; + Uint8 data[USB_PACKET_LENGTH]; + int length; + + /* This will fail if we're on Bluetooth */ + length = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdSerialNumber, data, sizeof(data)); + if (length >= 7) { + SDL_bool had_data = SDL_FALSE; + + for (i = 0; i < length; ++i) { + if (data[i] != 0x00) { + had_data = SDL_TRUE; + break; + } + } + + if (had_data) { + char serial[18]; + + SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", + data[6], data[5], data[4], data[3], data[2], data[1]); + joystick->serial = SDL_strdup(serial); + } else { + /* Maybe the dongle without a connected controller? */ + } + + ctx->is_bluetooth = SDL_FALSE; + } else { + ctx->is_bluetooth = SDL_TRUE; + } } else { /* Third party controllers appear to all be wired */ ctx->is_bluetooth = SDL_FALSE; diff --git a/src/joystick/hidapi/SDL_hidapi_ps5.c b/src/joystick/hidapi/SDL_hidapi_ps5.c index d16d8d6cb..6580a29b3 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps5.c +++ b/src/joystick/hidapi/SDL_hidapi_ps5.c @@ -140,16 +140,11 @@ HIDAPI_DriverPS5_GetDeviceName(Uint16 vendor_id, Uint16 product_id) return NULL; } -static SDL_bool ReadFeatureReport(hid_device *dev, Uint8 report_id) +static int ReadFeatureReport(hid_device *dev, Uint8 report_id, Uint8 *report, size_t length) { - Uint8 report[USB_PACKET_LENGTH + 1]; - - SDL_memset(report, 0, sizeof(report)); + SDL_memset(report, 0, length); report[0] = report_id; - if (hid_get_feature_report(dev, report, sizeof(report)) < 0) { - return SDL_FALSE; - } - return SDL_TRUE; + return hid_get_feature_report(dev, report, length); } static void @@ -277,6 +272,7 @@ static SDL_bool HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { SDL_DriverPS5_Context *ctx; + Uint8 data[USB_PACKET_LENGTH]; ctx = (SDL_DriverPS5_Context *)SDL_calloc(1, sizeof(*ctx)); if (!ctx) { @@ -295,7 +291,13 @@ HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) /* Read the serial number (Bluetooth address in reverse byte order) This will also enable enhanced reports over Bluetooth */ - ReadFeatureReport(device->dev, k_EPS5FeatureReportIdSerialNumber); + if (ReadFeatureReport(device->dev, k_EPS5FeatureReportIdSerialNumber, data, sizeof(data)) >= 7) { + char serial[18]; + + SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", + data[6], data[5], data[4], data[3], data[2], data[1]); + joystick->serial = SDL_strdup(serial); + } /* Initialize player index (needed for setting LEDs) */ ctx->player_index = SDL_JoystickGetPlayerIndex(joystick); diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index c732cbaa2..9d7f65b94 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -690,6 +690,24 @@ HIDAPI_JoystickGetCount(void) return SDL_HIDAPI_numjoysticks; } +static char * +HIDAPI_ConvertString(const wchar_t *wide_string) +{ + char *string = NULL; + + if (wide_string) { + string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t)); + if (!string) { + if (sizeof(wchar_t) == sizeof(Uint16)) { + string = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t)); + } else if (sizeof(wchar_t) == sizeof(Uint32)) { + string = SDL_iconv_string("UTF-8", "UCS-4-INTERNAL", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t)); + } + } + } + return string; +} + static void HIDAPI_AddDevice(struct hid_device_info *info) { @@ -743,29 +761,9 @@ HIDAPI_AddDevice(struct hid_device_info *info) /* Need the device name before getting the driver to know whether to ignore this device */ { - char *manufacturer_string = NULL; - char *product_string = NULL; - - if (info->manufacturer_string) { - manufacturer_string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)info->manufacturer_string, (SDL_wcslen(info->manufacturer_string)+1)*sizeof(wchar_t)); - if (!manufacturer_string) { - if (sizeof(wchar_t) == sizeof(Uint16)) { - manufacturer_string = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char*)info->manufacturer_string, (SDL_wcslen(info->manufacturer_string)+1)*sizeof(wchar_t)); - } else if (sizeof(wchar_t) == sizeof(Uint32)) { - manufacturer_string = SDL_iconv_string("UTF-8", "UCS-4-INTERNAL", (char*)info->manufacturer_string, (SDL_wcslen(info->manufacturer_string)+1)*sizeof(wchar_t)); - } - } - } - if (info->product_string) { - product_string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)info->product_string, (SDL_wcslen(info->product_string)+1)*sizeof(wchar_t)); - if (!product_string) { - if (sizeof(wchar_t) == sizeof(Uint16)) { - product_string = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char*)info->product_string, (SDL_wcslen(info->product_string)+1)*sizeof(wchar_t)); - } else if (sizeof(wchar_t) == sizeof(Uint32)) { - product_string = SDL_iconv_string("UTF-8", "UCS-4-INTERNAL", (char*)info->product_string, (SDL_wcslen(info->product_string)+1)*sizeof(wchar_t)); - } - } - } + char *manufacturer_string = HIDAPI_ConvertString(info->manufacturer_string); + char *product_string = HIDAPI_ConvertString(info->product_string); + char *serial_number = HIDAPI_ConvertString(info->serial_number); device->name = SDL_CreateJoystickName(device->vendor_id, device->product_id, manufacturer_string, product_string); @@ -776,7 +774,14 @@ HIDAPI_AddDevice(struct hid_device_info *info) SDL_free(product_string); } + if (serial_number && *serial_number) { + device->serial = serial_number; + } else { + SDL_free(serial_number); + } + if (!device->name) { + SDL_free(device->serial); SDL_free(device->path); SDL_free(device); return; @@ -793,7 +798,7 @@ HIDAPI_AddDevice(struct hid_device_info *info) HIDAPI_SetupDeviceDriver(device); #ifdef DEBUG_HIDAPI - SDL_Log("Added HIDAPI device '%s' VID 0x%.4x, PID 0x%.4x, version %d, interface %d, interface_class %d, interface_subclass %d, interface_protocol %d, usage page 0x%.4x, usage 0x%.4x, path = %s, driver = %s (%s)\n", device->name, device->vendor_id, device->product_id, device->version, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol, device->usage_page, device->usage, device->path, device->driver ? device->driver->hint : "NONE", device->driver && device->driver->enabled ? "ENABLED" : "DISABLED"); + SDL_Log("Added HIDAPI device '%s' VID 0x%.4x, PID 0x%.4x, version %d, serial %s, interface %d, interface_class %d, interface_subclass %d, interface_protocol %d, usage page 0x%.4x, usage 0x%.4x, path = %s, driver = %s (%s)\n", device->name, device->vendor_id, device->product_id, device->version, device->serial ? device->serial : "NONE", device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol, device->usage_page, device->usage, device->path, device->driver ? device->driver->hint : "NONE", device->driver && device->driver->enabled ? "ENABLED" : "DISABLED"); #endif } @@ -813,6 +818,7 @@ HIDAPI_DelDevice(SDL_HIDAPI_Device *device) HIDAPI_CleanupDeviceDriver(device); SDL_DestroyMutex(device->dev_lock); + SDL_free(device->serial); SDL_free(device->name); SDL_free(device->path); SDL_free(device); @@ -1051,6 +1057,10 @@ HIDAPI_JoystickOpen(SDL_Joystick * joystick, int device_index) return -1; } + if (!joystick->serial && device->serial) { + joystick->serial = SDL_strdup(device->serial); + } + joystick->hwdata = hwdata; return 0; } diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h index 4ea3f6029..f84c1ec3f 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick_c.h +++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -61,6 +61,7 @@ typedef struct _SDL_HIDAPI_Device Uint16 vendor_id; Uint16 product_id; Uint16 version; + char *serial; SDL_JoystickGUID guid; int interface_number; /* Available on Windows and Linux */ int interface_class; diff --git a/test/testgamecontroller.c b/test/testgamecontroller.c index 6b0f512ff..bc1f66dd5 100644 --- a/test/testgamecontroller.c +++ b/test/testgamecontroller.c @@ -101,8 +101,9 @@ static void UpdateWindowTitle() { const char *name = SDL_GameControllerName(gamecontroller); + const char *serial = SDL_GameControllerGetSerial(gamecontroller); const char *basetitle = "Game Controller Test: "; - const size_t titlelen = SDL_strlen(basetitle) + SDL_strlen(name) + 1; + const size_t titlelen = SDL_strlen(basetitle) + SDL_strlen(name) + (serial ? 3 + SDL_strlen(serial) : 0) + 1; char *title = (char *)SDL_malloc(titlelen); retval = SDL_FALSE; @@ -110,6 +111,11 @@ UpdateWindowTitle() if (title) { SDL_snprintf(title, titlelen, "%s%s", basetitle, name); + if (serial) { + SDL_strlcat(title, " (", titlelen); + SDL_strlcat(title, serial, titlelen); + SDL_strlcat(title, ")", titlelen); + } SDL_SetWindowTitle(window, title); SDL_free(title); }