Add gamepad support

This commit is contained in:
Alessandro Proto 2023-02-14 23:06:37 +01:00
parent e3616e4ac6
commit e37ed56a43
6 changed files with 307 additions and 0 deletions

View file

@ -18,6 +18,11 @@ public class EventEmitter
public event EventHandler<KeyEvent> OnKeyUp;
public event EventHandler<CharEvent> OnChar;
// GamePad events
public event EventHandler<GamePadButtonEvent> OnGamePadButton;
public event EventHandler<GamePadTriggerEvent> OnGamePadTrigger;
public event EventHandler<GamePadThumbstickEvent> OnGamePadThumbstick;
// Functional events
public event EventHandler<TickEvent> 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)

View file

@ -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; }
}

View file

@ -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; }
}

View file

@ -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; }
}

View file

@ -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;
}
}

View file

@ -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;
});
}
}