gamepad-viewer/gamepad.js
2016-05-08 10:14:36 +02:00

163 lines
4.3 KiB
JavaScript

var haveEvents = 'ongamepadconnected' in window;
var gamepads = {};
var $gamepad = $('.gamepad');
var gamepadIdentifiers = {
'ds4': /Vendor: 054c Product: 05c4/,
'xbox-one': /XInput/
};
var activeGamepad = null;
var activeGamepadType = null;
var mapping = {
buttons: [],
axes: []
};
window.addEventListener("gamepadconnected", onGamepadConenct);
window.addEventListener("gamepaddisconnected", onGamepadDisconnect);
function onGamepadConenct(e) {
addGamepad(e.gamepad);
}
function onGamepadDisconnect(e) {
removeGamepad(e.gamepad.index);
}
function addGamepad(gamepad) {
gamepads[gamepad.index] = gamepad;
requestAnimationFrame(updateStatus);
}
function removeGamepad(gamepadIndex) {
var gamepad = gamepads[gamepadIndex];
if (gamepad && activeGamepad && gamepad.index === activeGamepad.index) {
activeGamepad = null;
$gamepad.empty();
}
delete gamepads[gamepadIndex];
}
function scanGamepads() {
var navigatorGamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);
for (var gamepadIndex = 0; gamepadIndex < navigatorGamepads.length; gamepadIndex++) {
var gamepad = navigatorGamepads[gamepadIndex];
if (gamepad) {
if (gamepad.index in gamepads) {
gamepads[gamepad.index] = gamepad;
} else {
addGamepad(gamepad);
}
for (var buttonIndex = 0; buttonIndex < gamepad.buttons.length; buttonIndex++) {
button = gamepad.buttons[buttonIndex];
if (!activeGamepad && button.pressed) {
mapGamepad(gamepad);
}
}
} else {
if (gamepadIndex in gamepads) {
removeGamepad(gamepadIndex);
}
}
}
}
function updateStatus() {
if (!haveEvents) {
scanGamepads();
}
requestAnimationFrame(updateStatus);
}
function mapGamepad(gamepad) {
var button;
var axis;
activeGamepad = gamepad;
for (var gamepadType in gamepadIdentifiers) {
if (gamepadIdentifiers[gamepadType].test(activeGamepad.id)) {
activeGamepadType = gamepadType;
}
}
$.ajax(
activeGamepadType + '/template.html',
{
async: true
}
).done(function(template) {
$gamepad.html(template).addClass(activeGamepadType);
mapping.buttons = [];
for (var buttonIndex = 0; buttonIndex < activeGamepad.buttons.length; buttonIndex++) {
button = activeGamepad.buttons[buttonIndex];
mapping.buttons[buttonIndex] = $('[data-button='+buttonIndex+']');
}
mapping.axes = [];
for (var axisIndex = 0; axisIndex < activeGamepad.axes.length; axisIndex++) {
axis = activeGamepad.axes[axisIndex];
mapping.axes[axisIndex] = $('[data-axis-x='+axisIndex+'], [data-axis-y='+axisIndex+'], [data-axis-z='+axisIndex+']');
}
updateVisualStatus();
});
}
function updateVisualStatus() {
requestAnimationFrame(updateVisualStatus);
if (!activeGamepad) {
return;
}
var button;
var $button;
for (var buttonIndex = 0; buttonIndex < activeGamepad.buttons.length; buttonIndex++) {
$button = mapping.buttons[buttonIndex];
if (!$button) {
break;
}
button = activeGamepad.buttons[buttonIndex];
$button.attr('data-pressed', button.pressed);
$button.attr('data-value', button.value);
if ("function" === typeof updateButton) {
updateButton($button);
}
}
var axis;
var $axis;
for (var axisIndex = 0; axisIndex < activeGamepad.axes.length; axisIndex++) {
$axis = mapping.axes[axisIndex];
if (!$axis) {
break;
}
axis = activeGamepad.axes[axisIndex];
if ($axis.is('[data-axis-x='+axisIndex+']')) {
$axis.attr('data-value-x', axis);
}
if ($axis.is('[data-axis-y='+axisIndex+']')) {
$axis.attr('data-value-y', axis);
}
if ($axis.is('[data-axis-z='+axisIndex+']')) {
$axis.attr('data-value-z', axis);
}
if ("function" === typeof updateAxis) {
updateAxis($axis);
}
}
}
if (!haveEvents) {
setInterval(scanGamepads, 500);
}