From 75be77d79e1e9b05d008a43a56d292f3bc083911 Mon Sep 17 00:00:00 2001 From: Pete Gordon Date: Sat, 23 May 2026 20:35:18 -0400 Subject: [PATCH] refactor: rename DualSenseDriver to PlayStationDriver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The class covers both DualSense (DS5) and DualShock 4 (DS4) USB protocols plus their clones (GameSir Super Nova / Cyclone 2 in DS4 mode). Naming it "DualSenseDriver" was misleading — DualSense is one specific physical controller, not the protocol family — and users hit that confusion in practice ("I have a DualSense, not a DualShock, why is the file/class named like that?"). Pure rename, no behavior change: - File: packages/core/src/drivers/{dualsense → playstation}-driver.js (via git mv so history follows) - Class: DualSenseDriver → PlayStationDriver - Module header comment expanded to spell out which protocols it covers and which clones spoof them. Preserved on purpose: - PROTOCOLS map key stays 'dualsense'. The visualizer's PROFILES table uses 'dualsense' as its profile key, and entry.controllerProfile defaults to entry.protocol → 'dualsense' for all Sony entries. Renaming the protocol key would force a controllerProfile: 'dualsense' override on every PlayStation entry just to keep the same GLB loading. Not worth the churn for a cosmetic improvement. A comment in PROTOCOLS explains the historical naming. Touched files: - packages/core/src/drivers/playstation-driver.js (renamed + class + static method references DualSenseDriver._parseTouchPoint / ._crc32 updated) - packages/core/src/devices.js (import + PROTOCOLS map entry) - packages/core/src/index.js (barrel re-export) - packages/core/src/drivers/controller-registry.js (one comment) - packages/core/README.md (subpath-exports table) - docs/ADDING-A-CONTROLLER.md (protocol-table row + the worked-example code-link) Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/ADDING-A-CONTROLLER.md | 4 +-- packages/core/README.md | 2 +- packages/core/src/devices.js | 11 +++++--- .../core/src/drivers/controller-registry.js | 2 +- ...lsense-driver.js => playstation-driver.js} | 26 +++++++++++++------ packages/core/src/index.js | 2 +- 6 files changed, 31 insertions(+), 16 deletions(-) rename packages/core/src/drivers/{dualsense-driver.js => playstation-driver.js} (94%) 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';