Skip to content

Commit

Permalink
Added support for the touchpad on PS4 and PS5 controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Nov 14, 2020
1 parent 78422fa commit 9f51fad
Show file tree
Hide file tree
Showing 13 changed files with 434 additions and 61 deletions.
74 changes: 47 additions & 27 deletions include/SDL_events.h
Expand Up @@ -125,6 +125,9 @@ typedef enum
SDL_CONTROLLERDEVICEADDED, /**< A new Game controller has been inserted into the system */
SDL_CONTROLLERDEVICEREMOVED, /**< An opened Game controller has been removed */
SDL_CONTROLLERDEVICEREMAPPED, /**< The controller mapping was updated */
SDL_CONTROLLERTOUCHPADDOWN, /**< Game controller touchpad was touched */
SDL_CONTROLLERTOUCHPADMOTION, /**< Game controller touchpad finger was moved */
SDL_CONTROLLERTOUCHPADUP, /**< Game controller touchpad finger was lifted */

/* Touch events */
SDL_FINGERDOWN = 0x700,
Expand Down Expand Up @@ -415,6 +418,22 @@ typedef struct SDL_ControllerDeviceEvent
Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */
} SDL_ControllerDeviceEvent;

/**
* \brief Game controller touchpad event structure (event.ctouchpad.*)
*/
typedef struct SDL_ControllerTouchpadEvent
{
Uint32 type; /**< ::SDL_CONTROLLERTOUCHPADDOWN or ::SDL_CONTROLLERTOUCHPADMOTION or ::SDL_CONTROLLERTOUCHPADUP */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
SDL_JoystickID which; /**< The joystick instance id */
int touchpad; /**< The index of the touchpad */
int finger; /**< The index of the finger on the touchpad */
float x; /**< Normalized in the range 0...1 with 0 being on the left */
float y; /**< Normalized in the range 0...1 with 0 being at the top */
float pressure; /**< Normalized in the range 0...1 */
} SDL_ControllerTouchpadEvent;


/**
* \brief Audio device event structure (event.adevice.*)
*/
Expand Down Expand Up @@ -559,33 +578,34 @@ typedef struct SDL_SysWMEvent
*/
typedef union SDL_Event
{
Uint32 type; /**< Event type, shared with all events */
SDL_CommonEvent common; /**< Common event data */
SDL_DisplayEvent display; /**< Display event data */
SDL_WindowEvent window; /**< Window event data */
SDL_KeyboardEvent key; /**< Keyboard event data */
SDL_TextEditingEvent edit; /**< Text editing event data */
SDL_TextInputEvent text; /**< Text input event data */
SDL_MouseMotionEvent motion; /**< Mouse motion event data */
SDL_MouseButtonEvent button; /**< Mouse button event data */
SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */
SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */
SDL_JoyBallEvent jball; /**< Joystick ball event data */
SDL_JoyHatEvent jhat; /**< Joystick hat event data */
SDL_JoyButtonEvent jbutton; /**< Joystick button event data */
SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */
SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */
SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */
SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */
SDL_AudioDeviceEvent adevice; /**< Audio device event data */
SDL_SensorEvent sensor; /**< Sensor event data */
SDL_QuitEvent quit; /**< Quit request event data */
SDL_UserEvent user; /**< Custom event data */
SDL_SysWMEvent syswm; /**< System dependent window event data */
SDL_TouchFingerEvent tfinger; /**< Touch finger event data */
SDL_MultiGestureEvent mgesture; /**< Gesture event data */
SDL_DollarGestureEvent dgesture; /**< Gesture event data */
SDL_DropEvent drop; /**< Drag and drop event data */
Uint32 type; /**< Event type, shared with all events */
SDL_CommonEvent common; /**< Common event data */
SDL_DisplayEvent display; /**< Display event data */
SDL_WindowEvent window; /**< Window event data */
SDL_KeyboardEvent key; /**< Keyboard event data */
SDL_TextEditingEvent edit; /**< Text editing event data */
SDL_TextInputEvent text; /**< Text input event data */
SDL_MouseMotionEvent motion; /**< Mouse motion event data */
SDL_MouseButtonEvent button; /**< Mouse button event data */
SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */
SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */
SDL_JoyBallEvent jball; /**< Joystick ball event data */
SDL_JoyHatEvent jhat; /**< Joystick hat event data */
SDL_JoyButtonEvent jbutton; /**< Joystick button event data */
SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */
SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */
SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */
SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */
SDL_ControllerTouchpadEvent ctouchpad; /**< Game Controller touchpad event data */
SDL_AudioDeviceEvent adevice; /**< Audio device event data */
SDL_SensorEvent sensor; /**< Sensor event data */
SDL_QuitEvent quit; /**< Quit request event data */
SDL_UserEvent user; /**< Custom event data */
SDL_SysWMEvent syswm; /**< System dependent window event data */
SDL_TouchFingerEvent tfinger; /**< Touch finger event data */
SDL_MultiGestureEvent mgesture; /**< Gesture event data */
SDL_DollarGestureEvent dgesture; /**< Gesture event data */
SDL_DropEvent drop; /**< Drag and drop event data */

/* This is necessary for ABI compatibility between Visual C++ and GCC
Visual C++ will respect the push pack pragma and use 52 bytes for
Expand Down
40 changes: 33 additions & 7 deletions include/SDL_gamecontroller.h
Expand Up @@ -330,6 +330,12 @@ extern DECLSPEC SDL_GameControllerButtonBind SDLCALL
SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller,
SDL_GameControllerAxis axis);

/**
* Return whether a game controller has a given axis
*/
extern DECLSPEC SDL_bool SDLCALL
SDL_GameControllerHasAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis);

