mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-15 22:35:59 +00:00
hidapi: Add support for the Steam Controller wireless dongle
This commit is contained in:

committed by
Sam Lantinga

parent
1a311bc638
commit
68c2cf84f6
@@ -136,6 +136,8 @@ typedef struct SteamControllerStateInternal_t
|
|||||||
#define D0G_WIRELESS_NEWLYPAIRED 3
|
#define D0G_WIRELESS_NEWLYPAIRED 3
|
||||||
|
|
||||||
#define D0G_IS_WIRELESS_DISCONNECT(data, len) (D0G_IS_VALID_WIRELESS_EVENT(data, len) && D0G_GET_WIRELESS_EVENT_TYPE(data) == D0G_WIRELESS_DISCONNECTED)
|
#define D0G_IS_WIRELESS_DISCONNECT(data, len) (D0G_IS_VALID_WIRELESS_EVENT(data, len) && D0G_GET_WIRELESS_EVENT_TYPE(data) == D0G_WIRELESS_DISCONNECTED)
|
||||||
|
#define D0G_IS_WIRELESS_CONNECT(data, len) (D0G_IS_VALID_WIRELESS_EVENT(data, len) && D0G_GET_WIRELESS_EVENT_TYPE(data) != D0G_WIRELESS_DISCONNECTED)
|
||||||
|
|
||||||
|
|
||||||
#define MAX_REPORT_SEGMENT_PAYLOAD_SIZE 18
|
#define MAX_REPORT_SEGMENT_PAYLOAD_SIZE 18
|
||||||
/*
|
/*
|
||||||
@@ -317,7 +319,14 @@ static int SetFeatureReport(SDL_HIDAPI_Device *dev, unsigned char uBuffer[65], i
|
|||||||
nRet = SDL_hid_send_feature_report(dev->dev, uPacketBuffer, sizeof(uPacketBuffer));
|
nRet = SDL_hid_send_feature_report(dev->dev, uPacketBuffer, sizeof(uPacketBuffer));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nRet = SDL_hid_send_feature_report(dev->dev, uBuffer, 65);
|
for (int nRetries = 0; nRetries < RADIO_WORKAROUND_SLEEP_ATTEMPTS; nRetries++) {
|
||||||
|
nRet = SDL_hid_send_feature_report(dev->dev, uBuffer, 65);
|
||||||
|
if (nRet >= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_DelayNS(RADIO_WORKAROUND_SLEEP_DURATION_US * 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF("SetFeatureReport() ret = %d\n", nRet);
|
DPRINTF("SetFeatureReport() ret = %d\n", nRet);
|
||||||
@@ -380,7 +389,15 @@ static int GetFeatureReport(SDL_HIDAPI_Device *dev, unsigned char uBuffer[65])
|
|||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
SDL_memset(uBuffer, 0, 65);
|
SDL_memset(uBuffer, 0, 65);
|
||||||
nRet = SDL_hid_get_feature_report(dev->dev, uBuffer, 65);
|
|
||||||
|
for (int nRetries = 0; nRetries < RADIO_WORKAROUND_SLEEP_ATTEMPTS; nRetries++) {
|
||||||
|
nRet = SDL_hid_get_feature_report(dev->dev, uBuffer, 65);
|
||||||
|
if (nRet >= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_DelayNS(RADIO_WORKAROUND_SLEEP_DURATION_US * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
DPRINTF("GetFeatureReport USB ret=%d\n", nRet);
|
DPRINTF("GetFeatureReport USB ret=%d\n", nRet);
|
||||||
HEXDUMP(uBuffer, nRet);
|
HEXDUMP(uBuffer, nRet);
|
||||||
@@ -992,7 +1009,24 @@ static bool HIDAPI_DriverSteam_InitDevice(SDL_HIDAPI_Device *device)
|
|||||||
|
|
||||||
HIDAPI_SetDeviceName(device, "Steam Controller");
|
HIDAPI_SetDeviceName(device, "Steam Controller");
|
||||||
|
|
||||||
return HIDAPI_JoystickConnected(device, NULL);
|
// If this is a wireless dongle, request a wireless state update
|
||||||
|
if (device->product_id == USB_PRODUCT_VALVE_STEAM_CONTROLLER_DONGLE) {
|
||||||
|
unsigned char buf[65];
|
||||||
|
int res;
|
||||||
|
|
||||||
|
buf[0] = 0;
|
||||||
|
buf[1] = ID_DONGLE_GET_WIRELESS_STATE;
|
||||||
|
res = SetFeatureReport(device, buf, 2);
|
||||||
|
if (res < 0) {
|
||||||
|
return SDL_SetError("Failed to send ID_DONGLE_GET_WIRELESS_STATE request");
|
||||||
|
}
|
||||||
|
|
||||||
|
// We will enumerate any attached controllers in UpdateDevices()
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// Wired and BLE controllers are always connected if HIDAPI can see them
|
||||||
|
return HIDAPI_JoystickConnected(device, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int HIDAPI_DriverSteam_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
|
static int HIDAPI_DriverSteam_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
|
||||||
@@ -1095,8 +1129,6 @@ static bool HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||||||
|
|
||||||
if (device->num_joysticks > 0) {
|
if (device->num_joysticks > 0) {
|
||||||
joystick = SDL_GetJoystickFromID(device->joysticks[0]);
|
joystick = SDL_GetJoystickFromID(device->joysticks[0]);
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -1109,10 +1141,6 @@ static bool HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!joystick) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
nPacketLength = 0;
|
nPacketLength = 0;
|
||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
nPacketLength = WriteSegmentToSteamControllerPacketAssembler(&ctx->m_assembler, data, r);
|
nPacketLength = WriteSegmentToSteamControllerPacketAssembler(&ctx->m_assembler, data, r);
|
||||||
@@ -1123,6 +1151,10 @@ static bool HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||||||
if (nPacketLength > 0 && UpdateSteamControllerState(pPacket, nPacketLength, &ctx->m_state)) {
|
if (nPacketLength > 0 && UpdateSteamControllerState(pPacket, nPacketLength, &ctx->m_state)) {
|
||||||
Uint64 timestamp = SDL_GetTicksNS();
|
Uint64 timestamp = SDL_GetTicksNS();
|
||||||
|
|
||||||
|
if (!joystick) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->m_state.ulButtons != ctx->m_last_state.ulButtons) {
|
if (ctx->m_state.ulButtons != ctx->m_last_state.ulButtons) {
|
||||||
Uint8 hat = 0;
|
Uint8 hat = 0;
|
||||||
|
|
||||||
@@ -1203,11 +1235,24 @@ static bool HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx->m_last_state = ctx->m_state;
|
ctx->m_last_state = ctx->m_state;
|
||||||
|
} else if (joystick && D0G_IS_WIRELESS_DISCONNECT(pPacket, nPacketLength)) {
|
||||||
|
// Controller has disconnected from the wireless dongle
|
||||||
|
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
|
||||||
|
joystick = NULL;
|
||||||
|
} else if (!joystick && D0G_IS_WIRELESS_CONNECT(pPacket, nPacketLength)) {
|
||||||
|
// Controller has connected to the wireless dongle
|
||||||
|
if (!HIDAPI_JoystickConnected(device, NULL)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
joystick = SDL_GetJoystickFromID(device->joysticks[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r <= 0) {
|
if (r <= 0) {
|
||||||
// Failed to read from controller
|
// Failed to read from controller
|
||||||
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
|
if (joystick) {
|
||||||
|
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -125,6 +125,7 @@
|
|||||||
#define USB_PRODUCT_THRUSTMASTER_ESWAPX_PRO 0xd012
|
#define USB_PRODUCT_THRUSTMASTER_ESWAPX_PRO 0xd012
|
||||||
#define USB_PRODUCT_TURTLE_BEACH_SERIES_X_REACT_R 0x7013
|
#define USB_PRODUCT_TURTLE_BEACH_SERIES_X_REACT_R 0x7013
|
||||||
#define USB_PRODUCT_TURTLE_BEACH_SERIES_X_RECON 0x7009
|
#define USB_PRODUCT_TURTLE_BEACH_SERIES_X_RECON 0x7009
|
||||||
|
#define USB_PRODUCT_VALVE_STEAM_CONTROLLER_DONGLE 0x1142
|
||||||
#define USB_PRODUCT_VICTRIX_FS_PRO 0x0203
|
#define USB_PRODUCT_VICTRIX_FS_PRO 0x0203
|
||||||
#define USB_PRODUCT_VICTRIX_FS_PRO_V2 0x0207
|
#define USB_PRODUCT_VICTRIX_FS_PRO_V2 0x0207
|
||||||
#define USB_PRODUCT_XBOX360_XUSB_CONTROLLER 0x02a1 // XUSB driver software PID
|
#define USB_PRODUCT_XBOX360_XUSB_CONTROLLER 0x02a1 // XUSB driver software PID
|
||||||
|
Reference in New Issue
Block a user