@codexo/exojs 0.7.12 → 0.7.13
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/CHANGELOG.md +334 -0
- package/dist/esm/core/Application.d.ts +3 -1
- package/dist/esm/core/Application.js +7 -6
- package/dist/esm/core/Application.js.map +1 -1
- package/dist/esm/core/Scene.d.ts +30 -0
- package/dist/esm/core/Scene.js +56 -0
- package/dist/esm/core/Scene.js.map +1 -1
- package/dist/esm/core/SceneManager.js +2 -2
- package/dist/esm/core/SceneManager.js.map +1 -1
- package/dist/esm/debug/DebugOverlay.js +2 -2
- package/dist/esm/debug/DebugOverlay.js.map +1 -1
- package/dist/esm/debug/PointerStackLayer.js +1 -1
- package/dist/esm/debug/PointerStackLayer.js.map +1 -1
- package/dist/esm/index.js +4 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/input/ArcadeStickGamepadMapping.js +18 -19
- package/dist/esm/input/ArcadeStickGamepadMapping.js.map +1 -1
- package/dist/esm/input/Gamepad.d.ts +164 -62
- package/dist/esm/input/Gamepad.js +290 -134
- package/dist/esm/input/Gamepad.js.map +1 -1
- package/dist/esm/input/GamepadAxis.d.ts +120 -0
- package/dist/esm/input/GamepadAxis.js +106 -0
- package/dist/esm/input/GamepadAxis.js.map +1 -0
- package/dist/esm/input/GamepadButton.d.ts +110 -0
- package/dist/esm/input/GamepadButton.js +99 -0
- package/dist/esm/input/GamepadButton.js.map +1 -0
- package/dist/esm/input/GamepadDefinitions.js +4 -0
- package/dist/esm/input/GamepadDefinitions.js.map +1 -1
- package/dist/esm/input/GamepadMapping.d.ts +28 -24
- package/dist/esm/input/GamepadMapping.js +33 -16
- package/dist/esm/input/GamepadMapping.js.map +1 -1
- package/dist/esm/input/GamepadPromptLayouts.d.ts +10 -8
- package/dist/esm/input/GamepadPromptLayouts.js +21 -20
- package/dist/esm/input/GamepadPromptLayouts.js.map +1 -1
- package/dist/esm/input/GenericDualAnalogGamepadMapping.d.ts +6 -3
- package/dist/esm/input/GenericDualAnalogGamepadMapping.js +55 -46
- package/dist/esm/input/GenericDualAnalogGamepadMapping.js.map +1 -1
- package/dist/esm/input/InputBinding.d.ts +74 -0
- package/dist/esm/input/InputBinding.js +100 -0
- package/dist/esm/input/InputBinding.js.map +1 -0
- package/dist/esm/input/InputManager.d.ts +79 -33
- package/dist/esm/input/InputManager.js +229 -104
- package/dist/esm/input/InputManager.js.map +1 -1
- package/dist/esm/input/InteractionManager.d.ts +1 -1
- package/dist/esm/input/InteractionManager.js +13 -13
- package/dist/esm/input/InteractionManager.js.map +1 -1
- package/dist/esm/input/JoyConLeftGamepadMapping.d.ts +14 -9
- package/dist/esm/input/JoyConLeftGamepadMapping.js +39 -9
- package/dist/esm/input/JoyConLeftGamepadMapping.js.map +1 -1
- package/dist/esm/input/JoyConRightGamepadMapping.d.ts +14 -9
- package/dist/esm/input/JoyConRightGamepadMapping.js +35 -9
- package/dist/esm/input/JoyConRightGamepadMapping.js.map +1 -1
- package/dist/esm/input/Pointer.d.ts +84 -71
- package/dist/esm/input/Pointer.js +71 -71
- package/dist/esm/input/Pointer.js.map +1 -1
- package/dist/esm/input/SteamDeckGamepadMapping.d.ts +18 -0
- package/dist/esm/input/SteamDeckGamepadMapping.js +76 -0
- package/dist/esm/input/SteamDeckGamepadMapping.js.map +1 -0
- package/dist/esm/input/index.d.ts +7 -4
- package/dist/esm/input/types.d.ts +0 -76
- package/dist/esm/input/types.js +1 -80
- package/dist/esm/input/types.js.map +1 -1
- package/dist/esm/resources/CacheFirstStrategy.d.ts +7 -4
- package/dist/esm/resources/CacheFirstStrategy.js +11 -8
- package/dist/esm/resources/CacheFirstStrategy.js.map +1 -1
- package/dist/esm/resources/CacheStrategy.d.ts +14 -6
- package/dist/esm/resources/Loader.d.ts +8 -3
- package/dist/esm/resources/Loader.js +19 -37
- package/dist/esm/resources/Loader.js.map +1 -1
- package/dist/esm/resources/NetworkOnlyStrategy.d.ts +3 -0
- package/dist/esm/resources/NetworkOnlyStrategy.js +8 -3
- package/dist/esm/resources/NetworkOnlyStrategy.js.map +1 -1
- package/dist/esm/resources/factories/ImageFactory.d.ts +2 -2
- package/dist/esm/resources/factories/ImageFactory.js.map +1 -1
- package/dist/esm/resources/factories/TextureFactory.d.ts +2 -2
- package/dist/esm/resources/factories/TextureFactory.js.map +1 -1
- package/dist/esm/resources/factories/VttFactory.d.ts +3 -3
- package/dist/esm/resources/factories/VttFactory.js +83 -6
- package/dist/esm/resources/factories/VttFactory.js.map +1 -1
- package/dist/exo.esm.js +1390 -795
- package/dist/exo.esm.js.map +1 -1
- package/package.json +2 -1
- package/dist/esm/input/GamepadChannels.d.ts +0 -47
- package/dist/esm/input/GamepadChannels.js +0 -53
- package/dist/esm/input/GamepadChannels.js.map +0 -1
- package/dist/esm/input/GamepadControl.d.ts +0 -33
- package/dist/esm/input/GamepadControl.js +0 -42
- package/dist/esm/input/GamepadControl.js.map +0 -1
- package/dist/esm/input/Input.d.ts +0 -52
- package/dist/esm/input/Input.js +0 -90
- package/dist/esm/input/Input.js.map +0 -1
|
@@ -1,194 +1,350 @@
|
|
|
1
1
|
import { Signal } from '../core/Signal.js';
|
|
2
2
|
import { ChannelOffset, ChannelSize } from './types.js';
|
|
3
|
+
import { InputBinding } from './InputBinding.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
+
* One of four stable gamepad slots. Lives for the entire `Application`
|
|
7
|
+
* lifetime even when no physical pad is attached — a "mailbox" that
|
|
8
|
+
* physical hardware moves into and out of.
|
|
6
9
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* {@link
|
|
11
|
-
*
|
|
10
|
+
* Subscribe to {@link onConnect} / {@link onDisconnect} for hardware
|
|
11
|
+
* lifecycle, {@link onButtonDown} / {@link onButtonUp} / {@link onAxisChange}
|
|
12
|
+
* for granular per-event notifications, or call {@link onTrigger} /
|
|
13
|
+
* {@link onActive} / {@link onStart} / {@link onStop} to register
|
|
14
|
+
* stateful {@link InputBinding}s pinned to this slot.
|
|
15
|
+
*
|
|
16
|
+
* Listeners survive disconnect/reconnect cycles — a binding registered when
|
|
17
|
+
* the slot was empty will automatically activate when a pad connects.
|
|
12
18
|
*/
|
|
13
19
|
class Gamepad {
|
|
20
|
+
/** Fires when a physical pad connects to this slot. */
|
|
14
21
|
onConnect = new Signal();
|
|
22
|
+
/** Fires when the physical pad in this slot disconnects. */
|
|
15
23
|
onDisconnect = new Signal();
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this.setInfo({
|
|
42
|
-
name: definition.name,
|
|
43
|
-
label: definition.descriptor.label,
|
|
44
|
-
vendorId: definition.descriptor.vendorId,
|
|
45
|
-
productId: definition.descriptor.productId,
|
|
46
|
-
productKey: definition.descriptor.productKey,
|
|
47
|
-
});
|
|
48
|
-
this.connect(gamepad);
|
|
49
|
-
}
|
|
24
|
+
/** Fires for every button transition from inactive to active. */
|
|
25
|
+
onButtonDown = new Signal();
|
|
26
|
+
/** Fires for every button transition from active to inactive. */
|
|
27
|
+
onButtonUp = new Signal();
|
|
28
|
+
/** Fires whenever an axis crosses its activation threshold. */
|
|
29
|
+
onAxisChange = new Signal();
|
|
30
|
+
/**
|
|
31
|
+
* Fires when this slot's physical pad has been replaced by a previously
|
|
32
|
+
* higher-numbered slot's pad, after a `'compact'`-strategy disconnect.
|
|
33
|
+
* Dispatched with the source slot index the pad came from. Listeners
|
|
34
|
+
* remain attached and the channel buffer is preserved across the move.
|
|
35
|
+
*/
|
|
36
|
+
onPadReassigned = new Signal();
|
|
37
|
+
_slot;
|
|
38
|
+
_channels;
|
|
39
|
+
_bindings = new Set();
|
|
40
|
+
_detacher = { detach: (binding) => { this._bindings.delete(binding); } };
|
|
41
|
+
_channelOffset;
|
|
42
|
+
_mapping = null;
|
|
43
|
+
_info = null;
|
|
44
|
+
_browserGamepad = null;
|
|
45
|
+
constructor(slot, channels) {
|
|
46
|
+
this._slot = slot;
|
|
47
|
+
this._channels = channels;
|
|
48
|
+
this._channelOffset = ChannelOffset.Gamepads + (slot * ChannelSize.Gamepad);
|
|
50
49
|
}
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
/** This pad's stable slot (0..3). */
|
|
51
|
+
get slot() {
|
|
52
|
+
return this._slot;
|
|
53
53
|
}
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
/** `true` while a physical pad is attached to this slot. */
|
|
55
|
+
get connected() {
|
|
56
|
+
return this._browserGamepad !== null;
|
|
56
57
|
}
|
|
57
|
-
/** The
|
|
58
|
+
/** The active mapping, or `null` when disconnected. */
|
|
59
|
+
get mapping() {
|
|
60
|
+
return this._mapping;
|
|
61
|
+
}
|
|
62
|
+
/** The {@link GamepadMappingFamily}, or `null` when disconnected. */
|
|
58
63
|
get mappingFamily() {
|
|
59
|
-
return this.
|
|
64
|
+
return this._mapping?.family ?? null;
|
|
60
65
|
}
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
/** Identity metadata, or `null` when disconnected. */
|
|
67
|
+
get info() {
|
|
68
|
+
return this._info;
|
|
63
69
|
}
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
/** The underlying browser gamepad object, or `null` when disconnected. */
|
|
71
|
+
get browserGamepad() {
|
|
72
|
+
return this._browserGamepad;
|
|
66
73
|
}
|
|
67
|
-
|
|
68
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Browser-assigned hardware index from `navigator.getGamepads()` (i.e.
|
|
76
|
+
* `Gamepad.index`), or `null` when no pad is attached. Stable for the
|
|
77
|
+
* lifetime of a single physical connection but may change across
|
|
78
|
+
* disconnect/reconnect. Low-level escape hatch for advanced consumers
|
|
79
|
+
* that need to correlate slots with the raw browser API; prefer
|
|
80
|
+
* {@link slot} for stable per-application pad identity.
|
|
81
|
+
*/
|
|
82
|
+
get internalIndex() {
|
|
83
|
+
return this._browserGamepad?.index ?? null;
|
|
69
84
|
}
|
|
70
|
-
/**
|
|
71
|
-
get
|
|
72
|
-
return this.
|
|
85
|
+
/** `true` when the connected pad supports rumble via the Web Gamepad API. */
|
|
86
|
+
get canVibrate() {
|
|
87
|
+
return this._browserGamepad?.vibrationActuator != null;
|
|
73
88
|
}
|
|
74
|
-
|
|
75
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Returns `true` when this pad's mapping declares the requested channel.
|
|
91
|
+
* Use to gate listener registration on optional hardware (e.g. Joy-Con
|
|
92
|
+
* solo lacks a right stick — `pad.hasChannel(GamepadAxis.RightStickX)`
|
|
93
|
+
* returns `false`).
|
|
94
|
+
*/
|
|
95
|
+
hasChannel(channel) {
|
|
96
|
+
return this._mapping?.hasChannel(channel) ?? false;
|
|
76
97
|
}
|
|
77
|
-
|
|
78
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Trigger a rumble effect on this pad. Resolves when the effect finishes.
|
|
100
|
+
* Silent no-op when the pad is disconnected or the platform does not
|
|
101
|
+
* support haptic feedback. Use {@link canVibrate} to detect support.
|
|
102
|
+
*/
|
|
103
|
+
async vibrate(options) {
|
|
104
|
+
const actuator = this._browserGamepad?.vibrationActuator;
|
|
105
|
+
if (!actuator?.playEffect) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
await actuator.playEffect('dual-rumble', {
|
|
109
|
+
duration: options.duration,
|
|
110
|
+
weakMagnitude: options.weakMagnitude ?? 1,
|
|
111
|
+
strongMagnitude: options.strongMagnitude ?? 1,
|
|
112
|
+
startDelay: options.startDelay ?? 0,
|
|
113
|
+
});
|
|
79
114
|
}
|
|
80
|
-
|
|
81
|
-
|
|
115
|
+
/** Stop any active rumble on this pad. Silent no-op when unsupported. */
|
|
116
|
+
stopVibration() {
|
|
117
|
+
this._browserGamepad?.vibrationActuator?.reset?.();
|
|
82
118
|
}
|
|
83
|
-
|
|
84
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Register a callback fired once when any of `channels` becomes active.
|
|
121
|
+
* Listener survives disconnect/reconnect; call `.unbind()` on the
|
|
122
|
+
* returned {@link InputBinding} to detach.
|
|
123
|
+
*/
|
|
124
|
+
onStart(channel, callback, options) {
|
|
125
|
+
const binding = this._createBinding(channel, options);
|
|
126
|
+
binding.onStart.add(callback);
|
|
127
|
+
return binding;
|
|
85
128
|
}
|
|
86
|
-
|
|
87
|
-
|
|
129
|
+
/**
|
|
130
|
+
* Register a callback fired every frame while any of `channels` is active.
|
|
131
|
+
* Receives the channel value (0..1 for buttons, -1..1 for bipolar axes).
|
|
132
|
+
*/
|
|
133
|
+
onActive(channel, callback, options) {
|
|
134
|
+
const binding = this._createBinding(channel, options);
|
|
135
|
+
binding.onActive.add(callback);
|
|
136
|
+
return binding;
|
|
137
|
+
}
|
|
138
|
+
/** Register a callback fired once when all of `channels` become inactive. */
|
|
139
|
+
onStop(channel, callback, options) {
|
|
140
|
+
const binding = this._createBinding(channel, options);
|
|
141
|
+
binding.onStop.add(callback);
|
|
142
|
+
return binding;
|
|
88
143
|
}
|
|
89
144
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* provided; exposed publicly to allow runtime overrides.
|
|
145
|
+
* Register a callback fired when the input is released within
|
|
146
|
+
* {@link InputBindingOptions.threshold} ms of activation (a "tap").
|
|
93
147
|
*/
|
|
94
|
-
|
|
95
|
-
this.
|
|
96
|
-
|
|
148
|
+
onTrigger(channel, callback, options) {
|
|
149
|
+
const binding = this._createBinding(channel, options);
|
|
150
|
+
binding.onTrigger.add(callback);
|
|
151
|
+
return binding;
|
|
97
152
|
}
|
|
98
153
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
154
|
+
* Attach a physical browser gamepad to this slot. Called by
|
|
155
|
+
* {@link InputManager} on connect.
|
|
156
|
+
*
|
|
157
|
+
* @internal
|
|
101
158
|
*/
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
this.
|
|
105
|
-
|
|
106
|
-
|
|
159
|
+
_bind(gamepad, definition) {
|
|
160
|
+
this._browserGamepad = gamepad;
|
|
161
|
+
this._mapping = definition.mapping;
|
|
162
|
+
this._info = {
|
|
163
|
+
name: definition.name,
|
|
164
|
+
label: definition.descriptor.label,
|
|
165
|
+
vendorId: definition.descriptor.vendorId,
|
|
166
|
+
productId: definition.descriptor.productId,
|
|
167
|
+
productKey: definition.descriptor.productKey,
|
|
168
|
+
};
|
|
169
|
+
this.onConnect.dispatch();
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Detach the physical gamepad and clear its channels.
|
|
173
|
+
*
|
|
174
|
+
* @internal
|
|
175
|
+
*/
|
|
176
|
+
_unbind() {
|
|
177
|
+
if (this._browserGamepad === null) {
|
|
178
|
+
return;
|
|
107
179
|
}
|
|
108
|
-
|
|
180
|
+
this._clearMappedChannels();
|
|
181
|
+
this._browserGamepad = null;
|
|
182
|
+
this._mapping = null;
|
|
183
|
+
this._info = null;
|
|
184
|
+
this.onDisconnect.dispatch();
|
|
109
185
|
}
|
|
110
186
|
/**
|
|
111
|
-
*
|
|
112
|
-
* {@link onDisconnect}.
|
|
187
|
+
* Detach the physical gamepad and clear channels without firing
|
|
188
|
+
* {@link onDisconnect}. Used by {@link InputManager} during the compact
|
|
189
|
+
* slot-shift to silently vacate a slot before another pad shifts into
|
|
190
|
+
* its place; the disconnect signal is fired separately on the slot that
|
|
191
|
+
* ends up empty after compaction.
|
|
192
|
+
*
|
|
193
|
+
* @internal
|
|
113
194
|
*/
|
|
114
|
-
|
|
115
|
-
if (this.
|
|
116
|
-
|
|
117
|
-
this.clearMappedChannels();
|
|
118
|
-
this.onDisconnect.dispatch(this);
|
|
195
|
+
_silentUnbind() {
|
|
196
|
+
if (this._browserGamepad === null) {
|
|
197
|
+
return;
|
|
119
198
|
}
|
|
120
|
-
|
|
199
|
+
this._clearMappedChannels();
|
|
200
|
+
this._browserGamepad = null;
|
|
201
|
+
this._mapping = null;
|
|
202
|
+
this._info = null;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Dispatch this slot's {@link onDisconnect} signal without altering its
|
|
206
|
+
* state. Used by {@link InputManager} after a compact-mode shift, when a
|
|
207
|
+
* slot has already been emptied by {@link _rebindFrom} and now needs to
|
|
208
|
+
* notify subscribers that its mailbox is no longer occupied.
|
|
209
|
+
*
|
|
210
|
+
* @internal
|
|
211
|
+
*/
|
|
212
|
+
_dispatchDisconnect() {
|
|
213
|
+
this.onDisconnect.dispatch();
|
|
121
214
|
}
|
|
122
215
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
216
|
+
* Reassign this slot to take over another slot's physical gamepad without
|
|
217
|
+
* firing the full disconnect / connect cycle. Used by {@link InputManager}
|
|
218
|
+
* when the `'compact'` slot strategy shuffles pads after a disconnect.
|
|
219
|
+
*
|
|
220
|
+
* @internal
|
|
221
|
+
*/
|
|
222
|
+
_rebindFrom(other) {
|
|
223
|
+
const gamepad = other._browserGamepad;
|
|
224
|
+
const mapping = other._mapping;
|
|
225
|
+
const info = other._info;
|
|
226
|
+
this._clearMappedChannels();
|
|
227
|
+
other._clearMappedChannels();
|
|
228
|
+
other._browserGamepad = null;
|
|
229
|
+
other._mapping = null;
|
|
230
|
+
other._info = null;
|
|
231
|
+
this._browserGamepad = gamepad;
|
|
232
|
+
this._mapping = mapping;
|
|
233
|
+
this._info = info;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Sample the browser gamepad's current state and write transformed values
|
|
237
|
+
* into the shared channel buffer, dispatching transition events when
|
|
238
|
+
* channel activity crosses thresholds. Called once per frame by the
|
|
239
|
+
* engine's input loop. No-op when disconnected.
|
|
240
|
+
*
|
|
241
|
+
* @internal
|
|
127
242
|
*/
|
|
128
243
|
update() {
|
|
129
|
-
if (this.
|
|
130
|
-
|
|
244
|
+
if (this._browserGamepad === null || this._mapping === null) {
|
|
245
|
+
this._updateBindings();
|
|
246
|
+
return;
|
|
131
247
|
}
|
|
132
|
-
const channels = this.
|
|
133
|
-
const { buttons:
|
|
134
|
-
for (const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
248
|
+
const channels = this._channels;
|
|
249
|
+
const { buttons: rawButtons, axes: rawAxes } = this._browserGamepad;
|
|
250
|
+
for (const button of this._mapping.buttons) {
|
|
251
|
+
if (button.index >= rawButtons.length) {
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
const offset = this._resolveOffset(button.channel);
|
|
255
|
+
const previous = channels[offset];
|
|
256
|
+
const value = button.transformValue(rawButtons[button.index].value) || 0;
|
|
257
|
+
if (previous === value) {
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
channels[offset] = value;
|
|
261
|
+
if (previous === 0 && value !== 0) {
|
|
262
|
+
this.onButtonDown.dispatch(button, value);
|
|
263
|
+
}
|
|
264
|
+
else if (previous !== 0 && value === 0) {
|
|
265
|
+
this.onButtonUp.dispatch(button, value);
|
|
142
266
|
}
|
|
143
267
|
}
|
|
144
|
-
for (const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const value = control.transformValue(gamepadAxes[control.index]) || 0;
|
|
148
|
-
if (channels[offsetChannel] !== value) {
|
|
149
|
-
channels[offsetChannel] = value;
|
|
150
|
-
this.onUpdate.dispatch(control.channel, value, this);
|
|
151
|
-
}
|
|
268
|
+
for (const axis of this._mapping.axes) {
|
|
269
|
+
if (axis.index >= rawAxes.length) {
|
|
270
|
+
continue;
|
|
152
271
|
}
|
|
272
|
+
const offset = this._resolveOffset(axis.channel);
|
|
273
|
+
const previous = channels[offset];
|
|
274
|
+
const value = axis.transformValue(rawAxes[axis.index]) || 0;
|
|
275
|
+
if (previous === value) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
channels[offset] = value;
|
|
279
|
+
this.onAxisChange.dispatch(axis, value);
|
|
153
280
|
}
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
/** Zeroes all channel buffer entries that belong to this gamepad's mapping. */
|
|
157
|
-
clearChannels() {
|
|
158
|
-
this.clearMappedChannels();
|
|
159
|
-
return this;
|
|
281
|
+
this._updateBindings();
|
|
160
282
|
}
|
|
161
283
|
/**
|
|
162
|
-
*
|
|
163
|
-
* The instance must not be used after this call.
|
|
284
|
+
* Tear down this gamepad slot. Called on application shutdown.
|
|
164
285
|
*/
|
|
165
286
|
destroy() {
|
|
166
|
-
this.
|
|
167
|
-
|
|
287
|
+
for (const binding of Array.from(this._bindings)) {
|
|
288
|
+
binding.unbind();
|
|
289
|
+
}
|
|
290
|
+
this._bindings.clear();
|
|
291
|
+
this._unbind();
|
|
168
292
|
this.onConnect.destroy();
|
|
169
293
|
this.onDisconnect.destroy();
|
|
170
|
-
this.
|
|
294
|
+
this.onButtonDown.destroy();
|
|
295
|
+
this.onButtonUp.destroy();
|
|
296
|
+
this.onAxisChange.destroy();
|
|
297
|
+
this.onPadReassigned.destroy();
|
|
171
298
|
}
|
|
172
299
|
/**
|
|
173
|
-
*
|
|
174
|
-
* buffer for this
|
|
300
|
+
* Convert a slot-relative channel value to its absolute index in the
|
|
301
|
+
* shared channel buffer for this slot.
|
|
175
302
|
*/
|
|
176
303
|
resolveChannelOffset(channel) {
|
|
177
|
-
return this.
|
|
304
|
+
return this._resolveOffset(channel);
|
|
178
305
|
}
|
|
179
306
|
/**
|
|
180
|
-
*
|
|
181
|
-
* channel
|
|
307
|
+
* Static counterpart to {@link Gamepad.resolveChannelOffset} — resolves
|
|
308
|
+
* an absolute channel-buffer offset for a given slot index without
|
|
309
|
+
* requiring a Gamepad instance.
|
|
182
310
|
*/
|
|
183
|
-
static resolveChannelOffset(
|
|
184
|
-
return ChannelOffset.Gamepads + (
|
|
311
|
+
static resolveChannelOffset(slot, channel) {
|
|
312
|
+
return ChannelOffset.Gamepads + (slot * ChannelSize.Gamepad) + (channel ^ ChannelOffset.Gamepads);
|
|
313
|
+
}
|
|
314
|
+
_resolveOffset(channel) {
|
|
315
|
+
return this._channelOffset + (channel ^ ChannelOffset.Gamepads);
|
|
316
|
+
}
|
|
317
|
+
_clearMappedChannels() {
|
|
318
|
+
if (this._mapping === null) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
for (const button of this._mapping.buttons) {
|
|
322
|
+
this._channels[this._resolveOffset(button.channel)] = 0;
|
|
323
|
+
}
|
|
324
|
+
for (const axis of this._mapping.axes) {
|
|
325
|
+
this._channels[this._resolveOffset(axis.channel)] = 0;
|
|
326
|
+
}
|
|
185
327
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
328
|
+
_createBinding(channel, options = {}) {
|
|
329
|
+
const list = Array.isArray(channel) ? channel : [channel];
|
|
330
|
+
const resolved = list.map((c) => this._resolveExternalChannel(c));
|
|
331
|
+
const binding = new InputBinding(resolved, options, this._detacher);
|
|
332
|
+
this._bindings.add(binding);
|
|
333
|
+
return binding;
|
|
334
|
+
}
|
|
335
|
+
_resolveExternalChannel(channel) {
|
|
336
|
+
// Keyboard channels are global (no slot offset). Gamepad channels
|
|
337
|
+
// need slot-aware translation. Any channel value within the
|
|
338
|
+
// gamepad-section maps through this pad's slot offset; others
|
|
339
|
+
// (Keyboard, Pointer) pass through as-is.
|
|
340
|
+
if (channel >= ChannelOffset.Gamepads && channel < ChannelOffset.Gamepads + ChannelSize.Category) {
|
|
341
|
+
return this._resolveOffset(channel);
|
|
189
342
|
}
|
|
190
|
-
|
|
191
|
-
|
|
343
|
+
return channel;
|
|
344
|
+
}
|
|
345
|
+
_updateBindings() {
|
|
346
|
+
for (const binding of this._bindings) {
|
|
347
|
+
binding.update(this._channels);
|
|
192
348
|
}
|
|
193
349
|
}
|
|
194
350
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Gamepad.js","sources":["../../../../src/input/Gamepad.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Gamepad.js","sources":["../../../../src/input/Gamepad.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
declare const gamepadAxisChannelBrand: unique symbol;
|
|
2
|
+
/**
|
|
3
|
+
* Branded literal-union type identifying a canonical analog axis-style
|
|
4
|
+
* gamepad input channel. Members are absolute offsets into the engine's
|
|
5
|
+
* shared {@link Float32Array} input channel buffer (relative to slot 0):
|
|
6
|
+
* the 32 slots reserved for a gamepad slot's axis section, computed as
|
|
7
|
+
* `ChannelOffset.Gamepads + 32..63` (544..575 with the default layout).
|
|
8
|
+
*
|
|
9
|
+
* The 24 named axes (sticks split + signed aggregates + dual touchpad XY +
|
|
10
|
+
* 4 auxiliary bipolar) cover offsets 32..55; offsets 56..63 are reserved
|
|
11
|
+
* for forward-compat / custom-mapping use and remain part of this type so
|
|
12
|
+
* custom `GamepadMapping` subclasses can address them without casting.
|
|
13
|
+
*
|
|
14
|
+
* The brand keeps the type system from confusing axis channels with
|
|
15
|
+
* {@link GamepadButtonChannel} or raw `number`s during mapping authoring.
|
|
16
|
+
* User code does not construct values of this type directly — read them
|
|
17
|
+
* from the {@link GamepadAxis} namespace (`GamepadAxis.LeftStickLeft`, ...).
|
|
18
|
+
*
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export type GamepadAxisChannel = (544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575) & {
|
|
22
|
+
readonly [gamepadAxisChannelBrand]: void;
|
|
23
|
+
};
|
|
24
|
+
/** Construction options for a {@link GamepadAxis}. */
|
|
25
|
+
export interface GamepadAxisOptions {
|
|
26
|
+
/** Negate the raw value before further processing. Default `false`. */
|
|
27
|
+
invert?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Convert from bipolar [-1, +1] to unipolar [0, 1] via `(v + 1) / 2`.
|
|
30
|
+
* Used for direction-split channels where each direction reads 0..1.
|
|
31
|
+
* Default `false`.
|
|
32
|
+
*/
|
|
33
|
+
normalize?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Activation threshold (deadzone). After the invert/normalize pipeline,
|
|
36
|
+
* any value at or below this reads as 0. Default 0.2.
|
|
37
|
+
*/
|
|
38
|
+
threshold?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Skip the deadzone clamp. Used for aggregate signed channels
|
|
41
|
+
* (`LeftStickX`, `LeftStickY`, ...) that need to preserve the full
|
|
42
|
+
* [-1, +1] range and apply their own deadzone client-side.
|
|
43
|
+
* Default `false`.
|
|
44
|
+
*/
|
|
45
|
+
bipolar?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Single mappable analog axis on a physical gamepad. Holds the raw browser
|
|
49
|
+
* `Gamepad.axes[]` index, the canonical channel the value is written to, and
|
|
50
|
+
* the transform pipeline applied each frame by {@link transformValue}.
|
|
51
|
+
*
|
|
52
|
+
* Direction-split axis channels (e.g. `LeftStickLeft`, `LeftStickRight`)
|
|
53
|
+
* live in the 0..1 range — set `invert: true` on the negative half so it
|
|
54
|
+
* reads positive when pushed in its direction.
|
|
55
|
+
*
|
|
56
|
+
* Aggregate channels (e.g. `LeftStickX`, `LeftStickY`) live in the full
|
|
57
|
+
* -1..1 range — set `bipolar: true` to preserve sign through the pipeline.
|
|
58
|
+
*
|
|
59
|
+
* The static namespace exports (`GamepadAxis.LeftStickLeft`,
|
|
60
|
+
* `.LeftStickX`, ...) carry the canonical channel offsets used to address
|
|
61
|
+
* each axis.
|
|
62
|
+
*/
|
|
63
|
+
export declare class GamepadAxis {
|
|
64
|
+
readonly index: number;
|
|
65
|
+
readonly channel: GamepadAxisChannel;
|
|
66
|
+
readonly invert: boolean;
|
|
67
|
+
readonly normalize: boolean;
|
|
68
|
+
readonly threshold: number;
|
|
69
|
+
readonly bipolar: boolean;
|
|
70
|
+
constructor(index: number, channel: GamepadAxisChannel, options?: GamepadAxisOptions);
|
|
71
|
+
/**
|
|
72
|
+
* Apply the axis transform pipeline to a raw browser axis value
|
|
73
|
+
* (typically `Gamepad.axes[i]`, in -1..1).
|
|
74
|
+
*
|
|
75
|
+
* Pipeline: clamp to [-1, 1] → optional invert → optional normalize to
|
|
76
|
+
* [0, 1] → bipolar passthrough OR deadzone (returns 0 when the absolute
|
|
77
|
+
* value is at or below `threshold`).
|
|
78
|
+
*/
|
|
79
|
+
transformValue(value: number): number;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Channel-identifier constants. The axis section starts after the 32-slot
|
|
83
|
+
* button block: 24 named axes (offsets 32..55) plus 8 reserved slots
|
|
84
|
+
* (offsets 56..63).
|
|
85
|
+
*/
|
|
86
|
+
export declare namespace GamepadAxis {
|
|
87
|
+
const LeftStickLeft: GamepadAxisChannel;
|
|
88
|
+
const LeftStickRight: GamepadAxisChannel;
|
|
89
|
+
const LeftStickUp: GamepadAxisChannel;
|
|
90
|
+
const LeftStickDown: GamepadAxisChannel;
|
|
91
|
+
const RightStickLeft: GamepadAxisChannel;
|
|
92
|
+
const RightStickRight: GamepadAxisChannel;
|
|
93
|
+
const RightStickUp: GamepadAxisChannel;
|
|
94
|
+
const RightStickDown: GamepadAxisChannel;
|
|
95
|
+
/** Signed left-stick X axis (-1..1). Negative = left, positive = right. */
|
|
96
|
+
const LeftStickX: GamepadAxisChannel;
|
|
97
|
+
/** Signed left-stick Y axis (-1..1). Negative = up (screen-up), positive = down. */
|
|
98
|
+
const LeftStickY: GamepadAxisChannel;
|
|
99
|
+
/** Signed right-stick X axis (-1..1). */
|
|
100
|
+
const RightStickX: GamepadAxisChannel;
|
|
101
|
+
/** Signed right-stick Y axis (-1..1). */
|
|
102
|
+
const RightStickY: GamepadAxisChannel;
|
|
103
|
+
/** Primary touchpad X (0..1, left to right). PlayStation, Steam Deck (left pad), Steam Controller. */
|
|
104
|
+
const TouchpadX: GamepadAxisChannel;
|
|
105
|
+
/** Primary touchpad Y (0..1, top to bottom). */
|
|
106
|
+
const TouchpadY: GamepadAxisChannel;
|
|
107
|
+
/** Secondary touchpad X (0..1). Steam Deck (right pad), other dual-touchpad hardware. */
|
|
108
|
+
const Touchpad2X: GamepadAxisChannel;
|
|
109
|
+
/** Secondary touchpad Y (0..1). */
|
|
110
|
+
const Touchpad2Y: GamepadAxisChannel;
|
|
111
|
+
const AuxiliaryAxis0Negative: GamepadAxisChannel;
|
|
112
|
+
const AuxiliaryAxis0Positive: GamepadAxisChannel;
|
|
113
|
+
const AuxiliaryAxis1Negative: GamepadAxisChannel;
|
|
114
|
+
const AuxiliaryAxis1Positive: GamepadAxisChannel;
|
|
115
|
+
const AuxiliaryAxis2Negative: GamepadAxisChannel;
|
|
116
|
+
const AuxiliaryAxis2Positive: GamepadAxisChannel;
|
|
117
|
+
const AuxiliaryAxis3Negative: GamepadAxisChannel;
|
|
118
|
+
const AuxiliaryAxis3Positive: GamepadAxisChannel;
|
|
119
|
+
}
|
|
120
|
+
export {};
|