diff --git a/src/css/animations.scss b/src/css/animations.scss index 0716da70..16ba7fd1 100644 --- a/src/css/animations.scss +++ b/src/css/animations.scss @@ -1,4 +1,4 @@ -@each $num in ("changeAnimEven", "changeAnimOdd") { +@each $animName in ("changeAnimEven", "changeAnimOdd") { @keyframes #{$animName} { 0% { transform: scale(1, 1); diff --git a/src/js/application.js b/src/js/application.js index d9ca7641..f3461ab5 100644 --- a/src/js/application.js +++ b/src/js/application.js @@ -366,6 +366,8 @@ export class Application { const time = performance.now(); + this.inputMgr.processGamepadInputs(); + // Periodically check for resizes, this is expensive (takes 2-3ms so only do it once in a while!) if (!this.lastResizeCheck || time - this.lastResizeCheck > 1000) { this.checkResize(); diff --git a/src/js/core/input_distributor.js b/src/js/core/input_distributor.js index 03ad8e0c..a63da6e9 100644 --- a/src/js/core/input_distributor.js +++ b/src/js/core/input_distributor.js @@ -28,6 +28,8 @@ export class InputDistributor { */ this.keysDown = new Set(); + this.connectedGamepadIndex = null; + this.bindToEvents(); } @@ -149,6 +151,8 @@ export class InputDistributor { window.addEventListener("mouseup", this.handleKeyMouseUp.bind(this)); window.addEventListener("blur", this.handleBlur.bind(this)); + + window.addEventListener("gamepadconnected", this.handleGamepadConnected.bind(this)) } forwardToReceiver(eventId, payload = null) { @@ -169,6 +173,45 @@ export class InputDistributor { return signal.dispatch(payload); } + handleGamepadConnected(event) { + this.connectedGamepadIndex = event.gamepad.index; + } + + processGamepadInputs() { + if (this.connectedGamepadIndex === null) { + return + } + + const gamepad = navigator.getGamepads()[this.connectedGamepadIndex]; + + for (const [index, button] of gamepad.buttons.entries()) { + const keyCode = 200 + index + const isInitial = !this.keysDown.has(keyCode); + + if (button.pressed) { + logger.debug(`gamepad button [${index}]: ${button.pressed ? 'pressed' : ''}`) + this.keysDown.add(keyCode); + + this.forwardToReceiver("keydown", { + keyCode: keyCode, + shift: 0, + alt: 0, + initial: isInitial, + }) + } + if (!button.pressed && !isInitial) { + this.keysDown.delete(keyCode); + + this.forwardToReceiver("keyup", { + keyCode: keyCode, + shift: 0, + alt: 0, + }); + } + } + } + + /** * @param {Event} event */ diff --git a/src/js/states/keybindings.js b/src/js/states/keybindings.js index a01629f1..89edca10 100644 --- a/src/js/states/keybindings.js +++ b/src/js/states/keybindings.js @@ -99,7 +99,7 @@ export class KeybindingsState extends TextualGameState { event.preventDefault(); } - if (event.target && event.target.tagName === "BUTTON" && keyCode === 1) { + if (event && event.target && event.target.tagName === "BUTTON" && keyCode === 1) { return; } @@ -117,7 +117,7 @@ export class KeybindingsState extends TextualGameState { this.updateKeybindings(); }); - dialog.inputReciever.backButton.add(() => {}); + dialog.inputReciever.backButton.add(() => { }); this.dialogs.internalShowDialog(dialog); this.app.sound.playUiSound(SOUNDS.dialogOk); diff --git a/yarn.lock b/yarn.lock index 4a7612d0..0e84ad55 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5103,14 +5103,6 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -line-column@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/line-column/-/line-column-1.0.2.tgz#d25af2936b6f4849172b312e4792d1d987bc34a2" - integrity sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI= - dependencies: - isarray "^1.0.0" - isobject "^2.0.0" - load-bmfont@^1.3.1, load-bmfont@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.0.tgz#75f17070b14a8c785fe7f5bee2e6fd4f98093b6b" @@ -5619,10 +5611,10 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== -nanoid@^3.1.12: - version "3.1.12" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.12.tgz#6f7736c62e8d39421601e4a0c77623a97ea69654" - integrity sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A== +nanoid@^3.1.20: + version "3.1.20" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" + integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== nanomatch@^1.2.9: version "1.2.13" @@ -6927,6 +6919,15 @@ postcss-zindex@^4.0.1: postcss "^7.0.0" uniqs "^2.0.0" +postcss@>=5.0.0: + version "8.2.1" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.1.tgz#eabc5557c4558059b9d9e5b15bce7ffa9089c2a8" + integrity sha512-RhsqOOAQzTgh1UB/IZdca7F9WDb7SUCR2Vnv1x7DbvuuggQIpoDwjK+q0rzoPffhYvWNKX5JSwS4so4K3UC6vA== + dependencies: + colorette "^1.2.1" + nanoid "^3.1.20" + source-map "^0.6.1" + postcss@^5.0.2: version "5.2.18" resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" @@ -6955,16 +6956,6 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2 source-map "^0.6.1" supports-color "^6.1.0" -postcss@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.1.1.tgz#c3a287dd10e4f6c84cb3791052b96a5d859c9389" - integrity sha512-9DGLSsjooH3kSNjTZUOt2eIj2ZTW0VI2PZ/3My+8TC7KIbH2OKwUlISfDsf63EP4aiRUt3XkEWMWvyJHvJelEg== - dependencies: - colorette "^1.2.1" - line-column "^1.0.2" - nanoid "^3.1.12" - source-map "^0.6.1" - prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"