mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-06-04 19:55:19 +00:00
Add support for new Steam Controller input report on mobile devices
This commit is contained in:
parent
a95f5f9874
commit
f6ffa69890
6 changed files with 93 additions and 98 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) },
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue