Add support for new Steam Controller input report on mobile devices

This commit is contained in:
Sam Lantinga 2026-05-28 11:18:20 -07:00
parent a95f5f9874
commit f6ffa69890
6 changed files with 93 additions and 98 deletions

View file

@ -44,6 +44,8 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
GattOperation mCurrentOperation = null;
private Handler mHandler;
private int mProductId = -1;
private int mReportId = 0;
private UUID mInputCharacteristic;
private static final int D0G_BLE2_PID = 0x1106;
private static final int TRITON_BLE_PID = 0x1303;
@ -57,7 +59,8 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
static final UUID steamControllerService = UUID.fromString("100F6C32-1735-4313-B402-38567131E5F3");
static final UUID inputCharacteristicD0G = UUID.fromString("100F6C33-1735-4313-B402-38567131E5F3");
static final UUID inputCharacteristicTriton = UUID.fromString("100F6C7A-1735-4313-B402-38567131E5F3");
static final UUID inputCharacteristicTriton_0x45 = UUID.fromString("100F6C7A-1735-4313-B402-38567131E5F3");
static final UUID inputCharacteristicTriton_0x47 = UUID.fromString("100F6C7C-1735-4313-B402-38567131E5F3");
static final UUID reportCharacteristic = UUID.fromString("100F6C34-1735-4313-B402-38567131E5F3");
static private final byte[] enterValveMode = new byte[] { (byte)0xC0, (byte)0x87, 0x03, 0x08, 0x07, 0x00 };
@ -352,16 +355,21 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
Log.v(TAG, "Found Valve steam controller service " + service.getUuid());
for (BluetoothGattCharacteristic chr : service.getCharacteristics()) {
boolean bShouldStartNotifications = false;
if (chr.getUuid().equals(inputCharacteristicTriton)) {
Log.v(TAG, "Found Triton input characteristic");
if (chr.getUuid().equals(inputCharacteristicTriton_0x45)) {
Log.v(TAG, "Found Triton input characteristic 0x45");
mProductId = TRITON_BLE_PID;
bShouldStartNotifications = true;
mReportId = 0x45;
mInputCharacteristic = chr.getUuid();
} else if (chr.getUuid().equals(inputCharacteristicTriton_0x47)) {
Log.v(TAG, "Found Triton input characteristic 0x47");
mProductId = TRITON_BLE_PID;
mReportId = 0x47;
mInputCharacteristic = chr.getUuid();
} else if (chr.getUuid().equals(inputCharacteristicD0G)) {
Log.v(TAG, "Found D0G input characteristic");
mProductId = D0G_BLE2_PID;
bShouldStartNotifications = true;
mReportId = 0x03;
mInputCharacteristic = chr.getUuid();
} else {
Pattern reportPattern = Pattern.compile("100F6C([0-9A-Z]{2})", Pattern.CASE_INSENSITIVE);
Matcher matcher = reportPattern.matcher(chr.getUuid().toString());
@ -382,8 +390,10 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
}
}
}
}
if (bShouldStartNotifications) {
for (BluetoothGattCharacteristic chr : service.getCharacteristics()) {
if (chr.getUuid().equals(mInputCharacteristic)) {
// Start notifications
BluetoothGattDescriptor cccd = chr.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
if (cccd != null) {
@ -590,7 +600,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
// Only register controller with the native side once it has been fully configured
if (!isRegistered()) {
Log.v(TAG, "Registering Steam Controller with ID: " + getId());
mManager.HIDDeviceConnected(getId(), getIdentifier(), getVendorId(), getProductId(), getSerialNumber(), getVersion(), getManufacturerName(), getProductName(), 0, 0, 0, 0, true);
mManager.HIDDeviceConnected(getId(), getIdentifier(), getVendorId(), getProductId(), getSerialNumber(), getVersion(), getManufacturerName(), getProductName(), 0, 0, 0, 0, true, mReportId);
setRegistered();
}
}
@ -603,7 +613,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
// Enable this for verbose logging of controller input reports
//Log.v(TAG, "onCharacteristicChanged uuid=" + characteristic.getUuid() + " data=" + HexDump.dumpHexString(characteristic.getValue()));
if (characteristic.getUuid().equals(getInputCharacteristic()) && !mFrozen) {
if (characteristic.getUuid().equals(mInputCharacteristic) && !mFrozen) {
mHasSeenInputUpdate = true;
mManager.HIDDeviceInputReport(getId(), characteristic.getValue());
}
@ -625,7 +635,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
if (getProductId() == TRITON_BLE_PID) {
// For Triton we just mark things registered.
Log.v(TAG, "Registering Triton Steam Controller with ID: " + getId());
mManager.HIDDeviceConnected(getId(), getIdentifier(), getVendorId(), getProductId(), getSerialNumber(), getVersion(), getManufacturerName(), getProductName(), 0, 0, 0, 0, true);
mManager.HIDDeviceConnected(getId(), getIdentifier(), getVendorId(), getProductId(), getSerialNumber(), getVersion(), getManufacturerName(), getProductName(), 0, 0, 0, 0, true, mReportId);
setRegistered();
} else {
// For the original controller, we need to manually enter Valve mode.
@ -641,7 +651,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
BluetoothGattCharacteristic chr = descriptor.getCharacteristic();
//Log.v(TAG, "onDescriptorWrite status=" + status + " uuid=" + chr.getUuid() + " descriptor=" + descriptor.getUuid());
if (chr.getUuid().equals(getInputCharacteristic())) {
if (chr.getUuid().equals(mInputCharacteristic)) {
mHasEnabledNotifications = true;
enableValveMode();
}
@ -698,14 +708,6 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
return mProductId;
}
private UUID getInputCharacteristic() {
if (getProductId() == TRITON_BLE_PID) {
return inputCharacteristicTriton;
} else {
return inputCharacteristicD0G;
}
}
@Override
public String getSerialNumber() {
// This will be read later via feature report by Steam

View file

@ -361,7 +361,7 @@ public class HIDDeviceManager {
HIDDeviceUSB device = new HIDDeviceUSB(this, usbDevice, interface_index);
int id = device.getId();
mDevicesById.put(id, device);
HIDDeviceConnected(id, device.getIdentifier(), device.getVendorId(), device.getProductId(), device.getSerialNumber(), device.getVersion(), device.getManufacturerName(), device.getProductName(), usbInterface.getId(), usbInterface.getInterfaceClass(), usbInterface.getInterfaceSubclass(), usbInterface.getInterfaceProtocol(), false);
HIDDeviceConnected(id, device.getIdentifier(), device.getVendorId(), device.getProductId(), device.getSerialNumber(), device.getVersion(), device.getManufacturerName(), device.getProductName(), usbInterface.getId(), usbInterface.getInterfaceClass(), usbInterface.getInterfaceSubclass(), usbInterface.getInterfaceProtocol(), false, 0);
}
}
}
@ -688,7 +688,7 @@ public class HIDDeviceManager {
private native void HIDDeviceRegisterCallback();
private native void HIDDeviceReleaseCallback();
native void HIDDeviceConnected(int deviceID, String identifier, int vendorId, int productId, String serial_number, int release_number, String manufacturer_string, String product_string, int interface_number, int interface_class, int interface_subclass, int interface_protocol, boolean bBluetooth);
native void HIDDeviceConnected(int deviceID, String identifier, int vendorId, int productId, String serial_number, int release_number, String manufacturer_string, String product_string, int interface_number, int interface_class, int interface_subclass, int interface_protocol, boolean bBluetooth, int reportID);
native void HIDDeviceOpenPending(int deviceID);
native void HIDDeviceOpenResult(int deviceID, boolean opened);
native void HIDDeviceDisconnected(int deviceID);

View file

@ -434,10 +434,11 @@ static void ExceptionCheck( JNIEnv *env, const char *pszClassName, const char *p
class CHIDDevice
{
public:
CHIDDevice( int nDeviceID, hid_device_info *pInfo )
CHIDDevice( int nDeviceID, hid_device_info *pInfo, int nReportID )
{
m_nId = nDeviceID;
m_pInfo = pInfo;
m_nReportID = nReportID;
// The Bluetooth Steam Controller needs special handling
const int VALVE_USB_VID = 0x28DE;
@ -606,14 +607,7 @@ public:
size_t nDataLen = buffer.size() > length ? length : buffer.size();
if ( m_bIsBLESteamController )
{
if ( m_pInfo->product_id == TRITON_BLE_PID )
{
data[0] = 0x45;
}
else
{
data[0] = 0x03;
}
data[0] = m_nReportID;
SDL_memcpy( data + 1, buffer.data(), nDataLen );
++nDataLen;
}
@ -788,6 +782,7 @@ private:
pthread_mutex_t m_refCountLock = PTHREAD_MUTEX_INITIALIZER;
int m_nRefCount = 0;
int m_nId = 0;
int m_nReportID = 0;
hid_device_info *m_pInfo = nullptr;
hid_device *m_pDevice = nullptr;
bool m_bIsBLESteamController = false;
@ -837,7 +832,7 @@ extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, jint nDeviceID, jstring sIdentifier, jint nVendorId, jint nProductId, jstring sSerialNumber, jint nReleaseNumber, jstring sManufacturer, jstring sProduct, jint nInterface, jint nInterfaceClass, jint nInterfaceSubclass, jint nInterfaceProtocol, jboolean bBluetooth );
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, jint nDeviceID, jstring sIdentifier, jint nVendorId, jint nProductId, jstring sSerialNumber, jint nReleaseNumber, jstring sManufacturer, jstring sProduct, jint nInterface, jint nInterfaceClass, jint nInterfaceSubclass, jint nInterfaceProtocol, jboolean bBluetooth, jint nReportID );
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, jint nDeviceID);
@ -917,7 +912,7 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallbac
}
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, jint nDeviceID, jstring sIdentifier, jint nVendorId, jint nProductId, jstring sSerialNumber, jint nReleaseNumber, jstring sManufacturer, jstring sProduct, jint nInterface, jint nInterfaceClass, jint nInterfaceSubclass, jint nInterfaceProtocol, jboolean bBluetooth )
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, jint nDeviceID, jstring sIdentifier, jint nVendorId, jint nProductId, jstring sSerialNumber, jint nReleaseNumber, jstring sManufacturer, jstring sProduct, jint nInterface, jint nInterfaceClass, jint nInterfaceSubclass, jint nInterfaceProtocol, jboolean bBluetooth, jint nReportID )
{
LOGV( "HIDDeviceConnected() id=%d VID/PID = %.4x/%.4x, interface %d\n", nDeviceID, nVendorId, nProductId, nInterface );
@ -943,7 +938,7 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNI
pInfo->bus_type = HID_API_BUS_USB;
}
hid_device_ref<CHIDDevice> pDevice( new CHIDDevice( nDeviceID, pInfo ) );
hid_device_ref<CHIDDevice> pDevice( new CHIDDevice( nDeviceID, pInfo, nReportID ) );
hid_mutex_guard l( &g_DevicesMutex );
hid_device_ref<CHIDDevice> pLast, pCurr;
@ -1423,7 +1418,7 @@ extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, jint nDeviceID, jstring sIdentifier, jint nVendorId, jint nProductId, jstring sSerialNumber, jint nReleaseNumber, jstring sManufacturer, jstring sProduct, jint nInterface, jint nInterfaceClass, jint nInterfaceSubclass, jint nInterfaceProtocol, jboolean bBluetooth );
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, jint nDeviceID, jstring sIdentifier, jint nVendorId, jint nProductId, jstring sSerialNumber, jint nReleaseNumber, jstring sManufacturer, jstring sProduct, jint nInterface, jint nInterfaceClass, jint nInterfaceSubclass, jint nInterfaceProtocol, jboolean bBluetooth, jint nReportID );
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, jint nDeviceID);
@ -1454,7 +1449,7 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallbac
}
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, jint nDeviceID, jstring sIdentifier, jint nVendorId, jint nProductId, jstring sSerialNumber, jint nReleaseNumber, jstring sManufacturer, jstring sProduct, jint nInterface, jint nInterfaceClass, jint nInterfaceSubclass, jint nInterfaceProtocol, jboolean bBluetooth )
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, jint nDeviceID, jstring sIdentifier, jint nVendorId, jint nProductId, jstring sSerialNumber, jint nReleaseNumber, jstring sManufacturer, jstring sProduct, jint nInterface, jint nInterfaceClass, jint nInterfaceSubclass, jint nInterfaceProtocol, jboolean bBluetooth, jint nReportID )
{
LOGV("Stub HIDDeviceConnected() id=%d VID/PID = %.4x/%.4x, interface %d\n", nDeviceID, nVendorId, nProductId, nInterface);
}
@ -1495,7 +1490,7 @@ extern "C"
JNINativeMethod HIDDeviceManager_tab[8] = {
{ "HIDDeviceRegisterCallback", "()V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback) },
{ "HIDDeviceReleaseCallback", "()V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback) },
{ "HIDDeviceConnected", "(ILjava/lang/String;IILjava/lang/String;ILjava/lang/String;Ljava/lang/String;IIIIZ)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected) },
{ "HIDDeviceConnected", "(ILjava/lang/String;IILjava/lang/String;ILjava/lang/String;Ljava/lang/String;IIIIZI)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected) },
{ "HIDDeviceOpenPending", "(I)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending) },
{ "HIDDeviceOpenResult", "(IZ)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult) },
{ "HIDDeviceDisconnected", "(I)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected) },

View file

@ -78,7 +78,8 @@ typedef uint64_t uint64;
// (READ/NOTIFICATIONS)
#define VALVE_INPUT_CHAR_0x1106 @"100F6C33-1735-4313-B402-38567131E5F3"
#define VALVE_INPUT_CHAR_0x1303 @"100F6C7A-1735-4313-B402-38567131E5F3"
#define VALVE_INPUT_CHAR_0x1303_0x45 @"100F6C7A-1735-4313-B402-38567131E5F3"
#define VALVE_INPUT_CHAR_0x1303_0x47 @"100F6C7C-1735-4313-B402-38567131E5F3"
//  (READ/WRITE)
#define VALVE_REPORT_CHAR @"100F6C34-1735-4313-B402-38567131E5F3"
@ -220,6 +221,8 @@ typedef enum
}
@property (nonatomic, readwrite) uint16_t pid;
@property (nonatomic, readwrite) uint8_t report_id;
@property (nonatomic, readwrite) int report_length;
@property (nonatomic, readwrite) bool connected;
@property (nonatomic, readwrite) bool ready;
@ -523,7 +526,9 @@ static void process_pending_events(void)
if ( self = [super init] )
{
self.pid = 0;
_inputReports = NULL;
self.report_id = 0;
self.report_length = 0;
_inputReports = NULL;
_outputReports = [[NSMutableDictionary alloc] init];
_connected = NO;
_ready = NO;
@ -539,7 +544,9 @@ static void process_pending_events(void)
if ( self = [super init] )
{
self.pid = 0;
_inputReports = NULL;
self.report_id = 0;
self.report_length = 0;
_inputReports = NULL;
_outputReports = [[NSMutableDictionary alloc] init];
_connected = NO;
_ready = NO;
@ -583,17 +590,7 @@ static void process_pending_events(void)
{
if ( RingBuffer_read( _inputReports, dst+1 ) )
{
switch ( self.pid )
{
case D0G_BLE2_PID:
*dst = 0x03;
break;
case TRITON_BLE_PID:
*dst = 0x45;
break;
default:
abort();
}
*dst = self.report_id;
return _inputReports->_cbElem + 1;
}
return 0;
@ -603,9 +600,9 @@ static void process_pending_events(void)
{
if ( self.pid == D0G_BLE2_PID )
{
[_bleSteamController writeValue:[NSData dataWithBytes:data length:length] forCharacteristic:_bleCharacteristicReport type:CBCharacteristicWriteWithResponse];
return (int)length;
}
[_bleSteamController writeValue:[NSData dataWithBytes:data length:length] forCharacteristic:_bleCharacteristicReport type:CBCharacteristicWriteWithResponse];
return (int)length;
}
// We need to look up the correct characteristic for this output report
if ( length > 0 )
@ -748,11 +745,22 @@ static void process_pending_events(void)
if ( [aChar.UUID isEqual:[CBUUID UUIDWithString:VALVE_INPUT_CHAR_0x1106]] )
{
self.pid = D0G_BLE2_PID;
self.report_id = 0x03;
self.report_length = 19;
self.bleCharacteristicInput = aChar;
}
else if ( [aChar.UUID isEqual:[CBUUID UUIDWithString:VALVE_INPUT_CHAR_0x1303]] )
else if ( [aChar.UUID isEqual:[CBUUID UUIDWithString:VALVE_INPUT_CHAR_0x1303_0x45]] )
{
self.pid = TRITON_BLE_PID;
self.report_id = 0x45;
self.report_length = 45;
self.bleCharacteristicInput = aChar;
}
else if ( [aChar.UUID isEqual:[CBUUID UUIDWithString:VALVE_INPUT_CHAR_0x1303_0x47]] )
{
self.pid = TRITON_BLE_PID;
self.report_id = 0x47;
self.report_length = 45;
self.bleCharacteristicInput = aChar;
}
else if ( [aChar.UUID isEqual:[CBUUID UUIDWithString:VALVE_REPORT_CHAR]] )
@ -789,22 +797,10 @@ static void process_pending_events(void)
if ( self.ready == NO )
{
self.ready = YES;
if ( _inputReports == NULL )
{
int cbElem = 0;
switch ( self.pid )
{
case D0G_BLE2_PID:
cbElem = 19;
break;
case TRITON_BLE_PID:
cbElem = 45;
break;
default:
abort();
}
_inputReports = RingBuffer_alloc( cbElem );
}
if ( _inputReports == NULL )
{
_inputReports = RingBuffer_alloc( self.report_length );
}
HIDBLEManager.sharedInstance.nPendingPairs -= 1;
}

View file

@ -96,7 +96,8 @@ typedef struct
{
bool connected;
bool report_sensors;
Uint32 last_sensor_tick;
Uint16 last_sensor_tick16;
Uint32 last_sensor_tick32;
Uint64 sensor_timestamp_ns;
Uint64 last_button_state;
Uint64 last_lizard_update;
@ -139,7 +140,7 @@ static bool DisableSteamTritonLizardMode(SDL_hid_device *dev)
// 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 )
static void HIDAPI_DriverSteamTriton_HandleGenericState(SDL_DriverSteamTriton_Context *ctx, SDL_Joystick *joystick, Uint64 timestamp, TritonMTUNoQuat_t *pTritonReport)
{
if (pTritonReport->buttons != ctx->last_button_state) {
Uint8 hat = 0;
@ -213,11 +214,11 @@ static void Parse_SteamTriton_HandleGenericState( SDL_DriverSteamTriton_Context*
ctx->last_button_state = pTritonReport->buttons;
}
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);
@ -228,19 +229,19 @@ static void Parse_SteamTriton_HandleGenericState( SDL_DriverSteamTriton_Context*
}
static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device,
SDL_Joystick *joystick,
TritonMTUNoQuat_t *pTritonReport)
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);
HIDAPI_DriverSteamTriton_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_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;
@ -249,7 +250,7 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device,
left_touch_down,
ctx->left_touch_x,
ctx->left_touch_y,
pTritonReport->ucPressureLeft / 32768.0f);
pTritonReport->unPressureLeft / 32768.0f);
ctx->left_touch_down = left_touch_down;
}
if (right_touch_down || ctx->right_touch_down) {
@ -261,12 +262,12 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device,
right_touch_down,
ctx->right_touch_x,
ctx->right_touch_y,
pTritonReport->ucPressureRight / 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);
if (ctx->report_sensors && pTritonReport->imu.timestamp != ctx->last_sensor_tick32) {
Uint32 delta_us = (pTritonReport->imu.timestamp - ctx->last_sensor_tick32);
ctx->sensor_timestamp_ns += SDL_US_TO_NS(delta_us);
@ -280,19 +281,19 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device,
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;
ctx->last_sensor_tick32 = pTritonReport->imu.timestamp;
}
}
// New Ibex MTU has IMU data in
static void HIDAPI_DriverSteamTriton_HandleState_Timestamp(SDL_HIDAPI_Device *device,
SDL_Joystick *joystick,
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);
HIDAPI_DriverSteamTriton_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;
@ -322,8 +323,9 @@ static void HIDAPI_DriverSteamTriton_HandleState_Timestamp(SDL_HIDAPI_Device *de
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);
if (ctx->report_sensors && pTritonReport->imu.timestamp != ctx->last_sensor_tick16) {
// The timestamp is in units of 32 microseconds
Uint32 delta_us = (Uint32)(pTritonReport->imu.timestamp - ctx->last_sensor_tick16) * 32;
ctx->sensor_timestamp_ns += SDL_US_TO_NS(delta_us);
@ -337,7 +339,7 @@ static void HIDAPI_DriverSteamTriton_HandleState_Timestamp(SDL_HIDAPI_Device *de
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;
ctx->last_sensor_tick16 = pTritonReport->imu.timestamp;
}
}
@ -438,8 +440,8 @@ static bool HIDAPI_DriverSteamTriton_IsSupportedDevice(
return true;
}
} else if (SDL_IsJoystickSteamTriton(vendor_id, product_id)) {
return true;
}
return true;
}
return false;
}
@ -537,7 +539,7 @@ static bool HIDAPI_DriverSteamTriton_UpdateDevice(SDL_HIDAPI_Device *device)
HIDAPI_DriverSteamTriton_HandleState_Timestamp(device, joystick, pTritonReport);
}
break;
case ID_TRITON_BATTERY_STATUS:
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);
@ -593,7 +595,7 @@ static bool HIDAPI_DriverSteamTriton_RumbleJoystick(SDL_HIDAPI_Device *device, S
Uint8 buffer[HID_RUMBLE_OUTPUT_REPORT_BYTES] = { 0 };
OutputReportMsg *msg = (OutputReportMsg *)(buffer);
msg->report_id = ID_OUT_REPORT_HAPTIC_RUMBLE;
msg->report_id = ID_OUT_REPORT_HAPTIC_RUMBLE;
msg->payload.hapticRumble.type = 0;
msg->payload.hapticRumble.intensity = 0;
msg->payload.hapticRumble.left.speed = low_frequency_rumble;

View file

@ -620,11 +620,11 @@ typedef struct
short sLeftPadX;
short sLeftPadY;
unsigned short ucPressureLeft;
unsigned short unPressureLeft;
short sRightPadX;
short sRightPadY;
unsigned short ucPressureRight;
unsigned short unPressureRight;
TritonMTUIMU_t imu;
} TritonMTUFull_t;
@ -641,11 +641,11 @@ typedef struct {
short sLeftPadX;
short sLeftPadY;
unsigned short ucPressureLeft;
unsigned short unPressureLeft;
short sRightPadX;
short sRightPadY;
unsigned short ucPressureRight;
unsigned short unPressureRight;
TritonMTUIMUNoQuat_t imu;
} TritonMTUNoQuat_t;