/* Joystick gesture */ /* cross == a <--> a circle == b <--> b square == x <--> start triangle == y <--> select share <--> load option <--> save L2 == LT <--> full R2 == RT <--> quit dpad <--> up down left right axis 0, 1 <--> second dpad */ /* change full to help (temporary) */ let joystickMap; let joystickState; let joystickIdx; let joystickTimer = null; // check state for each axis -> dpad function checkJoystickAxisState(name, state) { if (joystickState[name] !== state) { joystickState[name] = state; if (state === true) { doButtonDown(name); } else { doButtonUp(name); } } } // loop timer for checking joystick state function checkJoystickState() { var gamepad = navigator.getGamepads()[joystickIdx]; if (gamepad) { // axis -> dpad var corX = gamepad.axes[0]; // -1 -> 1, left -> right var corY = gamepad.axes[1]; // -1 -> 1, up -> down checkJoystickAxisState("left", corX <= -0.5); checkJoystickAxisState("right", corX >= 0.5); checkJoystickAxisState("up", corY <= -0.5); checkJoystickAxisState("down", corY >= 0.5); // normal button map Object.keys(joystickMap).forEach(function (btnIdx) { var isPressed = false; if (navigator.webkitGetGamepads) { isPressed = (gamepad.buttons[btnIdx] === 1); } else { isPressed = (gamepad.buttons[btnIdx].value > 0 || gamepad.buttons[btnIdx].pressed === true); } if (joystickState[btnIdx] !== isPressed) { joystickState[btnIdx] = isPressed; if (isPressed === true) { doButtonDown(joystickMap[btnIdx]); } else { doButtonUp(joystickMap[btnIdx]); } } }); } } // we only capture the last plugged joystick window.addEventListener("gamepadconnected", function (event) { var gamepad = event.gamepad; log(`Gamepad connected at index ${gamepad.index}: ${gamepad.id}. ${gamepad.buttons.length} buttons, ${gamepad.axes.length} axes.`); joystickIdx = gamepad.index; // Ref: https://github.com/giongto35/cloud-game/issues/14 // get mapping first (default KeyMap2) var os = getOS(); var browser = getBrowser(); if (os === "android") { // default of android is KeyMap1 joystickMap = { 2: "a", 0: "b", 3: "start", 4: "select", 10: "load", 11: "save", 8: "help", 9: "quit", 12: "up", 13: "down", 14: "left", 15: "right" }; } else { // default of other OS is KeyMap2 joystickMap = { 0: "a", 1: "b", 2: "start", 3: "select", 8: "load", 9: "save", 6: "help", 7: "quit", 12: "up", 13: "down", 14: "left", 15: "right" }; } if (os === "android" && (browser === "firefox" || browser === "uc")) { //KeyMap2 joystickMap = { 0: "a", 1: "b", 2: "start", 3: "select", 8: "load", 9: "save", 6: "help", 7: "quit", 12: "up", 13: "down", 14: "left", 15: "right" }; } if (os === "win" && browser === "firefox") { //KeyMap3 joystickMap = { 1: "a", 2: "b", 0: "start", 3: "select", 8: "load", 9: "save", 6: "help", 7: "quit" }; } if (os === "mac" && browser === "safari") { //KeyMap4 joystickMap = { 1: "a", 2: "b", 0: "start", 3: "select", 8: "load", 9: "save", 6: "help", 7: "quit", 14: "up", 15: "down", 16: "left", 17: "right" }; } if (os === "mac" && browser === "firefox") { //KeyMap5 joystickMap = { 1: "a", 2: "b", 0: "start", 3: "select", 8: "load", 9: "save", 6: "help", 7: "quit", 14: "up", 15: "down", 16: "left", 17: "right" }; } // reset state joystickState = { left: false, right: false, up: false, down: false, }; Object.keys(joystickMap).forEach(function (btnIdx) { joystickState[btnIdx] = false; }); // looper, too intense? if (joystickTimer !== null) { clearInterval(joystickTimer); } joystickTimer = setInterval(checkJoystickState, 10); // miliseconds per hit }); // disconnected event is triggered window.addEventListener("gamepaddisconnected", (event) => { clearInterval(joystickTimer); log(`Gamepad disconnected at index ${e.gamepad.index}`); });