Skip to content

Commit 062a777

Browse files
committed
Added support for the Steam Virtual Gamepad on macOS Sequoia
(cherry picked from commit d7b1ba1) (cherry picked from commit cfb3db0)
1 parent 1842745 commit 062a777

File tree

6 files changed

+45
-5
lines changed

6 files changed

+45
-5
lines changed

src/joystick/SDL_joystick.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2843,6 +2843,15 @@ SDL_bool SDL_IsJoystickNintendoSwitchJoyConPair(Uint16 vendor_id, Uint16 product
28432843
return vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR;
28442844
}
28452845

2846+
SDL_bool SDL_IsJoystickSteamVirtualGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version)
2847+
{
2848+
#ifdef __MACOSX__
2849+
return (vendor_id == USB_VENDOR_MICROSOFT && product_id == USB_PRODUCT_XBOX360_WIRED_CONTROLLER && version == 0);
2850+
#else
2851+
return (vendor_id == USB_VENDOR_VALVE && product_id == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD);
2852+
#endif
2853+
}
2854+
28462855
SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id)
28472856
{
28482857
EControllerType eType = GuessControllerType(vendor_id, product_id);

src/joystick/SDL_joystick_c.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConRight(Uint16 vendor_id, Uint16
123123
extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConGrip(Uint16 vendor_id, Uint16 product_id);
124124
extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConPair(Uint16 vendor_id, Uint16 product_id);
125125

126+
/* Function to return whether a joystick is a Steam Virtual Gamepad */
127+
extern SDL_bool SDL_IsJoystickSteamVirtualGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version);
128+
126129
/* Function to return whether a joystick is a Steam Controller */
127130
extern SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id);
128131

src/joystick/hidapi/SDL_hidapi_xbox360.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,15 @@ static SDL_bool HIDAPI_DriverXbox360_IsSupportedDevice(SDL_HIDAPI_Device *device
8585
return SDL_FALSE;
8686
}
8787
#if defined(__MACOSX__) && defined(SDL_JOYSTICK_MFI)
88-
/* On macOS you can't write output reports to wired XBox controllers,
89-
so we'll just use the GCController support instead.
90-
*/
91-
return SDL_FALSE;
88+
if (SDL_IsJoystickSteamVirtualGamepad(vendor_id, product_id, version)) {
89+
/* GCController support doesn't work with the Steam Virtual Gamepad */
90+
return SDL_TRUE;
91+
} else {
92+
/* On macOS you can't write output reports to wired XBox controllers,
93+
so we'll just use the GCController support instead.
94+
*/
95+
return SDL_FALSE;
96+
}
9297
#else
9398
return (type == SDL_CONTROLLER_TYPE_XBOX360) ? SDL_TRUE : SDL_FALSE;
9499
#endif
@@ -143,6 +148,13 @@ static SDL_bool HIDAPI_DriverXbox360_InitDevice(SDL_HIDAPI_Device *device)
143148

144149
device->type = SDL_CONTROLLER_TYPE_XBOX360;
145150

151+
if (SDL_IsJoystickSteamVirtualGamepad(device->vendor_id, device->product_id, device->version) &&
152+
device->product_string && SDL_strncmp(device->product_string, "GamePad-", 8) == 0) {
153+
int slot = 0;
154+
SDL_sscanf(device->product_string, "GamePad-%d", &slot);
155+
device->steam_virtual_gamepad_slot = (slot - 1);
156+
}
157+
146158
return HIDAPI_JoystickConnected(device, NULL);
147159
}
148160

@@ -231,7 +243,11 @@ static int HIDAPI_DriverXbox360_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *dev
231243
static void HIDAPI_DriverXbox360_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXbox360_Context *ctx, Uint8 *data, int size)
232244
{
233245
Sint16 axis;
246+
#ifdef __MACOSX__
247+
const SDL_bool invert_y_axes = SDL_FALSE;
248+
#else
234249
const SDL_bool invert_y_axes = SDL_TRUE;
250+
#endif
235251

236252
if (ctx->last_state[2] != data[2]) {
237253
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, (data[2] & 0x01) ? SDL_PRESSED : SDL_RELEASED);

src/joystick/hidapi/SDL_hidapijoystick.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,7 @@ static SDL_HIDAPI_Device *HIDAPI_AddDevice(const struct SDL_hid_device_info *inf
929929
device->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, device->vendor_id, device->product_id, device->version, device->manufacturer_string, device->product_string, 'h', 0);
930930
device->joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER;
931931
device->type = SDL_GetJoystickGameControllerProtocol(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol);
932+
device->steam_virtual_gamepad_slot = -1;
932933

933934
if (num_children > 0) {
934935
int i;
@@ -1380,6 +1381,12 @@ static const char *HIDAPI_JoystickGetDevicePath(int device_index)
13801381

13811382
static int HIDAPI_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index)
13821383
{
1384+
SDL_HIDAPI_Device *device;
1385+
1386+
device = HIDAPI_GetDeviceByIndex(device_index, NULL);
1387+
if (device) {
1388+
return device->steam_virtual_gamepad_slot;
1389+
}
13831390
return -1;
13841391
}
13851392

src/joystick/hidapi/SDL_hidapijoystick_c.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ typedef struct _SDL_HIDAPI_Device
8383
SDL_bool is_bluetooth;
8484
SDL_JoystickType joystick_type;
8585
SDL_GameControllerType type;
86+
int steam_virtual_gamepad_slot;
8687

8788
struct _SDL_HIDAPI_DeviceDriver *driver;
8889
void *context;

src/joystick/iphoneos/SDL_mfijoystick.m

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,10 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
419419
return FALSE;
420420
}
421421
#endif
422+
if (device->is_xbox && SDL_strncmp(name, "GamePad-", 8) == 0) {
423+
/* This is a Steam Virtual Gamepad, which isn't supported by GCController */
424+
return FALSE;
425+
}
422426
CheckControllerSiriRemote(controller, &device->is_siri_remote);
423427

424428
if (device->is_siri_remote && !SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) {
@@ -438,7 +442,7 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
438442
device->has_xbox_share_button = TRUE;
439443
}
440444
}
441-
#endif // ENABLE_PHYSICAL_INPUT_PROFILE
445+
#endif /* ENABLE_PHYSICAL_INPUT_PROFILE */
442446

443447
if (device->is_backbone_one) {
444448
vendor = USB_VENDOR_BACKBONE;

0 commit comments

Comments
 (0)