Skip to content

Commit

Permalink
Added SDL_GameControllerTypeForIndex() and SDL_GameControllerGetType(…
Browse files Browse the repository at this point in the history
…) to return the type of controller attached.
  • Loading branch information
slouken committed Nov 22, 2019
1 parent c0650ac commit b5aff9d
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 161 deletions.
20 changes: 20 additions & 0 deletions include/SDL_gamecontroller.h
Expand Up @@ -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
{
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
*
Expand Down
2 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Expand Up @@ -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 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi_procs.h
Expand Up @@ -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 changes: 20 additions & 0 deletions src/joystick/SDL_gamecontroller.c
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
{
Expand Down
70 changes: 45 additions & 25 deletions src/joystick/SDL_joystick.c
Expand Up @@ -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)
{
Expand All @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down
13 changes: 4 additions & 9 deletions src/joystick/SDL_joystick_c.h
Expand Up @@ -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;
Expand All @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion src/joystick/hidapi/SDL_hidapi_ps4.c
Expand Up @@ -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 *
Expand Down
6 changes: 4 additions & 2 deletions src/joystick/hidapi/SDL_hidapi_xbox360.c
Expand Up @@ -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 */
Expand All @@ -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
}

Expand Down
2 changes: 1 addition & 1 deletion src/joystick/hidapi/SDL_hidapi_xboxone.c
Expand Up @@ -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 *
Expand Down

0 comments on commit b5aff9d

Please sign in to comment.