Skip to content

Commit

Permalink
Added support for the Steam Virtual Gamepad on macOS Sequoia
Browse files Browse the repository at this point in the history
(cherry picked from commit d7b1ba1)
  • Loading branch information
slouken committed Oct 17, 2024
1 parent a976f7f commit cfb3db0
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 5 deletions.
9 changes: 9 additions & 0 deletions src/joystick/SDL_joystick.c
Original file line number Diff line number Diff line change
Expand Up @@ -2843,6 +2843,15 @@ SDL_bool SDL_IsJoystickNintendoSwitchJoyConPair(Uint16 vendor_id, Uint16 product
return vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR;
}

SDL_bool SDL_IsJoystickSteamVirtualGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version)
{
#ifdef __MACOSX__
return (vendor_id == USB_VENDOR_MICROSOFT && product_id == USB_PRODUCT_XBOX360_WIRED_CONTROLLER && version == 0);
#else
return (vendor_id == USB_VENDOR_VALVE && product_id == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD);
#endif
}

SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id)
{
EControllerType eType = GuessControllerType(vendor_id, product_id);
Expand Down
3 changes: 3 additions & 0 deletions src/joystick/SDL_joystick_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConRight(Uint16 vendor_id, Uint16
extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConGrip(Uint16 vendor_id, Uint16 product_id);
extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConPair(Uint16 vendor_id, Uint16 product_id);

/* Function to return whether a joystick is a Steam Virtual Gamepad */
extern SDL_bool SDL_IsJoystickSteamVirtualGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version);

/* Function to return whether a joystick is a Steam Controller */
extern SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id);

Expand Down
24 changes: 20 additions & 4 deletions src/joystick/hidapi/SDL_hidapi_xbox360.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,15 @@ static SDL_bool HIDAPI_DriverXbox360_IsSupportedDevice(SDL_HIDAPI_Device *device
return SDL_FALSE;
}
#if defined(__MACOSX__) && defined(SDL_JOYSTICK_MFI)
/* On macOS you can't write output reports to wired XBox controllers,
so we'll just use the GCController support instead.
*/
return SDL_FALSE;
if (SDL_IsJoystickSteamVirtualGamepad(vendor_id, product_id, version)) {
/* GCController support doesn't work with the Steam Virtual Gamepad */
return SDL_TRUE;
} else {
/* On macOS you can't write output reports to wired XBox controllers,
so we'll just use the GCController support instead.
*/
return SDL_FALSE;
}
#else
return (type == SDL_CONTROLLER_TYPE_XBOX360) ? SDL_TRUE : SDL_FALSE;
#endif
Expand Down Expand Up @@ -143,6 +148,13 @@ static SDL_bool HIDAPI_DriverXbox360_InitDevice(SDL_HIDAPI_Device *device)

device->type = SDL_CONTROLLER_TYPE_XBOX360;

if (SDL_IsJoystickSteamVirtualGamepad(device->vendor_id, device->product_id, device->version) &&
device->product_string && SDL_strncmp(device->product_string, "GamePad-", 8) == 0) {
int slot = 0;
SDL_sscanf(device->product_string, "GamePad-%d", &slot);
device->steam_virtual_gamepad_slot = (slot - 1);
}

return HIDAPI_JoystickConnected(device, NULL);
}

Expand Down Expand Up @@ -231,7 +243,11 @@ static int HIDAPI_DriverXbox360_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *dev
static void HIDAPI_DriverXbox360_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXbox360_Context *ctx, Uint8 *data, int size)
{
Sint16 axis;
#ifdef __MACOSX__
const SDL_bool invert_y_axes = SDL_FALSE;
#else
const SDL_bool invert_y_axes = SDL_TRUE;
#endif

if (ctx->last_state[2] != data[2]) {
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, (data[2] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
Expand Down
7 changes: 7 additions & 0 deletions src/joystick/hidapi/SDL_hidapijoystick.c
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,7 @@ static SDL_HIDAPI_Device *HIDAPI_AddDevice(const struct SDL_hid_device_info *inf
device->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, device->vendor_id, device->product_id, device->version, device->manufacturer_string, device->product_string, 'h', 0);
device->joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER;
device->type = SDL_GetJoystickGameControllerProtocol(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol);
device->steam_virtual_gamepad_slot = -1;

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

static int HIDAPI_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index)
{
SDL_HIDAPI_Device *device;

device = HIDAPI_GetDeviceByIndex(device_index, NULL);
if (device) {
return device->steam_virtual_gamepad_slot;
}
return -1;
}

Expand Down
1 change: 1 addition & 0 deletions src/joystick/hidapi/SDL_hidapijoystick_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ typedef struct _SDL_HIDAPI_Device
SDL_bool is_bluetooth;
SDL_JoystickType joystick_type;
SDL_GameControllerType type;
int steam_virtual_gamepad_slot;

struct _SDL_HIDAPI_DeviceDriver *driver;
void *context;
Expand Down
6 changes: 5 additions & 1 deletion src/joystick/iphoneos/SDL_mfijoystick.m
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
return FALSE;
}
#endif
if (device->is_xbox && SDL_strncmp(name, "GamePad-", 8) == 0) {
/* This is a Steam Virtual Gamepad, which isn't supported by GCController */
return FALSE;
}
CheckControllerSiriRemote(controller, &device->is_siri_remote);

if (device->is_siri_remote && !SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) {
Expand All @@ -438,7 +442,7 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
device->has_xbox_share_button = TRUE;
}
}
#endif // ENABLE_PHYSICAL_INPUT_PROFILE
#endif /* ENABLE_PHYSICAL_INPUT_PROFILE */

if (device->is_backbone_one) {
vendor = USB_VENDOR_BACKBONE;
Expand Down

0 comments on commit cfb3db0

Please sign in to comment.