mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-04 08:56:25 +00:00
Implement the D-pad as a hat for SInput controllers
This lets games that use the joystick API handle the D-pad the same way as other controllers
This commit is contained in:
@@ -805,22 +805,23 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
|
|||||||
switch (product) {
|
switch (product) {
|
||||||
case USB_PRODUCT_HANDHELDLEGEND_PROGCC:
|
case USB_PRODUCT_HANDHELDLEGEND_PROGCC:
|
||||||
// ProGCC Mapping
|
// ProGCC Mapping
|
||||||
SDL_strlcat(mapping_string, "a:b1,b:b0,back:b15,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b8,lefttrigger:b12,leftx:a0,lefty:a1,misc1:b17,rightshoulder:b11,rightstick:b9,righttrigger:b13,rightx:a2,righty:a3,start:b14,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", sizeof(mapping_string));
|
SDL_strlcat(mapping_string, "a:b1,b:b0,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b4,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b7,rightstick:b5,righttrigger:b9,rightx:a2,righty:a3,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", sizeof(mapping_string));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USB_PRODUCT_HANDHELDLEGEND_GCULTIMATE:
|
case USB_PRODUCT_HANDHELDLEGEND_GCULTIMATE:
|
||||||
// GC Ultimate Map
|
// GC Ultimate Map
|
||||||
SDL_strlcat(mapping_string, "a:b0,b:b2,back:b15,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b8,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b17,misc2:b18,rightshoulder:b11,rightstick:b9,righttrigger:a5,rightx:a2,righty:a3,start:b14,x:b1,y:b3,misc3:b12,misc4:b13,hint:!SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1,", sizeof(mapping_string));
|
SDL_strlcat(mapping_string, "a:b0,b:b2,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b4,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b13,misc2:b14,rightshoulder:b7,rightstick:b5,righttrigger:a5,rightx:a2,righty:a3,start:b10,x:b1,y:b3,misc3:b8,misc4:b9,hint:!SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1,", sizeof(mapping_string));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USB_PRODUCT_HANDHELDLEGEND_SINPUT_GENERIC:
|
case USB_PRODUCT_HANDHELDLEGEND_SINPUT_GENERIC:
|
||||||
if (u_id != 1) {
|
switch (u_id) {
|
||||||
return NULL;
|
case 1:
|
||||||
}
|
|
||||||
|
|
||||||
// SuperGamepad+ Map
|
// SuperGamepad+ Map
|
||||||
if (u_id == 1) {
|
SDL_strlcat(mapping_string, "a:b1,b:b0,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b3,y:b2,", sizeof(mapping_string));
|
||||||
SDL_strlcat(mapping_string, "a:b1,b:b0,back:b11,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,leftshoulder:b8,rightshoulder:b9,start:b10,x:b3,y:b2,", sizeof(mapping_string));
|
break;
|
||||||
|
default:
|
||||||
|
// Unknown mapping
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply face style
|
// Apply face style
|
||||||
|
@@ -30,6 +30,9 @@
|
|||||||
|
|
||||||
#ifdef SDL_JOYSTICK_HIDAPI_SINPUT
|
#ifdef SDL_JOYSTICK_HIDAPI_SINPUT
|
||||||
|
|
||||||
|
/*****************************************************************************************************/
|
||||||
|
// This protocol is documented at:
|
||||||
|
// https://docs.handheldlegend.com/s/sinput/doc/sinput-hid-protocol-TkPYWlDMAg
|
||||||
/*****************************************************************************************************/
|
/*****************************************************************************************************/
|
||||||
|
|
||||||
// Define this if you want to log all packets from the controller
|
// Define this if you want to log all packets from the controller
|
||||||
@@ -83,6 +86,39 @@
|
|||||||
#define SINPUT_REPORT_IDX_TOUCH2_Y 43
|
#define SINPUT_REPORT_IDX_TOUCH2_Y 43
|
||||||
#define SINPUT_REPORT_IDX_TOUCH2_P 45
|
#define SINPUT_REPORT_IDX_TOUCH2_P 45
|
||||||
|
|
||||||
|
#define SINPUT_BUTTON_IDX_SOUTH 0
|
||||||
|
#define SINPUT_BUTTON_IDX_EAST 1
|
||||||
|
#define SINPUT_BUTTON_IDX_WEST 2
|
||||||
|
#define SINPUT_BUTTON_IDX_NORTH 3
|
||||||
|
#define SINPUT_BUTTON_IDX_DPAD_UP 4
|
||||||
|
#define SINPUT_BUTTON_IDX_DPAD_DOWN 5
|
||||||
|
#define SINPUT_BUTTON_IDX_DPAD_LEFT 6
|
||||||
|
#define SINPUT_BUTTON_IDX_DPAD_RIGHT 7
|
||||||
|
#define SINPUT_BUTTON_IDX_LEFT_STICK 8
|
||||||
|
#define SINPUT_BUTTON_IDX_RIGHT_STICK 9
|
||||||
|
#define SINPUT_BUTTON_IDX_LEFT_BUMPER 10
|
||||||
|
#define SINPUT_BUTTON_IDX_RIGHT_BUMPER 11
|
||||||
|
#define SINPUT_BUTTON_IDX_LEFT_TRIGGER 12
|
||||||
|
#define SINPUT_BUTTON_IDX_RIGHT_TRIGGER 13
|
||||||
|
#define SINPUT_BUTTON_IDX_LEFT_PADDLE1 14
|
||||||
|
#define SINPUT_BUTTON_IDX_RIGHT_PADDLE1 15
|
||||||
|
#define SINPUT_BUTTON_IDX_START 16
|
||||||
|
#define SINPUT_BUTTON_IDX_BACK 17
|
||||||
|
#define SINPUT_BUTTON_IDX_GUIDE 18
|
||||||
|
#define SINPUT_BUTTON_IDX_CAPTURE 19
|
||||||
|
#define SINPUT_BUTTON_IDX_LEFT_PADDLE2 20
|
||||||
|
#define SINPUT_BUTTON_IDX_RIGHT_PADDLE2 21
|
||||||
|
#define SINPUT_BUTTON_IDX_TOUCHPAD1 22
|
||||||
|
#define SINPUT_BUTTON_IDX_TOUCHPAD2 23
|
||||||
|
#define SINPUT_BUTTON_IDX_POWER 24
|
||||||
|
#define SINPUT_BUTTON_IDX_MISC4 25
|
||||||
|
#define SINPUT_BUTTON_IDX_MISC5 26
|
||||||
|
#define SINPUT_BUTTON_IDX_MISC6 27
|
||||||
|
#define SINPUT_BUTTON_IDX_MISC7 28
|
||||||
|
#define SINPUT_BUTTON_IDX_MISC8 29
|
||||||
|
#define SINPUT_BUTTON_IDX_MISC9 30
|
||||||
|
#define SINPUT_BUTTON_IDX_MISC10 31
|
||||||
|
|
||||||
#define SINPUT_REPORT_IDX_COMMAND_RESPONSE_ID 1
|
#define SINPUT_REPORT_IDX_COMMAND_RESPONSE_ID 1
|
||||||
#define SINPUT_REPORT_IDX_COMMAND_RESPONSE_BULK 2
|
#define SINPUT_REPORT_IDX_COMMAND_RESPONSE_BULK 2
|
||||||
|
|
||||||
@@ -160,6 +196,7 @@ typedef struct
|
|||||||
bool right_analog_stick_supported;
|
bool right_analog_stick_supported;
|
||||||
bool left_analog_trigger_supported;
|
bool left_analog_trigger_supported;
|
||||||
bool right_analog_trigger_supported;
|
bool right_analog_trigger_supported;
|
||||||
|
bool dpad_supported;
|
||||||
bool touchpad_supported;
|
bool touchpad_supported;
|
||||||
|
|
||||||
Uint8 touchpad_count; // 2 touchpads maximum
|
Uint8 touchpad_count; // 2 touchpads maximum
|
||||||
@@ -257,6 +294,17 @@ static void ProcessSDLFeaturesResponse(SDL_HIDAPI_Device *device, Uint8 *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert DPAD to hat
|
||||||
|
const DPAD_MASK = (1 << SINPUT_BUTTON_IDX_DPAD_UP) |
|
||||||
|
(1 << SINPUT_BUTTON_IDX_DPAD_DOWN) |
|
||||||
|
(1 << SINPUT_BUTTON_IDX_DPAD_LEFT) |
|
||||||
|
(1 << SINPUT_BUTTON_IDX_DPAD_RIGHT);
|
||||||
|
if ((ctx->usage_masks[0] & DPAD_MASK) == DPAD_MASK) {
|
||||||
|
ctx->dpad_supported = true;
|
||||||
|
ctx->usage_masks[0] &= ~DPAD_MASK;
|
||||||
|
ctx->buttons_count -= 4;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(DEBUG_SINPUT_INIT)
|
#if defined(DEBUG_SINPUT_INIT)
|
||||||
SDL_Log("Buttons count: %d", ctx->buttons_count);
|
SDL_Log("Buttons count: %d", ctx->buttons_count);
|
||||||
#endif
|
#endif
|
||||||
@@ -447,6 +495,10 @@ static bool HIDAPI_DriverSInput_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joys
|
|||||||
|
|
||||||
joystick->naxes = axes;
|
joystick->naxes = axes;
|
||||||
|
|
||||||
|
if (ctx->dpad_supported) {
|
||||||
|
joystick->nhats = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->accelerometer_supported) {
|
if (ctx->accelerometer_supported) {
|
||||||
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 1000.0f / ctx->polling_rate_ms);
|
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 1000.0f / ctx->polling_rate_ms);
|
||||||
}
|
}
|
||||||
@@ -594,6 +646,24 @@ static void HIDAPI_DriverSInput_HandleStatePacket(SDL_Joystick *joystick, SDL_Dr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->dpad_supported) {
|
||||||
|
Uint8 hat = SDL_HAT_CENTERED;
|
||||||
|
|
||||||
|
if (data[SINPUT_REPORT_IDX_BUTTONS_0] & (1 << SINPUT_BUTTON_IDX_DPAD_UP)) {
|
||||||
|
hat |= SDL_HAT_UP;
|
||||||
|
}
|
||||||
|
if (data[SINPUT_REPORT_IDX_BUTTONS_0] & (1 << SINPUT_BUTTON_IDX_DPAD_DOWN)) {
|
||||||
|
hat |= SDL_HAT_DOWN;
|
||||||
|
}
|
||||||
|
if (data[SINPUT_REPORT_IDX_BUTTONS_0] & (1 << SINPUT_BUTTON_IDX_DPAD_LEFT)) {
|
||||||
|
hat |= SDL_HAT_LEFT;
|
||||||
|
}
|
||||||
|
if (data[SINPUT_REPORT_IDX_BUTTONS_0] & (1 << SINPUT_BUTTON_IDX_DPAD_RIGHT)) {
|
||||||
|
hat |= SDL_HAT_RIGHT;
|
||||||
|
}
|
||||||
|
SDL_SendJoystickHat(timestamp, joystick, 0, hat);
|
||||||
|
}
|
||||||
|
|
||||||
// Analog inputs map to a signed Sint16 range of -32768 to 32767 from the device.
|
// Analog inputs map to a signed Sint16 range of -32768 to 32767 from the device.
|
||||||
// Use an axis index because not all gamepads will have the same axis inputs.
|
// Use an axis index because not all gamepads will have the same axis inputs.
|
||||||
Uint8 axis_idx = 0;
|
Uint8 axis_idx = 0;
|
||||||
|
Reference in New Issue
Block a user