OpenBuilds-CONTROL/app/lib/gamepad/doc/files/gamepad.js.html

1279 wiersze
34 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>gamepad.js - HTML5-JavaScript-Gamepad-Controller-Library</title>
<link rel="stylesheet" href="http://yui.yahooapis.com/3.9.1/build/cssgrids/cssgrids-min.css">
<link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
<link rel="stylesheet" href="../assets/css/main.css" id="site_styles">
<link rel="shortcut icon" type="image/png" href="../assets/favicon.png">
<script src="http://yui.yahooapis.com/combo?3.9.1/build/yui/yui-min.js"></script>
</head>
<body class="yui3-skin-sam">
<div id="doc">
<div id="hd" class="yui3-g header">
<div class="yui3-u-3-4">
<h1><img src="../assets/css/logo.png" title="HTML5-JavaScript-Gamepad-Controller-Library"></h1>
</div>
<div class="yui3-u-1-4 version">
<em>API Docs for: 0.0.1</em>
</div>
</div>
<div id="bd" class="yui3-g">
<div class="yui3-u-1-4">
<div id="docs-sidebar" class="sidebar apidocs">
<div id="api-list">
<h2 class="off-left">APIs</h2>
<div id="api-tabview" class="tabview">
<ul class="tabs">
<li><a href="#api-classes">Classes</a></li>
<li><a href="#api-modules">Modules</a></li>
</ul>
<div id="api-tabview-filter">
<input type="search" id="api-filter" placeholder="Type to filter APIs">
</div>
<div id="api-tabview-panel">
<ul id="api-classes" class="apis classes">
<li><a href="../classes/AnimFrameUpdateStrategy.html">AnimFrameUpdateStrategy</a></li>
<li><a href="../classes/FirefoxPlatform.html">FirefoxPlatform</a></li>
<li><a href="../classes/Gamepad.html">Gamepad</a></li>
<li><a href="../classes/ManualUpdateStrategy.html">ManualUpdateStrategy</a></li>
<li><a href="../classes/WebKitPlatform.html">WebKitPlatform</a></li>
</ul>
<ul id="api-modules" class="apis modules">
<li><a href="../modules/Gamepad.html">Gamepad</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="yui3-u-3-4">
<div id="api-options">
Show:
<label for="api-show-inherited">
<input type="checkbox" id="api-show-inherited" checked>
Inherited
</label>
<label for="api-show-protected">
<input type="checkbox" id="api-show-protected">
Protected
</label>
<label for="api-show-private">
<input type="checkbox" id="api-show-private">
Private
</label>
<label for="api-show-deprecated">
<input type="checkbox" id="api-show-deprecated">
Deprecated
</label>
</div>
<div class="apidocs">
<div id="docs-main">
<div class="content">
<h1 class="file-heading">File: gamepad.js</h1>
<div class="file">
<pre class="code prettyprint linenums">
/*
* Copyright 2012 Priit Kallas &lt;kallaspriit@gmail.com&gt;
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* &quot;Software&quot;), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
(function(exports) {
&#x27;use strict&#x27;;
/**
* A null function - does nothing, returns nothing
*/
var nullFunction = function() {};
/**
* The null platform, which doesn&#x27;t support anything
*/
var nullPlatform = {
getType: function() {
return &#x27;null&#x27;;
},
isSupported: function() {
return false;
},
update: nullFunction
};
/**
* This strategy uses a timer function to call an update function.
* The timer (re)start function can be provided or the strategy reverts to
* one of the window.*requestAnimationFrame variants.
*
* @class AnimFrameUpdateStrategy
* @constructor
* @param {Function} [requestAnimationFrame] function to use for timer creation
* @module Gamepad
*/
var AnimFrameUpdateStrategy = function(requestAnimationFrame) {
var that = this;
var win = window;
this.update = nullFunction;
this.requestAnimationFrame = requestAnimationFrame || win.requestAnimationFrame ||
win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame;
/**
* This method calls the (user) update and restarts itself
* @method tickFunction
*/
this.tickFunction = function() {
that.update();
that.startTicker();
};
/**
* (Re)Starts the ticker
* @method startTicker
*/
this.startTicker = function() {
that.requestAnimationFrame.apply(win, [that.tickFunction]);
};
};
/**
* Starts the update strategy using the given function
*
* @method start
* @param {Function} updateFunction the function to call at each update
*/
AnimFrameUpdateStrategy.prototype.start = function(updateFunction) {
this.update = updateFunction || nullFunction;
this.startTicker();
};
/**
* This strategy gives the user the ability to call the library internal
* update function on request. Use this strategy if you already have a
* timer function running by requestAnimationFrame and you need fine control
* over when the gamepads are updated.
*
* @class ManualUpdateStrategy
* @constructor
* @module Gamepad
*/
var ManualUpdateStrategy = function() {
};
/**
* Calls the update function in the started state. Does nothing otherwise.
* @method update
*/
ManualUpdateStrategy.prototype.update = nullFunction;
/**
* Starts the update strategy using the given function
*
* @method start
* @param {Function} updateFunction the function to call at each update
*/
ManualUpdateStrategy.prototype.start = function(updateFunction) {
this.update = updateFunction || nullFunction;
};
/**
* This platform is for webkit based environments that need to be polled
* for updates.
*
* @class WebKitPlatform
* @constructor
* @param {Object} listener the listener to provide _connect and _disconnect callbacks
* @param {Function} gamepadGetter the poll function to return an array of connected gamepads
* @module Gamepad
*/
var WebKitPlatform = function(listener, gamepadGetter) {
this.listener = listener;
this.gamepadGetter = gamepadGetter;
this.knownGamepads = [];
};
/**
* Provides a platform object that returns true for isSupported() if valid.
* @method factory
* @static
* @param {Object} listener the listener to use
* @return {Object} a platform object
*/
WebKitPlatform.factory = function(listener) {
var platform = nullPlatform;
var navigator = window &amp;&amp; window.navigator;
if (navigator) {
if (typeof(navigator.getGamepads) !== &#x27;undefined&#x27;) {
platform = new WebKitPlatform(listener, function() {
return navigator.getGamepads();
});
} else if (typeof(navigator.webkitGamepads) !== &#x27;undefined&#x27;) {
platform = new WebKitPlatform(listener, function() {
return navigator.webkitGamepads();
});
} else if (typeof(navigator.webkitGetGamepads) !== &#x27;undefined&#x27;) {
platform = new WebKitPlatform(listener, function() {
return navigator.webkitGetGamepads();
});
}
}
return platform;
};
/**
* @method getType()
* @static
* @return {String} &#x27;WebKit&#x27;
*/
WebKitPlatform.getType = function() {
return &#x27;WebKit&#x27;;
},
/**
* @method getType()
* @return {String} &#x27;WebKit&#x27;
*/
WebKitPlatform.prototype.getType = function() {
return WebKitPlatform.getType();
},
/**
* @method isSupported
* @return {Boolean} true
*/
WebKitPlatform.prototype.isSupported = function() {
return true;
};
/**
* Queries the currently connected gamepads and reports any changes.
* @method update
*/
WebKitPlatform.prototype.update = function() {
var that = this;
var gamepads = Array.prototype.slice.call(this.gamepadGetter(), 0);
var gamepad;
var i;
for (i = this.knownGamepads.length - 1; i &gt;= 0; i--) {
gamepad = this.knownGamepads[i];
if (gamepads.indexOf(gamepad) &lt; 0) {
this.knownGamepads.splice(i, 1);
this.listener._disconnect(gamepad);
}
}
for (i = 0; i &lt; gamepads.length; i++) {
gamepad = gamepads[i];
if (gamepad &amp;&amp; (that.knownGamepads.indexOf(gamepad) &lt; 0)) {
that.knownGamepads.push(gamepad);
that.listener._connect(gamepad);
}
}
};
/**
* This platform is for mozilla based environments that provide gamepad
* updates via events.
*
* @class FirefoxPlatform
* @constructor
* @module Gamepad
*/
var FirefoxPlatform = function(listener) {
this.listener = listener;
window.addEventListener(&#x27;gamepadconnected&#x27;, function(e) {
listener._connect(e.gamepad);
});
window.addEventListener(&#x27;gamepaddisconnected&#x27;, function(e) {
listener._disconnect(e.gamepad);
});
};
/**
* Provides a platform object that returns true for isSupported() if valid.
* @method factory
* @static
* @param {Object} listener the listener to use
* @return {Object} a platform object
*/
FirefoxPlatform.factory = function(listener) {
var platform = nullPlatform;
if (window &amp;&amp; (typeof(window.addEventListener) !== &#x27;undefined&#x27;)) {
platform = new FirefoxPlatform(listener);
}
return platform;
};
/**
* @method getType()
* @static
* @return {String} &#x27;Firefox&#x27;
*/
FirefoxPlatform.getType = function() {
return &#x27;Firefox&#x27;;
},
/**
* @method getType()
* @return {String} &#x27;Firefox&#x27;
*/
FirefoxPlatform.prototype.getType = function() {
return FirefoxPlatform.getType();
},
/**
* @method isSupported
* @return {Boolean} true
*/
FirefoxPlatform.prototype.isSupported = function() {
var navigator = window &amp;&amp; window.navigator;
return navigator.userAgent.indexOf(&#x27;Firefox&#x27;) !== -1;
};
/**
* Does nothing on the Firefox platform
* @method update
*/
FirefoxPlatform.prototype.update = nullFunction;
/**
* Provides simple interface and multi-platform support for the gamepad API.
*
* You can change the deadzone and maximizeThreshold parameters to suit your
* taste but the defaults should generally work fine.
*
* @class Gamepad
* @constructor
* @param {Object} [updateStrategy] an update strategy, defaulting to
* {{#crossLink &quot;AnimFrameUpdateStrategy&quot;}}{{/crossLink}}
* @module Gamepad
* @author Priit Kallas &lt;kallaspriit@gmail.com&gt;
*/
var Gamepad = function(updateStrategy) {
this.updateStrategy = updateStrategy || new AnimFrameUpdateStrategy();
this.gamepads = [];
this.listeners = {};
this.platform = nullPlatform;
this.deadzone = 0.03;
this.maximizeThreshold = 0.97;
};
/**
* The available update strategies
* @property UpdateStrategies
* @param {AnimFrameUpdateStrategy} AnimFrameUpdateStrategy
* @param {ManualUpdateStrategy} ManualUpdateStrategy
*/
Gamepad.UpdateStrategies = {
AnimFrameUpdateStrategy: AnimFrameUpdateStrategy,
ManualUpdateStrategy: ManualUpdateStrategy
};
/**
* List of factories of supported platforms. Currently available platforms:
* {{#crossLink &quot;WebKitPlatform&quot;}}{{/crossLink}},
* {{#crossLink &quot;FirefoxPlatform&quot;}}{{/crossLink}},
* @property PlatformFactories
* @type {Array}
*/
Gamepad.PlatformFactories = [FirefoxPlatform.factory, WebKitPlatform.factory];
/**
* List of supported controller types.
*
* @property Type
* @param {String} Type.N64 Retrolink N64 controller
* @param {String} Type.PLAYSTATION Playstation controller
* @param {String} Type.LOGITECH Logitech controller
* @param {String} Type.XBOX XBOX controller
* @param {String} Type.UNKNOWN Unknown controller
*/
Gamepad.Type = {
N64: &#x27;n64&#x27;,
PLAYSTATION: &#x27;playstation&#x27;,
LOGITECH: &#x27;logitech&#x27;,
XBOX: &#x27;xbox&#x27;,
UNKNOWN: &#x27;unknown&#x27;
};
/*
* List of events you can expect from the library.
*
* CONNECTED, DISCONNECTED and UNSUPPORTED events include the gamepad in
* question and tick provides the list of all connected gamepads.
*
* BUTTON_DOWN and BUTTON_UP events provide an alternative to polling button states at each tick.
*
* AXIS_CHANGED is called if a value of some specific axis changes.
*/
Gamepad.Event = {
/**
* Triggered when a new controller connects.
*
* @event connected
* @param {Object} device
*/
CONNECTED: &#x27;connected&#x27;,
/**
* Called when an unsupported controller connects.
*
* @event unsupported
* @param {Object} device
* @deprecated not used anymore. Any controller is supported.
*/
UNSUPPORTED: &#x27;unsupported&#x27;,
/**
* Triggered when a controller disconnects.
*
* @event disconnected
* @param {Object} device
*/
DISCONNECTED: &#x27;disconnected&#x27;,
/**
* Called regularly with the latest controllers info.
*
* @event tick
* @param {Array} gamepads
*/
TICK: &#x27;tick&#x27;,
/**
* Called when a gamepad button is pressed down.
*
* @event button-down
* @param {Object} event
* @param {Object} event.gamepad The gamepad object
* @param {String} event.control Control name
*/
BUTTON_DOWN: &#x27;button-down&#x27;,
/**
* Called when a gamepad button is released.
*
* @event button-up
* @param {Object} event
* @param {Object} event.gamepad The gamepad object
* @param {String} event.control Control name
*/
BUTTON_UP: &#x27;button-up&#x27;,
/**
* Called when gamepad axis value changed.
*
* @event axis-changed
* @param {Object} event
* @param {Object} event.gamepad The gamepad object
* @param {String} event.axis Axis name
* @param {Number} event.value New axis value
*/
AXIS_CHANGED: &#x27;axis-changed&#x27;
};
/**
* List of standard button names. The index is the according standard button
* index as per standard.
*
* @property StandardButtons
*/
Gamepad.StandardButtons = [
&#x27;FACE_1&#x27;, &#x27;FACE_2&#x27;, &#x27;FACE_3&#x27;, &#x27;FACE_4&#x27;,
&#x27;LEFT_TOP_SHOULDER&#x27;, &#x27;RIGHT_TOP_SHOULDER&#x27;, &#x27;LEFT_BOTTOM_SHOULDER&#x27;, &#x27;RIGHT_BOTTOM_SHOULDER&#x27;,
&#x27;SELECT_BACK&#x27;, &#x27;START_FORWARD&#x27;, &#x27;LEFT_STICK&#x27;, &#x27;RIGHT_STICK&#x27;,
&#x27;DPAD_UP&#x27;, &#x27;DPAD_DOWN&#x27;, &#x27;DPAD_LEFT&#x27;, &#x27;DPAD_RIGHT&#x27;,
&#x27;HOME&#x27;
];
/**
* List of standard axis names. The index is the according standard axis
* index as per standard.
*
* @property StandardAxes
*/
Gamepad.StandardAxes = [&#x27;LEFT_STICK_X&#x27;, &#x27;LEFT_STICK_Y&#x27;, &#x27;RIGHT_STICK_X&#x27;, &#x27;RIGHT_STICK_Y&#x27;];
var getControlName = function(names, index, extraPrefix) {
return (index &lt; names.length) ? names[index] : extraPrefix + (index - names.length + 1);
};
/**
* The standard mapping that represents the mapping as per definition.
* Each button and axis map to the same index.
*
* @property StandardMapping
*/
Gamepad.StandardMapping = {
env: {},
buttons: {
byButton: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
},
axes: {
byAxis: [0, 1, 2, 3]
}
};
/**
* Mapping of various gamepads that differ from the standard mapping on
* different platforms too unify their buttons and axes.
*
* Each mapping should have an &#x27;env&#x27; object, which describes the environment
* in which the mapping is active. The more entries such an environment has,
* the more specific it is.
*
* Mappings are expressed for both buttons and axes. Buttons might refer to
* axes if they are notified as such.
*
* @property Mappings
*/
Gamepad.Mappings = [
// Retrolink N64 controller on Firefox
{
env: {
platform: FirefoxPlatform.getType(),
type: Gamepad.Type.N64
},
buttons: {
byButton: [
// TODO: Figure out which buttons to map A and Z buttons to.
2, // FACE_1 -- C-down button
1, // FACE_2 -- C-right button
3, // FACE_3 -- C-left button
0, // FACE_4 -- C-down button
4, // LEFT_TOP_SHOULDER -- L button
5, // RIGHT_TOP_SHOULDER -- R button
-1, // LEFT_BOTTOM_SHOULDER -- missing on controller
-1, // RIGHT_BOTTOM_SHOULDER -- missing on controller
8, // SELECT_BACK -- B button (is this right?)
9, // START_FORWARD -- START button
-1, // LEFT_STICK -- missing on controller
-1, // RIGHT_STICK -- missing on controller
12, // DPAD_UP -- not supported by API (but may eventually)
13, // DPAD_DOWN -- not supported by API (but may eventually)
14, // DPAD_LEFT -- not supported by API (but may eventually)
15, // DPAD_RIGHT -- not supported by API (but may eventually)
-1 // HOME -- missing on controller (could be START/B?)
]
},
axes: {
byAxis: [
1, // LEFT_STICK_X
2, // LEFT_STICK_Y
-1, // RIGHT_STICK_X
-1 // RIGHT_STICK_Y
]
}
},
// Retrolink N64 controller on WebKit
{
env: {
platform: WebKitPlatform.getType(),
type: Gamepad.Type.N64
},
buttons: {
byButton: [
// TODO: Figure out which buttons to map A and Z buttons to.
2, // FACE_1 -- C-down button
1, // FACE_2 -- C-right button
3, // FACE_3 -- C-left button
0, // FACE_4 -- C-down button
4, // LEFT_TOP_SHOULDER -- L button
5, // RIGHT_TOP_SHOULDER -- R button
-1, // LEFT_BOTTOM_SHOULDER -- missing on controller
-1, // RIGHT_BOTTOM_SHOULDER -- missing on controller
8, // SELECT_BACK -- B button (is this right?)
9, // START_FORWARD -- START button
-1, // LEFT_STICK -- missing on controller
-1, // RIGHT_STICK -- missing on controller
12, // DPAD_UP -- D-Pad-up button
13, // DPAD_DOWN -- D-Pad-down button
14, // DPAD_LEFT -- D-Pad-left button
15, // DPAD_RIGHT -- D-Pad-right button
-1 // HOME -- missing on controller (could be START/B?)
]
},
axes: {
byAxis: [
0, // LEFT_STICK_X
1, // LEFT_STICK_Y
-1, // RIGHT_STICK_X
-1 // RIGHT_STICK_Y
]
}
},
// XBOX360 controller on Firefox
{
env: {
platform: FirefoxPlatform.getType(),
type: Gamepad.Type.XBOX
},
buttons: {
byButton: [0, 1, 2, 3, 4, 5, 15, 16, 9, 8, 6, 7, 11, 12, 13, 14, 10]
},
axes: {
byAxis: [0, 1, 2, 3]
}
},
// PS3 controller on Firefox
{
env: {
platform: FirefoxPlatform.getType(),
type: Gamepad.Type.PLAYSTATION
},
buttons: {
byButton: [14, 13, 15, 12, 10, 11, 8, 9, 0, 3, 1, 2, 4, 6, 7, 5, 16]
},
axes: {
byAxis: [0, 1, 2, 3]
}
},
// Logitech gamepad on WebKit
{
env: {
platform: WebKitPlatform.getType(),
type: Gamepad.Type.LOGITECH
},
buttons: { // TODO: This can&#x27;t be right - LEFT/RIGHT_STICK have same mappings as HOME/DPAD_UP
byButton: [1, 2, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 10]
},
axes: {
byAxis: [0, 1, 2, 3]
}
},
// Logitech gamepad on Firefox
{
env: {
platform: FirefoxPlatform.getType(),
type: Gamepad.Type.LOGITECH
},
buttons: {
byButton: [0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 11, 12, 13, 14, 10],
byAxis: [-1, -1, -1, -1, -1, -1, [2, 0, 1],
[2, 0, -1]
]
},
axes: {
byAxis: [0, 1, 3, 4]
}
}
];
/**
* Initializes the gamepad.
*
* You usually want to bind to the events first and then initialize it.
*
* @method init
* @return {Boolean} true if a supporting platform was detected, false otherwise.
*/
Gamepad.prototype.init = function() {
var platform = Gamepad.resolvePlatform(this);
var that = this;
this.platform = platform;
this.updateStrategy.start(function() {
that._update();
});
return platform.isSupported();
};
/**
* Binds a listener to a gamepad event.
*
* @method bind
* @param {String} event Event to bind to, one of Gamepad.Event..
* @param {Function} listener Listener to call when given event occurs
* @return {Gamepad} Self
*/
Gamepad.prototype.bind = function(event, listener) {
if (typeof(this.listeners[event]) === &#x27;undefined&#x27;) {
this.listeners[event] = [];
}
this.listeners[event].push(listener);
return this;
};
/**
* Removes listener of given type.
*
* If no type is given, all listeners are removed. If no listener is given, all
* listeners of given type are removed.
*
* @method unbind
* @param {String} [type] Type of listener to remove
* @param {Function} [listener] The listener function to remove
* @return {Boolean} Was unbinding the listener successful
*/
Gamepad.prototype.unbind = function(type, listener) {
if (typeof(type) === &#x27;undefined&#x27;) {
this.listeners = {};
return;
}
if (typeof(listener) === &#x27;undefined&#x27;) {
this.listeners[type] = [];
return;
}
if (typeof(this.listeners[type]) === &#x27;undefined&#x27;) {
return false;
}
for (var i = 0; i &lt; this.listeners[type].length; i++) {
if (this.listeners[type][i] === listener) {
this.listeners[type].splice(i, 1);
return true;
}
}
return false;
};
/**
* Returns the number of connected gamepads.
*
* @method count
* @return {Number}
*/
Gamepad.prototype.count = function() {
return this.gamepads.length;
};
/**
* Fires an internal event with given data.
*
* @method _fire
* @param {String} event Event to fire, one of Gamepad.Event..
* @param {*} data Data to pass to the listener
* @private
*/
Gamepad.prototype._fire = function(event, data) {
if (typeof(this.listeners[event]) === &#x27;undefined&#x27;) {
return;
}
for (var i = 0; i &lt; this.listeners[event].length; i++) {
this.listeners[event][i].apply(this.listeners[event][i], [data]);
}
};
/**
* @method getNullPlatform
* @static
* @return {Object} a platform that does not support anything
*/
Gamepad.getNullPlatform = function() {
return Object.create(nullPlatform);
};
/**
* Resolves platform.
*
* @method resolvePlatform
* @static
* @param listener {Object} the listener to handle _connect() or _disconnect() calls
* @return {Object} A platform instance
*/
Gamepad.resolvePlatform = function(listener) {
var platform = nullPlatform;
var i;
for (i = 0; !platform.isSupported() &amp;&amp; (i &lt; Gamepad.PlatformFactories.length); i++) {
platform = Gamepad.PlatformFactories[i](listener);
}
return platform;
};
/**
* Registers given gamepad.
*
* @method _connect
* @param {Object} gamepad Gamepad to connect to
* @private
*/
Gamepad.prototype._connect = function(gamepad) {
var mapping = this._resolveMapping(gamepad);
var count;
var i;
//gamepad.mapping = this._resolveMapping(gamepad);
gamepad.state = {};
gamepad.lastState = {};
gamepad.updater = [];
count = mapping.buttons.byButton.length;
for (i = 0; i &lt; count; i++) {
this._addButtonUpdater(gamepad, mapping, i);
}
count = mapping.axes.byAxis.length;
for (i = 0; i &lt; count; i++) {
this._addAxisUpdater(gamepad, mapping, i);
}
this.gamepads[gamepad.index] = gamepad;
this._fire(Gamepad.Event.CONNECTED, gamepad);
};
/**
* Adds an updater for a button control
*
* @method _addButtonUpdater
* @private
* @param {Object} gamepad the gamepad for which to create the updater
* @param {Object} mapping the mapping on which to work on
* @param {Number} index button index
*/
Gamepad.prototype._addButtonUpdater = function(gamepad, mapping, index) {
var updater = nullFunction;
var controlName = getControlName(Gamepad.StandardButtons, index, &#x27;EXTRA_BUTTON_&#x27;);
var getter = this._createButtonGetter(gamepad, mapping.buttons, index);
var that = this;
var buttonEventData = {
gamepad: gamepad,
control: controlName
};
gamepad.state[controlName] = 0;
gamepad.lastState[controlName] = 0;
updater = function() {
var value = getter();
var lastValue = gamepad.lastState[controlName];
var isDown = value &gt; 0.5;
var wasDown = lastValue &gt; 0.5;
gamepad.state[controlName] = value;
if (isDown &amp;&amp; !wasDown) {
that._fire(Gamepad.Event.BUTTON_DOWN, Object.create(buttonEventData));
} else if (!isDown &amp;&amp; wasDown) {
that._fire(Gamepad.Event.BUTTON_UP, Object.create(buttonEventData));
}
if ((value !== 0) &amp;&amp; (value !== 1) &amp;&amp; (value !== lastValue)) {
that._fireAxisChangedEvent(gamepad, controlName, value);
}
gamepad.lastState[controlName] = value;
};
gamepad.updater.push(updater);
};
/**
* Adds an updater for an axis control
*
* @method _addAxisUpdater
* @private
* @param {Object} gamepad the gamepad for which to create the updater
* @param {Object} mapping the mapping on which to work on
* @param {Number} index axis index
*/
Gamepad.prototype._addAxisUpdater = function(gamepad, mapping, index) {
var updater = nullFunction;
var controlName = getControlName(Gamepad.StandardAxes, index, &#x27;EXTRA_AXIS_&#x27;);
var getter = this._createAxisGetter(gamepad, mapping.axes, index);
var that = this;
gamepad.state[controlName] = 0;
gamepad.lastState[controlName] = 0;
updater = function() {
var value = getter();
var lastValue = gamepad.lastState[controlName];
gamepad.state[controlName] = value;
if ((value !== lastValue)) {
that._fireAxisChangedEvent(gamepad, controlName, value);
}
gamepad.lastState[controlName] = value;
};
gamepad.updater.push(updater);
};
/**
* Fires an AXIS_CHANGED event
* @method _fireAxisChangedEvent
* @private
* @param {Object} gamepad the gamepad to notify for
* @param {String} controlName name of the control that changes its value
* @param {Number} value the new value
*/
Gamepad.prototype._fireAxisChangedEvent = function(gamepad, controlName, value) {
var eventData = {
gamepad: gamepad,
axis: controlName,
value: value
};
this._fire(Gamepad.Event.AXIS_CHANGED, eventData);
};
/**
* Creates a getter according to the mapping entry for the specific index.
* Currently supported entries:
*
* buttons.byButton[index]: Number := Index into gamepad.buttons; -1 tests byAxis
* buttons.byAxis[index]: Array := [Index into gamepad.axes; Zero Value, One Value]
*
* @method _createButtonGetter
* @private
* @param {Object} gamepad the gamepad for which to create a getter
* @param {Object} buttons the mappings entry for the buttons
* @param {Number} index the specific button entry
* @return {Function} a getter returning the value for the requested button
*/
Gamepad.prototype._createButtonGetter = (function() {
var nullGetter = function() {
return 0;
};
var createRangeGetter = function(valueGetter, from, to) {
var getter = nullGetter;
if (from &lt; to) {
getter = function() {
var range = to - from;
var value = valueGetter();
value = (value - from) / range;
return (value &lt; 0) ? 0 : value;
};
} else if (to &lt; from) {
getter = function() {
var range = from - to;
var value = valueGetter();
value = (value - to) / range;
return (value &gt; 1) ? 0 : (1 - value);
};
}
return getter;
};
var isArray = function(thing) {
return Object.prototype.toString.call(thing) === &#x27;[object Array]&#x27;;
};
return function(gamepad, buttons, index) {
var getter = nullGetter;
var entry;
var that = this;
entry = buttons.byButton[index];
if (entry !== -1) {
if ((typeof(entry) === &#x27;number&#x27;) &amp;&amp; (entry &lt; gamepad.buttons.length)) {
getter = function() {
var value = gamepad.buttons[entry];
if (typeof value === &#x27;number&#x27;) {
return value;
}
if (typeof value.value === &#x27;number&#x27;) {
return value.value;
}
return 0;
};
}
} else if (buttons.byAxis &amp;&amp; (index &lt; buttons.byAxis.length)) {
entry = buttons.byAxis[index];
if (isArray(entry) &amp;&amp; (entry.length == 3) &amp;&amp; (entry[0] &lt; gamepad.axes.length)) {
getter = function() {
var value = gamepad.axes[entry[0]];
return that._applyDeadzoneMaximize(value);
};
getter = createRangeGetter(getter, entry[1], entry[2]);
}
}
return getter;
};
})();
/**
* Creates a getter according to the mapping entry for the specific index.
* Currently supported entries:
*
* axes.byAxis[index]: Number := Index into gamepad.axes; -1 ignored
*
* @method _createAxisGetter
* @private
* @param {Object} gamepad the gamepad for which to create a getter
* @param {Object} axes the mappings entry for the axes
* @param {Number} index the specific axis entry
* @return {Function} a getter returning the value for the requested axis
*/
Gamepad.prototype._createAxisGetter = (function() {
var nullGetter = function() {
return 0;
};
return function(gamepad, axes, index) {
var getter = nullGetter;
var entry;
var that = this;
entry = axes.byAxis[index];
if (entry !== -1) {
if ((typeof(entry) === &#x27;number&#x27;) &amp;&amp; (entry &lt; gamepad.axes.length)) {
getter = function() {
var value = gamepad.axes[entry];
return that._applyDeadzoneMaximize(value);
};
}
}
return getter;
};
})();
/**
* Disconnects from given gamepad.
*
* @method _disconnect
* @param {Object} gamepad Gamepad to disconnect
* @private
*/
Gamepad.prototype._disconnect = function(gamepad) {
var newGamepads = [],
i;
if (typeof(this.gamepads[gamepad.index]) !== &#x27;undefined&#x27;) {
delete this.gamepads[gamepad.index];
}
for (i = 0; i &lt; this.gamepads.length; i++) {
if (typeof(this.gamepads[i]) !== &#x27;undefined&#x27;) {
newGamepads[i] = this.gamepads[i];
}
}
this.gamepads = newGamepads;
this._fire(Gamepad.Event.DISCONNECTED, gamepad);
};
/**
* Resolves controller type from its id.
*
* @method _resolveControllerType
* @param {String} id Controller id
* @return {String} Controller type, one of Gamepad.Type
* @private
*/
Gamepad.prototype._resolveControllerType = function(id) {
// Lowercase and strip all extra whitespace.
id = id.toLowerCase().replace(/\s+/g, &#x27; &#x27;).replace(/^\s+|\s+$/g, &#x27;&#x27;);
if (id.indexOf(&#x27;playstation&#x27;) !== -1) {
return Gamepad.Type.PLAYSTATION;
} else if (
id.indexOf(&#x27;logitech&#x27;) !== -1 || id.indexOf(&#x27;wireless gamepad&#x27;) !== -1) {
return Gamepad.Type.LOGITECH;
} else if (id.indexOf(&#x27;xbox&#x27;) !== -1 || id.indexOf(&#x27;360&#x27;) !== -1) {
return Gamepad.Type.XBOX;
} else if ((id.indexOf(&#x27;79-6-generic&#x27;) !== -1 &amp;&amp; id.indexOf(&#x27;joystick&#x27;) !== -1) ||
(id.indexOf(&#x27;vendor: 0079 product: 0006&#x27;) !== -1 &amp;&amp;
id.indexOf(&#x27;generic usb joystick&#x27;) !== -1)) {
return Gamepad.Type.N64;
} else {
return Gamepad.Type.UNKNOWN;
}
};
/**
* @method _resolveMapping
* @private
* @param {Object} gamepad the gamepad for which to resolve the mapping
* @return {Object} a mapping object for the given gamepad
*/
Gamepad.prototype._resolveMapping = function(gamepad) {
var mappings = Gamepad.Mappings;
var mapping = null;
var env = {
platform: this.platform.getType(),
type: this._resolveControllerType(gamepad.id)
};
var i;
var test;
for (i = 0; !mapping &amp;&amp; (i &lt; mappings.length); i++) {
test = mappings[i];
if (Gamepad.envMatchesFilter(test.env, env)) {
mapping = test;
}
}
return mapping || Gamepad.StandardMapping;
};
/**
* @method envMatchesFilter
* @static
* @param {Object} filter the filter object describing properties to match
* @param {Object} env the environment object that is matched against filter
* @return {Boolean} true if env is covered by filter
*/
Gamepad.envMatchesFilter = function(filter, env) {
var result = true;
var field;
for (field in filter) {
if (filter[field] !== env[field]) {
result = false;
}
}
return result;
};
/**
* Updates the controllers, triggering TICK events.
*
* @method _update
* @private
*/
Gamepad.prototype._update = function() {
this.platform.update();
this.gamepads.forEach(function(gamepad) {
if (gamepad) {
gamepad.updater.forEach(function(updater) {
updater();
});
}
});
if (this.gamepads.length &gt; 0) {
this._fire(Gamepad.Event.TICK, this.gamepads);
}
},
/**
* Applies deadzone and maximization.
*
* You can change the thresholds via deadzone and maximizeThreshold members.
*
* @method _applyDeadzoneMaximize
* @param {Number} value Value to modify
* @param {Number} [deadzone] Deadzone to apply
* @param {Number} [maximizeThreshold] From which value to maximize value
* @private
*/
Gamepad.prototype._applyDeadzoneMaximize = function(
value,
deadzone,
maximizeThreshold) {
deadzone = typeof(deadzone) !== &#x27;undefined&#x27; ? deadzone : this.deadzone;
maximizeThreshold = typeof(maximizeThreshold) !== &#x27;undefined&#x27; ? maximizeThreshold : this.maximizeThreshold;
if (value &gt;= 0) {
if (value &lt; deadzone) {
value = 0;
} else if (value &gt; maximizeThreshold) {
value = 1;
}
} else {
if (value &gt; -deadzone) {
value = 0;
} else if (value &lt; -maximizeThreshold) {
value = -1;
}
}
return value;
};
exports.Gamepad = Gamepad;
})(((typeof(module) !== &#x27;undefined&#x27;) &amp;&amp; module.exports) || window);
</pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="../assets/vendor/prettify/prettify-min.js"></script>
<script>prettyPrint();</script>
<script src="../assets/js/yui-prettify.js"></script>
<script src="../assets/../api.js"></script>
<script src="../assets/js/api-filter.js"></script>
<script src="../assets/js/api-list.js"></script>
<script src="../assets/js/api-search.js"></script>
<script src="../assets/js/apidocs.js"></script>
</body>
</html>