Skip to content

Commit e8b5d90

Browse files
SInput: ABXY Style Application and Code Cleanup (#13624)
ABXY Face Style Application - The abxy face style extraction now applies to any SInput device. - The use-case here is that gamepads that allow for changing styles can dynamically adjust the button labels firmware-side to have the physical location better represent the actual button being pressed. SInput Sub-Type Clarification - The code has been updated to better reflect the intention behind the sub-type field of the GUID byte 15. - Any SInput device may utilize the Sub-Type field to indicate variants of the same device (Same device that has rear paddles or additional physical features but is otherwise identical, etc.). "Firebird" Company Name Clarification - "Bonjiri" was a wrong translation. Got clarification from the company and official PID registration for the official English spelling (See raspberrypi/usb-pid@0c5234c). - Fixed this spelling for all references (official mapping strings still pending and this will return NULL until this is provided). Code Notes - Various notes have been updated to have more clear indications. - I have moved the face-type and sub-type debug messages to be paired with the extraction for easier location. - I've removed an incorrect note left-over from a previous commit regarding command response information.
1 parent 51ce3f8 commit e8b5d90

File tree

4 files changed

+55
-46
lines changed

4 files changed

+55
-46
lines changed

src/joystick/SDL_gamepad.c

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -800,50 +800,53 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
800800
SDL_strlcat(mapping_string, "a:b1,b:b0,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", sizeof(mapping_string));
801801
} else if (SDL_IsJoystickSInputController(vendor, product)) {
802802
Uint8 face_style = (guid.data[15] & 0xE0) >> 5;
803-
Uint8 sinput_id = guid.data[15] & 0x1F;
803+
Uint8 sub_type = guid.data[15] & 0x1F;
804804

805-
switch (product) {
806-
case USB_PRODUCT_HANDHELDLEGEND_PROGCC:
807-
// ProGCC Mapping
808-
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));
805+
// Apply face style according to gamepad response
806+
switch (face_style) {
807+
default:
808+
SDL_strlcat(mapping_string, "face:abxy,", sizeof(mapping_string));
809809
break;
810-
811-
case USB_PRODUCT_HANDHELDLEGEND_GCULTIMATE:
812-
// GC Ultimate Map
813-
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));
810+
case 2:
811+
SDL_strlcat(mapping_string, "face:axby,", sizeof(mapping_string));
812+
break;
813+
case 3:
814+
SDL_strlcat(mapping_string, "face:bayx,", sizeof(mapping_string));
814815
break;
816+
case 4:
817+
SDL_strlcat(mapping_string, "face:sony,", sizeof(mapping_string));
818+
break;
819+
}
815820

