From 5d97ab033f162fc199c9c830d9d49e534d1e1c04 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Mon, 14 Mar 2022 15:15:30 +0100 Subject: [PATCH] Added GamepadExtensions.GetAnalogValue to get the analog value of any gamepad button --- CHANGELOG.md | 2 ++ MLEM/Input/GamepadExtensions.cs | 46 +++++++++++++++++++++++++++++++++ MLEM/Input/InputHandler.cs | 29 ++++++++++++--------- 3 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 MLEM/Input/GamepadExtensions.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dda420..29c1320 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Additions - Added SoundEffectInstanceHandler.Stop - Added TextureRegion.OffsetCopy - Added RectangleF.DistanceSquared and RectangleF.Distance +- Added GamepadExtensions.GetAnalogValue to get the analog value of any gamepad button Improvements - Generify GenericFont's string drawing @@ -22,6 +23,7 @@ Improvements - Added float version of GetRandomWeightedEntry - Allow LinkCode to specify a color to draw with - Allow better control over the order and layout of a Keybind's combinations +- Allow setting a gamepad button deadzone in InputHandler Fixes - **Fixed a formatting Code only knowing about the last Token that it is applied in** diff --git a/MLEM/Input/GamepadExtensions.cs b/MLEM/Input/GamepadExtensions.cs new file mode 100644 index 0000000..981458e --- /dev/null +++ b/MLEM/Input/GamepadExtensions.cs @@ -0,0 +1,46 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; + +namespace MLEM.Input { + /// + /// A set of extension methods for dealing with , and . + /// + public static class GamepadExtensions { + + /// + /// Returns the given 's value as an analog value between 0 and 1, where 1 is fully down and 0 is not down at all. + /// For non-analog buttons, like or , only 0 and 1 will be returned and no inbetween values are possible. + /// + /// The gamepad state to query. + /// The button to query. + /// The button's state as an analog value. + public static float GetAnalogValue(this GamePadState state, Buttons button) { + switch (button) { + case Buttons.LeftThumbstickDown: + return -MathHelper.Clamp(state.ThumbSticks.Left.Y, -1, 0); + case Buttons.LeftThumbstickUp: + return MathHelper.Clamp(state.ThumbSticks.Left.Y, 0, 1); + case Buttons.LeftThumbstickLeft: + return -MathHelper.Clamp(state.ThumbSticks.Left.X, -1, 0); + case Buttons.LeftThumbstickRight: + return MathHelper.Clamp(state.ThumbSticks.Left.X, 0, 1); + case Buttons.RightTrigger: + return state.Triggers.Right; + case Buttons.LeftTrigger: + return state.Triggers.Left; + case Buttons.RightThumbstickDown: + return -MathHelper.Clamp(state.ThumbSticks.Right.Y, -1, 0); + case Buttons.RightThumbstickUp: + return MathHelper.Clamp(state.ThumbSticks.Right.Y, 0, 1); + case Buttons.RightThumbstickLeft: + return -MathHelper.Clamp(state.ThumbSticks.Right.X, -1, 0); + case Buttons.RightThumbstickRight: + return MathHelper.Clamp(state.ThumbSticks.Right.X, 0, 1); + default: + return state.IsButtonDown(button) ? 1 : 0; + } + } + + } +} \ No newline at end of file diff --git a/MLEM/Input/InputHandler.cs b/MLEM/Input/InputHandler.cs index 5a61256..23a24fe 100644 --- a/MLEM/Input/InputHandler.cs +++ b/MLEM/Input/InputHandler.cs @@ -59,6 +59,12 @@ namespace MLEM.Input { /// Set this field to false to enable and being calculated. /// public bool StoreAllActiveInputs; + /// + /// This field represents the deadzone that gamepad have when input is queried for them using this input handler. + /// A deadzone is the percentage (between 0 and 1) that an analog value has to reach for it to be considered down () or pressed (). + /// Querying of analog values is done using . + /// + public float GamepadButtonDeadzone; /// /// An array of all , and values that are currently down. @@ -234,13 +240,13 @@ namespace MLEM.Input { this.ConnectedGamepads = GamePad.MaximumGamePadCount; for (var i = 0; i < GamePad.MaximumGamePadCount; i++) { this.lastGamepads[i] = this.gamepads[i]; - var state = GamePadState.Default; + this.gamepads[i] = GamePadState.Default; if (GamePad.GetCapabilities(i).IsConnected) { if (active) { - state = GamePad.GetState(i); + this.gamepads[i] = GamePad.GetState(i); if (this.StoreAllActiveInputs) { foreach (var button in EnumHelper.Buttons) { - if (state.IsButtonDown(button)) + if (this.IsGamepadButtonDown(button, i)) this.inputsDownAccum.Add(button); } } @@ -249,7 +255,6 @@ namespace MLEM.Input { if (this.ConnectedGamepads > i) this.ConnectedGamepads = i; } - this.gamepads[i] = state; } if (this.HandleGamepadRepeats) { @@ -446,48 +451,48 @@ namespace MLEM.Input { public bool IsGamepadButtonDown(Buttons button, int index = -1) { if (index < 0) { for (var i = 0; i < this.ConnectedGamepads; i++) { - if (this.GetGamepadState(i).IsButtonDown(button)) + if (this.GetGamepadState(i).GetAnalogValue(button) >= this.GamepadButtonDeadzone) return true; } return false; } - return this.GetGamepadState(index).IsButtonDown(button); + return this.GetGamepadState(index).GetAnalogValue(button) >= this.GamepadButtonDeadzone; } /// public bool IsGamepadButtonUp(Buttons button, int index = -1) { if (index < 0) { for (var i = 0; i < this.ConnectedGamepads; i++) { - if (this.GetGamepadState(i).IsButtonUp(button)) + if (this.GetGamepadState(i).GetAnalogValue(button) < this.GamepadButtonDeadzone) return true; } return false; } - return this.GetGamepadState(index).IsButtonUp(button); + return this.GetGamepadState(index).GetAnalogValue(button) < this.GamepadButtonDeadzone; } /// public bool WasGamepadButtonDown(Buttons button, int index = -1) { if (index < 0) { for (var i = 0; i < this.ConnectedGamepads; i++) { - if (this.GetLastGamepadState(i).IsButtonDown(button)) + if (this.GetLastGamepadState(i).GetAnalogValue(button) >= this.GamepadButtonDeadzone) return true; } return false; } - return this.GetLastGamepadState(index).IsButtonDown(button); + return this.GetLastGamepadState(index).GetAnalogValue(button) >= this.GamepadButtonDeadzone; } /// public bool WasGamepadButtonUp(Buttons button, int index = -1) { if (index < 0) { for (var i = 0; i < this.ConnectedGamepads; i++) { - if (this.GetLastGamepadState(i).IsButtonUp(button)) + if (this.GetLastGamepadState(i).GetAnalogValue(button) < this.GamepadButtonDeadzone) return true; } return false; } - return this.GetLastGamepadState(index).IsButtonUp(button); + return this.GetLastGamepadState(index).GetAnalogValue(button) < this.GamepadButtonDeadzone; } ///