From 4c129b22f009697c38fc8c96f4c6ca5a209e3855 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 5 Aug 2026 19:07:58 +1000 Subject: [PATCH] added vendor ids for v2 pro --- src/devices/razer/TESTING.md | 2 ++ src/devices/razer/hid.ts | 8 +++++++- src/devices/vendors.ts | 11 ++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/devices/razer/TESTING.md b/src/devices/razer/TESTING.md index dab27605..59b8c7c7 100644 --- a/src/devices/razer/TESTING.md +++ b/src/devices/razer/TESTING.md @@ -5,6 +5,8 @@ control interface open and reads then time out. Supported identifiers: +- `1532:00a5` — Viper V2 Pro, wired +- `1532:00a6` — Viper V2 Pro, Stock receiver - `1532:00c0` — Viper V3 Pro, wired - `1532:00c1` — Viper V3 Pro, HyperSpeed receiver diff --git a/src/devices/razer/hid.ts b/src/devices/razer/hid.ts index ee9b9456..82543259 100644 --- a/src/devices/razer/hid.ts +++ b/src/devices/razer/hid.ts @@ -24,6 +24,8 @@ interface RazerProduct { model: string; wireless: boolean; pollingRates: readonly number[]; + // Defaults to DPI_MAX when omitted + maxDpi?: number; } // The cable tops out at 1000 Hz on this model, which is also the ceiling the @@ -32,6 +34,10 @@ const RATES_WIRED: readonly number[] = [125, 500, 1000]; const RATES_RECEIVER: readonly number[] = [125, 500, 1000, 2000, 4000, 8000]; const PRODUCTS: ReadonlyMap = new Map([ + // Stock receiver, not 8K HyperPolling. + [0x00a5, { model: "Viper V2 Pro", wireless: false, pollingRates: RATES_WIRED, maxDpi: 30000 }], + [0x00a6, { model: "Viper V2 Pro", wireless: true, pollingRates: RATES_WIRED, maxDpi: 30000 }], + [0x00c0, { model: "Viper V3 Pro", wireless: false, pollingRates: RATES_WIRED }], [0x00c1, { model: "Viper V3 Pro", wireless: true, pollingRates: RATES_RECEIVER }], ]); @@ -88,7 +94,7 @@ export class RazerHidClient { } maxDpi(): number { - return DPI_MAX; + return this.profile()?.maxDpi ?? DPI_MAX; } getSupportedPollingRates(): number[] { diff --git a/src/devices/vendors.ts b/src/devices/vendors.ts index d43c8162..56095aec 100644 --- a/src/devices/vendors.ts +++ b/src/devices/vendors.ts @@ -14,10 +14,14 @@ export const VENDOR_ID = { atk: 0x373b, } as const; -// Viper V3 Pro exposes its control channel as a Generic Desktop Mouse -// collection. Limit this broad collection filter to its two known PIDs so it -// cannot also surface unrelated Razer keyboards or the Viper V4 Pro's ordinary +// Viper V2/V3 Pro expose their control channel as a Generic Desktop Mouse +// collection. Limit this broad collection filter to known PIDs so it cannot +// also surface unrelated Razer keyboards or the Viper V4 Pro's ordinary // boot-mouse interfaces. +export const RAZER_VIPER_V2_CONTROL_FILTERS: HIDDeviceFilter[] = [0x00a5, 0x00a6].map( + (productId) => ({ vendorId: VENDOR_ID.razer, productId, usagePage: 0x01, usage: 0x02 }), +); + export const RAZER_VIPER_V3_CONTROL_FILTERS: HIDDeviceFilter[] = [0x00c0, 0x00c1].map( (productId) => ({ vendorId: VENDOR_ID.razer, productId, usagePage: 0x01, usage: 0x02 }), ); @@ -89,6 +93,7 @@ export const SUPPORTED_HID_FILTERS: HIDDeviceFilter[] = [ { vendorId: VENDOR_ID.lamzu }, { vendorId: VENDOR_ID.orbital, usagePage: 0xff0a, usage: 1 }, ...TEEVOLUTION_PRODUCT_IDS.map((productId) => ({ vendorId: VENDOR_ID.teevolution, productId })), + ...RAZER_VIPER_V2_CONTROL_FILTERS, ...RAZER_VIPER_V3_CONTROL_FILTERS, { vendorId: VENDOR_ID.vgn, productId: 0xfb56 }, { vendorId: VENDOR_ID.vgn, productId: 0xfb57 },