diff --git a/docs/ADDING-A-CONTROLLER.md b/docs/ADDING-A-CONTROLLER.md index 9c9f7cb..d7b59ba 100644 --- a/docs/ADDING-A-CONTROLLER.md +++ b/docs/ADDING-A-CONTROLLER.md @@ -36,7 +36,7 @@ If the vid:pid matches a known controller family, the existing protocol driver p | Family | Driver class | Examples | | --- | --- | --- | -| PlayStation (DS4 + DS5) | `DualSenseDriver` | DualSense, DualSense Edge, DualShock 4, GameSir Super Nova/Cyclone in DS4 mode | +| PlayStation (DS4 + DS5) | `PlayStationDriver` | DualSense, DualSense Edge, DualShock 4, GameSir Super Nova/Cyclone in DS4 mode | | Nintendo Switch Pro | `SwitchProDriver` | Switch Pro, GameSir Cyclone in Switch mode | | Xbox | `XboxDriver` | All Xbox families (Gamepad-API only, no WebHID features) | | Steam Controller 2026 | `SteamControllerDriver` | (stub — real HID parsing TBD) | @@ -87,7 +87,7 @@ This prints: > yaw gyroY_std=257.2 likely axis: gyro Y > ``` > -> The "winner" line told us GameSir packs IMU at byte 12/18 — three bytes earlier than Sony's DualSense layout (15/21). That single insight fixed a months-old latent bug: the existing DualSense parser was *also* wrong for real Sony DS4 (which uses the same byte-12 layout), it had only ever been validated against a DualSense (DS5). The fix in [packages/core/src/drivers/dualsense-driver.js](../packages/core/src/drivers/dualsense-driver.js) branches on `entry.mode === 'ds4'` and lights up both clones and real Sony DS4 hardware simultaneously. +> The "winner" line told us GameSir packs IMU at byte 12/18 — three bytes earlier than Sony's DualSense layout (15/21). That single insight fixed a months-old latent bug: the existing PlayStation parser was *also* wrong for real Sony DS4 (which uses the same byte-12 layout), it had only ever been validated against a DualSense (DS5). The fix in [packages/core/src/drivers/playstation-driver.js](../packages/core/src/drivers/playstation-driver.js) branches on `entry.mode === 'ds4'` and lights up both clones and real Sony DS4 hardware simultaneously. ## 5 — Update `devices.js` diff --git a/packages/core/README.md b/packages/core/README.md index 7bf03ea..2b6b626 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -11,7 +11,7 @@ Vendor-agnostic gamepad drivers, WebHID sensor fusion, and the slot/claim `Contr | `@usersfirst/controller-core/sensor-fusion` | `SensorFusion` (gyro orientation + bias calibration + drift correction) | | `@usersfirst/controller-core/drivers/controller-registry` | Registry lookup (`getEntry`, `getDriver`, `identifyFromGamepadId`, `getGamepadQuirks`, ...) | | `@usersfirst/controller-core/drivers/base-driver` | Abstract `ControllerDriver` (protocol interface) | -| `@usersfirst/controller-core/drivers/dualsense-driver` | DualSense / DualShock 4 protocol — gyro, accel, touchpad, lightbar | +| `@usersfirst/controller-core/drivers/playstation-driver` | PlayStation (DualSense + DualShock 4) protocol — gyro, accel, touchpad, lightbar. Registered under the `'dualsense'` protocol key. | | `@usersfirst/controller-core/drivers/switch-pro-driver` | Switch Pro protocol — IMU enable + gyro | | `@usersfirst/controller-core/drivers/xbox-driver` | Xbox identity stub (Gamepad-API only on Chromium; no WebHID capabilities today) | | `@usersfirst/controller-core/drivers/steam-controller-driver` | Steam Controller 2026 identity stub (placeholder for full Steam Input parsing) | diff --git a/packages/core/src/devices.js b/packages/core/src/devices.js index 8ef907b..c43f018 100644 --- a/packages/core/src/devices.js +++ b/packages/core/src/devices.js @@ -51,14 +51,19 @@ // } // ============================================================ -import { DualSenseDriver } from './drivers/dualsense-driver.js'; +import { PlayStationDriver } from './drivers/playstation-driver.js'; import { SwitchProDriver } from './drivers/switch-pro-driver.js'; import { XboxDriver } from './drivers/xbox-driver.js'; import { SteamControllerDriver } from './drivers/steam-controller-driver.js'; -/** Protocol id → driver class. Add a new protocol here when a new driver lands. */ +// Protocol id → driver class. The 'dualsense' key historically named +// just the DS5 protocol; it now covers PlayStation's DS4 + DS5 layouts +// (the class was renamed to PlayStationDriver to reflect that, but the +// key is preserved so the visualizer's PROFILES['dualsense'] GLB +// continues to load for all Sony entries without needing a per-entry +// controllerProfile override). export const PROTOCOLS = { - 'dualsense': DualSenseDriver, + 'dualsense': PlayStationDriver, 'switch-pro': SwitchProDriver, 'xbox': XboxDriver, 'steam-controller': SteamControllerDriver, diff --git a/packages/core/src/drivers/controller-registry.js b/packages/core/src/drivers/controller-registry.js index c93c17a..528310b 100644 --- a/packages/core/src/drivers/controller-registry.js +++ b/packages/core/src/drivers/controller-registry.js @@ -50,7 +50,7 @@ export class ControllerRegistry { /** * Find the driver class for a vid:pid. Returns the protocol implementation - * (DualSenseDriver, SwitchProDriver, etc.) or null. + * (PlayStationDriver, SwitchProDriver, etc.) or null. * @returns {typeof ControllerDriver|null} */ static getDriver(vendorId, productId) { diff --git a/packages/core/src/drivers/dualsense-driver.js b/packages/core/src/drivers/playstation-driver.js similarity index 94% rename from packages/core/src/drivers/dualsense-driver.js rename to packages/core/src/drivers/playstation-driver.js index 676e201..774a821 100644 --- a/packages/core/src/drivers/dualsense-driver.js +++ b/packages/core/src/drivers/playstation-driver.js @@ -1,13 +1,23 @@ // ============================================================ -// DUALSENSE / DUALSHOCK 4 DRIVER +// PLAYSTATION DRIVER — DualSense (DS5) + DualShock 4 (DS4) protocol // ============================================================ +// +// Covers both Sony PlayStation HID protocols and any clones that spoof +// them (GameSir Super Nova / Cyclone 2 in DS4 mode, etc.). The two +// protocols share most of the input-report layout, differing mainly in +// IMU byte offsets — that branch is driven by the dictionary entry's +// `mode` field ('ds5' vs 'ds4'), not by a separate driver class. +// +// Registered in PROTOCOLS under the key 'dualsense' (preserved as-is so +// existing visualizer profile mappings keep working without forcing a +// controllerProfile override on every Sony PlayStation entry). +// +// Identity (vid:pid, name, capabilities, gamepad-id pattern) lives in +// devices.js — this class is purely the protocol implementation. import { ControllerDriver } from './base-driver.js'; -// Identity (vid:pid, name, capabilities, gamepad-id pattern) lives in -// devices.js — this class is the DualSense/DualShock 4 protocol only. - -export class DualSenseDriver extends ControllerDriver { +export class PlayStationDriver extends ControllerDriver { constructor(device, connectionType, entry = null) { super(device, connectionType, entry); @@ -129,8 +139,8 @@ export class DualSenseDriver extends ControllerDriver { // ── Touchpad — 2 touch points, 4 bytes each ── const touchpad = [ - DualSenseDriver._parseTouchPoint(data, touchOffset), - DualSenseDriver._parseTouchPoint(data, touchOffset + 4) + PlayStationDriver._parseTouchPoint(data, touchOffset), + PlayStationDriver._parseTouchPoint(data, touchOffset + 4) ]; // Touchpad click: bit 1 of the PS byte @@ -394,7 +404,7 @@ export class DualSenseDriver extends ControllerDriver { crcInput[0] = 0xA2; crcInput[1] = 0x31; crcInput.set(buf.subarray(0, PAYLOAD_LEN - 4), 2); - const crc = DualSenseDriver._crc32(crcInput); + const crc = PlayStationDriver._crc32(crcInput); buf[PAYLOAD_LEN - 4] = crc & 0xFF; buf[PAYLOAD_LEN - 3] = (crc >>> 8) & 0xFF; buf[PAYLOAD_LEN - 2] = (crc >>> 16) & 0xFF; diff --git a/packages/core/src/index.js b/packages/core/src/index.js index aa61597..4227c3e 100644 --- a/packages/core/src/index.js +++ b/packages/core/src/index.js @@ -27,7 +27,7 @@ export { export { ControllerDriver } from './drivers/base-driver.js'; export { ControllerRegistry } from './drivers/controller-registry.js'; -export { DualSenseDriver } from './drivers/dualsense-driver.js'; +export { PlayStationDriver } from './drivers/playstation-driver.js'; export { SwitchProDriver } from './drivers/switch-pro-driver.js'; export { XboxDriver } from './drivers/xbox-driver.js'; export { SteamControllerDriver } from './drivers/steam-controller-driver.js';