Disable lizard mode while steam deck HID device is opened.

This commit is contained in:
Max Maisel 2023-09-07 17:20:24 +02:00 committed by Sam Lantinga
parent a6b9d987e9
commit 0dbe9022fc
3 changed files with 97 additions and 0 deletions

View file

@ -47,8 +47,73 @@ typedef struct
Uint32 update_rate_us; Uint32 update_rate_us;
Uint32 sensor_timestamp_us; Uint32 sensor_timestamp_us;
Uint64 last_button_state; Uint64 last_button_state;
Uint8 watchdog_counter;
} SDL_DriverSteamDeck_Context; } 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) static void HIDAPI_DriverSteamDeck_RegisterHints(SDL_HintCallback callback, void *userdata)
@ -106,6 +171,9 @@ static SDL_bool HIDAPI_DriverSteamDeck_InitDevice(SDL_HIDAPI_Device *device)
if (size == 0) if (size == 0)
return SDL_FALSE; return SDL_FALSE;
if (!DisableDeckLizardMode(device->dev))
return SDL_FALSE;
HIDAPI_SetDeviceName(device, "Steam Deck"); HIDAPI_SetDeviceName(device, "Steam Deck");
return HIDAPI_JoystickConnected(device, NULL); return HIDAPI_JoystickConnected(device, NULL);
@ -138,6 +206,12 @@ static SDL_bool HIDAPI_DriverSteamDeck_UpdateDevice(SDL_HIDAPI_Device *device)
return SDL_FALSE; 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)); SDL_memset(data, 0, sizeof(data));
r = SDL_hid_read(device->dev, data, sizeof(data)); r = SDL_hid_read(device->dev, data, sizeof(data));
if (r == 0) { if (r == 0) {

View file

@ -467,6 +467,15 @@ typedef enum
SETTING_ALL=0xFF SETTING_ALL=0xFF
} ControllerSettings; } 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 typedef enum
{ {
SETTING_DEFAULT, SETTING_DEFAULT,

View file

@ -45,6 +45,19 @@ typedef struct
ControllerAttribute attributes[ ( HID_FEATURE_REPORT_BYTES - sizeof( FeatureReportHeader ) ) / sizeof( ControllerAttribute ) ]; ControllerAttribute attributes[ ( HID_FEATURE_REPORT_BYTES - sizeof( FeatureReportHeader ) ) / sizeof( ControllerAttribute ) ];
} MsgGetAttributes; } 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 // 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 // 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 union
{ {
MsgGetAttributes getAttributes; MsgGetAttributes getAttributes;
MsgWriteDeckRegister wrDeckRegister;
} payload; } payload;
} FeatureReportMsg; } FeatureReportMsg;