Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FlxGamepadManager: Add FlxG.gamepads.acceptMode #3280

Merged
merged 21 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion flixel/input/gamepad/FlxGamepad.hx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package flixel.input.gamepad;

import flixel.input.FlxInput.FlxInputState;
import flixel.input.gamepad.FlxGamepadMappedInput;
import flixel.input.gamepad.lists.FlxGamepadAnalogList;
import flixel.input.gamepad.lists.FlxGamepadButtonList;
import flixel.input.gamepad.lists.FlxGamepadMotionValueList;
Expand Down Expand Up @@ -879,13 +880,25 @@ class FlxGamepad implements IFlxDestroyable
return _deadZone = deadZone;
}

/**
/**
* A string representing the label of the target input. For instance, on a PS4 gamepad
* `A` is "x", while Xbox is "a" and the Switch pro controller is "B"
* @since 4.8.0
*/
public inline function getInputLabel(id:FlxGamepadInputID)
{
return mapping.getInputLabel(id);
}

/**
* The value of the target gamepad input. For instance, on a PS4 gamepad `A` is `PS4(PS4ID.X)`,
* while Xbox is `X_INPUT(XInputID.A)` and the Switch pro controller is `SWITCH_PRO(SwitchProID.B)`
* @since 5.9.0
*/
public function getMappedInput(id:FlxGamepadInputID):FlxGamepadMappedInput
{
return mapping.getMappedInput(id);
}

public function toString():String
{
Expand Down
53 changes: 33 additions & 20 deletions flixel/input/gamepad/FlxGamepadAnalogStick.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,32 @@ package flixel.input.gamepad;

import flixel.util.FlxStringUtil;

class FlxGamepadAnalogStick
typedef FlxGamepadAnalogStick = FlxTypedGamepadAnalogStick<Int>;

class FlxTypedGamepadAnalogStick<TInputID:Int>
{
public var x(default, null):Int;
public var y(default, null):Int;

/**
* a raw button input ID, for sending a digital event for "up" alongside the analog event
*/
public var rawUp(default, null):Int = -1;
public var rawUp(default, null):TInputID = cast -1;

/**
* a raw button input ID, for sending a digital event for "down" alongside the analog event
*/
public var rawDown(default, null):Int = -1;
public var rawDown(default, null):TInputID = cast -1;

/**
* a raw button input ID, for sending a digital event for "left" alongside the analog event
*/
public var rawLeft(default, null):Int = -1;
public var rawLeft(default, null):TInputID = cast -1;

/**
* a raw button input ID, for sending a digital event for "right" alongside the analog event
*/
public var rawRight(default, null):Int = -1;
public var rawRight(default, null):TInputID = cast -1;

/**
* the absolute value the dpad must be greater than before digital inputs are sent
Expand All @@ -37,20 +39,31 @@ class FlxGamepadAnalogStick
*/
public var mode(default, null):FlxAnalogToDigitalMode = BOTH;

public function new(x:Int, y:Int, ?settings:FlxGamepadAnalogStickSettings)
public function new(x:Int, y:Int, ?settings:FlxGamepadAnalogStickSettings<TInputID>)
{
this.x = x;
this.y = y;

if (settings == null)
return;

mode = (settings.mode != null) ? settings.mode : BOTH;
rawUp = (settings.up != null) ? settings.up : -1;
rawDown = (settings.down != null) ? settings.down : -1;
rawLeft = (settings.left != null) ? settings.left : -1;
rawRight = (settings.right != null) ? settings.right : -1;
digitalThreshold = (settings.threshold != null) ? settings.threshold : 0.5;
if (settings != null)
{
if (settings.mode != null)
mode = settings.mode;

if (settings.up != null)
rawUp = settings.up;

if (settings.down != null)
rawDown = settings.down;

if (settings.left != null)
rawLeft = settings.left;

if (settings.right != null)
rawRight = settings.right;

if (settings.threshold != null)
digitalThreshold = settings.threshold;
}
}

public function toString():String
Expand All @@ -68,12 +81,12 @@ class FlxGamepadAnalogStick
}
}

typedef FlxGamepadAnalogStickSettings =
typedef FlxGamepadAnalogStickSettings<TInputID:Int> =
{
?up:Int,
?down:Int,
?left:Int,
?right:Int,
?up:TInputID,
?down:TInputID,
?left:TInputID,
?right:TInputID,
?threshold:Float,
?mode:FlxAnalogToDigitalMode
}
Expand Down
32 changes: 31 additions & 1 deletion flixel/input/gamepad/FlxGamepadManager.hx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@ class FlxGamepadManager implements IFlxInputManager
* @since 4.6.0
*/
public var deviceDisconnected(default, null):FlxTypedSignal<FlxGamepad->Void>;


