inkjs-linux/js/gamepad.js

255 lines
8 KiB
JavaScript

import $ from 'jquery';
const gamepadmappings = [
require("./mappings/ps4-ff-osx.json"),
require("./mappings/ps3-ff-linux.json"),
require("./mappings/ps4-ff-linux.json"),
require("./mappings/xbone-ff-linux.json"),
require("./mappings/ps4-chrome-linux.json"),
require("./mappings/xbox360-ff-linux.json"),
require("./mappings/ps3-chrome-osx-linux.json"),
require("./mappings/ps4-chrome-windows-osx.json"),
require("./mappings/xbone-chrome-osx-linux.json"),
require("./mappings/xbox360-chrome-windows-osx.json"),
require("./mappings/logitechf310-xinput-ff-linux.json"),
require("./mappings/logitechf310-directinput-ff-osx.json"),
require("./mappings/logitechf310-xinput-chrome-linux.json"),
require("./mappings/logitechf310-directinput-ff-windows.json"),
require("./mappings/logitechf310-directinput-chrome-ff-linux.json"),
require("./mappings/logitechf310-directinput-chrome-windows-osx.json"),
]
// Gamepad HTML5 API
export default class Gamepad {
constructor(pad) {
this.gamepad = pad;
this.map = this.detectMapping(pad.id, navigator.userAgent);
this.pressed = this.getPressed();
}
detectMapping(id, browser) {
for (let map of gamepadmappings) {
var device;
for (device of map.supported) {
if ((id.indexOf(device.id) !== -1) && (browser.indexOf(device.browser) !== -1)) {
return map;
}
}
// mapping not found, return the first map for this browser
for (device of map.supported) {
if (browser.indexOf(device.browser) !== -1) {
return map;
}
}
// browser and device are not supported, just return the first map
console.warn("Browser and device are not found, gamepad support not guaranteed.");
return gamepadmappings[0];
}
}
axis(name) {
const map = this.map.axes[name];
if (map == null) {
return 0;
}
if (map.index != null) {
return this.gamepad.axes[map.index];
}
if ((map.buttonPositive != null) && this.gamepad.buttons[map.buttonPositive].pressed) {
return 1;
}
if ((map.buttonNegative != null) && this.gamepad.buttons[map.buttonNegative].pressed) {
return -1;
}
return 0;
}
button(name) {
const map = this.map.buttons[name];
if (map == null) {
return 0;
}
if ((map.index != null) && (this.gamepad.buttons[map.index] != null)) {
return this.gamepad.buttons[map.index].pressed;
}
if (map.axis != null) {
if (map.direction < 0) {
return this.gamepad.axes[map.axis] < -0.75;
} else {
return this.gamepad.axes[map.axis] > 0.75;
}
}
return false;
}
// Return the name of the pressed button
getPressed() {
for (let buttonname in this.map.buttons) {
const button = this.map.buttons[buttonname];
if ((
(this.gamepad.buttons[button.index] != null) &&
this.gamepad.buttons[button.index].pressed
) || (
(this.gamepad.axes[button.axis] < -0.75) &&
(button.direction < 0)
) || (
(this.gamepad.axes[button.axis] > 0.75) &&
(button.direction > 0)
)) {
return buttonname;
}
}
}
// Select the previous choice
selectUp (event, button, padid) {
if ((button !== "dpad up") && (button !== "left stick up")) {
return;
}
if ($(".options li").length === 0) {
return selectUpLink(event, button, padid);
}
$(".options li").removeClass("active");
const count = $(".options li").length;
window.selectedoption--;
if (window.selectedoption <= 0) {
window.selectedoption = count;
}
$(`.options li:nth-child(${window.selectedoption}`).addClass("active");
}
// Select the next choice
selectDown (event, button, padid) {
if ((button !== "dpad down") && (button !== "left stick down")) {
return;
}
if ($(".options li").length === 0) {
return selectDownLink(event, button, padid);
}
$(".options li").removeClass("active");
window.selectedoption++;
const count = $(".options li").length;
if (window.selectedoption > count) {
window.selectedoption = 1;
}
$(`.options li:nth-child(${window.selectedoption})`).addClass("active");
};
// Select the next link inside room text
selectDownLink (event, button, padid) {
let tabid = $("#current-room .active").first().attr("tabindex");
$("#current-room .active").removeClass("active");
let maxtab = 0;
for (let element of $("#current-room [tabindex]")) {
if (maxtab < $(element).attr("tabindex")) {
maxtab = $(element).attr("tabindex");
}
}
tabid = Gamepad.prototype.increaseTabindex(tabid, maxtab);
$(`#current-room [tabindex='${tabid}']`).addClass("active");
};
// Select the previous link inside room text
selectUpLink (event, button, padid) {
let tabid = $("#current-room .active").attr("tabindex");
$("#current-room .active").removeClass("active");
tabid = this.decreaseTabindex(tabid);
$(`#current-room [tabindex='${tabid}']`).addClass("active");
};
decreaseTabindex (tabid) {
tabid--;
if (tabid < 0) {
// tabindex can't be negative, choosing maximum tabindex
let maxtab = 0;
for (let element of $("#current-room [tabindex]")) {
if (maxtab < $(element).attr("tabindex")) {
maxtab = $(element).attr("tabindex");
}
}
tabid = maxtab;
}
if ($(`#current-room [tabindex='${tabid}']`).length === 0) {
return this.decreaseTabindex(tabid);
}
};
increaseTabindex (tabid, maxtab) {
if (tabid < maxtab) {
tabid++;
} else {
tabid = 0;
}
if ($(`#current-room [tabindex='${tabid}']`).length === 0) {
return Gamepad.prototype.increaseTabindex(tabid);
}
};
selectOption (event, button) {
if (button !== "a") {
return;
}
$(".options li.active").click();
};
// enter the options room
enterOptions (event, button, padid) {
if ((button !== "back") && (button !== "start")) {
return;
}
if (button === "start") {
return salet.goTo(salet.optionsRoom);
}
if ((button === "back") && (salet.currentRoom === salet.optionsRoom)) {
return salet.goBack();
}
};
// Joystick check, fires events
joystick () {
if (typeof navigator.getGamepads === "function") {
return (() => {
const result = [];
for (let pad of navigator.getGamepads()) {
if (pad != null) {
const temp = new Gamepad(pad);
if (temp.pressed != null) {
if (window.gamepads[pad.id].pressed !== temp.pressed) {
$(document).trigger("press", temp.pressed, pad.id);
}
}
if (temp.map.axes != null) {
for (let axisname = 0; axisname < temp.map.axes.length; axisname++) {
const axis = temp.map.axes[axisname];
const oldval = window.gamepads[pad.id].gamepad.axes[axis.index];
let newval = temp.gamepad.axes[axis.index];
if (Math.abs(newval) <= 0.2) {
newval = 0;
}
if (newval !== oldval) {
$(document).trigger("axis", axisname, newval, padid);
}
}
}
result.push(window.gamepads[pad.id] = temp);
} else {
result.push(undefined);
}
}
return result;
})();
}
};
init() {
// Connected gamepads (see Gamepad class)
window.gamepads = {};
window.addEventListener("gamepadconnected", e => window.gamepads[e.gamepad.id] = new Gamepad(e.gamepad));
window.addEventListener("gamepaddisconnected", e => window.gamepads[e.gamepad.id] = undefined);
setInterval(joystick, 50); // 50 = 1000 / 20 fps
if (window.selectedoption == null) {
window.selectedoption = 1;
}
$(document).on("press", Gamepad.prototype.selectUp);
$(document).on("press", Gamepad.prototype.selectDown);
$(document).on("press", Gamepad.prototype.selectOption);
$(document).on("press", Gamepad.prototype.enterOptions);
}
}