├── LICENSE
├── README.md
├── gamepad.css
├── gamepad.js
├── gamepad_visualizer.js
├── images
├── crosshair_ball.png
├── crosshair_ball2.png
├── crosshair_ball3.png
├── crosshair_mine.png
├── crosshair_mine2.png
├── crosshair_star.png
├── crosshair_thick.png
├── crosshair_thin.png
├── dpad.png
├── grid.png
├── trigger_meter.png
└── trigger_meter_fill.png
└── index.html
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2014 Microsoft Corporation
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Gamepad-Sample
2 | ==============
3 |
4 | A basic sample on how to use the W3C GamePad API across browsers. Try the [demo](http://internetexplorer.github.io/Gamepad-Sample) in the new [IE Developer Channel](http://devchannel.modern.IE).
5 |
6 | ### Code of Conduct
7 |
8 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
9 |
--------------------------------------------------------------------------------
/gamepad.css:
--------------------------------------------------------------------------------
1 | .gpTableCell {
2 | border: solid 2px gray;
3 | border-radius: 6px;
4 | }
5 |
6 | .gpTableCellUnConnected {
7 | border-color: lightgray;
8 | color: gray;
9 | }
10 |
11 | .gpNotConnectedText {
12 | font-size: 26pt;
13 | text-align: center;
14 | }
15 |
16 | #gamepadStateTable, #gamepadStateTable th {
17 | border-collapse: collapse;
18 | }
19 |
20 | #gamepadStateTable th {
21 | font-weight: bold;
22 | text-align:left;
23 | }
24 |
25 | #gamepadStateTable td, #gamepadStateTable th {
26 | border: solid 1px #0094FF;
27 | padding: 1px 5px 1px 5px;
28 | }
29 |
30 | .AxisVisualizer {
31 | width: 108px;
32 | height: 108px;
33 | background-image: url(images/crosshair_ball3.png), url(images/grid.png);
34 | background-position: 10px 10px, 4px 4px;
35 | background-repeat: no-repeat;
36 | }
37 |
38 | .AnalogButtonVisualizer {
39 | width: 30px;
40 | height: 100px;
41 | background-image: url(images/trigger_meter_fill.png), url(images/trigger_meter.png);
42 | background-repeat: no-repeat;
43 | font-weight: bold;
44 | text-align: center;
45 | }
46 |
47 | .VisualizerGeneric {
48 | float: left;
49 | margin: 5px;
50 | }
51 |
52 | .AnalogButtonVisualizer #val {
53 | font-size: 9pt;
54 | font-weight: normal;
55 | }
56 |
57 | .oval {
58 | border: solid 1px #0094FF;
59 | border-radius: 3px 3px;
60 | background-clip: border-box;
61 | font-weight: bold;
62 | text-align: center;
63 | }
64 |
65 | .circle {
66 | width: 20px;
67 | height: 20px;
68 | border: solid 1px #0094FF;
69 | border-radius: 100%;
70 | background-clip: border-box;
71 | font-weight: bold;
72 | text-align: center;
73 | line-height: 20px;
74 | }
75 |
76 | .DPad {
77 | position: relative;
78 | left: 10px;
79 | width: 65px;
80 | height: 64px;
81 | background-image: url(images/dpad.png);
82 | }
83 |
84 | .btnDU, .btnDL, .btnDR, .btnDD {
85 | width: 20px;
86 | height: 20px;
87 | position: absolute;
88 | }
89 |
90 | .btnDU {
91 | left: 23px;
92 | top: 1px;
93 | border-radius: 3px 3px 0px 0px;
94 | }
95 |
96 | .btnDL {
97 | left: 1px;
98 | top: 22px;
99 | border-radius: 3px 0px 0px 3px;
100 | }
101 |
102 | .btnDR {
103 | left: 44px;
104 | top: 23px;
105 | border-radius: 0px 3px 3px 0px;
106 | }
107 |
108 | .btnDD {
109 | left: 23px;
110 | top: 43px;
111 | border-radius: 0px 0px 3px 3px;
112 | }
113 |
114 | .selOrStart {
115 | width: 45px;
116 | }
117 |
118 | .bumper {
119 | width: 80px;
120 | }
121 |
122 | #gamepadSupportedDiv {
123 | font-size: 4em;
124 | }
125 |
126 | #buttonNeverPressedDiv {
127 | font-size: 3em;
128 | }
129 |
--------------------------------------------------------------------------------
/gamepad.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | function Init() {
4 | if (navigator.getGamepads === undefined) {
5 | document.getElementById("gamepadSupportedDiv").style.display = "block";
6 | document.getElementById("gamepadDisplayDiv").style.display = "none";
7 | } else {
8 | window.requestAnimationFrame(runAnimation);
9 | }
10 | }
11 |
12 | // --------------------------------------
13 | // Animation loop
14 | // --------------------------------------
15 | var buttonPressedOnAnyGamepadEver = false;
16 | var gamepadVisualizers = [];
17 | function runAnimation() {
18 | // Get the latest gamepad state.
19 | var gamepads = navigator.getGamepads();
20 | for (var i = 0; i < gamepads.length; i++) {
21 | var pad = gamepads[i];
22 | if (pad) {
23 | // Gamepads physically plugged into the system will not be visible to JavaScript until
24 | // the user has pressed a button on a gamepad. Note that each browser has slightly different
25 | // behavior for which buttons need to be pressed.
26 | if (!buttonPressedOnAnyGamepadEver) {
27 | document.getElementById("buttonNeverPressedDiv").style.display = "none";
28 | document.getElementById("buttonPressedDiv").style.display = "block";
29 | buttonPressedOnAnyGamepadEver = true;
30 | }
31 |
32 | var usingStandardMapping = (pad.mapping && pad.mapping === "standard");
33 | var gamepadVisualizer = usingStandardMapping ? new StandardGamepadVisualizer(pad) : new GenericGamepadVisualizer(pad);
34 | gamepadVisualizers[i] = gamepadVisualizer;
35 | } else {
36 | if (gamepadVisualizers[i]) {
37 | gamepadVisualizers[i].retired = true;
38 | }
39 | }
40 | }
41 |
42 | for (var i = 0; i < gamepadVisualizers.length; i++) {
43 | var gamepadVisualizer = gamepadVisualizers[i];
44 | if (gamepadVisualizers[i]) {
45 | gamepadVisualizer.UpdateView();
46 | }
47 | }
48 |
49 | window.requestAnimationFrame(runAnimation);
50 | }
51 |
52 | // --------------------------------------
53 | // Misc.
54 | // --------------------------------------
55 | function FloatValueAsString(flValue) {
56 | var strVal = flValue.toString();
57 | strVal = strVal.substring(0, 4);
58 | return strVal;
59 | }
60 |
61 | var stateTableRowTemplate = '\
62 |
gpIndex | \
63 | gpTimestamp | \
64 | gpMapping | \
65 | gpConnected | \
66 | gpId | \
67 | ';
68 |
69 | function UpdateGamepadStateTable(gamepad, index) {
70 | var connectedStr = "N/A";
71 | var indexStr = "N/A";
72 | var timestampStr = "N/A";
73 | var mappingStr = "N/A";
74 | var idStr = "N/A";
75 | if (gamepad) {
76 | idStr = (gamepad.id !== undefined) ? gamepad.id : "undefined";
77 | mappingStr = (gamepad.mapping !== undefined) ? gamepad.mapping : "undefined";
78 | indexStr = (gamepad.index !== undefined) ? gamepad.index : "undefined";
79 | connectedStr = (gamepad.connected !== undefined) ? gamepad.connected : "undefined";
80 | timestampStr = (gamepad.timestamp !== undefined) ? (gamepad.timestamp / 1000) + "s" : "undefined";
81 | }
82 |
83 | var newRow = stateTableRowTemplate;
84 | newRow = newRow.replace(/gpIndex/g, indexStr);
85 | newRow = newRow.replace(/gpTimestamp/g, timestampStr);
86 | newRow = newRow.replace(/gpMapping/g, mappingStr);
87 | newRow = newRow.replace(/gpConnected/g, connectedStr);
88 | newRow = newRow.replace(/gpId/g, idStr);
89 | var containerElem = document.getElementById("gpStateTableRow" + index);
90 | containerElem.innerHTML = newRow.replace(/\[#\]/g, index);
91 | }
92 |
93 | function ClearGamepadStateTableRow(index) {
94 | var containerElem = document.getElementById("gpStateTableRow" + index);
95 | containerElem.innerHTML = "";
96 | }
--------------------------------------------------------------------------------
/gamepad_visualizer.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // --------------------------------------
4 | // StandardGamepadVisualizer
5 | // --------------------------------------
6 | function StandardGamepadVisualizer(pad) {
7 | this.pad = pad;
8 | this.index = pad.index;
9 | this.containerElemId = "gp" + this.index + "Cell";
10 | this.leftThumbVisualizer = new AxisVisualizer("gp" + this.index + "leftThumb");
11 | this.rightThumbVisualizer = new AxisVisualizer("gp" + this.index + "rightThumb");
12 | this.leftTriggerVisualizer = new AnalogButtonVisualizer("gp" + this.index + "LT");
13 | this.rightTriggerVisualizer = new AnalogButtonVisualizer("gp" + this.index + "RT");
14 | this.retired = false;
15 |
16 | this.UpdateView = function StandardGamepadVisualizer_UpdateView() {
17 | var pad = this.pad;
18 | var containerElem = document.getElementById(this.containerElemId);
19 |
20 | if (pad && !this.retired) {
21 | if (pad.mapping === "standard") {
22 | var templateStr = starndardGamepadVisualizerTemplate.replace(/gp\[#\]/g, "gp" + this.index);
23 | containerElem.innerHTML = templateStr;
24 |
25 | this.leftThumbVisualizer.setXAxisValue(pad.axes[0]);
26 | this.leftThumbVisualizer.setYAxisValue(pad.axes[1]);
27 |
28 | this.rightThumbVisualizer.setXAxisValue(pad.axes[2]);
29 | this.rightThumbVisualizer.setYAxisValue(pad.axes[3]);
30 |
31 | var buttonLeftTrigger = pad.buttons[6];
32 | var buttonRightTrigger = pad.buttons[7];
33 |
34 | this.leftTriggerVisualizer.setValue(buttonLeftTrigger.value, buttonLeftTrigger.pressed);
35 | this.rightTriggerVisualizer.setValue(buttonRightTrigger.value, buttonRightTrigger.pressed);
36 |
37 | this.UpdateButtons(pad);
38 |
39 | UpdateGamepadStateTable(pad, pad.index);
40 | containerElem.classList.remove("gpTableCellUnConnected");
41 | }
42 | } else {
43 | containerElem.innerHTML = "Gamepad not connected.
";
44 | ClearGamepadStateTableRow(this.index);
45 | containerElem.classList.add("gpTableCellUnConnected");
46 | }
47 | }
48 |
49 | this.buttonMap = [
50 | { buttonIndex: 0, elemIdTemplate: "gp[#]BtnA" },
51 | { buttonIndex: 1, elemIdTemplate: "gp[#]BtnB" },
52 | { buttonIndex: 2, elemIdTemplate: "gp[#]BtnX" },
53 | { buttonIndex: 3, elemIdTemplate: "gp[#]BtnY" },
54 | { buttonIndex: 4, elemIdTemplate: "gp[#]BtnLB" },
55 | { buttonIndex: 5, elemIdTemplate: "gp[#]BtnRB" },
56 | { buttonIndex: 8, elemIdTemplate: "gp[#]BtnSelect" },
57 | { buttonIndex: 9, elemIdTemplate: "gp[#]BtnStart" },
58 | { buttonIndex: 10, elemIdTemplate: "gp[#]BtnLThumb" },
59 | { buttonIndex: 11, elemIdTemplate: "gp[#]BtnRThumb" },
60 | { buttonIndex: 12, elemIdTemplate: "gp[#]BtnDU" },
61 | { buttonIndex: 13, elemIdTemplate: "gp[#]BtnDD" },
62 | { buttonIndex: 14, elemIdTemplate: "gp[#]BtnDL" },
63 | { buttonIndex: 15, elemIdTemplate: "gp[#]BtnDR" }
64 | ];
65 |
66 | this.UpdateButtons = function StandardGamepadVisualizer_UpdateButtons(pad) {
67 | for (var i = 0; i < this.buttonMap.length; i++) {
68 | var visualizer = this.buttonMap[i].visualizer;
69 | if (this.buttonMap[i].buttonIndex < pad.buttons.length) {
70 | var index = this.buttonMap[i].buttonIndex;
71 | var button = pad.buttons[index];
72 | visualizer.setValue(button.value, button.pressed);
73 | }
74 | }
75 | }
76 |
77 | this.Init = function _Init() {
78 | for (var i = 0; i < this.buttonMap.length; i++) {
79 | var elemId = this.buttonMap[i].elemIdTemplate.replace(/\[#\]/g, this.index);
80 | this.buttonMap[i].visualizer = new DigitalButtonVisualizer(elemId);
81 | }
82 | }
83 | this.Init();
84 | }
85 |
86 |
87 | // --------------------------------------
88 | // GenericGamepadVisualizer
89 | // --------------------------------------
90 | function GenericGamepadVisualizer(pad) {
91 | this.pad = pad;
92 | this.index = pad.index;
93 | this.containerElemId = "gp" + this.index + "Cell";
94 | this.retired = false;
95 |
96 | this.Init = function GenericGamepadVisualizer_Init(pad) {
97 | var containerElem = document.getElementById(this.containerElemId);
98 | var strInject = "";
99 |
100 | var buttonTemplateStr = '';
101 | for (var index = 0; index < pad.buttons.length; index++) {
102 | var elemId = "gp" + this.index + "Btn" + index;
103 | var buttonStr = buttonTemplateStr.replace(/gp\[#\]/g, elemId);
104 | buttonStr = buttonStr.replace(/\[BTN#\]/g, "B" + index);
105 | strInject += buttonStr;
106 | }
107 | strInject += "
";
108 |
109 | var axisTemplateStr = '';
110 | for (var index = 0; index < pad.axes.length; index += 2) {
111 | var elemId = "gp" + this.index + "Axis" + index;
112 | var axisStr = axisTemplateStr.replace(/gp\[#\]/g, elemId);
113 | strInject += axisStr;
114 | }
115 |
116 | containerElem.innerHTML = strInject;
117 | }
118 |
119 | this.UpdateView = function GenericGamepadVisualizer_UpdateView() {
120 | var pad = this.pad;
121 | var containerElem = document.getElementById(this.containerElemId);
122 | if (pad && !this.retired) {
123 | if (pad.mapping === "" /* Firefox doesn't use the "standard" mapping. */) {
124 | for (var index = 0; index < pad.buttons.length; index++) {
125 | var elemId = "gp" + this.index + "Btn" + index;
126 | var visualizer = new AnalogButtonVisualizer(elemId);
127 | var button = pad.buttons[index];
128 | visualizer.setValue(button.value, button.pressed);
129 | }
130 |
131 | for (var index = 0; index < pad.axes.length; index += 2) {
132 | var elemId = "gp" + this.index + "Axis" + index;
133 | var visualizer = new AxisVisualizer(elemId);
134 | visualizer.setXAxisValue(pad.axes[index]);
135 | if (pad.axes[index + 1]) {
136 | visualizer.setYAxisValue(pad.axes[index + 1]);
137 | }
138 | }
139 |
140 | UpdateGamepadStateTable(pad, pad.index);
141 | containerElem.classList.remove("gpTableCellUnConnected");
142 | }
143 | } else {
144 | containerElem.innerHTML = "Gamepad not connected.
";
145 | ClearGamepadStateTableRow(this.index);
146 | containerElem.classList.add("gpTableCellUnConnected");
147 | }
148 | }
149 | this.Init(pad);
150 | }
151 |
152 | // --------------------------------------
153 | // AxisVisualizer
154 | // --------------------------------------
155 | function AxisVisualizer(elemId) {
156 | this.XAxisValue = 0.0;
157 | this.YAxisValue = 0.0;
158 | this.elemId = elemId;
159 | this.cxCursor = 11;
160 |
161 | this.setElemStyles = function AxisVisualizer_setElemStyles(elem) {
162 | var cxImage = 100 + (this.cxCursor - 1);
163 | var cxOffset = (this.cxCursor - 1) / 2;
164 | elem.style.width = cxImage + "px";
165 | elem.style.height = cxImage + "px";
166 | var xAxisLeft = Math.round((this.XAxisValue + 1.0) * 50);
167 | var yAxisRight = Math.round((this.YAxisValue + 1.0) * 50);
168 | elem.style.backgroundPosition = xAxisLeft + "px " + yAxisRight + "px, " + cxOffset + "px " + cxOffset + "px";
169 |
170 | if (this.value > 1.0 || this.value < -1.0) { alert('Invalid Value!') };
171 | var childNodes = elem.childNodes;
172 | var lastChild = childNodes[childNodes.length - 1];
173 | lastChild.innerHTML = FloatValueAsString(this.XAxisValue) + ',' + FloatValueAsString(this.YAxisValue);
174 | }
175 |
176 | this.setXAxisValue = function AxisVisualizer_setXAxisValue(val) {
177 | if (val < -1.0) {
178 | val = -1.0;
179 | }
180 | else if (val > 1.0) {
181 | val = 1.0;
182 | }
183 | this.XAxisValue = val;
184 | this.onValueChange();
185 | }
186 |
187 | this.setYAxisValue = function AxisVisualizer_setYAxisValue(val) {
188 | if (val < -1.0) {
189 | val = -1.0;
190 | }
191 | else if (val > 1.0) {
192 | val = 1.0;
193 | }
194 | this.YAxisValue = val;
195 | this.onValueChange();
196 | }
197 |
198 | this.onValueChange = function AxisVisualizer_onValueChange() {
199 | var elem = document.getElementById(this.elemId);
200 | this.setElemStyles(elem);
201 | }
202 | }
203 |
204 | // --------------------------------------
205 | // AnalogButtonVisualizer
206 | // --------------------------------------
207 | function AnalogButtonVisualizer(elemId) {
208 | this.elemId = elemId;
209 | this.value = 0;
210 | this.fIsPressed = false;
211 |
212 | this.setElemStyles = function AnalogButtonVisualizer_setElemStyles(elem) {
213 | var cxHeight = Math.round(this.value * 98);
214 | var top = 100 - cxHeight - 1
215 | elem.style.backgroundPosition = "1px " + top + "px, 0px 0px";
216 | elem.style.backgroundSize = "28px " + cxHeight + "px, 30px 100px";
217 | if (this.fIsPressed) {
218 | elem.style.color = "salmon";
219 | }
220 | else {
221 | elem.style.color = "black";
222 | }
223 |
224 | if (this.value > 1.0 || this.value < 0) { alert('oops!') };
225 | var childNodes = elem.childNodes;
226 | var lastChild = childNodes[childNodes.length - 1];
227 | lastChild.innerHTML = FloatValueAsString(this.value);
228 | }
229 |
230 | this.setValue = function AnalogButtonVisualizer_setValue(val, fIsPressed) {
231 | if (val < -1.0) {
232 | val = -1.0;
233 | }
234 | else if (val > 1.0) {
235 | val = 1.0;
236 | }
237 | this.value = val;
238 | this.fIsPressed = fIsPressed;
239 |
240 | var elem = document.getElementById(this.elemId);
241 | this.setElemStyles(elem);
242 | }
243 | }
244 |
245 | // --------------------------------------
246 | // DigitalButtonVisualizer
247 | // --------------------------------------
248 | function DigitalButtonVisualizer(elemId) {
249 | this.elemId = elemId;
250 | this.value = 0;
251 | this.fIsPressed = false;
252 |
253 | this.setElemStyles = function DigitalButtonVisualizer_setElemStyles(elem) {
254 | if (this.value === 1.0) {
255 | elem.style.backgroundColor = "#8AFF59";
256 | } else {
257 | elem.style.backgroundColor = "transparent";
258 | }
259 |
260 | if (this.fIsPressed) {
261 | elem.style.color = "salmon";
262 | }
263 | else {
264 | elem.style.color = "black";
265 | }
266 | }
267 |
268 | this.setValue = function DigitalButtonVisualizer_setValue(val, fIsPressed) {
269 | this.value = val;
270 | this.fIsPressed = fIsPressed;
271 | var elem = document.getElementById(this.elemId);
272 | this.setElemStyles(elem);
273 | }
274 | }
275 |
276 | var starndardGamepadVisualizerTemplate = '\
277 | \
278 | \
279 | | \
280 | LB | \
281 | | \
282 | RB | \
283 | | \
284 |
\
285 | \
286 | | \
287 | | \
288 | | \
289 | Y | \
290 | | \
291 | | \
292 |
\
293 | \
294 | Select | \
295 | Start | \
296 | X | \
297 | | \
298 | B | \
299 |
\
300 | | A |
\
301 | \
302 | | \
303 | Left Thumb | \
304 | Right Thumb | \
305 |
\
306 | \
307 | | \
308 | | \
309 | | \
310 |
\
311 |
\
312 | ';
--------------------------------------------------------------------------------
/images/crosshair_ball.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MicrosoftEdge/Gamepad-Sample/20ec3992488d7d233432a4feef50e3aa2b9d331c/images/crosshair_ball.png
--------------------------------------------------------------------------------
/images/crosshair_ball2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MicrosoftEdge/Gamepad-Sample/20ec3992488d7d233432a4feef50e3aa2b9d331c/images/crosshair_ball2.png
--------------------------------------------------------------------------------
/images/crosshair_ball3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MicrosoftEdge/Gamepad-Sample/20ec3992488d7d233432a4feef50e3aa2b9d331c/images/crosshair_ball3.png
--------------------------------------------------------------------------------
/images/crosshair_mine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MicrosoftEdge/Gamepad-Sample/20ec3992488d7d233432a4feef50e3aa2b9d331c/images/crosshair_mine.png
--------------------------------------------------------------------------------
/images/crosshair_mine2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MicrosoftEdge/Gamepad-Sample/20ec3992488d7d233432a4feef50e3aa2b9d331c/images/crosshair_mine2.png
--------------------------------------------------------------------------------
/images/crosshair_star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MicrosoftEdge/Gamepad-Sample/20ec3992488d7d233432a4feef50e3aa2b9d331c/images/crosshair_star.png
--------------------------------------------------------------------------------
/images/crosshair_thick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MicrosoftEdge/Gamepad-Sample/20ec3992488d7d233432a4feef50e3aa2b9d331c/images/crosshair_thick.png
--------------------------------------------------------------------------------
/images/crosshair_thin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MicrosoftEdge/Gamepad-Sample/20ec3992488d7d233432a4feef50e3aa2b9d331c/images/crosshair_thin.png
--------------------------------------------------------------------------------
/images/dpad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MicrosoftEdge/Gamepad-Sample/20ec3992488d7d233432a4feef50e3aa2b9d331c/images/dpad.png
--------------------------------------------------------------------------------
/images/grid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MicrosoftEdge/Gamepad-Sample/20ec3992488d7d233432a4feef50e3aa2b9d331c/images/grid.png
--------------------------------------------------------------------------------
/images/trigger_meter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MicrosoftEdge/Gamepad-Sample/20ec3992488d7d233432a4feef50e3aa2b9d331c/images/trigger_meter.png
--------------------------------------------------------------------------------
/images/trigger_meter_fill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MicrosoftEdge/Gamepad-Sample/20ec3992488d7d233432a4feef50e3aa2b9d331c/images/trigger_meter_fill.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
Please press a button on any gamepad.
14 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------