summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/Input/InputState.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Framework/Input/InputState.cs')
-rw-r--r--src/SMAPI/Framework/Input/InputState.cs163
1 files changed, 163 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;
+ }
+ }
+ }
+}