Inputs.AnyPressed implementation

pull/20/head
cosmonaut 2022-07-08 16:47:12 -07:00
parent db5ca97726
commit 1cf3a13541
6 changed files with 113 additions and 9 deletions

View File

@ -1,7 +1,7 @@
namespace MoonWorks.Input namespace MoonWorks.Input
{ {
// Blittable identifier that can be used for button state lookups. // Blittable identifier that can be used for button state lookups.
public struct ButtonIdentifier public struct ButtonIdentifier : System.IEquatable<ButtonIdentifier>
{ {
public DeviceKind DeviceKind { get; } public DeviceKind DeviceKind { get; }
public int Index { get; } // 1-4 for gamepads, 0 otherwise public int Index { get; } // 1-4 for gamepads, 0 otherwise
@ -27,5 +27,33 @@ namespace MoonWorks.Input
Index = 0; Index = 0;
Code = (int) mouseCode; 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

@ -2,8 +2,9 @@ namespace MoonWorks.Input
{ {
public enum DeviceKind public enum DeviceKind
{ {
None,
Keyboard, Keyboard,
Mouse, Mouse,
Gamepad Gamepad,
} }
} }

View File

@ -36,6 +36,9 @@ namespace MoonWorks.Input
public bool IsDummy => Handle == IntPtr.Zero; public bool IsDummy => Handle == IntPtr.Zero;
public bool AnyPressed { get; private set; }
public ButtonCode AnyPressedButtonCode { get; private set; }
private Dictionary<SDL.SDL_GameControllerButton, Button> EnumToButton; private Dictionary<SDL.SDL_GameControllerButton, Button> EnumToButton;
private Dictionary<SDL.SDL_GameControllerAxis, Axis> EnumToAxis; private Dictionary<SDL.SDL_GameControllerAxis, Axis> EnumToAxis;
private Dictionary<SDL.SDL_GameControllerAxis, Trigger> EnumToTrigger; private Dictionary<SDL.SDL_GameControllerAxis, Trigger> EnumToTrigger;
@ -45,6 +48,8 @@ namespace MoonWorks.Input
Handle = handle; Handle = handle;
Index = index; Index = index;
AnyPressed = false;
EnumToButton = new Dictionary<SDL.SDL_GameControllerButton, Button> EnumToButton = new Dictionary<SDL.SDL_GameControllerButton, Button>
{ {
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_A, A }, { SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_A, A },
@ -81,11 +86,20 @@ namespace MoonWorks.Input
internal void Update() internal void Update()
{ {
AnyPressed = false;
if (!IsDummy) if (!IsDummy)
{ {
foreach (var (sdlEnum, button) in EnumToButton) foreach (var (sdlEnum, button) in EnumToButton)
{ {
button.Update(CheckPressed(sdlEnum)); var pressed = CheckPressed(sdlEnum);
button.Update(pressed);
if (button.IsPressed)
{
AnyPressed = true;
AnyPressedButtonCode = (ButtonCode) sdlEnum;
}
} }
foreach (var (sdlEnum, axis) in EnumToAxis) foreach (var (sdlEnum, axis) in EnumToAxis)

View File

@ -14,6 +14,9 @@ namespace MoonWorks.Input
public static event Action<char> TextInput; public static event Action<char> TextInput;
public bool AnyPressed { get; private set; }
public ButtonIdentifier AnyPressedButton { get; private set; }
internal Inputs() internal Inputs()
{ {
Keyboard = new Keyboard(); Keyboard = new Keyboard();
@ -37,13 +40,34 @@ namespace MoonWorks.Input
// Assumes that SDL_PumpEvents has been called! // Assumes that SDL_PumpEvents has been called!
internal void Update() internal void Update()
{ {
AnyPressed = false;
Mouse.Wheel = 0; Mouse.Wheel = 0;
Keyboard.Update(); Keyboard.Update();
if (Keyboard.AnyPressed)
{
AnyPressed = true;
AnyPressedButton = new ButtonIdentifier(Keyboard.AnyPressedKeyCode);
}
Mouse.Update(); Mouse.Update();
if (Mouse.AnyPressed)
{
AnyPressed = true;
AnyPressedButton = new ButtonIdentifier(Mouse.AnyPressedButtonCode);
}
foreach (var gamepad in gamepads) foreach (var gamepad in gamepads)
{ {
gamepad.Update(); gamepad.Update();
if (gamepad.AnyPressed)
{
AnyPressed = true;
AnyPressedButton = new ButtonIdentifier(gamepad, gamepad.AnyPressedButtonCode);
}
} }
} }
@ -72,6 +96,10 @@ namespace MoonWorks.Input
{ {
return Mouse.ButtonState((MouseButtonCode) identifier.Code); return Mouse.ButtonState((MouseButtonCode) identifier.Code);
} }
else if (identifier.DeviceKind == DeviceKind.None)
{
return new ButtonState(ButtonStatus.Released);
}
else else
{ {
throw new System.ArgumentException("Invalid button identifier!"); throw new System.ArgumentException("Invalid button identifier!");

View File

@ -7,6 +7,9 @@ namespace MoonWorks.Input
{ {
public class Keyboard public class Keyboard
{ {
public bool AnyPressed { get; private set; }
public KeyCode AnyPressedKeyCode { get; private set; }
private Button[] Keys { get; } private Button[] Keys { get; }
private int numKeys; private int numKeys;
@ -45,14 +48,16 @@ namespace MoonWorks.Input
internal void Update() internal void Update()
{ {
AnyPressed = false;
IntPtr keyboardState = SDL.SDL_GetKeyboardState(out _); IntPtr keyboardState = SDL.SDL_GetKeyboardState(out _);
foreach (int keycode in Enum.GetValues(typeof(KeyCode))) foreach (int keycode in Enum.GetValues(typeof(KeyCode)))
{ {
var keyDown = Marshal.ReadByte(keyboardState, keycode); var keyDown = Conversions.ByteToBool(Marshal.ReadByte(keyboardState, keycode));
Keys[keycode].Update(Conversions.ByteToBool(keyDown)); Keys[keycode].Update(keyDown);
if (Conversions.ByteToBool(keyDown)) if (keyDown)
{ {
if (TextInputBindings.TryGetValue((KeyCode) keycode, out var textIndex)) if (TextInputBindings.TryGetValue((KeyCode) keycode, out var textIndex))
{ {
@ -63,6 +68,12 @@ namespace MoonWorks.Input
Inputs.OnTextInput(TextInputCharacters[6]); Inputs.OnTextInput(TextInputCharacters[6]);
} }
} }
if (Keys[keycode].IsPressed)
{
AnyPressed = true;
AnyPressedKeyCode = (KeyCode) keycode;
}
} }
} }

View File

@ -16,6 +16,9 @@ namespace MoonWorks.Input
public int Wheel { get; internal set; } public int Wheel { get; internal set; }
public bool AnyPressed { get; private set; }
public MouseButtonCode AnyPressedButtonCode { get; private set; }
private bool relativeMode; private bool relativeMode;
public bool RelativeMode public bool RelativeMode
{ {
@ -32,6 +35,7 @@ namespace MoonWorks.Input
} }
private readonly Dictionary<MouseButtonCode, Button> CodeToButton; private readonly Dictionary<MouseButtonCode, Button> CodeToButton;
private readonly Dictionary<uint, MouseButtonCode> MaskToButtonCode;
public Mouse() public Mouse()
{ {
@ -41,10 +45,19 @@ namespace MoonWorks.Input
{ MouseButtonCode.Right, RightButton }, { MouseButtonCode.Right, RightButton },
{ MouseButtonCode.Middle, MiddleButton } { 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() internal void Update()
{ {
AnyPressed = false;
var buttonMask = SDL.SDL_GetMouseState(out var x, out var y); var buttonMask = SDL.SDL_GetMouseState(out var x, out var y);
var _ = SDL.SDL_GetRelativeMouseState(out var deltaX, out var deltaY); var _ = SDL.SDL_GetRelativeMouseState(out var deltaX, out var deltaY);
@ -53,9 +66,18 @@ namespace MoonWorks.Input
DeltaX = deltaX; DeltaX = deltaX;
DeltaY = deltaY; DeltaY = deltaY;
LeftButton.Update(IsPressed(buttonMask, SDL.SDL_BUTTON_LMASK)); foreach (var (mask, buttonCode) in MaskToButtonCode)
MiddleButton.Update(IsPressed(buttonMask, SDL.SDL_BUTTON_MMASK)); {
RightButton.Update(IsPressed(buttonMask, SDL.SDL_BUTTON_RMASK)); var pressed = IsPressed(buttonMask, mask);
var button = CodeToButton[buttonCode];
button.Update(pressed);
if (button.IsPressed)
{
AnyPressed = true;
AnyPressedButtonCode = buttonCode;
}
}
} }
public ButtonState ButtonState(MouseButtonCode buttonCode) public ButtonState ButtonState(MouseButtonCode buttonCode)