Improved reliability of the Steam Controller driver

This commit is contained in:
Sam Lantinga
2024-11-15 15:55:13 -08:00
parent f8468d580d
commit 8657fa8b3b

View File

@@ -28,6 +28,9 @@
#ifdef SDL_JOYSTICK_HIDAPI_STEAM #ifdef SDL_JOYSTICK_HIDAPI_STEAM
// Define this if you want to log all packets from the controller
// #define DEBUG_STEAM_PROTOCOL
#define SDL_HINT_JOYSTICK_HIDAPI_STEAM_PAIRING_ENABLED "SDL_JOYSTICK_HIDAPI_STEAM_PAIRING_ENABLED" #define SDL_HINT_JOYSTICK_HIDAPI_STEAM_PAIRING_ENABLED "SDL_JOYSTICK_HIDAPI_STEAM_PAIRING_ENABLED"
#if defined(SDL_PLATFORM_ANDROID) || defined(SDL_PLATFORM_IOS) || defined(SDL_PLATFORM_TVOS) #if defined(SDL_PLATFORM_ANDROID) || defined(SDL_PLATFORM_IOS) || defined(SDL_PLATFORM_TVOS)
@@ -210,11 +213,7 @@ static uint8_t GetSegmentHeader(int nSegmentNumber, bool bLastPacket)
static void hexdump(const uint8_t *ptr, int len) static void hexdump(const uint8_t *ptr, int len)
{ {
int i; HIDAPI_DumpPacket("Data", ptr, len);
for (i = 0; i < len; ++i) {
printf("%02x ", ptr[i]);
}
printf("\n");
} }
static void ResetSteamControllerPacketAssembler(SteamControllerPacketAssembler *pAssembler) static void ResetSteamControllerPacketAssembler(SteamControllerPacketAssembler *pAssembler)
@@ -418,22 +417,25 @@ static int GetFeatureReport(SDL_HIDAPI_Device *dev, unsigned char uBuffer[65])
static int ReadResponse(SDL_HIDAPI_Device *dev, uint8_t uBuffer[65], int nExpectedResponse) static int ReadResponse(SDL_HIDAPI_Device *dev, uint8_t uBuffer[65], int nExpectedResponse)
{ {
int nRet = GetFeatureReport(dev, uBuffer); for (int nRetries = 0; nRetries < 10; nRetries++) {
int nRet = GetFeatureReport(dev, uBuffer);
DPRINTF("ReadResponse( %p %p %d )\n", dev, uBuffer, nExpectedResponse); DPRINTF("ReadResponse( %p %p 0x%x )\n", dev, uBuffer, nExpectedResponse);
if (nRet < 0) {
continue;
}
DPRINTF("ReadResponse got %d bytes of data: ", nRet);
HEXDUMP(uBuffer, nRet);
if (uBuffer[1] != nExpectedResponse) {
continue;
}
if (nRet < 0) {
return nRet; return nRet;
} }
return -1;
DPRINTF("ReadResponse got %d bytes of data: ", nRet);
HEXDUMP(uBuffer, nRet);
if (uBuffer[1] != nExpectedResponse) {
return -1;
}
return nRet;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -1223,15 +1225,23 @@ static bool HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
const Uint8 *pPacket; const Uint8 *pPacket;
r = ReadSteamController(device->dev, data, sizeof(data)); r = ReadSteamController(device->dev, data, sizeof(data));
if (r == 0) { if (r <= 0) {
if (r < 0) {
// Failed to read from controller
if (ctx->connected) {
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
ctx->connected = false;
}
return false;
}
break; break;
} }
nPacketLength = 0; #ifdef DEBUG_STEAM_PROTOCOL
if (r > 0) { HIDAPI_DumpPacket("Steam Controller packet: size = %d", data, r);
nPacketLength = WriteSegmentToSteamControllerPacketAssembler(&ctx->m_assembler, data, r); #endif
}
nPacketLength = WriteSegmentToSteamControllerPacketAssembler(&ctx->m_assembler, data, r);
pPacket = ctx->m_assembler.uBuffer; pPacket = ctx->m_assembler.uBuffer;
if (nPacketLength > 0 && UpdateSteamControllerState(pPacket, nPacketLength, &ctx->m_state)) { if (nPacketLength > 0 && UpdateSteamControllerState(pPacket, nPacketLength, &ctx->m_state)) {
@@ -1321,11 +1331,6 @@ 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 (ctx->connected && D0G_IS_WIRELESS_DISCONNECT(pPacket, nPacketLength)) {
// Controller has disconnected from the wireless dongle
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
joystick = NULL;
ctx->connected = false;
} else if (!ctx->connected && D0G_IS_WIRELESS_CONNECT(pPacket, nPacketLength)) { } else if (!ctx->connected && D0G_IS_WIRELESS_CONNECT(pPacket, nPacketLength)) {
// Controller has connected to the wireless dongle // Controller has connected to the wireless dongle
if (!HIDAPI_JoystickConnected(device, NULL)) { if (!HIDAPI_JoystickConnected(device, NULL)) {
@@ -1337,14 +1342,11 @@ static bool HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
joystick = SDL_GetJoystickFromID(device->joysticks[0]); joystick = SDL_GetJoystickFromID(device->joysticks[0]);
ctx->connected = true; ctx->connected = true;
} } else if (ctx->connected && D0G_IS_WIRELESS_DISCONNECT(pPacket, nPacketLength)) {
// Controller has disconnected from the wireless dongle
if (r <= 0) { HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
// Failed to read from controller joystick = NULL;
if (ctx->connected) { ctx->connected = false;
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
}
return false;
} }
} }
return true; return true;