MoonWorks/src/Input/Input.cs

183 lines
4.3 KiB
C#
Raw Normal View History

2022-02-23 05:14:32 +00:00
using SDL2;
2021-03-25 22:57:26 +00:00
using System;
2021-01-19 07:29:07 +00:00
namespace MoonWorks.Input
2021-01-19 07:29:07 +00:00
{
/// <summary>
/// The main container class for all input tracking.
/// Your Game class will automatically have a reference to this class.
/// </summary>
2022-02-23 05:14:32 +00:00
public class Inputs
{
public const int MAX_GAMEPADS = 4;
/// <summary>
/// The reference to the Keyboard input abstraction.
/// </summary>
2022-02-23 05:14:32 +00:00
public Keyboard Keyboard { get; }
/// <summary>
/// The reference to the Mouse input abstraction.
/// </summary>
2022-02-23 05:14:32 +00:00
public Mouse Mouse { get; }
Gamepad[] Gamepads;
2022-02-23 05:14:32 +00:00
public static event Action<char> TextInput;
/// <summary>
/// True if any input on any input device is active. Useful for input remapping.
/// </summary>
2022-07-08 23:47:12 +00:00
public bool AnyPressed { get; private set; }
/// <summary>
/// Contains a reference to an arbitrary VirtualButton that was pressed this frame. Useful for input remapping.
/// </summary>
2022-07-12 23:09:23 +00:00
public VirtualButton AnyPressedButton { get; private set; }
2022-07-08 23:47:12 +00:00
public delegate void OnGamepadConnectedFunc(int slot);
/// <summary>
/// Called when a gamepad has been connected.
/// </summary>
/// <param name="slot">The slot where the connection occurred.</param>
public OnGamepadConnectedFunc OnGamepadConnected = delegate { };
public delegate void OnGamepadDisconnectedFunc(int slot);
/// <summary>
/// Called when a gamepad has been disconnected.
/// </summary>
/// <param name="slot">The slot where the disconnection occurred.</param>
public OnGamepadDisconnectedFunc OnGamepadDisconnected = delegate { };
2022-02-23 05:14:32 +00:00
internal Inputs()
{
Keyboard = new Keyboard();
Mouse = new Mouse();
Gamepads = new Gamepad[MAX_GAMEPADS];
// initialize dummy controllers
for (var slot = 0; slot < MAX_GAMEPADS; slot += 1)
2022-02-23 05:14:32 +00:00
{
Gamepads[slot] = new Gamepad(IntPtr.Zero, slot);
2022-02-23 05:14:32 +00:00
}
}
// Assumes that SDL_PumpEvents has been called!
internal void Update()
{
2022-07-08 23:47:12 +00:00
AnyPressed = false;
AnyPressedButton = default; // DeviceKind.None
2022-07-08 23:47:12 +00:00
2022-02-23 05:14:32 +00:00
Keyboard.Update();
2022-07-08 23:47:12 +00:00
if (Keyboard.AnyPressed)
{
AnyPressed = true;
2022-07-12 23:09:23 +00:00
AnyPressedButton = Keyboard.AnyPressedButton;
2022-07-08 23:47:12 +00:00
}
2022-02-23 05:14:32 +00:00
Mouse.Update();
2022-07-08 23:47:12 +00:00
if (Mouse.AnyPressed)
{
AnyPressed = true;
2022-07-12 23:09:23 +00:00
AnyPressedButton = Mouse.AnyPressedButton;
2022-07-08 23:47:12 +00:00
}
foreach (var gamepad in Gamepads)
2022-02-23 05:14:32 +00:00
{
gamepad.Update();
2022-07-08 23:47:12 +00:00
if (gamepad.AnyPressed)
{
AnyPressed = true;
2022-07-12 23:09:23 +00:00
AnyPressedButton = gamepad.AnyPressedButton;
2022-07-08 23:47:12 +00:00
}
2022-02-23 05:14:32 +00:00
}
}
/// <summary>
/// Returns true if a gamepad is currently connected in the given slot.
/// </summary>
/// <param name="slot">Range: 0-3</param>
/// <returns></returns>
2022-02-23 05:14:32 +00:00
public bool GamepadExists(int slot)
{
if (slot < 0 || slot >= MAX_GAMEPADS)
{
return false;
}
return !Gamepads[slot].IsDummy;
2022-02-23 05:14:32 +00:00
}
/// <summary>
/// Gets a gamepad associated with the given slot.
/// The first n slots are guaranteed to occupied with gamepads if they are connected.
/// If a gamepad does not exist for the given slot, a dummy object with all inputs in default state will be returned.
/// You can check if a gamepad is connected in a slot with the GamepadExists function.
/// </summary>
/// <param name="slot">Range: 0-3</param>
2022-02-23 05:14:32 +00:00
public Gamepad GetGamepad(int slot)
{
return Gamepads[slot];
2022-02-23 05:14:32 +00:00
}
internal void AddGamepad(int index)
{
for (var slot = 0; slot < MAX_GAMEPADS; slot += 1)
{
if (!GamepadExists(slot))
{
2023-02-22 00:00:16 +00:00
var openResult = SDL.SDL_GameControllerOpen(index);
if (openResult == 0)
{
Logger.LogError("Error opening gamepad!");
Logger.LogError(SDL.SDL_GetError());
2023-02-22 00:00:16 +00:00
}
else
{
Gamepads[slot].Register(openResult);
Logger.LogInfo($"Gamepad added to slot {slot}!");
if (OnGamepadConnected != null)
{
OnGamepadConnected(slot);
}
2023-02-22 00:00:16 +00:00
}
return;
}
}
Logger.LogInfo("Too many gamepads already!");
}
internal void RemoveGamepad(int joystickInstanceID)
{
for (int slot = 0; slot < MAX_GAMEPADS; slot += 1)
{
if (joystickInstanceID == Gamepads[slot].JoystickInstanceID)
{
SDL.SDL_GameControllerClose(Gamepads[slot].Handle);
Gamepads[slot].Unregister();
Logger.LogInfo($"Removing gamepad from slot {slot}!");
OnGamepadDisconnected(slot);
return;
}
}
}
2022-02-23 05:14:32 +00:00
internal static void OnTextInput(char c)
{
if (TextInput != null)
{
TextInput(c);
}
}
}
2021-01-19 07:29:07 +00:00
}