Skip to content

sinput: Add fully generic capabilities #13565

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 28 additions & 49 deletions src/joystick/SDL_gamepad.c
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention here is to see how SInput is used for some time before dedicating slots to pre-defined types. I think that it's reasonable to start drafting some out and have proposals for these.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need these for my use of the protocol. I could drop the XInput one but that's about it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With all buttons and analog axis exposed, what is missing for your current use case to get things working?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to be able to expose the correct amount of back buttons. I do not need all the buttons, there are enough controllers to do that with.

Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "controller_type.h"
#include "usb_ids.h"
#include "hidapi/SDL_hidapi_nintendo.h"
#include "hidapi/SDL_hidapi_sinput.h"
#include "../events/SDL_events_c.h"


Expand Down Expand Up @@ -57,16 +58,6 @@
static bool SDL_gamepads_initialized;
static SDL_Gamepad *SDL_gamepads SDL_GUARDED_BY(SDL_joystick_lock) = NULL;

// The face button style of a gamepad
typedef enum
{
SDL_GAMEPAD_FACE_STYLE_UNKNOWN,
SDL_GAMEPAD_FACE_STYLE_ABXY,
SDL_GAMEPAD_FACE_STYLE_AXBY,
SDL_GAMEPAD_FACE_STYLE_BAYX,
SDL_GAMEPAD_FACE_STYLE_SONY,
} SDL_GamepadFaceStyle;

// our hard coded list of mapping support
typedef enum
{
Expand Down Expand Up @@ -697,10 +688,11 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
char mapping_string[1024];
Uint16 vendor;
Uint16 product;
Uint16 version;

SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string));

SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version, NULL);

if (SDL_IsJoystickWheel(vendor, product)) {
// We don't want to pick up Logitech FFB wheels here
Expand Down Expand Up @@ -799,55 +791,42 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
// This controller has no guide button
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));
} else if (SDL_IsJoystickSInputController(vendor, product)) {
Uint8 face_style = (guid.data[15] & 0xE0) >> 5;
Uint8 sub_type = guid.data[15] & 0x1F;
struct SDL_SInputFeatures features;
HIDAPI_DriverSInput_GetControllerType(vendor, product, version, guid.data[15], &features);

// Apply face style according to gamepad response
switch (face_style) {
// Apply mapping profile for type
switch (features.controller_type) {
case k_eSInputControllerType_HHL_PROGCC:
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;
case k_eSInputControllerType_HHL_GCCULT:
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;
default:
case k_eSInputControllerType_Dynamic:
// Default Fully Exposed Mapping
// TODO...
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));
break;
}

// Apply face style
switch (features.face_style) {
case SDL_GAMEPAD_FACE_STYLE_ABXY:
SDL_strlcat(mapping_string, "face:abxy,", sizeof(mapping_string));
break;
case 2:
case SDL_GAMEPAD_FACE_STYLE_AXBY:
SDL_strlcat(mapping_string, "face:axby,", sizeof(mapping_string));
break;
case 3:
case SDL_GAMEPAD_FACE_STYLE_BAYX:
SDL_strlcat(mapping_string, "face:bayx,", sizeof(mapping_string));
break;
case 4:
case SDL_GAMEPAD_FACE_STYLE_SONY:
SDL_strlcat(mapping_string, "face:sony,", sizeof(mapping_string));
break;
}

switch (product) {
case USB_PRODUCT_HANDHELDLEGEND_PROGCC:
switch (sub_type) {
default:
// ProGCC Primary Mapping
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:
switch (sub_type) {
default:
// GC Ultimate Primary Map
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:
switch (sub_type) {
default:
// Default Fully Exposed Mapping (Development Purposes)
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));
break;
}
break;

case USB_PRODUCT_BONZIRICHANNEL_FIREBIRD:
case SDL_GAMEPAD_FACE_STYLE_UNKNOWN:
default:
// Unmapped device
return NULL;
break;
}
} else {
// All other gamepads have the standard set of 19 buttons and 6 axes
Expand Down
10 changes: 10 additions & 0 deletions src/joystick/SDL_gamepad_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@

#include "SDL_internal.h"

// The face button style of a gamepad
typedef enum
{
SDL_GAMEPAD_FACE_STYLE_UNKNOWN,
SDL_GAMEPAD_FACE_STYLE_ABXY,
SDL_GAMEPAD_FACE_STYLE_AXBY,
SDL_GAMEPAD_FACE_STYLE_BAYX,
SDL_GAMEPAD_FACE_STYLE_SONY,
} SDL_GamepadFaceStyle;

// Useful functions and variables from SDL_gamepad.c

// Initialization and shutdown functions
Expand Down
4 changes: 3 additions & 1 deletion src/joystick/SDL_joystick.c
Original file line number Diff line number Diff line change
Expand Up @@ -3216,7 +3216,9 @@ bool SDL_IsJoystickSInputController(Uint16 vendor_id, Uint16 product_id)
return true;
}
}
return false;

EControllerType eType = GuessControllerType(vendor_id, product_id);
return eType == k_eControllerType_Sinput;
}

bool SDL_IsJoystickFlydigiController(Uint16 vendor_id, Uint16 product_id)
Expand Down
3 changes: 3 additions & 0 deletions src/joystick/controller_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -598,4 +598,7 @@ static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x28de, 0x1201 ), k_eControllerType_SteamControllerV2, NULL }, // Valve wired Steam Controller (HEADCRAB)
{ MAKE_CONTROLLER_ID( 0x28de, 0x1202 ), k_eControllerType_SteamControllerV2, NULL }, // Valve Bluetooth Steam Controller (HEADCRAB)
{ MAKE_CONTROLLER_ID( 0x28de, 0x1205 ), k_eControllerType_SteamControllerNeptune, NULL }, // Valve Steam Deck Builtin Controller

// Sinput controllers
{ MAKE_CONTROLLER_ID( 0x16d0, 0x145b ), k_eControllerType_Sinput, NULL },
};
4 changes: 4 additions & 0 deletions src/joystick/controller_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ EControllerType GuessControllerType( int nVID, int nPID )
{
return k_eControllerType_SteamController;
}
if ( SDL_strncasecmp( pszOverride, "sinput", 5 ) == 0 )
{
return k_eControllerType_Sinput;
}
return k_eControllerType_UnknownNonSteamController;
}

Expand Down
1 change: 1 addition & 0 deletions src/joystick/controller_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ typedef enum
k_eControllerType_XInputSwitchController = 44, // Client-side only, used to mark Nintendo Switch style controllers as using XInput instead of the Nintendo Switch protocol
k_eControllerType_PS5Controller = 45,
k_eControllerType_XInputPS4Controller = 46, // Client-side only, used to mark DualShock 4 style controllers using XInput instead of the DualShock 4 controller protocol
k_eControllerType_Sinput = 47,
k_eControllerType_LastController, // Don't add game controllers below this enumeration - this enumeration can change value

// Keyboards and Mice
Expand Down
Loading
Loading