Skip to content

Commit ec4be00

Browse files
committed
Improved gamepad support and added basic mapping for unknown controllers.
Updated dependencies.
1 parent c8b571a commit ec4be00

File tree

13 files changed

+105
-33
lines changed

13 files changed

+105
-33
lines changed

src/frameworks/internal/ev3/ev3.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,7 @@ cwc.framework.Ev3.prototype.handleUpdateWheelDiameter_ = function(data) {
713713
*/
714714
cwc.framework.Ev3.prototype.handleUpdateGamepad_ = function(data) {
715715
console.log(data);
716+
console.log(data['buttons']);
716717
};
717718

718719

src/mode/lego/ev3/monitor.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,10 @@ cwc.mode.lego.ev3.Monitor.prototype.addGamepadHandler_ = function() {
259259
this.api.rotatePower(e.data * 100);
260260
});
261261
this.events_.listen(eventHandler, cwc.utils.Gamepad.Events.Type.BUTTON[0],
262-
() => {
263-
this.api.playTone(3000, 200, 50);
262+
(e) => {
263+
if (e.data) {
264+
this.api.playTone(3000, 200, 50);
265+
}
264266
});
265267
};
266268

src/mode/sphero/classic/advanced/mod.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
goog.provide('cwc.mode.sphero.classic.advanced.Mod');
2121

2222
goog.require('cwc.mode.default.Mod');
23-
goog.require('cwc.mode.sphero.Connection');
2423
goog.require('cwc.mode.sphero.Hints');
2524
goog.require('cwc.mode.sphero.Monitor');
2625
goog.require('cwc.mode.sphero.Runner');
26+
goog.require('cwc.mode.sphero.classic.Connection');
2727
goog.require('cwc.renderer.external.Sphero');
2828

2929

