浏览代码

Merge pull request #187 from motion-twin/pad

HL SDL Pad
Nicolas Cannasse 9 年之前
父节点
当前提交
aaf1303148
共有 3 个文件被更改,包括 268 次插入2 次删除
  1. 128 2
      hxd/Pad.hx
  2. 2 0
      hxd/System.hx
  3. 138 0
      samples/Pad.hx

+ 128 - 2
hxd/Pad.hx

@@ -25,6 +25,31 @@ class Pad {
 		dpadRight : 19,
 		names : ["LX","LY","RX","RY","A","B","X","Y","LB","RB","LT","RT","Select","Start","LCLK","RCLK","DUp","DDown","DLeft","DRight"],
 	};
+	
+	public static var CONFIG_SDL = {
+		analogX : 0,
+		analogY : 1,
+		ranalogX : 2,
+		ranalogY : 3,
+		A : 6,
+		B : 7,
+		X : 8,
+		Y : 9,
+		LB : 15,
+		RB : 16,
+		LT : 4,
+		RT : 5,
+		back : 10,
+		start : 12,
+		analogClick : 13,
+		ranalogClick : 14,
+		dpadUp : 17,
+		dpadDown : 18,
+		dpadLeft : 19,
+		dpadRight : 20,
+		names : ["LX","LY","RX","RY","LT","RT","A","B","X","Y","Select","Guide","Start","LCLK","RCLK","LB","RB","DUp","DDown","DLeft","DRight"],
+	};
+
 
 	public var connected(default, null) = true;
 	public var name(get, never) : String;
