From e37ed56a433e55de6852a4f76a29e2931720939e Mon Sep 17 00:00:00 2001 From: Alessandro Proto Date: Tue, 14 Feb 2023 23:06:37 +0100 Subject: [PATCH] Add gamepad support --- Capy64/Eventing/EventEmitter.cs | 29 +++ Capy64/Eventing/Events/GamePadButtonEvent.cs | 10 + .../Eventing/Events/GamePadThumbstickEvent.cs | 11 + Capy64/Eventing/Events/GamePadTriggerEvent.cs | 10 + Capy64/Eventing/InputManager.cs | 207 ++++++++++++++++++ Capy64/Runtime/EventEmitter.cs | 40 ++++ 6 files changed, 307 insertions(+) create mode 100644 Capy64/Eventing/Events/GamePadButtonEvent.cs create mode 100644 Capy64/Eventing/Events/GamePadThumbstickEvent.cs create mode 100644 Capy64/Eventing/Events/GamePadTriggerEvent.cs diff --git a/Capy64/Eventing/EventEmitter.cs b/Capy64/Eventing/EventEmitter.cs index f07d0df..d46d41f 100644 --- a/Capy64/Eventing/EventEmitter.cs +++ b/Capy64/Eventing/EventEmitter.cs @@ -18,6 +18,11 @@ public class EventEmitter public event EventHandler OnKeyUp; public event EventHandler OnChar; + // GamePad events + public event EventHandler OnGamePadButton; + public event EventHandler OnGamePadTrigger; + public event EventHandler OnGamePadThumbstick; + // Functional events public event EventHandler OnTick; public event EventHandler OnInit; @@ -85,6 +90,30 @@ public class EventEmitter } } + public void RaiseGamePadButton(GamePadButtonEvent ev) + { + if (OnGamePadButton is not null) + { + OnGamePadButton(this, ev); + } + } + + public void RaiseGamePadTrigger(GamePadTriggerEvent ev) + { + if (OnGamePadTrigger is not null) + { + OnGamePadTrigger(this, ev); + } + } + + public void RaiseGamePadThumbstick(GamePadThumbstickEvent ev) + { + if (OnGamePadThumbstick is not null) + { + OnGamePadThumbstick(this, ev); + } + } + public void RaiseTick(TickEvent ev) { if (OnTick is not null) diff --git a/Capy64/Eventing/Events/GamePadButtonEvent.cs b/Capy64/Eventing/Events/GamePadButtonEvent.cs new file mode 100644 index 0000000..e078cc2 --- /dev/null +++ b/Capy64/Eventing/Events/GamePadButtonEvent.cs @@ -0,0 +1,10 @@ +using Microsoft.Xna.Framework.Input; +using System; + +namespace Capy64.Eventing.Events; + +public class GamePadButtonEvent : EventArgs +{ + public Buttons Button { get; set; } + public ButtonState State { get; set; } +} diff --git a/Capy64/Eventing/Events/GamePadThumbstickEvent.cs b/Capy64/Eventing/Events/GamePadThumbstickEvent.cs new file mode 100644 index 0000000..ed9f99d --- /dev/null +++ b/Capy64/Eventing/Events/GamePadThumbstickEvent.cs @@ -0,0 +1,11 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; +using System; + +namespace Capy64.Eventing.Events; + +public class GamePadThumbstickEvent : EventArgs +{ + public int Stick { get; set; } + public Vector2 Value { get; set; } +} diff --git a/Capy64/Eventing/Events/GamePadTriggerEvent.cs b/Capy64/Eventing/Events/GamePadTriggerEvent.cs new file mode 100644 index 0000000..839f1b4 --- /dev/null +++ b/Capy64/Eventing/Events/GamePadTriggerEvent.cs @@ -0,0 +1,10 @@ +using Microsoft.Xna.Framework.Input; +using System; + +namespace Capy64.Eventing.Events; + +public class GamePadTriggerEvent : EventArgs +{ + public int Trigger { get; set; } + public float Value { get; set; } +} diff --git a/Capy64/Eventing/InputManager.cs b/Capy64/Eventing/InputManager.cs index f74f286..9f756cc 100644 --- a/Capy64/Eventing/InputManager.cs +++ b/Capy64/Eventing/InputManager.cs @@ -90,6 +90,7 @@ public class InputManager { UpdateMouse(Mouse.GetState(), IsActive); UpdateKeyboard(Keyboard.GetState(), IsActive); + UpdateGamePad(GamePad.GetState(PlayerIndex.One), IsActive); } private void UpdateMouse(MouseState state, bool isActive) @@ -288,4 +289,210 @@ public class InputManager { return string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower(); } + + private GamePadState oldGamePadState = new(); + private void UpdateGamePad(GamePadState state, bool isActive) + { + if (!isActive) + return; + + if (!state.IsConnected) + return; + + var ob = oldGamePadState.Buttons; + var b = state.Buttons; + // ABXY + if (ob.A != b.A) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.A, + State = b.A, + }); + } + + if (ob.B != b.B) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.B, + State = b.B, + }); + } + + if (ob.X != b.X) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.X, + State = b.X, + }); + } + + if (ob.Y != b.Y) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.Y, + State = b.Y, + }); + } + + // Back & Start + if (ob.Back != b.Back) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.Back, + State = b.Back, + }); + } + + if (ob.Start != b.Start) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.Start, + State = b.Start, + }); + } + + // Shoulders + if (ob.LeftShoulder != b.LeftShoulder) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.LeftShoulder, + State = b.LeftShoulder, + }); + } + + if (ob.RightShoulder != b.RightShoulder) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.RightShoulder, + State = b.RightShoulder, + }); + } + + // Sticks + if (ob.LeftStick != b.LeftStick) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.LeftStick, + State = b.LeftStick, + }); + } + + if (ob.RightStick != b.RightStick) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.RightStick, + State = b.RightStick, + }); + } + + // BIG BUTTON + if (ob.BigButton != b.BigButton) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.BigButton, + State = b.BigButton, + }); + } + + // D-PAD + var od = oldGamePadState.DPad; + var d = state.DPad; + + if (od.Left != d.Left) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.DPadLeft, + State = d.Left, + }); + } + + if (od.Right != d.Right) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.DPadRight, + State = d.Right, + }); + } + + if (od.Up != d.Up) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.DPadUp, + State = d.Up, + }); + } + + if (od.Down != d.Down) + { + _eventEmitter.RaiseGamePadButton(new() + { + Button = Buttons.DPadDown, + State = d.Down, + }); + } + + // triggers + var ot = oldGamePadState.Triggers; + var t = state.Triggers; + + if (ot.Left != t.Left) + { + + _eventEmitter.RaiseGamePadTrigger(new() + { + Trigger = 1, // left + Value = t.Left, + }); + } + + if (ot.Right != t.Right) + { + + _eventEmitter.RaiseGamePadTrigger(new() + { + Trigger = 2, // right + Value = t.Right, + }); + } + + // thumbsticks + var os = oldGamePadState.ThumbSticks; + var s = state.ThumbSticks; + + if (os.Left != s.Left) + { + + _eventEmitter.RaiseGamePadThumbstick(new() + { + Stick = 1, // left + Value = s.Left, + }); + } + + if (os.Right != s.Right) + { + + _eventEmitter.RaiseGamePadThumbstick(new() + { + Stick = 2, // right + Value = s.Right, + }); + } + + oldGamePadState = state; + } } diff --git a/Capy64/Runtime/EventEmitter.cs b/Capy64/Runtime/EventEmitter.cs index b072677..568978b 100644 --- a/Capy64/Runtime/EventEmitter.cs +++ b/Capy64/Runtime/EventEmitter.cs @@ -35,6 +35,10 @@ internal class EventEmitter _eventEmitter.OnTick += OnTick; _eventEmitter.OnScreenSizeChange += OnScreenSizeChange; + + _eventEmitter.OnGamePadButton += OnGamePadButton; + _eventEmitter.OnGamePadTrigger += OnGamePadTrigger; + _eventEmitter.OnGamePadThumbstick += OnGamePadThumbstick; } public void Unregister() @@ -49,6 +53,11 @@ internal class EventEmitter _eventEmitter.OnChar -= OnChar; _eventEmitter.OnTick -= OnTick; + _eventEmitter.OnScreenSizeChange -= OnScreenSizeChange; + + _eventEmitter.OnGamePadButton -= OnGamePadButton; + _eventEmitter.OnGamePadTrigger -= OnGamePadTrigger; + _eventEmitter.OnGamePadThumbstick -= OnGamePadThumbstick; } private void OnTick(object sender, TickEvent e) @@ -189,4 +198,35 @@ internal class EventEmitter return 0; }); } + + private void OnGamePadButton(object sender, GamePadButtonEvent e) + { + _runtime.QueueEvent("gamepad_button", LK => + { + LK.PushInteger((int)e.Button); + LK.PushBoolean(e.State == ButtonState.Pressed); + return 2; + }); + } + + private void OnGamePadTrigger(object sender, GamePadTriggerEvent e) + { + _runtime.QueueEvent("gamepad_trigger", LK => + { + LK.PushInteger(e.Trigger); + LK.PushNumber(e.Value); + return 2; + }); + } + + private void OnGamePadThumbstick(object sender, GamePadThumbstickEvent e) + { + _runtime.QueueEvent("gamepad_stick", LK => + { + LK.PushInteger(e.Stick); + LK.PushNumber(e.Value.X); + LK.PushNumber(e.Value.Y); + return 2; + }); + } }