@@ -36,7 +36,7 @@ cwc.mode.sphero.classic.advanced.Mod = function(helper) {
3636
this.mod = new cwc.mode.default.Mod(helper);
3737

3838
/** @type {!cwc.mode.sphero.Connection} */
39-
this.connection = new cwc.mode.sphero.Connection(helper);
39+
this.connection = new cwc.mode.sphero.classic.Connection(helper);
4040

4141
/** @type {!cwc.mode.sphero.Monitor} */
4242
this.monitor = new cwc.mode.sphero.Monitor(helper, this.connection);

src/mode/sphero/classic/blockly/mod.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
goog.provide('cwc.mode.sphero.classic.blockly.Mod');
2121

2222
goog.require('cwc.mode.default.Mod');
23-
goog.require('cwc.mode.sphero.Connection');
2423
goog.require('cwc.mode.sphero.Monitor');
2524
goog.require('cwc.mode.sphero.Runner');
25+
goog.require('cwc.mode.sphero.classic.Connection');
2626
goog.require('cwc.renderer.external.Sphero');
2727
goog.require('cwc.soy.sphero.Blocks');
2828

@@ -36,7 +36,7 @@ cwc.mode.sphero.classic.blockly.Mod = function(helper) {
3636
this.mod = new cwc.mode.default.Mod(helper);
3737

3838
/** @type {!cwc.mode.sphero.Connection} */
39-
this.connection = new cwc.mode.sphero.Connection(helper);
39+
this.connection = new cwc.mode.sphero.classic.Connection(helper);
4040

4141
/** @type {!cwc.mode.sphero.Monitor} */
4242
this.monitor = new cwc.mode.sphero.Monitor(helper, this.connection);

src/mode/sphero/connection.js renamed to src/mode/sphero/classic/connection.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
*
1818
* @author [email protected] (Markus Bordihn)
1919
*/
20-
goog.provide('cwc.mode.sphero.Connection');
20+
goog.provide('cwc.mode.sphero.classic.Connection');
2121

2222
goog.require('cwc.protocol.sphero.classic.Api');
2323
goog.require('cwc.utils.Events');
@@ -29,7 +29,7 @@ goog.require('goog.Timer');
2929
* @constructor
3030
* @param {!cwc.utils.Helper} helper
3131
*/
32-
cwc.mode.sphero.Connection = function(helper) {
32+
cwc.mode.sphero.classic.Connection = function(helper) {
3333
/** @type {string} */
3434
this.name = 'Sphero 2.0 Connection';
3535

@@ -57,7 +57,7 @@ cwc.mode.sphero.Connection = function(helper) {
5757
* Connects the Sphero unit.
5858
* @export
5959
*/
60-
cwc.mode.sphero.Connection.prototype.init = function() {
60+
cwc.mode.sphero.classic.Connection.prototype.init = function() {
6161
if (!this.connectMonitor) {
6262
this.connectMonitor = new goog.Timer(this.connectMonitorInterval);
6363
this.events_.listen(this.connectMonitor, goog.Timer.TICK,
@@ -73,7 +73,7 @@ cwc.mode.sphero.Connection.prototype.init = function() {
7373
* @param {Event=} opt_event
7474
* @export
7575
*/
76-
cwc.mode.sphero.Connection.prototype.connect = function(opt_event) {
76+
cwc.mode.sphero.classic.Connection.prototype.connect = function(opt_event) {
7777
if (!this.isConnected()) {
7878
let bluetoothInstance = this.helper.getInstance('bluetooth', true);
7979
bluetoothInstance.autoConnectDevice(this.autoConnectName, function(device) {
@@ -89,7 +89,7 @@ cwc.mode.sphero.Connection.prototype.connect = function(opt_event) {
8989
/**
9090
* Stops the current executions.
9191
*/
92-
cwc.mode.sphero.Connection.prototype.stop = function() {
92+
cwc.mode.sphero.classic.Connection.prototype.stop = function() {
9393
let runnerInstance = this.helper.getInstance('runner');
9494
if (runnerInstance) {
9595
runnerInstance.terminate();
@@ -103,7 +103,7 @@ cwc.mode.sphero.Connection.prototype.stop = function() {
103103
* @param {Event=} opt_event
104104
* @export
105105
*/
106-
cwc.mode.sphero.Connection.prototype.reset = function(opt_event) {
106+
cwc.mode.sphero.classic.Connection.prototype.reset = function(opt_event) {
107107
if (this.isConnected()) {
108108
this.api_.reset();
109109
}
@@ -114,15 +114,15 @@ cwc.mode.sphero.Connection.prototype.reset = function(opt_event) {
114114
* @return {!boolean}
115115
* @export
116116
*/
117-
cwc.mode.sphero.Connection.prototype.isConnected = function() {
117+
cwc.mode.sphero.classic.Connection.prototype.isConnected = function() {
118118
return this.api_.isConnected();
119119
};
120120

121121

122122
/**
123123
* @return {goog.events.EventTarget}
124124
*/
125-
cwc.mode.sphero.Connection.prototype.getEventHandler = function() {
125+
cwc.mode.sphero.classic.Connection.prototype.getEventHandler = function() {
126126
return this.api_.getEventHandler();
127127
};
128128

@@ -131,15 +131,15 @@ cwc.mode.sphero.Connection.prototype.getEventHandler = function() {
131131
* @return {!cwc.protocol.sphero.classic.Api}
132132
* @export
133133
*/
134-
cwc.mode.sphero.Connection.prototype.getApi = function() {
134+
cwc.mode.sphero.classic.Connection.prototype.getApi = function() {
135135
return this.api_;
136136
};
137137

138138

139139
/**
140140
* Cleans up the event listener and any other modification.
141141
*/
142-
cwc.mode.sphero.Connection.prototype.cleanUp = function() {
142+
cwc.mode.sphero.classic.Connection.prototype.cleanUp = function() {
143143
console.log('Clean up Sphero connection ...');
144144
if (this.connectMonitor) {
145145
this.connectMonitor.stop();

src/utils/byte_tools.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ cwc.utils.ByteTools.uint8Data;
148148
* @return {cwc.utils.ByteTools.uint8Data} result
149149
*/
150150
cwc.utils.ByteTools.getUint8Data = function(data, headers, size, buffer) {
151-
console.log(data, headers, size, buffer);
152151
// Prepare Data Buffer
153152
let dataArray = cwc.utils.ByteTools.getUint8Array(data);
154153
let uint8Data = {

src/utils/gamepad/gamepad.js

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
*/
2020
goog.provide('cwc.utils.Gamepad');
2121

22+
goog.require('cwc.utils.Gamepad.Events');
23+
goog.require('cwc.utils.Gamepad.Mapping');
2224
goog.require('cwc.utils.Logger');
2325

2426
goog.require('goog.events.EventTarget');
@@ -60,7 +62,7 @@ cwc.utils.Gamepad.prototype.prepare = function() {
6062
window.addEventListener('gamepadconnected',
6163
this.handleConnect_.bind(this));
6264
window.addEventListener('gamepaddisconnected',
63-
this.handleDisconnect_.bind(this));
65+
this.handleDisconnect_.bind(this));
6466
};
6567

6668

@@ -142,7 +144,7 @@ cwc.utils.Gamepad.prototype.handleTick_ = function() {
142144
this.handleEvent_(gamepad);
143145
this.cache_['timestamp'] = gamepad['timestamp'];
144146
}
145-
window.requestAnimationFrame(this.handleTick_.bind(this));
147+
window.setTimeout(this.handleTick_.bind(this), 33);
146148
};
147149

148150

@@ -151,31 +153,40 @@ cwc.utils.Gamepad.prototype.handleTick_ = function() {
151153
*/
152154
cwc.utils.Gamepad.prototype.handleEvent_ = function(gamepad) {
153155
let changed = false;
156+
157+
// Checking current status for each single axes.
154158
gamepad['axes'].forEach((axis, index) => {
159+
let mappedIndex = cwc.utils.Gamepad.getIndex(index, 'axes', gamepad);
155160
// Smooth axes to avoid false triggers from vibrations.
156161
if (axis > -0.04 && axis < 0.04) {
157162
axis = 0;
158163
}
159-
if (axis !== this.cache_['axes'][index]) {
160-
this.cache_['axes'][index] = axis;
164+
if (axis !== this.cache_['axes'][mappedIndex]) {
165+
this.cache_['axes'][mappedIndex] = axis;
161166
this.eventHandler_.dispatchEvent(cwc.utils.Gamepad.Events.axisMoved(
162-
index, axis
167+
mappedIndex, axis
163168
));
164169
changed = true;
165170
}
166171
});
172+
173+
// Checking current status for each single button.
167174
gamepad['buttons'].forEach((button, index) => {
168-
if (button['pressed'] ||
169-
this.cache_['buttons'][index] !== button['value']) {
170-
this.cache_['buttons'][index] = button['value'];
175+
let mappedIndex = cwc.utils.Gamepad.getIndex(index, 'buttons', gamepad);
176+
if (this.cache_['buttons'][mappedIndex] !== button['value']) {
177+
this.cache_['buttons'][mappedIndex] = button['value'];
178+
let value = button['value'];
171179
this.eventHandler_.dispatchEvent(cwc.utils.Gamepad.Events.buttonPressed(
172-
index, button['value']
180+
mappedIndex, button['value'], value
173181
));
174182
changed = true;
175183
}
176184
});
185+
177186
if (changed) {
178-
this.eventHandler_.dispatchEvent(cwc.utils.Gamepad.Events.update());
187+
// Create an immutable version of the current cache for the event.
188+
this.eventHandler_.dispatchEvent(cwc.utils.Gamepad.Events.update(
189+
JSON.parse(JSON.stringify(this.cache_))));
179190
}
180191
};
181192

@@ -194,6 +205,28 @@ cwc.utils.Gamepad.getAngle = function(x, y, shift = 90) {
194205
angle += 360;
195206
}
196207
}
197-
198208
return angle;
199209
};
210+
211+
212+
/**
213+
* Return's mapped index for supported controllers.
214+
* @param {!number} index
215+
* @param {!string} type
216+
* @param {!Object} gamepad
217+
* @return {!number}
218+
*/
219+
cwc.utils.Gamepad.getIndex = function(index, type, gamepad) {
220+
if (gamepad['mapping'] === 'standard') {
221+
return index;
222+
}
223+
224+
if (gamepad['mapping'] === '' && cwc.utils.Gamepad.Mapping[gamepad['id']]) {
225+
let mapping = cwc.utils.Gamepad.Mapping[gamepad['id']][type];
226+
if (typeof mapping[index] !== 'undefined') {
227+
return mapping[index] || 0;
228+
}
229+
}
230+
231+
return index || 0;
232+
};

src/utils/gamepad/mapping.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* @fileoverview Gamepad Mapping definitions.
3+
*
4+
* @license Copyright 2018 The Coding with Chrome Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
* @author [email protected] (Markus Bordihn)
19+
*/
20+
goog.provide('cwc.utils.Gamepad.Mapping');
21+
22+
23+
/**
24+
* @type {Object}
25+
*/
26+
cwc.utils.Gamepad.Mapping = {
27+
'HORIPAD 4 (Vendor: 0f0d Product: 0066)': {
28+
'axes': {
29+
5: 3,
30+
},
31+
'buttons': {
32+
0: 2,
33+
1: 0,
34+
2: 1,
35+
},
36+
},
37+
};

third_party/blockly

Submodule blockly updated 227 files

third_party/brython

Submodule brython updated 78 files

0 commit comments

Comments
 (0)