Skip to content

Instantly share code, notes, and snippets.

@girasquid
Last active September 17, 2015 02:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save girasquid/50c7c9f2de45a6079e4c to your computer and use it in GitHub Desktop.
Save girasquid/50c7c9f2de45a6079e4c to your computer and use it in GitHub Desktop.
Kinda-bad multi-controller helper library, loosely modelled off KeyActionBinder but simpler. Supports XBone, PS3 DS, and Logitech F310 (DirectInput mode) on OS X.
package controllers {
import com.junkbyte.console.ConsoleChannel;
import flash.events.GameInputEvent;
import flash.ui.GameInput;
import flash.ui.GameInputDevice;
public class Controllers {
private static const channel:ConsoleChannel = new ConsoleChannel("Controllers");
private static var _input:GameInput;
private static var _connectedDevices:Array;
private static var _removedDevice:GameInputDevice;
public static function init():void {
_input = new GameInput();
_input.addEventListener(GameInputEvent.DEVICE_ADDED, deviceAddedHandler);
_input.addEventListener(GameInputEvent.DEVICE_REMOVED, deviceRemovedHandler);
_input.addEventListener(GameInputEvent.DEVICE_UNUSABLE, deviceUnusableHandler);
_connectedDevices = new Array();
for(var i:int = 0; i < GameInput.numDevices; i++) {
attach(GameInput.getDeviceAt(i));
}
}
public static function get numControllers():int {
return _connectedDevices.length;
}
public static function getDeviceAt(index:int):Controller {
return _connectedDevices[index];
}
private static function attach(d:GameInputDevice):void {
channel.info("Added:", d.name, "(", d.id, ")");
d.enabled = true;
_connectedDevices.push(resolveController(d));
channel.info(_connectedDevices);
}
private static function deviceAddedHandler(e:GameInputEvent):void {
// TODO handle reconnects
attach(e.device);
}
private static function deviceRemovedHandler(e:GameInputEvent):void {
// LOLOLOLOLOLOL JUST PUNT ON THIS
for(var i:int = 0; i < _connectedDevices.length; i++) {
if(_connectedDevices[i].device == e.device) {
// splice this one and break
}
}
}
private static function deviceUnusableHandler(e:GameInputEvent):void {
// lol when does this happen
}
private static function resolveController(d:GameInputDevice):Controller {
// Logitech F310 that returns "Logitech Dual Action" for name
if(d.name.toLowerCase().indexOf("logitech") != -1) {
return new LogitechController(d);
// PS3 wired controller that reutrns "PLAYSTATION(R)3 Controller" for name
} else if(d.name.toLowerCase().indexOf("playstation") != -1) {
return new PlaystationController(d);
// XBone wired controller that returns "X360Controller" for name
} else if(d.name.toLowerCase().indexOf("360") != -1) {
return new XboxController(d);
} else {
return new Controller(d);
}
}
}
}
import flash.ui.GameInputDevice;
import flash.ui.GameInputControl;
import flash.events.Event;
import com.junkbyte.console.ConsoleChannel;
class Controller {
public static const channel:ConsoleChannel = new ConsoleChannel("Controller");
channel.enabled = false;
public var device:GameInputDevice;
public static const STICK_LEFT_X:String = "stick_left_x";
public static const STICK_LEFT_Y:String = "stick_left_y";
public static const STICK_LEFT_PRESS:String = "stick_left_press";
public static const STICK_RIGHT_X:String = "stick_right_x";
public static const STICK_RIGHT_Y:String = "stick_right_y";
public static const STICK_RIGHT_PRESS:String = "stick_right_press";
public static const LB:String = "left_button";
public static const LT:String = "left_trigger";
public static const RB:String = "right_button";
public static const RT:String = "right_trigger";
public static const DPAD_UP:String = "dpad_up";
public static const DPAD_DOWN:String = "dpad_down";
public static const DPAD_LEFT:String = "dpad_left";
public static const DPAD_RIGHT:String = "dpad_right";
public static const ACTION_UP:String = "action_up";
public static const ACTION_DOWN:String = "action_down";
public static const ACTION_LEFT:String = "action_left";
public static const ACTION_RIGHT:String = "action_right";
public static const BACK:String = "meta_back";
public static const SELECT:String = "meta_select";
public static const START:String = "meta_start";
public static const MENU:String = "meta_menu";
public static const OPTIONS:String = "meta_options";
public static const TRACKPAD:String = "meta_trackpad";
public static const SHARE:String = "meta_share";
private var _controls:Object;
public function Controller(d:GameInputDevice):void {
device = d;
_controls = new Object();
bindControls();
}
public function pressing(controlName:String):Boolean {
return _controls[controlName].value > 0;
}
// Consuming comes from KeyActionBinder; it lets you make it so that the press
// only gets tracked once, even if the player holds the button down.
public function consume(controlName:String):void {
_controls[controlName].consume();
}
public function value(controlName:String):Number {
return _controls[controlName].value;
}
private function bindControls():void {
for(var i:int = 0; i < device.numControls; i++) {
var control:GameInputControl = device.getControlAt(i);
_controls[controlsMap[control.id]] = new SimpleControl(control, this, this.invertedControlsMap.indexOf(controlsMap[control.id]) != -1);
}
}
// private function debugControlChangeHandler(e:Event):void {
// var control:GameInputControl = GameInputControl(e.target);
// // channel.info(control.id, ":", GameInputControl(e.target).value);
// // channel.info("Change", this, this.controlsMap[control.id]);
// }
protected function get controlsMap():Object {
return {};
}
protected function get invertedControlsMap():Array {
return [];
}
}
class PlaystationController extends Controller {
public function PlaystationController(d:GameInputDevice):void {
super(d);
}
protected override function get controlsMap():Object {
return {
"AXIS_0": STICK_LEFT_Y,
"AXIS_1": STICK_LEFT_X,
"AXIS_2": STICK_RIGHT_Y,
"AXIS_3": STICK_RIGHT_X,
"BUTTON_4": SELECT,
"BUTTON_7": START,
"BUTTON_20": MENU,
"BUTTON_14": LB,
"BUTTON_12": LT,
"BUTTON_15": RB,
"BUTTON_13": RT,
"BUTTON_5": STICK_LEFT_PRESS,
"BUTTON_6": STICK_RIGHT_PRESS,
"BUTTON_8": DPAD_UP,
"BUTTON_9": DPAD_RIGHT,
"BUTTON_10": DPAD_DOWN,
"BUTTON_11": DPAD_LEFT,
"BUTTON_16": ACTION_UP,
"BUTTON_17": ACTION_RIGHT,
"BUTTON_18": ACTION_DOWN,
"BUTTON_19": ACTION_LEFT
};
}
protected override function get invertedControlsMap():Array {
return [STICK_LEFT_X, STICK_RIGHT_X];
}
}
class XboxController extends Controller {
public function XboxController(d:GameInputDevice):void {
super(d);
}
protected override function get controlsMap():Object {
return {
"BUTTON_21": MENU,
"BUTTON_10": START,
"BUTTON_11": SELECT,
"AXIS_0": STICK_LEFT_Y,
"AXIS_1": STICK_LEFT_X,
"BUTTON_12": STICK_LEFT_PRESS,
"AXIS_3": STICK_RIGHT_Y,
"AXIS_4": STICK_RIGHT_X,
"BUTTON_13": STICK_RIGHT_PRESS,
"BUTTON_14": LB,
"AXIS_2": LT,
"BUTTON_15": RB,
"AXIS_5": RT,
"BUTTON_6": DPAD_UP,
"BUTTON_9": DPAD_RIGHT,
"BUTTON_7": DPAD_DOWN,
"BUTTON_8": DPAD_LEFT,
"BUTTON_20": ACTION_UP,
"BUTTON_18": ACTION_RIGHT,
"BUTTON_17": ACTION_DOWN,
"BUTTON_19": ACTION_LEFT
}
}
protected override function get invertedControlsMap():Array {
return [STICK_LEFT_X, STICK_RIGHT_X];
}
}
class LogitechController extends Controller {
public function LogitechController(d:GameInputDevice):void {
super(d);
}
protected override function get controlsMap():Object {
return {
"BUTTON_17": BACK,
"BUTTON_18": START,
"AXIS_1": STICK_LEFT_Y,
"AXIS_2": STICK_LEFT_X,
"BUTTON_19": STICK_LEFT_PRESS,
"AXIS_4": STICK_RIGHT_Y,
"AXIS_3": STICK_RIGHT_X,
"BUTTON_20": STICK_RIGHT_PRESS,
"BUTTON_13": LB,
"BUTTON_15": LT,
"BUTTON_14": RB,
"BUTTON_16": RT,
"BUTTON_5": DPAD_UP,
"BUTTON_8": DPAD_RIGHT,
"BUTTON_6": DPAD_DOWN,
"BUTTON_7": DPAD_LEFT,
"BUTTON_12": ACTION_UP,
"BUTTON_11": ACTION_RIGHT,
"BUTTON_10": ACTION_DOWN,
"BUTTON_9": ACTION_LEFT
};
}
protected override function get invertedControlsMap():Array {
return [STICK_LEFT_X, STICK_RIGHT_X, STICK_RIGHT_Y];
}
}
class SimpleControl {
public var value:Number;
private var device:Controller;
private var inverted:Boolean;
private static const channel:ConsoleChannel = new ConsoleChannel("SimpleControl");
private static const DEFAULT_VALUE:Number = 0;
public function SimpleControl(c:GameInputControl, d:Controller, invertValues:Boolean = false):void {
c.addEventListener(Event.CHANGE, changeHandler);
value = DEFAULT_VALUE;
device = d;
inverted = invertValues;
}
public function consume():void {
value = DEFAULT_VALUE;
}
private function changeHandler(e:Event):void {
if(inverted) {
value = -GameInputControl(e.target).value;
} else {
value = GameInputControl(e.target).value;
}
channel.add("Change (" + device + ") " + GameInputControl(e.target).id, value, true);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment