From 0fa6aec4a68bf2de25dbbca8200a6c7cca24430f Mon Sep 17 00:00:00 2001 From: itsnttt Date: Sat, 5 Sep 2026 07:04:49 +0700 Subject: [PATCH 1/2] supported devices: add the ATK ZERO, correct the ZERO family note The ZERO does not speak the 0xff02 EEPROM protocol the existing ATK driver implements, so the "ATK driver (0x373b) likely covers" note on the VXE Zero Normal row was wrong: that vendor id alone is not enough. The family uses the BITMOUSE channel on usage page 0xff05, added in OpenMouse-Project/mouse-protocol. Pin the two PIDs verified on hardware and let the PID universe in the test import them from the protocol package, so the row cannot drift. Co-Authored-By: Claude Opus 5 --- src/supported-mice.test.ts | 2 ++ src/supported-mice.ts | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/supported-mice.test.ts b/src/supported-mice.test.ts index 11b474a4..76bdb28d 100644 --- a/src/supported-mice.test.ts +++ b/src/supported-mice.test.ts @@ -3,6 +3,7 @@ import test from "node:test"; import { DEVICE_DRIVERS } from "@openmouse/protocol/drivers/registry"; import { WLMOUSE_PRODUCTS, GLORIOUS_PRODUCTS, GLORIOUS_CLASSIC_PRODUCTS, VENDOR_ID } from "@openmouse/protocol/drivers/vendors"; +import { BITMOUSE_PRODUCT_IDS } from "@openmouse/protocol/bitmouse"; import { EGG_DEVICE_PROFILES } from "@openmouse/protocol/endgame-gear-op1"; import { KEYCHRON_NAPE_PRODUCTS } from "@openmouse/protocol/keychron"; import { LAMZU_PRODUCTS } from "@openmouse/protocol/lamzu"; @@ -77,6 +78,7 @@ test("supported / PR / quickwin claims require a registered driver brand", () => // is exempt. The moment the protocol pins those PIDs, the row is flipped to // "supported" and this check proves the PIDs are real. const PID_UNIVERSE = new Set([ + ...BITMOUSE_PRODUCT_IDS, ...WLMOUSE_PRODUCTS.keys(), ...LAMZU_PRODUCTS.keys(), ...LOGITECH_DIRECT_PRODUCT_IDS, diff --git a/src/supported-mice.ts b/src/supported-mice.ts index 288ef22b..9a367425 100644 --- a/src/supported-mice.ts +++ b/src/supported-mice.ts @@ -427,8 +427,11 @@ export const MICE: Mouse[] = [ note: "ATK driver (0x373b) likely covers — needs hardware test" }, { brand: "ATK", model: "VXE Mad R Major", status: "likely", req: 1, note: "ATK driver (0x373b) likely covers — needs hardware test" }, + { brand: "ATK", model: "ZERO", status: "supported", req: 1, + pids: [0x1154, 0x1155], + note: "BITMOUSE driver — wired 0x1154, 8K receiver 0x1155, usagePage 0xff05. Verified on hardware: DPI, poll rate, debounce, sleep, motion sync, ripple. Lift-off not decoded" }, { brand: "ATK", model: "VXE Zero Normal", status: "likely", req: 1, - note: "ATK driver (0x373b) likely covers — needs hardware test" }, + note: "The 0xff02 ATK driver does not reach the ZERO family — it uses the BITMOUSE channel on 0xff05; needs its own PID confirmed on hardware" }, { brand: "VGN", model: "Dragonfly F2 Master+", status: "supported", req: 1, pids: [0xfb56, 0xfb57], note: "VGN F2 driver — PIDs 0xfb56/0xfb57" }, From c206565d9e05c009fe3efbe1c8fbcc0731302c97 Mon Sep 17 00:00:00 2001 From: itsnttt Date: Sat, 5 Sep 2026 08:14:55 +0700 Subject: [PATCH 2/2] control: drive the ATK ZERO, and let a mouse state its own lift-off range MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wiring the BITMOUSE driver up exposed three things the app assumed. A driver the app does not name is treated as Pulsar. `pulsarClient()` is a negative test — anything not in DEDICATED falls through to the Pulsar explorer — so connecting an ATK ZERO failed on `client.describeCollections is not a function`. The client joins DM_CLASSES, beside the older ATK, Lamzu and WLMouse drivers whose surface it shares. Cards come from BY_FAMILY, not from the status. `ui.showAdvancedSection` opens the section but `sleep` and `debounce` stay false until the family is in the table, so both cards were missing even though the driver reported values for them. "atk-bitmouse" gets the same DIRECT_MODE entry as "atk". Lift-off was three stops for everyone. `liftOffDistance` has only Low, Medium and High, so a mouse that tunes lift-off continuously — the ATK ZERO runs 0.7 mm to 1.7 mm in eleven steps — had ten of its settings thrown away. Drivers can now report a `liftOffScale`, and the card renders a slider over the raw device codes labelled with the millimetres the driver supplies, so the scale stays in the driver and any brand can use the control. The coarse field is still reported alongside it, and a driver that sets no scale keeps the three stops exactly as before. Sensor sampling mode was likewise Teevolution-only; a generic row now shows whenever a status carries `sensorMode`. Ultra Long Range gets a toggle against the new `longRangeMode` field. Also maps both ATK ZERO product ids to atk-zero.png. The art itself goes through an artwork request, as public/devices/README.md asks. Co-Authored-By: Claude Opus 5 --- src/app/cards/AdvancedCards.tsx | 25 ++++++++++++++ src/app/cards/PerformanceCards.tsx | 47 ++++++++++++++++++++++++++ src/app/cards/availability.ts | 1 + src/device/controller.ts | 54 ++++++++++++++++++++++++++++-- src/device/traits.ts | 1 + src/device/types.ts | 3 +- src/ui/device-images.ts | 3 ++ 7 files changed, 130 insertions(+), 4 deletions(-) diff --git a/src/app/cards/AdvancedCards.tsx b/src/app/cards/AdvancedCards.tsx index 13862fda..cc6614cf 100644 --- a/src/app/cards/AdvancedCards.tsx +++ b/src/app/cards/AdvancedCards.tsx @@ -291,6 +291,24 @@ export function ProcessingCard({ snapshot }: { snapshot: ControlSnapshot }): Rea ) : null} + {status.sensorMode != null && !traits.teevolution ? ( +
+ Sensor sampling mode + +
+ ) : null} +