Files
webRtc/WebApp/client/public/videoplayer/js/gamepadEvents.js

147 lines
5.0 KiB
JavaScript
Raw Normal View History

2026-02-27 18:35:40 +08:00
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);
}
}