UNPKG

dualsense-ts

Version:

The natural interface for your DualSense Classic and DualSense Access controllers, with Typescript

112 lines 6.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AccessHIDProvider = exports.DefaultAccessHIDState = exports.AccessInputId = void 0; const hid_provider_1 = require("../hid_provider"); const access_hid_1 = require("../access_hid"); const access_hid_state_1 = require("./access_hid_state"); Object.defineProperty(exports, "AccessInputId", { enumerable: true, get: function () { return access_hid_state_1.AccessInputId; } }); Object.defineProperty(exports, "DefaultAccessHIDState", { enumerable: true, get: function () { return access_hid_state_1.DefaultAccessHIDState; } }); /** Supports a connection to a physical or virtual DualSense Access device */ class AccessHIDProvider { constructor() { /** Callback to use for new input events */ this.onData = () => { }; /** Callback to use for Error events */ this.onError = () => { }; /** Callback fired the moment a device is fully attached and ready for I/O */ this.onConnect = () => { }; /** Callback fired the moment a device detaches (cleanly or via error) */ this.onDisconnect = () => { }; } /** * Selects the correct method for reading the report. */ processReport(buffer) { const reportId = buffer.readUint8(0); switch (reportId) { case 0x01: return this.wireless ? this.processBluetoothInputReport01(buffer) : this.processUsbInputReport01(buffer); case 0x31: return this.processBluetoothInputReport31(buffer); default: this.onError(new Error(`Cannot process report, unexpected report id: ${reportId}`)); this.disconnect(); return { ...access_hid_state_1.DefaultAccessHIDState }; } } /** Reset the provider state when the device is disconnected */ reset() { const wasAttached = this.device !== undefined; if (this.deviceId) { AccessHIDProvider.claimedDevices.delete(this.deviceId); } this.device = undefined; this.wireless = undefined; this.buffer = undefined; this.deviceId = undefined; this.serialNumber = undefined; this.onData(access_hid_state_1.DefaultAccessHIDState); if (wasAttached) this.onDisconnect(); } /** * Process a BT input report 0x01 (limited mode, pre-Feature 0x05). * Only has the mapped DualSense-compatible header, no Access-specific data. */ processBluetoothInputReport01(_buffer // eslint-disable-line @typescript-eslint/no-unused-vars ) { // BT 0x01 only contains the mapped DualSense-compatible header. // Without the Access-specific section, we can't read raw buttons, // raw stick, battery, or profile. Return default state. return { ...access_hid_state_1.DefaultAccessHIDState }; } /** Process BT input report 0x31 (full mode, offset +1 from USB) */ processBluetoothInputReport31(buffer) { const o = access_hid_1.AccessInput.BT_OFFSET; // +1 return this.parseAccessReport(buffer, o); } /** Process USB input report 0x01 (full Access report) */ processUsbInputReport01(buffer) { return this.parseAccessReport(buffer, 0); } /** Parse Access-specific fields from the report buffer at the given offset */ parseAccessReport(buffer, offset) { const rawButtons1 = buffer.readUint8(access_hid_1.AccessInput.RAW_BUTTONS_1 + offset); const rawButtons2 = buffer.readUint8(access_hid_1.AccessInput.RAW_BUTTONS_2 + offset); const batteryByte = buffer.readUint8(access_hid_1.AccessInput.BATTERY + offset); const profileByte = buffer.readUint8(access_hid_1.AccessInput.PROFILE + offset); return { [access_hid_state_1.AccessInputId.B1]: (rawButtons1 & access_hid_1.AccessButton1.B1) > 0, [access_hid_state_1.AccessInputId.B2]: (rawButtons1 & access_hid_1.AccessButton1.B2) > 0, [access_hid_state_1.AccessInputId.B3]: (rawButtons1 & access_hid_1.AccessButton1.B3) > 0, [access_hid_state_1.AccessInputId.B4]: (rawButtons1 & access_hid_1.AccessButton1.B4) > 0, [access_hid_state_1.AccessInputId.B5]: (rawButtons1 & access_hid_1.AccessButton1.B5) > 0, [access_hid_state_1.AccessInputId.B6]: (rawButtons1 & access_hid_1.AccessButton1.B6) > 0, [access_hid_state_1.AccessInputId.B7]: (rawButtons1 & access_hid_1.AccessButton1.B7) > 0, [access_hid_state_1.AccessInputId.B8]: (rawButtons1 & access_hid_1.AccessButton1.B8) > 0, [access_hid_state_1.AccessInputId.Center]: (rawButtons2 & access_hid_1.AccessButton2.CENTER) > 0, [access_hid_state_1.AccessInputId.StickClick]: (rawButtons2 & access_hid_1.AccessButton2.STICK) > 0, [access_hid_state_1.AccessInputId.PS]: (rawButtons2 & access_hid_1.AccessButton2.PS) > 0, [access_hid_state_1.AccessInputId.Profile]: (rawButtons2 & access_hid_1.AccessButton2.PROFILE) > 0, [access_hid_state_1.AccessInputId.StickX]: (0, hid_provider_1.mapAxis)(buffer.readUint8(access_hid_1.AccessInput.RAW_STICK_X + offset)), [access_hid_state_1.AccessInputId.StickY]: (0, hid_provider_1.mapAxis)(buffer.readUint8(access_hid_1.AccessInput.RAW_STICK_Y + offset)), [access_hid_state_1.AccessInputId.BatteryLevel]: (0, hid_provider_1.mapBatteryLevel)(batteryByte), [access_hid_state_1.AccessInputId.BatteryStatus]: (batteryByte >> 4), [access_hid_state_1.AccessInputId.ProfileId]: (profileByte & 0x07) || 1, }; } } exports.AccessHIDProvider = AccessHIDProvider; /** HID vendorId for a DualSense Access controller */ AccessHIDProvider.vendorId = 0x054c; /** HID productId for a DualSense Access controller */ AccessHIDProvider.productId = 0x0e5f; /** HID usagePage for a DualSense Access controller */ AccessHIDProvider.usagePage = 0x0001; /** HID usage for a DualSense Access controller */ AccessHIDProvider.usage = 0x0005; /** Global set of device paths currently claimed by a provider instance */ AccessHIDProvider.claimedDevices = new Set(); //# sourceMappingURL=access_hid_provider.js.map