forked from MoonsideGames/MoonWorks
VirtualButton system
parent
3543f074f4
commit
d07a722fb1
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
namespace MoonWorks.Input
|
||||
{
|
||||
// Enum values are equivalent to the SDL GameControllerButton value.
|
||||
public enum ButtonCode
|
||||
public enum GamepadButtonCode
|
||||
{
|
||||
A,
|
||||
B,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue