Added the ability to specify a gamepad type in the mapping
Also renamed most cases of SDL_GAMEPAD_TYPE_UNKNOWN to SDL_GAMEPAD_TYPE_STANDARD, and SDL_GetGamepadType() will return SDL_GAMEPAD_TYPE_UNKNOWN only if the gamepad is invalid.main
parent
57820071a4
commit
b271e92c6e
|
@ -390,17 +390,14 @@ The following symbols have been renamed:
|
|||
* SDL_CONTROLLER_BUTTON_TOUCHPAD => SDL_GAMEPAD_BUTTON_TOUCHPAD
|
||||
* SDL_CONTROLLER_BUTTON_X => SDL_GAMEPAD_BUTTON_X
|
||||
* SDL_CONTROLLER_BUTTON_Y => SDL_GAMEPAD_BUTTON_Y
|
||||
* SDL_CONTROLLER_TYPE_AMAZON_LUNA => SDL_GAMEPAD_TYPE_AMAZON_LUNA
|
||||
* SDL_CONTROLLER_TYPE_GOOGLE_STADIA => SDL_GAMEPAD_TYPE_GOOGLE_STADIA
|
||||
* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT
|
||||
* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR
|
||||
* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT
|
||||
* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO
|
||||
* SDL_CONTROLLER_TYPE_NVIDIA_SHIELD => SDL_GAMEPAD_TYPE_NVIDIA_SHIELD
|
||||
* SDL_CONTROLLER_TYPE_PS3 => SDL_GAMEPAD_TYPE_PS3
|
||||
* SDL_CONTROLLER_TYPE_PS4 => SDL_GAMEPAD_TYPE_PS4
|
||||
* SDL_CONTROLLER_TYPE_PS5 => SDL_GAMEPAD_TYPE_PS5
|
||||
* SDL_CONTROLLER_TYPE_UNKNOWN => SDL_GAMEPAD_TYPE_UNKNOWN
|
||||
* SDL_CONTROLLER_TYPE_UNKNOWN => SDL_GAMEPAD_TYPE_STANDARD
|
||||
* SDL_CONTROLLER_TYPE_VIRTUAL => SDL_GAMEPAD_TYPE_VIRTUAL
|
||||
* SDL_CONTROLLER_TYPE_XBOX360 => SDL_GAMEPAD_TYPE_XBOX360
|
||||
* SDL_CONTROLLER_TYPE_XBOXONE => SDL_GAMEPAD_TYPE_XBOXONE
|
||||
|
|
|
@ -61,6 +61,7 @@ typedef struct SDL_Gamepad SDL_Gamepad;
|
|||
typedef enum
|
||||
{
|
||||
SDL_GAMEPAD_TYPE_UNKNOWN = 0,
|
||||
SDL_GAMEPAD_TYPE_STANDARD,
|
||||
SDL_GAMEPAD_TYPE_XBOX360,
|
||||
SDL_GAMEPAD_TYPE_XBOXONE,
|
||||
SDL_GAMEPAD_TYPE_PS3,
|
||||
|
@ -70,6 +71,7 @@ typedef enum
|
|||
SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT,
|
||||
SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT,
|
||||
SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR,
|
||||
SDL_GAMEPAD_TYPE_MAX
|
||||
} SDL_GamepadType;
|
||||
|
||||
/**
|
||||
|
@ -411,6 +413,18 @@ extern DECLSPEC Uint16 SDLCALL SDL_GetGamepadInstanceProductVersion(SDL_Joystick
|
|||
*/
|
||||
extern DECLSPEC SDL_GamepadType SDLCALL SDL_GetGamepadInstanceType(SDL_JoystickID instance_id);
|
||||
|
||||
/**
|
||||
* Get the type of a gamepad, ignoring any mapping override.
|
||||
*
|
||||
* This can be called before any gamepads are opened.
|
||||
*
|
||||
* \param instance_id the joystick instance ID
|
||||
* \returns the gamepad type.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern DECLSPEC SDL_GamepadType SDLCALL SDL_GetRealGamepadInstanceType(SDL_JoystickID instance_id);
|
||||
|
||||
/**
|
||||
* Get the mapping of a gamepad.
|
||||
*
|
||||
|
@ -481,9 +495,6 @@ extern DECLSPEC SDL_JoystickID SDLCALL SDL_GetGamepadInstanceID(SDL_Gamepad *gam
|
|||
/**
|
||||
* Get the implementation-dependent name for an opened gamepad.
|
||||
*
|
||||
* This is the same name as returned by SDL_GetGamepadNameForIndex(), but it
|
||||
* takes a gamepad identifier instead of the (unstable) device index.
|
||||
*
|
||||
* \param gamepad a gamepad identifier previously returned by
|
||||
* SDL_OpenGamepad()
|
||||
* \returns the implementation dependent name for the gamepad, or NULL if
|
||||
|
@ -499,9 +510,6 @@ extern DECLSPEC const char *SDLCALL SDL_GetGamepadName(SDL_Gamepad *gamepad);
|
|||
/**
|
||||
* Get the implementation-dependent path for an opened gamepad.
|
||||
*
|
||||
* This is the same path as returned by SDL_GetGamepadNameForIndex(), but it
|
||||
* takes a gamepad identifier instead of the (unstable) device index.
|
||||
*
|
||||
* \param gamepad a gamepad identifier previously returned by
|
||||
* SDL_OpenGamepad()
|
||||
* \returns the implementation dependent path for the gamepad, or NULL if
|
||||
|
@ -514,18 +522,29 @@ extern DECLSPEC const char *SDLCALL SDL_GetGamepadName(SDL_Gamepad *gamepad);
|
|||
extern DECLSPEC const char *SDLCALL SDL_GetGamepadPath(SDL_Gamepad *gamepad);
|
||||
|
||||
/**
|
||||
* Get the type of this currently opened gamepad
|
||||
*
|
||||
* This is the same name as returned by SDL_GetGamepadInstanceType(), but it
|
||||
* takes a gamepad identifier instead of the (unstable) device index.
|
||||
* Get the type of an opened gamepad.
|
||||
*
|
||||
* \param gamepad the gamepad object to query.
|
||||
* \returns the gamepad type.
|
||||
* \returns the gamepad type, or SDL_GAMEPAD_TYPE_INVALID if it's not available.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetGamepadInstanceType
|
||||
*/
|
||||
extern DECLSPEC SDL_GamepadType SDLCALL SDL_GetGamepadType(SDL_Gamepad *gamepad);
|
||||
|
||||
/**
|
||||
* Get the type of an opened gamepad, ignoring any mapping override.
|
||||
*
|
||||
* \param gamepad the gamepad object to query.
|
||||
* \returns the gamepad type, or SDL_GAMEPAD_TYPE_INVALID if it's not available.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetRealGamepadInstanceType
|
||||
*/
|
||||
extern DECLSPEC SDL_GamepadType SDLCALL SDL_GetRealGamepadType(SDL_Gamepad *gamepad);
|
||||
|
||||
/**
|
||||
* Get the player index of an opened gamepad.
|
||||
*
|
||||
|
@ -697,6 +716,39 @@ extern DECLSPEC SDL_bool SDLCALL SDL_GamepadEventsEnabled(void);
|
|||
*/
|
||||
extern DECLSPEC void SDLCALL SDL_UpdateGamepads(void);
|
||||
|
||||
/**
|
||||
* Convert a string into SDL_GamepadType enum.
|
||||
*
|
||||
* This function is called internally to translate SDL_Gamepad mapping strings
|
||||
* for the underlying joystick device into the consistent SDL_Gamepad mapping.
|
||||
* You do not normally need to call this function unless you are parsing
|
||||
* SDL_Gamepad mappings in your own code.
|
||||
*
|
||||
* \param str string representing a SDL_GamepadType type
|
||||
* \returns the SDL_GamepadType enum corresponding to the input string, or
|
||||
* `SDL_GAMEPAD_TYPE_INVALID` if no match was found.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetGamepadStringForType
|
||||
*/
|
||||
extern DECLSPEC SDL_GamepadType SDLCALL SDL_GetGamepadTypeFromString(const char *str);
|
||||
|
||||
/**
|
||||
* Convert from an SDL_GamepadType enum to a string.
|
||||
*
|
||||
* The caller should not SDL_free() the returned string.
|
||||
*
|
||||
* \param type an enum value for a given SDL_GamepadType
|
||||
* \returns a string for the given type, or NULL if an invalid type is
|
||||
* specified. The string returned is of the format used by
|
||||
* SDL_Gamepad mapping strings.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetGamepadTypeFromString
|
||||
*/
|
||||
extern DECLSPEC const char *SDLCALL SDL_GetGamepadStringForType(SDL_GamepadType type);
|
||||
|
||||
/**
|
||||
* Convert a string into SDL_GamepadAxis enum.
|
||||
|
|
|
@ -184,17 +184,14 @@
|
|||
#define SDL_CONTROLLER_BUTTON_TOUCHPAD SDL_GAMEPAD_BUTTON_TOUCHPAD
|
||||
#define SDL_CONTROLLER_BUTTON_X SDL_GAMEPAD_BUTTON_X
|
||||
#define SDL_CONTROLLER_BUTTON_Y SDL_GAMEPAD_BUTTON_Y
|
||||
#define SDL_CONTROLLER_TYPE_AMAZON_LUNA SDL_GAMEPAD_TYPE_AMAZON_LUNA
|
||||
#define SDL_CONTROLLER_TYPE_GOOGLE_STADIA SDL_GAMEPAD_TYPE_GOOGLE_STADIA
|
||||
#define SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT
|
||||
#define SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR
|
||||
#define SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT
|
||||
#define SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO
|
||||
#define SDL_CONTROLLER_TYPE_NVIDIA_SHIELD SDL_GAMEPAD_TYPE_NVIDIA_SHIELD
|
||||
#define SDL_CONTROLLER_TYPE_PS3 SDL_GAMEPAD_TYPE_PS3
|
||||
#define SDL_CONTROLLER_TYPE_PS4 SDL_GAMEPAD_TYPE_PS4
|
||||
#define SDL_CONTROLLER_TYPE_PS5 SDL_GAMEPAD_TYPE_PS5
|
||||
#define SDL_CONTROLLER_TYPE_UNKNOWN SDL_GAMEPAD_TYPE_UNKNOWN
|
||||
#define SDL_CONTROLLER_TYPE_UNKNOWN SDL_GAMEPAD_TYPE_STANDARD
|
||||
#define SDL_CONTROLLER_TYPE_VIRTUAL SDL_GAMEPAD_TYPE_VIRTUAL
|
||||
#define SDL_CONTROLLER_TYPE_XBOX360 SDL_GAMEPAD_TYPE_XBOX360
|
||||
#define SDL_CONTROLLER_TYPE_XBOXONE SDL_GAMEPAD_TYPE_XBOXONE
|
||||
|
@ -626,17 +623,14 @@
|
|||
#define SDL_CONTROLLER_BUTTON_TOUCHPAD SDL_CONTROLLER_BUTTON_TOUCHPAD_renamed_SDL_GAMEPAD_BUTTON_TOUCHPAD
|
||||
#define SDL_CONTROLLER_BUTTON_X SDL_CONTROLLER_BUTTON_X_renamed_SDL_GAMEPAD_BUTTON_X
|
||||
#define SDL_CONTROLLER_BUTTON_Y SDL_CONTROLLER_BUTTON_Y_renamed_SDL_GAMEPAD_BUTTON_Y
|
||||
#define SDL_CONTROLLER_TYPE_AMAZON_LUNA SDL_CONTROLLER_TYPE_AMAZON_LUNA_renamed_SDL_GAMEPAD_TYPE_AMAZON_LUNA
|
||||
#define SDL_CONTROLLER_TYPE_GOOGLE_STADIA SDL_CONTROLLER_TYPE_GOOGLE_STADIA_renamed_SDL_GAMEPAD_TYPE_GOOGLE_STADIA
|
||||
#define SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT_renamed_SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT
|
||||
#define SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR_renamed_SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR
|
||||
#define SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT_renamed_SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT
|
||||
#define SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO_renamed_SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO
|
||||
#define SDL_CONTROLLER_TYPE_NVIDIA_SHIELD SDL_CONTROLLER_TYPE_NVIDIA_SHIELD_renamed_SDL_GAMEPAD_TYPE_NVIDIA_SHIELD
|
||||
#define SDL_CONTROLLER_TYPE_PS3 SDL_CONTROLLER_TYPE_PS3_renamed_SDL_GAMEPAD_TYPE_PS3
|
||||
#define SDL_CONTROLLER_TYPE_PS4 SDL_CONTROLLER_TYPE_PS4_renamed_SDL_GAMEPAD_TYPE_PS4
|
||||
#define SDL_CONTROLLER_TYPE_PS5 SDL_CONTROLLER_TYPE_PS5_renamed_SDL_GAMEPAD_TYPE_PS5
|
||||
#define SDL_CONTROLLER_TYPE_UNKNOWN SDL_CONTROLLER_TYPE_UNKNOWN_renamed_SDL_GAMEPAD_TYPE_UNKNOWN
|
||||
#define SDL_CONTROLLER_TYPE_UNKNOWN SDL_CONTROLLER_TYPE_UNKNOWN_renamed_SDL_GAMEPAD_TYPE_STANDARD
|
||||
#define SDL_CONTROLLER_TYPE_VIRTUAL SDL_CONTROLLER_TYPE_VIRTUAL_renamed_SDL_GAMEPAD_TYPE_VIRTUAL
|
||||
#define SDL_CONTROLLER_TYPE_XBOX360 SDL_CONTROLLER_TYPE_XBOX360_renamed_SDL_GAMEPAD_TYPE_XBOX360
|
||||
#define SDL_CONTROLLER_TYPE_XBOXONE SDL_CONTROLLER_TYPE_XBOXONE_renamed_SDL_GAMEPAD_TYPE_XBOXONE
|
||||
|
|
|
@ -871,6 +871,10 @@ SDL3_0.0.0 {
|
|||
SDL_GetGamepadPowerLevel;
|
||||
SDL_SetGamepadMapping;
|
||||
SDL_strndup;
|
||||
SDL_GetGamepadTypeFromString;
|
||||
SDL_GetGamepadStringForType;
|
||||
SDL_GetRealGamepadInstanceType;
|
||||
SDL_GetRealGamepadType;
|
||||
# extra symbols go here (don't modify this line)
|
||||
local: *;
|
||||
};
|
||||
|
|
|
@ -897,3 +897,7 @@
|
|||
#define SDL_GetGamepadPowerLevel SDL_GetGamepadPowerLevel_REAL
|
||||
#define SDL_SetGamepadMapping SDL_SetGamepadMapping_REAL
|
||||
#define SDL_strndup SDL_strndup_REAL
|
||||
#define SDL_GetGamepadTypeFromString SDL_GetGamepadTypeFromString_REAL
|
||||
#define SDL_GetGamepadStringForType SDL_GetGamepadStringForType_REAL
|
||||
#define SDL_GetRealGamepadInstanceType SDL_GetRealGamepadInstanceType_REAL
|
||||
#define SDL_GetRealGamepadType SDL_GetRealGamepadType_REAL
|
||||
|
|
|
@ -942,3 +942,7 @@ SDL_DYNAPI_PROC(SDL_JoystickID,SDL_GetGamepadInstanceID,(SDL_Gamepad *a),(a),ret
|
|||
SDL_DYNAPI_PROC(SDL_JoystickPowerLevel,SDL_GetGamepadPowerLevel,(SDL_Gamepad *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SetGamepadMapping,(SDL_JoystickID a, const char *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(char*,SDL_strndup,(const char *a, size_t b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(SDL_GamepadType,SDL_GetGamepadTypeFromString,(const char *a),(a),return)
|
||||
SDL_DYNAPI_PROC(const char*,SDL_GetGamepadStringForType,(SDL_GamepadType a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_GamepadType,SDL_GetRealGamepadInstanceType,(SDL_JoystickID a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_GamepadType,SDL_GetRealGamepadType,(SDL_Gamepad *a),(a),return)
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
|
||||
#define SDL_GAMEPAD_CRC_FIELD "crc:"
|
||||
#define SDL_GAMEPAD_CRC_FIELD_SIZE 4 /* hard-coded for speed */
|
||||
#define SDL_GAMEPAD_TYPE_FIELD "type:"
|
||||
#define SDL_GAMEPAD_TYPE_FIELD_SIZE SDL_strlen(SDL_GAMEPAD_TYPE_FIELD)
|
||||
#define SDL_GAMEPAD_PLATFORM_FIELD "platform:"
|
||||
#define SDL_GAMEPAD_PLATFORM_FIELD_SIZE SDL_strlen(SDL_GAMEPAD_PLATFORM_FIELD)
|
||||
#define SDL_GAMEPAD_HINT_FIELD "hint:"
|
||||
|
@ -864,22 +866,71 @@ static GamepadMapping_t *SDL_PrivateGetGamepadMappingForGUID(SDL_JoystickGUID gu
|
|||
return mapping;
|
||||
}
|
||||
|
||||
static const char *map_StringForGamepadType[] = {
|
||||
"unknown",
|
||||
"standard",
|
||||
"xbox360",
|
||||
"xboxone",
|
||||
"ps3",
|
||||
"ps4",
|
||||
"ps5",
|
||||
"switchpro",
|
||||
"joyconleft",
|
||||
"joyconright",
|
||||
"joyconpair"
|
||||
};
|
||||
SDL_COMPILE_TIME_ASSERT(map_StringForGamepadType, SDL_arraysize(map_StringForGamepadType) == SDL_GAMEPAD_TYPE_MAX);
|
||||
|
||||
/*
|
||||
* convert a string to its enum equivalent
|
||||
*/
|
||||
SDL_GamepadType SDL_GetGamepadTypeFromString(const char *str)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (str == NULL || str[0] == '\0') {
|
||||
return SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
if (*str == '+' || *str == '-') {
|
||||
++str;
|
||||
}
|
||||
|
||||
for (i = 0; i < SDL_arraysize(map_StringForGamepadType); ++i) {
|
||||
if (SDL_strcasecmp(str, map_StringForGamepadType[i]) == 0) {
|
||||
return (SDL_GamepadType)i;
|
||||
}
|
||||
}
|
||||
return SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert an enum to its string equivalent
|
||||
*/
|
||||
const char *SDL_GetGamepadStringForType(SDL_GamepadType type)
|
||||
{
|
||||
if (type >= SDL_GAMEPAD_TYPE_STANDARD && type < SDL_GAMEPAD_TYPE_MAX) {
|
||||
return map_StringForGamepadType[type];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *map_StringForGamepadAxis[] = {
|
||||
"leftx",
|
||||
"lefty",
|
||||
"rightx",
|
||||
"righty",
|
||||
"lefttrigger",
|
||||
"righttrigger",
|
||||
NULL
|
||||
"righttrigger"
|
||||
};
|
||||
SDL_COMPILE_TIME_ASSERT(map_StringForGamepadAxis, SDL_arraysize(map_StringForGamepadAxis) == SDL_GAMEPAD_AXIS_MAX);
|
||||
|
||||
/*
|
||||
* convert a string to its enum equivalent
|
||||
*/
|
||||
SDL_GamepadAxis SDL_GetGamepadAxisFromString(const char *str)
|
||||
{
|
||||
int entry;
|
||||
int i;
|
||||
|
||||
if (str == NULL || str[0] == '\0') {
|
||||
return SDL_GAMEPAD_AXIS_INVALID;
|
||||
|
@ -889,9 +940,9 @@ SDL_GamepadAxis SDL_GetGamepadAxisFromString(const char *str)
|
|||
++str;
|
||||
}
|
||||
|
||||
for (entry = 0; map_StringForGamepadAxis[entry]; ++entry) {
|
||||
if (SDL_strcasecmp(str, map_StringForGamepadAxis[entry]) == 0) {
|
||||
return (SDL_GamepadAxis)entry;
|
||||
for (i = 0; i < SDL_arraysize(map_StringForGamepadAxis); ++i) {
|
||||
if (SDL_strcasecmp(str, map_StringForGamepadAxis[i]) == 0) {
|
||||
return (SDL_GamepadAxis)i;
|
||||
}
|
||||
}
|
||||
return SDL_GAMEPAD_AXIS_INVALID;
|
||||
|
@ -929,23 +980,24 @@ static const char *map_StringForGamepadButton[] = {
|
|||
"paddle2",
|
||||
"paddle3",
|
||||
"paddle4",
|
||||
"touchpad",
|
||||
NULL
|
||||
"touchpad"
|
||||
};
|
||||
SDL_COMPILE_TIME_ASSERT(map_StringForGamepadButton, SDL_arraysize(map_StringForGamepadButton) == SDL_GAMEPAD_BUTTON_MAX);
|
||||
|
||||
/*
|
||||
* convert a string to its enum equivalent
|
||||
*/
|
||||
SDL_GamepadButton SDL_GetGamepadButtonFromString(const char *str)
|
||||
{
|
||||
int entry;
|
||||
int i;
|
||||
|
||||
if (str == NULL || str[0] == '\0') {
|
||||
return SDL_GAMEPAD_BUTTON_INVALID;
|
||||
}
|
||||
|
||||
for (entry = 0; map_StringForGamepadButton[entry]; ++entry) {
|
||||
if (SDL_strcasecmp(str, map_StringForGamepadButton[entry]) == 0) {
|
||||
return (SDL_GamepadButton)entry;
|
||||
for (i = 0; i < SDL_arraysize(map_StringForGamepadButton); ++i) {
|
||||
if (SDL_strcasecmp(str, map_StringForGamepadButton[i]) == 0) {
|
||||
return (SDL_GamepadButton)i;
|
||||
}
|
||||
}
|
||||
return SDL_GAMEPAD_BUTTON_INVALID;
|
||||
|
@ -2048,6 +2100,37 @@ Uint16 SDL_GetGamepadInstanceProductVersion(SDL_JoystickID instance_id)
|
|||
}
|
||||
|
||||
SDL_GamepadType SDL_GetGamepadInstanceType(SDL_JoystickID instance_id)
|
||||
{
|
||||
SDL_GamepadType type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
{
|
||||
GamepadMapping_t *mapping = SDL_PrivateGetGamepadMapping(instance_id);
|
||||
if (mapping != NULL) {
|
||||
char *type_string, *comma;
|
||||
|
||||
type_string = SDL_strstr(mapping->mapping, SDL_GAMEPAD_TYPE_FIELD);
|
||||
if (type_string != NULL) {
|
||||
type_string += SDL_GAMEPAD_TYPE_FIELD_SIZE;
|
||||
comma = SDL_strchr(type_string, ',');
|
||||
if (comma != NULL) {
|
||||
*comma = '\0';
|
||||
type = SDL_GetGamepadTypeFromString(type_string);
|
||||
*comma = ',';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
if (type != SDL_GAMEPAD_TYPE_UNKNOWN) {
|
||||
return type;
|
||||
}
|
||||
return SDL_GetRealGamepadInstanceType(instance_id);
|
||||
}
|
||||
|
||||
SDL_GamepadType SDL_GetRealGamepadInstanceType(SDL_JoystickID instance_id)
|
||||
{
|
||||
return SDL_GetGamepadTypeFromGUID(SDL_GetJoystickInstanceGUID(instance_id), SDL_GetJoystickInstanceName(instance_id));
|
||||
}
|
||||
|
@ -2753,6 +2836,21 @@ const char *SDL_GetGamepadPath(SDL_Gamepad *gamepad)
|
|||
}
|
||||
|
||||
SDL_GamepadType SDL_GetGamepadType(SDL_Gamepad *gamepad)
|
||||
{
|
||||
SDL_JoystickID instance_id = 0;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
{
|
||||
CHECK_GAMEPAD_MAGIC(gamepad, SDL_GAMEPAD_TYPE_UNKNOWN);
|
||||
|
||||
instance_id = gamepad->joystick->instance_id;
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
return SDL_GetGamepadInstanceType(instance_id);
|
||||
}
|
||||
|
||||
SDL_GamepadType SDL_GetRealGamepadType(SDL_Gamepad *gamepad)
|
||||
{
|
||||
SDL_Joystick *joystick = SDL_GetGamepadJoystick(gamepad);
|
||||
|
||||
|
|
|
@ -2271,7 +2271,7 @@ void SDL_SetJoystickGUIDCRC(SDL_JoystickGUID *guid, Uint16 crc)
|
|||
|
||||
SDL_GamepadType SDL_GetGamepadTypeFromVIDPID(Uint16 vendor, Uint16 product, const char *name, SDL_bool forUI)
|
||||
{
|
||||
SDL_GamepadType type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
SDL_GamepadType type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
|
||||
if (vendor == 0x0000 && product == 0x0000) {
|
||||
/* Some devices are only identifiable by their name */
|
||||
|
@ -2284,7 +2284,7 @@ SDL_GamepadType SDL_GetGamepadTypeFromVIDPID(Uint16 vendor, Uint16 product, cons
|
|||
}
|
||||
|
||||
} else if (vendor == 0x0001 && product == 0x0001) {
|
||||
type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
|
||||
} else if (vendor == USB_VENDOR_MICROSOFT && product == USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER) {
|
||||
type = SDL_GAMEPAD_TYPE_XBOXONE;
|
||||
|
@ -2295,7 +2295,7 @@ SDL_GamepadType SDL_GetGamepadTypeFromVIDPID(Uint16 vendor, Uint16 product, cons
|
|||
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT) {
|
||||
if (name && SDL_strstr(name, "NES Controller") != NULL) {
|
||||
/* We don't have a type for the Nintendo Online NES Controller */
|
||||
type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
} else {
|
||||
type = SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT;
|
||||
}
|
||||
|
@ -2331,7 +2331,7 @@ SDL_GamepadType SDL_GetGamepadTypeFromVIDPID(Uint16 vendor, Uint16 product, cons
|
|||
if (forUI) {
|
||||
type = SDL_GAMEPAD_TYPE_PS4;
|
||||
} else {
|
||||
type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
}
|
||||
break;
|
||||
case k_eControllerType_SwitchProController:
|
||||
|
@ -2342,7 +2342,7 @@ SDL_GamepadType SDL_GetGamepadTypeFromVIDPID(Uint16 vendor, Uint16 product, cons
|
|||
if (forUI) {
|
||||
type = SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO;
|
||||
} else {
|
||||
type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -2359,7 +2359,7 @@ SDL_GamepadType SDL_GetGamepadTypeFromGUID(SDL_JoystickGUID guid, const char *na
|
|||
|
||||
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
|
||||
type = SDL_GetGamepadTypeFromVIDPID(vendor, product, name, SDL_TRUE);
|
||||
if (type == SDL_GAMEPAD_TYPE_UNKNOWN) {
|
||||
if (type == SDL_GAMEPAD_TYPE_STANDARD) {
|
||||
if (SDL_IsJoystickXInput(guid)) {
|
||||
/* This is probably an Xbox One controller */
|
||||
return SDL_GAMEPAD_TYPE_XBOXONE;
|
||||
|
|
|
@ -1219,40 +1219,40 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
|
|||
break;
|
||||
case k_eSwitchDeviceInfoControllerType_HVCLeft:
|
||||
HIDAPI_SetDeviceName(device, "Nintendo HVC Controller (1)");
|
||||
device->type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
device->type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
break;
|
||||
case k_eSwitchDeviceInfoControllerType_HVCRight:
|
||||
HIDAPI_SetDeviceName(device, "Nintendo HVC Controller (2)");
|
||||
device->type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
device->type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
break;
|
||||
case k_eSwitchDeviceInfoControllerType_NESLeft:
|
||||
HIDAPI_SetDeviceName(device, "Nintendo NES Controller (L)");
|
||||
device->type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
device->type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
break;
|
||||
case k_eSwitchDeviceInfoControllerType_NESRight:
|
||||
HIDAPI_SetDeviceName(device, "Nintendo NES Controller (R)");
|
||||
device->type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
device->type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
break;
|
||||
case k_eSwitchDeviceInfoControllerType_SNES:
|
||||
HIDAPI_SetDeviceName(device, "Nintendo SNES Controller");
|
||||
HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SNES_CONTROLLER);
|
||||
device->type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
device->type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
break;
|
||||
case k_eSwitchDeviceInfoControllerType_N64:
|
||||
HIDAPI_SetDeviceName(device, "Nintendo N64 Controller");
|
||||
HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_N64_CONTROLLER);
|
||||
device->type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
device->type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
break;
|
||||
case k_eSwitchDeviceInfoControllerType_SEGA_Genesis:
|
||||
HIDAPI_SetDeviceName(device, "Nintendo SEGA Genesis Controller");
|
||||
HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER);
|
||||
device->type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
device->type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
break;
|
||||
case k_eSwitchDeviceInfoControllerType_Unknown:
|
||||
/* We couldn't read the device info for this controller, might not be fully compliant */
|
||||
return;
|
||||
default:
|
||||
device->type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
device->type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
break;
|
||||
}
|
||||
device->guid.data[15] = ctx->m_eControllerType;
|
||||
|
|
|
@ -139,7 +139,7 @@ SDL_bool HIDAPI_SupportsPlaystationDetection(Uint16 vendor, Uint16 product)
|
|||
/* If we already know the controller is a different type, don't try to detect it.
|
||||
* This fixes a hang with the HORIPAD for Nintendo Switch (0x0f0d/0x00c1)
|
||||
*/
|
||||
if (SDL_GetGamepadTypeFromVIDPID(vendor, product, NULL, SDL_FALSE) != SDL_GAMEPAD_TYPE_UNKNOWN) {
|
||||
if (SDL_GetGamepadTypeFromVIDPID(vendor, product, NULL, SDL_FALSE) != SDL_GAMEPAD_TYPE_STANDARD) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
|
@ -208,7 +208,7 @@ static SDL_GamepadType SDL_GetJoystickGameControllerProtocol(const char *name, U
|
|||
static const int XBONE_IFACE_SUBCLASS = 71;
|
||||
static const int XBONE_IFACE_PROTOCOL = 208;
|
||||
|
||||
SDL_GamepadType type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
SDL_GamepadType type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
|
||||
/* This code should match the checks in libusb/hid.c and HIDDeviceManager.java */
|
||||
if (interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
|
||||
|
@ -283,7 +283,7 @@ static SDL_GamepadType SDL_GetJoystickGameControllerProtocol(const char *name, U
|
|||
}
|
||||
}
|
||||
|
||||
if (type == SDL_GAMEPAD_TYPE_UNKNOWN) {
|
||||
if (type == SDL_GAMEPAD_TYPE_STANDARD) {
|
||||
type = SDL_GetGamepadTypeFromVIDPID(vendor, product, name, SDL_FALSE);
|
||||
}
|
||||
return type;
|
||||
|
@ -1284,7 +1284,7 @@ SDL_JoystickType HIDAPI_GetJoystickTypeFromGUID(SDL_JoystickGUID guid)
|
|||
SDL_GamepadType HIDAPI_GetGamepadTypeFromGUID(SDL_JoystickGUID guid)
|
||||
{
|
||||
SDL_HIDAPI_Device *device;
|
||||
SDL_GamepadType type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
SDL_GamepadType type = SDL_GAMEPAD_TYPE_STANDARD;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
for (device = SDL_HIDAPI_devices; device; device = device->next) {
|
||||
|
|
|
@ -71,6 +71,10 @@ def save_controller(line):
|
|||
print("Controller '%s' not unique, skipping" % name)
|
||||
return
|
||||
|
||||
pos = find_element("type", bindings)
|
||||
if pos >= 0:
|
||||
bindings.insert(0, bindings.pop(pos))
|
||||
|
||||
pos = find_element("platform", bindings)
|
||||
if pos >= 0:
|
||||
bindings.insert(0, bindings.pop(pos))
|
||||
|
|
|
@ -1268,6 +1268,177 @@ void DestroyGamepadDisplay(GamepadDisplay *ctx)
|
|||
SDL_free(ctx);
|
||||
}
|
||||
|
||||
struct GamepadTypeDisplay
|
||||
{
|
||||
SDL_Renderer *renderer;
|
||||
|
||||
int type_highlighted;
|
||||
SDL_bool type_pressed;
|
||||
int type_selected;
|
||||
SDL_GamepadType real_type;
|
||||
|
||||
SDL_Rect area;
|
||||
};
|
||||
|
||||
GamepadTypeDisplay *CreateGamepadTypeDisplay(SDL_Renderer *renderer)
|
||||
{
|
||||
GamepadTypeDisplay *ctx = SDL_calloc(1, sizeof(*ctx));
|
||||
if (ctx) {
|
||||
ctx->renderer = renderer;
|
||||
|
||||
ctx->type_highlighted = SDL_GAMEPAD_TYPE_UNSELECTED;
|
||||
ctx->type_selected = SDL_GAMEPAD_TYPE_UNSELECTED;
|
||||
ctx->real_type = SDL_GAMEPAD_TYPE_UNKNOWN;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void SetGamepadTypeDisplayArea(GamepadTypeDisplay *ctx, const SDL_Rect *area)
|
||||
{
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_copyp(&ctx->area, area);
|
||||
}
|
||||
|
||||
void SetGamepadTypeDisplayHighlight(GamepadTypeDisplay *ctx, int type, SDL_bool pressed)
|
||||
{
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->type_highlighted = type;
|
||||
ctx->type_pressed = pressed;
|
||||
}
|
||||
|
||||
void SetGamepadTypeDisplaySelected(GamepadTypeDisplay *ctx, int type)
|
||||
{
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->type_selected = type;
|
||||
}
|
||||
|
||||
void SetGamepadTypeDisplayRealType(GamepadTypeDisplay *ctx, SDL_GamepadType type)
|
||||
{
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->real_type = type;
|
||||
}
|
||||
|
||||
int GetGamepadTypeDisplayAt(GamepadTypeDisplay *ctx, float x, float y)
|
||||
{
|
||||
int i;
|
||||
const float margin = 8.0f;
|
||||
const float line_height = 16.0f;
|
||||
SDL_FRect highlight;
|
||||
SDL_FPoint point;
|
||||
|
||||
if (!ctx) {
|
||||
return SDL_GAMEPAD_TYPE_UNSELECTED;
|
||||
}
|
||||
|
||||
point.x = x;
|
||||
point.y = y;
|
||||
|
||||
x = ctx->area.x + margin;
|
||||
y = ctx->area.y + margin;
|
||||
|
||||
for (i = SDL_GAMEPAD_TYPE_UNKNOWN; i < SDL_GAMEPAD_TYPE_MAX; ++i) {
|
||||
highlight.x = x;
|
||||
highlight.y = y;
|
||||
highlight.w = (float)ctx->area.w - (margin * 2);
|
||||
highlight.h = (float)line_height;
|
||||
|
||||
if (SDL_PointInRectFloat(&point, &highlight)) {
|
||||
return i;
|
||||
}
|
||||
|
||||
y += line_height;
|
||||
}
|
||||
return SDL_GAMEPAD_TYPE_UNSELECTED;
|
||||
}
|
||||
|
||||
static void RenderGamepadTypeHighlight(GamepadTypeDisplay *ctx, int type, const SDL_FRect *area)
|
||||
{
|
||||
if (type == ctx->type_highlighted || type == ctx->type_selected) {
|
||||
Uint8 r, g, b, a;
|
||||
|
||||
SDL_GetRenderDrawColor(ctx->renderer, &r, &g, &b, &a);
|
||||
|
||||
if (type == ctx->type_highlighted) {
|
||||
if (ctx->type_pressed) {
|
||||
SDL_SetRenderDrawColor(ctx->renderer, PRESSED_COLOR);
|
||||
} else {
|
||||
SDL_SetRenderDrawColor(ctx->renderer, HIGHLIGHT_COLOR);
|
||||
}
|
||||
} else {
|
||||
SDL_SetRenderDrawColor(ctx->renderer, SELECTED_COLOR);
|
||||
}
|
||||
SDL_RenderFillRect(ctx->renderer, area);
|
||||
|
||||
SDL_SetRenderDrawColor(ctx->renderer, r, g, b, a);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderGamepadTypeDisplay(GamepadTypeDisplay *ctx)
|
||||
{
|
||||
float x, y;
|
||||
int i;
|
||||
char text[128];
|
||||
const float margin = 8.0f;
|
||||
const float line_height = 16.0f;
|
||||
SDL_FPoint dst;
|
||||
SDL_FRect highlight;
|
||||
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
x = ctx->area.x + margin;
|
||||
y = ctx->area.y + margin;
|
||||
|
||||
for (i = SDL_GAMEPAD_TYPE_UNKNOWN; i < SDL_GAMEPAD_TYPE_MAX; ++i) {
|
||||
highlight.x = x;
|
||||
highlight.y = y;
|
||||
highlight.w = (float)ctx->area.w - (margin * 2);
|
||||
highlight.h = (float)line_height;
|
||||
RenderGamepadTypeHighlight(ctx, i, &highlight);
|
||||
|
||||
if (i == SDL_GAMEPAD_TYPE_UNKNOWN) {
|
||||
if (ctx->real_type == SDL_GAMEPAD_TYPE_UNKNOWN ||
|
||||
ctx->real_type == SDL_GAMEPAD_TYPE_STANDARD) {
|
||||
SDL_strlcpy(text, "Auto (Standard)", sizeof(text));
|
||||
} else {
|
||||
SDL_snprintf(text, sizeof(text), "Auto (%s)", GetGamepadTypeString(ctx->real_type));
|
||||
}
|
||||
} else if (i == SDL_GAMEPAD_TYPE_STANDARD) {
|
||||
SDL_strlcpy(text, "Standard", sizeof(text));
|
||||
} else {
|
||||
SDL_strlcpy(text, GetGamepadTypeString((SDL_GamepadType)i), sizeof(text));
|
||||
}
|
||||
|
||||
dst.x = x + margin;
|
||||
dst.y = y + line_height / 2 - FONT_CHARACTER_SIZE / 2;
|
||||
SDLTest_DrawString(ctx->renderer, dst.x, dst.y, text);
|
||||
|
||||
y += line_height;
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyGamepadTypeDisplay(GamepadTypeDisplay *ctx)
|
||||
{
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_free(ctx);
|
||||
}
|
||||
|
||||
|
||||
struct JoystickDisplay
|
||||
{
|
||||
|
@ -2185,13 +2356,14 @@ static char *JoinMapping(MappingParts *parts)
|
|||
}
|
||||
length += 1;
|
||||
|
||||
/* The sort order is: crc, platform, *, sdk, hint */
|
||||
/* The sort order is: crc, platform, type, *, sdk, hint */
|
||||
sort_order = SDL_stack_alloc(MappingSortEntry, parts->num_elements);
|
||||
for (i = 0; i < parts->num_elements; ++i) {
|
||||
sort_order[i].parts = parts;
|
||||
sort_order[i].index = i;
|
||||
}
|
||||
SDL_qsort(sort_order, parts->num_elements, sizeof(*sort_order), SortMapping);
|
||||
MoveSortedEntry("type", sort_order, parts->num_elements, SDL_TRUE);
|
||||
MoveSortedEntry("platform", sort_order, parts->num_elements, SDL_TRUE);
|
||||
MoveSortedEntry("crc", sort_order, parts->num_elements, SDL_TRUE);
|
||||
MoveSortedEntry("sdk>=", sort_order, parts->num_elements, SDL_FALSE);
|
||||
|
@ -2334,7 +2506,7 @@ static char *SetMappingValue(char *mapping, const char *key, const char *value)
|
|||
return mapping;
|
||||
}
|
||||
|
||||
static char *RemoveMappingKey(char *mapping, const char *key)
|
||||
static char *RemoveMappingValue(char *mapping, const char *key)
|
||||
{
|
||||
MappingParts parts;
|
||||
int i;
|
||||
|
@ -2447,14 +2619,46 @@ char *SetMappingName(char *mapping, const char *name)
|
|||
return RecreateMapping(&parts, mapping);
|
||||
}
|
||||
|
||||
char *GetMappingType(const char *mapping)
|
||||
|
||||
const char *GetGamepadTypeString(SDL_GamepadType type)
|
||||
{
|
||||
return GetMappingValue(mapping, "type");
|
||||
switch (type) {
|
||||
case SDL_GAMEPAD_TYPE_XBOX360:
|
||||
return "Xbox 360";
|
||||
case SDL_GAMEPAD_TYPE_XBOXONE:
|
||||
return "Xbox One";
|
||||
case SDL_GAMEPAD_TYPE_PS3:
|
||||
return "PS3";
|
||||
case SDL_GAMEPAD_TYPE_PS4:
|
||||
return "PS4";
|
||||
case SDL_GAMEPAD_TYPE_PS5:
|
||||
return "PS5";
|
||||
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO:
|
||||
return "Nintendo Switch";
|
||||
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT:
|
||||
return "Joy-Con (L)";
|
||||
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT:
|
||||
return "Joy-Con (R)";
|
||||
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR:
|
||||
return "Joy-Con Pair";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
char *SetMappingType(char *mapping, const char *type)
|
||||
SDL_GamepadType GetMappingType(const char *mapping)
|
||||
{
|
||||
return SetMappingValue(mapping, "type", type);
|
||||
return SDL_GetGamepadTypeFromString(GetMappingValue(mapping, "type"));
|
||||
}
|
||||
|
||||
char *SetMappingType(char *mapping, SDL_GamepadType type)
|
||||
{
|
||||
const char *type_string = SDL_GetGamepadStringForType(type);
|
||||
if (type_string == NULL || type == SDL_GAMEPAD_TYPE_UNKNOWN) {
|
||||
return RemoveMappingValue(mapping, "type");
|
||||
} else {
|
||||
return SetMappingValue(mapping, "type", type_string);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *GetElementKey(int element)
|
||||
|
@ -2527,7 +2731,7 @@ char *SetElementBinding(char *mapping, int element, const char *binding)
|
|||
if (binding) {
|
||||
return SetMappingValue(mapping, GetElementKey(element), binding);
|
||||
} else {
|
||||
return RemoveMappingKey(mapping, GetElementKey(element));
|
||||
return RemoveMappingValue(mapping, GetElementKey(element));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,24 @@ extern void SetGamepadDisplaySelected(GamepadDisplay *ctx, int element);
|
|||
extern void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad);
|
||||
extern void DestroyGamepadDisplay(GamepadDisplay *ctx);
|
||||
|
||||
/* Gamepad type display */
|
||||
|
||||
enum
|
||||
{
|
||||
SDL_GAMEPAD_TYPE_UNSELECTED = -1
|
||||
};
|
||||
|
||||
typedef struct GamepadTypeDisplay GamepadTypeDisplay;
|
||||
|
||||
extern GamepadTypeDisplay *CreateGamepadTypeDisplay(SDL_Renderer *renderer);
|
||||
extern void SetGamepadTypeDisplayArea(GamepadTypeDisplay *ctx, const SDL_Rect *area);
|
||||
extern int GetGamepadTypeDisplayAt(GamepadTypeDisplay *ctx, float x, float y);
|
||||
extern void SetGamepadTypeDisplayHighlight(GamepadTypeDisplay *ctx, int type, SDL_bool pressed);
|
||||
extern void SetGamepadTypeDisplaySelected(GamepadTypeDisplay *ctx, int type);
|
||||
extern void SetGamepadTypeDisplayRealType(GamepadTypeDisplay *ctx, SDL_GamepadType type);
|
||||
extern void RenderGamepadTypeDisplay(GamepadTypeDisplay *ctx);
|
||||
extern void DestroyGamepadTypeDisplay(GamepadTypeDisplay *ctx);
|
||||
|
||||
/* Joystick element display */
|
||||
|
||||
typedef struct JoystickDisplay JoystickDisplay;
|
||||
|
@ -131,11 +149,14 @@ extern char *GetMappingName(const char *mapping);
|
|||
/* Set the name in a mapping, freeing the mapping passed in and returning a new mapping */
|
||||
extern char *SetMappingName(char *mapping, const char *name);
|
||||
|
||||
/* Get the friendly string for an SDL_GamepadType */
|
||||
extern const char *GetGamepadTypeString(SDL_GamepadType type);
|
||||
|
||||
/* Return the type from a mapping, which should be freed using SDL_free(), or NULL if there is no type specified */
|
||||
extern char *GetMappingType(const char *mapping);
|
||||
extern SDL_GamepadType GetMappingType(const char *mapping);
|
||||
|
||||
/* Set the type in a mapping, freeing the mapping passed in and returning a new mapping */
|
||||
extern char *SetMappingType(char *mapping, const char *type);
|
||||
extern char *SetMappingType(char *mapping, SDL_GamepadType type);
|
||||
|
||||
/* Return true if a mapping has this element bound */
|
||||
extern SDL_bool MappingHasElement(const char *mapping, int element);
|
||||
|
|
|
@ -68,6 +68,7 @@ static SDL_Renderer *screen = NULL;
|
|||
static ControllerDisplayMode display_mode = CONTROLLER_MODE_TESTING;
|
||||
static GamepadImage *image = NULL;
|
||||
static GamepadDisplay *gamepad_elements = NULL;
|
||||
static GamepadTypeDisplay *gamepad_type = NULL;
|
||||
static JoystickDisplay *joystick_elements = NULL;
|
||||
static GamepadButton *setup_mapping_button = NULL;
|
||||
static GamepadButton *done_mapping_button = NULL;
|
||||
|
@ -89,6 +90,9 @@ static Uint64 binding_advance_time = 0;
|
|||
static SDL_FRect title_area;
|
||||
static SDL_bool title_highlighted;
|
||||
static SDL_bool title_pressed;
|
||||
static SDL_FRect type_area;
|
||||
static SDL_bool type_highlighted;
|
||||
static SDL_bool type_pressed;
|
||||
static char *controller_name;
|
||||
static SDL_Joystick *virtual_joystick = NULL;
|
||||
static SDL_GamepadAxis virtual_axis_active = SDL_GAMEPAD_AXIS_INVALID;
|
||||
|
@ -210,8 +214,12 @@ static void ClearButtonHighlights(void)
|
|||
title_highlighted = SDL_FALSE;
|
||||
title_pressed = SDL_FALSE;
|
||||
|
||||
type_highlighted = SDL_FALSE;
|
||||
type_pressed = SDL_FALSE;
|
||||
|
||||
ClearGamepadImage(image);
|
||||
SetGamepadDisplayHighlight(gamepad_elements, SDL_GAMEPAD_ELEMENT_INVALID, SDL_FALSE);
|
||||
SetGamepadTypeDisplayHighlight(gamepad_type, SDL_GAMEPAD_TYPE_UNSELECTED, SDL_FALSE);
|
||||
SetGamepadButtonHighlight(setup_mapping_button, SDL_FALSE, SDL_FALSE);
|
||||
SetGamepadButtonHighlight(done_mapping_button, SDL_FALSE, SDL_FALSE);
|
||||
SetGamepadButtonHighlight(cancel_button, SDL_FALSE, SDL_FALSE);
|
||||
|
@ -241,6 +249,14 @@ static void UpdateButtonHighlights(float x, float y, SDL_bool button_down)
|
|||
title_pressed = SDL_FALSE;
|
||||
}
|
||||
|
||||
if (SDL_PointInRectFloat(&point, &type_area)) {
|
||||
type_highlighted = SDL_TRUE;
|
||||
type_pressed = button_down;
|
||||
} else {
|
||||
type_highlighted = SDL_FALSE;
|
||||
type_pressed = SDL_FALSE;
|
||||
}
|
||||
|
||||
if (controller->joystick != virtual_joystick) {
|
||||
gamepad_highlight_element = GetGamepadImageElementAt(image, x, y);
|
||||
}
|
||||
|
@ -249,6 +265,11 @@ static void UpdateButtonHighlights(float x, float y, SDL_bool button_down)
|
|||
}
|
||||
SetGamepadDisplayHighlight(gamepad_elements, gamepad_highlight_element, button_down);
|
||||
|
||||
if (binding_element == SDL_GAMEPAD_ELEMENT_TYPE) {
|
||||
int gamepad_highlight_type = GetGamepadTypeDisplayAt(gamepad_type, x, y);
|
||||
SetGamepadTypeDisplayHighlight(gamepad_type, gamepad_highlight_type, button_down);
|
||||
}
|
||||
|
||||
joystick_highlight_element = GetJoystickDisplayElementAt(joystick_elements, controller->joystick, x, y);
|
||||
SetJoystickDisplayHighlight(joystick_elements, joystick_highlight_element, button_down);
|
||||
SDL_free(joystick_highlight_element);
|
||||
|
@ -606,6 +627,19 @@ static void PasteControllerName(void)
|
|||
CommitControllerName();
|
||||
}
|
||||
|
||||
static void CommitGamepadType(SDL_GamepadType type)
|
||||
{
|
||||
char *mapping = NULL;
|
||||
|
||||
if (controller->mapping) {
|
||||
mapping = SDL_strdup(controller->mapping);
|
||||
} else {
|
||||
mapping = NULL;
|
||||
}
|
||||
mapping = SetMappingType(mapping, type);
|
||||
SetAndFreeGamepadMapping(mapping);
|
||||
}
|
||||
|
||||
static const char *GetBindingInstruction(void)
|
||||
{
|
||||
switch (binding_element) {
|
||||
|
@ -1097,6 +1131,7 @@ static void DrawGamepadWaiting(SDL_Renderer *renderer)
|
|||
|
||||
static void DrawGamepadInfo(SDL_Renderer *renderer)
|
||||
{
|
||||
const char *type;
|
||||
const char *serial;
|
||||
char text[128];
|
||||
float x, y;
|
||||
|
@ -1116,9 +1151,24 @@ static void DrawGamepadInfo(SDL_Renderer *renderer)
|
|||
SDL_SetRenderDrawColor(renderer, r, g, b, a);
|
||||
}
|
||||
|
||||
if (type_highlighted) {
|
||||
Uint8 r, g, b, a;
|
||||
|
||||
SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a);
|
||||
|
||||
if (type_pressed) {
|
||||
SDL_SetRenderDrawColor(renderer, PRESSED_COLOR);
|
||||
} else {
|
||||
SDL_SetRenderDrawColor(renderer, HIGHLIGHT_COLOR);
|
||||
}
|
||||
SDL_RenderFillRect(renderer, &type_area);
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, r, g, b, a);
|
||||
}
|
||||
|
||||
if (controller_name && *controller_name) {
|
||||
x = (float)SCREEN_WIDTH / 2 - (FONT_CHARACTER_SIZE * SDL_strlen(controller_name)) / 2;
|
||||
y = (float)TITLE_HEIGHT / 2 - FONT_CHARACTER_SIZE / 2;
|
||||
x = title_area.x + title_area.w / 2 - (FONT_CHARACTER_SIZE * SDL_strlen(controller_name)) / 2;
|
||||
y = title_area.y + title_area.h / 2 - FONT_CHARACTER_SIZE / 2;
|
||||
SDLTest_DrawString(renderer, x, y, controller_name);
|
||||
}
|
||||
|
||||
|
@ -1129,6 +1179,11 @@ static void DrawGamepadInfo(SDL_Renderer *renderer)
|
|||
SDLTest_DrawString(renderer, x, y, text);
|
||||
}
|
||||
|
||||
type = GetGamepadTypeString(SDL_GetGamepadType(controller->gamepad));
|
||||
x = type_area.x + type_area.w / 2 - (FONT_CHARACTER_SIZE * SDL_strlen(type)) / 2;
|
||||
y = type_area.y + type_area.h / 2 - FONT_CHARACTER_SIZE / 2;
|
||||
SDLTest_DrawString(renderer, x, y, type);
|
||||
|
||||
if (display_mode == CONTROLLER_MODE_TESTING) {
|
||||
SDL_snprintf(text, SDL_arraysize(text), "VID: 0x%.4x PID: 0x%.4x",
|
||||
SDL_GetJoystickVendor(controller->joystick),
|
||||
|
@ -1185,6 +1240,8 @@ static void DrawBindingTips(SDL_Renderer *renderer)
|
|||
|
||||
if (binding_element == SDL_GAMEPAD_ELEMENT_NAME) {
|
||||
text = "(press RETURN to complete)";
|
||||
} else if (binding_element == SDL_GAMEPAD_ELEMENT_TYPE) {
|
||||
text = "(press ESC to cancel)";
|
||||
} else {
|
||||
bound_A = MappingHasElement(controller->mapping, SDL_GAMEPAD_BUTTON_A);
|
||||
bound_B = MappingHasElement(controller->mapping, SDL_GAMEPAD_BUTTON_B);
|
||||
|
@ -1467,6 +1524,14 @@ static void loop(void *arg)
|
|||
PasteMapping();
|
||||
} else if (title_pressed) {
|
||||
SetCurrentBindingElement(SDL_GAMEPAD_ELEMENT_NAME, SDL_FALSE);
|
||||
} else if (type_pressed) {
|
||||
SetCurrentBindingElement(SDL_GAMEPAD_ELEMENT_TYPE, SDL_FALSE);
|
||||
} else if (binding_element == SDL_GAMEPAD_ELEMENT_TYPE) {
|
||||
int type = GetGamepadTypeDisplayAt(gamepad_type, event.button.x, event.button.y);
|
||||
if (type != SDL_GAMEPAD_TYPE_UNSELECTED) {
|
||||
CommitGamepadType((SDL_GamepadType)type);
|
||||
StopBinding();
|
||||
}
|
||||
} else {
|
||||
int gamepad_element = SDL_GAMEPAD_ELEMENT_INVALID;
|
||||
char *joystick_element;
|
||||
|
@ -1599,7 +1664,12 @@ static void loop(void *arg)
|
|||
}
|
||||
RenderGamepadImage(image);
|
||||
|
||||
if (binding_element == SDL_GAMEPAD_ELEMENT_TYPE) {
|
||||
SetGamepadTypeDisplayRealType(gamepad_type, SDL_GetRealGamepadType(controller->gamepad));
|
||||
RenderGamepadTypeDisplay(gamepad_type);
|
||||
} else {
|
||||
RenderGamepadDisplay(gamepad_elements, controller->gamepad);
|
||||
}
|
||||
RenderJoystickDisplay(joystick_elements, controller->joystick);
|
||||
|
||||
if (display_mode == CONTROLLER_MODE_TESTING) {
|
||||
|
@ -1741,6 +1811,11 @@ int main(int argc, char *argv[])
|
|||
title_area.x = (float)PANEL_WIDTH + PANEL_SPACING;
|
||||
title_area.y = (float)TITLE_HEIGHT / 2 - title_area.h / 2;
|
||||
|
||||
type_area.w = (float)PANEL_WIDTH - 2 * BUTTON_MARGIN;
|
||||
type_area.h = (float)FONT_CHARACTER_SIZE + 2 * BUTTON_MARGIN;
|
||||
type_area.x = (float)BUTTON_MARGIN;
|
||||
type_area.y = (float)TITLE_HEIGHT / 2 - type_area.h / 2;
|
||||
|
||||
image = CreateGamepadImage(screen);
|
||||
if (image == NULL) {
|
||||
SDL_DestroyRenderer(screen);
|
||||
|
@ -1756,6 +1831,13 @@ int main(int argc, char *argv[])
|
|||
area.h = GAMEPAD_HEIGHT;
|
||||
SetGamepadDisplayArea(gamepad_elements, &area);
|
||||
|
||||
gamepad_type = CreateGamepadTypeDisplay(screen);
|
||||
area.x = 0;
|
||||
area.y = TITLE_HEIGHT;
|
||||
area.w = PANEL_WIDTH;
|
||||
area.h = GAMEPAD_HEIGHT;
|
||||
SetGamepadTypeDisplayArea(gamepad_type, &area);
|
||||
|
||||
joystick_elements = CreateJoystickDisplay(screen);
|
||||
area.x = PANEL_WIDTH + PANEL_SPACING + GAMEPAD_WIDTH + PANEL_SPACING;
|
||||
area.y = TITLE_HEIGHT;
|
||||
|
@ -1829,6 +1911,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
DestroyGamepadImage(image);
|
||||
DestroyGamepadDisplay(gamepad_elements);
|
||||
DestroyGamepadTypeDisplay(gamepad_type);
|
||||
DestroyJoystickDisplay(joystick_elements);
|
||||
DestroyGamepadButton(copy_button);
|
||||
SDL_DestroyRenderer(screen);
|
||||
|
|
Loading…
Reference in New Issue