summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/SGame.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Framework/SGame.cs')
-rw-r--r--src/SMAPI/Framework/SGame.cs113
1 files changed, 16 insertions, 97 deletions
diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs
index 4f5bd96b..182b90fc 100644
--- a/src/SMAPI/Framework/SGame.cs
+++ b/src/SMAPI/Framework/SGame.cs
@@ -53,6 +53,9 @@ namespace StardewModdingAPI.Framework
/// <summary>Manages SMAPI events for mods.</summary>
private readonly EventManager Events;
+ /// <summary>Manages input visible to the game.</summary>
+ private SInputState Input => (SInputState)Game1.input;
+
/// <summary>The maximum number of consecutive attempts SMAPI should make to recover from a draw error.</summary>
private readonly Countdown DrawCrashTimer = new Countdown(60); // 60 ticks = roughly one second
@@ -78,9 +81,6 @@ namespace StardewModdingAPI.Framework
/****
** Game state
****/
- /// <summary>The player input as of the previous tick.</summary>
- private InputState PreviousInput = new InputState();
-
/// <summary>The underlying watchers for convenience. These are accessible individually as separate properties.</summary>
private readonly List<IWatcher> Watchers = new List<IWatcher>();
@@ -120,9 +120,6 @@ namespace StardewModdingAPI.Framework
/// <summary>Simplifies access to private game code.</summary>
private readonly Reflector Reflection;
- /// <summary>The buttons to suppress when the game next handles input. Each button is suppressed until it's released.</summary>
- private readonly HashSet<SButton> SuppressButtons = new HashSet<SButton>();
-
/*********
** Accessors
@@ -157,7 +154,7 @@ namespace StardewModdingAPI.Framework
this.OnGameExiting = onGameExiting;
if (this.ContentCore == null) // shouldn't happen since CreateContentManager is called first, but let's init here just in case
this.ContentCore = new ContentCore(this.Content.ServiceProvider, this.Content.RootDirectory, Thread.CurrentThread.CurrentUICulture, this.Monitor, reflection);
- Game1.hooks = new SModHooks(this.UpdateControlInput);
+ Game1.input = new SInputState();
// init watchers
Game1.locations = new ObservableCollection<GameLocation>();
@@ -289,7 +286,7 @@ namespace StardewModdingAPI.Framework
if (this.FirstUpdate)
this.OnGameInitialised();
-
+
/*********
** Update context
*********/
@@ -390,16 +387,9 @@ namespace StardewModdingAPI.Framework
*********/
if (Game1.game1.IsActive)
{
- // get input state
- InputState inputState;
- try
- {
- inputState = InputState.GetState(this.PreviousInput);
- }
- catch (InvalidOperationException) // GetState() may crash for some players if window doesn't have focus but game1.IsActive == true
- {
- inputState = this.PreviousInput;
- }
+ SInputState previousInputState = this.Input.Clone();
+ SInputState inputState = this.Input;
+ inputState.TrueUpdate();
// raise events
bool isChatInput = Game1.IsChatting || (Context.IsMultiplayer && Context.IsWorldReady && Game1.activeClickableMenu == null && Game1.currentMinigame == null && inputState.IsAnyDown(Game1.options.chatButton));
@@ -425,7 +415,7 @@ namespace StardewModdingAPI.Framework
if (status == InputStatus.Pressed)
{
- this.Events.Input_ButtonPressed.Raise(new EventArgsInput(button, cursor, button.IsActionButton(), button.IsUseToolButton(), this.SuppressButtons));
+ this.Events.Input_ButtonPressed.Raise(new EventArgsInput(button, cursor, button.IsActionButton(), button.IsUseToolButton(), inputState.SuppressButtons));
// legacy events
if (button.TryGetKeyboard(out Keys key))
@@ -436,14 +426,14 @@ namespace StardewModdingAPI.Framework
else if (button.TryGetController(out Buttons controllerButton))
{
if (controllerButton == Buttons.LeftTrigger || controllerButton == Buttons.RightTrigger)
- this.Events.Control_ControllerTriggerPressed.Raise(new EventArgsControllerTriggerPressed(PlayerIndex.One, controllerButton, controllerButton == Buttons.LeftTrigger ? inputState.ControllerState.Triggers.Left : inputState.ControllerState.Triggers.Right));
+ this.Events.Control_ControllerTriggerPressed.Raise(new EventArgsControllerTriggerPressed(PlayerIndex.One, controllerButton, controllerButton == Buttons.LeftTrigger ? inputState.RealController.Triggers.Left : inputState.RealController.Triggers.Right));
else
this.Events.Control_ControllerButtonPressed.Raise(new EventArgsControllerButtonPressed(PlayerIndex.One, controllerButton));
}
}
else if (status == InputStatus.Released)
{
- this.Events.Input_ButtonReleased.Raise(new EventArgsInput(button, cursor, button.IsActionButton(), button.IsUseToolButton(), this.SuppressButtons));
+ this.Events.Input_ButtonReleased.Raise(new EventArgsInput(button, cursor, button.IsActionButton(), button.IsUseToolButton(), inputState.SuppressButtons));
// legacy events
if (button.TryGetKeyboard(out Keys key))
@@ -454,7 +444,7 @@ namespace StardewModdingAPI.Framework
else if (button.TryGetController(out Buttons controllerButton))
{
if (controllerButton == Buttons.LeftTrigger || controllerButton == Buttons.RightTrigger)
- this.Events.Control_ControllerTriggerReleased.Raise(new EventArgsControllerTriggerReleased(PlayerIndex.One, controllerButton, controllerButton == Buttons.LeftTrigger ? inputState.ControllerState.Triggers.Left : inputState.ControllerState.Triggers.Right));
+ this.Events.Control_ControllerTriggerReleased.Raise(new EventArgsControllerTriggerReleased(PlayerIndex.One, controllerButton, controllerButton == Buttons.LeftTrigger ? inputState.RealController.Triggers.Left : inputState.RealController.Triggers.Right));
else
this.Events.Control_ControllerButtonReleased.Raise(new EventArgsControllerButtonReleased(PlayerIndex.One, controllerButton));
}
@@ -462,14 +452,11 @@ namespace StardewModdingAPI.Framework
}
// raise legacy state-changed events
- if (inputState.KeyboardState != this.PreviousInput.KeyboardState)
- this.Events.Control_KeyboardChanged.Raise(new EventArgsKeyboardStateChanged(this.PreviousInput.KeyboardState, inputState.KeyboardState));
- if (inputState.MouseState != this.PreviousInput.MouseState)
- this.Events.Control_MouseChanged.Raise(new EventArgsMouseStateChanged(this.PreviousInput.MouseState, inputState.MouseState, this.PreviousInput.MousePosition, inputState.MousePosition));
+ if (inputState.RealKeyboard != previousInputState.RealKeyboard)
+ this.Events.Control_KeyboardChanged.Raise(new EventArgsKeyboardStateChanged(previousInputState.RealKeyboard, inputState.RealKeyboard));
+ if (inputState.RealMouse != previousInputState.RealMouse)
+ this.Events.Control_MouseChanged.Raise(new EventArgsMouseStateChanged(previousInputState.RealMouse, inputState.RealMouse, previousInputState.MousePosition, inputState.MousePosition));
}
-
- // track state
- this.PreviousInput = inputState;
}
/*********
@@ -624,17 +611,6 @@ namespace StardewModdingAPI.Framework
}
}
- /// <summary>Read the current input state for handling.</summary>
- /// <param name="keyboardState">The game's keyboard state for the current tick.</param>
- /// <param name="mouseState">The game's mouse state for the current tick.</param>
- /// <param name="gamePadState">The game's controller state for the current tick.</param>
- /// <param name="defaultLogic">The game's default logic.</param>
- public void UpdateControlInput(ref KeyboardState keyboardState, ref MouseState mouseState, ref GamePadState gamePadState, Action defaultLogic)
- {
- this.ApplySuppression(ref keyboardState, ref mouseState, ref gamePadState);
- defaultLogic();
- }
-
/// <summary>The method called to draw everything to the screen.</summary>
/// <param name="gameTime">A snapshot of the game timing state.</param>
protected override void Draw(GameTime gameTime)
@@ -1256,63 +1232,6 @@ namespace StardewModdingAPI.Framework
/****
** Methods
****/
- /// <summary>Apply input suppression for the given input states.</summary>
- /// <param name="keyboardState">The game's keyboard state for the current tick.</param>
- /// <param name="mouseState">The game's mouse state for the current tick.</param>
- /// <param name="gamePadState">The game's controller state for the current tick.</param>
- private void ApplySuppression(ref KeyboardState keyboardState, ref MouseState mouseState, ref GamePadState gamePadState)
- {
- // stop suppressing buttons once released
- if (this.SuppressButtons.Count != 0)
- {
- InputState inputState = new InputState(this.PreviousInput, gamePadState, keyboardState, mouseState);
- this.SuppressButtons.RemoveWhere(p => !inputState.IsDown(p));
- }
- if (this.SuppressButtons.Count == 0)
- return;
-
- // gather info
- HashSet<Keys> keyboardButtons = new HashSet<Keys>();
- HashSet<SButton> controllerButtons = new HashSet<SButton>();
- HashSet<SButton> mouseButtons = new HashSet<SButton>();
- foreach (SButton button in this.SuppressButtons)
- {
- if (button == SButton.MouseLeft || button == SButton.MouseMiddle || button == SButton.MouseRight || button == SButton.MouseX1 || button == SButton.MouseX2)
- mouseButtons.Add(button);
- else if (button.TryGetKeyboard(out Keys key))
- keyboardButtons.Add(key);
- else if (gamePadState.IsConnected && button.TryGetController(out Buttons _))
- controllerButtons.Add(button);
- }
-
- // suppress keyboard keys
- if (keyboardState.GetPressedKeys().Any() && keyboardButtons.Any())
- keyboardState = new KeyboardState(keyboardState.GetPressedKeys().Except(keyboardButtons).ToArray());
-
- // suppress controller keys
- if (gamePadState.IsConnected && controllerButtons.Any())
- {
- GamePadStateBuilder builder = new GamePadStateBuilder(gamePadState);
- builder.SuppressButtons(controllerButtons);
- gamePadState = builder.ToGamePadState();
- }
-
- // suppress mouse buttons
- if (mouseButtons.Any())
- {
- mouseState = new MouseState(
- x: mouseState.X,
- y: mouseState.Y,
- scrollWheel: mouseState.ScrollWheelValue,
- leftButton: mouseButtons.Contains(SButton.MouseLeft) ? ButtonState.Pressed : mouseState.LeftButton,
- middleButton: mouseButtons.Contains(SButton.MouseMiddle) ? ButtonState.Pressed : mouseState.MiddleButton,
- rightButton: mouseButtons.Contains(SButton.MouseRight) ? ButtonState.Pressed : mouseState.RightButton,
- xButton1: mouseButtons.Contains(SButton.MouseX1) ? ButtonState.Pressed : mouseState.XButton1,
- xButton2: mouseButtons.Contains(SButton.MouseX2) ? ButtonState.Pressed : mouseState.XButton2
- );
- }
- }
-
/// <summary>Perform any cleanup needed when the player unloads a save and returns to the title screen.</summary>
private void CleanupAfterReturnToTitle()
{