Parcourir la source

Disable lizard mode while steam deck HID device is opened.

Max Maisel il y a 1 an
Parent
commit
67d44c1017

+ 74 - 0
src/joystick/hidapi/SDL_hidapi_steamdeck.c

@@ -46,8 +46,73 @@ typedef struct
     Uint32 update_rate_us;
     Uint32 sensor_timestamp_us;
     Uint64 last_button_state;
+    Uint8 watchdog_counter;
 } SDL_DriverSteamDeck_Context;
 
+static SDL_bool DisableDeckLizardMode(SDL_hid_device *dev)
+{
+    int rc;
+    Uint8 buffer[HID_FEATURE_REPORT_BYTES + 1] = { 0 };
+    FeatureReportMsg *msg = (FeatureReportMsg *)(buffer + 1);
+
+    msg->header.type = ID_CLEAR_DIGITAL_MAPPINGS;
+
+    rc = SDL_hid_send_feature_report(dev, buffer, sizeof(buffer));
+    if (rc != sizeof(buffer))
+        return SDL_FALSE;
+
+    msg->header.type = ID_SET_SETTINGS_VALUES;
+    msg->header.length = 5 * sizeof(WriteDeckRegister);
+    msg->payload.wrDeckRegister.reg[0].addr = SETTING_DECK_RPAD_MARGIN; // disable margin
+    msg->payload.wrDeckRegister.reg[0].val = 0;
+    msg->payload.wrDeckRegister.reg[1].addr = SETTING_DECK_LPAD_MODE; // disable mouse
+    msg->payload.wrDeckRegister.reg[1].val = 7;
+    msg->payload.wrDeckRegister.reg[2].addr = SETTING_DECK_RPAD_MODE; // disable mouse
+    msg->payload.wrDeckRegister.reg[2].val = 7;
+    msg->payload.wrDeckRegister.reg[3].addr = SETTING_DECK_LPAD_CLICK_PRESSURE; // disable clicky pad
+    msg->payload.wrDeckRegister.reg[3].val = 0xFFFF;
+    msg->payload.wrDeckRegister.reg[4].addr = SETTING_DECK_RPAD_CLICK_PRESSURE; // disable clicky pad
+    msg->payload.wrDeckRegister.reg[4].val = 0xFFFF;
+
+    rc = SDL_hid_send_feature_report(dev, buffer, sizeof(buffer));
+    if (rc != sizeof(buffer))
+        return SDL_FALSE;
+
+    // There may be a lingering report read back after changing settings.
+    // Discard it.
+    SDL_hid_get_feature_report(dev, buffer, sizeof(buffer));
+
+    return SDL_TRUE;
+}
+
+static SDL_bool FeedDeckLizardWatchdog(SDL_hid_device *dev)
+{
+    int rc;
+    Uint8 buffer[HID_FEATURE_REPORT_BYTES + 1] = { 0 };
+    FeatureReportMsg *msg = (FeatureReportMsg *)(buffer + 1);
+
+    msg->header.type = ID_CLEAR_DIGITAL_MAPPINGS;
+
+    rc = SDL_hid_send_feature_report(dev, buffer, sizeof(buffer));
+    if (rc != sizeof(buffer))
+        return SDL_FALSE;
+
+    msg->header.type = ID_SET_SETTINGS_VALUES;
+    msg->header.length = 1 * sizeof(WriteDeckRegister);
+    msg->payload.wrDeckRegister.reg[0].addr = SETTING_DECK_RPAD_MODE; // disable mouse
+    msg->payload.wrDeckRegister.reg[0].val = 7;
+
+    rc = SDL_hid_send_feature_report(dev, buffer, sizeof(buffer));
+    if (rc != sizeof(buffer))
+        return SDL_FALSE;
+
+    // There may be a lingering report read back after changing settings.
+    // Discard it.
+    SDL_hid_get_feature_report(dev, buffer, sizeof(buffer));
+
+    return SDL_TRUE;
+}
+
 /*****************************************************************************************************/
 
 static void HIDAPI_DriverSteamDeck_RegisterHints(SDL_HintCallback callback, void *userdata)
@@ -105,6 +170,9 @@ static SDL_bool HIDAPI_DriverSteamDeck_InitDevice(SDL_HIDAPI_Device *device)
     if (size == 0)
         return SDL_FALSE;
 
+    if (!DisableDeckLizardMode(device->dev))
+        return SDL_FALSE;
+
     HIDAPI_SetDeviceName(device, "Steam Deck");
 
     return HIDAPI_JoystickConnected(device, NULL);
@@ -137,6 +205,12 @@ static SDL_bool HIDAPI_DriverSteamDeck_UpdateDevice(SDL_HIDAPI_Device *device)
         return SDL_FALSE;
     }
 
+    if (ctx->watchdog_counter++ > 200) {
+        ctx->watchdog_counter = 0;
+        if (!FeedDeckLizardWatchdog(device->dev))
+            return SDL_FALSE;
+    }
+
     SDL_memset(data, 0, sizeof(data));
     r = SDL_hid_read(device->dev, data, sizeof(data));
     if (r == 0) {

+ 9 - 0
src/joystick/hidapi/steam/controller_constants.h

@@ -467,6 +467,15 @@ typedef enum
 	SETTING_ALL=0xFF
 } ControllerSettings;
 
+typedef enum
+{
+	SETTING_DECK_LPAD_MODE = 0x07,
+	SETTING_DECK_RPAD_MODE = 0x08,
+	SETTING_DECK_RPAD_MARGIN = 0x18,
+	SETTING_DECK_LPAD_CLICK_PRESSURE = 0x34,
+	SETTING_DECK_RPAD_CLICK_PRESSURE = 0x35
+} DeckSettings;
+
 typedef enum
 {
 	SETTING_DEFAULT,

+ 14 - 0
src/joystick/hidapi/steam/controller_structs.h

@@ -45,6 +45,19 @@ typedef struct
 	ControllerAttribute attributes[ ( HID_FEATURE_REPORT_BYTES - sizeof( FeatureReportHeader ) ) / sizeof( ControllerAttribute ) ];
 } MsgGetAttributes;
 
+// 16bit Steam Deck register with address
+typedef struct
+{
+	uint8_t addr;
+	uint16_t val;
+} WriteDeckRegister;
+
+// Generic Steam Deck write register message
+typedef struct
+{
+	WriteDeckRegister reg[ (HID_FEATURE_REPORT_BYTES - sizeof ( FeatureReportHeader ) ) / sizeof (WriteDeckRegister ) ];
+} MsgWriteDeckRegister;
+
 
 // This is the only message struct that application code should use to interact with feature request messages. Any new
 // messages should be added to the union. The structures defined here should correspond to the ones defined in
@@ -56,6 +69,7 @@ typedef struct
 	union
 	{
 		MsgGetAttributes				getAttributes;
+		MsgWriteDeckRegister			wrDeckRegister;
 	} payload;
 
 } FeatureReportMsg;