Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/drivers/gearhub/hid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,20 @@ describe("GearHubHidClient", () => {
assert.equal(client.getDpiOptions().at(-1), 26000, "PAW3395 DPI ceiling");
});

it("identifies the Attack Shark X3 Pro (device id 1660, PAW3395)", async () => {
const { device } = fakeReceiver({
deviceId: 1660,
replies: {
[CMD.GET_DPI]: dpiReply([1800, 26000], 1),
[CMD.GET_OPTIONPARAM0]: opt0Reply({ rate: 129, lod: 0 }),
},
});
const status = await new GearHubHidClient(device).readStatus();

assert.equal(status.name, "Attack Shark X3 Pro");
assert.ok(status.firmware.includes("PixArt PAW3395"));
});

it("maps the PAW3950 R3 revision (device id 3310) to the 42000 DPI profile", async () => {
const { device } = fakeReceiver({
deviceId: 3310,
Expand Down
2 changes: 1 addition & 1 deletion src/gearhub/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ it("keeps AJ179 model quirks in its profile without changing sibling button layo
assert.equal(AJAZZ_AJ179_PRO_PROFILE.buttons?.find((button) => button.name === "Forward")?.slot, 3);
assert.equal(AJAZZ_AJ179_PRO_PROFILE.dpiStageCountIsCapacity, true);
assert.equal(AJAZZ_AJ179_PRO_PROFILE.batteryPercentageOnly, true);
for (const id of [2285, 1893, 1643, 3310, 0]) {
for (const id of [2285, 1893, 1643, 3310, 1660, 0]) {
const profile = gearHubProfileFor(id);
assert.equal(profile.buttons, undefined);
assert.equal(profile.dpiStageCountIsCapacity, undefined);
Expand Down
19 changes: 19 additions & 0 deletions src/gearhub/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,24 @@ export const ATTACK_SHARK_R3_3950_PROFILE: GearHubProfile = {
maxDpi: 42000,
};

/**
* Attack Shark X3 Pro. Same GearHub-V5 platform, VID:PID and block protocol as
* the R2 / R3. Device id 1660 (0x067C) confirmed from a user diagnostic on
* 0x3151:0x402D (2.4 GHz receiver) - firmware v3.00, six-stage DPI table,
* polling up to 8000 Hz, every relay read answering. The PAW3395 sensor and
* its 26000 DPI ceiling are from the vendor spec, not read from the device.
*/
export const ATTACK_SHARK_X3_PRO_PROFILE: GearHubProfile = {
deviceId: 1660,
brand: "Attack Shark",
model: "X3 Pro",
sensor: "PixArt PAW3395",
maxPollingHz: 8000,
minDpi: 50,
maxDpi: 26000,
dpiStep: 50,
};

/** AJ179 PRO, device id 1851. Verified on receiver, USB cable and Bluetooth.
* Vendor AJAZZ Driver (R) also maps id 1851 to its PAW3395 AJ179 PRO profile.
* See docs/ajazz-aj179-pro.md for measured capabilities and limitations. */
Expand Down Expand Up @@ -379,6 +397,7 @@ export const GEARHUB_DEVICE_PROFILES: ReadonlyMap<number, GearHubProfile> = new
[3485, ATTACK_SHARK_R3_PROFILE],
[ATTACK_SHARK_R3_3950_PROFILE.deviceId, ATTACK_SHARK_R3_3950_PROFILE],
[3310, ATTACK_SHARK_R3_3950_PROFILE],
[ATTACK_SHARK_X3_PRO_PROFILE.deviceId, ATTACK_SHARK_X3_PRO_PROFILE],
]);

/**
Expand Down
Loading