diff --git a/README.md b/README.md
index ab576719..ddbce14c 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ MonoGame.Extended is designed to build on top of MonoGame, but may work with XNA
- **Tile based maps** using [Tiled](http://www.mapeditor.org/) (orthogonal only in v0.3, isometric in master)
- **Bitmap fonts** using [BMFont](http://www.angelcode.com/products/bmfont/)
- **[Sprites](http://dylanwilson.net/sprites-and-spritebatch-extensions-in-monogame-extended)** (with SpriteBatch extensions!)
-- **Input listeners** for event driven input handling (Keyboard, Mouse, Touch)
+- **Input listeners** for event driven input handling (Keyboard, Mouse, Touch) (GamePad in master)
- **Texture Atlases** using the JSON format in [TexturePacker](https://www.codeandweb.com/texturepacker)
- **2D Camera** with pan, zoom, and rotation
- **Viewport Adapters** for resolution independent rendering
diff --git a/Source/MonoGame.Extended/InputListeners/GamePadEventArgs.cs b/Source/MonoGame.Extended/InputListeners/GamePadEventArgs.cs
new file mode 100644
index 00000000..ced422ee
--- /dev/null
+++ b/Source/MonoGame.Extended/InputListeners/GamePadEventArgs.cs
@@ -0,0 +1,62 @@
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Input;
+
+namespace MonoGame.Extended.InputListeners
+{
+ ///
+ /// This class contains all information resulting from events fired by
+ /// .
+ ///
+ public class GamePadEventArgs : EventArgs
+ {
+ internal GamePadEventArgs(GamePadState previousState, GamePadState currentState,
+ TimeSpan elapsedTime, PlayerIndex playerIndex, Buttons? button = null,
+ float triggerState = 0, Vector2? thumbStickState = null)
+ {
+ PlayerIndex = playerIndex;
+ PreviousState = previousState;
+ CurrentState = currentState;
+ ElapsedTime = elapsedTime;
+ if (button != null)
+ Button = button.Value;
+ TriggerState = triggerState;
+ ThumbStickState = thumbStickState ?? Vector2.Zero;
+ }
+
+ ///
+ /// The index of the controller.
+ ///
+ public PlayerIndex PlayerIndex { get; private set; }
+
+ ///
+ /// The state of the controller in the previous update.
+ ///
+ public GamePadState PreviousState { get; private set; }
+
+ ///
+ /// The state of the controller in this update.
+ ///
+ public GamePadState CurrentState { get; private set; }
+
+ ///
+ /// The button that triggered this event, if appliable.
+ ///
+ public Buttons Button { get; private set; }
+
+ ///
+ /// The time elapsed since last event.
+ ///
+ public TimeSpan ElapsedTime { get; private set; }
+
+ ///
+ /// If a TriggerMoved event, displays the responsible trigger's position.
+ ///
+ public float TriggerState { get; private set; }
+
+ ///
+ /// If a ThumbStickMoved event, displays the responsible stick's position.
+ ///
+ public Vector2 ThumbStickState { get; private set; }
+ }
+}
diff --git a/Source/MonoGame.Extended/InputListeners/GamePadListener.cs b/Source/MonoGame.Extended/InputListeners/GamePadListener.cs
new file mode 100644
index 00000000..a5fc45bc
--- /dev/null
+++ b/Source/MonoGame.Extended/InputListeners/GamePadListener.cs
@@ -0,0 +1,486 @@
+using System;
+using System.Linq;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Input;
+
+namespace MonoGame.Extended.InputListeners
+{
+ ///
+ /// This is a listener that exposes several events for easier handling of gamepads.
+ /// In order to initialise it, call the method
+ /// with a object.
+ ///
+ public class GamePadListener : InputListener
+ {
+ internal GamePadListener(GamePadListenerSettings settings)
+ {
+ PlayerIndex = settings.PlayerIndex;
+ VibrationEnabled = settings.VibrationEnabled;
+ VibrationStrengthLeft = settings.VibrationStrengthLeft;
+ VibrationStrengthRight = settings.VibrationStrengthRight;
+ ThumbStickDeltaTreshold = settings.ThumbStickDeltaTreshold;
+ ThumbstickDownTreshold = settings.ThumbstickDownTreshold;
+ TriggerDeltaTreshold = settings.TriggerDeltaTreshold;
+ TriggerDownTreshold = settings.TriggerDownTreshold;
+ RepeatInitialDelay = settings.RepeatInitialDelay;
+ RepeatDelay = settings.RepeatDelay;
+
+ _previousGameTime = new GameTime();
+ _previousState = GamePadState.Default;
+ }
+
+ #region events
+
+ ///
+ /// This event fires whenever a controller connects or disconnects. In order
+ /// for it to work, the property must
+ /// be set to true.
+ ///
+ public static event EventHandler ControllerConnectionChanged;
+
+ ///
+ /// This event fires whenever a button changes from the Up
+ /// to the Down state.
+ ///
+ public event EventHandler ButtonDown;
+
+ ///
+ /// This event fires whenever a button changes from the Down
+ /// to the Up state.
+ ///
+ public event EventHandler ButtonUp;
+
+ ///
+ /// This event fires repeatedly whenever a button is held sufficiently
+ /// long. Use this for things like menu navigation.
+ ///
+ public event EventHandler ButtonRepeated;
+
+ ///
+ /// This event fires whenever a thumbstick changes position.
+ /// The parameter governing the sensitivity of this functionality
+ /// is .
+ ///
+ public event EventHandler ThumbStickMoved;
+
+ ///
+ /// This event fires whenever a trigger changes position.
+ /// The parameter governing the sensitivity of this functionality
+ /// is .
+ ///
+ public event EventHandler TriggerMoved;
+
+ #endregion
+
+ #region public properties
+
+ ///
+ /// If set to true, the static event
+ /// will fire when any controller changes in connectivity status.
+ /// This functionality requires that you have one actively updating
+ /// .
+ ///
+ public static bool CheckControllerConnections { get; set; }
+
+ ///
+ /// The index of the controller.
+ ///
+ public PlayerIndex PlayerIndex { get; private set; }
+
+ ///
+ /// When a button is held down, the interval in which
+ /// ButtonRepeated fires. Value in milliseconds.
+ ///
+ public int RepeatDelay { get; private set; }
+
+ ///
+ /// The amount of time a button has to be held down
+ /// in order to fire ButtonRepeated the first time.
+ /// Value in milliseconds.
+ ///
+ public int RepeatInitialDelay { get; private set; }
+
+ ///
+ /// Whether vibration is enabled for this controller.
+ ///
+ public bool VibrationEnabled { get; set; }
+
+ ///
+ /// General setting for the strength of the left motor.
+ /// This motor has a slow, deep, powerful rumble.
+ /// This setting will modify all future vibrations
+ /// through this listener.
+ ///
+ public float VibrationStrengthLeft
+ {
+ get { return _vibrationStrengthLeft; }
+ // Clamp the value, just to be sure.
+ set { _vibrationStrengthLeft = MathHelper.Clamp(value, 0, 1); }
+ }
+
+ ///
+ /// General setting for the strength of the right motor.
+ /// This motor has a snappy, quick, high-pitched rumble.
+ /// This setting will modify all future vibrations
+ /// through this listener.
+ ///
+ public float VibrationStrengthRight
+ {
+ get { return _vibrationStrengthRight; }
+ // Clamp the value, just to be sure.
+ set { _vibrationStrengthRight = MathHelper.Clamp(value, 0, 1); }
+ }
+
+ ///
+ /// The treshold of movement that has to be met in order
+ /// for the listener to fire an event with the trigger's
+ /// updated position.
+ /// In essence this defines the event's
+ /// resolution.
+ /// At a value of 0 this will fire every time
+ /// the trigger's position is not 0f.
+ ///
+ public float TriggerDeltaTreshold { get; private set; }
+
+ ///
+ /// The treshold of movement that has to be met in order
+ /// for the listener to fire an event with the thumbstick's
+ /// updated position.
+ /// In essence this defines the event's
+ /// resolution.
+ /// At a value of 0 this will fire every time
+ /// the thumbstick's position is not {x:0, y:0}.
+ ///
+ public float ThumbStickDeltaTreshold { get; private set; }
+
+ ///
+ /// How deep the triggers have to be depressed in order to
+ /// register as a ButtonDown event.
+ ///
+ public float TriggerDownTreshold { get; private set; }
+
+ ///
+ /// How deep the triggers have to be depressed in order to
+ /// register as a ButtonDown event.
+ ///
+ public float ThumbstickDownTreshold { get; private set; }
+
+ #endregion
+
+ #region private fields
+ private static readonly bool[] GamePadConnections = new bool[4];
+
+ private float _vibrationStrengthLeft;
+ private float _vibrationStrengthRight;
+
+ private GamePadState _currentState;
+ private GamePadState _previousState;
+ //private int _lastPacketNumber;
+ // Implementation doesn't work, see explanation in CheckAllButtons().
+ private GameTime _gameTime;
+ private GameTime _previousGameTime;
+ private Buttons _lastButton;
+ private int _repeatedButtonTimer;
+
+ private GamePadState _lastTriggerState;
+ private GamePadState _lastThumbStickState;
+ private bool _leftTriggerDown;
+ private bool _rightTriggerDown;
+ private bool _leftStickDown;
+ private bool _rightStickDown;
+ private Buttons _lastRightStickDirection;
+ private Buttons _lastLeftStickDirection;
+
+ private float _leftCurVibrationStrength;
+ private float _rightCurVibrationStrength;
+ private TimeSpan _vibrationStart;
+ private TimeSpan _vibrationDurationLeft;
+ private TimeSpan _vibrationDurationRight;
+ private bool _leftVibrating;
+ private bool _rightVibrating;
+
+ // These buttons are not to be evaluated normally, but with the debounce filter
+ // in their respective methods.
+ private readonly Buttons[] _excludedButtons =
+ {
+ Buttons.LeftTrigger, Buttons.RightTrigger,
+ Buttons.LeftThumbstickDown, Buttons.LeftThumbstickUp, Buttons.LeftThumbstickRight, Buttons.LeftThumbstickLeft,
+ Buttons.RightThumbstickLeft, Buttons.RightThumbstickRight, Buttons.RightThumbstickUp, Buttons.RightThumbstickDown
+ };
+
+ #endregion
+
+
+ ///
+ /// Send a vibration command to the controller.
+ /// Returns true if the operation succeeded.
+ /// Motor values that are unset preserve
+ /// their current vibration strength and duration.
+ /// Note: Vibration currently only works on select platforms,
+ /// like Monogame.Windows.
+ ///
+ /// Duration of the vibration in milliseconds.
+ /// The strength of the left motor.
+ /// This motor has a slow, deep, powerful rumble.
+ /// The strength of the right motor.
+ /// This motor has a snappy, quick, high-pitched rumble.
+ /// Returns true if the operation succeeded.
+ public bool Vibrate(int durationMs, float leftStrength = float.NegativeInfinity,
+ float rightStrength = float.NegativeInfinity)
+ {
+ if (!VibrationEnabled)
+ return false;
+
+ var lstrength = MathHelper.Clamp(leftStrength, 0, 1);
+ var rstrength = MathHelper.Clamp(rightStrength, 0, 1);
+
+ if (float.IsNegativeInfinity(leftStrength))
+ lstrength = _leftCurVibrationStrength;
+ if (float.IsNegativeInfinity(rightStrength))
+ rstrength = _rightCurVibrationStrength;
+
+ var success = GamePad.SetVibration(PlayerIndex, lstrength * VibrationStrengthLeft,
+ rstrength * VibrationStrengthRight);
+ if (success)
+ {
+ _leftVibrating = true;
+ _rightVibrating = true;
+
+ if (leftStrength > 0)
+ _vibrationDurationLeft = new TimeSpan(0, 0, 0, 0, durationMs);
+ else if (lstrength > 0)
+ _vibrationDurationLeft -= _gameTime.TotalGameTime - _vibrationStart;
+ else
+ _leftVibrating = false;
+
+ if (rightStrength > 0)
+ _vibrationDurationRight = new TimeSpan(0, 0, 0, 0, durationMs);
+ else if (rstrength > 0)
+ _vibrationDurationRight -= _gameTime.TotalGameTime - _vibrationStart;
+ else
+ _rightVibrating = false;
+
+ _vibrationStart = _gameTime.TotalGameTime;
+
+ _leftCurVibrationStrength = lstrength;
+ _rightCurVibrationStrength = rstrength;
+ }
+ return success;
+ }
+
+ private void CheckAllButtons()
+ {
+ // PacketNumber only and always changes if there is a difference between GamePadStates.
+ // ...At least, that's the theory. It doesn't seem to be implemented. Disabled for now.
+ //if (_lastPacketNumber == _currentState.PacketNumber)
+ // return;
+ foreach (Buttons button in Enum.GetValues(typeof (Buttons)))
+ {
+ if (_excludedButtons.Contains(button))
+ break;
+ if (_currentState.IsButtonDown(button) && _previousState.IsButtonUp(button))
+ RaiseButtonDown(button);
+ if (_currentState.IsButtonUp(button) && _previousState.IsButtonDown(button))
+ RaiseButtonUp(button);
+ }
+
+ // Checks triggers as buttons and floats
+ CheckTriggers(s => s.Triggers.Left, Buttons.LeftTrigger);
+ CheckTriggers(s => s.Triggers.Right, Buttons.RightTrigger);
+
+ // Checks thumbsticks as vector2s
+ CheckThumbSticks(s => s.ThumbSticks.Right, Buttons.RightStick);
+ CheckThumbSticks(s => s.ThumbSticks.Left, Buttons.LeftStick);
+ }
+
+ private void CheckTriggers(Func getButtonState, Buttons button)
+ {
+ float debounce = 0.05f; // Value used to qualify a trigger as coming Up from a Down state
+ var curstate = getButtonState(_currentState);
+ bool curdown = curstate > TriggerDownTreshold;
+ bool prevdown = button == Buttons.RightTrigger ? _rightTriggerDown : _leftTriggerDown;
+
+ if (!prevdown && curdown)
+ {
+ RaiseButtonDown(button);
+ if (button == Buttons.RightTrigger)
+ _rightTriggerDown = true;
+ else
+ _leftTriggerDown = true;
+
+ }
+ else if (prevdown && curstate < debounce)
+ {
+ RaiseButtonUp(button);
+ if (button == Buttons.RightTrigger)
+ _rightTriggerDown = false;
+ else
+ _leftTriggerDown = false;
+ }
+
+ var prevstate = getButtonState(_lastTriggerState);
+ if (curstate > TriggerDeltaTreshold)
+ {
+ if (Math.Abs(prevstate - curstate) >= TriggerDeltaTreshold)
+ {
+ TriggerMoved.Raise(this, MakeArgs(button, triggerstate: curstate));
+ _lastTriggerState = _currentState;
+ }
+ }
+ else if (prevstate > TriggerDeltaTreshold)
+ {
+ TriggerMoved.Raise(this, MakeArgs(button, triggerstate: curstate));
+ _lastTriggerState = _currentState;
+ }
+ }
+
+ private void CheckThumbSticks(Func getButtonState, Buttons button)
+ {
+ const float debounce = 0.15f;
+ var curVector = getButtonState(_currentState);
+ bool curdown = curVector.Length() > ThumbstickDownTreshold;
+ bool right = button == Buttons.RightStick;
+ bool prevdown = right ? _rightStickDown : _leftStickDown;
+
+ var prevdir = button == Buttons.RightStick ? _lastRightStickDirection : _lastLeftStickDirection;
+ Buttons curdir;
+ if (curVector.Y > curVector.X)
+ {
+ if (curVector.Y > -curVector.X)
+ curdir = right ? Buttons.RightThumbstickUp : Buttons.LeftThumbstickUp;
+ else
+ curdir = right ? Buttons.RightThumbstickLeft : Buttons.LeftThumbstickLeft;
+ }
+ else
+ {
+ if (curVector.Y < -curVector.X)
+ curdir = right ? Buttons.RightThumbstickDown : Buttons.LeftThumbstickDown;
+ else
+ curdir = right ? Buttons.RightThumbstickRight : Buttons.LeftThumbstickRight;
+ }
+
+ if (!prevdown && curdown)
+ {
+ if (right)
+ _lastRightStickDirection = curdir;
+ else
+ _lastLeftStickDirection = curdir;
+
+ RaiseButtonDown(curdir);
+ if (button == Buttons.RightStick)
+ _rightStickDown = true;
+ else
+ _leftStickDown = true;
+ }
+ else if (prevdown && curVector.Length() < debounce)
+ {
+ RaiseButtonUp(prevdir);
+ if (button == Buttons.RightStick)
+ _rightStickDown = false;
+ else
+ _leftStickDown = false;
+ }
+ else if (prevdown && curdown && curdir != prevdir)
+ {
+ RaiseButtonUp(prevdir);
+ if (right)
+ _lastRightStickDirection = curdir;
+ else
+ _lastLeftStickDirection = curdir;
+ RaiseButtonDown(curdir);
+ }
+
+ var prevVector = getButtonState(_lastThumbStickState);
+ if (curVector.Length() > ThumbStickDeltaTreshold)
+ {
+ if (Vector2.Distance(curVector, prevVector) >= ThumbStickDeltaTreshold)
+ {
+ ThumbStickMoved.Raise(this, MakeArgs(button, thumbStickState: curVector));
+ _lastThumbStickState = _currentState;
+ }
+ } else if (prevVector.Length() > ThumbStickDeltaTreshold)
+ {
+ ThumbStickMoved.Raise(this, MakeArgs(button, thumbStickState: curVector));
+ _lastThumbStickState = _currentState;
+ }
+ }
+
+ internal static void CheckConnections()
+ {
+ if (!CheckControllerConnections)
+ return;
+
+ foreach (PlayerIndex index in Enum.GetValues(typeof(PlayerIndex)))
+ {
+ if (GamePad.GetState(index).IsConnected ^ GamePadConnections[(int) index]) // We need more XORs in this world
+ {
+ GamePadConnections[(int) index] = !GamePadConnections[(int) index];
+ ControllerConnectionChanged.Raise(null,
+ new GamePadEventArgs(GamePadState.Default, GamePad.GetState(index), TimeSpan.Zero, index));
+ }
+ }
+ }
+
+ private void CheckVibrate()
+ {
+ if (_leftVibrating && _vibrationStart + _vibrationDurationLeft < _gameTime.TotalGameTime)
+ Vibrate(0, leftStrength: 0);
+ if (_rightVibrating && _vibrationStart + _vibrationDurationRight < _gameTime.TotalGameTime)
+ Vibrate(0, rightStrength: 0);
+ }
+
+ internal override void Update(GameTime gameTime)
+ {
+ _gameTime = gameTime;
+ _currentState = GamePad.GetState(PlayerIndex);
+ CheckVibrate();
+ if (!_currentState.IsConnected)
+ return;
+ CheckAllButtons();
+ CheckRepeatButton();
+ //_lastPacketNumber = _currentState.PacketNumber;
+ _previousGameTime = gameTime;
+ _previousState = _currentState;
+ }
+ private GamePadEventArgs MakeArgs(Buttons? button,
+ float triggerstate = 0, Vector2? thumbStickState = null)
+ {
+ var elapsedTime = _gameTime.TotalGameTime - _previousGameTime.TotalGameTime;
+ return new GamePadEventArgs(_previousState, _currentState,
+ elapsedTime, PlayerIndex, button, triggerstate, thumbStickState);
+ }
+
+ private void RaiseButtonDown(Buttons button)
+ {
+ ButtonDown.Raise(this, MakeArgs(button));
+ ButtonRepeated.Raise(this, MakeArgs(button));
+ _lastButton = button;
+ _repeatedButtonTimer = 0;
+ }
+
+ private void RaiseButtonUp(Buttons button)
+ {
+ ButtonUp.Raise(this, MakeArgs(button));
+ _lastButton = 0;
+ }
+
+ private void CheckRepeatButton()
+ {
+ _repeatedButtonTimer += _gameTime.ElapsedGameTime.Milliseconds;
+
+ if(_repeatedButtonTimer < RepeatInitialDelay || _lastButton == 0)
+ return;
+
+ if (_repeatedButtonTimer < RepeatInitialDelay + RepeatDelay)
+ {
+ ButtonRepeated.Raise(this, MakeArgs(_lastButton));
+ _repeatedButtonTimer = RepeatDelay + RepeatInitialDelay;
+ }
+ else if (_repeatedButtonTimer > RepeatInitialDelay + RepeatDelay*2)
+ {
+ ButtonRepeated.Raise(this, MakeArgs(_lastButton));
+ _repeatedButtonTimer = RepeatDelay + RepeatInitialDelay;
+ }
+ }
+ }
+}
diff --git a/Source/MonoGame.Extended/InputListeners/GamePadListenerSettings.cs b/Source/MonoGame.Extended/InputListeners/GamePadListenerSettings.cs
new file mode 100644
index 00000000..33b53892
--- /dev/null
+++ b/Source/MonoGame.Extended/InputListeners/GamePadListenerSettings.cs
@@ -0,0 +1,121 @@
+using Microsoft.Xna.Framework;
+
+namespace MonoGame.Extended.InputListeners
+{
+ ///
+ /// This is a class that contains settings to be used to initialise a .
+ ///
+ ///
+ public class GamePadListenerSettings : InputListenerSettings
+ {
+ ///
+ /// This is a class that contains settings to be used to initialise a .
+ /// Note: There are a number of extra settings that are settable properties.
+ ///
+ /// The index of the controller the listener will be tied to.
+ /// Whether vibration is enabled on the controller.
+ /// General setting for the strength of the left motor.
+ /// This motor has a slow, deep, powerful rumble.
+ /// This setting will modify all future vibrations
+ /// through this listener.
+ /// General setting for the strength of the right motor.
+ /// This motor has a snappy, quick, high-pitched rumble.
+ /// This setting will modify all future vibrations
+ /// through this listener.
+ public GamePadListenerSettings(PlayerIndex playerIndex, bool vibrationEnabled = true,
+ float vibrationStrengthLeft = 1.0f, float vibrationStrengthRight = 1.0f)
+ {
+ PlayerIndex = playerIndex;
+ VibrationEnabled = vibrationEnabled;
+ VibrationStrengthLeft = vibrationStrengthLeft;
+ VibrationStrengthRight = vibrationStrengthRight;
+ TriggerDownTreshold = 0.15f;
+ ThumbstickDownTreshold = 0.5f;
+ RepeatInitialDelay = 500;
+ RepeatDelay = 50;
+ }
+
+ ///
+ /// The index of the controller.
+ ///
+ public PlayerIndex PlayerIndex { get; set; }
+
+ ///
+ /// When a button is held down, the interval in which
+ /// ButtonRepeated fires. Value in milliseconds.
+ ///
+ public int RepeatDelay { get; set; }
+
+ ///
+ /// The amount of time a button has to be held down
+ /// in order to fire ButtonRepeated the first time.
+ /// Value in milliseconds.
+ ///
+ public int RepeatInitialDelay { get; set; }
+
+
+ ///
+ /// Whether vibration is enabled for this controller.
+ ///
+ public bool VibrationEnabled { get; set; }
+
+ ///
+ /// General setting for the strength of the left motor.
+ /// This motor has a slow, deep, powerful rumble.
+ /// This setting will modify all future vibrations
+ /// through this listener.
+ ///
+ public float VibrationStrengthLeft { get; set; }
+
+ ///
+ /// General setting for the strength of the right motor.
+ /// This motor has a snappy, quick, high-pitched rumble.
+ /// This setting will modify all future vibrations
+ /// through this listener.
+ ///
+ public float VibrationStrengthRight { get; set; }
+
+ ///
+ /// The treshold of movement that has to be met in order
+ /// for the listener to fire an event with the trigger's
+ /// updated position.
+ /// In essence this defines the event's
+ /// resolution.
+ /// At a value of 0 this will fire every time
+ /// the trigger's position is not 0f.
+ ///
+ public float TriggerDeltaTreshold { get; set; }
+
+ ///
+ /// The treshold of movement that has to be met in order
+ /// for the listener to fire an event with the thumbstick's
+ /// updated position.
+ /// In essence this defines the event's
+ /// resolution.
+ /// At a value of 0 this will fire every time
+ /// the thumbstick's position is not {x:0, y:0}.
+ ///
+ public float ThumbStickDeltaTreshold { get; set; }
+
+ ///
+ /// How deep the triggers have to be depressed in order to
+ /// register as a ButtonDown event.
+ ///
+ public float TriggerDownTreshold { get; set; }
+
+ ///
+ /// How deep the triggers have to be depressed in order to
+ /// register as a ButtonDown event.
+ ///
+ public float ThumbstickDownTreshold { get; private set; }
+
+ internal override GamePadListener CreateListener()
+ {
+ return new GamePadListener(this);
+ }
+
+ // For internal use only. This limits the user to only having
+ // one controller.
+ internal GamePadListenerSettings() : this(PlayerIndex.One) { }
+ }
+}
diff --git a/Source/MonoGame.Extended/InputListeners/InputListenerManager.cs b/Source/MonoGame.Extended/InputListeners/InputListenerManager.cs
index 8d01f2ff..f80c46a6 100644
--- a/Source/MonoGame.Extended/InputListeners/InputListenerManager.cs
+++ b/Source/MonoGame.Extended/InputListeners/InputListenerManager.cs
@@ -62,6 +62,8 @@ namespace MonoGame.Extended.InputListeners
{
foreach (var listener in _listeners)
listener.Update(gameTime);
+
+ GamePadListener.CheckConnections();
}
}
}