[SOLVED] Questions about gamepad, one at a time...



  • Hi, I've updated a game I made one year ago for the Ouya. Since then, I've updated Flixel and other libs to their lastest versions. Now gamepads don't work anymore...
    So I have several problems for you guys. Let's start with the first one:

    Dpad is working weird on OUYA

    Here's the function I wrote for retreiving the directional pad or analog stick for any gamepads:

    public static inline function getAxis():Int
    {
    	var gamepads:Array < FlxGamepad > = FlxG.gamepads.getActiveGamepads();
    	var d:Int = 0;
    	for (gamepad in gamepads)
    	{
    		var xAxis:Float = gamepad.analog.value.LEFT_STICK_X;
    		var yAxis:Float = gamepad.analog.value.LEFT_STICK_Y;
    		if (gamepad.justPressed.DPAD_LEFT)	xAxis = -1;
    		if (gamepad.justPressed.DPAD_RIGHT)	xAxis = 1;
    		if (gamepad.justPressed.DPAD_UP)	yAxis = -1;
    		if (gamepad.justPressed.DPAD_DOWN)	yAxis = 1;
    		if	(xAxis < 0	&& yAxis > 0)	d = 1;	// DOWN-LEFT
    		else if	(xAxis == 0	&& yAxis > 0)	d = 2;	// DOWN
    		else if	(xAxis > 0	&& yAxis > 0)	d = 3;	// DOWN-RIGHT
    		else if	(xAxis < 0	&& yAxis == 0)	d = 4;	// LEFT
    		else if	(xAxis > 0	&& yAxis == 0)	d = 6;	// RIGHT
    		else if	(xAxis < 0	&& yAxis < 0)	d = 7;	// UP-LEFT
    		else if	(xAxis == 0	&& yAxis < 0)	d = 8;	// UP
    		else if	(xAxis > 0	&& yAxis < 0)	d = 9;	// UP-RIGHT
    	}
    	return d;
    }
    

    At first, I was using

    if (FlxG.gamepads.anyJustPressed(FlxGamepadInputID.DPAD_LEFT))	xAxis = -1;
    

    for each axes, but I didn't find how tu use something similar for the analog stick.
    Nevermind, it works great on Flash build. But when I try the apk on the OUYA I obtain three different behaviors with the Dpad:

    1. After the game has launched, the action seems to be called twice. For example, in the entry menu, when I press Dpad up, the menu goes up two times instead of once. It's the same for all directions.
    2. After I move the analog stick, the Dpad act differently: the action is called for press and for release. Don't know why...
    3. After I switch the FlxState, the Dpad is working fine.

    Do you know what can I do to repair that?
    ( Then we'll talk about the buttons ... )



  • Nailed it!

    It didn't came from my code but from Android behavior regarding keyboard (at least on OUYA and on my GSM with the NES30 gamepad. I've tried on NVIDIA Shield TV but Dpad isn't recognized).
    Is it normal that if (FlxG.keys.justPressed.UP) returns true when you press OR release Dpad up on Android? I believe it's something that was not there last year... If so I'll update my code so it is not called twice for the keyboard and the gamepad :)



  • There comes my second problem with the gamepad:

    Why the buttons positions are inconsistent between systems?

    Same as before, I've wrote a simple button handler for all active gamepads:

    public static inline function getButton(button:String):Bool
    {
    	var gamepads:Array< FlxGamepad > = FlxG.gamepads.getActiveGamepads();
    	var press:Bool = false;
    	for (gamepad in gamepads)
    	{
    		switch (button)
    		{
    			case "OK":	press = gamepad.justPressed.A;
    			case "BACK":	press = gamepad.justPressed.B;
    			case "QUIT":	press = gamepad.justPressed.Y;
    		}
    	}
    	return press;
    }
    

    Assuming that the Gamepad doc is right , checking gamepad.justPressed.Y; should return the state of the Y button on the gamepad.
    So I've tried with an XBOX controller and a PS3 one, everything is fine for the Flash export.
    But when I play my game on OUYA, the Y button is swapped with the X button (I'm talking about XBOX layout. To make it simple, I'll always put the XBOX layout in bold otherwise explanations are going to be complicated). So these two buttons are swapped on the OUYA gamepade (U/Y), but also on the PS3 gamepad (square/triangle).

    I've checked the mapping on OUYA, and it should work:

    case OUYAID.O: A;
    case OUYAID.A: B;
    case OUYAID.U: X;
    case OUYAID.Y: Y;
    

    Am I missing something?

    Also you may wonder why the heck I'm still struggling with my "almost dead" OUYA? It's because the NVIDIA shield TV gamepad is not supported yet (and that's gonna be my next question).



  • Three years later, I'm still struggling with that. So I was searching on the internet, only to find this topic where I'm asking for help...
    I'm currently resurrecting old projects, so it's still the same code as above.
    And using FlxGamepad this way, no gamepad buttons are consistent from one device to another. So how should I program this so when I press "BOTTOM face button" on one gamepad, it is not moved to "DPAD_LEFT" on another device's gamepad?



  • So I compiled the GamepadTest to see what's going on.

    On Windows (Flash), the 360 controller is working perfectly.
    On Nvidia Shield TV, the Nvidia gamepad is working perfectly.
    On OUYA with the OUYA gamepad, it's a mess...
    Here's the mapping I get from OUYA Game Controller to Haxeflixel GamepadText:

    O (BOTTOM face button) -> LB
    U (LEFT face button) -> LEFT_TRIGGER
    Y (TOP face button) -> RIGHT_TRIGGER
    A (RIGHT face button) -> RB
    
    LB -> DPAD_DOWN
    RB -> DPAD_UP
    
    LEFT_STICK_CLICK -> DPAD_LEFT
    RIGHT_STICK_CLICK -> RIGHT_ANALOG_STICK down + DPAD_RIGHT
    
    HOME -> ?
    
    LEFT_TRIGGER -> Y
    RIGHT_TRIGGER -> ?
    
    DPAD_LEFT -> ?
    DPAD_RIGHT -> ?
    DPAD_DOWN -> ?
    DPAD_UP -> ?
    
    LEFT_ANALOG_STICK left -> LEFT_ANALOG_STICK left + A
    LEFT_ANALOG_STICK right -> LEFT_ANALOG_STICK right + A
    LEFT_ANALOG_STICK up -> LEFT_ANALOG_STICK up + B
    LEFT_ANALOG_STICK down -> LEFT_ANALOG_STICK down + B
    
    RIGHT_ANALOG_STICK left -> HOME
    RIGHT_ANALOG_STICK right -> HOME
    RIGHT_ANALOG_STICK up -> X
    RIGHT_ANALOG_STICK down -> X
    
    LEFT_TRIGGER_ANALOG -> ?
    RIGHT_TRIGGER_ANALOG -> ?
    

    As you can see, everything is scrambled, and I have no clue what's going on. Should I remap the buttons in flixel/input/gamepad/id/OUYA/OUYAID.hx?
    Or maybe I need to install that lib (https://lib.haxe.org/p/openfl-ouya) ?

    I really don't understand what's going on...



  • All right! After hours of testing, switching numbers, compiling Android builds and some good guessing, I managed to repair the flixel/input/gamepad/id/OUYAID.hx
    And it turns out that it was impossible for that file to work from the very start (May 21, 2015).

    Here's the current code:

    class OUYAID
    {
    	public static inline var O:Int = 0;
    	public static inline var U:Int = 3;
    	public static inline var Y:Int = 4;
    	public static inline var A:Int = 1;
    	public static inline var LB:Int = 6;
    	public static inline var RB:Int = 7;
    	public static inline var LEFT_STICK_CLICK:Int = 10;
    	public static inline var RIGHT_STICK_CLICK:Int = 11;
    	public static inline var HOME:Int = 2;
    	public static inline var LEFT_TRIGGER:Int = 8;
    	public static inline var RIGHT_TRIGGER:Int = 9;
    
    	// "fake" IDs, we manually watch for hat axis changes and then send events using these otherwise unused joystick button codes
    	public static inline var DPAD_LEFT:Int = 13;
    	public static inline var DPAD_RIGHT:Int = 14;
    	public static inline var DPAD_DOWN:Int = 15;
    	public static inline var DPAD_UP:Int = 16;
    
    	// If TRIGGER axis returns value > 0 then LT is being pressed, and if it's < 0 then RT is being pressed
    	public static var LEFT_ANALOG_STICK(default, null) = new FlxGamepadAnalogStick(0, 1, {
    		up: 23,
    		down: 24,
    		left: 25,
    		right: 26
    	});
    	public static var RIGHT_ANALOG_STICK(default, null) = new FlxGamepadAnalogStick(11, 14, {
    		up: 27,
    		down: 28,
    		left: 29,
    		right: 30
    	});
    
    	public static inline var LEFT_TRIGGER_ANALOG:Int = 17;
    	public static inline var RIGHT_TRIGGER_ANALOG:Int = 18;
    }
    

    In fact, those numbers are coming from openfl-ouya/tv/ouya/console/api/OuyaController.hx

      static inline public var BUTTON_O:Int = 0; // 96;
      static inline public var BUTTON_U:Int = 3; // 99;
      static inline public var BUTTON_Y:Int = 4; // 100;
      static inline public var BUTTON_A:Int = 1; // 97;
      static inline public var BUTTON_L1:Int = 6; // 102;
      static inline public var BUTTON_L2:Int = 8; // 104;
      static inline public var BUTTON_R1:Int = 7; // 103;
      static inline public var BUTTON_R2:Int = 9; // 105;
      static inline public var BUTTON_MENU:Int = 0x01000012; // 82;
      static inline public var AXIS_LS_X:Int = 0;
      static inline public var AXIS_LS_Y:Int = 1;
      static inline public var AXIS_RS_X:Int = 11;
      static inline public var AXIS_RS_Y:Int = 14;
      static inline public var AXIS_L2:Int = 17;
      static inline public var AXIS_R2:Int = 18;
      static inline public var BUTTON_DPAD_UP:Int = 19;
      static inline public var BUTTON_DPAD_RIGHT:Int = 22;
      static inline public var BUTTON_DPAD_DOWN:Int = 20;
      static inline public var BUTTON_DPAD_LEFT:Int = 21;
      static inline public var BUTTON_R3:Int = 11; // 107;
      static inline public var BUTTON_L3:Int = 10; // 106;
    

    And it is entirely possible that it was never tested back in 2015. After a brief search through the forum, maybe I was the only one making games for the OUYA using HaxeFlixel? Anyway, here are the correct numbers:

    class OUYAID
    {
    	public static inline var O:Int = 6;
    	public static inline var U:Int = 8;
    	public static inline var Y:Int = 9;
    	public static inline var A:Int = 7;
    	public static inline var LB:Int = 15;
    	public static inline var RB:Int = 16;
    	public static inline var LEFT_STICK_CLICK:Int = 13;
    	public static inline var RIGHT_STICK_CLICK:Int = 14;
    	public static inline var HOME:Int = 0x01000012;	// Not sure if press HOME is taken in account on OUYA
    	public static inline var LEFT_TRIGGER:Int = 4;
    	public static inline var RIGHT_TRIGGER:Int = 5;
    
    	// "fake" IDs, we manually watch for hat axis changes and then send events using these otherwise unused joystick button codes
    	public static inline var DPAD_LEFT:Int = 19;
    	public static inline var DPAD_RIGHT:Int = 20;
    	public static inline var DPAD_DOWN:Int = 18;
    	public static inline var DPAD_UP:Int = 17;
    
    	// If TRIGGER axis returns value > 0 then LT is being pressed, and if it's < 0 then RT is being pressed
    	public static var LEFT_ANALOG_STICK(default, null) = new FlxGamepadAnalogStick(0, 1, {
    		up: 23,
    		down: 24,
    		left: 25,
    		right: 26
    	});
    	public static var RIGHT_ANALOG_STICK(default, null) = new FlxGamepadAnalogStick(2, 3, {
    		up: 27,
    		down: 28,
    		left: 29,
    		right: 30
    	});
    }
    

    By the way, I removed those two lines because those vars are never used elsewhere:
    public static inline var LEFT_TRIGGER_ANALOG:Int = 17;
    public static inline var RIGHT_TRIGGER_ANALOG:Int = 18;

    One last note, I didn't manage to find the correct number for HOME. I believe this button does not work like the others on the OUYA and it needs the official OUYA lib or something.

    After four years, I'll finally be able to update my old game on this dead system. Yeah!


Log in to reply
 

Looks like your connection to HaxeFlixel was lost, please wait while we try to reconnect.