diff --git a/src/Input/Axis.cs b/src/Input/Axis.cs
index acef4a0..3fba7bc 100644
--- a/src/Input/Axis.cs
+++ b/src/Input/Axis.cs
@@ -1,15 +1,38 @@
+using System;
+using MoonWorks.Math;
+using SDL2;
+
namespace MoonWorks.Input
{
public class Axis
{
+ IntPtr GamepadHandle;
+ SDL.SDL_GameControllerAxis SDL_Axis;
+
+ public AxisCode Code { get; private set; }
+
///
/// An axis value between -1 and 1.
///
public float Value { get; private set; }
- internal void Update(float value)
+ public Axis(
+ IntPtr gamepadHandle,
+ AxisCode code,
+ SDL.SDL_GameControllerAxis sdlAxis
+ ) {
+ GamepadHandle = gamepadHandle;
+ SDL_Axis = sdlAxis;
+ Code = code;
+ }
+
+ internal void Update()
{
- Value = value;
+ Value = MathHelper.Normalize(
+ SDL.SDL_GameControllerGetAxis(GamepadHandle, SDL_Axis),
+ short.MinValue, short.MaxValue,
+ -1, 1
+ );
}
}
}
diff --git a/src/Input/AxisButtonCode.cs b/src/Input/AxisButtonCode.cs
new file mode 100644
index 0000000..cd8c92c
--- /dev/null
+++ b/src/Input/AxisButtonCode.cs
@@ -0,0 +1,14 @@
+namespace MoonWorks.Input
+{
+ public enum AxisButtonCode
+ {
+ LeftX_Left,
+ LeftX_Right,
+ LeftY_Up,
+ LeftY_Down,
+ RightX_Left,
+ RightX_Right,
+ RightY_Up,
+ RightY_Down
+ }
+}
diff --git a/src/Input/ButtonCode.cs b/src/Input/ButtonCode.cs
index c28b9af..d607081 100644
--- a/src/Input/ButtonCode.cs
+++ b/src/Input/ButtonCode.cs
@@ -1,7 +1,7 @@
namespace MoonWorks.Input
{
// Enum values are equivalent to the SDL GameControllerButton value.
- public enum ButtonCode
+ public enum GamepadButtonCode
{
A,
B,
diff --git a/src/Input/ButtonIdentifier.cs b/src/Input/ButtonIdentifier.cs
deleted file mode 100644
index 7a31922..0000000
--- a/src/Input/ButtonIdentifier.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-namespace MoonWorks.Input
-{
- // Blittable identifier that can be used for button state lookups.
- public struct ButtonIdentifier : System.IEquatable
- {
- public DeviceKind DeviceKind { get; }
- public int Index { get; } // 1-4 for gamepads, 0 otherwise
- public int Code { get; }
-
- public ButtonIdentifier(Gamepad gamepad, ButtonCode buttonCode)
- {
- DeviceKind = DeviceKind.Gamepad;
- Index = gamepad.Index;
- Code = (int) buttonCode;
- }
-
- public ButtonIdentifier(KeyCode keyCode)
- {
- DeviceKind = DeviceKind.Keyboard;
- Index = 0;
- Code = (int) keyCode;
- }
-
- public ButtonIdentifier(MouseButtonCode mouseCode)
- {
- DeviceKind = DeviceKind.Mouse;
- Index = 0;
- Code = (int) mouseCode;
- }
-
- public override int GetHashCode()
- {
- return System.HashCode.Combine(DeviceKind, Index, Code);
- }
-
- public override bool Equals(object obj)
- {
- return obj is ButtonIdentifier identifier && Equals(identifier);
- }
-
- public bool Equals(ButtonIdentifier identifier)
- {
- return
- DeviceKind == identifier.DeviceKind &&
- Index == identifier.Index &&
- Code == identifier.Code;
- }
-
- public static bool operator ==(ButtonIdentifier a, ButtonIdentifier b)
- {
- return a.Equals(b);
- }
-
- public static bool operator !=(ButtonIdentifier a, ButtonIdentifier b)
- {
- return !(a == b);
- }
- }
-}
diff --git a/src/Input/ButtonState.cs b/src/Input/ButtonState.cs
index 270f6b9..0d13743 100644
--- a/src/Input/ButtonState.cs
+++ b/src/Input/ButtonState.cs
@@ -9,7 +9,7 @@
public bool IsDown => ButtonStatus == ButtonStatus.Pressed || ButtonStatus == ButtonStatus.Held;
public bool IsReleased => ButtonStatus == ButtonStatus.Released;
- public ButtonState(ButtonStatus buttonStatus)
+ internal ButtonState(ButtonStatus buttonStatus)
{
ButtonStatus = buttonStatus;
}
diff --git a/src/Input/Gamepad.cs b/src/Input/Gamepad.cs
index 16a8e6c..4e432e7 100644
--- a/src/Input/Gamepad.cs
+++ b/src/Input/Gamepad.cs
@@ -10,39 +10,57 @@ namespace MoonWorks.Input
internal IntPtr Handle;
internal int Index;
- public Button A { get; } = new Button();
- public Button B { get; } = new Button();
- public Button X { get; } = new Button();
- public Button Y { get; } = new Button();
- public Button Back { get; } = new Button();
- public Button Guide { get; } = new Button();
- public Button Start { get; } = new Button();
- public Button LeftStick { get; } = new Button();
- public Button RightStick { get; } = new Button();
- public Button LeftShoulder { get; } = new Button();
- public Button RightShoulder { get; } = new Button();
- public Button DpadUp { get; } = new Button();
- public Button DpadDown { get; } = new Button();
- public Button DpadLeft { get; } = new Button();
- public Button DpadRight { get; } = new Button();
+ public GamepadButton A { get; }
+ public GamepadButton B { get; }
+ public GamepadButton X { get; }
+ public GamepadButton Y { get; }
+ public GamepadButton Back { get; }
+ public GamepadButton Guide { get; }
+ public GamepadButton Start { get; }
+ public GamepadButton LeftStick { get; }
+ public GamepadButton RightStick { get; }
+ public GamepadButton LeftShoulder { get; }
+ public GamepadButton RightShoulder { get; }
+ public GamepadButton DpadUp { get; }
+ public GamepadButton DpadDown { get; }
+ public GamepadButton DpadLeft { get; }
+ public GamepadButton DpadRight { get; }
- public Axis LeftX { get; } = new Axis();
- public Axis LeftY { get; } = new Axis();
- public Axis RightX { get; } = new Axis();
- public Axis RightY { get; } = new Axis();
+ public Axis LeftX { get; }
+ public Axis LeftY { get; }
+ public Axis RightX { get; }
+ public Axis RightY { get; }
- public Trigger TriggerLeft { get; } = new Trigger();
- public Trigger TriggerRight { get; } = new Trigger();
+ public AxisButton LeftXLeft { get; }
+ public AxisButton LeftXRight { get; }
+ public AxisButton LeftYUp { get; }
+ public AxisButton LeftYDown { get; }
+
+ public AxisButton RightXLeft { get; }
+ public AxisButton RightXRight { get; }
+ public AxisButton RightYUp { get; }
+ public AxisButton RightYDown { get; }
+
+ public Trigger TriggerLeft { get; }
+ public Trigger TriggerRight { get; }
+
+ public TriggerButton TriggerLeftButton { get; }
+ public TriggerButton TriggerRightButton { get; }
public bool IsDummy => Handle == IntPtr.Zero;
public bool AnyPressed { get; private set; }
- public ButtonCode AnyPressedButtonCode { get; private set; }
+ public VirtualButton AnyPressedButton { get; private set; }
- private Dictionary EnumToButton;
+ private Dictionary EnumToButton;
private Dictionary EnumToAxis;
private Dictionary EnumToTrigger;
+ private Dictionary AxisButtonCodeToAxisButton;
+ private Dictionary TriggerCodeToTriggerButton;
+
+ private VirtualButton[] VirtualButtons;
+
internal Gamepad(IntPtr handle, int index)
{
Handle = handle;
@@ -50,7 +68,48 @@ namespace MoonWorks.Input
AnyPressed = false;
- EnumToButton = new Dictionary
+ A = new GamepadButton(handle, GamepadButtonCode.A, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_A);
+ B = new GamepadButton(handle, GamepadButtonCode.B, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_B);
+ X = new GamepadButton(handle, GamepadButtonCode.X, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_X);
+ Y = new GamepadButton(handle, GamepadButtonCode.Y, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_Y);
+
+ Back = new GamepadButton(handle, GamepadButtonCode.Back, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_BACK);
+ Guide = new GamepadButton(handle, GamepadButtonCode.Guide, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_GUIDE);
+ Start = new GamepadButton(handle, GamepadButtonCode.Start, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_START);
+
+ LeftStick = new GamepadButton(handle, GamepadButtonCode.LeftStick, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSTICK);
+ RightStick = new GamepadButton(handle, GamepadButtonCode.RightStick, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSTICK);
+
+ LeftShoulder = new GamepadButton(handle, GamepadButtonCode.LeftShoulder, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
+ RightShoulder = new GamepadButton(handle, GamepadButtonCode.RightShoulder, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
+
+ DpadUp = new GamepadButton(handle, GamepadButtonCode.DpadUp, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_UP);
+ DpadDown = new GamepadButton(handle, GamepadButtonCode.DpadDown, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_DOWN);
+ DpadLeft = new GamepadButton(handle, GamepadButtonCode.DpadLeft, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_LEFT);
+ DpadRight = new GamepadButton(handle, GamepadButtonCode.DpadRight, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
+
+ LeftX = new Axis(handle, AxisCode.LeftX, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTX);
+ LeftY = new Axis(handle, AxisCode.LeftY, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTY);
+ RightX = new Axis(handle, AxisCode.RightX, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTX);
+ RightY = new Axis(handle, AxisCode.RightY, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTY);
+
+ LeftXLeft = new AxisButton(LeftX, false);
+ LeftXRight = new AxisButton(LeftX, true);
+ LeftYUp = new AxisButton(LeftY, false);
+ LeftYDown = new AxisButton(LeftY, true);
+
+ RightXLeft = new AxisButton(RightX, false);
+ RightXRight = new AxisButton(RightX, true);
+ RightYUp = new AxisButton(RightY, false);
+ RightYDown = new AxisButton(RightY, true);
+
+ TriggerLeft = new Trigger(handle, TriggerCode.Left, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT);
+ TriggerRight = new Trigger(handle, TriggerCode.Right, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
+
+ TriggerLeftButton = new TriggerButton(TriggerLeft);
+ TriggerRightButton = new TriggerButton(TriggerRight);
+
+ EnumToButton = new Dictionary
{
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_A, A },
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_B, B },
@@ -82,6 +141,47 @@ namespace MoonWorks.Input
{ SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT, TriggerLeft },
{ SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT, TriggerRight }
};
+
+ AxisButtonCodeToAxisButton = new Dictionary
+ {
+ { AxisButtonCode.LeftX_Left, LeftXLeft },
+ { AxisButtonCode.LeftX_Right, LeftXRight },
+ { AxisButtonCode.LeftY_Down, LeftYDown },
+ { AxisButtonCode.LeftY_Up, LeftYUp },
+ { AxisButtonCode.RightX_Left, RightXLeft },
+ { AxisButtonCode.RightX_Right, RightXRight },
+ { AxisButtonCode.RightY_Up, RightYUp },
+ { AxisButtonCode.RightY_Down, RightYDown }
+ };
+
+ VirtualButtons = new VirtualButton[]
+ {
+ A,
+ B,
+ X,
+ Y,
+ Back,
+ Guide,
+ Start,
+ LeftStick,
+ RightStick,
+ LeftShoulder,
+ RightShoulder,
+ DpadUp,
+ DpadDown,
+ DpadLeft,
+ DpadRight,
+ LeftXLeft,
+ LeftXRight,
+ LeftYUp,
+ LeftYDown,
+ RightXLeft,
+ RightXRight,
+ RightYUp,
+ RightYDown,
+ TriggerLeftButton,
+ TriggerRightButton
+ };
}
internal void Update()
@@ -90,31 +190,42 @@ namespace MoonWorks.Input
if (!IsDummy)
{
- foreach (var (sdlEnum, button) in EnumToButton)
+ foreach (var button in EnumToButton.Values)
{
- var pressed = CheckPressed(sdlEnum);
- button.Update(pressed);
+ button.Update();
+ }
+ foreach (var axis in EnumToAxis.Values)
+ {
+ axis.Update();
+ }
+
+ foreach (var trigger in EnumToTrigger.Values)
+ {
+ trigger.Update();
+ }
+
+ LeftXLeft.Update();
+ LeftXRight.Update();
+ LeftYUp.Update();
+ LeftYDown.Update();
+ RightXLeft.Update();
+ RightXRight.Update();
+ RightYUp.Update();
+ RightYDown.Update();
+
+ TriggerLeftButton.Update();
+ TriggerRightButton.Update();
+
+ foreach (var button in VirtualButtons)
+ {
if (button.IsPressed)
{
AnyPressed = true;
- AnyPressedButtonCode = (ButtonCode) sdlEnum;
+ AnyPressedButton = button;
+ break;
}
}
-
- foreach (var (sdlEnum, axis) in EnumToAxis)
- {
- var sdlAxisValue = SDL.SDL_GameControllerGetAxis(Handle, sdlEnum);
- var axisValue = MathHelper.Normalize(sdlAxisValue, short.MinValue, short.MaxValue, -1, 1);
- axis.Update(axisValue);
- }
-
- foreach (var (sdlEnum, trigger) in EnumToTrigger)
- {
- var sdlAxisValue = SDL.SDL_GameControllerGetAxis(Handle, sdlEnum);
- var axisValue = MathHelper.Normalize(sdlAxisValue, 0, short.MaxValue, 0, 1);
- trigger.Update(axisValue);
- }
}
}
@@ -131,44 +242,19 @@ namespace MoonWorks.Input
) == 0;
}
- ///
- /// True if the button is pressed or held.
- ///
- public bool IsDown(ButtonCode buttonCode)
+ public GamepadButton Button(GamepadButtonCode buttonCode)
{
- return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].IsDown;
+ return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode];
}
- ///
- /// True if the button was pressed this exact frame.
- ///
- public bool IsPressed(ButtonCode buttonCode)
+ public AxisButton Button(AxisButtonCode axisButtonCode)
{
- return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].IsPressed;
+ return AxisButtonCodeToAxisButton[axisButtonCode];
}
- ///
- /// True if the button has been continuously held for more than one frame.
- ///
- public bool IsHeld(ButtonCode buttonCode)
+ public TriggerButton Button(TriggerCode triggerCode)
{
- return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].IsHeld;
- }
-
- ///
- /// True if the button is not pressed.
- ///
- public bool IsReleased(ButtonCode buttonCode)
- {
- return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].IsReleased;
- }
-
- ///
- /// Obtains the button state given a ButtonCode.
- ///
- public ButtonState ButtonState(ButtonCode buttonCode)
- {
- return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].State;
+ return TriggerCodeToTriggerButton[triggerCode];
}
///
diff --git a/src/Input/Input.cs b/src/Input/Input.cs
index c41178f..739a641 100644
--- a/src/Input/Input.cs
+++ b/src/Input/Input.cs
@@ -15,7 +15,7 @@ namespace MoonWorks.Input
public static event Action TextInput;
public bool AnyPressed { get; private set; }
- public ButtonIdentifier AnyPressedButton { get; private set; }
+ public VirtualButton AnyPressedButton { get; private set; }
internal Inputs()
{
@@ -49,7 +49,7 @@ namespace MoonWorks.Input
if (Keyboard.AnyPressed)
{
AnyPressed = true;
- AnyPressedButton = new ButtonIdentifier(Keyboard.AnyPressedKeyCode);
+ AnyPressedButton = Keyboard.AnyPressedButton;
}
Mouse.Update();
@@ -57,7 +57,7 @@ namespace MoonWorks.Input
if (Mouse.AnyPressed)
{
AnyPressed = true;
- AnyPressedButton = new ButtonIdentifier(Mouse.AnyPressedButtonCode);
+ AnyPressedButton = Mouse.AnyPressedButton;
}
foreach (var gamepad in gamepads)
@@ -67,7 +67,7 @@ namespace MoonWorks.Input
if (gamepad.AnyPressed)
{
AnyPressed = true;
- AnyPressedButton = new ButtonIdentifier(gamepad, gamepad.AnyPressedButtonCode);
+ AnyPressedButton = gamepad.AnyPressedButton;
}
}
}
@@ -82,31 +82,6 @@ namespace MoonWorks.Input
return gamepads[slot];
}
- public ButtonState ButtonState(ButtonIdentifier identifier)
- {
- if (identifier.DeviceKind == DeviceKind.Gamepad)
- {
- var gamepad = GetGamepad(identifier.Index);
- return gamepad.ButtonState((ButtonCode) identifier.Code);
- }
- else if (identifier.DeviceKind == DeviceKind.Keyboard)
- {
- return Keyboard.ButtonState((KeyCode) identifier.Code);
- }
- else if (identifier.DeviceKind == DeviceKind.Mouse)
- {
- return Mouse.ButtonState((MouseButtonCode) identifier.Code);
- }
- else if (identifier.DeviceKind == DeviceKind.None)
- {
- return new ButtonState(ButtonStatus.Released);
- }
- else
- {
- throw new System.ArgumentException("Invalid button identifier!");
- }
- }
-
internal static void OnTextInput(char c)
{
if (TextInput != null)
diff --git a/src/Input/Keyboard.cs b/src/Input/Keyboard.cs
index 1c31a7d..ac66018 100644
--- a/src/Input/Keyboard.cs
+++ b/src/Input/Keyboard.cs
@@ -8,9 +8,11 @@ namespace MoonWorks.Input
public class Keyboard
{
public bool AnyPressed { get; private set; }
- public KeyCode AnyPressedKeyCode { get; private set; }
+ public KeyboardButton AnyPressedButton { get; private set; }
- private Button[] Keys { get; }
+ public IntPtr State { get; private set; }
+
+ private KeyboardButton[] Keys { get; }
private int numKeys;
private static readonly char[] TextInputCharacters = new char[]
@@ -39,10 +41,10 @@ namespace MoonWorks.Input
{
SDL.SDL_GetKeyboardState(out numKeys);
- Keys = new Button[numKeys];
+ Keys = new KeyboardButton[numKeys];
foreach (KeyCode keycode in Enum.GetValues(typeof(KeyCode)))
{
- Keys[(int) keycode] = new Button();
+ Keys[(int) keycode] = new KeyboardButton(this, keycode);
}
}
@@ -50,14 +52,14 @@ namespace MoonWorks.Input
{
AnyPressed = false;
- IntPtr keyboardState = SDL.SDL_GetKeyboardState(out _);
+ State = SDL.SDL_GetKeyboardState(out _);
foreach (int keycode in Enum.GetValues(typeof(KeyCode)))
{
- var keyDown = Conversions.ByteToBool(Marshal.ReadByte(keyboardState, keycode));
- Keys[keycode].Update(keyDown);
+ var button = Keys[keycode];
+ button.Update();
- if (keyDown)
+ if (button.IsPressed)
{
if (TextInputBindings.TryGetValue((KeyCode) keycode, out var textIndex))
{
@@ -67,12 +69,9 @@ namespace MoonWorks.Input
{
Inputs.OnTextInput(TextInputCharacters[6]);
}
- }
- if (Keys[keycode].IsPressed)
- {
AnyPressed = true;
- AnyPressedKeyCode = (KeyCode) keycode;
+ AnyPressedButton = button;
}
}
}
@@ -97,7 +96,7 @@ namespace MoonWorks.Input
return Keys[(int) keycode].IsReleased;
}
- public Button Button(KeyCode keycode)
+ public KeyboardButton Button(KeyCode keycode)
{
return Keys[(int) keycode];
}
diff --git a/src/Input/Mouse.cs b/src/Input/Mouse.cs
index ea803e3..3ee65bc 100644
--- a/src/Input/Mouse.cs
+++ b/src/Input/Mouse.cs
@@ -5,9 +5,9 @@ namespace MoonWorks.Input
{
public class Mouse
{
- public Button LeftButton { get; } = new Button();
- public Button MiddleButton { get; } = new Button();
- public Button RightButton { get; } = new Button();
+ public MouseButton LeftButton { get; }
+ public MouseButton MiddleButton { get; }
+ public MouseButton RightButton { get; }
public int X { get; private set; }
public int Y { get; private set; }
@@ -17,7 +17,9 @@ namespace MoonWorks.Input
public int Wheel { get; internal set; }
public bool AnyPressed { get; private set; }
- public MouseButtonCode AnyPressedButtonCode { get; private set; }
+ public MouseButton AnyPressedButton { get; private set; }
+
+ public uint ButtonMask { get; private set; }
private bool relativeMode;
public bool RelativeMode
@@ -34,31 +36,37 @@ namespace MoonWorks.Input
}
}
- private readonly Dictionary CodeToButton;
- private readonly Dictionary MaskToButtonCode;
+ private readonly Dictionary CodeToButton;
+
+ private IEnumerable Buttons
+ {
+ get
+ {
+ yield return LeftButton;
+ yield return MiddleButton;
+ yield return RightButton;
+ }
+ }
public Mouse()
{
- CodeToButton = new Dictionary
+ LeftButton = new MouseButton(this, MouseButtonCode.Left, SDL.SDL_BUTTON_LMASK);
+ MiddleButton = new MouseButton(this, MouseButtonCode.Middle, SDL.SDL_BUTTON_MMASK);
+ RightButton = new MouseButton(this, MouseButtonCode.Right, SDL.SDL_BUTTON_RMASK);
+
+ CodeToButton = new Dictionary
{
{ MouseButtonCode.Left, LeftButton },
{ MouseButtonCode.Right, RightButton },
{ MouseButtonCode.Middle, MiddleButton }
};
-
- MaskToButtonCode = new Dictionary
- {
- { SDL.SDL_BUTTON_LMASK, MouseButtonCode.Left },
- { SDL.SDL_BUTTON_MMASK, MouseButtonCode.Middle },
- { SDL.SDL_BUTTON_RMASK, MouseButtonCode.Right }
- };
}
internal void Update()
{
AnyPressed = false;
- var buttonMask = SDL.SDL_GetMouseState(out var x, out var y);
+ ButtonMask = SDL.SDL_GetMouseState(out var x, out var y);
var _ = SDL.SDL_GetRelativeMouseState(out var deltaX, out var deltaY);
X = x;
@@ -66,16 +74,18 @@ namespace MoonWorks.Input
DeltaX = deltaX;
DeltaY = deltaY;
- foreach (var (mask, buttonCode) in MaskToButtonCode)
+ LeftButton.Update();
+ MiddleButton.Update();
+ RightButton.Update();
+
+ foreach (var button in Buttons)
{
- var pressed = IsPressed(buttonMask, mask);
- var button = CodeToButton[buttonCode];
- button.Update(pressed);
+ button.Update();
if (button.IsPressed)
{
AnyPressed = true;
- AnyPressedButtonCode = buttonCode;
+ AnyPressedButton = button;
}
}
}
@@ -84,10 +94,5 @@ namespace MoonWorks.Input
{
return CodeToButton[buttonCode].State;
}
-
- private bool IsPressed(uint buttonMask, uint buttonFlag)
- {
- return (buttonMask & buttonFlag) != 0;
- }
}
}
diff --git a/src/Input/Trigger.cs b/src/Input/Trigger.cs
index 58b151d..4a8c826 100644
--- a/src/Input/Trigger.cs
+++ b/src/Input/Trigger.cs
@@ -1,15 +1,38 @@
+using System;
+using MoonWorks.Math;
+using SDL2;
+
namespace MoonWorks.Input
{
public class Trigger
{
+ public IntPtr GamepadHandle;
+ public SDL.SDL_GameControllerAxis SDL_Axis;
+
+ public TriggerCode Code { get; }
+
///
/// A trigger value between 0 and 1.
///
public float Value { get; private set; }
- internal void Update(float value)
+ public Trigger(
+ IntPtr gamepadHandle,
+ TriggerCode code,
+ SDL.SDL_GameControllerAxis sdlAxis
+ ) {
+ GamepadHandle = gamepadHandle;
+ Code = code;
+ SDL_Axis = sdlAxis;
+ }
+
+ internal void Update()
{
- Value = value;
+ Value = MathHelper.Normalize(
+ SDL.SDL_GameControllerGetAxis(GamepadHandle, SDL_Axis),
+ 0, short.MaxValue,
+ 0, 1
+ );
}
}
}
diff --git a/src/Input/Button.cs b/src/Input/VirtualButton.cs
similarity index 73%
rename from src/Input/Button.cs
rename to src/Input/VirtualButton.cs
index 7826d07..4f9efc2 100644
--- a/src/Input/Button.cs
+++ b/src/Input/VirtualButton.cs
@@ -1,8 +1,8 @@
namespace MoonWorks.Input
{
- public class Button
+ public abstract class VirtualButton
{
- public ButtonState State { get; private set; }
+ public ButtonState State { get; protected set; }
///
/// True if the button is pressed or held.
@@ -24,9 +24,11 @@ namespace MoonWorks.Input
///
public bool IsReleased => State.IsReleased;
- internal void Update(bool isPressed)
+ internal virtual void Update()
{
- State = State.Update(isPressed);
+ State = State.Update(CheckPressed());
}
+
+ internal abstract bool CheckPressed();
}
}
diff --git a/src/Input/VirtualButtons/AxisButton.cs b/src/Input/VirtualButtons/AxisButton.cs
new file mode 100644
index 0000000..92e244a
--- /dev/null
+++ b/src/Input/VirtualButtons/AxisButton.cs
@@ -0,0 +1,73 @@
+namespace MoonWorks.Input
+{
+ public class AxisButton : VirtualButton
+ {
+ public Axis Parent { get; }
+ public AxisButtonCode Code { get; }
+
+ private float threshold = 0.9f;
+ public float Threshold
+ {
+ get => threshold;
+ set => threshold = System.Math.Clamp(value, 0, 1);
+ }
+
+ private int Sign;
+
+ internal AxisButton(Axis parent, bool positive)
+ {
+ Parent = parent;
+ Sign = positive ? 1 : -1;
+
+ if (parent.Code == AxisCode.LeftX)
+ {
+ if (positive)
+ {
+ Code = AxisButtonCode.LeftX_Right;
+ }
+ else
+ {
+ Code = AxisButtonCode.LeftX_Left;
+ }
+ }
+ else if (parent.Code == AxisCode.LeftY)
+ {
+ if (positive)
+ {
+ Code = AxisButtonCode.LeftY_Up;
+ }
+ else
+ {
+ Code = AxisButtonCode.LeftY_Down;
+ }
+ }
+ else if (parent.Code == AxisCode.RightX)
+ {
+ if (positive)
+ {
+ Code = AxisButtonCode.RightX_Right;
+ }
+ else
+ {
+ Code = AxisButtonCode.RightX_Left;
+ }
+ }
+ else if (parent.Code == AxisCode.RightY)
+ {
+ if (positive)
+ {
+ Code = AxisButtonCode.RightY_Up;
+ }
+ else
+ {
+ Code = AxisButtonCode.RightY_Down;
+ }
+ }
+ }
+
+ internal override bool CheckPressed()
+ {
+ return Sign * Parent.Value >= threshold;
+ }
+ }
+}
diff --git a/src/Input/VirtualButtons/GamepadButton.cs b/src/Input/VirtualButtons/GamepadButton.cs
new file mode 100644
index 0000000..344ee5b
--- /dev/null
+++ b/src/Input/VirtualButtons/GamepadButton.cs
@@ -0,0 +1,25 @@
+using System;
+using SDL2;
+
+namespace MoonWorks.Input
+{
+ public class GamepadButton : VirtualButton
+ {
+ IntPtr GamepadHandle;
+ SDL.SDL_GameControllerButton SDL_Button;
+
+ public GamepadButtonCode Code { get; private set; }
+
+ internal GamepadButton(IntPtr gamepadHandle, GamepadButtonCode code, SDL.SDL_GameControllerButton sdlButton)
+ {
+ GamepadHandle = gamepadHandle;
+ Code = code;
+ SDL_Button = sdlButton;
+ }
+
+ internal override bool CheckPressed()
+ {
+ return MoonWorks.Conversions.ByteToBool(SDL.SDL_GameControllerGetButton(GamepadHandle, SDL_Button));
+ }
+ }
+}
diff --git a/src/Input/VirtualButtons/KeyboardButton.cs b/src/Input/VirtualButtons/KeyboardButton.cs
new file mode 100644
index 0000000..733ee77
--- /dev/null
+++ b/src/Input/VirtualButtons/KeyboardButton.cs
@@ -0,0 +1,21 @@
+using System.Runtime.InteropServices;
+
+namespace MoonWorks.Input
+{
+ public class KeyboardButton : VirtualButton
+ {
+ Keyboard Parent;
+ KeyCode KeyCode;
+
+ internal KeyboardButton(Keyboard parent, KeyCode keyCode)
+ {
+ Parent = parent;
+ KeyCode = keyCode;
+ }
+
+ internal override bool CheckPressed()
+ {
+ return Conversions.ByteToBool(Marshal.ReadByte(Parent.State, (int) KeyCode));
+ }
+ }
+}
diff --git a/src/Input/VirtualButtons/MouseButton.cs b/src/Input/VirtualButtons/MouseButton.cs
new file mode 100644
index 0000000..4637114
--- /dev/null
+++ b/src/Input/VirtualButtons/MouseButton.cs
@@ -0,0 +1,22 @@
+namespace MoonWorks.Input
+{
+ public class MouseButton : VirtualButton
+ {
+ Mouse Parent;
+ uint ButtonMask;
+
+ public MouseButtonCode Code { get; private set; }
+
+ internal MouseButton(Mouse parent, MouseButtonCode code, uint buttonMask)
+ {
+ Parent = parent;
+ Code = code;
+ ButtonMask = buttonMask;
+ }
+
+ internal override bool CheckPressed()
+ {
+ return (Parent.ButtonMask & ButtonMask) != 0;
+ }
+ }
+}
diff --git a/src/Input/VirtualButtons/TriggerButton.cs b/src/Input/VirtualButtons/TriggerButton.cs
new file mode 100644
index 0000000..f0a93cb
--- /dev/null
+++ b/src/Input/VirtualButtons/TriggerButton.cs
@@ -0,0 +1,25 @@
+namespace MoonWorks.Input
+{
+ public class TriggerButton : VirtualButton
+ {
+ public Trigger Parent { get; }
+ public TriggerCode Code => Parent.Code;
+
+ private float threshold = 0.7f;
+ public float Threshold
+ {
+ get => threshold;
+ set => threshold = System.Math.Clamp(value, 0, 1);
+ }
+
+ internal TriggerButton(Trigger parent)
+ {
+ Parent = parent;
+ }
+
+ internal override bool CheckPressed()
+ {
+ return Parent.Value >= Threshold;
+ }
+ }
+}