-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
136 lines (107 loc) · 3.44 KB
/
index.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
const { Buttons, Sticks } = require('./inputs');
const mappings = require('./mappings');
const getGamepadMapping = (gamepadId) => {
for (let key in mappings) {
const gamepadMapping = mappings[key];
if (gamepadId.indexOf(gamepadMapping.name) >= 0) {
return gamepadMapping;
}
}
return null;
};
const mapButton = (buttonState, gamepadMapping, key) => {
return {
value: buttonState[gamepadMapping.buttons[key]] && buttonState[gamepadMapping.buttons[key]].value,
pressed: buttonState[gamepadMapping.buttons[key]] && buttonState[gamepadMapping.buttons[key]].pressed ? true : false
}
};
const mapStick = (stickState, gamepadMapping, key) => {
const baseValue = stickState[gamepadMapping.sticks[key]];
if (gamepadMapping.deadzones && gamepadMapping.deadzones[key]) {
const keyDeadzone = gamepadMapping.deadzones[key];
if (Math.abs(baseValue) < keyDeadzone) {
return {
value: 0
}
}
if (baseValue < 0) {
return {
value: (baseValue + keyDeadzone) / (1 - keyDeadzone)
}
} else {
return {
value: (baseValue - keyDeadzone) / (1 - keyDeadzone)
}
}
}
return {
value: baseValue
}
};
const buildButtonState = (buttonState, gamepadMapping) => {
const ret = {};
for (let key in gamepadMapping.buttons) {
ret[key] = mapButton(buttonState, gamepadMapping, key)
}
return ret;
}
const buildStickState = (stickState, gamepadMapping) => {
const ret = {};
for (let key in gamepadMapping.sticks) {
ret[key] = mapStick(stickState, gamepadMapping, key)
}
return ret;
}
class Homepad {
constructor() {
if (!window) {
throw new Error('No window available');
}
this.indexToMapping = {};
this.initializeListeners();
}
initializeListeners() {
window.addEventListener('gamepadconnected', (e) => {
const gamepad = e.gamepad;
const gamepadMapping = getGamepadMapping(gamepad.id);
if (gamepadMapping) {
this.indexToMapping[gamepad.index] = gamepadMapping;
}
});
window.addEventListener('gamepaddisconnected', (e) => {
delete this.indexToMapping[gamepad.index];
});
}
getGamepadState(gamepadIndex) {
const gamepad = navigator.getGamepads()[gamepadIndex];
const gamepadMapping = this.indexToMapping[gamepadIndex];
const buttonResponse = buildButtonState(gamepad.buttons, gamepadMapping);
const stickResponse = buildStickState(gamepad.axes, gamepadMapping);
return {
buttons: buttonResponse,
sticks: stickResponse
}
}
getGamepads() {
if (!navigator || !navigator.getGamepads) {
throw new Error('No gamepad API available');
}
const gamepads = navigator.getGamepads();
return gamepads.filter(gamepad => gamepad).map(gamepad => {
return {
index: gamepad.index,
mapping: getGamepadMapping(gamepad.id)
}
}).filter(g => !!g.mapping).map(g => {
return {
state: this.getGamepadState(g.index),
...g
}
});
}
};
module.exports = {
Homepad,
Buttons,
Sticks
};