improve gamepad init and support hotplugging
parent
646e5e9283
commit
f6fc80804e
24
src/Game.cs
24
src/Game.cs
|
@ -205,6 +205,14 @@ namespace MoonWorks
|
|||
case SDL.SDL_EventType.SDL_DROPFILE:
|
||||
HandleFileDrop(_event);
|
||||
break;
|
||||
|
||||
case SDL.SDL_EventType.SDL_CONTROLLERDEVICEADDED:
|
||||
HandleControllerAdded(_event);
|
||||
break;
|
||||
|
||||
case SDL.SDL_EventType.SDL_CONTROLLERDEVICEREMOVED:
|
||||
HandleControllerRemoved(_event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -244,6 +252,22 @@ namespace MoonWorks
|
|||
DropFile(filePath);
|
||||
}
|
||||
|
||||
private void HandleControllerAdded(SDL.SDL_Event evt)
|
||||
{
|
||||
var index = evt.cdevice.which;
|
||||
if (SDL.SDL_IsGameController(index) == SDL.SDL_bool.SDL_TRUE)
|
||||
{
|
||||
System.Console.WriteLine($"New controller detected!");
|
||||
Inputs.AddGamepad(index);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleControllerRemoved(SDL.SDL_Event evt)
|
||||
{
|
||||
System.Console.WriteLine($"Controller removal detected!");
|
||||
Inputs.RemoveGamepad(evt.cdevice.which);
|
||||
}
|
||||
|
||||
private TimeSpan AdvanceElapsedTime()
|
||||
{
|
||||
long currentTicks = gameTimer.Elapsed.Ticks;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using MoonWorks.Math;
|
||||
using SDL2;
|
||||
|
||||
|
@ -6,7 +5,7 @@ namespace MoonWorks.Input
|
|||
{
|
||||
public class Axis
|
||||
{
|
||||
IntPtr GamepadHandle;
|
||||
public Gamepad Parent { get; }
|
||||
SDL.SDL_GameControllerAxis SDL_Axis;
|
||||
|
||||
public AxisCode Code { get; private set; }
|
||||
|
@ -17,11 +16,11 @@ namespace MoonWorks.Input
|
|||
public float Value { get; private set; }
|
||||
|
||||
public Axis(
|
||||
IntPtr gamepadHandle,
|
||||
Gamepad parent,
|
||||
AxisCode code,
|
||||
SDL.SDL_GameControllerAxis sdlAxis
|
||||
) {
|
||||
GamepadHandle = gamepadHandle;
|
||||
Parent = parent;
|
||||
SDL_Axis = sdlAxis;
|
||||
Code = code;
|
||||
}
|
||||
|
@ -29,7 +28,7 @@ namespace MoonWorks.Input
|
|||
internal void Update()
|
||||
{
|
||||
Value = MathHelper.Normalize(
|
||||
SDL.SDL_GameControllerGetAxis(GamepadHandle, SDL_Axis),
|
||||
SDL.SDL_GameControllerGetAxis(Parent.Handle, SDL_Axis),
|
||||
short.MinValue, short.MaxValue,
|
||||
-1, 1
|
||||
);
|
||||
|
|
|
@ -8,7 +8,9 @@ namespace MoonWorks.Input
|
|||
public class Gamepad
|
||||
{
|
||||
internal IntPtr Handle;
|
||||
internal int Index;
|
||||
internal int JoystickInstanceID;
|
||||
|
||||
public int Slot { get; internal set; }
|
||||
|
||||
public GamepadButton A { get; }
|
||||
public GamepadButton B { get; }
|
||||
|
@ -61,37 +63,40 @@ namespace MoonWorks.Input
|
|||
|
||||
private VirtualButton[] VirtualButtons;
|
||||
|
||||
internal Gamepad(IntPtr handle, int index)
|
||||
internal Gamepad(IntPtr handle, int slot)
|
||||
{
|
||||
Handle = handle;
|
||||
Index = index;
|
||||
Slot = slot;
|
||||
|
||||
IntPtr joystickHandle = SDL.SDL_GameControllerGetJoystick(Handle);
|
||||
JoystickInstanceID = SDL.SDL_JoystickInstanceID(joystickHandle);
|
||||
|
||||
AnyPressed = false;
|
||||
|
||||
A = new GamepadButton(handle, GamepadButtonCode.A, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_A);
|
||||
B = new GamepadButton(handle, GamepadButtonCode.B, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_B);
|
||||
X = new GamepadButton(handle, GamepadButtonCode.X, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_X);
|
||||
Y = new GamepadButton(handle, GamepadButtonCode.Y, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_Y);
|
||||
A = new GamepadButton(this, GamepadButtonCode.A, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_A);
|
||||
B = new GamepadButton(this, GamepadButtonCode.B, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_B);
|
||||
X = new GamepadButton(this, GamepadButtonCode.X, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_X);
|
||||
Y = new GamepadButton(this, GamepadButtonCode.Y, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_Y);
|
||||
|
||||
Back = new GamepadButton(handle, GamepadButtonCode.Back, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_BACK);
|
||||
Guide = new GamepadButton(handle, GamepadButtonCode.Guide, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_GUIDE);
|
||||
Start = new GamepadButton(handle, GamepadButtonCode.Start, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_START);
|
||||
Back = new GamepadButton(this, GamepadButtonCode.Back, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_BACK);
|
||||
Guide = new GamepadButton(this, GamepadButtonCode.Guide, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_GUIDE);
|
||||
Start = new GamepadButton(this, GamepadButtonCode.Start, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_START);
|
||||
|
||||
LeftStick = new GamepadButton(handle, GamepadButtonCode.LeftStick, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSTICK);
|
||||
RightStick = new GamepadButton(handle, GamepadButtonCode.RightStick, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSTICK);
|
||||
LeftStick = new GamepadButton(this, GamepadButtonCode.LeftStick, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSTICK);
|
||||
RightStick = new GamepadButton(this, GamepadButtonCode.RightStick, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSTICK);
|
||||
|
||||
LeftShoulder = new GamepadButton(handle, GamepadButtonCode.LeftShoulder, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
|
||||
RightShoulder = new GamepadButton(handle, GamepadButtonCode.RightShoulder, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
|
||||
LeftShoulder = new GamepadButton(this, GamepadButtonCode.LeftShoulder, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
|
||||
RightShoulder = new GamepadButton(this, GamepadButtonCode.RightShoulder, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
|
||||
|
||||
DpadUp = new GamepadButton(handle, GamepadButtonCode.DpadUp, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_UP);
|
||||
DpadDown = new GamepadButton(handle, GamepadButtonCode.DpadDown, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_DOWN);
|
||||
DpadLeft = new GamepadButton(handle, GamepadButtonCode.DpadLeft, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
||||
DpadRight = new GamepadButton(handle, GamepadButtonCode.DpadRight, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
||||
DpadUp = new GamepadButton(this, GamepadButtonCode.DpadUp, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_UP);
|
||||
DpadDown = new GamepadButton(this, GamepadButtonCode.DpadDown, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_DOWN);
|
||||
DpadLeft = new GamepadButton(this, GamepadButtonCode.DpadLeft, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
||||
DpadRight = new GamepadButton(this, GamepadButtonCode.DpadRight, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
||||
|
||||
LeftX = new Axis(handle, AxisCode.LeftX, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTX);
|
||||
LeftY = new Axis(handle, AxisCode.LeftY, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTY);
|
||||
RightX = new Axis(handle, AxisCode.RightX, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTX);
|
||||
RightY = new Axis(handle, AxisCode.RightY, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTY);
|
||||
LeftX = new Axis(this, AxisCode.LeftX, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTX);
|
||||
LeftY = new Axis(this, AxisCode.LeftY, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTY);
|
||||
RightX = new Axis(this, AxisCode.RightX, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTX);
|
||||
RightY = new Axis(this, AxisCode.RightY, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTY);
|
||||
|
||||
LeftXLeft = new AxisButton(LeftX, false);
|
||||
LeftXRight = new AxisButton(LeftX, true);
|
||||
|
@ -103,8 +108,8 @@ namespace MoonWorks.Input
|
|||
RightYUp = new AxisButton(RightY, false);
|
||||
RightYDown = new AxisButton(RightY, true);
|
||||
|
||||
TriggerLeft = new Trigger(handle, TriggerCode.Left, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT);
|
||||
TriggerRight = new Trigger(handle, TriggerCode.Right, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
|
||||
TriggerLeft = new Trigger(this, TriggerCode.Left, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT);
|
||||
TriggerRight = new Trigger(this, TriggerCode.Right, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
|
||||
|
||||
TriggerLeftButton = new TriggerButton(TriggerLeft);
|
||||
TriggerRightButton = new TriggerButton(TriggerRight);
|
||||
|
|
|
@ -24,16 +24,10 @@ namespace MoonWorks.Input
|
|||
|
||||
gamepads = new Gamepad[MAX_GAMEPADS];
|
||||
|
||||
for (var i = 0; i < 4; i += 1)
|
||||
// initialize dummy controllers
|
||||
for (var slot = 0; slot < MAX_GAMEPADS; slot += 1)
|
||||
{
|
||||
if (SDL.SDL_IsGameController(i) == SDL.SDL_bool.SDL_TRUE)
|
||||
{
|
||||
gamepads[i] = new Gamepad(SDL.SDL_GameControllerOpen(i), i);
|
||||
}
|
||||
else
|
||||
{
|
||||
gamepads[i] = new Gamepad(IntPtr.Zero, -1);
|
||||
}
|
||||
gamepads[slot] = new Gamepad(IntPtr.Zero, slot);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,14 +68,49 @@ namespace MoonWorks.Input
|
|||
|
||||
public bool GamepadExists(int slot)
|
||||
{
|
||||
if (slot < 0 || slot >= MAX_GAMEPADS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !gamepads[slot].IsDummy;
|
||||
}
|
||||
|
||||
// From 0-4
|
||||
public Gamepad GetGamepad(int slot)
|
||||
{
|
||||
return gamepads[slot];
|
||||
}
|
||||
|
||||
internal void AddGamepad(int index)
|
||||
{
|
||||
for (var slot = 0; slot < MAX_GAMEPADS; slot += 1)
|
||||
{
|
||||
if (!GamepadExists(slot))
|
||||
{
|
||||
gamepads[slot].Handle = SDL.SDL_GameControllerOpen(index);
|
||||
System.Console.WriteLine($"Gamepad added to slot {slot}!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
System.Console.WriteLine("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].Handle = IntPtr.Zero;
|
||||
System.Console.WriteLine($"Removing gamepad from slot {slot}!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void OnTextInput(char c)
|
||||
{
|
||||
if (TextInput != null)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using MoonWorks.Math;
|
||||
using SDL2;
|
||||
|
||||
|
@ -6,7 +5,7 @@ namespace MoonWorks.Input
|
|||
{
|
||||
public class Trigger
|
||||
{
|
||||
public IntPtr GamepadHandle;
|
||||
public Gamepad Parent { get; }
|
||||
public SDL.SDL_GameControllerAxis SDL_Axis;
|
||||
|
||||
public TriggerCode Code { get; }
|
||||
|
@ -17,11 +16,11 @@ namespace MoonWorks.Input
|
|||
public float Value { get; private set; }
|
||||
|
||||
public Trigger(
|
||||
IntPtr gamepadHandle,
|
||||
Gamepad parent,
|
||||
TriggerCode code,
|
||||
SDL.SDL_GameControllerAxis sdlAxis
|
||||
) {
|
||||
GamepadHandle = gamepadHandle;
|
||||
Parent = parent;
|
||||
Code = code;
|
||||
SDL_Axis = sdlAxis;
|
||||
}
|
||||
|
@ -29,7 +28,7 @@ namespace MoonWorks.Input
|
|||
internal void Update()
|
||||
{
|
||||
Value = MathHelper.Normalize(
|
||||
SDL.SDL_GameControllerGetAxis(GamepadHandle, SDL_Axis),
|
||||
SDL.SDL_GameControllerGetAxis(Parent.Handle, SDL_Axis),
|
||||
0, short.MaxValue,
|
||||
0, 1
|
||||
);
|
||||
|
|
|
@ -1,25 +1,23 @@
|
|||
using System;
|
||||
using SDL2;
|
||||
|
||||
namespace MoonWorks.Input
|
||||
{
|
||||
public class GamepadButton : VirtualButton
|
||||
{
|
||||
IntPtr GamepadHandle;
|
||||
public Gamepad Parent { get; }
|
||||
SDL.SDL_GameControllerButton SDL_Button;
|
||||
public GamepadButtonCode Code { get; }
|
||||
|
||||
public GamepadButtonCode Code { get; private set; }
|
||||
|
||||
internal GamepadButton(IntPtr gamepadHandle, GamepadButtonCode code, SDL.SDL_GameControllerButton sdlButton)
|
||||
internal GamepadButton(Gamepad parent, GamepadButtonCode code, SDL.SDL_GameControllerButton sdlButton)
|
||||
{
|
||||
GamepadHandle = gamepadHandle;
|
||||
Parent = parent;
|
||||
Code = code;
|
||||
SDL_Button = sdlButton;
|
||||
}
|
||||
|
||||
internal override bool CheckPressed()
|
||||
{
|
||||
return MoonWorks.Conversions.ByteToBool(SDL.SDL_GameControllerGetButton(GamepadHandle, SDL_Button));
|
||||
return MoonWorks.Conversions.ByteToBool(SDL.SDL_GameControllerGetButton(Parent.Handle, SDL_Button));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue