diff --git a/src/joystick/hidapi/SDL_hidapi_steam_triton.c b/src/joystick/hidapi/SDL_hidapi_steam_triton.c index 9339bcb4aa..92cd1e703e 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam_triton.c +++ b/src/joystick/hidapi/SDL_hidapi_steam_triton.c @@ -137,14 +137,10 @@ static bool DisableSteamTritonLizardMode(SDL_hid_device *dev) return true; } -static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device, - SDL_Joystick *joystick, - TritonMTUNoQuat_t *pTritonReport) +// Triton newer state MTUs are identical until touchpads. Parse them using this routine. +// Expects report to be a TritonMTUNoQuat_t, so cast as needed +static void Parse_SteamTriton_HandleGenericState( SDL_DriverSteamTriton_Context* ctx, SDL_Joystick* joystick, Uint64 timestamp, TritonMTUNoQuat_t* pTritonReport ) { - float values[3]; - SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context; - Uint64 timestamp = SDL_GetTicksNS(); - if (pTritonReport->buttons != ctx->last_button_state) { Uint8 hat = 0; @@ -217,13 +213,11 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device, ctx->last_button_state = pTritonReport->buttons; } - // RKRK There're button bits for this if you so choose. - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, (int)pTritonReport->sTriggerLeft * 2 - 32768); SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, (int)pTritonReport->sTriggerRight * 2 - 32768); - - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX, + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX, pTritonReport->sLeftStickX); SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY, -pTritonReport->sLeftStickY); @@ -231,6 +225,45 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device, pTritonReport->sRightStickX); SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, -pTritonReport->sRightStickY); +} + +static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device, + SDL_Joystick *joystick, + TritonMTUNoQuat_t *pTritonReport) +{ + float values[3]; + SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context; + Uint64 timestamp = SDL_GetTicksNS(); + + Parse_SteamTriton_HandleGenericState(ctx, joystick, timestamp, pTritonReport); + + bool left_touch_down = (pTritonReport->buttons & TRITON_LEFT_TOUCHPAD_TOUCH) ? true : false; + bool right_touch_down = (pTritonReport->buttons & TRITON_RIGHT_TOUCHPAD_TOUCH) ? true : false; + + if (left_touch_down || ctx->left_touch_down) { + if (left_touch_down) { + ctx->left_touch_x = pTritonReport->sLeftPadX / 65536.0f + 0.5f; + ctx->left_touch_y = -(float)pTritonReport->sLeftPadY / 65536.0f + 0.5f; + } + SDL_SendJoystickTouchpad(timestamp, joystick, 0, 0, + left_touch_down, + ctx->left_touch_x, + ctx->left_touch_y, + pTritonReport->ucPressureLeft / 32768.0f); + ctx->left_touch_down = left_touch_down; + } + if (right_touch_down || ctx->right_touch_down) { + if (right_touch_down) { + ctx->right_touch_x = pTritonReport->sRightPadX / 65536.0f + 0.5f; + ctx->right_touch_y = -(float)pTritonReport->sRightPadY / 65536.0f + 0.5f; + } + SDL_SendJoystickTouchpad(timestamp, joystick, 1, 0, + right_touch_down, + ctx->right_touch_x, + ctx->right_touch_y, + pTritonReport->ucPressureRight / 32768.0f); + ctx->right_touch_down = right_touch_down; + } if (ctx->report_sensors && pTritonReport->imu.timestamp != ctx->last_sensor_tick) { Uint32 delta_us = (pTritonReport->imu.timestamp - ctx->last_sensor_tick); @@ -249,20 +282,31 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device, ctx->last_sensor_tick = pTritonReport->imu.timestamp; } +} +// New Ibex MTU has IMU data in +static void HIDAPI_DriverSteamTriton_HandleState_Timestamp(SDL_HIDAPI_Device *device, + SDL_Joystick *joystick, + TritonMTUNoQuat32TS_t *pTritonReport) +{ + float values[3]; + SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context; + Uint64 timestamp = SDL_GetTicksNS(); + + Parse_SteamTriton_HandleGenericState(ctx, joystick, timestamp, (TritonMTUNoQuat_t *) pTritonReport); bool left_touch_down = (pTritonReport->buttons & TRITON_LEFT_TOUCHPAD_TOUCH) ? true : false; bool right_touch_down = (pTritonReport->buttons & TRITON_RIGHT_TOUCHPAD_TOUCH) ? true : false; + if (left_touch_down || ctx->left_touch_down) { if (left_touch_down) { ctx->left_touch_x = pTritonReport->sLeftPadX / 65536.0f + 0.5f; ctx->left_touch_y = -(float)pTritonReport->sLeftPadY / 65536.0f + 0.5f; - } SDL_SendJoystickTouchpad(timestamp, joystick, 0, 0, left_touch_down, ctx->left_touch_x, ctx->left_touch_y, - pTritonReport->sPressureLeft / 32768.0f); + pTritonReport->unPressureLeft / 32768.0f); ctx->left_touch_down = left_touch_down; } if (right_touch_down || ctx->right_touch_down) { @@ -274,9 +318,27 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device, right_touch_down, ctx->right_touch_x, ctx->right_touch_y, - pTritonReport->sPressureRight / 32768.0f); + pTritonReport->unPressureRight / 32768.0f); ctx->right_touch_down = right_touch_down; } + + if (ctx->report_sensors && pTritonReport->imu.timestamp != ctx->last_sensor_tick) { + Uint32 delta_us = (pTritonReport->imu.timestamp - ctx->last_sensor_tick); + + ctx->sensor_timestamp_ns += SDL_US_TO_NS(delta_us); + + values[0] = (pTritonReport->imu.sGyroX / 32768.0f) * (2000.0f * (SDL_PI_F / 180.0f)); + values[1] = (pTritonReport->imu.sGyroZ / 32768.0f) * (2000.0f * (SDL_PI_F / 180.0f)); + values[2] = (-pTritonReport->imu.sGyroY / 32768.0f) * (2000.0f * (SDL_PI_F / 180.0f)); + SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO, ctx->sensor_timestamp_ns, values, 3); + + values[0] = (pTritonReport->imu.sAccelX / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + values[1] = (pTritonReport->imu.sAccelZ / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + values[2] = (-pTritonReport->imu.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, ctx->sensor_timestamp_ns, values, 3); + + ctx->last_sensor_tick = pTritonReport->imu.timestamp; + } } static void HIDAPI_DriverSteamTriton_HandleBatteryStatus(SDL_HIDAPI_Device *device, @@ -463,7 +525,19 @@ static bool HIDAPI_DriverSteamTriton_UpdateDevice(SDL_HIDAPI_Device *device) HIDAPI_DriverSteamTriton_HandleState(device, joystick, pTritonReport); } break; - case ID_TRITON_BATTERY_STATUS: + case ID_TRITON_CONTROLLER_STATE_TIMESTAMP: + if (!joystick) { + HIDAPI_DriverSteamTriton_SetControllerConnected(device, true); + if (device->num_joysticks > 0) { + joystick = SDL_GetJoystickFromID(device->joysticks[0]); + } + } + if (joystick && r >= (1 + sizeof(TritonMTUNoQuat32TS_t))) { + TritonMTUNoQuat32TS_t *pTritonReport = (TritonMTUNoQuat32TS_t *)&data[1]; + HIDAPI_DriverSteamTriton_HandleState_Timestamp(device, joystick, pTritonReport); + } + break; + case ID_TRITON_BATTERY_STATUS: if (joystick && r >= (1 + sizeof(TritonBatteryStatus_t))) { TritonBatteryStatus_t *pTritonBatteryStatus = (TritonBatteryStatus_t *)&data[1]; HIDAPI_DriverSteamTriton_HandleBatteryStatus(device, joystick, pTritonBatteryStatus); diff --git a/src/joystick/hidapi/steam/controller_structs.h b/src/joystick/hidapi/steam/controller_structs.h index b0f86ea32b..ae0c043e2d 100644 --- a/src/joystick/hidapi/steam/controller_structs.h +++ b/src/joystick/hidapi/steam/controller_structs.h @@ -556,6 +556,8 @@ enum ETritonReportIDTypes ID_TRITON_BATTERY_STATUS = 0x43, ID_TRITON_CONTROLLER_STATE_BLE = 0x45, ID_TRITON_WIRELESS_STATUS_X = 0x46, + ID_TRITON_CONTROLLER_STATE_TIMESTAMP = 0x47, + ID_TRITON_WIRELESS_STATUS = 0x79, }; @@ -593,6 +595,18 @@ typedef struct { short sGyroZ; } TritonMTUIMUNoQuat_t; +typedef struct +{ + uint16_t timestamp; + short sAccelX; + short sAccelY; + short sAccelZ; + + short sGyroX; + short sGyroY; + short sGyroZ; +} TritonMTUIMUNoQuat32usTS_t; + typedef struct { uint8_t seq_num; @@ -607,11 +621,11 @@ typedef struct short sLeftPadX; short sLeftPadY; - unsigned short sPressureLeft; + unsigned short ucPressureLeft; short sRightPadX; short sRightPadY; - unsigned short sPressureRight; + unsigned short ucPressureRight; TritonMTUIMU_t imu; } TritonMTUFull_t; @@ -628,14 +642,40 @@ typedef struct { short sLeftPadX; short sLeftPadY; - unsigned short sPressureLeft; + unsigned short ucPressureLeft; short sRightPadX; short sRightPadY; - unsigned short sPressureRight; + unsigned short ucPressureRight; TritonMTUIMUNoQuat_t imu; } TritonMTUNoQuat_t; +// New Ibex packet that adds a timestamp to the trackpad sampling +// and reduces the size of the IMU timestamp. Timestamps are now 16 bits +typedef struct +{ + uint8_t seq_num; + uint32_t buttons; + short sTriggerLeft; + short sTriggerRight; + + short sLeftStickX; + short sLeftStickY; + short sRightStickX; + short sRightStickY; + + unsigned short unTrackpadTimestamp; + short sLeftPadX; + short sLeftPadY; + unsigned short unPressureLeft; + + short sRightPadX; + short sRightPadY; + unsigned short unPressureRight; + + TritonMTUIMUNoQuat32usTS_t imu; +} TritonMTUNoQuat32TS_t; + enum EChargeState { k_EChargeStateReset,