2022-02-23 05:14:32 +00:00
|
|
|
|
using System;
|
2022-03-18 18:46:44 +00:00
|
|
|
|
using System.Collections.Generic;
|
2021-03-10 05:48:31 +00:00
|
|
|
|
using MoonWorks.Math;
|
2021-01-19 07:29:07 +00:00
|
|
|
|
using SDL2;
|
|
|
|
|
|
2021-01-22 08:20:07 +00:00
|
|
|
|
namespace MoonWorks.Input
|
2021-01-19 07:29:07 +00:00
|
|
|
|
{
|
2022-02-23 05:14:32 +00:00
|
|
|
|
public class Gamepad
|
|
|
|
|
{
|
|
|
|
|
internal IntPtr Handle;
|
2022-04-27 18:37:35 +00:00
|
|
|
|
internal int Index;
|
2021-01-19 07:29:07 +00:00
|
|
|
|
|
2022-03-18 18:58:10 +00:00
|
|
|
|
public Button A { get; } = new Button();
|
|
|
|
|
public Button B { get; } = new Button();
|
|
|
|
|
public Button X { get; } = new Button();
|
|
|
|
|
public Button Y { get; } = new Button();
|
|
|
|
|
public Button Back { get; } = new Button();
|
|
|
|
|
public Button Guide { get; } = new Button();
|
|
|
|
|
public Button Start { get; } = new Button();
|
|
|
|
|
public Button LeftStick { get; } = new Button();
|
|
|
|
|
public Button RightStick { get; } = new Button();
|
|
|
|
|
public Button LeftShoulder { get; } = new Button();
|
|
|
|
|
public Button RightShoulder { get; } = new Button();
|
|
|
|
|
public Button DpadUp { get; } = new Button();
|
|
|
|
|
public Button DpadDown { get; } = new Button();
|
|
|
|
|
public Button DpadLeft { get; } = new Button();
|
|
|
|
|
public Button DpadRight { get; } = new Button();
|
|
|
|
|
|
|
|
|
|
public Axis LeftX { get; } = new Axis();
|
|
|
|
|
public Axis LeftY { get; } = new Axis();
|
|
|
|
|
public Axis RightX { get; } = new Axis();
|
|
|
|
|
public Axis RightY { get; } = new Axis();
|
|
|
|
|
|
|
|
|
|
public Trigger TriggerLeft { get; } = new Trigger();
|
|
|
|
|
public Trigger TriggerRight { get; } = new Trigger();
|
2022-03-18 18:46:44 +00:00
|
|
|
|
|
2022-03-18 19:11:00 +00:00
|
|
|
|
public bool IsDummy => Handle == IntPtr.Zero;
|
|
|
|
|
|
2022-07-08 23:47:12 +00:00
|
|
|
|
public bool AnyPressed { get; private set; }
|
|
|
|
|
public ButtonCode AnyPressedButtonCode { get; private set; }
|
|
|
|
|
|
2022-03-18 18:46:44 +00:00
|
|
|
|
private Dictionary<SDL.SDL_GameControllerButton, Button> EnumToButton;
|
|
|
|
|
private Dictionary<SDL.SDL_GameControllerAxis, Axis> EnumToAxis;
|
|
|
|
|
private Dictionary<SDL.SDL_GameControllerAxis, Trigger> EnumToTrigger;
|
2021-01-19 07:29:07 +00:00
|
|
|
|
|
2022-04-27 18:37:35 +00:00
|
|
|
|
internal Gamepad(IntPtr handle, int index)
|
2022-02-23 05:14:32 +00:00
|
|
|
|
{
|
|
|
|
|
Handle = handle;
|
2022-04-27 18:37:35 +00:00
|
|
|
|
Index = index;
|
2022-03-18 18:46:44 +00:00
|
|
|
|
|
2022-07-08 23:47:12 +00:00
|
|
|
|
AnyPressed = false;
|
|
|
|
|
|
2022-03-18 18:46:44 +00:00
|
|
|
|
EnumToButton = new Dictionary<SDL.SDL_GameControllerButton, Button>
|
|
|
|
|
{
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_A, A },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_B, B },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_X, X },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_Y, Y },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_BACK, Back },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_GUIDE, Guide },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_START, Start },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSTICK, LeftStick },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSTICK, RightStick },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSHOULDER, LeftShoulder },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, RightShoulder },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_UP, DpadUp },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_DOWN, DpadDown },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_LEFT, DpadLeft },
|
|
|
|
|
{ SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_RIGHT, DpadRight }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
EnumToAxis = new Dictionary<SDL.SDL_GameControllerAxis, Axis>
|
|
|
|
|
{
|
|
|
|
|
{ SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTX, LeftX },
|
|
|
|
|
{ SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTY, LeftY },
|
|
|
|
|
{ SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTX, RightX },
|
|
|
|
|
{ SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTY, RightY }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
EnumToTrigger = new Dictionary<SDL.SDL_GameControllerAxis, Trigger>
|
|
|
|
|
{
|
|
|
|
|
{ SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT, TriggerLeft },
|
|
|
|
|
{ SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT, TriggerRight }
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal void Update()
|
|
|
|
|
{
|
2022-07-08 23:47:12 +00:00
|
|
|
|
AnyPressed = false;
|
|
|
|
|
|
2022-03-18 19:11:00 +00:00
|
|
|
|
if (!IsDummy)
|
2022-03-18 18:46:44 +00:00
|
|
|
|
{
|
2022-03-18 19:11:00 +00:00
|
|
|
|
foreach (var (sdlEnum, button) in EnumToButton)
|
|
|
|
|
{
|
2022-07-08 23:47:12 +00:00
|
|
|
|
var pressed = CheckPressed(sdlEnum);
|
|
|
|
|
button.Update(pressed);
|
|
|
|
|
|
|
|
|
|
if (button.IsPressed)
|
|
|
|
|
{
|
|
|
|
|
AnyPressed = true;
|
|
|
|
|
AnyPressedButtonCode = (ButtonCode) sdlEnum;
|
|
|
|
|
}
|
2022-03-18 19:11:00 +00:00
|
|
|
|
}
|
2022-03-18 18:46:44 +00:00
|
|
|
|
|
2022-03-18 19:11:00 +00:00
|
|
|
|
foreach (var (sdlEnum, axis) in EnumToAxis)
|
|
|
|
|
{
|
|
|
|
|
var sdlAxisValue = SDL.SDL_GameControllerGetAxis(Handle, sdlEnum);
|
2022-03-24 06:07:34 +00:00
|
|
|
|
var axisValue = MathHelper.Normalize(sdlAxisValue, short.MinValue, short.MaxValue, -1, 1);
|
2022-03-18 19:11:00 +00:00
|
|
|
|
axis.Update(axisValue);
|
|
|
|
|
}
|
2022-03-18 18:46:44 +00:00
|
|
|
|
|
2022-03-18 19:11:00 +00:00
|
|
|
|
foreach (var (sdlEnum, trigger) in EnumToTrigger)
|
|
|
|
|
{
|
|
|
|
|
var sdlAxisValue = SDL.SDL_GameControllerGetAxis(Handle, sdlEnum);
|
2022-03-24 06:07:34 +00:00
|
|
|
|
var axisValue = MathHelper.Normalize(sdlAxisValue, 0, short.MaxValue, 0, 1);
|
2022-03-18 19:11:00 +00:00
|
|
|
|
trigger.Update(axisValue);
|
|
|
|
|
}
|
2022-03-18 18:46:44 +00:00
|
|
|
|
}
|
2022-02-23 05:14:32 +00:00
|
|
|
|
}
|
2021-01-19 07:29:07 +00:00
|
|
|
|
|
2022-03-18 18:58:10 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sets vibration values on the left and right motors.
|
|
|
|
|
/// </summary>
|
2022-02-23 05:14:32 +00:00
|
|
|
|
public bool SetVibration(float leftMotor, float rightMotor, uint durationInMilliseconds)
|
|
|
|
|
{
|
|
|
|
|
return SDL.SDL_GameControllerRumble(
|
|
|
|
|
Handle,
|
|
|
|
|
(ushort) (MathHelper.Clamp(leftMotor, 0f, 1f) * 0xFFFF),
|
|
|
|
|
(ushort) (MathHelper.Clamp(rightMotor, 0f, 1f) * 0xFFFF),
|
|
|
|
|
durationInMilliseconds
|
|
|
|
|
) == 0;
|
|
|
|
|
}
|
2021-03-10 05:48:31 +00:00
|
|
|
|
|
2022-03-18 18:58:10 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// True if the button is pressed or held.
|
|
|
|
|
/// </summary>
|
2022-03-18 18:46:44 +00:00
|
|
|
|
public bool IsDown(ButtonCode buttonCode)
|
2022-02-23 05:14:32 +00:00
|
|
|
|
{
|
2022-03-18 18:46:44 +00:00
|
|
|
|
return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].IsDown;
|
2022-02-23 05:14:32 +00:00
|
|
|
|
}
|
2021-01-19 07:29:07 +00:00
|
|
|
|
|
2022-03-18 18:58:10 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// True if the button was pressed this exact frame.
|
|
|
|
|
/// </summary>
|
2022-03-18 18:46:44 +00:00
|
|
|
|
public bool IsPressed(ButtonCode buttonCode)
|
2022-02-23 05:14:32 +00:00
|
|
|
|
{
|
2022-03-18 18:46:44 +00:00
|
|
|
|
return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].IsPressed;
|
2022-02-23 05:14:32 +00:00
|
|
|
|
}
|
2021-01-19 07:29:07 +00:00
|
|
|
|
|
2022-03-18 18:58:10 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// True if the button has been continuously held for more than one frame.
|
|
|
|
|
/// </summary>
|
2022-03-18 18:46:44 +00:00
|
|
|
|
public bool IsHeld(ButtonCode buttonCode)
|
2022-02-23 05:14:32 +00:00
|
|
|
|
{
|
2022-03-18 18:46:44 +00:00
|
|
|
|
return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].IsHeld;
|
2022-02-23 05:14:32 +00:00
|
|
|
|
}
|
2021-01-19 07:29:07 +00:00
|
|
|
|
|
2022-03-18 18:58:10 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// True if the button is not pressed.
|
|
|
|
|
/// </summary>
|
2022-03-18 18:46:44 +00:00
|
|
|
|
public bool IsReleased(ButtonCode buttonCode)
|
2022-02-23 05:14:32 +00:00
|
|
|
|
{
|
2022-03-18 18:46:44 +00:00
|
|
|
|
return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].IsReleased;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-18 18:58:10 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Obtains the button state given a ButtonCode.
|
|
|
|
|
/// </summary>
|
2022-03-18 18:46:44 +00:00
|
|
|
|
public ButtonState ButtonState(ButtonCode buttonCode)
|
|
|
|
|
{
|
|
|
|
|
return EnumToButton[(SDL.SDL_GameControllerButton) buttonCode].State;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-18 18:58:10 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Obtains the axis value given an AxisCode.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>A value between -1 and 1.</returns>
|
2022-03-18 18:46:44 +00:00
|
|
|
|
public float AxisValue(AxisCode axisCode)
|
|
|
|
|
{
|
|
|
|
|
return EnumToAxis[(SDL.SDL_GameControllerAxis) axisCode].Value;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-18 18:58:10 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Obtains the trigger value given an TriggerCode.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>A value between 0 and 1.</returns>
|
2022-03-18 18:46:44 +00:00
|
|
|
|
public float TriggerValue(TriggerCode triggerCode)
|
|
|
|
|
{
|
|
|
|
|
return EnumToTrigger[(SDL.SDL_GameControllerAxis) triggerCode].Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool CheckPressed(SDL.SDL_GameControllerButton button)
|
|
|
|
|
{
|
|
|
|
|
return MoonWorks.Conversions.ByteToBool(SDL.SDL_GameControllerGetButton(Handle, button));
|
2022-02-23 05:14:32 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-19 07:29:07 +00:00
|
|
|
|
}
|