-
Notifications
You must be signed in to change notification settings - Fork 2
/
gamepads-src-0.1.js
74 lines (65 loc) · 2.31 KB
/
gamepads-src-0.1.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
function registerHostFunctions(importObject, wasm_memory_holder) {
const MAX_GAMEPADS = 8;
const BYTES_PER_GAMEPAD = 28;
// How should deadzones be handled in browsers?
// See e.g. https://github.com/ensemblejs/gamepad-api-mappings
// For now use a value picked from some limited data points.
const DEADZONE = 0.04;
// Event listener on 'gamepadconnected' necessary for gamepad listing to work.
globalThis.addEventListener(`gamepadconnected`, () => {});
importObject.env.getGamepads = (wasm_memory_offset) => {
const gamepads = navigator.getGamepads();
// 'wasm_memory' is setup in https://github.com/not-fl3/miniquad/blob/master/js/gl.js
const memory = wasm_memory_holder ? wasm_memory_holder.memory : wasm_memory;
const f32 = new Float32Array(memory.buffer);
const u32 = new Uint32Array(memory.buffer);
const u8 = new Uint8Array(memory.buffer);
for (const [gamepad_idx, gamepad] of gamepads
.slice(0, MAX_GAMEPADS)
.entries()) {
let byteOffset =
wasm_memory_offset +
// Skip gamepads with lower index:
BYTES_PER_GAMEPAD * gamepad_idx +
// Skip the initial u8 gamepad id:
1;
if (!gamepad || !gamepad.connected || gamepad.mapping !== "standard") {
u8[byteOffset] = 0;
continue;
}
// Mark connected.
u8[byteOffset] = 1;
byteOffset += 3;
// Write u32, pressed_bits:
let pressed_bits = 0;
for (const [index, button] of gamepad.buttons.entries()) {
if (index < 17 && button.pressed) pressed_bits |= 1 << index;
}
u32[byteOffset / 4] = pressed_bits;
byteOffset += 4;
for (const [index, axes] of gamepad.axes.slice(0, 4).entries()) {
const sign = index === 1 || index === 3 ? -1 : 1;
f32[byteOffset / 4] =
Math.abs(axes) < DEADZONE
? 0.0
: (sign * (axes - Math.sign(axes) * DEADZONE)) / (1 - DEADZONE);
byteOffset += 4;
}
}
};
importObject.env.playEffect = (
gamepadId,
duration,
startDelay,
strongMagnitude,
weakMagnitude,
) => {
const gamepad = navigator.getGamepads().find((p) => p?.index === gamepadId);
gamepad?.vibrationActuator?.playEffect("dual-rumble", {
duration,
startDelay,
strongMagnitude,
weakMagnitude,
});
};
}