Skip to content

Instantly share code, notes, and snippets.

@easierbycode
Last active June 13, 2021 15:35
Show Gist options
  • Save easierbycode/8e2935dd68e210713c4167d86852f4b7 to your computer and use it in GitHub Desktop.
Save easierbycode/8e2935dd68e210713c4167d86852f4b7 to your computer and use it in GitHub Desktop.
const MAX_PLAYERS = 4;
const haveEvents = 'ongamepadconnected' in window;
const controllers = {};
// D-PAD AND BUTTONS
// (U, D, L, R, B, A, START)
const buttons = {
U : 12,
D : 13,
L : 14,
R : 15,
B : 2,
A : 0,
S : 9
};
const buttonValues = Object.values( buttons );
const buttonKeys = Object.keys( buttons );
// KeyboardEvent keyCode mappings by gamepad
// i.e. - keyCodes[0] maps to the first gamepad,
// pressing (S)TART triggers a keypress for 13 (ENTER)
const keyCodes = [
{
U : 38,
D : 40,
L : 37,
R : 39,
B : 67,
A : 88,
S : 13
},
{
U : 87,
D : 83,
L : 65,
R : 68
}];
const pendingKeyupEvents = Array( MAX_PLAYERS ).fill({
U : null,
D : null,
L : null,
R : null,
B : null,
A : null,
S : null
});
function connecthandler(e) {
console.log( '.. adding gamepad:' );
console.log( e.gamepad );
addgamepad( e.gamepad );
}
function addgamepad(gamepad) {
controllers[gamepad.index] = gamepad;
requestAnimationFrame(updateStatus);
}
function disconnecthandler(e) {
removegamepad(e.gamepad);
}
function removegamepad(gamepad) {
delete controllers[gamepad.index];
}
function updateStatus() {
if (!haveEvents) {
scangamepads();
}
for (
let controllerIdx = 0;
controllerIdx < Object.keys(controllers).length;
controllerIdx++
) {
var controller = controllers[Object.keys(controllers)[controllerIdx]];
// HOME button - enter fullscreen
if ( controller.buttons[16].pressed ) {
if ( !document.fullscreen ) {
document.getElementById( 'canvas' ).requestFullscreen();
}
}
for (i = 0; i < buttonValues.length; i++) {
let buttonKey = buttonKeys[i];
var val = controller.buttons[buttonValues[i]];
var pressed = val.pressed;
let pendingKeyupEvent = pendingKeyupEvents[controllerIdx][buttonKey];
if ( pressed ) {
let keyCode = keyCodes[controllerIdx][buttonKey];
// if button is still pressed (pendingKeyupEvent),
// don't create / dispatch duplicate events
if ( pendingKeyupEvent && pendingKeyupEvent.keyCode === keyCode ) continue;
var event = document.createEvent('event');
let keyupEvent = document.createEvent('event');
event.initEvent('keydown', true, true);
keyupEvent.initEvent('keyup', true, true);
event.keyCode = keyCode;
keyupEvent.keyCode = keyCode;
document.getElementById( 'canvas' ).dispatchEvent( event );
pendingKeyupEvents[controllerIdx][buttonKey] = keyupEvent;
} else if ( pendingKeyupEvent ) {
document.getElementById( 'canvas' ).dispatchEvent( pendingKeyupEvent );
pendingKeyupEvents[controllerIdx][buttonKey] = null;
}
}
}
requestAnimationFrame(updateStatus);
}
function scangamepads() {
var gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);
for (var i = 0; i < gamepads.length; i++) {
if (gamepads[i]) {
if (gamepads[i].index in controllers) {
controllers[gamepads[i].index] = gamepads[i];
} else {
addgamepad(gamepads[i]);
}
}
}
}
window.addEventListener("gamepadconnected", connecthandler);
window.addEventListener("gamepaddisconnected", disconnecthandler);
if (!haveEvents) scangamepads();
var haveEvents = 'ongamepadconnected' in window;
var controllers = {};
var keyCodes = {
L : 37,
U : 38,
R : 39,
D : 40
};
function connecthandler(e) {
console.log( '.. adding gamepad:' );
console.log( e.gamepad );
addgamepad( e.gamepad );
}
function addgamepad(gamepad) {
controllers[gamepad.index] = gamepad;
requestAnimationFrame(updateStatus);
}
function disconnecthandler(e) {
removegamepad(e.gamepad);
}
function removegamepad(gamepad) {
delete controllers[gamepad.index];
}
function updateStatus() {
if (!haveEvents) {
scangamepads();
}
var i = 0;
var j;
for (j in controllers) {
var gamepad1 = j === 0;
var gamepad2 = j === 1;
var controller = controllers[j];
for (i = 0; i < controller.buttons.length; i++) {
//up, down, left, right
var U = i === 12,
D = i === 13,
L = i === 14,
R = i === 15;
var val = controller.buttons[i];
var pressed = val == 1.0;
if (typeof(val) == "object") {
pressed = val.pressed;
if ( pressed ) {
var event = document.createEvent('event');
event.initEvent('keydown', true, true);
if (U) event.keyCode = keyCodes.U;
if (D) event.keyCode = keyCodes.D;
if (L) event.keyCode = keyCodes.L;
if (R) event.keyCode = keyCodes.R;
document.getElementById( 'logo' ).dispatchEvent( event );
}
}
}
}
requestAnimationFrame(updateStatus);
}
function scangamepads() {
var gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);
for (var i = 0; i < gamepads.length; i++) {
if (gamepads[i]) {
if (gamepads[i].index in controllers) {
controllers[gamepads[i].index] = gamepads[i];
} else {
addgamepad(gamepads[i]);
}
}
}
}
window.addEventListener("gamepadconnected", connecthandler);
window.addEventListener("gamepaddisconnected", disconnecthandler);
if (!haveEvents) scangamepads();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment