dualsense-ts 5.5.0 → 6.0.0

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.
Files changed (72) hide show
  1. package/MIGRATION_GUIDE.md +19 -0
  2. package/README.md +68 -3
  3. package/dist/dualsense.d.ts +4 -0
  4. package/dist/dualsense.d.ts.map +1 -1
  5. package/dist/dualsense.js +47 -9
  6. package/dist/dualsense.js.map +1 -1
  7. package/dist/elements/index.d.ts +1 -0
  8. package/dist/elements/index.d.ts.map +1 -1
  9. package/dist/elements/index.js +1 -0
  10. package/dist/elements/index.js.map +1 -1
  11. package/dist/elements/trigger.d.ts +3 -0
  12. package/dist/elements/trigger.d.ts.map +1 -1
  13. package/dist/elements/trigger.js +3 -0
  14. package/dist/elements/trigger.js.map +1 -1
  15. package/dist/elements/trigger_feedback.d.ts +109 -0
  16. package/dist/elements/trigger_feedback.d.ts.map +1 -0
  17. package/dist/elements/trigger_feedback.js +168 -0
  18. package/dist/elements/trigger_feedback.js.map +1 -0
  19. package/dist/hid/bt_checksum.d.ts +2 -0
  20. package/dist/hid/bt_checksum.d.ts.map +1 -0
  21. package/dist/hid/bt_checksum.js +60 -0
  22. package/dist/hid/bt_checksum.js.map +1 -0
  23. package/dist/hid/command.d.ts +8 -18
  24. package/dist/hid/command.d.ts.map +1 -1
  25. package/dist/hid/dualsense_hid.d.ts +6 -5
  26. package/dist/hid/dualsense_hid.d.ts.map +1 -1
  27. package/dist/hid/dualsense_hid.js +38 -20
  28. package/dist/hid/dualsense_hid.js.map +1 -1
  29. package/dist/hid/hid_provider.d.ts +1 -0
  30. package/dist/hid/hid_provider.d.ts.map +1 -1
  31. package/dist/hid/index.d.ts +1 -0
  32. package/dist/hid/index.d.ts.map +1 -1
  33. package/dist/hid/index.js +1 -0
  34. package/dist/hid/index.js.map +1 -1
  35. package/dist/hid/node_hid_provider.d.ts +1 -0
  36. package/dist/hid/node_hid_provider.d.ts.map +1 -1
  37. package/dist/hid/web_hid_provider.d.ts.map +1 -1
  38. package/dist/hid/web_hid_provider.js +3 -1
  39. package/dist/hid/web_hid_provider.js.map +1 -1
  40. package/nodehid_example/debug.ts +122 -39
  41. package/package.json +5 -5
  42. package/src/dualsense.ts +55 -12
  43. package/src/elements/index.ts +1 -0
  44. package/src/elements/trigger.ts +4 -0
  45. package/src/elements/trigger_feedback.ts +267 -0
  46. package/src/hid/bt_checksum.spec.ts +15 -0
  47. package/src/hid/bt_checksum.ts +58 -0
  48. package/src/hid/command.ts +24 -34
  49. package/src/hid/dualsense_hid.ts +54 -23
  50. package/src/hid/index.ts +1 -0
  51. package/src/hid/web_hid_provider.ts +3 -1
  52. package/webhid_example/build/asset-manifest.json +6 -6
  53. package/webhid_example/build/index.html +1 -1
  54. package/webhid_example/build/static/css/{main.237f8cfa.css → main.9393bbb9.css} +2 -2
  55. package/webhid_example/build/static/css/main.9393bbb9.css.map +1 -0
  56. package/webhid_example/build/static/js/main.d804191f.js +3 -0
  57. package/webhid_example/build/static/js/main.d804191f.js.map +1 -0
  58. package/webhid_example/src/App.tsx +59 -18
  59. package/webhid_example/src/hud/ControllerConnection.tsx +59 -57
  60. package/webhid_example/src/hud/Debugger.tsx +83 -79
  61. package/webhid_example/src/hud/Gyro.tsx +48 -53
  62. package/webhid_example/src/hud/HUDLayout.tsx +2 -10
  63. package/webhid_example/src/hud/Reticle.tsx +12 -62
  64. package/webhid_example/src/hud/RightStick.tsx +26 -0
  65. package/webhid_example/src/hud/StickVisualization.tsx +81 -0
  66. package/webhid_example/src/hud/TriggerEffectControls.tsx +417 -0
  67. package/webhid_example/src/hud/index.tsx +3 -0
  68. package/webhid_example/src/index.css +20 -1
  69. package/webhid_example/build/static/css/main.237f8cfa.css.map +0 -1
  70. package/webhid_example/build/static/js/main.0432376e.js +0 -3
  71. package/webhid_example/build/static/js/main.0432376e.js.map +0 -1
  72. /package/webhid_example/build/static/js/{main.0432376e.js.LICENSE.txt → main.d804191f.js.LICENSE.txt} +0 -0
@@ -1,5 +1,24 @@
1
1
  # Migration Guide
2
2
 
3
+ ### v5 to v6
4
+
5
+ `TriggerMode` is deprecated. The low-level `DualsenseHID` methods for setting trigger effects now accept 11-byte effect blocks instead of individual mode/value pairs.
6
+
7
+ Use the new element-based API instead:
8
+
9
+ ```typescript
10
+ import { TriggerEffect } from "dualsense-ts";
11
+
12
+ controller.right.trigger.feedback.set({
13
+ effect: TriggerEffect.Weapon,
14
+ start: 0.2,
15
+ end: 0.6,
16
+ strength: 0.9,
17
+ });
18
+
19
+ controller.right.trigger.feedback.reset();
20
+ ```
21
+
3
22
  ### v4 to v5
4
23
 
5
24
  `node-hid` is now an optional peer dependency, simplifying the use of this library in the browser.
package/README.md CHANGED
@@ -2,11 +2,13 @@
2
2
 
3
3
  This module provides a natural interface for your DualSense controller.
4
4
 
5
+ **[Try it in your browser](https://nsfm.github.io/dualsense-ts/)** — connect a DualSense controller and explore inputs, rumble, and adaptive trigger effects with the interactive demo.
6
+
5
7
  ## Getting started
6
8
 
7
9
  ### Installation
8
10
 
9
- [This package is distributed via npm](https://npmjs.org/package.dualsense-ts). Install it the usual way:
11
+ [This package is distributed via npm](https://www.npmjs.com/package/dualsense-ts). Install it the usual way:
10
12
 
11
13
  - `npm add dualsense-ts`
12
14
 
@@ -37,6 +39,8 @@ controller.connection.on("change", ({ active }) = > {
37
39
  });
38
40
  ```
39
41
 
42
+ This package supports both wired and Bluetooth devices. While connected via Bluetooth, `controller.wireless` will return `true`.
43
+
40
44
  ### Input APIs
41
45
 
42
46
  `dualsense-ts` provides several interfaces for reading input:
@@ -60,7 +64,7 @@ controller.left.analog.magnitude; // 0.23, 0 to 1
60
64
 
61
65
  // Touchpad - each touch point works like an analog input
62
66
  controller.touchpad.right.contact.state; // false
63
- +controller.touchpad.right.x; // -0.44, -1 to 1
67
+ controller.touchpad.right.x; // -0.44, -1 to 1
64
68
  ```
65
69
 
66
70
  - _Callbacks_: Each input is an EventEmitter or EventTarget that provides `input`, `press`, `release`, and `change` events
@@ -130,7 +134,7 @@ controller.accelerometer.z.on("change", ({ force }) => {
130
134
 
131
135
  #### Rumble
132
136
 
133
- Only supported in node.js over USB at this time.
137
+ The controller has two independent rumble motors. The left motor is larger and produces a stronger, lower-frequency rumble, while the right motor is smaller and produces a lighter, higher-frequency vibration. They are controlled independently:
134
138
 
135
139
  ```typescript
136
140
  controller.rumble(1.0); // 100% rumble intensity
@@ -148,6 +152,67 @@ controller.right.trigger.on("change", (trigger) => {
148
152
  });
149
153
  ```
150
154
 
155
+ #### Adaptive Triggers
156
+
157
+ Haptic trigger feedback is controlled via `controller.left.trigger.feedback` / `controller.right.trigger.feedback`. All position and strength values are normalized 0–1.
158
+
159
+ ```typescript
160
+ import { Dualsense, TriggerEffect } from "dualsense-ts";
161
+
162
+ const controller = new Dualsense();
163
+
164
+ // Continuous resistance starting at 30% travel
165
+ controller.right.trigger.feedback.set({
166
+ effect: TriggerEffect.Feedback,
167
+ position: 0.3,
168
+ strength: 0.8,
169
+ });
170
+
171
+ // Weapon trigger — resistance with snap release
172
+ controller.right.trigger.feedback.set({
173
+ effect: TriggerEffect.Weapon,
174
+ start: 0.2,
175
+ end: 0.6,
176
+ strength: 0.9,
177
+ });
178
+
179
+ // Vibration with frequency
180
+ controller.right.trigger.feedback.set({
181
+ effect: TriggerEffect.Vibration,
182
+ position: 0.1,
183
+ amplitude: 0.7,
184
+ frequency: 40, // in Hz, 0 - 255
185
+ });
186
+
187
+ // Reset to default linear feel
188
+ controller.right.trigger.feedback.reset();
189
+
190
+ // Reset both triggers
191
+ controller.resetTriggerFeedback();
192
+
193
+ // Read current config
194
+ console.log(controller.right.trigger.feedback.config);
195
+ console.log(controller.right.trigger.feedback.effect); // TriggerEffect.Off
196
+ ```
197
+
198
+ Feedback state is automatically restored if the controller disconnects and reconnects — no handling required on your end.
199
+
200
+ #### Trigger effects
201
+
202
+ | Effect | Description |
203
+ | ------------------------- | ---------------------------------------------------------- |
204
+ | `TriggerEffect.Off` | No resistance (default linear feel) |
205
+ | `TriggerEffect.Feedback` | Zone-based continuous resistance from a start position |
206
+ | `TriggerEffect.Weapon` | Resistance with a snap release point |
207
+ | `TriggerEffect.Bow` | Weapon feel with snap-back force |
208
+ | `TriggerEffect.Galloping` | Rhythmic two-stroke oscillation |
209
+ | `TriggerEffect.Vibration` | Zone-based oscillation with amplitude and frequency |
210
+ | `TriggerEffect.Machine` | Dual-amplitude vibration with frequency and period control |
211
+
212
+ Each effect accepts a unique set of configuration options — your editor's type hints will guide you through the available parameters for each effect. The [interactive demo](https://nsfm.github.io/dualsense-ts/) includes full slider controls for every effect and parameter, making it a great tool for finding the right values.
213
+
214
+ Effect names are based on [Nielk1's DualSense trigger effect documentation](https://gist.github.com/Nielk1/6d54cc2c00d2201ccb8c2720ad7538db).
215
+
151
216
  ### With React
152
217
 
153
218
  Check out [the example app](./webhid_example/) for more details.
@@ -71,8 +71,12 @@ export declare class Dualsense extends Input<Dualsense> {
71
71
  /** A virtual button representing whether or not a controller is connected */
72
72
  readonly connection: Momentary;
73
73
  get active(): boolean;
74
+ /** Returns `true` if the controller is connected via Bluetooth */
75
+ get wireless(): boolean;
74
76
  constructor(params?: DualsenseParams);
75
77
  private get rumbleIntensity();
78
+ /** Reset adaptive trigger feedback on both sides to the default linear feel */
79
+ resetTriggerFeedback(): void;
76
80
  /** Check or adjust rumble intensity evenly across both sides of the controller */
77
81
  rumble(intensity?: Intensity): number;
78
82
  /** Distributes HID event values to the controller's inputs */
@@ -1 +1 @@
1
- {"version":3,"file":"dualsense.d.ts","sourceRoot":"","sources":["../src/dualsense.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,IAAI,EACJ,UAAU,EACV,IAAI,EACJ,QAAQ,EACR,cAAc,EACd,QAAQ,EACR,SAAS,EACT,eAAe,EACf,aAAa,EACb,mBAAmB,EACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,EAAY,WAAW,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,EAEL,YAAY,EAGb,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnC,oEAAoE;AACpE,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,oEAAoE;IACpE,GAAG,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC1B,0CAA0C;IAC1C,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,mCAAmC;IACnC,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,sCAAsC;IACtC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,qCAAqC;IACrC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,qCAAqC;IACrC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,oCAAoC;IACpC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,qCAAqC;IACrC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,oCAAoC;IACpC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,iCAAiC;IACjC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,qCAAqC;IACrC,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC;AAED,wCAAwC;AACxC,qBAAa,SAAU,SAAQ,KAAK,CAAC,SAAS,CAAC;IAC7C,SAAgB,KAAK,EAAE,SAAS,CAAQ;IAExC,6BAA6B;IAC7B,SAAgB,EAAE,EAAE,SAAS,CAAC;IAC9B,uCAAuC;IACvC,SAAgB,IAAI,EAAE,IAAI,CAAC;IAC3B,yBAAyB;IACzB,SAAgB,OAAO,EAAE,SAAS,CAAC;IACnC,wBAAwB;IACxB,SAAgB,MAAM,EAAE,SAAS,CAAC;IAClC,0BAA0B;IAC1B,SAAgB,QAAQ,EAAE,SAAS,CAAC;IACpC,wBAAwB;IACxB,SAAgB,MAAM,EAAE,SAAS,CAAC;IAClC,6BAA6B;IAC7B,SAAgB,KAAK,EAAE,SAAS,CAAC;IACjC,wBAAwB;IACxB,SAAgB,MAAM,EAAE,SAAS,CAAC;IAClC,0CAA0C;IAC1C,SAAgB,IAAI,EAAE,IAAI,CAAC;IAC3B,gDAAgD;IAChD,SAAgB,IAAI,EAAE,QAAQ,CAAC;IAC/B,iDAAiD;IACjD,SAAgB,KAAK,EAAE,QAAQ,CAAC;IAChC,uDAAuD;IACvD,SAAgB,QAAQ,EAAE,QAAQ,CAAC;IACnC,+CAA+C;IAC/C,SAAgB,SAAS,EAAE,SAAS,CAAC;IACrC,kDAAkD;IAClD,SAAgB,aAAa,EAAE,aAAa,CAAC;IAE7C,kEAAkE;IAClE,SAAgB,GAAG,EAAE,YAAY,CAAC;IAElC,6EAA6E;IAC7E,SAAgB,UAAU,EAAE,SAAS,CAAC;IAEtC,IAAW,MAAM,IAAI,OAAO,CAI3B;gBAEW,MAAM,GAAE,eAAoB;IAiHxC,OAAO,KAAK,eAAe,GAE1B;IAED,kFAAkF;IAC3E,MAAM,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,MAAM;IAM5C,8DAA8D;IAC9D,OAAO,CAAC,UAAU;CAiDnB"}
1
+ {"version":3,"file":"dualsense.d.ts","sourceRoot":"","sources":["../src/dualsense.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,IAAI,EACJ,UAAU,EACV,IAAI,EACJ,QAAQ,EACR,cAAc,EACd,QAAQ,EACR,SAAS,EACT,eAAe,EACf,aAAa,EACb,mBAAmB,EACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,EAAY,WAAW,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,EAEL,YAAY,EAGb,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnC,oEAAoE;AACpE,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,oEAAoE;IACpE,GAAG,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC1B,0CAA0C;IAC1C,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,mCAAmC;IACnC,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,sCAAsC;IACtC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,qCAAqC;IACrC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,qCAAqC;IACrC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,oCAAoC;IACpC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,qCAAqC;IACrC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,oCAAoC;IACpC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,iCAAiC;IACjC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,qCAAqC;IACrC,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC;AAED,wCAAwC;AACxC,qBAAa,SAAU,SAAQ,KAAK,CAAC,SAAS,CAAC;IAC7C,SAAgB,KAAK,EAAE,SAAS,CAAQ;IAExC,6BAA6B;IAC7B,SAAgB,EAAE,EAAE,SAAS,CAAC;IAC9B,uCAAuC;IACvC,SAAgB,IAAI,EAAE,IAAI,CAAC;IAC3B,yBAAyB;IACzB,SAAgB,OAAO,EAAE,SAAS,CAAC;IACnC,wBAAwB;IACxB,SAAgB,MAAM,EAAE,SAAS,CAAC;IAClC,0BAA0B;IAC1B,SAAgB,QAAQ,EAAE,SAAS,CAAC;IACpC,wBAAwB;IACxB,SAAgB,MAAM,EAAE,SAAS,CAAC;IAClC,6BAA6B;IAC7B,SAAgB,KAAK,EAAE,SAAS,CAAC;IACjC,wBAAwB;IACxB,SAAgB,MAAM,EAAE,SAAS,CAAC;IAClC,0CAA0C;IAC1C,SAAgB,IAAI,EAAE,IAAI,CAAC;IAC3B,gDAAgD;IAChD,SAAgB,IAAI,EAAE,QAAQ,CAAC;IAC/B,iDAAiD;IACjD,SAAgB,KAAK,EAAE,QAAQ,CAAC;IAChC,uDAAuD;IACvD,SAAgB,QAAQ,EAAE,QAAQ,CAAC;IACnC,+CAA+C;IAC/C,SAAgB,SAAS,EAAE,SAAS,CAAC;IACrC,kDAAkD;IAClD,SAAgB,aAAa,EAAE,aAAa,CAAC;IAE7C,kEAAkE;IAClE,SAAgB,GAAG,EAAE,YAAY,CAAC;IAElC,6EAA6E;IAC7E,SAAgB,UAAU,EAAE,SAAS,CAAC;IAEtC,IAAW,MAAM,IAAI,OAAO,CAI3B;IAED,kEAAkE;IAClE,IAAW,QAAQ,IAAI,OAAO,CAE7B;gBAEW,MAAM,GAAE,eAAoB;IAiJxC,OAAO,KAAK,eAAe,GAE1B;IAED,+EAA+E;IACxE,oBAAoB,IAAI,IAAI;IAKnC,kFAAkF;IAC3E,MAAM,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,MAAM;IAM5C,8DAA8D;IAC9D,OAAO,CAAC,UAAU;CAiDnB"}
package/dist/dualsense.js CHANGED
@@ -9,6 +9,10 @@ class Dualsense extends input_1.Input {
9
9
  get active() {
10
10
  return Object.values(this).some((input) => input !== this && input instanceof input_1.Input && input.active);
11
11
  }
12
+ /** Returns `true` if the controller is connected via Bluetooth */
13
+ get wireless() {
14
+ return this.hid.wireless;
15
+ }
12
16
  constructor(params = {}) {
13
17
  super(params);
14
18
  this.state = this;
@@ -94,29 +98,63 @@ class Dualsense extends input_1.Input {
94
98
  this.hid.register((state) => {
95
99
  this.processHID(state);
96
100
  });
101
+ const rumbleMemo = { left: -1, right: -1 };
102
+ const triggerFeedbackMemo = { left: "", right: "" };
97
103
  /** Refresh connection state */
104
+ let lastConnected = false;
98
105
  setInterval(() => {
99
106
  const { provider: { connected }, } = this.hid;
100
107
  this.connection[input_1.InputSet](connected);
108
+ if (connected && !lastConnected) {
109
+ // Invalidate memo so the output loop restores desired state on reconnect.
110
+ triggerFeedbackMemo.left = "";
111
+ triggerFeedbackMemo.right = "";
112
+ }
113
+ lastConnected = connected;
101
114
  if (!connected)
102
115
  this.hid.provider.connect();
103
116
  }, 200);
104
- /** Refresh rumble state */
105
- const rumbleMemo = { left: -1, right: -1 };
117
+ /** Refresh output state (rumble + trigger feedback) */
106
118
  setInterval(() => {
107
- const left = this.left.rumble();
108
- const right = this.right.rumble();
109
- if (this.connection.active &&
110
- (left !== rumbleMemo.left || right !== rumbleMemo.right)) {
111
- this.hid.setRumble(left * 255, right * 255);
112
- rumbleMemo.left = left;
113
- rumbleMemo.right = right;
119
+ if (!this.connection.active)
120
+ return;
121
+ const leftRumble = this.left.rumble();
122
+ const rightRumble = this.right.rumble();
123
+ if (leftRumble !== rumbleMemo.left || rightRumble !== rumbleMemo.right) {
124
+ this.hid.setRumble(leftRumble * 255, rightRumble * 255);
125
+ rumbleMemo.left = leftRumble;
126
+ rumbleMemo.right = rightRumble;
127
+ }
128
+ const leftFeedback = this.left.trigger.feedback;
129
+ const rightFeedback = this.right.trigger.feedback;
130
+ const leftKey = leftFeedback.toKey();
131
+ const rightKey = rightFeedback.toKey();
132
+ const feedbackChanged = leftKey !== triggerFeedbackMemo.left ||
133
+ rightKey !== triggerFeedbackMemo.right;
134
+ if (feedbackChanged) {
135
+ // Force rumble into the same batch so MotorPower scope bit is always present.
136
+ this.hid.setRumble(leftRumble * 255, rightRumble * 255);
137
+ rumbleMemo.left = leftRumble;
138
+ rumbleMemo.right = rightRumble;
139
+ }
140
+ if (leftKey !== triggerFeedbackMemo.left) {
141
+ this.hid.setLeftTriggerFeedback(leftFeedback.toBytes());
142
+ triggerFeedbackMemo.left = leftKey;
143
+ }
144
+ if (rightKey !== triggerFeedbackMemo.right) {
145
+ this.hid.setRightTriggerFeedback(rightFeedback.toBytes());
146
+ triggerFeedbackMemo.right = rightKey;
114
147
  }
115
148
  }, 1000 / 30);
116
149
  }
117
150
  get rumbleIntensity() {
118
151
  return (this.left.rumble() + this.right.rumble()) / 2;
119
152
  }
153
+ /** Reset adaptive trigger feedback on both sides to the default linear feel */
154
+ resetTriggerFeedback() {
155
+ this.left.trigger.feedback.reset();
156
+ this.right.trigger.feedback.reset();
157
+ }
120
158
  /** Check or adjust rumble intensity evenly across both sides of the controller */
121
159
  rumble(intensity) {
122
160
  this.left.rumble(intensity);
@@ -1 +1 @@
1
- {"version":3,"file":"dualsense.js","sourceRoot":"","sources":["../src/dualsense.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dualsense.js","sourceRoot":"","sources":["../src/dualsense.ts"],"names":[],"mappings":"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"}
@@ -13,5 +13,6 @@ export * from "./mute";
13
13
  export * from "./touch";
14
14
  export * from "./touchpad";
15
15
  export * from "./trigger";
16
+ export * from "./trigger_feedback";
16
17
  export * from "./unisense";
17
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/elements/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/elements/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC"}
@@ -29,5 +29,6 @@ __exportStar(require("./mute"), exports);
29
29
  __exportStar(require("./touch"), exports);
30
30
  __exportStar(require("./touchpad"), exports);
31
31
  __exportStar(require("./trigger"), exports);
32
+ __exportStar(require("./trigger_feedback"), exports);
32
33
  __exportStar(require("./unisense"), exports);
33
34
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/elements/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,kDAAgC;AAChC,2CAAyB;AACzB,yCAAuB;AACvB,yCAAuB;AACvB,8CAA4B;AAC5B,8CAA4B;AAC5B,8CAA4B;AAC5B,2CAAyB;AACzB,yCAAuB;AACvB,0CAAwB;AACxB,6CAA2B;AAC3B,4CAA0B;AAC1B,6CAA2B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/elements/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,kDAAgC;AAChC,2CAAyB;AACzB,yCAAuB;AACvB,yCAAuB;AACvB,8CAA4B;AAC5B,8CAA4B;AAC5B,8CAA4B;AAC5B,2CAAyB;AACzB,yCAAuB;AACvB,0CAAwB;AACxB,6CAA2B;AAC3B,4CAA0B;AAC1B,qDAAmC;AACnC,6CAA2B"}
@@ -1,9 +1,12 @@
1
1
  import { Input } from "../input";
2
2
  import { Magnitude } from "../math";
3
3
  import { Momentary } from "./momentary";
4
+ import { TriggerFeedback } from "./trigger_feedback";
4
5
  export declare class Trigger extends Input<Magnitude> {
5
6
  state: Magnitude;
6
7
  button: Momentary;
8
+ /** Desired adaptive trigger feedback state */
9
+ readonly feedback: TriggerFeedback;
7
10
  get active(): boolean;
8
11
  get pressure(): Magnitude;
9
12
  get magnitude(): Magnitude;
@@ -1 +1 @@
1
- {"version":3,"file":"trigger.d.ts","sourceRoot":"","sources":["../../src/elements/trigger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,qBAAa,OAAQ,SAAQ,KAAK,CAAC,SAAS,CAAC;IACpC,KAAK,EAAE,SAAS,CAAK;IAErB,MAAM,EAAE,SAAS,CAAmB;IAE3C,IAAW,MAAM,IAAI,OAAO,CAE3B;IAED,IAAW,QAAQ,IAAI,SAAS,CAE/B;IAED,IAAW,SAAS,IAAI,SAAS,CAEhC;IAEM,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO;CAG1C"}
1
+ {"version":3,"file":"trigger.d.ts","sourceRoot":"","sources":["../../src/elements/trigger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,qBAAa,OAAQ,SAAQ,KAAK,CAAC,SAAS,CAAC;IACpC,KAAK,EAAE,SAAS,CAAK;IAErB,MAAM,EAAE,SAAS,CAAmB;IAE3C,8CAA8C;IAC9C,SAAgB,QAAQ,kBAAyB;IAEjD,IAAW,MAAM,IAAI,OAAO,CAE3B;IAED,IAAW,QAAQ,IAAI,SAAS,CAE/B;IAED,IAAW,SAAS,IAAI,SAAS,CAEhC;IAEM,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO;CAG1C"}
@@ -3,11 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Trigger = void 0;
4
4
  const input_1 = require("../input");
5
5
  const momentary_1 = require("./momentary");
6
+ const trigger_feedback_1 = require("./trigger_feedback");
6
7
  class Trigger extends input_1.Input {
7
8
  constructor() {
8
9
  super(...arguments);
9
10
  this.state = 0;
10
11
  this.button = new momentary_1.Momentary();
12
+ /** Desired adaptive trigger feedback state */
13
+ this.feedback = new trigger_feedback_1.TriggerFeedback();
11
14
  }
12
15
  get active() {
13
16
  return this.state > 0;
@@ -1 +1 @@
1
- {"version":3,"file":"trigger.js","sourceRoot":"","sources":["../../src/elements/trigger.ts"],"names":[],"mappings":";;;AAAA,oCAAiC;AAEjC,2CAAwC;AAExC,MAAa,OAAQ,SAAQ,aAAgB;IAA7C;;QACS,UAAK,GAAc,CAAC,CAAC;QAErB,WAAM,GAAc,IAAI,qBAAS,EAAE,CAAC;IAiB7C,CAAC;IAfC,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAEM,OAAO,CAAC,KAAgB;QAC7B,OAAO,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC;IAC9B,CAAC;CACF;AApBD,0BAoBC"}
1
+ {"version":3,"file":"trigger.js","sourceRoot":"","sources":["../../src/elements/trigger.ts"],"names":[],"mappings":";;;AAAA,oCAAiC;AAEjC,2CAAwC;AACxC,yDAAqD;AAErD,MAAa,OAAQ,SAAQ,aAAgB;IAA7C;;QACS,UAAK,GAAc,CAAC,CAAC;QAErB,WAAM,GAAc,IAAI,qBAAS,EAAE,CAAC;QAE3C,8CAA8C;QAC9B,aAAQ,GAAG,IAAI,kCAAe,EAAE,CAAC;IAiBnD,CAAC;IAfC,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAEM,OAAO,CAAC,KAAgB;QAC7B,OAAO,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC;IAC9B,CAAC;CACF;AAvBD,0BAuBC"}
@@ -0,0 +1,109 @@
1
+ /** Canonical trigger effect types from the DualSense firmware */
2
+ export declare enum TriggerEffect {
3
+ /** No resistance — default linear feel */
4
+ Off = "off",
5
+ /** Zone-based continuous resistance */
6
+ Feedback = "feedback",
7
+ /** Resistance with a snap release point, like a weapon trigger */
8
+ Weapon = "weapon",
9
+ /** Weapon feel with snap-back force, like drawing a bow */
10
+ Bow = "bow",
11
+ /** Rhythmic two-stroke oscillation */
12
+ Galloping = "galloping",
13
+ /** Zone-based oscillation with configurable amplitude and frequency */
14
+ Vibration = "vibration",
15
+ /** Dual-amplitude vibration with frequency and period control */
16
+ Machine = "machine"
17
+ }
18
+ /** Zone-based resistance with per-zone force control */
19
+ export interface FeedbackEffect {
20
+ effect: TriggerEffect.Feedback;
21
+ /** Where resistance begins along trigger travel (0-1) */
22
+ position: number;
23
+ /** Resistance strength (0-1, maps to firmware's 1-8 scale) */
24
+ strength: number;
25
+ }
26
+ /** Resistance with a start position, snap release point, and force */
27
+ export interface WeaponEffect {
28
+ effect: TriggerEffect.Weapon;
29
+ /** Where resistance begins (0-1, maps to zones 2-7) */
30
+ start: number;
31
+ /** Where snap release occurs (0-1, maps to zones 3-8, must be after start) */
32
+ end: number;
33
+ /** Resistance strength (0-1) */
34
+ strength: number;
35
+ }
36
+ /** Weapon feel with snap-back force */
37
+ export interface BowEffect {
38
+ effect: TriggerEffect.Bow;
39
+ /** Where resistance begins (0-1) */
40
+ start: number;
41
+ /** Where snap-back occurs (0-1, must be after start) */
42
+ end: number;
43
+ /** Pull strength (0-1) */
44
+ strength: number;
45
+ /** Snap-back force (0-1) */
46
+ snapForce: number;
47
+ }
48
+ /** Rhythmic two-stroke oscillation */
49
+ export interface GallopingEffect {
50
+ effect: TriggerEffect.Galloping;
51
+ /** Where effect begins (0-1) */
52
+ start: number;
53
+ /** Where effect ends (0-1) */
54
+ end: number;
55
+ /** First foot timing (0-1, maps to 0-6) */
56
+ firstFoot: number;
57
+ /** Second foot timing (0-1, maps to 0-7, must be after firstFoot) */
58
+ secondFoot: number;
59
+ /** Oscillation frequency in Hz (1-255) */
60
+ frequency: number;
61
+ }
62
+ /** Zone-based oscillation with amplitude and frequency control */
63
+ export interface VibrationEffect {
64
+ effect: TriggerEffect.Vibration;
65
+ /** Where vibration begins along trigger travel (0-1) */
66
+ position: number;
67
+ /** Vibration amplitude (0-1, maps to firmware's 1-8 scale) */
68
+ amplitude: number;
69
+ /** Vibration frequency in Hz (1-255) */
70
+ frequency: number;
71
+ }
72
+ /** Dual-amplitude vibration with frequency and period */
73
+ export interface MachineEffect {
74
+ effect: TriggerEffect.Machine;
75
+ /** Where effect begins (0-1) */
76
+ start: number;
77
+ /** Where effect ends (0-1) */
78
+ end: number;
79
+ /** First amplitude (0-1, maps to 0-7) */
80
+ amplitudeA: number;
81
+ /** Second amplitude (0-1, maps to 0-7) */
82
+ amplitudeB: number;
83
+ /** Vibration frequency in Hz (1-255) */
84
+ frequency: number;
85
+ /** Period in tenths of a second */
86
+ period: number;
87
+ }
88
+ export type TriggerFeedbackConfig = {
89
+ effect: TriggerEffect.Off;
90
+ } | FeedbackEffect | WeaponEffect | BowEffect | GallopingEffect | VibrationEffect | MachineEffect;
91
+ /** Build the 11-byte trigger effect block from a config */
92
+ export declare function buildTriggerEffectBlock(config: TriggerFeedbackConfig): Uint8Array;
93
+ /** Holds the desired adaptive trigger feedback state and translates it for HID output */
94
+ export declare class TriggerFeedback {
95
+ private _config;
96
+ /** The current feedback configuration */
97
+ get config(): TriggerFeedbackConfig;
98
+ /** The current effect type */
99
+ get effect(): TriggerEffect;
100
+ /** Set adaptive trigger feedback */
101
+ set(config: TriggerFeedbackConfig): void;
102
+ /** Reset to no resistance */
103
+ reset(): void;
104
+ /** Build the raw 11-byte effect block for HID output */
105
+ toBytes(): Uint8Array;
106
+ /** String key for change detection in the polling loop */
107
+ toKey(): string;
108
+ }
109
+ //# sourceMappingURL=trigger_feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger_feedback.d.ts","sourceRoot":"","sources":["../../src/elements/trigger_feedback.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TriggerFeedback = exports.buildTriggerEffectBlock = exports.TriggerEffect = void 0;
4
+ /** Canonical trigger effect types from the DualSense firmware */
5
+ var TriggerEffect;
6
+ (function (TriggerEffect) {
7
+ /** No resistance — default linear feel */
8
+ TriggerEffect["Off"] = "off";
9
+ /** Zone-based continuous resistance */
10
+ TriggerEffect["Feedback"] = "feedback";
11
+ /** Resistance with a snap release point, like a weapon trigger */
12
+ TriggerEffect["Weapon"] = "weapon";
13
+ /** Weapon feel with snap-back force, like drawing a bow */
14
+ TriggerEffect["Bow"] = "bow";
15
+ /** Rhythmic two-stroke oscillation */
16
+ TriggerEffect["Galloping"] = "galloping";
17
+ /** Zone-based oscillation with configurable amplitude and frequency */
18
+ TriggerEffect["Vibration"] = "vibration";
19
+ /** Dual-amplitude vibration with frequency and period control */
20
+ TriggerEffect["Machine"] = "machine";
21
+ })(TriggerEffect = exports.TriggerEffect || (exports.TriggerEffect = {}));
22
+ // --- Internal translation to raw 11-byte trigger effect block ---
23
+ /** Mode byte values per effect type */
24
+ const EFFECT_MODE = {
25
+ [TriggerEffect.Off]: 0x05,
26
+ [TriggerEffect.Feedback]: 0x21,
27
+ [TriggerEffect.Weapon]: 0x25,
28
+ [TriggerEffect.Bow]: 0x22,
29
+ [TriggerEffect.Galloping]: 0x23,
30
+ [TriggerEffect.Vibration]: 0x26,
31
+ [TriggerEffect.Machine]: 0x27,
32
+ };
33
+ /** Clamp and round a 0-1 value to an integer range */
34
+ function scale(value, max, min = 0) {
35
+ return Math.round(Math.min(max, Math.max(min, value * max)));
36
+ }
37
+ /** Build the 11-byte trigger effect block from a config */
38
+ function buildTriggerEffectBlock(config) {
39
+ const block = new Uint8Array(11).fill(0);
40
+ if (config.effect === TriggerEffect.Off) {
41
+ block[0] = EFFECT_MODE[TriggerEffect.Off];
42
+ return block;
43
+ }
44
+ block[0] = EFFECT_MODE[config.effect];
45
+ switch (config.effect) {
46
+ case TriggerEffect.Feedback: {
47
+ const position = scale(config.position, 9);
48
+ const strength = scale(config.strength, 8, 1);
49
+ const forceValue = (strength - 1) & 0x07;
50
+ let forceZones = 0;
51
+ let activeZones = 0;
52
+ for (let i = position; i < 10; i++) {
53
+ forceZones |= forceValue << (3 * i);
54
+ activeZones |= 1 << i;
55
+ }
56
+ block[1] = activeZones & 0xff;
57
+ block[2] = (activeZones >> 8) & 0xff;
58
+ block[3] = forceZones & 0xff;
59
+ block[4] = (forceZones >> 8) & 0xff;
60
+ block[5] = (forceZones >> 16) & 0xff;
61
+ block[6] = (forceZones >> 24) & 0xff;
62
+ break;
63
+ }
64
+ case TriggerEffect.Weapon: {
65
+ const start = Math.min(7, Math.max(2, scale(config.start, 9)));
66
+ const end = Math.min(8, Math.max(start + 1, scale(config.end, 9)));
67
+ const strength = scale(config.strength, 8, 1);
68
+ const startAndStopZones = (1 << start) | (1 << end);
69
+ block[1] = startAndStopZones & 0xff;
70
+ block[2] = (startAndStopZones >> 8) & 0xff;
71
+ block[3] = strength - 1;
72
+ break;
73
+ }
74
+ case TriggerEffect.Bow: {
75
+ const start = scale(config.start, 8);
76
+ const end = Math.max(start + 1, scale(config.end, 8));
77
+ const strength = scale(config.strength, 8, 1);
78
+ const snapForce = scale(config.snapForce, 8, 1);
79
+ const startAndStopZones = (1 << start) | (1 << end);
80
+ const forcePair = ((strength - 1) & 0x07) | (((snapForce - 1) & 0x07) << 3);
81
+ block[1] = startAndStopZones & 0xff;
82
+ block[2] = (startAndStopZones >> 8) & 0xff;
83
+ block[3] = forcePair & 0xff;
84
+ block[4] = (forcePair >> 8) & 0xff;
85
+ break;
86
+ }
87
+ case TriggerEffect.Galloping: {
88
+ const start = scale(config.start, 8);
89
+ const end = Math.max(start + 1, scale(config.end, 9));
90
+ const firstFoot = scale(config.firstFoot, 6);
91
+ const secondFoot = Math.max(firstFoot + 1, scale(config.secondFoot, 7));
92
+ const startAndStopZones = (1 << start) | (1 << end);
93
+ const timeAndRatio = (secondFoot & 0x07) | ((firstFoot & 0x07) << 3);
94
+ block[1] = startAndStopZones & 0xff;
95
+ block[2] = (startAndStopZones >> 8) & 0xff;
96
+ block[3] = timeAndRatio & 0xff;
97
+ block[4] = Math.min(255, Math.max(1, Math.round(config.frequency)));
98
+ break;
99
+ }
100
+ case TriggerEffect.Vibration: {
101
+ const position = scale(config.position, 9);
102
+ const amplitude = scale(config.amplitude, 8, 1);
103
+ const strengthValue = (amplitude - 1) & 0x07;
104
+ let amplitudeZones = 0;
105
+ let activeZones = 0;
106
+ for (let i = position; i < 10; i++) {
107
+ amplitudeZones |= strengthValue << (3 * i);
108
+ activeZones |= 1 << i;
109
+ }
110
+ block[1] = activeZones & 0xff;
111
+ block[2] = (activeZones >> 8) & 0xff;
112
+ block[3] = amplitudeZones & 0xff;
113
+ block[4] = (amplitudeZones >> 8) & 0xff;
114
+ block[5] = (amplitudeZones >> 16) & 0xff;
115
+ block[6] = (amplitudeZones >> 24) & 0xff;
116
+ block[9] = Math.min(255, Math.max(1, Math.round(config.frequency)));
117
+ break;
118
+ }
119
+ case TriggerEffect.Machine: {
120
+ const start = scale(config.start, 8);
121
+ const end = Math.max(start + 1, scale(config.end, 9));
122
+ const amplitudeA = scale(config.amplitudeA, 7);
123
+ const amplitudeB = scale(config.amplitudeB, 7);
124
+ const startAndStopZones = (1 << start) | (1 << end);
125
+ const strengthPair = (amplitudeA & 0x07) | ((amplitudeB & 0x07) << 3);
126
+ block[1] = startAndStopZones & 0xff;
127
+ block[2] = (startAndStopZones >> 8) & 0xff;
128
+ block[3] = strengthPair & 0xff;
129
+ block[4] = Math.min(255, Math.max(1, Math.round(config.frequency)));
130
+ block[5] = Math.round(config.period);
131
+ break;
132
+ }
133
+ }
134
+ return block;
135
+ }
136
+ exports.buildTriggerEffectBlock = buildTriggerEffectBlock;
137
+ /** Holds the desired adaptive trigger feedback state and translates it for HID output */
138
+ class TriggerFeedback {
139
+ constructor() {
140
+ this._config = { effect: TriggerEffect.Off };
141
+ }
142
+ /** The current feedback configuration */
143
+ get config() {
144
+ return this._config;
145
+ }
146
+ /** The current effect type */
147
+ get effect() {
148
+ return this._config.effect;
149
+ }
150
+ /** Set adaptive trigger feedback */
151
+ set(config) {
152
+ this._config = config;
153
+ }
154
+ /** Reset to no resistance */
155
+ reset() {
156
+ this._config = { effect: TriggerEffect.Off };
157
+ }
158
+ /** Build the raw 11-byte effect block for HID output */
159
+ toBytes() {
160
+ return buildTriggerEffectBlock(this._config);
161
+ }
162
+ /** String key for change detection in the polling loop */
163
+ toKey() {
164
+ return JSON.stringify(this._config);
165
+ }
166
+ }
167
+ exports.TriggerFeedback = TriggerFeedback;
168
+ //# sourceMappingURL=trigger_feedback.js.map