123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 |
- /*
- Simple DirectMedia Layer
- Copyright (C) 2023 Max Maisel <[email protected]>
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- */
- #include "SDL_internal.h"
- #ifdef SDL_JOYSTICK_HIDAPI
- #include "../SDL_sysjoystick.h"
- #include "SDL_hidapijoystick_c.h"
- #ifdef SDL_JOYSTICK_HIDAPI_STEAMDECK
- /*****************************************************************************************************/
- #include "steam/controller_constants.h"
- #include "steam/controller_structs.h"
- enum
- {
- SDL_GAMEPAD_BUTTON_STEAM_DECK_QAM = 11,
- SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE1,
- SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE1,
- SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE2,
- SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2,
- SDL_GAMEPAD_NUM_STEAM_DECK_BUTTONS,
- };
- typedef enum
- {
- STEAMDECK_LBUTTON_R2 = 0x00000001,
- STEAMDECK_LBUTTON_L2 = 0x00000002,
- STEAMDECK_LBUTTON_R = 0x00000004,
- STEAMDECK_LBUTTON_L = 0x00000008,
- STEAMDECK_LBUTTON_Y = 0x00000010,
- STEAMDECK_LBUTTON_B = 0x00000020,
- STEAMDECK_LBUTTON_X = 0x00000040,
- STEAMDECK_LBUTTON_A = 0x00000080,
- STEAMDECK_LBUTTON_DPAD_UP = 0x00000100,
- STEAMDECK_LBUTTON_DPAD_RIGHT = 0x00000200,
- STEAMDECK_LBUTTON_DPAD_LEFT = 0x00000400,
- STEAMDECK_LBUTTON_DPAD_DOWN = 0x00000800,
- STEAMDECK_LBUTTON_VIEW = 0x00001000,
- STEAMDECK_LBUTTON_STEAM = 0x00002000,
- STEAMDECK_LBUTTON_MENU = 0x00004000,
- STEAMDECK_LBUTTON_L5 = 0x00008000,
- STEAMDECK_LBUTTON_R5 = 0x00010000,
- STEAMDECK_LBUTTON_LEFT_PAD = 0x00020000,
- STEAMDECK_LBUTTON_RIGHT_PAD = 0x00040000,
- STEAMDECK_LBUTTON_L3 = 0x00400000,
- STEAMDECK_LBUTTON_R3 = 0x04000000,
- STEAMDECK_HBUTTON_L4 = 0x00000200,
- STEAMDECK_HBUTTON_R4 = 0x00000400,
- STEAMDECK_HBUTTON_QAM = 0x00040000,
- } SteamDeckButtons;
- 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(ControllerSetting);
- msg->payload.setSettingsValues.settings[0].settingNum = SETTING_SMOOTH_ABSOLUTE_MOUSE;
- msg->payload.setSettingsValues.settings[0].settingValue = 0;
- msg->payload.setSettingsValues.settings[1].settingNum = SETTING_LEFT_TRACKPAD_MODE;
- msg->payload.setSettingsValues.settings[1].settingValue = TRACKPAD_NONE;
- msg->payload.setSettingsValues.settings[2].settingNum = SETTING_RIGHT_TRACKPAD_MODE; // disable mouse
- msg->payload.setSettingsValues.settings[2].settingValue = TRACKPAD_NONE;
- msg->payload.setSettingsValues.settings[3].settingNum = SETTING_LEFT_TRACKPAD_CLICK_PRESSURE; // disable clicky pad
- msg->payload.setSettingsValues.settings[3].settingValue = 0xFFFF;
- msg->payload.setSettingsValues.settings[4].settingNum = SETTING_RIGHT_TRACKPAD_CLICK_PRESSURE; // disable clicky pad
- msg->payload.setSettingsValues.settings[4].settingValue = 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(ControllerSetting);
- msg->payload.setSettingsValues.settings[0].settingNum = SETTING_RIGHT_TRACKPAD_MODE;
- msg->payload.setSettingsValues.settings[0].settingValue = TRACKPAD_NONE;
- 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_HandleState(SDL_HIDAPI_Device *device,
- SDL_Joystick *joystick,
- ValveInReport_t *pInReport)
- {
- float values[3];
- SDL_DriverSteamDeck_Context *ctx = (SDL_DriverSteamDeck_Context *)device->context;
- Uint64 timestamp = SDL_GetTicksNS();
- if (pInReport->payload.deckState.ulButtons != ctx->last_button_state) {
- Uint8 hat = 0;
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH,
- (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_A) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST,
- (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_B) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST,
- (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_X) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH,
- (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_Y) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER,
- (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER,
- (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK,
- (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_VIEW) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START,
- (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_MENU) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE,
- (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_STEAM) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_QAM,
- (pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_QAM) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK,
- (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L3) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK,
- (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R3) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE1,
- (pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_R4) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE1,
- (pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_L4) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE2,
- (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R5) ? SDL_PRESSED : SDL_RELEASED);
- SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2,
- (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L5) ? SDL_PRESSED : SDL_RELEASED);
- if (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_UP) {
- hat |= SDL_HAT_UP;
- }
- if (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_DOWN) {
- hat |= SDL_HAT_DOWN;
- }
- if (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_LEFT) {
- hat |= SDL_HAT_LEFT;
- }
- if (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_RIGHT) {
- hat |= SDL_HAT_RIGHT;
- }
- SDL_SendJoystickHat(timestamp, joystick, 0, hat);
- ctx->last_button_state = pInReport->payload.deckState.ulButtons;
- }
- SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER,
- (int)pInReport->payload.deckState.sTriggerRawL * 2 - 32768);
- SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER,
- (int)pInReport->payload.deckState.sTriggerRawR * 2 - 32768);
- SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX,
- pInReport->payload.deckState.sLeftStickX);
- SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY,
- -pInReport->payload.deckState.sLeftStickY);
- SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX,
- pInReport->payload.deckState.sRightStickX);
- SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY,
- -pInReport->payload.deckState.sRightStickY);
- ctx->sensor_timestamp_us += ctx->update_rate_us;
- values[0] = (pInReport->payload.deckState.sGyroX / 32768.0f) * (2000.0f * (SDL_PI_F / 180.0f));
- values[1] = (pInReport->payload.deckState.sGyroZ / 32768.0f) * (2000.0f * (SDL_PI_F / 180.0f));
- values[2] = (-pInReport->payload.deckState.sGyroY / 32768.0f) * (2000.0f * (SDL_PI_F / 180.0f));
- SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO, ctx->sensor_timestamp_us, values, 3);
- values[0] = (pInReport->payload.deckState.sAccelX / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY;
- values[1] = (pInReport->payload.deckState.sAccelZ / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY;
- values[2] = (-pInReport->payload.deckState.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY;
- SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, ctx->sensor_timestamp_us, values, 3);
- }
- /*****************************************************************************************************/
- static void HIDAPI_DriverSteamDeck_RegisterHints(SDL_HintCallback callback, void *userdata)
- {
- SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK, callback, userdata);
- }
- static void HIDAPI_DriverSteamDeck_UnregisterHints(SDL_HintCallback callback, void *userdata)
- {
- SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK, callback, userdata);
- }
- static SDL_bool HIDAPI_DriverSteamDeck_IsEnabled(void)
- {
- return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK,
- SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT));
- }
- static SDL_bool HIDAPI_DriverSteamDeck_IsSupportedDevice(
- SDL_HIDAPI_Device *device,
- const char *name,
- SDL_GamepadType type,
- Uint16 vendor_id,
- Uint16 product_id,
- Uint16 version,
- int interface_number,
- int interface_class,
- int interface_subclass,
- int interface_protocol)
- {
- return SDL_IsJoystickSteamDeck(vendor_id, product_id);
- }
- static SDL_bool HIDAPI_DriverSteamDeck_InitDevice(SDL_HIDAPI_Device *device)
- {
- int size;
- Uint8 data[64];
- SDL_DriverSteamDeck_Context *ctx;
- ctx = (SDL_DriverSteamDeck_Context *)SDL_calloc(1, sizeof(*ctx));
- if (ctx == NULL) {
- return SDL_FALSE;
- }
- // Always 1kHz according to USB descriptor, but actually about 4 ms.
- ctx->update_rate_us = 4000;
- device->context = ctx;
- // Read a report to see if this is the correct endpoint.
- // Mouse, Keyboard and Controller have the same VID/PID but
- // only the controller hidraw device receives hid reports.
- size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 16);
- if (size == 0)
- return SDL_FALSE;
- if (!DisableDeckLizardMode(device->dev))
- return SDL_FALSE;
- HIDAPI_SetDeviceName(device, "Steam Deck");
- return HIDAPI_JoystickConnected(device, NULL);
- }
- static int HIDAPI_DriverSteamDeck_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
- {
- return -1;
- }
- static void HIDAPI_DriverSteamDeck_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
- {
- }
- static SDL_bool HIDAPI_DriverSteamDeck_UpdateDevice(SDL_HIDAPI_Device *device)
- {
- SDL_DriverSteamDeck_Context *ctx = (SDL_DriverSteamDeck_Context *)device->context;
- SDL_Joystick *joystick = NULL;
- int r;
- uint8_t data[64];
- ValveInReport_t *pInReport = (ValveInReport_t *)data;
- if (device->num_joysticks > 0) {
- joystick = SDL_GetJoystickFromID(device->joysticks[0]);
- if (joystick == NULL) {
- return SDL_FALSE;
- }
- } else {
- 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));
- do {
- r = SDL_hid_read(device->dev, data, sizeof(data));
- if (r < 0) {
- /* Failed to read from controller */
- HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
- return SDL_FALSE;
- } else if (r == 64 &&
- pInReport->header.unReportVersion == k_ValveInReportMsgVersion &&
- pInReport->header.ucType == ID_CONTROLLER_DECK_STATE &&
- pInReport->header.ucLength == 64) {
- HIDAPI_DriverSteamDeck_HandleState(device, joystick, pInReport);
- }
- } while (r > 0);
- return SDL_TRUE;
- }
- static SDL_bool HIDAPI_DriverSteamDeck_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
- {
- SDL_DriverSteamDeck_Context *ctx = (SDL_DriverSteamDeck_Context *)device->context;
- float update_rate_in_hz = 1.0f / (float)(ctx->update_rate_us) * 1.0e6f;
- SDL_AssertJoysticksLocked();
- // Initialize the joystick capabilities
- joystick->nbuttons = SDL_GAMEPAD_NUM_STEAM_DECK_BUTTONS;
- joystick->naxes = SDL_GAMEPAD_AXIS_MAX;
- joystick->nhats = 1;
- SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, update_rate_in_hz);
- SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, update_rate_in_hz);
- return SDL_TRUE;
- }
- static int HIDAPI_DriverSteamDeck_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
- {
- int rc;
- Uint8 buffer[HID_FEATURE_REPORT_BYTES + 1] = { 0 };
- FeatureReportMsg *msg = (FeatureReportMsg *)(buffer + 1);
- msg->header.type = ID_TRIGGER_RUMBLE_CMD;
- msg->payload.simpleRumble.unRumbleType = 0;
- msg->payload.simpleRumble.unIntensity = HAPTIC_INTENSITY_SYSTEM;
- msg->payload.simpleRumble.unLeftMotorSpeed = low_frequency_rumble;
- msg->payload.simpleRumble.unRightMotorSpeed = high_frequency_rumble;
- msg->payload.simpleRumble.nLeftGain = 2;
- msg->payload.simpleRumble.nRightGain = 0;
- rc = SDL_hid_send_feature_report(device->dev, buffer, sizeof(buffer));
- if (rc != sizeof(buffer))
- return -1;
- return 0;
- }
- static int HIDAPI_DriverSteamDeck_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
- {
- return SDL_Unsupported();
- }
- static Uint32 HIDAPI_DriverSteamDeck_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
- {
- return SDL_JOYSTICK_CAP_RUMBLE;
- }
- static int HIDAPI_DriverSteamDeck_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
- {
- return SDL_Unsupported();
- }
- static int HIDAPI_DriverSteamDeck_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
- {
- return SDL_Unsupported();
- }
- static int HIDAPI_DriverSteamDeck_SetSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
- {
- // On steam deck, sensors are enabled by default. Nothing to do here.
- return 0;
- }
- static void HIDAPI_DriverSteamDeck_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
- {
- // Lizard mode id automatically re-enabled by watchdog. Nothing to do here.
- }
- static void HIDAPI_DriverSteamDeck_FreeDevice(SDL_HIDAPI_Device *device)
- {
- }
- SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteamDeck = {
- SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK,
- SDL_TRUE,
- HIDAPI_DriverSteamDeck_RegisterHints,
- HIDAPI_DriverSteamDeck_UnregisterHints,
- HIDAPI_DriverSteamDeck_IsEnabled,
- HIDAPI_DriverSteamDeck_IsSupportedDevice,
- HIDAPI_DriverSteamDeck_InitDevice,
- HIDAPI_DriverSteamDeck_GetDevicePlayerIndex,
- HIDAPI_DriverSteamDeck_SetDevicePlayerIndex,
- HIDAPI_DriverSteamDeck_UpdateDevice,
- HIDAPI_DriverSteamDeck_OpenJoystick,
- HIDAPI_DriverSteamDeck_RumbleJoystick,
- HIDAPI_DriverSteamDeck_RumbleJoystickTriggers,
- HIDAPI_DriverSteamDeck_GetJoystickCapabilities,
- HIDAPI_DriverSteamDeck_SetJoystickLED,
- HIDAPI_DriverSteamDeck_SendJoystickEffect,
- HIDAPI_DriverSteamDeck_SetSensorsEnabled,
- HIDAPI_DriverSteamDeck_CloseJoystick,
- HIDAPI_DriverSteamDeck_FreeDevice,
- };
- #endif /* SDL_JOYSTICK_HIDAPI_STEAMDECK */
- #endif /* SDL_JOYSTICK_HIDAPI */
|