1 decade ago by spacelime
I pieced together snippets of code here and there to get gamepad support working for Impact. The code I found at first was not compatible with Chrome 22 or higher and it only supported Xbox and PS2 controllers. I made it recognize any generic gamepad, but you might want to adjust the button mapping a bit to suit you. Also I've not modified it to work for Firefox yet. If you can get it working, please let me know =)
How to do this:
1) add the line
under .requires in main.js
2) under your main entity's update function, add this:
3) test for input state with for example:
4) add this at the end of the update function:
5) make a file called gamepad.js in lib/plugins/gamepad/ and paste this into it:
How to do this:
1) add the line
'plugins.gamepad.gamepad'
under .requires in main.js
2) under your main entity's update function, add this:
// Load gamepad state, if not active then set to 0
var pads = Gamepad.getStates();
if (pads[0] == undefined) pads[0] = 0;
3) test for input state with for example:
if( pads[0].leftStickX == -1 )
{
// move left
}
4) add this at the end of the update function:
// To make sure that gamepad.js can set it's variables properly pads[0] = undefined;
5) make a file called gamepad.js in lib/plugins/gamepad/ and paste this into it:
/*
gamepad.js, See README for copyright and usage instructions.
*/
ig.module(
'plugins.gamepad.gamepad'
)
.requires(
)
.defines(function() {
var getField = function() {
return navigator.webkitGamepads || navigator.mozGamepads || navigator.gamepads ||
navigator.webkitGetGamepads() || navigator.mozGetGamepads() || navigator.getGamepads();
};
var Item = function() {
this.leftStickX = 0.0;
this.leftStickY = 0.0;
this.rightStickX = 0.0;
this.rightStickY = 0.0;
this.faceButton0 = 0.0;
this.faceButton1 = 0.0;
this.faceButton2 = 0.0;
this.faceButton3 = 0.0;
this.leftShoulder0 = 0.0;
this.rightShoulder0 = 0.0;
this.leftShoulder1 = 0.0;
this.rightShoulder1 = 0.0;
this.select = 0.0;
this.start = 0.0;
this.leftStickButton = 0.0;
this.rightStickButton = 0.0;
this.dpadUp = 0.0;
this.dpadDown = 0.0;
this.dpadLeft = 0.0;
this.dpadRight = 0.0;
this.deadZoneLeftStick = 0.25;
this.deadZoneRightStick = 0.25;
this.deadZoneShoulder0 = 0.0;
this.deadZoneShoulder1 = 0.0;
this.images = Gamepad.ImageDataUrls_Unknown;
this.name = "Unknown";
};
var deepCopy = function(into, from) {
into.leftStickX = from.leftStickX;
into.leftStickY = from.leftStickY;
into.rightStickX = from.rightStickX;
into.rightStickY = from.rightStickY;
into.faceButton0 = from.faceButton0;
into.faceButton1 = from.faceButton1;
into.faceButton2 = from.faceButton2;
into.faceButton3 = from.faceButton3;
into.leftShoulder0 = from.leftShoulder0;
into.rightShoulder0 = from.rightShoulder0;
into.leftShoulder1 = from.leftShoulder1;
into.rightShoulder1 = from.rightShoulder1;
into.select = from.select;
into.start = from.start;
into.leftStickButton = from.leftStickButton;
into.rightStickButton = from.rightStickButton;
into.dpadUp = from.dpadUp;
into.dpadDown = from.dpadDown;
into.dpadLeft = from.dpadLeft;
into.dpadRight = from.dpadRight;
};
var contains = function(lookIn, forWhat) { return lookIn.indexOf(forWhat) != -1; };
var userAgent = navigator.userAgent;
var isWindows = contains(userAgent, 'Windows NT');
var isMac = contains(userAgent, 'Macintosh');
var isChrome = contains(userAgent, 'Chrome/');
var isFirefox = contains(userAgent, 'Firefox/');
var axisToButton = function(value) {
return (value + 1.0) / 2.0;
}
if (isFirefox) {
// todo; current moz nightly does not define this, so we'll always
// return true for .supported on that Firefox.
navigator.mozGamepads = [];
var mozConnectHandler = function(e) {
navigator.mozGamepads[e.gamepad.index] = e.gamepad;
}
var mozDisconnectHandler = function(e) {
navigator.mozGamepads[e.gamepad.index] = undefined;
}
window.addEventListener("MozGamepadConnected", mozConnectHandler);
window.addEventListener("MozGamepadDisconnected", mozDisconnectHandler);
}
var mapPad = function(raw, mapped) {
var len = active.length;
for (var i = 0; i < len; ++i) {
var entry = active[i];
var ss1 = entry[0];
var ss2 = entry[1];
if (contains(raw.id, ss1) && contains(raw.id, ss2)) {
var handler = entry[2];
handler(raw, mapped);
var deviceident = entry[3];
mapped.name = deviceident + " Player " + (raw.index + 1);
// todo; apply dead zones to mapped here
return;
}
}
var entry = active[0];
var handler = entry[2];
handler(raw, mapped);
var deviceident = entry[3];
mapped.name = deviceident + " Player " + (raw.index + 1);
};
var mapIndividualPad = function(rawPads, i) {
var raw = rawPads[i];
if (!raw) {
prevData[i] = undefined;
curData[i] = undefined;
return;
}
if (curData[i] === undefined) {
prevData[i] = new Item();
curData[i] = new Item();
}
deepCopy(prevData[i], curData[i]);
mapPad(raw, curData[i]);
};
var prevData = [];
var curData = [];
var Gamepad = {};
window.Gamepad = Gamepad;
Gamepad.getPreviousStates = function() {
return prevData;
};
Gamepad.getStates = function() {
var rawPads = getField()
var len = rawPads.length;
for (var i = 0; i < len; ++i) {
mapIndividualPad(rawPads, i);
}
for (; i < curData.length; ++i) {
prevData[i] = undefined;
curData[i] = undefined;
}
return curData;
};
Gamepad.getPreviousState = function(i) {
return prevData[i];
};
Gamepad.getState = function(i) {
var rawPads = getField();
mapIndividualPad(rawPads, i);
return curData[i];
};
Gamepad.supported = getField() != undefined;
// todo; These sort of seems like it could be data, but there's actually a
// lot of exceptions, and it might be slower to map per frame anyway (we
// want one of these methods to be hot for each connected device). Revisit
// once we have more pads accounted for to see if there's consistent
// patterns.
var ChromeWindowsXinputGamepad = function(raw, into, index) {
into.leftStickX = raw.axes[0];
into.leftStickY = raw.axes[1];
into.rightStickX = raw.axes[2];
into.rightStickY = raw.axes[3];
into.faceButton0 = raw.buttons[0];
into.faceButton1 = raw.buttons[1];
into.faceButton2 = raw.buttons[2];
into.faceButton3 = raw.buttons[3];
into.leftShoulder0 = raw.buttons[4];
into.rightShoulder0 = raw.buttons[5];
into.leftShoulder1 = raw.buttons[6];
into.rightShoulder1 = raw.buttons[7];
into.select = raw.buttons[8];
into.start = raw.buttons[9];
into.leftStickButton = raw.buttons[10];
into.rightStickButton = raw.buttons[11];
into.dpadUp = raw.buttons[12];
into.dpadDown = raw.buttons[13];
into.dpadLeft = raw.buttons[14];
into.dpadRight = raw.buttons[15];
// From http://msdn.microsoft.com/en-us/library/windows/desktop/ee417001(v=vs.85).aspx
into.deadZoneLeftStick = 7849.0/32767.0;
into.deadZoneRightStick = 8689/32767.0;
into.deadZoneShoulder0 = 0.5;
into.deadZoneShoulder1 = 30.0/255.0;
};
var FirefoxWindowsXbox360Controller = function(raw, into, index) {
// Wow, dinput is a disaster.
into.leftStickX = raw.axes[0];
into.leftStickY = raw.axes[1];
into.rightStickX = raw.axes[3];
into.rightStickY = raw.axes[4];
into.faceButton0 = raw.buttons[0];
into.faceButton1 = raw.buttons[1];
into.faceButton2 = raw.buttons[2];
into.faceButton3 = raw.buttons[3];
into.leftShoulder0 = raw.buttons[4];
into.rightShoulder0 = raw.buttons[5];
into.leftShoulder1 = raw.axes[2] > 0 ? raw.axes[2] : 0;
into.rightShoulder1 = raw.axes[2] < 0 ? -raw.axes[2] : 0;
into.select = raw.buttons[6];
into.start = raw.buttons[7];
into.leftStickButton = raw.buttons[8];
into.rightStickButton = raw.buttons[9];
into.dpadUp = raw.axes[6] < -0.5 ? 1 : 0;
into.dpadDown = raw.axes[6] > 0.5 ? 1 : 0;
into.dpadLeft = raw.axes[5] < -0.5 ? 1 : 0;
into.dpadRight = raw.axes[5] > 0.5 ? 1 : 0;
// From http://msdn.microsoft.com/en-us/library/windows/desktop/ee417001(v=vs.85).aspx
into.deadZoneLeftStick = 7849.0/32767.0;
into.deadZoneRightStick = 8689/32767.0;
into.deadZoneShoulder0 = 0.5;
into.deadZoneShoulder1 = 30.0/255.0;
}
var CommonMacXbox360Controller = function(raw, into, index) {
// NOTE: Partial, doesn't set all values.
into.leftStickX = raw.axes[0];
into.leftStickY = raw.axes[1];
into.faceButton0 = raw.buttons[0];
into.faceButton1 = raw.buttons[1];
into.faceButton2 = raw.buttons[2];
into.faceButton3 = raw.buttons[3];
into.leftShoulder0 = raw.buttons[4];
into.rightShoulder0 = raw.buttons[5];
into.select = raw.buttons[9];
into.start = raw.buttons[8];
into.leftStickButton = raw.buttons[6];
into.rightStickButton = raw.buttons[7];
into.dpadUp = raw.buttons[11];
into.dpadDown = raw.buttons[12];
into.dpadLeft = raw.buttons[13];
into.dpadRight = raw.buttons[14];
// From http://msdn.microsoft.com/en-us/library/windows/desktop/ee417001(v=vs.85).aspx
into.deadZoneLeftStick = 7849.0/32767.0;
into.deadZoneRightStick = 8689/32767.0;
into.deadZoneShoulder0 = 0.5;
into.deadZoneShoulder1 = 30.0/255.0;
}
var ChromeMacXbox360Controller = function(raw, into, index) {
CommonMacXbox360Controller(raw, into, index);
into.rightStickX = raw.axes[3];
into.rightStickY = raw.axes[4];
into.leftShoulder1 = axisToButton(raw.axes[2]);
into.rightShoulder1 = axisToButton(raw.axes[5]);
};
var ChromeMacLogitechF310Controller = function(raw, into, index) {
into.leftStickX = raw.axes[0];
into.leftStickY = raw.axes[1];
into.faceButton0 = raw.buttons[1];
into.faceButton1 = raw.buttons[2];
into.faceButton2 = raw.buttons[0];
into.faceButton3 = raw.buttons[3];
into.leftShoulder0 = raw.buttons[4];
into.rightShoulder0 = raw.buttons[5];
into.select = raw.buttons[8];
into.start = raw.buttons[9];
into.leftStickButton = raw.buttons[10];
into.rightStickButton = raw.buttons[11];
// There is a switch to toggle the left joystick and dpad
// only one is enabled at a time and the output always goes
// through the left joystick
into.dpadUp = 0;
into.dpadDown = 0;
into.dpadLeft = 0;
into.dpadRight = 0;
into.deadZoneLeftStick = 7849.0/32767.0;
into.deadZoneRightStick = 8689/32767.0;
into.deadZoneShoulder0 = 0.5;
into.deadZoneShoulder1 = 30.0/255.0;
console.log(raw.axes);
into.rightStickX = raw.axes[2];
into.rightStickY = raw.axes[5];
into.leftShoulder1 = raw.buttons[6];
into.rightShoulder1 = raw.buttons[7];
};
var FirefoxMacXbox360Controller = function(raw, into, index) {
CommonMacXbox360Controller(raw, into, index);
into.rightStickX = raw.axes[2];
into.rightStickY = raw.axes[3];
into.leftShoulder1 = axisToButton(raw.axes[4]);
into.rightShoulder1 = axisToButton(raw.axes[5]);
};
var CommonMacPS3Controller = function(Raw, into, index) {
// NOTE: Partial, doesn't set all values.
into.leftStickX = raw.axes[0];
into.leftStickY = raw.axes[1];
into.rightStickX = raw.axes[2];
into.faceButton0 = raw.buttons[14];
into.faceButton1 = raw.buttons[13];
into.faceButton2 = raw.buttons[15];
into.faceButton3 = raw.buttons[12];
into.leftShoulder0 = raw.buttons[10];
into.rightShoulder0 = raw.buttons[11];
into.leftShoulder1 = raw.buttons[8];
into.rightShoulder1 = raw.buttons[9];
into.select = raw.buttons[0];
into.start = raw.buttons[3];
into.leftStickButton = raw.buttons[1];
into.rightStickButton = raw.buttons[2];
into.dpadUp = raw.buttons[4];
into.dpadDown = raw.buttons[6];
into.dpadLeft = raw.buttons[7];
into.dpadRight = raw.buttons[5];
};
var FirefoxMacPS3Controller = function(raw, into, index) {
CommonMacPS3Controller(raw, into, index);
into.rightStickY = raw.axes[3];
};
var ChromeMacPS3Controller = function(raw, into, index) {
into.rightStickY = raw.axes[5];
};
var ChromeGenericController = function(raw, into, index) {
into.leftStickX = raw.axes[0];
into.leftStickY = raw.axes[1];
into.rightStickX = raw.axes[3];
into.rightStickY = raw.axes[2];
into.faceButton0 = raw.buttons[0];
into.faceButton1 = raw.buttons[1];
into.faceButton2 = raw.buttons[2];
into.faceButton3 = raw.buttons[3];
into.leftShoulder0 = raw.buttons[4];
into.rightShoulder0 = raw.buttons[5];
into.leftShoulder1 = raw.buttons[7];
into.rightShoulder1 = raw.buttons[6];
into.select = raw.buttons[8];
into.start = raw.buttons[9];
into.leftStickButton = raw.buttons[10];
into.rightStickButton = raw.buttons[11];
into.dpadUp = raw.axes[5] < -0.5 ? 1 : 0;
into.dpadDown = raw.axes[5] > 0.5 ? 1 : 0;
into.dpadLeft = raw.axes[4] < -0.5 ? 1 : 0;
into.dpadRight = raw.axes[4] > 0.5 ? 1 : 0;
// From http://msdn.microsoft.com/en-us/library/windows/desktop/ee417001(v=vs.85).aspx
into.deadZoneLeftStick = 7849.0/32767.0;
into.deadZoneRightStick = 8689/32767.0;
into.deadZoneShoulder0 = 0.5;
into.deadZoneShoulder1 = 30.0/255.0;
};
var active = [];
// todo; possible we need to add different deadzones based on controller
// manufacturer, but perhaps they're fairly close anyway.
if (isChrome && isWindows) {
active.push([ 'Vendor: Unknown', 'Product: Unknown', ChromeGenericController, "Generic Controller" ]);
active.push([ 'XInput ', 'GAMEPAD', ChromeWindowsXinputGamepad, "Xbox 360" ]);
} else if (isChrome && isMac) {
active.push([ 'Vendor: Unknown', 'Product: Unknown', ChromeGenericController, "Generic Controller" ]);
active.push([ 'Vendor: 045e', 'Product: 028e', ChromeMacXbox360Controller, "Xbox 360" ]);
active.push([ 'Vendor: 045e', 'Product: 02a1', ChromeMacXbox360Controller, "Xbox 360" ]);
active.push([ 'Vendor: 054c', 'Product: 0268', ChromeMacPS3Controller, "Playstation 3" ]);
active.push([ 'Vendor: 046d', 'Product: c216', ChromeMacLogitechF310Controller, "Logitech F310" ]);
} else if (isFirefox && isWindows) {
active.push([ 'Vendor: Unknown', 'Product: Unknown', ChromeGenericController, "Generic Controller" ]);
active.push([ '45e-', '28e-', FirefoxWindowsXbox360Controller, "Xbox 360" ]);
active.push([ '45e-', '2a1-', FirefoxWindowsXbox360Controller, "Xbox 360" ]);
active.push([ '46d-', 'c21d-', FirefoxWindowsXbox360Controller, "Logitech F310" ]);
active.push([ '46d-', 'c21e-', FirefoxWindowsXbox360Controller, "Logitech F510" ]);
} else if (isFirefox && isMac) {
active.push([ 'Vendor: Unknown', 'Product: Unknown', ChromeGenericController, "Generic Controller" ]);
active.push([ '45e-', '28e-', FirefoxMacXbox360Controller, "Xbox 360" ]);
active.push([ '54c-', '268-', FirefoxMacPS3Controller, "Playstation 3" ]);
}
Gamepad.magic = function(pad, mappings){
var attachedGamepads = getField();
if (attachedGamepads[0] || attachedGamepads[1] || attachedGamepads[2] || attachedGamepads[3]){
for(m=0; m < mappings.length; m++){
bindButtonToKey(pad, mappings[m][0], mappings[m][1]);
}
}
},
bindButtonToKey = function(pad, myButton, myKey){
if (myButton) {
if( document.createEvent ) {
var evObj = document.createEvent('Event');
evObj.initEvent( 'keydown', true, false );;
evObj.keyCode = myKey;
window.dispatchEvent(evObj);
} else if( document.createEventObject ) {
console.log('createEventObject');
}
}
else {
if( document.createEvent ) {;
var evObj = document.createEvent('Event');
evObj.initEvent( 'keyup', true, false );;
evObj.keyCode = myKey;
window.dispatchEvent(evObj);
} else if( document.createEventObject ) {
console.log('createEventObject');
}
}
}
});