@@ -33,13 +58,16 @@ class Pad {
 	public var yAxis : Float = 0.;
 	public var buttons : Array<Bool> = [];
 	public var values : Array<Float> = [];
+	
+	public dynamic function onDisconnect(){
+	}
 
 	function new() {
 	}
 
 	function get_name() {
 		if( index < 0 ) return "Dummy GamePad";
-		#if flash
+		#if (flash || hlsdl)
 		return d.name;
 		#else
 		return "GamePad";
@@ -60,6 +88,12 @@ class Pad {
 	static var waitPad : Pad -> Void;
 	static var initDone = false;
 	static var inst : flash.ui.GameInput;
+	static var pads : Array<hxd.Pad> = [];
+	#elseif hlsdl
+	var d : sdl.GameController;
+	static var waitPad : Pad -> Void;
+	static var initDone = false;
+	static var pads : Map<Int, hxd.Pad> = new Map();
 	#end
 
 	/**
@@ -73,6 +107,7 @@ class Pad {
 			inst = new flash.ui.GameInput();
 			inst.addEventListener(flash.events.GameInputEvent.DEVICE_ADDED, function(e:flash.events.GameInputEvent) {
 				var p = new Pad();
+				pads.push( p );
 				p.d = e.device;
 				//trace(p.d.name, p.d.id);
 				for( i in 0...flash.ui.GameInput.numDevices )
@@ -110,10 +145,101 @@ class Pad {
 
 				if( waitPad != null ) waitPad(p);
 			});
+			inst.addEventListener(flash.events.GameInputEvent.DEVICE_REMOVED, function(e:flash.events.GameInputEvent) {
+				for( p in pads )
+					if( p.d.id == e.device.id ){
+						pads.remove( p );
+						p.d.enabled = false;
+						p.connected = false;
+						p.onDisconnect();
+						break;
+					}
+			});
+			inst.addEventListener(flash.events.GameInputEvent.DEVICE_UNUSABLE, function(e:flash.events.GameInputEvent) {
+				for( p in pads )
+					if( p.d.id == e.device.id ){
+						pads.remove( p );
+						p.d.enabled = false;
+						p.connected = false;
+						p.onDisconnect();
+						break;
+					}
+			});
 			var count = flash.ui.GameInput.numDevices; // necessary to trigger added
 		}
-		#else
+		#elseif hlsdl
+		waitPad = onPad;
+		if( !initDone ) {
+			initDone = true;
+			var c = @:privateAccess sdl.GameController.gctrlCount();
+			for( idx in 0...c )
+				initPad( idx );
+		}
 		#end
 	}
+	
+	#if hlsdl
+	inline function _setAxis( axisId : Int, value : Int ){
+		var v = value / 0x7FFF;
+		
+		// Invert Y axis
+		if( axisId == 1 || axisId == 3 )
+			values[ axisId ] = -v;
+		else
+			values[ axisId ] = v;
+		
+		if( axisId == 0 )
+			xAxis = v;
+		else if( axisId == 1 )
+			yAxis = v;
+	}
+	
+	inline function _setButton( btnId : Int, down : Bool ){
+		buttons[ btnId+6 ] = down;
+		values[ btnId+6 ] = down ? 1 : 0;
+	}
+	
+	static function initPad( index ){
+		var sp = new sdl.GameController( index );
+		if( @:privateAccess sp.ptr == null )
+			return;
+		var p = new hxd.Pad();
+		p.index = sp.id;
+		p.d = sp;
+		pads.set( p.index, p );
+		for( axis in 0...6 )
+			p._setAxis( axis, sp.getAxis(axis) );
+		for( button in 0...15 )
+			p._setButton( button, sp.getButton(button) );
+		waitPad( p );
+	}
+	
+	static function onEvent( e : sdl.Event ){
+		var p = pads.get( e.controller );
+		switch( e.type ){
+			case GControllerAdded:
+				if( initDone )
+					initPad(e.controller);
+			case GControllerRemoved:
+				if( p != null ){
+					pads.remove( p.index );
+					p.d.close();
+					p.connected = false;
+					p.onDisconnect();
+				}
+			case GControllerDown:
+				if( p != null && e.button > -1 )
+					p._setButton( e.button, true );
+			case GControllerUp:
+				if( p != null && e.button > -1 )
+					p._setButton( e.button, false );
+			case GControllerAxis:
+				if( p != null && e.button > -1 && e.button < 6 )
+					p._setAxis( e.button, e.value );
+			default:
+		}
+		
+	}
+	#end
 
 }

+ 2 - 0
hxd/System.hx

@@ -542,6 +542,8 @@ class System {
 		case MouseWheel:
 			eh = new Event(EWheel, mouseX, mouseY);
 			eh.wheelDelta = -e.wheelDelta;
+		case GControllerAdded, GControllerRemoved, GControllerUp, GControllerDown, GControllerAxis:
+			@:privateAccess hxd.Pad.onEvent( e );
 		default:
 		}
 		if( eh != null ) Stage.getInstance().event(eh);

+ 138 - 0
samples/Pad.hx

@@ -0,0 +1,138 @@
+class Pad extends hxd.App {
+	
+	var flow : h2d.Flow;
+	var l : Array<PadUI>;
+
+	override function init() {
+		l = [];
+		flow = new h2d.Flow(s2d);
+		flow.padding = 20;
+		flow.isVertical = true;
+		
+		hxd.Pad.wait(onPad);
+	}
+	
+	function onPad( p : hxd.Pad ){
+		var ui = new PadUI(p, flow);
+		l.push( ui );
+		p.onDisconnect = function(){
+			ui.remove();
+			l.remove( ui );
+		}
+		flow.reflow();
+	}
+
+	// if we the window has been resized
+	override function onResize() {
+
+	}
+
+	override function update(dt:Float) {
+		for( ui in l )
+			ui.update();
+	}
+
+	static function main() {
+		hxd.Res.initEmbed();
+		new Pad();
+	}
+
+}
+
+class PadUI extends h2d.Sprite {
+	
+	var tfName : h2d.Text;
+	
+	var bg : h2d.Graphics;
+	var main : h2d.Graphics;
+	var left : h2d.Graphics;
+	var right : h2d.Graphics;
+	
+	var lt : h2d.Graphics;
+	var rt : h2d.Graphics;
+	
+	var buttons : Map<String,h2d.Text>;
+	
+	var pad : hxd.Pad;
+	
+	public function new( p : hxd.Pad, parent : h2d.Sprite ){
+		super( parent );
+		
+		pad = p;
+		
+		bg = new h2d.Graphics(this);
+		bg.lineStyle(1,0xFFFFFF,0.5);
+		bg.drawRect(0,0,600,160);
+		bg.lineStyle(1,0xFFFFFF,1);
+		bg.drawRect(20,20,100,100);
+		bg.drawRect(140,20,100,100);
+		bg.drawRect(260,20,20,100);
+		bg.drawRect(300,20,20,100);
+		bg.endFill();
+		
+		var fnt = hxd.Res.customFont.toFont();
+		
+		tfName = new h2d.Text(fnt,this);
+		tfName.text = pad.name;
+		
+		main = new h2d.Graphics(this);
+		main.lineStyle(1,0x00FF00,1);
+		main.drawCircle(0,0,4);
+		main.endFill();
+		
+		left = new h2d.Graphics(this);
+		right = new h2d.Graphics(this);
+		
+		for( g in [left,right] ){
+			g.beginFill(0xFF0000);
+			g.drawCircle(0,0,2);
+			g.endFill();
+		}
+		
+		lt = new h2d.Graphics(this);
+		lt.x = 260;
+		rt = new h2d.Graphics(this);
+		rt.x = 300;
+		for( g in [lt,rt] ){
+			g.beginFill(0x00FF00);
+			g.drawRect(0,0,20,100);
+			g.endFill();
+			g.scaleY = 0;
+			g.y = 120;
+		}
+		
+		buttons = new Map();
+		
+		var x = 0;
+		for( n in ["A","B","X","Y","LB","RB","back","start","dpadUp","dpadDown","dpadLeft","dpadRight"] ){
+			var t = new h2d.Text(fnt,this);
+			x += 20;
+			t.x = x;
+			t.y = 140;
+			t.text = n;
+			t.alpha = 0.1;
+			buttons.set(n,t);
+			x += t.textWidth;
+		}
+	}
+	
+	public function update(){
+		var conf = #if flash hxd.Pad.CONFIG_XBOX #else hxd.Pad.CONFIG_SDL #end;
+		main.x = 20 + 50 + pad.xAxis * 50;
+		main.y = 20 + 50 + pad.yAxis * 50;
+		
+		left.x = 20 + 50 + pad.values[ conf.analogX ] * 50;
+		left.y = 20 + 50 - pad.values[ conf.analogY ] * 50;
+		left.setScale( 1 + 3 * pad.values[conf.analogClick] );
+		
+		right.x = 140 + 50 + pad.values[ conf.ranalogX ] * 50;
+		right.y = 20 + 50 - pad.values[ conf.ranalogY ] * 50;
+		right.setScale( 1 + 3 * pad.values[conf.ranalogClick] );
+		
+		lt.scaleY = -pad.values[ conf.LT ];
+		rt.scaleY = -pad.values[ conf.RT ];
+		
+		for( k in buttons.keys() )
+			buttons[k].alpha = 0.3 + (pad.buttons[ Reflect.field(conf,k) ] ? 0.7 : 0);
+	}
+}