816-
case USB_PRODUCT_HANDHELDLEGEND_SINPUT_GENERIC:
817-
// Apply mapping profile for type
818-
switch (sinput_id) {
821+
switch (product) {
822+
case USB_PRODUCT_HANDHELDLEGEND_PROGCC:
823+
switch (sub_type) {
819824
default:
820-
case 0:
821-
// Default Fully Exposed Mapping
822-
SDL_strlcat(mapping_string, "leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,b:b0,a:b1,y:b2,x:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b4,rightstick:b5,leftshoulder:b6,rightshoulder:b7,paddle1:b10,paddle2:b11,start:b12,back:b13,guide:b14,misc1:b15,paddle3:b16,paddle4:b17,touchpad:b18,misc2:b19,misc3:b20,misc4:b21,misc5:b22,misc6:b23", sizeof(mapping_string));
825+
// ProGCC Primary Mapping
826+
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));
823827
break;
824828
}
825-
826-
// Apply face style
827-
switch (face_style) {
829+
break;
830+
case USB_PRODUCT_HANDHELDLEGEND_GCULTIMATE:
831+
switch (sub_type) {
828832
default:
829-
case 1:
830-
SDL_strlcat(mapping_string, "face:abxy,", sizeof(mapping_string));
831-
break;
832-
case 2:
833-
SDL_strlcat(mapping_string, "face:axby,", sizeof(mapping_string));
834-
break;
835-
case 3:
836-
SDL_strlcat(mapping_string, "face:bayx,", sizeof(mapping_string));
833+
// GC Ultimate Primary Map
834+
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));
837835
break;
838-
case 4:
839-
SDL_strlcat(mapping_string, "face:sony,", sizeof(mapping_string));
836+
}
837+
break;
838+
case USB_PRODUCT_HANDHELDLEGEND_SINPUT_GENERIC:
839+
switch (sub_type) {
840+
default:
841+
// Default Fully Exposed Mapping (Development Purposes)
842+
SDL_strlcat(mapping_string, "leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,b:b0,a:b1,y:b2,x:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b4,rightstick:b5,leftshoulder:b6,rightshoulder:b7,paddle1:b10,paddle2:b11,start:b12,back:b13,guide:b14,misc1:b15,paddle3:b16,paddle4:b17,touchpad:b18,misc2:b19,misc3:b20,misc4:b21,misc5:b22,misc6:b23", sizeof(mapping_string));
840843
break;
841844
}
842845
break;
843-
846+
847+
case USB_PRODUCT_BONZIRICHANNEL_FIREBIRD:
844848
default:
845-
case USB_PRODUCT_BONJIRICHANNEL_FIREBIRD:
846-
// Unmapped devices
849+
// Unmapped device
847850
return NULL;
848851
}
849852
} else {

src/joystick/SDL_joystick.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3212,7 +3212,7 @@ bool SDL_IsJoystickSInputController(Uint16 vendor_id, Uint16 product_id)
32123212
if (product_id == USB_PRODUCT_HANDHELDLEGEND_SINPUT_GENERIC ||
32133213
product_id == USB_PRODUCT_HANDHELDLEGEND_PROGCC ||
32143214
product_id == USB_PRODUCT_HANDHELDLEGEND_GCULTIMATE ||
3215-
product_id == USB_PRODUCT_BONJIRICHANNEL_FIREBIRD) {
3215+
product_id == USB_PRODUCT_BONZIRICHANNEL_FIREBIRD) {
32163216
return true;
32173217
}
32183218
}

src/joystick/hidapi/SDL_hidapi_sinput.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@
8686
#define SINPUT_REPORT_IDX_TOUCH2_Y 43
8787
#define SINPUT_REPORT_IDX_TOUCH2_P 45
8888

89-
#define SINPUT_BUTTON_IDX_SOUTH 0
90-
#define SINPUT_BUTTON_IDX_EAST 1
91-
#define SINPUT_BUTTON_IDX_WEST 2
92-
#define SINPUT_BUTTON_IDX_NORTH 3
89+
#define SINPUT_BUTTON_IDX_EAST 0
90+
#define SINPUT_BUTTON_IDX_SOUTH 1
91+
#define SINPUT_BUTTON_IDX_NORTH 2
92+
#define SINPUT_BUTTON_IDX_WEST 3
9393
#define SINPUT_BUTTON_IDX_DPAD_UP 4
9494
#define SINPUT_BUTTON_IDX_DPAD_DOWN 5
9595
#define SINPUT_BUTTON_IDX_DPAD_LEFT 6
@@ -256,6 +256,8 @@ static void ProcessSDLFeaturesResponse(SDL_HIDAPI_Device *device, Uint8 *data)
256256

257257
ctx->is_handheld = (data[3] & 0x04) != 0;
258258

259+
// The gamepad type represents a style of gamepad that most closely
260+
// resembles the gamepad in question (Button style, button layout)
259261
SDL_GamepadType type = SDL_GAMEPAD_TYPE_UNKNOWN;
260262
type = (SDL_GamepadType)SDL_clamp(data[4], SDL_GAMEPAD_TYPE_UNKNOWN, SDL_GAMEPAD_TYPE_COUNT);
261263
device->type = type;
@@ -266,20 +268,20 @@ static void ProcessSDLFeaturesResponse(SDL_HIDAPI_Device *device, Uint8 *data)
266268

267269
ctx->sub_type = (data[5] & 0x1F);
268270

