diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-01-24 11:44:28 -0500 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-01-24 11:44:28 -0500 |
commit | 0da5dab8932c53ba39f2290268294e9a72b9c5bb (patch) | |
tree | 9302a2a53a68202ac97e86662394a509df499541 /src/SMAPI/Framework/Input | |
parent | 15d4b6310e3dd15c62f3faedbf1290b2db26fb59 (diff) | |
parent | 5c96a10da5801049ee17ffa185dbf19e6d8a2306 (diff) | |
download | SMAPI-0da5dab8932c53ba39f2290268294e9a72b9c5bb.tar.gz SMAPI-0da5dab8932c53ba39f2290268294e9a72b9c5bb.tar.bz2 SMAPI-0da5dab8932c53ba39f2290268294e9a72b9c5bb.zip |
Merge branch 'develop' into stable
Diffstat (limited to 'src/SMAPI/Framework/Input')
-rw-r--r-- | src/SMAPI/Framework/Input/InputState.cs | 163 | ||||
-rw-r--r-- | src/SMAPI/Framework/Input/InputStatus.cs | 29 |
2 files changed, 192 insertions, 0 deletions
diff --git a/src/SMAPI/Framework/Input/InputState.cs b/src/SMAPI/Framework/Input/InputState.cs new file mode 100644 index 00000000..8b0108ae --- /dev/null +++ b/src/SMAPI/Framework/Input/InputState.cs @@ -0,0 +1,163 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; +using StardewValley; + +namespace StardewModdingAPI.Framework.Input +{ + /// <summary>A summary of input changes during an update frame.</summary> + internal class InputState + { + /********* + ** Accessors + *********/ + /// <summary>The underlying controller state.</summary> + public GamePadState ControllerState { get; } + + /// <summary>The underlying keyboard state.</summary> + public KeyboardState KeyboardState { get; } + + /// <summary>The underlying mouse state.</summary> + public MouseState MouseState { get; } + + /// <summary>The mouse position on the screen adjusted for the zoom level.</summary> + public Point MousePosition { get; } + + /// <summary>The buttons which were pressed, held, or released.</summary> + public IDictionary<SButton, InputStatus> ActiveButtons { get; } = new Dictionary<SButton, InputStatus>(); + + + /********* + ** Public methods + *********/ + /// <summary>Construct an empty instance.</summary> + public InputState() { } + + /// <summary>Construct an instance.</summary> + /// <param name="previousState">The previous input state.</param> + /// <param name="controllerState">The current controller state.</param> + /// <param name="keyboardState">The current keyboard state.</param> + /// <param name="mouseState">The current mouse state.</param> + public InputState(InputState previousState, GamePadState controllerState, KeyboardState keyboardState, MouseState mouseState) + { + // init properties + this.ControllerState = controllerState; + this.KeyboardState = keyboardState; + this.MouseState = mouseState; + this.MousePosition = new Point((int)(mouseState.X * (1.0 / Game1.options.zoomLevel)), (int)(mouseState.Y * (1.0 / Game1.options.zoomLevel))); // derived from Game1::getMouseX + + // get button states + SButton[] down = InputState.GetPressedButtons(keyboardState, mouseState, controllerState).ToArray(); + foreach (SButton button in down) + this.ActiveButtons[button] = this.GetStatus(previousState.GetStatus(button), isDown: true); + foreach (KeyValuePair<SButton, InputStatus> prev in previousState.ActiveButtons) + { + if (prev.Value.IsDown() && !this.ActiveButtons.ContainsKey(prev.Key)) + this.ActiveButtons[prev.Key] = InputStatus.Released; + } + } + + /// <summary>Get the status of a button.</summary> + /// <param name="button">The button to check.</param> + public InputStatus GetStatus(SButton button) + { + return this.ActiveButtons.TryGetValue(button, out InputStatus status) ? status : InputStatus.None; + } + + /// <summary>Get whether a given button was pressed or held.</summary> + /// <param name="button">The button to check.</param> + public bool IsDown(SButton button) + { + return this.GetStatus(button).IsDown(); + } + + /// <summary>Get the current input state.</summary> + /// <param name="previousState">The previous input state.</param> + public static InputState GetState(InputState previousState) + { + GamePadState controllerState = GamePad.GetState(PlayerIndex.One); + KeyboardState keyboardState = Keyboard.GetState(); + MouseState mouseState = Mouse.GetState(); + + return new InputState(previousState, controllerState, keyboardState, mouseState); + } + + /********* + ** Private methods + *********/ + /// <summary>Get the status of a button.</summary> + /// <param name="oldStatus">The previous button status.</param> + /// <param name="isDown">Whether the button is currently down.</param> + public InputStatus GetStatus(InputStatus oldStatus, bool isDown) + { + if (isDown && oldStatus.IsDown()) + return InputStatus.Held; + if (isDown) + return InputStatus.Pressed; + return InputStatus.Released; + } + + /// <summary>Get the buttons pressed in the given stats.</summary> + /// <param name="keyboard">The keyboard state.</param> + /// <param name="mouse">The mouse state.</param> + /// <param name="controller">The controller state.</param> + private static IEnumerable<SButton> GetPressedButtons(KeyboardState keyboard, MouseState mouse, GamePadState controller) + { + // keyboard + foreach (Keys key in keyboard.GetPressedKeys()) + yield return key.ToSButton(); + + // mouse + if (mouse.LeftButton == ButtonState.Pressed) + yield return SButton.MouseLeft; + if (mouse.RightButton == ButtonState.Pressed) + yield return SButton.MouseRight; + if (mouse.MiddleButton == ButtonState.Pressed) + yield return SButton.MouseMiddle; + if (mouse.XButton1 == ButtonState.Pressed) + yield return SButton.MouseX1; + if (mouse.XButton2 == ButtonState.Pressed) + yield return SButton.MouseX2; + + // controller + if (controller.IsConnected) + { + if (controller.Buttons.A == ButtonState.Pressed) + yield return SButton.ControllerA; + if (controller.Buttons.B == ButtonState.Pressed) + yield return SButton.ControllerB; + if (controller.Buttons.Back == ButtonState.Pressed) + yield return SButton.ControllerBack; + if (controller.Buttons.BigButton == ButtonState.Pressed) + yield return SButton.BigButton; + if (controller.Buttons.LeftShoulder == ButtonState.Pressed) + yield return SButton.LeftShoulder; + if (controller.Buttons.LeftStick == ButtonState.Pressed) + yield return SButton.LeftStick; + if (controller.Buttons.RightShoulder == ButtonState.Pressed) + yield return SButton.RightShoulder; + if (controller.Buttons.RightStick == ButtonState.Pressed) + yield return SButton.RightStick; + if (controller.Buttons.Start == ButtonState.Pressed) + yield return SButton.ControllerStart; + if (controller.Buttons.X == ButtonState.Pressed) + yield return SButton.ControllerX; + if (controller.Buttons.Y == ButtonState.Pressed) + yield return SButton.ControllerY; + if (controller.DPad.Up == ButtonState.Pressed) + yield return SButton.DPadUp; + if (controller.DPad.Down == ButtonState.Pressed) + yield return SButton.DPadDown; + if (controller.DPad.Left == ButtonState.Pressed) + yield return SButton.DPadLeft; + if (controller.DPad.Right == ButtonState.Pressed) + yield return SButton.DPadRight; + if (controller.Triggers.Left > 0.2f) + yield return SButton.LeftTrigger; + if (controller.Triggers.Right > 0.2f) + yield return SButton.RightTrigger; + } + } + } +} diff --git a/src/SMAPI/Framework/Input/InputStatus.cs b/src/SMAPI/Framework/Input/InputStatus.cs new file mode 100644 index 00000000..99b0006c --- /dev/null +++ b/src/SMAPI/Framework/Input/InputStatus.cs @@ -0,0 +1,29 @@ +namespace StardewModdingAPI.Framework.Input +{ + /// <summary>The input status for a button during an update frame.</summary> + internal enum InputStatus + { + /// <summary>The button was neither pressed, held, nor released.</summary> + None, + + /// <summary>The button was pressed in this frame.</summary> + Pressed, + + /// <summary>The button has been held since the last frame.</summary> + Held, + + /// <summary>The button was released in this frame.</summary> + Released + } + + /// <summary>Extension methods for <see cref="InputStatus"/>.</summary> + internal static class InputStatusExtensions + { + /// <summary>Whether the button was pressed or held.</summary> + /// <param name="status">The button status.</param> + public static bool IsDown(this InputStatus status) + { + return status == InputStatus.Held || status == InputStatus.Pressed; + } + } +} |