/**
* Get the current state of an axis control on a game controller.
*
Expand All @@ -339,8 +345,7 @@ SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller,
* The axis indices start at index 0.
*/
extern DECLSPEC Sint16 SDLCALL
SDL_GameControllerGetAxis(SDL_GameController *gamecontroller,
SDL_GameControllerAxis axis);
SDL_GameControllerGetAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis);

/**
* The list of buttons available from a controller
Expand All @@ -363,11 +368,12 @@ typedef enum
SDL_CONTROLLER_BUTTON_DPAD_DOWN,
SDL_CONTROLLER_BUTTON_DPAD_LEFT,
SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
SDL_CONTROLLER_BUTTON_MISC1, // Xbox Series X share button, PS4/PS5 touchpad button, Nintendo Switch Pro capture button
SDL_CONTROLLER_BUTTON_PADDLE1, // Xbox Elite paddle P1
SDL_CONTROLLER_BUTTON_PADDLE2, // Xbox Elite paddle P3
SDL_CONTROLLER_BUTTON_PADDLE3, // Xbox Elite paddle P2
SDL_CONTROLLER_BUTTON_PADDLE4, // Xbox Elite paddle P4
SDL_CONTROLLER_BUTTON_MISC1, /* Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button */
SDL_CONTROLLER_BUTTON_PADDLE1, /* Xbox Elite paddle P1 */
SDL_CONTROLLER_BUTTON_PADDLE2, /* Xbox Elite paddle P3 */
SDL_CONTROLLER_BUTTON_PADDLE3, /* Xbox Elite paddle P2 */
SDL_CONTROLLER_BUTTON_PADDLE4, /* Xbox Elite paddle P4 */
SDL_CONTROLLER_BUTTON_TOUCHPAD, /* PS4/PS5 touchpad button */
SDL_CONTROLLER_BUTTON_MAX
} SDL_GameControllerButton;

Expand All @@ -388,6 +394,11 @@ extern DECLSPEC SDL_GameControllerButtonBind SDLCALL
SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller,
SDL_GameControllerButton button);

/**
* Return whether a game controller has a given button
*/
extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasButton(SDL_GameController *gamecontroller,
SDL_GameControllerButton button);

/**
* Get the current state of a button on a game controller.
Expand All @@ -397,6 +408,21 @@ SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller,
extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *gamecontroller,
SDL_GameControllerButton button);

/**
* Get the number of touchpads on a game controller.
*/
extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpads(SDL_GameController *gamecontroller);

/**
* Get the number of supported simultaneous fingers on a touchpad on a game controller.
*/
extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpadFingers(SDL_GameController *gamecontroller, int touchpad);

/**
* Get the current state of a finger on a touchpad on a game controller.
*/
extern DECLSPEC int SDLCALL SDL_GameControllerGetTouchpadFinger(SDL_GameController *gamecontroller, int touchpad, int finger, Uint8 *state, float *x, float *y, float *pressure);

