VirtualButton system

pull/20/head
cosmonaut 2022-07-12 16:09:23 -07:00
parent 3543f074f4
commit d07a722fb1
16 changed files with 443 additions and 209 deletions

View File

@ -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; }
/// <summary>
/// An axis value between -1 and 1.
/// </summary>
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
);
}
}
}

View File

@ -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
}
}

View File

@ -1,7 +1,7 @@
namespace MoonWorks.Input
{
// Enum values are equivalent to the SDL GameControllerButton value.
public enum ButtonCode
public enum GamepadButtonCode
{
A,
B,

View File

@ -1,59 +0,0 @@
namespace MoonWorks.Input
{
// Blittable identifier that can be used for button state lookups.
public struct ButtonIdentifier : System.IEquatable<ButtonIdentifier>
{
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);
}
}
}

View File

@ -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;
}

View File

@ -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<SDL.SDL_GameControllerButton, Button> EnumToButton;
private Dictionary<SDL.SDL_GameControllerButton, GamepadButton> EnumToButton;
private Dictionary<SDL.SDL_GameControllerAxis, Axis> EnumToAxis;
private Dictionary<SDL.SDL_GameControllerAxis, Trigger> EnumToTrigger;
private Dictionary<AxisButtonCode, AxisButton> AxisButtonCodeToAxisButton;
private Dictionary<TriggerCode, TriggerButton> TriggerCodeToTriggerButton;
private VirtualButton[] VirtualButtons;
internal Gamepad(IntPtr handle, int index)
{
Handle = handle;
@ -50,7 +68,48 @@ namespace MoonWorks.Input
AnyPressed = false;
EnumToButton = new Dictionary<SDL.SDL_GameControllerButton, Button>
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, GamepadButton>
{
{ 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, AxisButton>
{
{ 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;
}
/// <summary>
/// True if the button is pressed or held.
/// </summary>
public bool IsDown(ButtonCode buttonCode)
public GamepadButton Button(GamepadButtonCode buttonCode)
{
return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].IsDown;
return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode];
}
/// <summary>
/// True if the button was pressed this exact frame.
/// </summary>
public bool IsPressed(ButtonCode buttonCode)
public AxisButton Button(AxisButtonCode axisButtonCode)
{
return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].IsPressed;
return AxisButtonCodeToAxisButton[axisButtonCode];
}
/// <summary>
/// True if the button has been continuously held for more than one frame.
/// </summary>
public bool IsHeld(ButtonCode buttonCode)
public TriggerButton Button(TriggerCode triggerCode)
{
return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].IsHeld;
}
/// <summary>
/// True if the button is not pressed.
/// </summary>
public bool IsReleased(ButtonCode buttonCode)
{
return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].IsReleased;
}
/// <summary>
/// Obtains the button state given a ButtonCode.
/// </summary>
public ButtonState ButtonState(ButtonCode buttonCode)
{
return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].State;
return TriggerCodeToTriggerButton[triggerCode];
}
/// <summary>

View File

@ -15,7 +15,7 @@ namespace MoonWorks.Input
public static event Action<char> 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)

View File

@ -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];
}

View File

@ -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<MouseButtonCode, Button> CodeToButton;
private readonly Dictionary<uint, MouseButtonCode> MaskToButtonCode;
private readonly Dictionary<MouseButtonCode, MouseButton> CodeToButton;
private IEnumerable<MouseButton> Buttons
{
get
{
yield return LeftButton;
yield return MiddleButton;
yield return RightButton;
}
}
public Mouse()
{
CodeToButton = new Dictionary<MouseButtonCode, Button>
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, MouseButton>
{
{ MouseButtonCode.Left, LeftButton },
{ MouseButtonCode.Right, RightButton },
{ MouseButtonCode.Middle, MiddleButton }
};
MaskToButtonCode = new Dictionary<uint, MouseButtonCode>
{
{ 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;
}
}
}

View File

@ -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; }
/// <summary>
/// A trigger value between 0 and 1.
/// </summary>
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
);
}
}
}

View File

@ -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; }
/// <summary>
/// True if the button is pressed or held.
@ -24,9 +24,11 @@ namespace MoonWorks.Input
/// </summary>
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();
}
}

View File

@ -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;
}
}
}

View File

@ -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));
}
}
}

View File

@ -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));
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}