From 1e1be0b954d5d4cb62da38655f229fe2781ded41 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 26 Sep 2022 23:00:58 -0700
Subject: [PATCH] Updated logic to match between PS4/PS5/Switch controllers
---
src/joystick/hidapi/SDL_hidapi_ps4.c | 7 +-
src/joystick/hidapi/SDL_hidapi_ps5.c | 5 +-
src/joystick/hidapi/SDL_hidapi_switch.c | 98 ++++++++++++-------------
3 files changed, 56 insertions(+), 54 deletions(-)
diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c
index 05ce68ca5af..6b4fee3ab29 100644
--- a/src/joystick/hidapi/SDL_hidapi_ps4.c
+++ b/src/joystick/hidapi/SDL_hidapi_ps4.c
@@ -1016,6 +1016,7 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
Uint8 data[USB_PACKET_LENGTH*2];
int size;
int packet_count = 0;
+ Uint32 now = SDL_GetTicks();
if (device->num_joysticks > 0) {
joystick = SDL_JoystickFromInstanceID(device->joysticks[0]);
@@ -1030,7 +1031,7 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
}
++packet_count;
- ctx->last_packet = SDL_GetTicks();
+ ctx->last_packet = now;
if (!joystick) {
continue;
@@ -1067,7 +1068,7 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
if (device->is_bluetooth) {
if (packet_count == 0) {
/* Check to see if it looks like the device disconnected */
- if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) {
+ if (SDL_TICKS_PASSED(now, ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) {
/* Send an empty output report to tickle the Bluetooth stack */
HIDAPI_DriverPS4_TickleBluetooth(device);
}
@@ -1084,7 +1085,7 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
if (packet_count == 0) {
if (device->num_joysticks > 0) {
/* Check to see if it looks like the device disconnected */
- if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) {
+ if (SDL_TICKS_PASSED(now, ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) {
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
}
}
diff --git a/src/joystick/hidapi/SDL_hidapi_ps5.c b/src/joystick/hidapi/SDL_hidapi_ps5.c
index 93b59cea1a7..3892764a1df 100644
--- a/src/joystick/hidapi/SDL_hidapi_ps5.c
+++ b/src/joystick/hidapi/SDL_hidapi_ps5.c
@@ -1302,6 +1302,7 @@ HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device)
Uint8 data[USB_PACKET_LENGTH*2];
int size;
int packet_count = 0;
+ Uint32 now = SDL_GetTicks();
if (device->num_joysticks > 0) {
joystick = SDL_JoystickFromInstanceID(device->joysticks[0]);
@@ -1316,7 +1317,7 @@ HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device)
}
++packet_count;
- ctx->last_packet = SDL_GetTicks();
+ ctx->last_packet = now;
if (!joystick) {
continue;
@@ -1361,7 +1362,7 @@ HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device)
if (device->is_bluetooth) {
if (packet_count == 0) {
/* Check to see if it looks like the device disconnected */
- if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) {
+ if (SDL_TICKS_PASSED(now, ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) {
/* Send an empty output report to tickle the Bluetooth stack */
HIDAPI_DriverPS5_TickleBluetooth(device);
}
diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c
index 66feeab45dd..8a7c9f0cb7f 100644
--- a/src/joystick/hidapi/SDL_hidapi_switch.c
+++ b/src/joystick/hidapi/SDL_hidapi_switch.c
@@ -2083,76 +2083,76 @@ HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device)
SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context;
SDL_Joystick *joystick = NULL;
int size;
- Uint32 now;
-
- /* Reconnect the Bluetooth device once the USB device is gone */
- if (device->num_joysticks == 0 &&
- device->is_bluetooth &&
- !HIDAPI_HasConnectedUSBDevice(device->serial)) {
- if (ReadInput(ctx) > 0) {
- HIDAPI_JoystickConnected(device, NULL);
- }
- }
+ int packet_count = 0;
+ Uint32 now = SDL_GetTicks();
if (device->num_joysticks > 0) {
joystick = SDL_JoystickFromInstanceID(device->joysticks[0]);
- } else {
- return SDL_FALSE;
}
- now = SDL_GetTicks();
-
while ((size = ReadInput(ctx)) > 0) {
#ifdef DEBUG_SWITCH_PROTOCOL
HIDAPI_DumpPacket("Nintendo Switch packet: size = %d", ctx->m_rgucReadBuffer, size);
#endif
- if (joystick) {
- if (ctx->m_bInputOnly) {
- HandleInputOnlyControllerState(joystick, ctx, (SwitchInputOnlyControllerStatePacket_t *)&ctx->m_rgucReadBuffer[0]);
- } else {
- switch (ctx->m_rgucReadBuffer[0]) {
- case k_eSwitchInputReportIDs_SimpleControllerState:
- HandleSimpleControllerState(joystick, ctx, (SwitchSimpleStatePacket_t *)&ctx->m_rgucReadBuffer[1]);
- break;
- case k_eSwitchInputReportIDs_FullControllerState:
- HandleFullControllerState(joystick, ctx, (SwitchStatePacket_t *)&ctx->m_rgucReadBuffer[1]);
- break;
- default:
- break;
- }
+ ++packet_count;
+ ctx->m_unLastInput = now;
+
+ if (!joystick) {
+ continue;
+ }
+
+ if (ctx->m_bInputOnly) {
+ HandleInputOnlyControllerState(joystick, ctx, (SwitchInputOnlyControllerStatePacket_t *)&ctx->m_rgucReadBuffer[0]);
+ } else {
+ switch (ctx->m_rgucReadBuffer[0]) {
+ case k_eSwitchInputReportIDs_SimpleControllerState:
+ HandleSimpleControllerState(joystick, ctx, (SwitchSimpleStatePacket_t *)&ctx->m_rgucReadBuffer[1]);
+ break;
+ case k_eSwitchInputReportIDs_FullControllerState:
+ HandleFullControllerState(joystick, ctx, (SwitchStatePacket_t *)&ctx->m_rgucReadBuffer[1]);
+ break;
+ default:
+ break;
}
}
- ctx->m_unLastInput = now;
}
if (joystick) {
- if (!ctx->m_bInputOnly && !device->is_bluetooth &&
- ctx->device->product_id != USB_PRODUCT_NINTENDO_SWITCH_JOYCON_GRIP) {
- const Uint32 INPUT_WAIT_TIMEOUT_MS = 100;
- if (SDL_TICKS_PASSED(now, ctx->m_unLastInput + INPUT_WAIT_TIMEOUT_MS)) {
- /* Steam may have put the controller back into non-reporting mode */
- WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_ForceUSB, NULL, 0, SDL_FALSE);
- }
- } else if (device->is_bluetooth) {
- const Uint32 INPUT_WAIT_TIMEOUT_MS = 3000;
- if (SDL_TICKS_PASSED(now, ctx->m_unLastInput + INPUT_WAIT_TIMEOUT_MS)) {
- /* Bluetooth may have disconnected, try reopening the controller */
- size = -1;
+ if (packet_count == 0) {
+ if (!ctx->m_bInputOnly && !device->is_bluetooth &&
+ ctx->device->product_id != USB_PRODUCT_NINTENDO_SWITCH_JOYCON_GRIP) {
+ const Uint32 INPUT_WAIT_TIMEOUT_MS = 100;
+ if (SDL_TICKS_PASSED(now, ctx->m_unLastInput + INPUT_WAIT_TIMEOUT_MS)) {
+ /* Steam may have put the controller back into non-reporting mode */
+ WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_ForceUSB, NULL, 0, SDL_FALSE);
+ }
+ } else if (device->is_bluetooth) {
+ const Uint32 INPUT_WAIT_TIMEOUT_MS = 3000;
+ if (SDL_TICKS_PASSED(now, ctx->m_unLastInput + INPUT_WAIT_TIMEOUT_MS)) {
+ /* Bluetooth may have disconnected, try reopening the controller */
+ size = -1;
+ }
}
}
- }
- if (ctx->m_bRumblePending || ctx->m_bRumbleZeroPending) {
- HIDAPI_DriverSwitch_SendPendingRumble(ctx);
- } else if (ctx->m_bRumbleActive &&
- SDL_TICKS_PASSED(now, ctx->m_unRumbleSent + RUMBLE_REFRESH_FREQUENCY_MS)) {
+ if (ctx->m_bRumblePending || ctx->m_bRumbleZeroPending) {
+ HIDAPI_DriverSwitch_SendPendingRumble(ctx);
+ } else if (ctx->m_bRumbleActive &&
+ SDL_TICKS_PASSED(now, ctx->m_unRumbleSent + RUMBLE_REFRESH_FREQUENCY_MS)) {
#ifdef DEBUG_RUMBLE
- SDL_Log("Sent continuing rumble, %d ms after previous rumble\n", now - ctx->m_unRumbleSent);
+ SDL_Log("Sent continuing rumble, %d ms after previous rumble\n", now - ctx->m_unRumbleSent);
#endif
- WriteRumble(ctx);
+ WriteRumble(ctx);
+ }
+ }
+
+ /* Reconnect the Bluetooth device once the USB device is gone */
+ if (device->num_joysticks == 0 && device->is_bluetooth && packet_count > 0 &&
+ !HIDAPI_HasConnectedUSBDevice(device->serial)) {
+ HIDAPI_JoystickConnected(device, NULL);
}
- if (size < 0) {
+ if (size < 0 && device->num_joysticks > 0) {
/* Read error, device is disconnected */
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
}