/**
* Whether the bottom or right face button is ACCEPT
* @since 5.9.0
*/
public var acceptMode:FlxGamepadAcceptMode = BOTTOM;

/**
* Stores all gamepads - can have null entries, but index matches event.device
*/
Expand Down Expand Up @@ -595,3 +601,27 @@ class FlxGamepadManager implements IFlxInputManager
return count;
}
}

/**
* @since 5.9.0
*/
enum FlxGamepadAcceptMode
{
/**
* The bottom face button is `ACCEPT` and the right face button is `CANCEL`.
* This is common on western-style consoles, like XBox or American PS4/5
*/
BOTTOM;

/**
* The right face button is `ACCEPT` and the bottom face button is `CANCEL`.
* This is common in Japanese PS4/5 consoles, and Nintendo consoles
*/
RIGHT;

/**
* Behaves like `BOTTOM` for nearly all gamepads, but `RIGHT` for specific mappings,
* namely Nintendo Switch gamepads
*/
USE_MAPPING;
}
57 changes: 57 additions & 0 deletions flixel/input/gamepad/FlxGamepadMappedInput.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package flixel.input.gamepad;

import flixel.input.gamepad.FlxGamepad;
import flixel.input.gamepad.id.LogitechID;
import flixel.input.gamepad.id.MayflashWiiRemoteID;
import flixel.input.gamepad.id.MFiID;
import flixel.input.gamepad.id.OUYAID;
import flixel.input.gamepad.id.PS4ID;
import flixel.input.gamepad.id.PSVitaID;
import flixel.input.gamepad.id.SwitchJoyconLeftID;
import flixel.input.gamepad.id.SwitchJoyconRightID;
import flixel.input.gamepad.id.SwitchProID;
import flixel.input.gamepad.id.WiiRemoteID;
import flixel.input.gamepad.id.XInputID;

/**
* A list of every possible gamepad input from every known device
* @since 5.9.0
*/
@:using(flixel.input.gamepad.FlxGamepadMappedInput.FlxGamepadMappedInputTools)
enum FlxGamepadMappedInput
{
LOGITECH(id:LogitechID);
MAYFLASH_WII(id:MayflashWiiRemoteID);
MFI(id:MFiID);
OUYA(id:OUYAID);
PS4(id:PS4ID);
PS_VITA(id:PSVitaID);
SWITCH_JOYCON_LEFT(id:SwitchJoyconLeftID);
SWITCH_JOYCON_RIGHT(id:SwitchJoyconRightID);
SWITCH_PRO(id:SwitchProID);
WII(id:WiiRemoteID);
X_INPUT(id:XInputID);
UNKNOWN(id:FlxGamepadInputID);
}

