Mapping Analog Control Sticks on Xbox 360 Gamepad

Justin

  • *
  • Posts: 4716
The part you're concerned about in onJoyAxisMove is used for determining when a press/release happens for axis controls. So it can be used with "when control pressed/released" blocks. That should remain as state, not pressure.

The update of the pressure happens in the last line of that function.
For Live Support: Join our discord server and ping me @justin.
I'm most often available between 10am and 10pm Japan time. (GMT+9)

ETHproductions

  • *
  • Posts: 430
Oops, thanks for the correction! I guess I'll take a look at "getButtonPressure" instead.
Fontstruct - Stencyl - Website (in progress)

Proud Member of the League of Idiotic Stencylers; doing things in Stencyl that probably shouldn't be done.

ETHproductions

  • *
  • Posts: 430
I fixed it! Yessssssssss! 8)

Now I'll explain what I changed to get it to work. Let's start with the old function:
Code: [Select]
public static function getButtonPressure(control:String):Float
{
#if desktop

if(_controlButtonMap.exists(control))
{
var buttons = _controlButtonMap.get(control);

var highestPressure:Float = 0;

if(check(control))
return 1;

for(b in buttons)
{
if(!_joyControllerReady[b.a[0]])
continue;

switch(b.a[JoystickButton.TYPE])
{
case JoystickButton.AXIS:
if(_joyAxisState.get(b.a[0])[b.a[2]] == b.a[3])
highestPressure = Math.max(highestPressure, Math.abs(_joyAxisPressure.get(b.a[0])[b.a[2]]));
case JoystickButton.HAT:
if(_joyHatState.get(b.a[0])[b.a[2]] == b.a[3])
return 1;
case JoystickButton.BUTTON:
if(_joyButtonState.get(b.a[0])[b.a[2]])
return 1;
}
}

return highestPressure;
}
else
return check(control) ? 1 : 0;

#else

return check(control) ? 1 : 0;

#end
}

While experimenting, there were two problems that I found.

Problem 1:
Code: [Select]
if(check(control))
return 1;

Before checking the actual pressure of the axis, it would check to see if the corresponding control was down. Of course, this means it would always return 1, as long as the pressure is more than the analog sensitivity. This can be fixed by simply removing this bit of code.

Problem 2:
Code: [Select]
case JoystickButton.AXIS:
if(_joyAxisState.get(b.a[0])[b.a[2]] == b.a[3])
highestPressure = Math.max(highestPressure, Math.abs(_joyAxisPressure.get(b.a[0])[b.a[2]]));

b.a[3] is always equal to 1 or -1, so this code (namely the second line) only detects that the pressure is valid if it is equal to 1 or -1. This can be fixed by first checking the sign, then correspondingly checking the value:
Code: [Select]
case JoystickButton.AXIS:
if(b.a[3] == 1 && _joyAxisState.get(b.a[0])[b.a[2]] > joySensitivity)
highestPressure = Math.max(highestPressure, Math.abs(_joyAxisPressure.get(b.a[0])[b.a[2]]));
else if(b.a[3] == -1 && _joyAxisState.get(b.a[0])[b.a[2]] < -joySensitivity)
highestPressure = Math.max(highestPressure, Math.abs(_joyAxisPressure.get(b.a[0])[b.a[2]]));

All in all, these fixes seem to work perfectly! I've tested this successfully with joysticks, triggers, hat buttons and regular buttons. The code may still need some improvements, but I currently see no need.

Here's the final code:
Code: [Select]
public static function getButtonPressure(control:String):Float
{
#if desktop

if(_controlButtonMap.exists(control))
{
var buttons = _controlButtonMap.get(control);

var highestPressure:Float = 0;

for(b in buttons)
{
if(!_joyControllerReady[b.a[0]])
continue;

switch(b.a[JoystickButton.TYPE])
{
case JoystickButton.AXIS:
if(b.a[3] == 1 && _joyAxisState.get(b.a[0])[b.a[2]] > joySensitivity)
highestPressure = Math.max(highestPressure, Math.abs(_joyAxisPressure.get(b.a[0])[b.a[2]]));
else if(b.a[3] == -1 && _joyAxisState.get(b.a[0])[b.a[2]] < -joySensitivity)
highestPressure = Math.max(highestPressure, Math.abs(_joyAxisPressure.get(b.a[0])[b.a[2]]));
case JoystickButton.HAT:
if(_joyHatState.get(b.a[0])[b.a[2]] == b.a[3])
return 1;
case JoystickButton.BUTTON:
if(_joyButtonState.get(b.a[0])[b.a[2]])
return 1;
}
}

return highestPressure;
}
else
return check(control) ? 1 : 0;

#else

return check(control) ? 1 : 0;

#end
}
Fontstruct - Stencyl - Website (in progress)

Proud Member of the League of Idiotic Stencylers; doing things in Stencyl that probably shouldn't be done.

ianfitz

  • Posts: 48
Waaaaaat you are awesome.

Justin

  • *
  • Posts: 4716
For problem 1, it's probably because check(control) used to only work properly for physical keyboard input. If that's removed entirely, the downside is that "get button pressure" won't report keyboard input on the desktop.

Unfortunately, I don't think there's anything we can do about this now (without some rewriting of the Input class, anyway), except to only check keyboard input if there's no gamepad input.

---

Are you sure the second modification was necessary? _joyAxisState should only be able to have the values 0, 1, and -1 anyway. This isn't the pressure, but simple trinary flags.

---

Given that, here's my modification to your fix. Would it be possible for you to test it?

Code: [Select]
public static function getButtonPressure(control:String):Float
{
#if desktop

if(_controlButtonMap.exists(control))
{
var buttons = _controlButtonMap.get(control);

var highestPressure:Float = 0;

for(b in buttons)
{
if(!_joyControllerReady[b.a[0]])
continue;

switch(b.a[JoystickButton.TYPE])
{
case JoystickButton.AXIS:
if(_joyAxisState.get(b.a[0])[b.a[2]] == b.a[3])
highestPressure = Math.max(highestPressure, Math.abs(_joyAxisPressure.get(b.a[0])[b.a[2]]));
case JoystickButton.HAT:
if(_joyHatState.get(b.a[0])[b.a[2]] == b.a[3])
return 1;
case JoystickButton.BUTTON:
if(_joyButtonState.get(b.a[0])[b.a[2]])
return 1;
}
}

if(highestPressure == 0 && check(control))
return 1;

return highestPressure;
}
else
return check(control) ? 1 : 0;

#else

return check(control) ? 1 : 0;

#end
}
For Live Support: Join our discord server and ping me @justin.
I'm most often available between 10am and 10pm Japan time. (GMT+9)

ETHproductions

  • *
  • Posts: 430
Yep, I can confirm your proposed code works properly, even with keyboard input now. Thanks for the help! Will this fix be included in the next release?
Fontstruct - Stencyl - Website (in progress)

Proud Member of the League of Idiotic Stencylers; doing things in Stencyl that probably shouldn't be done.

Justin

  • *
  • Posts: 4716
Oh yeah, sorry for the delay on this. Committing the fix now. Thanks!
For Live Support: Join our discord server and ping me @justin.
I'm most often available between 10am and 10pm Japan time. (GMT+9)