271+
#if defined(DEBUG_SINPUT_INIT)
272+
SDL_Log("SInput Face Style: %d", (data[5] & 0xE0) >> 5);
273+
SDL_Log("SInput Sub-type: %d", (data[5] & 0x1F));
274+
#endif
275+
269276
ctx->polling_rate_ms = data[6];
270277

271278
ctx->accelRange = EXTRACTUINT16(data, 8);
272279
ctx->gyroRange = EXTRACTUINT16(data, 10);
273280

274-
if ((device->product_id == USB_PRODUCT_HANDHELDLEGEND_SINPUT_GENERIC) && (device->vendor_id == USB_VENDOR_RASPBERRYPI)) {
275-
276-
#if defined(DEBUG_SINPUT_INIT)
277-
SDL_Log("SInput Face Style: %d", (data[5] & 0xE0) >> 5);
278-
SDL_Log("SInput Sub-type: %d", (data[5] & 0x1F));
279-
#endif
280281

282+
if ((device->product_id == USB_PRODUCT_HANDHELDLEGEND_SINPUT_GENERIC) && (device->vendor_id == USB_VENDOR_RASPBERRYPI)) {
281283
switch (ctx->sub_type) {
282-
// Default generic device, exposes all buttons
284+
// SInput generic device, exposes all buttons
283285
default:
284286
case 0:
285287
ctx->usage_masks[0] = 0xFF;
@@ -294,7 +296,7 @@ static void ProcessSDLFeaturesResponse(SDL_HIDAPI_Device *device, Uint8 *data)
294296
ctx->usage_masks[0] = data[12];
295297

296298
// Stick Left, Stick Right, L Shoulder, R Shoulder,
297-
// L Trigger, R Trigger, L Paddle 1, R Paddle 1
299+
// L Digital Trigger, R Digital Trigger, L Paddle 1, R Paddle 1
298300
ctx->usage_masks[1] = data[13];
299301

300302
// Start, Back, Guide, Capture, L Paddle 2, R Paddle 2, Touchpad L, Touchpad R
@@ -336,6 +338,7 @@ static void ProcessSDLFeaturesResponse(SDL_HIDAPI_Device *device, Uint8 *data)
336338
char serial[18];
337339
(void)SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
338340
data[18], data[19], data[20], data[21], data[22], data[23]);
341+
339342
#if defined(DEBUG_SINPUT_INIT)
340343
SDL_Log("Serial num: %s", serial);
341344
#endif
@@ -464,6 +467,10 @@ static bool HIDAPI_DriverSInput_InitDevice(SDL_HIDAPI_Device *device)
464467
case USB_PRODUCT_HANDHELDLEGEND_PROGCC:
465468
HIDAPI_SetDeviceName(device, "HHL ProGCC");
466469
break;
470+
case USB_PRODUCT_BONZIRICHANNEL_FIREBIRD:
471+
HIDAPI_SetDeviceName(device, "Bonziri Firebird");
472+
break;
473+
case USB_PRODUCT_HANDHELDLEGEND_SINPUT_GENERIC:
467474
default:
468475
// Use the USB product name
469476
break;
@@ -898,7 +905,6 @@ static bool HIDAPI_DriverSInput_UpdateDevice(SDL_HIDAPI_Device *device)
898905
continue;
899906
}
900907

901-
// Handle command response information
902908
if (data[0] == SINPUT_DEVICE_REPORT_ID_JOYSTICK_INPUT) {
903909
HIDAPI_DriverSInput_HandleStatePacket(joystick, ctx, data, size);
904910
}

src/joystick/usb_ids.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@
165165
#define USB_PRODUCT_HANDHELDLEGEND_SINPUT_GENERIC 0x10c6
166166
#define USB_PRODUCT_HANDHELDLEGEND_PROGCC 0x10df
167167
#define USB_PRODUCT_HANDHELDLEGEND_GCULTIMATE 0x10dd
168-
#define USB_PRODUCT_BONJIRICHANNEL_FIREBIRD 0x10e0
168+
#define USB_PRODUCT_BONZIRICHANNEL_FIREBIRD 0x10e0
169169

170170
// USB usage pages
171171
#define USB_USAGEPAGE_GENERIC_DESKTOP 0x0001

0 commit comments

Comments
 (0)