private class FlxGamepadMappedInputTools
{
public static inline function toModel(input:FlxGamepadMappedInput):FlxGamepadModel
{
return switch input
{
case FlxGamepadMappedInput.OUYA(_): FlxGamepadModel.OUYA;
case FlxGamepadMappedInput.PS4(_): FlxGamepadModel.PS4;
case FlxGamepadMappedInput.PS_VITA(_): FlxGamepadModel.PSVITA;
case FlxGamepadMappedInput.LOGITECH(_): FlxGamepadModel.LOGITECH;
case FlxGamepadMappedInput.X_INPUT(_): FlxGamepadModel.XINPUT;
case FlxGamepadMappedInput.WII(_): FlxGamepadModel.WII_REMOTE;
case FlxGamepadMappedInput.MAYFLASH_WII(_): FlxGamepadModel.MAYFLASH_WII_REMOTE;
case FlxGamepadMappedInput.SWITCH_PRO(_): FlxGamepadModel.SWITCH_PRO;
case FlxGamepadMappedInput.SWITCH_JOYCON_LEFT(_): FlxGamepadModel.SWITCH_JOYCON_LEFT;
case FlxGamepadMappedInput.SWITCH_JOYCON_RIGHT(_): FlxGamepadModel.SWITCH_JOYCON_RIGHT;
case FlxGamepadMappedInput.MFI(_): FlxGamepadModel.MFI;
case FlxGamepadMappedInput.UNKNOWN(_): FlxGamepadModel.UNKNOWN;
}
}
}
102 changes: 56 additions & 46 deletions flixel/input/gamepad/id/LogitechID.hx
Original file line number Diff line number Diff line change
Expand Up @@ -5,63 +5,73 @@ import flixel.input.gamepad.FlxGamepadAnalogStick;
/**
* IDs for Logitech controllers (key codes based on Cordless Rumblepad 2)
*/
class LogitechID
enum abstract LogitechID(Int) to Int
{
#if flash
public static inline var ONE:Int = 8;
public static inline var TWO:Int = 9;
public static inline var THREE:Int = 10;
public static inline var FOUR:Int = 11;
public static inline var FIVE:Int = 12;
public static inline var SIX:Int = 13;
public static inline var SEVEN:Int = 14;
public static inline var EIGHT:Int = 15;
public static inline var NINE:Int = 16;
public static inline var TEN:Int = 17;
public static inline var LEFT_STICK_CLICK:Int = 18;
public static inline var RIGHT_STICK_CLICK:Int = 19;
var ONE = 8;
var TWO = 9;
var THREE = 10;
var FOUR = 11;
var FIVE = 12;
var SIX = 13;
var SEVEN = 14;
var EIGHT = 15;
var NINE = 16;
var TEN = 17;
var LEFT_STICK_CLICK = 18;
var RIGHT_STICK_CLICK = 19;

public static inline var DPAD_UP:Int = 4;
public static inline var DPAD_DOWN:Int = 5;
public static inline var DPAD_LEFT:Int = 6;
public static inline var DPAD_RIGHT:Int = 7;
var DPAD_UP = 4;
var DPAD_DOWN = 5;
var DPAD_LEFT = 6;
var DPAD_RIGHT = 7;

// TODO: Someone needs to look this up and define it! (NOTE: not all logitech controllers have this)
public static inline var LOGITECH:Int = -1;
var LOGITECH = -1;
#else // native and html5
public static inline var ONE:Int = 0;
public static inline var TWO:Int = 1;
public static inline var THREE:Int = 2;
public static inline var FOUR:Int = 3;
public static inline var FIVE:Int = 4;
public static inline var SIX:Int = 5;
public static inline var SEVEN:Int = 6;
public static inline var EIGHT:Int = 7;
public static inline var NINE:Int = 8;
public static inline var TEN:Int = 9;
public static inline var LEFT_STICK_CLICK:Int = 10;
public static inline var RIGHT_STICK_CLICK:Int = 11;
var ONE = 0;
var TWO = 1;
var THREE = 2;
var FOUR = 3;
var FIVE = 4;
var SIX = 5;
var SEVEN = 6;
var EIGHT = 7;
var NINE = 8;
var TEN = 9;
var LEFT_STICK_CLICK = 10;
var RIGHT_STICK_CLICK = 11;

// "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_UP:Int = 16;
public static inline var DPAD_DOWN:Int = 17;
public static inline var DPAD_LEFT:Int = 18;
public static inline var DPAD_RIGHT:Int = 19;
var DPAD_UP = 16;
var DPAD_DOWN = 17;
var DPAD_LEFT = 18;
var DPAD_RIGHT = 19;

// TODO: Someone needs to look this up and define it! (NOTE: not all logitech controllers have this)
public static inline var LOGITECH:Int = -5;
var LOGITECH = -5;
#end

public static var LEFT_ANALOG_STICK(default, null) = new FlxGamepadAnalogStick(0, 1, {
up: 24,
down: 25,
left: 26,
right: 27

var LEFT_STICK_UP = 24;
var LEFT_STICK_DOWN = 25;
var LEFT_STICK_LEFT = 26;
var LEFT_STICK_RIGHT = 27;

var RIGHT_STICK_UP = 28;
var RIGHT_STICK_DOWN = 29;
var RIGHT_STICK_LEFT = 30;
var RIGHT_STICK_RIGHT = 31;

public static final LEFT_ANALOG_STICK = new FlxTypedGamepadAnalogStick<LogitechID>(0, 1, {
up: LEFT_STICK_UP,
down: LEFT_STICK_DOWN,
left: LEFT_STICK_LEFT,
right: LEFT_STICK_RIGHT
});
public static var RIGHT_ANALOG_STICK(default, null) = new FlxGamepadAnalogStick(2, 3, {
up: 28,
down: 29,
left: 30,
right: 31
public static final RIGHT_ANALOG_STICK = new FlxTypedGamepadAnalogStick<LogitechID>(2, 3, {
up: RIGHT_STICK_UP,
down: RIGHT_STICK_DOWN,
left: RIGHT_STICK_LEFT,
right: RIGHT_STICK_RIGHT
});
}
Loading
Loading