From 60c9236cbd36fb08a2b7f1e9278d7bd07ff4ef80 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Sun, 20 Jun 2021 23:05:02 +0200 Subject: [PATCH] added InputsDown and InputsPressed to InputHandler --- MLEM/Input/GenericInput.cs | 14 +++++++ MLEM/Input/InputHandler.cs | 83 ++++++++++++++++++++++++++++++-------- Sandbox/GameImpl.cs | 5 +++ 3 files changed, 85 insertions(+), 17 deletions(-) diff --git a/MLEM/Input/GenericInput.cs b/MLEM/Input/GenericInput.cs index 1809726..ff88704 100644 --- a/MLEM/Input/GenericInput.cs +++ b/MLEM/Input/GenericInput.cs @@ -25,6 +25,20 @@ namespace MLEM.Input { this.value = value; } + /// + public override string ToString() { + switch (this.Type) { + case InputType.Mouse: + return ((MouseButton) this).ToString(); + case InputType.Keyboard: + return ((Keys) this).ToString(); + case InputType.Gamepad: + return ((Buttons) this).ToString(); + default: + throw new ArgumentOutOfRangeException(nameof(this.Type)); + } + } + /// /// Converts a to a generic input. /// diff --git a/MLEM/Input/InputHandler.cs b/MLEM/Input/InputHandler.cs index c456902..d21373e 100644 --- a/MLEM/Input/InputHandler.cs +++ b/MLEM/Input/InputHandler.cs @@ -23,11 +23,7 @@ namespace MLEM.Input { /// public KeyboardState KeyboardState { get; private set; } /// - /// Contains the keyboard keys that are currently being pressed - /// - public Keys[] PressedKeys { get; private set; } - /// - /// Set this property to false to disable keyboard handling for this input handler. + /// Set this field to false to disable keyboard handling for this input handler. /// public bool HandleKeyboard; @@ -56,7 +52,7 @@ namespace MLEM.Input { /// public int LastScrollWheel => this.LastMouseState.ScrollWheelValue; /// - /// Set this property to false to disable mouse handling for this input handler. + /// Set this field to false to disable mouse handling for this input handler. /// public bool HandleMouse; @@ -64,11 +60,11 @@ namespace MLEM.Input { private readonly GamePadState[] gamepads = new GamePadState[GamePad.MaximumGamePadCount]; /// /// Contains the amount of gamepads that are currently connected. - /// This property is automatically updated in + /// This field is automatically updated in /// public int ConnectedGamepads { get; private set; } /// - /// Set this property to false to disable keyboard handling for this input handler. + /// Set this field to false to disable keyboard handling for this input handler. /// public bool HandleGamepads; @@ -87,7 +83,7 @@ namespace MLEM.Input { public readonly ReadOnlyCollection Gestures; private readonly List gestures = new List(); /// - /// Set this property to false to disable touch handling for this input handler. + /// Set this field to false to disable touch handling for this input handler. /// public bool HandleTouch; @@ -103,7 +99,7 @@ namespace MLEM.Input { public TimeSpan KeyRepeatRate = TimeSpan.FromSeconds(0.05); /// - /// Set this property to false to disable keyboard repeat event handling. + /// Set this field to false to disable keyboard repeat event handling. /// public bool HandleKeyboardRepeats = true; private DateTime heldKeyStart; @@ -112,7 +108,7 @@ namespace MLEM.Input { private Keys heldKey; /// - /// Set this property to false to disable gamepad repeat event handling. + /// Set this field to false to disable gamepad repeat event handling. /// public bool HandleGamepadRepeats = true; private readonly DateTime[] heldGamepadButtonStarts = new DateTime[GamePad.MaximumGamePadCount]; @@ -120,6 +116,23 @@ namespace MLEM.Input { private readonly bool[] triggerGamepadButtonRepeat = new bool[GamePad.MaximumGamePadCount]; private readonly Buttons?[] heldGamepadButtons = new Buttons?[GamePad.MaximumGamePadCount]; + /// + /// An array of all , and values that are currently down. + /// Note that this value only gets set if is true. + /// + public GenericInput[] InputsDown { get; private set; } + /// + /// An array of all , and that are currently considered pressed. + /// An input is considered pressed if it was up in the last update, and is up in the current one. + /// Note that this value only gets set if is true. + /// + public GenericInput[] InputsPressed { get; private set; } + private readonly List inputsDownAccum = new List(); + /// + /// Set this field to false to enable and being calculated. + /// + public bool StoreAllActiveInputs; + /// /// Creates a new input handler with optional initial values. /// @@ -128,11 +141,13 @@ namespace MLEM.Input { /// If mouse input should be handled /// If gamepad input should be handled /// If touch input should be handled - public InputHandler(Game game, bool handleKeyboard = true, bool handleMouse = true, bool handleGamepads = true, bool handleTouch = true) : base(game) { + /// Whether all inputs that are currently down and pressed should be calculated each update + public InputHandler(Game game, bool handleKeyboard = true, bool handleMouse = true, bool handleGamepads = true, bool handleTouch = true, bool storeAllActiveInputs = true) : base(game) { this.HandleKeyboard = handleKeyboard; this.HandleMouse = handleMouse; this.HandleGamepads = handleGamepads; this.HandleTouch = handleTouch; + this.StoreAllActiveInputs = storeAllActiveInputs; this.Gestures = this.gestures.AsReadOnly(); } @@ -145,14 +160,18 @@ namespace MLEM.Input { if (this.HandleKeyboard) { this.LastKeyboardState = this.KeyboardState; this.KeyboardState = active ? Keyboard.GetState() : default; - this.PressedKeys = this.KeyboardState.GetPressedKeys(); + var pressedKeys = this.KeyboardState.GetPressedKeys(); + if (this.StoreAllActiveInputs) { + foreach (var pressed in pressedKeys) + this.inputsDownAccum.Add(pressed); + } if (this.HandleKeyboardRepeats) { this.triggerKeyRepeat = false; if (this.heldKey == Keys.None) { // if we're not repeating a key, set the first key being held to the repeat key // note that modifier keys don't count as that wouldn't really make sense - var key = this.PressedKeys.FirstOrDefault(k => !k.IsModifier()); + var key = pressedKeys.FirstOrDefault(k => !k.IsModifier()); if (key != Keys.None) { this.heldKey = key; this.heldKeyStart = DateTime.UtcNow; @@ -184,6 +203,12 @@ namespace MLEM.Input { var state = Mouse.GetState(); if (active && this.Game.GraphicsDevice.Viewport.Bounds.Contains(state.Position)) { this.MouseState = state; + if (this.StoreAllActiveInputs) { + foreach (var button in MouseExtensions.MouseButtons) { + if (state.GetState(button) == ButtonState.Pressed) + this.inputsDownAccum.Add(button); + } + } } else { // mouse position and scroll wheel value should be preserved when the mouse is out of bounds this.MouseState = new MouseState(state.X, state.Y, state.ScrollWheelValue, 0, 0, 0, 0, 0, state.HorizontalScrollWheelValue); @@ -194,9 +219,22 @@ namespace MLEM.Input { this.ConnectedGamepads = GamePad.MaximumGamePadCount; for (var i = 0; i < GamePad.MaximumGamePadCount; i++) { this.lastGamepads[i] = this.gamepads[i]; - this.gamepads[i] = active ? GamePad.GetState(i) : default; - if (this.ConnectedGamepads > i && !GamePad.GetCapabilities(i).IsConnected) - this.ConnectedGamepads = i; + var state = GamePadState.Default; + if (GamePad.GetCapabilities(i).IsConnected) { + if (active) { + state = GamePad.GetState(i); + if (this.StoreAllActiveInputs) { + foreach (var button in EnumHelper.Buttons) { + if (state.IsButtonDown(button)) + this.inputsDownAccum.Add(button); + } + } + } + } else { + if (this.ConnectedGamepads > i) + this.ConnectedGamepads = i; + } + this.gamepads[i] = state; } if (this.HandleGamepadRepeats) { @@ -238,6 +276,17 @@ namespace MLEM.Input { while (active && TouchPanel.IsGestureAvailable) this.gestures.Add(TouchPanel.ReadGesture()); } + + if (this.StoreAllActiveInputs) { + if (this.inputsDownAccum.Count <= 0) { + this.InputsPressed = Array.Empty(); + this.InputsDown = Array.Empty(); + } else { + this.InputsPressed = this.inputsDownAccum.Where(i => !this.InputsDown.Contains(i)).ToArray(); + this.InputsDown = this.inputsDownAccum.ToArray(); + this.inputsDownAccum.Clear(); + } + } } /// diff --git a/Sandbox/GameImpl.cs b/Sandbox/GameImpl.cs index 6eea08a..9ce8fc1 100644 --- a/Sandbox/GameImpl.cs +++ b/Sandbox/GameImpl.cs @@ -230,6 +230,11 @@ namespace Sandbox { if (delta != 0) { this.camera.Zoom(0.1F * Math.Sign(delta), this.InputHandler.MousePosition.ToVector2()); } + + if (Input.InputsDown.Length > 0) + Console.WriteLine("Down: " + string.Join(", ", Input.InputsDown)); + if (Input.InputsPressed.Length > 0) + Console.WriteLine("Pressed: " + string.Join(", ", Input.InputsPressed)); } protected override void DoDraw(GameTime gameTime) {