147 lines
5.0 KiB
JavaScript
147 lines
5.0 KiB
JavaScript
import * as Logger from "../../module/logger.js";
|
|
|
|
const _e = 0.09;
|
|
const _gameloopInterval = 16.67; //in milliseconds, 60 times a second
|
|
var gameloop = null;
|
|
var gamepadsPreviousButtonsStates = {};
|
|
var gamepadsPreviousAxesStates = {};
|
|
var gamepadsConnectedTimeStamp = {};
|
|
const _axisOffset = 100;
|
|
const _axisMultiplier = 1;
|
|
const _axisYInverted = -1;
|
|
|
|
class GamepadButtonEvent extends Event {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.index = arguments[1].index;
|
|
this.id = arguments[1].id;
|
|
this.value = arguments[1].value;
|
|
}
|
|
}
|
|
|
|
class GamepadAxisEvent extends Event {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.index = arguments[1].index;
|
|
this.x = arguments[1].x;
|
|
this.y = arguments[1].y;
|
|
this.id = arguments[1].id;
|
|
}
|
|
}
|
|
|
|
function storePreviousState(gamepad) {
|
|
gamepadsPreviousButtonsStates[gamepad.index] = {};
|
|
gamepad.buttons.forEach(function (button, index) {
|
|
gamepadsPreviousButtonsStates[gamepad.index][index] = { value: button.value, pressed: button.pressed };
|
|
});
|
|
|
|
gamepadsPreviousAxesStates[gamepad.index] = [gamepad.axes.length];
|
|
for (var index = 0; index < gamepad.axes.length; index++)
|
|
gamepadsPreviousAxesStates[gamepad.index][index] = gamepad.axes[index];
|
|
}
|
|
|
|
function checkAxes(gamepad, previousGamePad) {
|
|
for (var i = 0; i < gamepad.axes.length; i += 2) {
|
|
var absX = Math.abs(gamepad.axes[i]);
|
|
var absY = Math.abs(gamepad.axes[i + 1]);
|
|
var event = null;
|
|
if ((absX > _e) ||
|
|
(absY > _e)) {
|
|
|
|
event = new GamepadAxisEvent('gamepadAxis', { id: gamepadsConnectedTimeStamp[gamepad.index], index: i / 2 + _axisOffset, x: gamepad.axes[i] * _axisMultiplier, y: gamepad.axes[i + 1] * _axisMultiplier * _axisYInverted });
|
|
document.dispatchEvent(event);
|
|
}
|
|
else {
|
|
var previousAbsX = Math.abs(previousGamePad[i]);
|
|
var previousAbsY = Math.abs(previousGamePad[i + 1]);
|
|
|
|
//have to send if previously was moved
|
|
if ((previousAbsX > _e) ||
|
|
(previousAbsY > _e)) {
|
|
event = new GamepadAxisEvent('gamepadAxis', { id: gamepadsConnectedTimeStamp[gamepad.index], index: i / 2 + _axisOffset, x: 0.0, y: 0.0 });
|
|
document.dispatchEvent(event);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function gameLoop() {
|
|
Object.keys(gamepadsPreviousAxesStates).forEach(function (gamepadIndex) {
|
|
var gamepad = navigator.webkitGetGamepads ? navigator.webkitGetGamepads()[gamepadIndex] : navigator.getGamepads()[gamepadIndex];
|
|
var previousButtons = gamepadsPreviousButtonsStates[gamepadIndex];
|
|
gamepad.buttons.forEach(function (button, index) {
|
|
var buttonStatus = navigator.webkitGetGamepads ? button == 1 : (button.value > 0 || button.pressed == true);
|
|
var previousButtonStatus = navigator.webkitGetGamepads ? previousButtons[index].value == 1 : (previousButtons[index].value > 0 || previousButtons[index].pressed == true);
|
|
var event;
|
|
if (buttonStatus != previousButtonStatus) {
|
|
if (buttonStatus) {
|
|
event = new GamepadButtonEvent('gamepadButtonDown', { id: gamepadsConnectedTimeStamp[gamepad.index], index: index, value: button.value });
|
|
}
|
|
else {
|
|
event = new GamepadButtonEvent('gamepadButtonUp', { id: gamepadsConnectedTimeStamp[gamepad.index], index: index, value: 0 });
|
|
}
|
|
document.dispatchEvent(event);
|
|
}
|
|
else if (buttonStatus) {
|
|
event = new GamepadButtonEvent('gamepadButtonPressed', { id: gamepadsConnectedTimeStamp[gamepad.index], index: index, value: button.value });
|
|
document.dispatchEvent(event);
|
|
}
|
|
|
|
});
|
|
checkAxes(gamepad, gamepadsPreviousAxesStates[gamepadIndex]);
|
|
storePreviousState(gamepad);
|
|
});
|
|
}
|
|
|
|
function getCookie(cname) {
|
|
var name = cname + "=";
|
|
var decodedCookie = decodeURIComponent(document.cookie);
|
|
var ca = decodedCookie.split(';');
|
|
for (var i = 0; i < ca.length; i++) {
|
|
var c = ca[i];
|
|
while (c.charAt(0) == ' ') {
|
|
c = c.substring(1);
|
|
}
|
|
if (c.indexOf(name) == 0) {
|
|
return c.substring(name.length, c.length);
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
export function gamepadHandler(event, connecting) {
|
|
var gamepad = event.gamepad;
|
|
|
|
var key = gamepad.id.replace(/\s/g, '');
|
|
var cookieTimeStamp = getCookie(key);
|
|
|
|
if (connecting) {
|
|
storePreviousState(gamepad);
|
|
if (Object.keys(gamepadsPreviousAxesStates).length == 1) {
|
|
gameloop = setInterval(gameLoop, _gameloopInterval);
|
|
}
|
|
|
|
//try to find the timestamp
|
|
//need to strip the : from the id
|
|
|
|
if (cookieTimeStamp == "") {
|
|
document.cookie = key + "=" + gamepad.timestamp;
|
|
gamepadsConnectedTimeStamp[gamepad.index] = gamepad.timestamp;
|
|
}
|
|
else {
|
|
gamepadsConnectedTimeStamp[gamepad.index] = cookieTimeStamp;
|
|
}
|
|
|
|
Logger.log("connected: " + gamepadsConnectedTimeStamp[gamepad.index]);
|
|
|
|
} else {
|
|
delete gamepadsPreviousAxesStates[gamepad.index];
|
|
delete gamepadsPreviousButtonsStates[gamepad.index];
|
|
if (Object.keys(gamepadsPreviousAxesStates).length == 0) {
|
|
clearInterval(gameloop);
|
|
gameloop = null;
|
|
}
|
|
Logger.log("disconnected: " + gamepad.id);
|
|
}
|
|
}
|