Skip to content

Commit

Permalink
Various input improvements and unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MattTuttle committed Nov 17, 2015
1 parent de6d301 commit 6043224
Show file tree
Hide file tree
Showing 12 changed files with 507 additions and 201 deletions.
120 changes: 72 additions & 48 deletions haxepunk/inputs/Gamepad.hx
Original file line number Diff line number Diff line change
@@ -1,74 +1,119 @@
package haxepunk.inputs;

import haxe.ds.IntMap;
import haxepunk.math.Vector3;
import haxepunk.math.*;
import haxepunk.inputs.InputState;

@:allow(haxepunk.inputs)
class Gamepad
{
/** Number of connected gamepads. */
public static var numberConnected(default, null):Int;

/** Holds the last button detected. */
public static var last(default, null):GamepadButton = NONE;
/**
* Holds the last button detected.
*/
public var last(default, null):Int = -1;

/**
* Globally unique identifier for device.
*/
public var guid(default, null):String;

/**
* Human-friendly name for controller.
*/
public var name(default, null):String;

/**
* Connected id of the controller.
*/
public var id(default, null):Int;

/** Determines the joystick's deadZone. Anything under this value will be considered 0 to prevent jitter. */
public var deadZone:Float = 0.1;

/** Each axis contained in an array. */
public var axis(default, null):IntMap<Float>;
/**
* Determines the joystick's deadZone.
* Anything under this value will be considered 0 to prevent jitter.
*/
public var deadZone:Float = 0.15;

/** If the gamepad is connected. */
public var connected(default, null):Bool = true;
/**
* If the gamepad is connected.
*/
public var isConnected(default, null):Bool = true;

public function new(name:String, id:Int, guid:String)
{
this.guid = guid;
this.name = name;
this.id = id;
trace(guid, name, id);
axis = new IntMap<Float>();
numberConnected += 1;
_axis = new IntMap<Float>();
}

/**
* Returns the name of the gamepad button.
*
* Examples:
* Gamepad.nameOf(GamepadButton.LEFT);
* Gamepad.nameOf(GamepadButton.last);
*
* @param button The gamepad button to name
* @return The name
*/
public static inline function nameOf(button:GamepadButton):String
{
return button.toString();
}

/**
* Get the value of an axis.
* @param The axis to poll.
* @return The value of the axis or 0 if not set.
*/
public function getAxis(axis:Int):Float
{
return _axis.exists(axis) ? _axis.get(axis) : 0;
}

/**
* Trigger when a button is released on the gamepad.
* @param button The button that was released.
*/
private function onButtonUp(button:Int):Void
{
getInputState(button).released += 1;
last = cast button;
last = button;
}

/**
* Trigger when a button is pressed on the gamepad.
* @param button The button that was pressed.
*/
private function onButtonDown(button:Int):Void
{
getInputState(button).pressed += 1;
last = cast button;
last = button;
}

/**
* Trigger when the gamepad is disconnected.
*/
private function onDisconnect():Void
{
numberConnected -= 1;
connected = false;
isConnected = false;
}

/**
* Trigger when an axis on the gamepad is moved.
* @param axis The axis that was moved.
* @param value The value of the axis -1 to 1
*/
private function onAxisMove(axis:Int, value:Float):Void
{
if (Math.abs(value) > deadZone)
{
this.axis.set(axis, value);
}
var abs = Math.abs(value);

// clamp (deadZone < axis < 1)
if (abs < deadZone) value = 0;
else if (abs > 1) value = Math.sign(value);

_axis.set(axis, value);
}

/**
Expand All @@ -78,7 +123,7 @@ class Gamepad
* @param v The value to get
* @return The value of [v] for [button]
*/
private inline function value(button:GamepadButton, v:InputValue):Int
private inline function value(button:Int, v:InputValue):Int
{
if (button < 0) // Any
{
Expand All @@ -91,7 +136,7 @@ class Gamepad
}
else
{
return getInputState(cast button).value(v);
return getInputState(button).value(v);
}
}

Expand Down Expand Up @@ -128,29 +173,8 @@ class Gamepad
}
}

/**
* Returns the name of the gamepad button.
*
* Examples:
* Gamepad.nameOf(GamepadButton.LEFT);
* Gamepad.nameOf(GamepadButton.last);
*
* @param button The gamepad button to name
* @return The name
*/
public static function nameOf(button:GamepadButton):String
{
if (button < 0) // ANY || NONE
{
return "";
}
else
{
var v:Int = cast button;
return "BUTTON " + v;
}
}

/** Each axis contained in an array. */
private var _axis(default, null):IntMap<Float>;
private var _states:IntMap<InputState> = new IntMap<InputState>();

}
58 changes: 38 additions & 20 deletions haxepunk/inputs/GamepadButton.hx
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
package haxepunk.inputs;

