gamepad support
This commit is contained in:
parent
815a589b23
commit
0c4c6fe58c
64
app/src/js/gamepad.ts
Normal file
64
app/src/js/gamepad.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
////
|
||||||
|
// Support for gamepads.
|
||||||
|
// Maps incoming gamepad button presses to keyboard buttons.
|
||||||
|
//
|
||||||
|
|
||||||
|
const BUTTONS = [
|
||||||
|
"A", "B", "X", "Y",
|
||||||
|
"LB", "RB", "LT", "RT",
|
||||||
|
"Select", "Start",
|
||||||
|
"LStick", "RStick",
|
||||||
|
"DPad Up", "DPad Down", "DPad Left", "DPad Right"
|
||||||
|
]
|
||||||
|
|
||||||
|
const BUTTONS_TO_KEYS: Record<number, string> = {
|
||||||
|
0: "z", // A → Z
|
||||||
|
1: "x", // B → X
|
||||||
|
2: "c", // X → C
|
||||||
|
3: "v", // Y → V
|
||||||
|
12: "ArrowUp",
|
||||||
|
13: "ArrowDown",
|
||||||
|
14: "ArrowLeft",
|
||||||
|
15: "ArrowRight",
|
||||||
|
9: "Enter", // Start
|
||||||
|
8: "Escape" // Select
|
||||||
|
}
|
||||||
|
|
||||||
|
const activePads = new Set<number>()
|
||||||
|
const prevState: Record<number, boolean[]> = {}
|
||||||
|
|
||||||
|
export function initGamepad() {
|
||||||
|
window.addEventListener("gamepadconnected", e => {
|
||||||
|
console.log("Gamepad connected:", e.gamepad)
|
||||||
|
activePads.add(e.gamepad.index)
|
||||||
|
requestAnimationFrame(handleGamepad)
|
||||||
|
})
|
||||||
|
|
||||||
|
window.addEventListener("gamepaddisconnected", e => {
|
||||||
|
console.log("Gamepad disconnected:", e.gamepad)
|
||||||
|
activePads.delete(e.gamepad.index)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleGamepad() {
|
||||||
|
const pads = navigator.getGamepads()
|
||||||
|
for (const gp of pads) {
|
||||||
|
if (!gp) continue
|
||||||
|
if (!prevState[gp.index]) prevState[gp.index] = gp.buttons.map(() => false)
|
||||||
|
|
||||||
|
gp.buttons.forEach((btn, i) => {
|
||||||
|
const was = prevState[gp.index]![i]
|
||||||
|
const is = btn.pressed
|
||||||
|
if (was !== is) {
|
||||||
|
const key = BUTTONS_TO_KEYS[i]
|
||||||
|
if (key) {
|
||||||
|
const type = is ? "keydown" : "keyup"
|
||||||
|
window.dispatchEvent(new KeyboardEvent(type, { code: key, key }))
|
||||||
|
}
|
||||||
|
prevState[gp.index]![i] = is
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(handleGamepad)
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ import { initCompletion } from "./completion.js"
|
||||||
import { initCursor } from "./cursor.js"
|
import { initCursor } from "./cursor.js"
|
||||||
import { initEditor } from "./editor.js"
|
import { initEditor } from "./editor.js"
|
||||||
import { initFocus } from "./focus.js"
|
import { initFocus } from "./focus.js"
|
||||||
|
import { initGamepad } from "./gamepad.js"
|
||||||
import { initHistory } from "./history.js"
|
import { initHistory } from "./history.js"
|
||||||
import { initHyperlink } from "./hyperlink.js"
|
import { initHyperlink } from "./hyperlink.js"
|
||||||
import { initInput } from "./input.js"
|
import { initInput } from "./input.js"
|
||||||
|
|
@ -13,6 +14,7 @@ initCompletion()
|
||||||
initCursor()
|
initCursor()
|
||||||
initFocus()
|
initFocus()
|
||||||
initEditor()
|
initEditor()
|
||||||
|
initGamepad()
|
||||||
initHistory()
|
initHistory()
|
||||||
initHyperlink()
|
initHyperlink()
|
||||||
initInput()
|
initInput()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user