/**
* Start a rumble effect
* Each call to this function cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling.
Expand Down
5 changes: 5 additions & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Expand Up @@ -774,3 +774,8 @@
#define SDL_JoystickSetLED SDL_JoystickSetLED_REAL
#define SDL_GameControllerRumbleTriggers SDL_GameControllerRumbleTriggers_REAL
#define SDL_JoystickRumbleTriggers SDL_JoystickRumbleTriggers_REAL
#define SDL_GameControllerHasAxis SDL_GameControllerHasAxis_REAL
#define SDL_GameControllerHasButton SDL_GameControllerHasButton_REAL
#define SDL_GameControllerGetNumTouchpads SDL_GameControllerGetNumTouchpads_REAL
#define SDL_GameControllerGetNumTouchpadFingers SDL_GameControllerGetNumTouchpadFingers_REAL
#define SDL_GameControllerGetTouchpadFinger SDL_GameControllerGetTouchpadFinger_REAL
5 changes: 5 additions & 0 deletions src/dynapi/SDL_dynapi_procs.h
Expand Up @@ -835,3 +835,8 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickHasLED,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_JoystickSetLED,(SDL_Joystick *a, Uint8 b, Uint8 c, Uint8 d),(a,b,c,d),return)
SDL_DYNAPI_PROC(int,SDL_GameControllerRumbleTriggers,(SDL_GameController *a, Uint16 b, Uint16 c, Uint32 d),(a,b,c,d),return)
SDL_DYNAPI_PROC(int,SDL_JoystickRumbleTriggers,(SDL_Joystick *a, Uint16 b, Uint16 c, Uint32 d),(a,b,c,d),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasAxis,(SDL_GameController *a, SDL_GameControllerAxis b),(a,b),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasButton,(SDL_GameController *a, SDL_GameControllerButton b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_GameControllerGetNumTouchpads,(SDL_GameController *a),(a),return)
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)
93 changes: 91 additions & 2 deletions src/joystick/SDL_gamecontroller.c
Expand Up @@ -580,9 +580,12 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
} else {
switch (SDL_GetJoystickGameControllerTypeFromGUID(guid, NULL)) {
case SDL_CONTROLLER_TYPE_PS4:
/* PS4 controllers have an additional touchpad button */
SDL_strlcat(mapping_string, "touchpad:b15,", sizeof(mapping_string));
break;
case SDL_CONTROLLER_TYPE_PS5:
/* PS4/PS5 controllers have an additional touchpad button */
SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string));
/* PS5 controllers have a microphone button and an additional touchpad button */
SDL_strlcat(mapping_string, "misc1:b15,touchpad:b16", sizeof(mapping_string));
break;
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
/* Nintendo Switch Pro controllers have a screenshot button */
Expand Down Expand Up @@ -713,6 +716,7 @@ static const char* map_StringForControllerButton[] = {
"paddle2",
"paddle3",
"paddle4",
"touchpad",
NULL
};

Expand Down Expand Up @@ -1870,6 +1874,16 @@ SDL_GameControllerUpdate(void)
SDL_JoystickUpdate();
}

/**
* Return whether a game controller has a given axis
*/
SDL_bool
SDL_GameControllerHasAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis)
{
SDL_GameControllerButtonBind bind = SDL_GameControllerGetBindForAxis(gamecontroller, axis);
return (bind.bindType != SDL_CONTROLLER_BINDTYPE_NONE) ? SDL_TRUE : SDL_FALSE;
}

/*
* Get the current state of an axis control on a controller
*/
Expand Down Expand Up @@ -1929,6 +1943,16 @@ SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_GameControlle
return 0;
}

/**
* Return whether a game controller has a given button
*/
SDL_bool
SDL_GameControllerHasButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button)
{
SDL_GameControllerButtonBind bind = SDL_GameControllerGetBindForButton(gamecontroller, button);
return (bind.bindType != SDL_CONTROLLER_BINDTYPE_NONE) ? SDL_TRUE : SDL_FALSE;
}

/*
* Get the current state of a button on a controller
*/
Expand Down Expand Up @@ -1970,6 +1994,71 @@ SDL_GameControllerGetButton(SDL_GameController * gamecontroller, SDL_GameControl
return SDL_RELEASED;
}

/**
* Get the number of touchpads on a game controller.
*/
int
SDL_GameControllerGetNumTouchpads(SDL_GameController *gamecontroller)
{
SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller);

if (joystick) {
return joystick->ntouchpads;
}
return 0;
}

/**
* Get the number of supported simultaneous fingers on a touchpad on a game controller.
*/
int SDL_GameControllerGetNumTouchpadFingers(SDL_GameController *gamecontroller, int touchpad)
{
SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller);

if (joystick && touchpad >= 0 && touchpad < joystick->ntouchpads) {
return joystick->touchpads[touchpad].nfingers;
}
return 0;
}

/**
* Get the current state of a finger on a touchpad on a game controller.
*/
int
SDL_GameControllerGetTouchpadFinger(SDL_GameController *gamecontroller, int touchpad, int finger, Uint8 *state, float *x, float *y, float *pressure)
{
SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller);

if (joystick ) {
if (touchpad >= 0 && touchpad < joystick->ntouchpads) {
SDL_JoystickTouchpadInfo *touchpad_info = &joystick->touchpads[touchpad];
if (finger >= 0 && finger < touchpad_info->nfingers) {
SDL_JoystickTouchpadFingerInfo *info = &touchpad_info->fingers[finger];

if (state) {
*state = info->state;
}
if (x) {
*x = info->x;
}
if (y) {
*y = info->y;
}
if (pressure) {
*pressure = info->pressure;
}
return 0;
} else {
return SDL_InvalidParamError("finger");
}
} else {
return SDL_InvalidParamError("touchpad");
}
} else {
return SDL_InvalidParamError("gamecontroller");
}
}

const char *
SDL_GameControllerName(SDL_GameController * gamecontroller)
{
Expand Down
2 changes: 1 addition & 1 deletion src/joystick/SDL_gamecontrollerdb.h
Expand Up @@ -826,7 +826,7 @@ static const char *s_ControllerMappings [] =
"05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,",
"050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,",
"050000004c050000cc090000ff070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
"050000004c050000cc090000ff870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
"050000004c050000cc090000ff870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,touchpad:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
"05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,",
"050000005e040000050b0000ff070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
"050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,",
Expand Down

0 comments on commit 9f51fad

Please sign in to comment.