dualsense-ts 6.1.0 → 6.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/dist/hid/node_hid_provider.d.ts +1 -0
- package/dist/hid/node_hid_provider.d.ts.map +1 -1
- package/dist/hid/node_hid_provider.js +25 -5
- package/dist/hid/node_hid_provider.js.map +1 -1
- package/package.json +1 -1
- package/src/hid/node_hid_provider.ts +50 -34
- package/webhid_example/build/asset-manifest.json +3 -3
- package/webhid_example/build/index.html +1 -1
- package/webhid_example/build/static/js/main.cc2a5794.js +3 -0
- package/webhid_example/build/static/js/main.cc2a5794.js.map +1 -0
- package/webhid_example/src/App.tsx +121 -14
- package/webhid_example/src/hud/BumperVisualization.tsx +93 -0
- package/webhid_example/src/hud/DpadVisualization.tsx +142 -0
- package/webhid_example/src/hud/FaceButtons.tsx +162 -0
- package/webhid_example/src/hud/Gyro.tsx +126 -27
- package/webhid_example/src/hud/LeftTrigger.tsx +18 -0
- package/webhid_example/src/hud/Reticle.tsx +4 -4
- package/webhid_example/src/hud/RightStick.tsx +4 -4
- package/webhid_example/src/hud/RightTrigger.tsx +18 -0
- package/webhid_example/src/hud/ShoulderVisualization.tsx +247 -0
- package/webhid_example/src/hud/StickVisualization.tsx +22 -35
- package/webhid_example/src/hud/TouchpadVisualization.tsx +132 -0
- package/webhid_example/src/hud/TriggerVisualization.tsx +99 -0
- package/webhid_example/src/hud/UtilityButtons.tsx +184 -0
- package/webhid_example/src/hud/index.tsx +9 -0
- package/webhid_example/build/static/js/main.53ce5f89.js +0 -3
- package/webhid_example/build/static/js/main.53ce5f89.js.map +0 -1
- /package/webhid_example/build/static/js/{main.53ce5f89.js.LICENSE.txt → main.cc2a5794.js.LICENSE.txt} +0 -0
package/README.md
CHANGED
|
@@ -37,13 +37,15 @@ If the device disconnects, `dualsense-ts` will quietly wait for it to come back.
|
|
|
37
37
|
|
|
38
38
|
```typescript
|
|
39
39
|
controller.connection.on("change", ({ active }) => {
|
|
40
|
-
console.log(`controller ${active ?
|
|
40
|
+
console.log(`controller ${active ? "" : "dis"}connected`);
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
-
controller.connection.active // returns true while the controller is available
|
|
44
|
-
controller.wireless // returns true while connected over bluetooth
|
|
43
|
+
controller.connection.active; // returns true while the controller is available
|
|
44
|
+
controller.wireless; // returns true while connected over bluetooth
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
When the user switches from wired to wireless or vice versa, `dualsense-ts` will reconnect to the same device seamlessly.
|
|
48
|
+
|
|
47
49
|
### Input APIs
|
|
48
50
|
|
|
49
51
|
`dualsense-ts` provides several interfaces for reading input:
|
|
@@ -361,9 +363,9 @@ If something seems wrong, use the debugger to view the report buffer. Collect a
|
|
|
361
363
|
|
|
362
364
|
## Other Dualsense Variants
|
|
363
365
|
|
|
364
|
-
The
|
|
366
|
+
The DualSense FlexStrike, DualSense Edge, and DualSense Access controllers are not yet supported. This functionality is on the roadmap.
|
|
365
367
|
|
|
366
|
-
The PS4
|
|
368
|
+
The PS4 DualShock controller is not supported.
|
|
367
369
|
|
|
368
370
|
## Multiplayer
|
|
369
371
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node_hid_provider.d.ts","sourceRoot":"","sources":["../../src/hid/node_hid_provider.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEhE,qBAAa,eAAgB,SAAQ,WAAW;IACvC,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"node_hid_provider.d.ts","sourceRoot":"","sources":["../../src/hid/node_hid_provider.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEhE,qBAAa,eAAgB,SAAQ,WAAW;IACvC,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEvB,OAAO,CAAC,UAAU,CAAS;IAErB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA8D9B,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtC,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,UAAU,IAAI,IAAI;IAQlB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB;CAY3C"}
|
|
@@ -26,11 +26,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.NodeHIDProvider = void 0;
|
|
27
27
|
const hid_provider_1 = require("./hid_provider");
|
|
28
28
|
class NodeHIDProvider extends hid_provider_1.HIDProvider {
|
|
29
|
+
constructor() {
|
|
30
|
+
super(...arguments);
|
|
31
|
+
this.connecting = false;
|
|
32
|
+
}
|
|
29
33
|
async connect() {
|
|
34
|
+
if (this.connecting)
|
|
35
|
+
return;
|
|
30
36
|
if (typeof window !== "undefined")
|
|
31
37
|
return this.onError(new Error("Attempted to use node-hid in browser environment"));
|
|
32
|
-
|
|
38
|
+
this.connecting = true;
|
|
39
|
+
let nodeHid;
|
|
40
|
+
try {
|
|
41
|
+
nodeHid = await Promise.resolve().then(() => __importStar(require("node-hid")));
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
this.connecting = false;
|
|
45
|
+
return this.onError(new Error(`Could not import 'node-hid'. Did you add it?\nError: ${err instanceof Error ? err.message : "???"}`));
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
33
48
|
this.disconnect();
|
|
49
|
+
const { HID, devices } = nodeHid;
|
|
34
50
|
const controllers = devices(hid_provider_1.HIDProvider.vendorId, hid_provider_1.HIDProvider.productId);
|
|
35
51
|
if (controllers.length === 0 || !controllers[0].path) {
|
|
36
52
|
return this.onError(new Error(`No controllers (${devices().length} other devices)`));
|
|
@@ -45,13 +61,17 @@ class NodeHIDProvider extends hid_provider_1.HIDProvider {
|
|
|
45
61
|
this.onData(this.process(arg));
|
|
46
62
|
});
|
|
47
63
|
device.on("error", (err) => {
|
|
64
|
+
this.disconnect();
|
|
48
65
|
this.onError(err);
|
|
49
66
|
});
|
|
50
67
|
this.device = device;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
this.onError(
|
|
54
|
-
}
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
this.onError(err instanceof Error ? err : new Error(String(err)));
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
this.connecting = false;
|
|
74
|
+
}
|
|
55
75
|
}
|
|
56
76
|
write(data) {
|
|
57
77
|
if (!this.device)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node_hid_provider.js","sourceRoot":"","sources":["../../src/hid/node_hid_provider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,iDAAgE;AAEhE,MAAa,eAAgB,SAAQ,0BAAW;
|
|
1
|
+
{"version":3,"file":"node_hid_provider.js","sourceRoot":"","sources":["../../src/hid/node_hid_provider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,iDAAgE;AAEhE,MAAa,eAAgB,SAAQ,0BAAW;IAAhD;;QAKU,eAAU,GAAG,KAAK,CAAC;IA8F7B,CAAC;IA5FC,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO;QAC5B,IAAI,OAAO,MAAM,KAAK,WAAW;YAC/B,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAC9D,CAAC;QAEJ,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,OAAkC,CAAC;QACvC,IAAI;YACF,OAAO,GAAG,wDAAa,UAAU,GAAC,CAAC;SACpC;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YACxB,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,KAAK,CACP,wDACE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KACvC,EAAE,CACH,CACF,CAAC;SACH;QAED,IAAI;YACF,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;YACjC,MAAM,WAAW,GAAG,OAAO,CACzB,0BAAW,CAAC,QAAQ,EACpB,0BAAW,CAAC,SAAS,CACtB,CAAC;YACF,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;gBACpD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,KAAK,CAAC,mBAAmB,OAAO,EAAE,CAAC,MAAM,iBAAiB,CAAC,CAChE,CAAC;aACH;YAED,yBAAyB;YACzB,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC;YAEhD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAE5C,uCAAuC;YACvC,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAElC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAW,EAAE,EAAE;gBAChC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;gBAClB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;gBAChC,IAAI,CAAC,UAAU,EAAE,CAAC;gBAClB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACpB,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;SACtB;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,CAAC,OAAO,CACV,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CACpD,CAAC;SACH;gBAAS;YACR,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;SACzB;IACH,CAAC;IAED,KAAK,CAAC,IAAgB;QACpB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACpC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC;IACnC,CAAC;IAED,UAAU;QACR,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;SACrB;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;IAED,OAAO,CAAC,MAAc;QACpB,MAAM,MAAM,GAAc;YACxB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,CAAC,MAAM;gBACd,OAAO,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAClC,CAAC;YACD,YAAY,CAAC,MAAM;gBACjB,OAAO,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YACrC,CAAC;SACF,CAAC;QACF,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;CACF;AAnGD,0CAmGC"}
|
package/package.json
CHANGED
|
@@ -7,52 +7,68 @@ export class NodeHIDProvider extends HIDProvider {
|
|
|
7
7
|
public wireless?: boolean;
|
|
8
8
|
public buffer?: Buffer;
|
|
9
9
|
|
|
10
|
+
private connecting = false;
|
|
11
|
+
|
|
10
12
|
async connect(): Promise<void> {
|
|
13
|
+
if (this.connecting) return;
|
|
11
14
|
if (typeof window !== "undefined")
|
|
12
15
|
return this.onError(
|
|
13
16
|
new Error("Attempted to use node-hid in browser environment")
|
|
14
17
|
);
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
this.connecting = true;
|
|
20
|
+
let nodeHid: typeof import("node-hid");
|
|
21
|
+
try {
|
|
22
|
+
nodeHid = await import("node-hid");
|
|
23
|
+
} catch (err) {
|
|
24
|
+
this.connecting = false;
|
|
25
|
+
return this.onError(
|
|
26
|
+
new Error(
|
|
27
|
+
`Could not import 'node-hid'. Did you add it?\nError: ${
|
|
28
|
+
err instanceof Error ? err.message : "???"
|
|
29
|
+
}`
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
}
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
try {
|
|
35
|
+
this.disconnect();
|
|
36
|
+
const { HID, devices } = nodeHid;
|
|
37
|
+
const controllers = devices(
|
|
38
|
+
HIDProvider.vendorId,
|
|
39
|
+
HIDProvider.productId
|
|
40
|
+
);
|
|
41
|
+
if (controllers.length === 0 || !controllers[0].path) {
|
|
42
|
+
return this.onError(
|
|
43
|
+
new Error(`No controllers (${devices().length} other devices)`)
|
|
44
|
+
);
|
|
45
|
+
}
|
|
31
46
|
|
|
32
|
-
|
|
47
|
+
// Detect connection type
|
|
48
|
+
this.wireless = controllers[0].interface === -1;
|
|
33
49
|
|
|
34
|
-
|
|
35
|
-
device.getFeatureReport(0x05, 41);
|
|
50
|
+
const device = new HID(controllers[0].path);
|
|
36
51
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this.onData(this.process(arg));
|
|
40
|
-
});
|
|
41
|
-
device.on("error", (err: Error) => {
|
|
42
|
-
this.onError(err);
|
|
43
|
-
});
|
|
52
|
+
// Enable accelerometer, gyro, touchpad
|
|
53
|
+
device.getFeatureReport(0x05, 41);
|
|
44
54
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}`
|
|
53
|
-
)
|
|
54
|
-
);
|
|
55
|
+
device.on("data", (arg: Buffer) => {
|
|
56
|
+
this.buffer = arg;
|
|
57
|
+
this.onData(this.process(arg));
|
|
58
|
+
});
|
|
59
|
+
device.on("error", (err: Error) => {
|
|
60
|
+
this.disconnect();
|
|
61
|
+
this.onError(err);
|
|
55
62
|
});
|
|
63
|
+
|
|
64
|
+
this.device = device;
|
|
65
|
+
} catch (err) {
|
|
66
|
+
this.onError(
|
|
67
|
+
err instanceof Error ? err : new Error(String(err))
|
|
68
|
+
);
|
|
69
|
+
} finally {
|
|
70
|
+
this.connecting = false;
|
|
71
|
+
}
|
|
56
72
|
}
|
|
57
73
|
|
|
58
74
|
write(data: Uint8Array): Promise<void> {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"files": {
|
|
3
3
|
"main.css": "/dualsense-ts/static/css/main.9393bbb9.css",
|
|
4
|
-
"main.js": "/dualsense-ts/static/js/main.
|
|
4
|
+
"main.js": "/dualsense-ts/static/js/main.cc2a5794.js",
|
|
5
5
|
"blueprint-icons-all-paths-loader.js": "/dualsense-ts/static/js/blueprint-icons-all-paths-loader.53883a20.chunk.js",
|
|
6
6
|
"blueprint-icons-split-paths-by-size-loader.js": "/dualsense-ts/static/js/blueprint-icons-split-paths-by-size-loader.6d8a31ce.chunk.js",
|
|
7
7
|
"static/js/787.b12b0301.chunk.js": "/dualsense-ts/static/js/787.b12b0301.chunk.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"static/media/blueprint-icons-16.woff2?": "/dualsense-ts/static/media/blueprint-icons-16.582f87288ff1d1f0dfae.woff2",
|
|
19
19
|
"index.html": "/dualsense-ts/index.html",
|
|
20
20
|
"main.9393bbb9.css.map": "/dualsense-ts/static/css/main.9393bbb9.css.map",
|
|
21
|
-
"main.
|
|
21
|
+
"main.cc2a5794.js.map": "/dualsense-ts/static/js/main.cc2a5794.js.map",
|
|
22
22
|
"blueprint-icons-all-paths-loader.53883a20.chunk.js.map": "/dualsense-ts/static/js/blueprint-icons-all-paths-loader.53883a20.chunk.js.map",
|
|
23
23
|
"blueprint-icons-split-paths-by-size-loader.6d8a31ce.chunk.js.map": "/dualsense-ts/static/js/blueprint-icons-split-paths-by-size-loader.6d8a31ce.chunk.js.map",
|
|
24
24
|
"787.b12b0301.chunk.js.map": "/dualsense-ts/static/js/787.b12b0301.chunk.js.map",
|
|
@@ -28,6 +28,6 @@
|
|
|
28
28
|
},
|
|
29
29
|
"entrypoints": [
|
|
30
30
|
"static/css/main.9393bbb9.css",
|
|
31
|
-
"static/js/main.
|
|
31
|
+
"static/js/main.cc2a5794.js"
|
|
32
32
|
]
|
|
33
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/dualsense-ts/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/dualsense-ts/manifest.json"/><script type="text/javascript">!function(n){if("/"===n.search[1]){var a=n.search.slice(1).split("&").map((function(n){return n.replace(/~and~/g,"&")})).join("?");window.history.replaceState(null,null,n.pathname.slice(0,-1)+a+n.hash)}}(window.location)</script><title>dualsense-ts</title><script defer="defer" src="/dualsense-ts/static/js/main.
|
|
1
|
+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/dualsense-ts/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/dualsense-ts/manifest.json"/><script type="text/javascript">!function(n){if("/"===n.search[1]){var a=n.search.slice(1).split("&").map((function(n){return n.replace(/~and~/g,"&")})).join("?");window.history.replaceState(null,null,n.pathname.slice(0,-1)+a+n.hash)}}(window.location)</script><title>dualsense-ts</title><script defer="defer" src="/dualsense-ts/static/js/main.cc2a5794.js"></script><link href="/dualsense-ts/static/css/main.9393bbb9.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|