diff --git a/main.js b/main.js index d01a4c5..d2d2d62 100644 --- a/main.js +++ b/main.js @@ -17,6 +17,10 @@ function bound(low, x, high) { // standard SNES buttons.) class SnesInput { constructor() { + this.reset(); + } + + reset() { this.up = false; this.down = false; this.left = false; @@ -95,12 +99,39 @@ class SnesInput { } } +class SnesGamepad { + update(input) { + const gamepads = navigator.getGamepads(); + if (gamepads.length < 1 || !gamepads[0] || !gamepads[0].connected) { + input.reset(); + return; + } + this.wasConnected = true; + // TODO: have a config screen instead of hard-coding the 8Bitdo SNES30 pad. + const gamepad = gamepads[0]; + input.up = gamepad.axes[1] < 0; + input.down = gamepad.axes[1] > 0; + input.left = gamepad.axes[0] < 0; + input.right = gamepad.axes[0] > 0; + input.a = gamepad.buttons[0].pressed; + input.b = gamepad.buttons[1].pressed; + input.x = gamepad.buttons[3].pressed; + input.y = gamepad.buttons[4].pressed; + input.l = gamepad.buttons[6].pressed; + input.r = gamepad.buttons[7].pressed; + input.select = gamepad.buttons[10].pressed; + input.start = gamepad.buttons[11].pressed; + } +} + class InputHandler { constructor() { this.keysPressed = {}; - - window.addEventListener('gamepadconnected', this.gamepadConnected); - window.addEventListener('gamepaddisconnected', this.gamepadDisconnected); + this.gamepad = new SnesGamepad(); + window.addEventListener( + 'gamepadconnected', (e) => this.gamepadConnected(e)); + window.addEventListener( + 'gamepaddisconnected', (e) => this.gamepadDisconnected(e)); document.addEventListener('keydown', (e) => this.keyDown(e)); document.addEventListener('keyup', (e) => this.keyUp(e)); } @@ -114,40 +145,23 @@ class InputHandler { } update(input) { + this.gamepad.update(input); + // Default ZSNES keybindings. See: // http://zsnes-docs.sourceforge.net/html/readme.htm#default_keys - input.up = this.keysPressed['ArrowUp']; - input.down = this.keysPressed['ArrowDown']; - input.left = this.keysPressed['ArrowLeft']; - input.right = this.keysPressed['ArrowRight']; - input.start = this.keysPressed['Enter']; - input.select = this.keysPressed['Shift']; - input.a = this.keysPressed['x']; - input.b = this.keysPressed['z']; - input.x = this.keysPressed['s']; - input.y = this.keysPressed['a']; - input.l = this.keysPressed['d']; - input.r = this.keysPressed['c']; - - const gamepad = navigator.getGamepads()[0]; - if (gamepad == null || !gamepad.connected || gamepad.axes.length < 2 || - gamepad.buttons.length < 12) { - return; - } - // TODO: have a config screen instead of hard-coding the 8Bitdo SNES30 pad. - // TODO: handle connects / disconnects more correctly. - input.up |= gamepad.axes[1] < 0; - input.down |= gamepad.axes[1] > 0; - input.left |= gamepad.axes[0] < 0; - input.right |= gamepad.axes[0] > 0; - input.a |= gamepad.buttons[0].pressed; - input.b |= gamepad.buttons[1].pressed; - input.x |= gamepad.buttons[3].pressed; - input.y |= gamepad.buttons[4].pressed; - input.l |= gamepad.buttons[6].pressed; - input.r |= gamepad.buttons[7].pressed; - input.select |= gamepad.buttons[10].pressed; - input.start |= gamepad.buttons[11].pressed; + input.up |= this.keysPressed['ArrowUp']; + input.down |= this.keysPressed['ArrowDown']; + input.left |= this.keysPressed['ArrowLeft']; + input.right |= this.keysPressed['ArrowRight']; + input.start |= this.keysPressed['Enter']; + input.select |= this.keysPressed['Shift']; + input.a |= this.keysPressed['x']; + input.b |= this.keysPressed['z']; + input.x |= this.keysPressed['s']; + input.y |= this.keysPressed['a']; + input.l |= this.keysPressed['d']; + input.r |= this.keysPressed['c']; + debug(input.toString()); }