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:
|
case SDL.SDL_EventType.SDL_DROPFILE:
|
||||||
HandleFileDrop(_event);
|
HandleFileDrop(_event);
|
||||||
break;
|
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);
|
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()
|
private TimeSpan AdvanceElapsedTime()
|
||||||
{
|
{
|
||||||
long currentTicks = gameTimer.Elapsed.Ticks;
|
long currentTicks = gameTimer.Elapsed.Ticks;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System;
|
|
||||||
using MoonWorks.Math;
|
using MoonWorks.Math;
|
||||||
using SDL2;
|
using SDL2;
|
||||||
|
|
||||||
|
@ -6,7 +5,7 @@ namespace MoonWorks.Input
|
||||||
{
|
{
|
||||||
public class Axis
|
public class Axis
|
||||||
{
|
{
|
||||||
IntPtr GamepadHandle;
|
public Gamepad Parent { get; }
|
||||||
SDL.SDL_GameControllerAxis SDL_Axis;
|
SDL.SDL_GameControllerAxis SDL_Axis;
|
||||||
|
|
||||||
public AxisCode Code { get; private set; }
|
public AxisCode Code { get; private set; }
|
||||||
|
@ -17,11 +16,11 @@ namespace MoonWorks.Input
|
||||||
public float Value { get; private set; }
|
public float Value { get; private set; }
|
||||||
|
|
||||||
public Axis(
|
public Axis(
|
||||||
IntPtr gamepadHandle,
|
Gamepad parent,
|
||||||
AxisCode code,
|
AxisCode code,
|
||||||
SDL.SDL_GameControllerAxis sdlAxis
|
SDL.SDL_GameControllerAxis sdlAxis
|
||||||
) {
|
) {
|
||||||
GamepadHandle = gamepadHandle;
|
Parent = parent;
|
||||||
SDL_Axis = sdlAxis;
|
SDL_Axis = sdlAxis;
|
||||||
Code = code;
|
Code = code;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +28,7 @@ namespace MoonWorks.Input
|
||||||
internal void Update()
|
internal void Update()
|
||||||
{
|
{
|
||||||
Value = MathHelper.Normalize(
|
Value = MathHelper.Normalize(
|
||||||
SDL.SDL_GameControllerGetAxis(GamepadHandle, SDL_Axis),
|
SDL.SDL_GameControllerGetAxis(Parent.Handle, SDL_Axis),
|
||||||
short.MinValue, short.MaxValue,
|
short.MinValue, short.MaxValue,
|
||||||
-1, 1
|
-1, 1
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,9 @@ namespace MoonWorks.Input
|
||||||
public class Gamepad
|
public class Gamepad
|
||||||
{
|
{
|
||||||
internal IntPtr Handle;
|
internal IntPtr Handle;
|
||||||
internal int Index;
|
internal int JoystickInstanceID;
|
||||||
|
|
||||||
|
public int Slot { get; internal set; }
|
||||||
|
|
||||||
public GamepadButton A { get; }
|
public GamepadButton A { get; }
|
||||||
public GamepadButton B { get; }
|
public GamepadButton B { get; }
|
||||||
|
@ -61,37 +63,40 @@ namespace MoonWorks.Input
|
||||||
|
|
||||||
private VirtualButton[] VirtualButtons;
|
private VirtualButton[] VirtualButtons;
|
||||||
|
|
||||||
internal Gamepad(IntPtr handle, int index)
|
internal Gamepad(IntPtr handle, int slot)
|
||||||
{
|
{
|
||||||
Handle = handle;
|
Handle = handle;
|
||||||
Index = index;
|
Slot = slot;
|
||||||
|
|
||||||
|
IntPtr joystickHandle = SDL.SDL_GameControllerGetJoystick(Handle);
|
||||||
|
JoystickInstanceID = SDL.SDL_JoystickInstanceID(joystickHandle);
|
||||||
|
|
||||||
AnyPressed = false;
|
AnyPressed = false;
|
||||||
|
|
||||||
A = new GamepadButton(handle, GamepadButtonCode.A, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_A);
|
A = new GamepadButton(this, GamepadButtonCode.A, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_A);
|
||||||
B = new GamepadButton(handle, GamepadButtonCode.B, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_B);
|
B = new GamepadButton(this, GamepadButtonCode.B, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_B);
|
||||||
X = new GamepadButton(handle, GamepadButtonCode.X, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_X);
|
X = new GamepadButton(this, GamepadButtonCode.X, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_X);
|
||||||
Y = new GamepadButton(handle, GamepadButtonCode.Y, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_Y);
|
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);
|
Back = new GamepadButton(this, GamepadButtonCode.Back, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_BACK);
|
||||||
Guide = new GamepadButton(handle, GamepadButtonCode.Guide, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_GUIDE);
|
Guide = new GamepadButton(this, GamepadButtonCode.Guide, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_GUIDE);
|
||||||
Start = new GamepadButton(handle, GamepadButtonCode.Start, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_START);
|
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);
|
LeftStick = new GamepadButton(this, GamepadButtonCode.LeftStick, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSTICK);
|
||||||
RightStick = new GamepadButton(handle, GamepadButtonCode.RightStick, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSTICK);
|
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);
|
LeftShoulder = new GamepadButton(this, GamepadButtonCode.LeftShoulder, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
|
||||||
RightShoulder = new GamepadButton(handle, GamepadButtonCode.RightShoulder, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
|
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);
|
DpadUp = new GamepadButton(this, GamepadButtonCode.DpadUp, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_UP);
|
||||||
DpadDown = new GamepadButton(handle, GamepadButtonCode.DpadDown, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_DOWN);
|
DpadDown = new GamepadButton(this, GamepadButtonCode.DpadDown, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_DOWN);
|
||||||
DpadLeft = new GamepadButton(handle, GamepadButtonCode.DpadLeft, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
DpadLeft = new GamepadButton(this, GamepadButtonCode.DpadLeft, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
||||||
DpadRight = new GamepadButton(handle, GamepadButtonCode.DpadRight, SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
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);
|
LeftX = new Axis(this, AxisCode.LeftX, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTX);
|
||||||
LeftY = new Axis(handle, AxisCode.LeftY, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTY);
|
LeftY = new Axis(this, AxisCode.LeftY, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTY);
|
||||||
RightX = new Axis(handle, AxisCode.RightX, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTX);
|
RightX = new Axis(this, AxisCode.RightX, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTX);
|
||||||
RightY = new Axis(handle, AxisCode.RightY, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTY);
|
RightY = new Axis(this, AxisCode.RightY, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTY);
|
||||||
|
|
||||||
LeftXLeft = new AxisButton(LeftX, false);
|
LeftXLeft = new AxisButton(LeftX, false);
|
||||||
LeftXRight = new AxisButton(LeftX, true);
|
LeftXRight = new AxisButton(LeftX, true);
|
||||||
|
@ -103,8 +108,8 @@ namespace MoonWorks.Input
|
||||||
RightYUp = new AxisButton(RightY, false);
|
RightYUp = new AxisButton(RightY, false);
|
||||||
RightYDown = new AxisButton(RightY, true);
|
RightYDown = new AxisButton(RightY, true);
|
||||||
|
|
||||||
TriggerLeft = new Trigger(handle, TriggerCode.Left, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT);
|
TriggerLeft = new Trigger(this, TriggerCode.Left, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT);
|
||||||
TriggerRight = new Trigger(handle, TriggerCode.Right, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
|
TriggerRight = new Trigger(this, TriggerCode.Right, SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
|
||||||
|
|
||||||
TriggerLeftButton = new TriggerButton(TriggerLeft);
|
TriggerLeftButton = new TriggerButton(TriggerLeft);
|
||||||
TriggerRightButton = new TriggerButton(TriggerRight);
|
TriggerRightButton = new TriggerButton(TriggerRight);
|
||||||
|
|
|
@ -24,16 +24,10 @@ namespace MoonWorks.Input
|
||||||
|
|
||||||
gamepads = new Gamepad[MAX_GAMEPADS];
|
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[slot] = new Gamepad(IntPtr.Zero, slot);
|
||||||
{
|
|
||||||
gamepads[i] = new Gamepad(SDL.SDL_GameControllerOpen(i), i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gamepads[i] = new Gamepad(IntPtr.Zero, -1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,14 +68,49 @@ namespace MoonWorks.Input
|
||||||
|
|
||||||
public bool GamepadExists(int slot)
|
public bool GamepadExists(int slot)
|
||||||
{
|
{
|
||||||
|
if (slot < 0 || slot >= MAX_GAMEPADS)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return !gamepads[slot].IsDummy;
|
return !gamepads[slot].IsDummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From 0-4
|
||||||
public Gamepad GetGamepad(int slot)
|
public Gamepad GetGamepad(int slot)
|
||||||
{
|
{
|
||||||
return gamepads[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)
|
internal static void OnTextInput(char c)
|
||||||
{
|
{
|
||||||
if (TextInput != null)
|
if (TextInput != null)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System;
|
|
||||||
using MoonWorks.Math;
|
using MoonWorks.Math;
|
||||||
using SDL2;
|
using SDL2;
|
||||||
|
|
||||||
|
@ -6,7 +5,7 @@ namespace MoonWorks.Input
|
||||||
{
|
{
|
||||||
public class Trigger
|
public class Trigger
|
||||||
{
|
{
|
||||||
public IntPtr GamepadHandle;
|
public Gamepad Parent { get; }
|
||||||
public SDL.SDL_GameControllerAxis SDL_Axis;
|
public SDL.SDL_GameControllerAxis SDL_Axis;
|
||||||
|
|
||||||
public TriggerCode Code { get; }
|
public TriggerCode Code { get; }
|
||||||
|
@ -17,11 +16,11 @@ namespace MoonWorks.Input
|
||||||
public float Value { get; private set; }
|
public float Value { get; private set; }
|
||||||
|
|
||||||
public Trigger(
|
public Trigger(
|
||||||
IntPtr gamepadHandle,
|
Gamepad parent,
|
||||||
TriggerCode code,
|
TriggerCode code,
|
||||||
SDL.SDL_GameControllerAxis sdlAxis
|
SDL.SDL_GameControllerAxis sdlAxis
|
||||||
) {
|
) {
|
||||||
GamepadHandle = gamepadHandle;
|
Parent = parent;
|
||||||
Code = code;
|
Code = code;
|
||||||
SDL_Axis = sdlAxis;
|
SDL_Axis = sdlAxis;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +28,7 @@ namespace MoonWorks.Input
|
||||||
internal void Update()
|
internal void Update()
|
||||||
{
|
{
|
||||||
Value = MathHelper.Normalize(
|
Value = MathHelper.Normalize(
|
||||||
SDL.SDL_GameControllerGetAxis(GamepadHandle, SDL_Axis),
|
SDL.SDL_GameControllerGetAxis(Parent.Handle, SDL_Axis),
|
||||||
0, short.MaxValue,
|
0, short.MaxValue,
|
||||||
0, 1
|
0, 1
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,25 +1,23 @@
|
||||||
using System;
|
|
||||||
using SDL2;
|
using SDL2;
|
||||||
|
|
||||||
namespace MoonWorks.Input
|
namespace MoonWorks.Input
|
||||||
{
|
{
|
||||||
public class GamepadButton : VirtualButton
|
public class GamepadButton : VirtualButton
|
||||||
{
|
{
|
||||||
IntPtr GamepadHandle;
|
public Gamepad Parent { get; }
|
||||||
SDL.SDL_GameControllerButton SDL_Button;
|
SDL.SDL_GameControllerButton SDL_Button;
|
||||||
|
public GamepadButtonCode Code { get; }
|
||||||
|
|
||||||
public GamepadButtonCode Code { get; private set; }
|
internal GamepadButton(Gamepad parent, GamepadButtonCode code, SDL.SDL_GameControllerButton sdlButton)
|
||||||
|
|
||||||
internal GamepadButton(IntPtr gamepadHandle, GamepadButtonCode code, SDL.SDL_GameControllerButton sdlButton)
|
|
||||||
{
|
{
|
||||||
GamepadHandle = gamepadHandle;
|
Parent = parent;
|
||||||
Code = code;
|
Code = code;
|
||||||
SDL_Button = sdlButton;
|
SDL_Button = sdlButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override bool CheckPressed()
|
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