summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2017-07-05 15:41:58 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2017-07-05 15:41:58 -0400
commit8d301162d87558826ed8fc8f2352800bf674ddf0 (patch)
tree9277661998c2cd2698336f9a2708a9c7d288b0fe /src
parent2f42051cc95f69a74e078ca8d0f9ae8ddbdbbbf0 (diff)
downloadSMAPI-8d301162d87558826ed8fc8f2352800bf674ddf0.tar.gz
SMAPI-8d301162d87558826ed8fc8f2352800bf674ddf0.tar.bz2
SMAPI-8d301162d87558826ed8fc8f2352800bf674ddf0.zip
add InputEvents which unify keyboard, mouse, and controller input with more metadata (#316)
Diffstat (limited to 'src')
-rw-r--r--src/StardewModdingAPI/Events/EventArgsInput.cs38
-rw-r--r--src/StardewModdingAPI/Events/InputEvents.cs45
-rw-r--r--src/StardewModdingAPI/Framework/CursorPosition.cs37
-rw-r--r--src/StardewModdingAPI/Framework/SGame.cs268
-rw-r--r--src/StardewModdingAPI/ICursorPosition.cs19
-rw-r--r--src/StardewModdingAPI/StardewModdingAPI.csproj5
-rw-r--r--src/StardewModdingAPI/Utilities/SButton.cs659
7 files changed, 928 insertions, 143 deletions
diff --git a/src/StardewModdingAPI/Events/EventArgsInput.cs b/src/StardewModdingAPI/Events/EventArgsInput.cs
new file mode 100644
index 00000000..1d5e6fde
--- /dev/null
+++ b/src/StardewModdingAPI/Events/EventArgsInput.cs
@@ -0,0 +1,38 @@
+#if SMAPI_2_0
+using System;
+using StardewModdingAPI.Utilities;
+
+namespace StardewModdingAPI.Events
+{
+ /// <summary>Event arguments when a button is pressed or released.</summary>
+ public class EventArgsInput : EventArgs
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The button on the controller, keyboard, or mouse.</summary>
+ public SButton Button { get; }
+
+ /// <summary>The current cursor position.</summary>
+ public ICursorPosition Cursor { get; set; }
+
+ /// <summary>Whether the input is considered a 'click' by the game for enabling action.</summary>
+ public bool IsClick { get; }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance.</summary>
+ /// <param name="button">The button on the controller, keyboard, or mouse.</param>
+ /// <param name="cursor">The cursor position.</param>
+ /// <param name="isClick">Whether the input is considered a 'click' by the game for enabling action.</param>
+ public EventArgsInput(SButton button, ICursorPosition cursor, bool isClick)
+ {
+ this.Button = button;
+ this.Cursor = cursor;
+ this.IsClick = isClick;
+ }
+ }
+}
+#endif
diff --git a/src/StardewModdingAPI/Events/InputEvents.cs b/src/StardewModdingAPI/Events/InputEvents.cs
new file mode 100644
index 00000000..285487af
--- /dev/null
+++ b/src/StardewModdingAPI/Events/InputEvents.cs
@@ -0,0 +1,45 @@
+#if SMAPI_2_0
+using System;
+using StardewModdingAPI.Framework;
+using StardewModdingAPI.Utilities;
+
+namespace StardewModdingAPI.Events
+{
+ /// <summary>Events raised when the player uses a controller, keyboard, or mouse button.</summary>
+ public static class InputEvents
+ {
+ /*********
+ ** Events
+ *********/
+ /// <summary>Raised when the player presses a button on the keyboard, controller, or mouse.</summary>
+ public static event EventHandler<EventArgsInput> ButtonPressed;
+
+ /// <summary>Raised when the player releases a keyboard key on the keyboard, controller, or mouse.</summary>
+ public static event EventHandler<EventArgsInput> ButtonReleased;
+
+
+ /*********
+ ** Internal methods
+ *********/
+ /// <summary>Raise a <see cref="ButtonPressed"/> event.</summary>
+ /// <param name="monitor">Encapsulates monitoring and logging.</param>
+ /// <param name="button">The button on the controller, keyboard, or mouse.</param>
+ /// <param name="cursor">The cursor position.</param>
+ /// <param name="isClick">Whether the input is considered a 'click' by the game for enabling action.</param>
+ internal static void InvokeButtonPressed(IMonitor monitor, SButton button, ICursorPosition cursor, bool isClick)
+ {
+ monitor.SafelyRaiseGenericEvent($"{nameof(InputEvents)}.{nameof(InputEvents.ButtonPressed)}", InputEvents.ButtonPressed?.GetInvocationList(), null, new EventArgsInput(button, cursor, isClick));
+ }
+
+ /// <summary>Raise a <see cref="ButtonReleased"/> event.</summary>
+ /// <param name="monitor">Encapsulates monitoring and logging.</param>
+ /// <param name="button">The button on the controller, keyboard, or mouse.</param>
+ /// <param name="cursor">The cursor position.</param>
+ /// <param name="isClick">Whether the input is considered a 'click' by the game for enabling action.</param>
+ internal static void InvokeButtonReleased(IMonitor monitor, SButton button, ICursorPosition cursor, bool isClick)
+ {
+ monitor.SafelyRaiseGenericEvent($"{nameof(InputEvents)}.{nameof(InputEvents.ButtonReleased)}", InputEvents.ButtonReleased?.GetInvocationList(), null, new EventArgsInput(button, cursor, isClick));
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/src/StardewModdingAPI/Framework/CursorPosition.cs b/src/StardewModdingAPI/Framework/CursorPosition.cs
new file mode 100644
index 00000000..4f256da5
--- /dev/null
+++ b/src/StardewModdingAPI/Framework/CursorPosition.cs
@@ -0,0 +1,37 @@
+#if SMAPI_2_0
+using Microsoft.Xna.Framework;
+
+namespace StardewModdingAPI.Framework
+{
+ /// <summary>Defines a position on a given map at different reference points.</summary>
+ internal class CursorPosition : ICursorPosition
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The pixel position relative to the top-left corner of the visible screen.</summary>
+ public Vector2 ScreenPixels { get; }
+
+ /// <summary>The tile position under the cursor relative to the top-left corner of the map.</summary>
+ public Vector2 Tile { get; }
+
+ /// <summary>The tile position that the game considers under the cursor for purposes of clicking actions. This may be different than <see cref="Tile"/> if that's too far from the player.</summary>
+ public Vector2 GrabTile { get; }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance.</summary>
+ /// <param name="screenPixels">The pixel position relative to the top-left corner of the visible screen.</param>
+ /// <param name="tile">The tile position relative to the top-left corner of the map.</param>
+ /// <param name="grabTile">The tile position that the game considers under the cursor for purposes of clicking actions.</param>
+ public CursorPosition(Vector2 screenPixels, Vector2 tile, Vector2 grabTile)
+ {
+ this.ScreenPixels = screenPixels;
+ this.Tile = tile;
+ this.GrabTile = grabTile;
+ }
+ }
+}
+#endif
diff --git a/src/StardewModdingAPI/Framework/SGame.cs b/src/StardewModdingAPI/Framework/SGame.cs
index 678dcf3a..f2c5c0c9 100644
--- a/src/StardewModdingAPI/Framework/SGame.cs
+++ b/src/StardewModdingAPI/Framework/SGame.cs
@@ -10,6 +10,7 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using StardewModdingAPI.Events;
+using StardewModdingAPI.Utilities;
using StardewValley;
using StardewValley.BellsAndWhistles;
using StardewValley.Locations;
@@ -59,12 +60,15 @@ namespace StardewModdingAPI.Framework
/****
** Game state
****/
- /// <summary>Arrays of pressed controller buttons indexed by <see cref="PlayerIndex"/>.</summary>
- private Buttons[] PreviousPressedButtons = new Buttons[0];
+ /// <summary>A record of the buttons pressed as of the previous tick.</summary>
+ private SButton[] PreviousPressedButtons = new SButton[0];
/// <summary>A record of the keyboard state (i.e. the up/down state for each button) as of the previous tick.</summary>
private KeyboardState PreviousKeyState;
+ /// <summary>A record of the controller state (i.e. the up/down state for each button) as of the previous tick.</summary>
+ private GamePadState PreviousControllerState;
+
/// <summary>A record of the mouse state (i.e. the cursor position, scroll amount, and the up/down state for each button) as of the previous tick.</summary>
private MouseState PreviousMouseState;
@@ -351,64 +355,95 @@ namespace StardewModdingAPI.Framework
{
// get latest state
KeyboardState keyState;
+ GamePadState controllerState;
MouseState mouseState;
Point mousePosition;
try
{
keyState = Keyboard.GetState();
+ controllerState = GamePad.GetState(PlayerIndex.One);
mouseState = Mouse.GetState();
mousePosition = new Point(Game1.getMouseX(), Game1.getMouseY());
}
catch (InvalidOperationException) // GetState() may crash for some players if window doesn't have focus but game1.IsActive == true
{
keyState = this.PreviousKeyState;
+ controllerState = this.PreviousControllerState;
mouseState = this.PreviousMouseState;
mousePosition = this.PreviousMousePosition;
}
// analyse state
- Keys[] currentlyPressedKeys = keyState.GetPressedKeys();
- Keys[] previousPressedKeys = this.PreviousKeyState.GetPressedKeys();
- Keys[] framePressedKeys = currentlyPressedKeys.Except(previousPressedKeys).ToArray();
- Keys[] frameReleasedKeys = previousPressedKeys.Except(currentlyPressedKeys).ToArray();
-
- // raise key pressed
- foreach (Keys key in framePressedKeys)
- ControlEvents.InvokeKeyPressed(this.Monitor, key);
-
- // raise key released
- foreach (Keys key in frameReleasedKeys)
- ControlEvents.InvokeKeyReleased(this.Monitor, key);
+ SButton[] currentlyPressedKeys = this.GetPressedButtons(keyState, mouseState, controllerState).ToArray();
+ SButton[] previousPressedKeys = this.PreviousPressedButtons;
+ SButton[] framePressedKeys = currentlyPressedKeys.Except(previousPressedKeys).ToArray();
+ SButton[] frameReleasedKeys = previousPressedKeys.Except(currentlyPressedKeys).ToArray();
+ bool isClick = framePressedKeys.Contains(SButton.MouseLeft) || (framePressedKeys.Contains(SButton.ControllerA) && !currentlyPressedKeys.Contains(SButton.ControllerX));
+
+ // get cursor position
+#if SMAPI_2_0
+ ICursorPosition cursor;
+ {
+ // cursor position
+ Vector2 screenPixels = new Vector2(Game1.getMouseX(), Game1.getMouseY());
+ Vector2 tile = new Vector2((Game1.viewport.X + screenPixels.X) / Game1.tileSize, (Game1.viewport.Y + screenPixels.Y) / Game1.tileSize);
+ Vector2 grabTile = (Game1.mouseCursorTransparency > 0 && Utility.tileWithinRadiusOfPlayer((int)tile.X, (int)tile.Y, 1, Game1.player)) // derived from Game1.pressActionButton
+ ? tile
+ : Game1.player.GetGrabTile();
+ cursor = new CursorPosition(screenPixels, tile, grabTile);
+ }
+#endif
- // raise controller button pressed
- foreach (Buttons button in this.GetFramePressedButtons())
+ // raise button pressed
+ foreach (SButton button in framePressedKeys)
{
- if (button == Buttons.LeftTrigger || button == Buttons.RightTrigger)
+#if SMAPI_2_0
+ InputEvents.InvokeButtonPressed(this.Monitor, button, cursor, isClick);
+#endif
+
+ // legacy events
+ if (button.TryGetKeyboard(out Keys key))
{
- var triggers = GamePad.GetState(PlayerIndex.One).Triggers;
- ControlEvents.InvokeTriggerPressed(this.Monitor, button, button == Buttons.LeftTrigger ? triggers.Left : triggers.Right);
+ if (key != Keys.None)
+ ControlEvents.InvokeKeyPressed(this.Monitor, key);
+ }
+ else if (button.TryGetController(out Buttons controllerButton))
+ {
+ if (controllerButton == Buttons.LeftTrigger || controllerButton == Buttons.RightTrigger)
+ ControlEvents.InvokeTriggerPressed(this.Monitor, controllerButton, controllerButton == Buttons.LeftTrigger ? controllerState.Triggers.Left : controllerState.Triggers.Right);
+ else
+ ControlEvents.InvokeButtonPressed(this.Monitor, controllerButton);
}
- else
- ControlEvents.InvokeButtonPressed(this.Monitor, button);
}
- // raise controller button released
- foreach (Buttons button in this.GetFrameReleasedButtons())
+ // raise button released
+ foreach (SButton button in frameReleasedKeys)
{
- if (button == Buttons.LeftTrigger || button == Buttons.RightTrigger)
+#if SMAPI_2_0
+ bool wasClick =
+ (button == SButton.MouseLeft && previousPressedKeys.Contains(SButton.MouseLeft)) // released left click
+ || (button == SButton.ControllerA && previousPressedKeys.Contains(SButton.ControllerA) && !previousPressedKeys.Contains(SButton.ControllerX));
+ InputEvents.InvokeButtonReleased(this.Monitor, button, cursor, wasClick);
+#endif
+
+ // legacy events
+ if (button.TryGetKeyboard(out Keys key))
{
- var triggers = GamePad.GetState(PlayerIndex.One).Triggers;
- ControlEvents.InvokeTriggerReleased(this.Monitor, button, button == Buttons.LeftTrigger ? triggers.Left : triggers.Right);
+ if (key != Keys.None)
+ ControlEvents.InvokeKeyReleased(this.Monitor, key);
+ }
+ else if (button.TryGetController(out Buttons controllerButton))
+ {
+ if (controllerButton == Buttons.LeftTrigger || controllerButton == Buttons.RightTrigger)
+ ControlEvents.InvokeTriggerReleased(this.Monitor, controllerButton, controllerButton == Buttons.LeftTrigger ? controllerState.Triggers.Left : controllerState.Triggers.Right);
+ else
+ ControlEvents.InvokeButtonReleased(this.Monitor, controllerButton);
}
- else
- ControlEvents.InvokeButtonReleased(this.Monitor, button);
}
- // raise keyboard state changed
+ // raise legacy state-changed events
if (keyState != this.PreviousKeyState)
ControlEvents.InvokeKeyboardChanged(this.Monitor, this.PreviousKeyState, keyState);
-
- // raise mouse state changed
if (mouseState != this.PreviousMouseState)
ControlEvents.InvokeMouseChanged(this.Monitor, this.PreviousMouseState, mouseState, this.PreviousMousePosition, mousePosition);
@@ -416,7 +451,8 @@ namespace StardewModdingAPI.Framework
this.PreviousMouseState = mouseState;
this.PreviousMousePosition = mousePosition;
this.PreviousKeyState = keyState;
- this.PreviousPressedButtons = this.GetButtonsDown();
+ this.PreviousControllerState = controllerState;
+ this.PreviousPressedButtons = currentlyPressedKeys;
}
/*********
@@ -1308,120 +1344,66 @@ namespace StardewModdingAPI.Framework
this.PreviousSaveID = 0;
}
- /// <summary>Get the controller buttons which are currently pressed.</summary>
- private Buttons[] GetButtonsDown()
+ /// <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 IEnumerable<SButton> GetPressedButtons(KeyboardState keyboard, MouseState mouse, GamePadState controller)
{
- var state = GamePad.GetState(PlayerIndex.One);
- var buttons = new List<Buttons>();
- if (state.IsConnected)
+ // 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 (state.Buttons.A == ButtonState.Pressed) buttons.Add(Buttons.A);
- if (state.Buttons.B == ButtonState.Pressed) buttons.Add(Buttons.B);
- if (state.Buttons.Back == ButtonState.Pressed) buttons.Add(Buttons.Back);
- if (state.Buttons.BigButton == ButtonState.Pressed) buttons.Add(Buttons.BigButton);
- if (state.Buttons.LeftShoulder == ButtonState.Pressed) buttons.Add(Buttons.LeftShoulder);
- if (state.Buttons.LeftStick == ButtonState.Pressed) buttons.Add(Buttons.LeftStick);
- if (state.Buttons.RightShoulder == ButtonState.Pressed) buttons.Add(Buttons.RightShoulder);
- if (state.Buttons.RightStick == ButtonState.Pressed) buttons.Add(Buttons.RightStick);
- if (state.Buttons.Start == ButtonState.Pressed) buttons.Add(Buttons.Start);
- if (state.Buttons.X == ButtonState.Pressed) buttons.Add(Buttons.X);
- if (state.Buttons.Y == ButtonState.Pressed) buttons.Add(Buttons.Y);
- if (state.DPad.Up == ButtonState.Pressed) buttons.Add(Buttons.DPadUp);
- if (state.DPad.Down == ButtonState.Pressed) buttons.Add(Buttons.DPadDown);
- if (state.DPad.Left == ButtonState.Pressed) buttons.Add(Buttons.DPadLeft);
- if (state.DPad.Right == ButtonState.Pressed) buttons.Add(Buttons.DPadRight);
- if (state.Triggers.Left > 0.2f) buttons.Add(Buttons.LeftTrigger);
- if (state.Triggers.Right > 0.2f) buttons.Add(Buttons.RightTrigger);
+ 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;
}
- return buttons.ToArray();
- }
-
- /// <summary>Get the controller buttons which were pressed after the last update.</summary>
- private Buttons[] GetFramePressedButtons()
- {
- var state = GamePad.GetState(PlayerIndex.One);
- var buttons = new List<Buttons>();
- if (state.IsConnected)
- {
- if (this.WasButtonJustPressed(Buttons.A, state.Buttons.A)) buttons.Add(Buttons.A);
- if (this.WasButtonJustPressed(Buttons.B, state.Buttons.B)) buttons.Add(Buttons.B);
- if (this.WasButtonJustPressed(Buttons.Back, state.Buttons.Back)) buttons.Add(Buttons.Back);
- if (this.WasButtonJustPressed(Buttons.BigButton, state.Buttons.BigButton)) buttons.Add(Buttons.BigButton);
- if (this.WasButtonJustPressed(Buttons.LeftShoulder, state.Buttons.LeftShoulder)) buttons.Add(Buttons.LeftShoulder);
- if (this.WasButtonJustPressed(Buttons.LeftStick, state.Buttons.LeftStick)) buttons.Add(Buttons.LeftStick);
- if (this.WasButtonJustPressed(Buttons.RightShoulder, state.Buttons.RightShoulder)) buttons.Add(Buttons.RightShoulder);
- if (this.WasButtonJustPressed(Buttons.RightStick, state.Buttons.RightStick)) buttons.Add(Buttons.RightStick);
- if (this.WasButtonJustPressed(Buttons.Start, state.Buttons.Start)) buttons.Add(Buttons.Start);
- if (this.WasButtonJustPressed(Buttons.X, state.Buttons.X)) buttons.Add(Buttons.X);
- if (this.WasButtonJustPressed(Buttons.Y, state.Buttons.Y)) buttons.Add(Buttons.Y);
- if (this.WasButtonJustPressed(Buttons.DPadUp, state.DPad.Up)) buttons.Add(Buttons.DPadUp);
- if (this.WasButtonJustPressed(Buttons.DPadDown, state.DPad.Down)) buttons.Add(Buttons.DPadDown);
- if (this.WasButtonJustPressed(Buttons.DPadLeft, state.DPad.Left)) buttons.Add(Buttons.DPadLeft);
- if (this.WasButtonJustPressed(Buttons.DPadRight, state.DPad.Right)) buttons.Add(Buttons.DPadRight);
- if (this.WasButtonJustPressed(Buttons.LeftTrigger, state.Triggers.Left)) buttons.Add(Buttons.LeftTrigger);
- if (this.WasButtonJustPressed(Buttons.RightTrigger, state.Triggers.Right)) buttons.Add(Buttons.RightTrigger);
- }
- return buttons.ToArray();
- }
-
- /// <summary>Get the controller buttons which were released after the last update.</summary>
- private Buttons[] GetFrameReleasedButtons()
- {
- var state = GamePad.GetState(PlayerIndex.One);
- var buttons = new List<Buttons>();
- if (state.IsConnected)
- {
- if (this.WasButtonJustReleased(Buttons.A, state.Buttons.A)) buttons.Add(Buttons.A);
- if (this.WasButtonJustReleased(Buttons.B, state.Buttons.B)) buttons.Add(Buttons.B);
- if (this.WasButtonJustReleased(Buttons.Back, state.Buttons.Back)) buttons.Add(Buttons.Back);
- if (this.WasButtonJustReleased(Buttons.BigButton, state.Buttons.BigButton)) buttons.Add(Buttons.BigButton);
- if (this.WasButtonJustReleased(Buttons.LeftShoulder, state.Buttons.LeftShoulder)) buttons.Add(Buttons.LeftShoulder);
- if (this.WasButtonJustReleased(Buttons.LeftStick, state.Buttons.LeftStick)) buttons.Add(Buttons.LeftStick);
- if (this.WasButtonJustReleased(Buttons.RightShoulder, state.Buttons.RightShoulder)) buttons.Add(Buttons.RightShoulder);
- if (this.WasButtonJustReleased(Buttons.RightStick, state.Buttons.RightStick)) buttons.Add(Buttons.RightStick);
- if (this.WasButtonJustReleased(Buttons.Start, state.Buttons.Start)) buttons.Add(Buttons.Start);
- if (this.WasButtonJustReleased(Buttons.X, state.Buttons.X)) buttons.Add(Buttons.X);
- if (this.WasButtonJustReleased(Buttons.Y, state.Buttons.Y)) buttons.Add(Buttons.Y);
- if (this.WasButtonJustReleased(Buttons.DPadUp, state.DPad.Up)) buttons.Add(Buttons.DPadUp);
- if (this.WasButtonJustReleased(Buttons.DPadDown, state.DPad.Down)) buttons.Add(Buttons.DPadDown);
- if (this.WasButtonJustReleased(Buttons.DPadLeft, state.DPad.Left)) buttons.Add(Buttons.DPadLeft);
- if (this.WasButtonJustReleased(Buttons.DPadRight, state.DPad.Right)) buttons.Add(Buttons.DPadRight);
- if (this.WasButtonJustReleased(Buttons.LeftTrigger, state.Triggers.Left)) buttons.Add(Buttons.LeftTrigger);
- if (this.WasButtonJustReleased(Buttons.RightTrigger, state.Triggers.Right)) buttons.Add(Buttons.RightTrigger);
- }
- return buttons.ToArray();
- }
-
- /// <summary>Get whether a controller button was pressed since the last check.</summary>
- /// <param name="button">The controller button to check.</param>
- /// <param name="buttonState">The last known state.</param>
- private bool WasButtonJustPressed(Buttons button, ButtonState buttonState)
- {
- return buttonState == ButtonState.Pressed && !this.PreviousPressedButtons.Contains(button);
- }
-
- /// <summary>Get whether a controller button was released since the last check.</summary>
- /// <param name="button">The controller button to check.</param>
- /// <param name="buttonState">The last known state.</param>
- private bool WasButtonJustReleased(Buttons button, ButtonState buttonState)
- {
- return buttonState == ButtonState.Released && this.PreviousPressedButtons.Contains(button);
- }
-
- /// <summary>Get whether an analogue controller button was pressed since the last check.</summary>
- /// <param name="button">The controller button to check.</param>
- /// <param name="value">The last known value.</param>
- private bool WasButtonJustPressed(Buttons button, float value)
- {
- return this.WasButtonJustPressed(button, value > 0.2f ? ButtonState.Pressed : ButtonState.Released);
- }
-
- /// <summary>Get whether an analogue controller button was released since the last check.</summary>
- /// <param name="button">The controller button to check.</param>
- /// <param name="value">The last known value.</param>
- private bool WasButtonJustReleased(Buttons button, float value)
- {
- return this.WasButtonJustReleased(button, value > 0.2f ? ButtonState.Pressed : ButtonState.Released);
}
/// <summary>Get the player inventory changes between two states.</summary>
diff --git a/src/StardewModdingAPI/ICursorPosition.cs b/src/StardewModdingAPI/ICursorPosition.cs
new file mode 100644
index 00000000..d03cda71
--- /dev/null
+++ b/src/StardewModdingAPI/ICursorPosition.cs
@@ -0,0 +1,19 @@
+#if SMAPI_2_0
+using Microsoft.Xna.Framework;
+
+namespace StardewModdingAPI
+{
+ /// <summary>Represents a cursor position in the different coordinate systems.</summary>
+ public interface ICursorPosition
+ {
+ /// <summary>The pixel position relative to the top-left corner of the visible screen.</summary>
+ Vector2 ScreenPixels { get; }
+
+ /// <summary>The tile position under the cursor relative to the top-left corner of the map.</summary>
+ Vector2 Tile { get; }
+
+ /// <summary>The tile position that the game considers under the cursor for purposes of clicking actions. This may be different than <see cref="Tile"/> if that's too far from the player.</summary>
+ Vector2 GrabTile { get; }
+ }
+}
+#endif
diff --git a/src/StardewModdingAPI/StardewModdingAPI.csproj b/src/StardewModdingAPI/StardewModdingAPI.csproj
index bf1c43d1..c442cc8a 100644
--- a/src/StardewModdingAPI/StardewModdingAPI.csproj
+++ b/src/StardewModdingAPI/StardewModdingAPI.csproj
@@ -93,7 +93,9 @@
<Compile Include="Command.cs" />
<Compile Include="ContentSource.cs" />
<Compile Include="Events\ContentEvents.cs" />
+ <Compile Include="Events\EventArgsInput.cs" />
<Compile Include="Events\EventArgsValueChanged.cs" />
+ <Compile Include="Events\InputEvents.cs" />
<Compile Include="Framework\Content\AssetInfo.cs" />
<Compile Include="Framework\Exceptions\SContentLoadException.cs" />
<Compile Include="Framework\Command.cs" />
@@ -207,7 +209,10 @@
<Compile Include="IReflectionHelper.cs" />
<Compile Include="SemanticVersion.cs" />
<Compile Include="Translation.cs" />
+ <Compile Include="ICursorPosition.cs" />
<Compile Include="Utilities\SDate.cs" />
+ <Compile Include="Utilities\SButton.cs" />
+ <Compile Include="Framework\CursorPosition.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config">
diff --git a/src/StardewModdingAPI/Utilities/SButton.cs b/src/StardewModdingAPI/Utilities/SButton.cs
new file mode 100644
index 00000000..f4fccfff
--- /dev/null
+++ b/src/StardewModdingAPI/Utilities/SButton.cs
@@ -0,0 +1,659 @@
+using System;
+using Microsoft.Xna.Framework.Input;
+
+namespace StardewModdingAPI.Utilities
+{
+ /// <summary>A unified button constant which includes all controller, keyboard, and mouse buttons.</summary>
+ /// <remarks>Derived from <see cref="Keys"/>, <see cref="Buttons"/>, and <see cref="System.Windows.Forms.MouseButtons"/>.</remarks>
+#if SMAPI_2_0
+ public
+#else
+ internal
+#endif
+ enum SButton
+ {
+ /// <summary>No valid key.</summary>
+ None = 0,
+
+ /*********
+ ** Mouse
+ *********/
+ /// <summary>The left mouse button.</summary>
+ MouseLeft = 1000,
+
+ /// <summary>The right mouse button.</summary>
+ MouseRight = 1001,
+
+ /// <summary>The middle mouse button.</summary>
+ MouseMiddle = 1002,
+
+ /// <summary>The first mouse XButton.</summary>
+ MouseX1 = 1003,
+
+ /// <summary>The second mouse XButton.</summary>
+ MouseX2 = 1004,
+
+ /*********
+ ** Controller
+ *********/
+ /// <summary>The 'A' button on a controller.</summary>
+ ControllerA = SButtonExtensions.ControllerOffset + Buttons.A,
+
+ /// <summary>The 'B' button on a controller.</summary>
+ ControllerB = SButtonExtensions.ControllerOffset + Buttons.B,
+
+ /// <summary>The 'X' button on a controller.</summary>
+ ControllerX = SButtonExtensions.ControllerOffset + Buttons.X,
+
+ /// <summary>The 'Y' button on a controller.</summary>
+ ControllerY = SButtonExtensions.ControllerOffset + Buttons.Y,
+
+ /// <summary>The back button on a controller.</summary>
+ ControllerBack = SButtonExtensions.ControllerOffset + Buttons.Back,
+
+ /// <summary>The start button on a controller.</summary>
+ ControllerStart = SButtonExtensions.ControllerOffset + Buttons.Start,
+
+ /// <summary>The up button on the directional pad of a controller.</summary>
+ DPadUp = SButtonExtensions.ControllerOffset + Buttons.DPadUp,
+
+ /// <summary>The down button on the directional pad of a controller.</summary>
+ DPadDown = SButtonExtensions.ControllerOffset + Buttons.DPadDown,
+
+ /// <summary>The left button on the directional pad of a controller.</summary>
+ DPadLeft = SButtonExtensions.ControllerOffset + Buttons.DPadLeft,
+
+ /// <summary>The right button on the directional pad of a controller.</summary>
+ DPadRight = SButtonExtensions.ControllerOffset + Buttons.DPadRight,
+
+ /// <summary>The left bumper (shoulder) button on a controller.</summary>
+ LeftShoulder = SButtonExtensions.ControllerOffset + Buttons.LeftShoulder,
+
+ /// <summary>The right bumper (shoulder) button on a controller.</summary>
+ RightShoulder = SButtonExtensions.ControllerOffset + Buttons.RightShoulder,
+
+ /// <summary>The left trigger on a controller.</summary>
+ LeftTrigger = SButtonExtensions.ControllerOffset + Buttons.LeftTrigger,
+
+ /// <summary>The right trigger on a controller.</summary>
+ RightTrigger = SButtonExtensions.ControllerOffset + Buttons.RightTrigger,
+
+ /// <summary>The left analog stick on a controller (when pressed).</summary>
+ LeftStick = SButtonExtensions.ControllerOffset + Buttons.LeftStick,
+
+ /// <summary>The right analog stick on a controller (when pressed).</summary>
+ RightStick = SButtonExtensions.ControllerOffset + Buttons.RightStick,
+
+ /// <summary>The 'big button' on a controller.</summary>
+ BigButton = SButtonExtensions.ControllerOffset + Buttons.BigButton,
+
+ /// <summary>The left analog stick on a controller (when pushed left).</summary>
+ LeftThumbstickLeft = SButtonExtensions.ControllerOffset + Buttons.LeftThumbstickLeft,
+
+ /// <summary>The left analog stick on a controller (when pushed right).</summary>
+ LeftThumbstickRight = SButtonExtensions.ControllerOffset + Buttons.LeftThumbstickRight,
+
+ /// <summary>The left analog stick on a controller (when pushed down).</summary>
+ LeftThumbstickDown = SButtonExtensions.ControllerOffset + Buttons.LeftThumbstickDown,
+
+ /// <summary>The left analog stick on a controller (when pushed up).</summary>
+ LeftThumbstickUp = SButtonExtensions.ControllerOffset + Buttons.LeftThumbstickUp,
+
+ /// <summary>The right analog stick on a controller (when pushed left).</summary>
+ RightThumbstickLeft = SButtonExtensions.ControllerOffset + Buttons.RightThumbstickLeft,
+
+ /// <summary>The right analog stick on a controller (when pushed right).</summary>
+ RightThumbstickRight = SButtonExtensions.ControllerOffset + Buttons.RightThumbstickRight,
+
+ /// <summary>The right analog stick on a controller (when pushed down).</summary>
+ RightThumbstickDown = SButtonExtensions.ControllerOffset + Buttons.RightThumbstickDown,
+
+ /// <summary>The right analog stick on a controller (when pushed up).</summary>
+ RightThumbstickUp = SButtonExtensions.ControllerOffset + Buttons.RightThumbstickUp,
+
+ /*********
+ ** Keyboard
+ *********/
+ /// <summary>The A button on a keyboard.</summary>
+ A = Keys.A,
+
+ /// <summary>The Add button on a keyboard.</summary>
+ Add = Keys.Add,
+
+ /// <summary>The Applications button on a keyboard.</summary>
+ Apps = Keys.Apps,
+
+ /// <summary>The Attn button on a keyboard.</summary>
+ Attn = Keys.Attn,
+
+ /// <summary>The B button on a keyboard.</summary>
+ B = Keys.B,
+
+ /// <summary>The Backspace button on a keyboard.</summary>
+ Back = Keys.Back,
+
+ /// <summary>The Browser Back button on a keyboard in Windows 2000/XP.</summary>
+ BrowserBack = Keys.BrowserBack,
+
+ /// <summary>The Browser Favorites button on a keyboard in Windows 2000/XP.</summary>
+ BrowserFavorites = Keys.BrowserFavorites,
+
+ /// <summary>The Browser Favorites button on a keyboard in Windows 2000/XP.</summary>
+ BrowserForward = Keys.BrowserForward,
+
+ /// <summary>The Browser Home button on a keyboard in Windows 2000/XP.</summary>
+ BrowserHome = Keys.BrowserHome,
+
+ /// <summary>The Browser Refresh button on a keyboard in Windows 2000/XP.</summary>
+ BrowserRefresh = Keys.BrowserRefresh,
+
+ /// <summary>The Browser Search button on a keyboard in Windows 2000/XP.</summary>
+ BrowserSearch = Keys.BrowserSearch,
+
+ /// <summary>The Browser Stop button on a keyboard in Windows 2000/XP.</summary>
+ BrowserStop = Keys.BrowserStop,
+
+ /// <summary>The C button on a keyboard.</summary>
+ C = Keys.C,
+
+ /// <summary>The Caps Lock button on a keyboard.</summary>
+ CapsLock = Keys.CapsLock,
+
+ /// <summary>The Green ChatPad button on a keyboard.</summary>
+ ChatPadGreen = Keys.ChatPadGreen,
+
+ /// <summary>The Orange ChatPad button on a keyboard.</summary>
+ ChatPadOrange = Keys.ChatPadOrange,
+
+ /// <summary>The CrSel button on a keyboard.</summary>
+ Crsel = Keys.Crsel,
+
+ /// <summary>The D button on a keyboard.</summary>
+ D = Keys.D,
+
+ /// <summary>A miscellaneous button on a keyboard; can vary by keyboard.</summary>
+ D0 = Keys.D0,
+
+ /// <summary>A miscellaneous button on a keyboard; can vary by keyboard.</summary>
+ D1 = Keys.D1,
+
+ /// <summary>A miscellaneous button on a keyboard; can vary by keyboard.</summary>
+ D2 = Keys.D2,
+
+ /// <summary>A miscellaneous button on a keyboard; can vary by keyboard.</summary>
+ D3 = Keys.D3,
+
+ /// <summary>A miscellaneous button on a keyboard; can vary by keyboard.</summary>
+ D4 = Keys.D4,
+
+ /// <summary>A miscellaneous button on a keyboard; can vary by keyboard.</summary>
+ D5 = Keys.D5,
+
+ /// <summary>A miscellaneous button on a keyboard; can vary by keyboard.</summary>
+ D6 = Keys.D6,
+
+ /// <summary>A miscellaneous button on a keyboard; can vary by keyboard.</summary>
+ D7 = Keys.D7,
+
+ /// <summary>A miscellaneous button on a keyboard; can vary by keyboard.</summary>
+ D8 = Keys.D8,
+
+ /// <summary>A miscellaneous button on a keyboard; can vary by keyboard.</summary>
+ D9 = Keys.D9,
+
+ /// <summary>The Decimal button on a keyboard.</summary>
+ Decimal = Keys.Decimal,
+
+ /// <summary>The Delete button on a keyboard.</summary>
+ Delete = Keys.Delete,
+
+ /// <summary>The Divide button on a keyboard.</summary>
+ Divide = Keys.Divide,
+
+ /// <summary>The Down arrow button on a keyboard.</summary>
+ Down = Keys.Down,
+
+ /// <summary>The E button on a keyboard.</summary>
+ E = Keys.E,
+
+ /// <summary>The End button on a keyboard.</summary>
+ End = Keys.End,
+
+ /// <summary>The Enter button on a keyboard.</summary>
+ Enter = Keys.Enter,
+
+ /// <summary>The Erase EOF button on a keyboard.</summary>
+ EraseEof = Keys.EraseEof,
+
+ /// <summary>The Escape button on a keyboard.</summary>
+ Escape = Keys.Escape,
+
+ /// <summary>The Execute button on a keyboard.</summary>
+ Execute = Keys.Execute,
+
+ /// <summary>The ExSel button on a keyboard.</summary>
+ Exsel = Keys.Exsel,
+
+ /// <summary>The F button on a keyboard.</summary>
+ F = Keys.F,
+
+ /// <summary>The F1 button on a keyboard.</summary>
+ F1 = Keys.F1,
+
+ /// <summary>The F10 button on a keyboard.</summary>
+ F10 = Keys.F10,
+
+ /// <summary>The F11 button on a keyboard.</summary>
+ F11 = Keys.F11,
+
+ /// <summary>The F12 button on a keyboard.</summary>
+ F12 = Keys.F12,
+
+ /// <summary>The F13 button on a keyboard.</summary>
+ F13 = Keys.F13,
+
+ /// <summary>The F14 button on a keyboard.</summary>
+ F14 = Keys.F14,
+
+ /// <summary>The F15 button on a keyboard.</summary>
+ F15 = Keys.F15,
+
+ /// <summary>The F16 button on a keyboard.</summary>
+ F16 = Keys.F16,
+
+ /// <summary>The F17 button on a keyboard.</summary>
+ F17 = Keys.F17,
+
+ /// <summary>The F18 button on a keyboard.</summary>
+ F18 = Keys.F18,
+
+ /// <summary>The F19 button on a keyboard.</summary>
+ F19 = Keys.F19,
+
+ /// <summary>The F2 button on a keyboard.</summary>
+ F2 = Keys.F2,
+
+ /// <summary>The F20 button on a keyboard.</summary>
+ F20 = Keys.F20,
+
+ /// <summary>The F21 button on a keyboard.</summary>
+ F21 = Keys.F21,
+
+ /// <summary>The F22 button on a keyboard.</summary>
+ F22 = Keys.F22,
+
+ /// <summary>The F23 button on a keyboard.</summary>
+ F23 = Keys.F23,
+
+ /// <summary>The F24 button on a keyboard.</summary>
+ F24 = Keys.F24,
+
+ /// <summary>The F3 button on a keyboard.</summary>
+ F3 = Keys.F3,
+
+ /// <summary>The F4 button on a keyboard.</summary>
+ F4 = Keys.F4,
+
+ /// <summary>The F5 button on a keyboard.</summary>
+ F5 = Keys.F5,
+
+ /// <summary>The F6 button on a keyboard.</summary>
+ F6 = Keys.F6,
+
+ /// <summary>The F7 button on a keyboard.</summary>
+ F7 = Keys.F7,
+
+ /// <summary>The F8 button on a keyboard.</summary>
+ F8 = Keys.F8,
+
+ /// <summary>The F9 button on a keyboard.</summary>
+ F9 = Keys.F9,
+
+ /// <summary>The G button on a keyboard.</summary>
+ G = Keys.G,
+
+ /// <summary>The H button on a keyboard.</summary>
+ H = Keys.H,
+
+ /// <summary>The Help button on a keyboard.</summary>
+ Help = Keys.Help,
+
+ /// <summary>The Home button on a keyboard.</summary>
+ Home = Keys.Home,
+
+ /// <summary>The I button on a keyboard.</summary>
+ I = Keys.I,
+
+ /// <summary>The IME Convert button on a keyboard.</summary>
+ ImeConvert = Keys.ImeConvert,
+
+ /// <summary>The IME NoConvert button on a keyboard.</summary>
+ ImeNoConvert = Keys.ImeNoConvert,
+
+ /// <summary>The INS button on a keyboard.</summary>
+ Insert = Keys.Insert,
+
+ /// <summary>The J button on a keyboard.</summary>
+ J = Keys.J,
+
+ /// <summary>The K button on a keyboard.</summary>
+ K = Keys.K,
+
+ /// <summary>The Kana button on a Japanese keyboard.</summary>
+ Kana = Keys.Kana,
+
+ /// <summary>The Kanji button on a Japanese keyboard.</summary>
+ Kanji = Keys.Kanji,
+
+ /// <summary>The L button on a keyboard.</summary>
+ L = Keys.L,
+
+ /// <summary>The Start Applications 1 button on a keyboard in Windows 2000/XP.</summary>
+ LaunchApplication1 = Keys.LaunchApplication1,
+
+ /// <summary>The Start Applications 2 button on a keyboard in Windows 2000/XP.</summary>
+ LaunchApplication2 = Keys.LaunchApplication2,
+
+ /// <summary>The Start Mail button on a keyboard in Windows 2000/XP.</summary>
+ LaunchMail = Keys.LaunchMail,
+
+ /// <summary>The Left arrow button on a keyboard.</summary>
+ Left = Keys.Left,
+
+ /// <summary>The Left Alt button on a keyboard.</summary>
+ LeftAlt = Keys.LeftAlt,
+
+ /// <summary>The Left Control button on a keyboard.</summary>
+ LeftControl = Keys.LeftControl,
+
+ /// <summary>The Left Shift button on a keyboard.</summary>
+ LeftShift = Keys.LeftShift,
+
+ /// <summary>The Left Windows button on a keyboard.</summary>
+ LeftWindows = Keys.LeftWindows,
+
+ /// <summary>The M button on a keyboard.</summary>
+ M = Keys.M,
+
+ /// <summary>The MediaNextTrack button on a keyboard in Windows 2000/XP.</summary>
+ MediaNextTrack = Keys.MediaNextTrack,
+
+ /// <summary>The MediaPlayPause button on a keyboard in Windows 2000/XP.</summary>
+ MediaPlayPause = Keys.MediaPlayPause,
+
+ /// <summary>The MediaPreviousTrack button on a keyboard in Windows 2000/XP.</summary>
+ MediaPreviousTrack = Keys.MediaPreviousTrack,
+
+ /// <summary>The MediaStop button on a keyboard in Windows 2000/XP.</summary>
+ MediaStop = Keys.MediaStop,
+
+ /// <summary>The Multiply button on a keyboard.</summary>
+ Multiply = Keys.Multiply,
+
+ /// <summary>The N button on a keyboard.</summary>
+ N = Keys.N,
+
+ /// <summary>The Num Lock button on a keyboard.</summary>
+ NumLock = Keys.NumLock,
+
+ /// <summary>The Numeric keypad 0 button on a keyboard.</summary>
+ NumPad0 = Keys.NumPad0,
+
+ /// <summary>The Numeric keypad 1 button on a keyboard.</summary>
+ NumPad1 = Keys.NumPad1,
+
+ /// <summary>The Numeric keypad 2 button on a keyboard.</summary>
+ NumPad2 = Keys.NumPad2,
+
+ /// <summary>The Numeric keypad 3 button on a keyboard.</summary>
+ NumPad3 = Keys.NumPad3,
+
+ /// <summary>The Numeric keypad 4 button on a keyboard.</summary>
+ NumPad4 = Keys.NumPad4,
+
+ /// <summary>The Numeric keypad 5 button on a keyboard.</summary>
+ NumPad5 = Keys.NumPad5,
+
+ /// <summary>The Numeric keypad 6 button on a keyboard.</summary>
+ NumPad6 = Keys.NumPad6,
+
+ /// <summary>The Numeric keypad 7 button on a keyboard.</summary>
+ NumPad7 = Keys.NumPad7,
+
+ /// <summary>The Numeric keypad 8 button on a keyboard.</summary>
+ NumPad8 = Keys.NumPad8,
+
+ /// <summary>The Numeric keypad 9 button on a keyboard.</summary>
+ NumPad9 = Keys.NumPad9,
+
+ /// <summary>The O button on a keyboard.</summary>
+ O = Keys.O,
+
+ /// <summary>A miscellaneous button on a keyboard; can vary by keyboard.</summary>
+ Oem8 = Keys.Oem8,
+
+ /// <summary>The OEM Auto button on a keyboard.</summary>
+ OemAuto = Keys.OemAuto,
+
+ /// <summary>The OEM Angle Bracket or Backslash button on the RT 102 keyboard in Windows 2000/XP.</summary>
+ OemBackslash = Keys.OemBackslash,
+
+ /// <summary>The Clear button on a keyboard.</summary>
+ OemClear = Keys.OemClear,
+
+ /// <summary>The OEM Close Bracket button on a US standard keyboard in Windows 2000/XP.</summary>
+ OemCloseBrackets = Keys.OemCloseBrackets,
+
+ /// <summary>The ',' button on a keyboard in any country/region in Windows 2000/XP.</summary>
+ OemComma = Keys.OemComma,
+
+ /// <summary>The OEM Copy button on a keyboard.</summary>
+ OemCopy = Keys.OemCopy,
+
+ /// <summary>The OEM Enlarge Window button on a keyboard.</summary>
+ OemEnlW = Keys.OemEnlW,
+
+ /// <summary>The '-' button on a keyboard in any country/region in Windows 2000/XP.</summary>
+ OemMinus = Keys.OemMinus,
+
+ /// <summary>The OEM Open Bracket button on a US standard keyboard in Windows 2000/XP.</summary>
+ OemOpenBrackets = Keys.OemOpenBrackets,
+
+ /// <summary>The '.' button on a keyboard in any country/region.</summary>
+ OemPeriod = Keys.OemPeriod,
+
+ /// <summary>The OEM Pipe button on a US standard keyboard.</summary>
+ OemPipe = Keys.OemPipe,
+
+ /// <summary>The '+' button on a keyboard in Windows 2000/XP.</summary>
+ OemPlus = Keys.OemPlus,
+
+ /// <summary>The OEM Question Mark button on a US standard keyboard.</summary>
+ OemQuestion = Keys.OemQuestion,
+
+ /// <summary>The OEM Single/Double Quote button on a US standard keyboard.</summary>
+ OemQuotes = Keys.OemQuotes,
+
+ /// <summary>The OEM Semicolon button on a US standard keyboard.</summary>
+ OemSemicolon = Keys.OemSemicolon,
+
+ /// <summary>The OEM Tilde button on a US standard keyboard.</summary>
+ OemTilde = Keys.OemTilde,
+
+ /// <summary>The P button on a keyboard.</summary>
+ P = Keys.P,
+
+ /// <summary>The PA1 button on a keyboard.</summary>
+ Pa1 = Keys.Pa1,
+
+ /// <summary>The Page Down button on a keyboard.</summary>
+ PageDown = Keys.PageDown,
+
+ /// <summary>The Page Up button on a keyboard.</summary>
+ PageUp = Keys.PageUp,
+
+ /// <summary>The Pause button on a keyboard.</summary>
+ Pause = Keys.Pause,
+
+ /// <summary>The Play button on a keyboard.</summary>
+ Play = Keys.Play,
+
+ /// <summary>The Print button on a keyboard.</summary>
+ Print = Keys.Print,
+
+ /// <summary>The Print Screen button on a keyboard.</summary>
+ PrintScreen = Keys.PrintScreen,
+
+ /// <summary>The IME Process button on a keyboard in Windows 95/98/ME/NT 4.0/2000/XP.</summary>
+ ProcessKey = Keys.ProcessKey,
+
+ /// <summary>The Q button on a keyboard.</summary>
+ Q = Keys.Q,
+
+ /// <summary>The R button on a keyboard.</summary>
+ R = Keys.R,
+
+ /// <summary>The Right Arrow button on a keyboard.</summary>
+ Right = Keys.Right,
+
+ /// <summary>The Right Alt button on a keyboard.</summary>
+ RightAlt = Keys.RightAlt,
+
+ /// <summary>The Right Control button on a keyboard.</summary>
+ RightControl = Keys.RightControl,
+
+ /// <summary>The Right Shift button on a keyboard.</summary>
+ RightShift = Keys.RightShift,
+
+ /// <summary>The Right Windows button on a keyboard.</summary>
+ RightWindows = Keys.RightWindows,
+
+ /// <summary>The S button on a keyboard.</summary>
+ S = Keys.S,
+
+ /// <summary>The Scroll Lock button on a keyboard.</summary>
+ Scroll = Keys.Scroll,
+
+ /// <summary>The Select button on a keyboard.</summary>
+ Select = Keys.Select,
+
+ /// <summary>The Select Media button on a keyboard in Windows 2000/XP.</summary>
+ SelectMedia = Keys.SelectMedia,
+
+ /// <summary>The Separator button on a keyboard.</summary>
+ Separator = Keys.Separator,
+
+ /// <summary>The Computer Sleep button on a keyboard.</summary>
+ Sleep = Keys.Sleep,
+
+ /// <summary>The Space bar on a keyboard.</summary>
+ Space = Keys.Space,
+
+ /// <summary>The Subtract button on a keyboard.</summary>
+ Subtract = Keys.Subtract,
+
+ /// <summary>The T button on a keyboard.</summary>
+ T = Keys.T,
+
+ /// <summary>The Tab button on a keyboard.</summary>
+ Tab = Keys.Tab,
+
+ /// <summary>The U button on a keyboard.</summary>
+ U = Keys.U,
+
+ /// <summary>The Up Arrow button on a keyboard.</summary>
+ Up = Keys.Up,
+
+ /// <summary>The V button on a keyboard.</summary>
+ V = Keys.V,
+
+ /// <summary>The Volume Down button on a keyboard in Windows 2000/XP.</summary>
+ VolumeDown = Keys.VolumeDown,
+
+ /// <summary>The Volume Mute button on a keyboard in Windows 2000/XP.</summary>
+ VolumeMute = Keys.VolumeMute,
+
+ /// <summary>The Volume Up button on a keyboard in Windows 2000/XP.</summary>
+ VolumeUp = Keys.VolumeUp,
+
+ /// <summary>The W button on a keyboard.</summary>
+ W = Keys.W,
+
+ /// <summary>The X button on a keyboard.</summary>
+ X = Keys.X,
+
+ /// <summary>The Y button on a keyboard.</summary>
+ Y = Keys.Y,
+
+ /// <summary>The Z button on a keyboard.</summary>
+ Z = Keys.Z,
+
+ /// <summary>The Zoom button on a keyboard.</summary>
+ Zoom = Keys.Zoom
+ }
+
+ /// <summary>Provides extension methods for <see cref="SButton"/>.</summary>
+#if SMAPI_2_0
+ public
+#else
+ internal
+#endif
+ static class SButtonExtensions
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The offset added to <see cref="Buttons"/> values when converting them to <see cref="SButton"/> to avoid collisions with <see cref="Keys"/> values.</summary>
+ internal const int ControllerOffset = 2000;
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Get the <see cref="SButton"/> equivalent for the given button.</summary>
+ /// <param name="key">The keyboard button to convert.</param>
+ internal static SButton ToSButton(this Keys key)
+ {
+ return (SButton)key;
+ }
+
+ /// <summary>Get the <see cref="SButton"/> equivalent for the given button.</summary>
+ /// <param name="key">The controller button to convert.</param>
+ internal static SButton ToSButton(this Buttons key)
+ {
+ return (SButton)(SButtonExtensions.ControllerOffset + key);
+ }
+
+ /// <summary>Get the <see cref="Keys"/> equivalent for the given button.</summary>
+ /// <param name="input">The button to convert.</param>
+ /// <param name="key">The keyboard equivalent.</param>
+ /// <returns>Returns whether the value was converted successfully.</returns>
+ public static bool TryGetKeyboard(this SButton input, out Keys key)
+ {
+ if (Enum.IsDefined(typeof(Keys), (int)input))
+ {
+ key = (Keys)input;
+ return true;
+ }
+
+ key = Keys.None;
+ return false;
+ }
+
+ /// <summary>Get the <see cref="Buttons"/> equivalent for the given button.</summary>
+ /// <param name="input">The button to convert.</param>
+ /// <param name="button">The controller equivalent.</param>
+ /// <returns>Returns whether the value was converted successfully.</returns>
+ public static bool TryGetController(this SButton input, out Buttons button)
+ {
+ if (Enum.IsDefined(typeof(Keys), (int)input - SButtonExtensions.ControllerOffset))
+ {
+ button = (Buttons)(input - SButtonExtensions.ControllerOffset);
+ return true;
+ }
+
+ button = 0;
+ return false;
+ }
+ }
+}