├── 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 = '
[BTN#]
'; 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 | \ 281 | \ 282 | \ 283 | \ 284 | \ 285 | \ 286 | \ 287 | \ 288 | \ 289 | \ 290 | \ 291 | \ 292 | \ 293 | \ 294 | \ 295 | \ 296 | \ 297 | \ 298 | \ 299 | \ 300 | \ 301 | \ 302 | \ 303 | \ 304 | \ 305 | \ 306 | \ 307 | \ 308 | \ 309 | \ 310 | \ 311 |
LB
RB
LT
Y
RT
Select
Start
X
B
A
Left Thumb
Right Thumb
\ 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 | Fork me on GitHub 10 | 11 | 12 |
13 |
Please press a button on any gamepad.
14 | 33 |
34 | 35 | 36 | 37 | 38 | --------------------------------------------------------------------------------