From fe09a4930aec2b465d99041360572fd0e400d570 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 11 Nov 2021 15:53:11 -0600 Subject: [PATCH] joystick: Add APIs to query rumble support --- include/SDL_gamecontroller.h | 30 ++++++++++++++++++++++++++ include/SDL_joystick.h | 28 ++++++++++++++++++++++++ src/dynapi/SDL_dynapi_overrides.h | 4 ++++ src/dynapi/SDL_dynapi_procs.h | 4 ++++ src/joystick/SDL_gamecontroller.c | 12 +++++++++++ src/joystick/SDL_joystick.c | 36 +++++++++++++++++++++++++++++++ test/testgamecontroller.c | 8 +++++++ test/testjoystick.c | 21 ++++++++++-------- 8 files changed, 134 insertions(+), 9 deletions(-) diff --git a/include/SDL_gamecontroller.h b/include/SDL_gamecontroller.h index 0ea47c1e2..0b6c14100 100644 --- a/include/SDL_gamecontroller.h +++ b/include/SDL_gamecontroller.h @@ -857,6 +857,8 @@ extern DECLSPEC int SDLCALL SDL_GameControllerGetSensorData(SDL_GameController * * \returns 0, or -1 if rumble isn't supported on this controller * * \since This function is available since SDL 2.0.9. + * + * \sa SDL_GameControllerHasRumble */ extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); @@ -879,6 +881,8 @@ extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecon * \returns 0, or -1 if trigger rumble isn't supported on this controller * * \since This function is available since SDL 2.0.14. + * + * \sa SDL_GameControllerHasRumbleTriggers */ extern DECLSPEC int SDLCALL SDL_GameControllerRumbleTriggers(SDL_GameController *gamecontroller, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms); @@ -893,6 +897,32 @@ extern DECLSPEC int SDLCALL SDL_GameControllerRumbleTriggers(SDL_GameController */ extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasLED(SDL_GameController *gamecontroller); +/** + * Query whether a game controller has rumble support. + * + * \param gamecontroller The controller to query + * \returns SDL_TRUE, or SDL_FALSE if this controller does not have + * rumble support + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerRumble + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasRumble(SDL_GameController *gamecontroller); + +/** + * Query whether a game controller has rumble support on triggers. + * + * \param gamecontroller The controller to query + * \returns SDL_TRUE, or SDL_FALSE if this controller does not have + * trigger rumble support + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerRumbleTriggers + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasRumbleTriggers(SDL_GameController *gamecontroller); + /** * Update a game controller's LED color. * diff --git a/include/SDL_joystick.h b/include/SDL_joystick.h index 88d043686..ef99a6560 100644 --- a/include/SDL_joystick.h +++ b/include/SDL_joystick.h @@ -818,6 +818,8 @@ extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick *joystick, * \returns 0, or -1 if rumble isn't supported on this joystick * * \since This function is available since SDL 2.0.9. + * + * \sa SDL_JoystickHasRumble */ extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); @@ -841,6 +843,8 @@ extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 lo * \returns 0, or -1 if trigger rumble isn't supported on this joystick * * \since This function is available since SDL 2.0.14. + * + * \sa SDL_JoystickHasRumbleTriggers */ extern DECLSPEC int SDLCALL SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms); @@ -857,6 +861,30 @@ extern DECLSPEC int SDLCALL SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, U */ extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasLED(SDL_Joystick *joystick); +/** + * Query whether a joystick has rumble support. + * + * \param joystick The joystick to query + * \return SDL_TRUE if the joystick has rumble, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_JoystickRumble + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasRumble(SDL_Joystick *joystick); + +/** + * Query whether a joystick has rumble support on triggers. + * + * \param joystick The joystick to query + * \return SDL_TRUE if the joystick has trigger rumble, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_JoystickRumbleTriggers + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasRumbleTriggers(SDL_Joystick *joystick); + /** * Update a joystick's LED color. * diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index e03b6bf2d..a6db07562 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -849,3 +849,7 @@ #define SDL_hid_device_change_count SDL_hid_device_change_count_REAL #define SDL_hid_open SDL_hid_open_REAL #define SDL_hid_open_path SDL_hid_open_path_REAL +#define SDL_JoystickHasRumble SDL_JoystickHasRumble_REAL +#define SDL_JoystickHasRumbleTriggers SDL_JoystickHasRumbleTriggers_REAL +#define SDL_GameControllerHasRumble SDL_GameControllerHasRumble_REAL +#define SDL_GameControllerHasRumbleTriggers SDL_GameControllerHasRumbleTriggers_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index ae7a18366..1d50eee31 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -918,3 +918,7 @@ SDL_DYNAPI_PROC(void,SDL_RenderLogicalToWindow,(SDL_Renderer *a, float b, float SDL_DYNAPI_PROC(Uint32,SDL_hid_device_change_count,(void),(),return) SDL_DYNAPI_PROC(SDL_hid_device*,SDL_hid_open,(unsigned short a, unsigned short b, const wchar_t *c),(a,b,c),return) SDL_DYNAPI_PROC(SDL_hid_device*,SDL_hid_open_path,(const char *a, int b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickHasRumble,(SDL_Joystick *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickHasRumbleTriggers,(SDL_Joystick *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasRumble,(SDL_GameController *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasRumbleTriggers,(SDL_GameController *a),(a),return) diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index 4e950ce56..59c510f34 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -2450,6 +2450,18 @@ SDL_GameControllerHasLED(SDL_GameController *gamecontroller) return SDL_JoystickHasLED(SDL_GameControllerGetJoystick(gamecontroller)); } +SDL_bool +SDL_GameControllerHasRumble(SDL_GameController *gamecontroller) +{ + return SDL_JoystickHasRumble(SDL_GameControllerGetJoystick(gamecontroller)); +} + +SDL_bool +SDL_GameControllerHasRumbleTriggers(SDL_GameController *gamecontroller) +{ + return SDL_JoystickHasRumbleTriggers(SDL_GameControllerGetJoystick(gamecontroller)); +} + int SDL_GameControllerSetLED(SDL_GameController *gamecontroller, Uint8 red, Uint8 green, Uint8 blue) { diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index ce1261375..8143da250 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -951,6 +951,42 @@ SDL_JoystickHasLED(SDL_Joystick *joystick) return result; } +SDL_bool +SDL_JoystickHasRumble(SDL_Joystick *joystick) +{ + SDL_bool result; + + if (!SDL_PrivateJoystickValid(joystick)) { + return SDL_FALSE; + } + + SDL_LockJoysticks(); + + result = (joystick->driver->GetCapabilities(joystick) & SDL_JOYCAP_RUMBLE) != 0; + + SDL_UnlockJoysticks(); + + return result; +} + +SDL_bool +SDL_JoystickHasRumbleTriggers(SDL_Joystick *joystick) +{ + SDL_bool result; + + if (!SDL_PrivateJoystickValid(joystick)) { + return SDL_FALSE; + } + + SDL_LockJoysticks(); + + result = (joystick->driver->GetCapabilities(joystick) & SDL_JOYCAP_RUMBLE_TRIGGERS) != 0; + + SDL_UnlockJoysticks(); + + return result; +} + int SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) { diff --git a/test/testgamecontroller.c b/test/testgamecontroller.c index 6aec60044..acd6382f7 100644 --- a/test/testgamecontroller.c +++ b/test/testgamecontroller.c @@ -168,6 +168,14 @@ static void AddController(int device_index, SDL_bool verbose) SDL_GameControllerSetSensorEnabled(gamecontroller, SDL_SENSOR_GYRO, SDL_TRUE); } + if (SDL_GameControllerHasRumble(gamecontroller)) { + SDL_Log("Rumble supported"); + } + + if (SDL_GameControllerHasRumbleTriggers(gamecontroller)) { + SDL_Log("Trigger rumble supported"); + } + UpdateWindowTitle(); } diff --git a/test/testjoystick.c b/test/testjoystick.c index b9e414bde..fc8389ff5 100644 --- a/test/testjoystick.c +++ b/test/testjoystick.c @@ -78,15 +78,18 @@ PrintJoystick(SDL_Joystick *joystick) break; } SDL_Log("Joystick\n"); - SDL_Log(" name: %s\n", SDL_JoystickName(joystick)); - SDL_Log(" type: %s\n", type); - SDL_Log(" axes: %d\n", SDL_JoystickNumAxes(joystick)); - SDL_Log(" balls: %d\n", SDL_JoystickNumBalls(joystick)); - SDL_Log(" hats: %d\n", SDL_JoystickNumHats(joystick)); - SDL_Log(" buttons: %d\n", SDL_JoystickNumButtons(joystick)); - SDL_Log("instance id: %d\n", SDL_JoystickInstanceID(joystick)); - SDL_Log(" guid: %s\n", guid); - SDL_Log(" VID/PID: 0x%.4x/0x%.4x\n", SDL_JoystickGetVendor(joystick), SDL_JoystickGetProduct(joystick)); + SDL_Log(" name: %s\n", SDL_JoystickName(joystick)); + SDL_Log(" type: %s\n", type); + SDL_Log(" LED: %s\n", SDL_JoystickHasLED(joystick) ? "yes" : "no"); + SDL_Log(" rumble: %s\n", SDL_JoystickHasRumble(joystick) ? "yes" : "no"); + SDL_Log("trigger rumble: %s\n", SDL_JoystickHasRumbleTriggers(joystick) ? "yes" : "no"); + SDL_Log(" axes: %d\n", SDL_JoystickNumAxes(joystick)); + SDL_Log(" balls: %d\n", SDL_JoystickNumBalls(joystick)); + SDL_Log(" hats: %d\n", SDL_JoystickNumHats(joystick)); + SDL_Log(" buttons: %d\n", SDL_JoystickNumButtons(joystick)); + SDL_Log(" instance id: %d\n", SDL_JoystickInstanceID(joystick)); + SDL_Log(" guid: %s\n", guid); + SDL_Log(" VID/PID: 0x%.4x/0x%.4x\n", SDL_JoystickGetVendor(joystick), SDL_JoystickGetProduct(joystick)); } static void