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); } }