/**
* The gamepad buttons.
* To be used with Input.define, Input.check, Input.pressed, Input.released and Gamepad.nameOf.
*
* Warning: ANY also encompass buttons that aren't listed here, for gamepad with more than 10 buttons.
*/
@:enum abstract GamepadButton(Int) to Int
@:enum abstract GamepadButton(Int) to Int from Int
{
var NONE = -2;
var ANY = -1;

var BUTTON0 = 0;
var BUTTON1 = 1;
var BUTTON2 = 2;
var BUTTON3 = 3;
var BUTTON4 = 4;
var BUTTON5 = 5;
var BUTTON6 = 6;
var BUTTON7 = 7;
var BUTTON8 = 8;
var BUTTON9 = 9;
// Generic button names
var A = 0;
var B = 1;
var X = 2;
var Y = 3;
var BACK = 4;
var HOME = 5;
var START = 6;
var STICK_LEFT = 7;
var STICK_RIGHT = 8;
var SHOULDER_LEFT = 9;
var SHOULDER_RIGHT = 10;
var DPAD_UP = 11;
var DPAD_DOWN = 12;
var DPAD_LEFT = 13;
var DPAD_RIGHT = 14;

@:op(A<B) private inline function less (rhs:Int):Bool { return this < rhs; }
@:op(A>B) private inline function more (rhs:Int):Bool { return this > rhs; }
public inline function toString():String {
return switch (this) {
case ANY: "";
case A: "A";
case B: "B";
case X: "X";
case Y: "Y";
case BACK: "BACK";
case HOME: "HOME";
case START: "START";
case STICK_LEFT: "STICK_LEFT";
case STICK_RIGHT: "STICK_RIGHT";
case SHOULDER_LEFT: "SHOULDER_LEFT";
case SHOULDER_RIGHT: "SHOULDER_RIGHT";
case DPAD_UP: "DPAD_UP";
case DPAD_DOWN: "DPAD_DOWN";
case DPAD_LEFT: "DPAD_LEFT";
case DPAD_RIGHT: "DPAD_RIGHT";
default: "GAMEPAD (" + this + ")";
}
}
}
23 changes: 11 additions & 12 deletions haxepunk/inputs/Input.hx
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package haxepunk.inputs;

import haxepunk.inputs.InputState;
import haxepunk.inputs.Keyboard;
import haxepunk.inputs.Mouse;
import lime.ui.Window;
import haxepunk.inputs.Gamepad;

/**
* Either enum used by InputType.
*/
private enum EitherInput
{
String(s:String);
MouseButton(mb:MouseButton);
GamepadButton(gb:GamepadButton);
MouseButton(button:MouseButton);
GamepadButton(button:Int);
Key(k:Key);
}

Expand All @@ -27,9 +25,9 @@ private abstract InputType(EitherInput)
@:to inline function get_type() { return this; }

@:from static function fromString(s:String) { return new InputType(String(s)); }
@:from static function fromMouseButton(mb:MouseButton) { return new InputType(MouseButton(mb)); }
@:from static function fromGamepadButton(gb:GamepadButton) { return new InputType(GamepadButton(gb)); }
@:from static function fromKey(k:Key) { return new InputType(Key(k)); }
@:from static function fromMouseButton(button:MouseButton) { return new InputType(MouseButton(button)); }
@:from static function fromKey(key:Key) { return new InputType(Key(key)); }
@:from static function fromGamepadButton(button:GamepadButton) { return new InputType(GamepadButton(button)); }
}

/**
Expand Down Expand Up @@ -131,7 +129,7 @@ class Input

#if lime
@:allow(haxepunk.Window)
private function register(?window:Window)
private function register(?window:lime.ui.Window)
{
// Register keyboard events
window.onKeyDown.add(keyboard.onKeyDown);
Expand Down Expand Up @@ -215,11 +213,11 @@ class Input
case MouseButton(mb):
mouse.value(mb, v);

case GamepadButton(gb):
case GamepadButton(button):
var val:Int = 0;
for (gamepad in gamepads)
{
val += gamepad.value(gb, v);
val += gamepad.value(button, v);
}
val;

Expand All @@ -236,10 +234,11 @@ class Input
{
keyboard.update();
mouse.update();
// TODO: remove disconnected gamepads?
for (i in 0...gamepads.length)
{
var gamepad = gamepads[i];
if (gamepad.connected)
if (gamepad.isConnected)
{
gamepad.update();
}
Expand Down
2 changes: 1 addition & 1 deletion haxepunk/inputs/InputState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ package haxepunk.inputs;
/**
* Store the values on, pressed and released for a mouse button.
*/
@:allow(haxepunk.inputs)
class InputState
{
public var on:Int = 0;
public var pressed:Int = 0;
public var released:Int = 0;

@:allow(haxepunk.inputs)
private function new() { }

public function value(v:InputValue):Int
Expand Down
Loading

0 comments on commit 6043224

Please sign in to comment.