Last active
September 17, 2015 02:21
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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