ryujinx-mirror/Ryujinx/Ui/JoyConController.cs
ReinUsesLisp 7a308d9e73 Window related changes (#308)
* Use integer math for touch screen

* Sleep polling thread

* Rework host input

* Add fullscreen with F11 or Alt+Enter

* Address feedback
2018-07-29 01:35:36 -03:00

216 lines
8 KiB
C#

using OpenTK;
using OpenTK.Input;
using Ryujinx.HLE.Input;
using System;
namespace Ryujinx.UI.Input
{
public enum ControllerInputID
{
Invalid,
LStick,
DPadUp,
DPadDown,
DPadLeft,
DPadRight,
Back,
LShoulder,
RStick,
A,
B,
X,
Y,
Start,
RShoulder,
LTrigger,
RTrigger,
LJoystick,
RJoystick
}
public struct JoyConControllerLeft
{
public ControllerInputID Stick;
public ControllerInputID StickButton;
public ControllerInputID DPadUp;
public ControllerInputID DPadDown;
public ControllerInputID DPadLeft;
public ControllerInputID DPadRight;
public ControllerInputID ButtonMinus;
public ControllerInputID ButtonL;
public ControllerInputID ButtonZL;
}
public struct JoyConControllerRight
{
public ControllerInputID Stick;
public ControllerInputID StickButton;
public ControllerInputID ButtonA;
public ControllerInputID ButtonB;
public ControllerInputID ButtonX;
public ControllerInputID ButtonY;
public ControllerInputID ButtonPlus;
public ControllerInputID ButtonR;
public ControllerInputID ButtonZR;
}
public class JoyConController
{
public bool Enabled { private set; get; }
public int Index { private set; get; }
public float Deadzone { private set; get; }
public float TriggerThreshold { private set; get; }
public JoyConControllerLeft Left { private set; get; }
public JoyConControllerRight Right { private set; get; }
public JoyConController(
bool Enabled,
int Index,
float Deadzone,
float TriggerThreshold,
JoyConControllerLeft Left,
JoyConControllerRight Right)
{
this.Enabled = Enabled;
this.Index = Index;
this.Deadzone = Deadzone;
this.TriggerThreshold = TriggerThreshold;
this.Left = Left;
this.Right = Right;
//Unmapped controllers are problematic, skip them
if (GamePad.GetName(Index) == "Unmapped Controller")
{
this.Enabled = false;
}
}
public HidControllerButtons GetButtons()
{
if (!Enabled)
{
return 0;
}
GamePadState GpState = GamePad.GetState(Index);
HidControllerButtons Buttons = 0;
if (IsPressed(GpState, Left.DPadUp)) Buttons |= HidControllerButtons.KEY_DUP;
if (IsPressed(GpState, Left.DPadDown)) Buttons |= HidControllerButtons.KEY_DDOWN;
if (IsPressed(GpState, Left.DPadLeft)) Buttons |= HidControllerButtons.KEY_DLEFT;
if (IsPressed(GpState, Left.DPadRight)) Buttons |= HidControllerButtons.KEY_DRIGHT;
if (IsPressed(GpState, Left.StickButton)) Buttons |= HidControllerButtons.KEY_LSTICK;
if (IsPressed(GpState, Left.ButtonMinus)) Buttons |= HidControllerButtons.KEY_MINUS;
if (IsPressed(GpState, Left.ButtonL)) Buttons |= HidControllerButtons.KEY_L;
if (IsPressed(GpState, Left.ButtonZL)) Buttons |= HidControllerButtons.KEY_ZL;
if (IsPressed(GpState, Right.ButtonA)) Buttons |= HidControllerButtons.KEY_A;
if (IsPressed(GpState, Right.ButtonB)) Buttons |= HidControllerButtons.KEY_B;
if (IsPressed(GpState, Right.ButtonX)) Buttons |= HidControllerButtons.KEY_X;
if (IsPressed(GpState, Right.ButtonY)) Buttons |= HidControllerButtons.KEY_Y;
if (IsPressed(GpState, Right.StickButton)) Buttons |= HidControllerButtons.KEY_RSTICK;
if (IsPressed(GpState, Right.ButtonPlus)) Buttons |= HidControllerButtons.KEY_PLUS;
if (IsPressed(GpState, Right.ButtonR)) Buttons |= HidControllerButtons.KEY_R;
if (IsPressed(GpState, Right.ButtonZR)) Buttons |= HidControllerButtons.KEY_ZR;
return Buttons;
}
public (short, short) GetLeftStick()
{
if (!Enabled)
{
return (0, 0);
}
return GetStick(Left.Stick);
}
public (short, short) GetRightStick()
{
if (!Enabled)
{
return (0, 0);
}
return GetStick(Right.Stick);
}
private (short, short) GetStick(ControllerInputID Joystick)
{
GamePadState GpState = GamePad.GetState(Index);
switch (Joystick)
{
case ControllerInputID.LJoystick:
return ApplyDeadzone(GpState.ThumbSticks.Left);
case ControllerInputID.RJoystick:
return ApplyDeadzone(GpState.ThumbSticks.Right);
default:
return (0, 0);
}
}
private (short, short) ApplyDeadzone(Vector2 Axis)
{
return (ClampAxis(MathF.Abs(Axis.X) > Deadzone ? Axis.X : 0f),
ClampAxis(MathF.Abs(Axis.Y) > Deadzone ? Axis.Y : 0f));
}
private static short ClampAxis(float Value)
{
if (Value <= -short.MaxValue)
{
return -short.MaxValue;
}
else
{
return (short)(Value * short.MaxValue);
}
}
private bool IsPressed(GamePadState GpState, ControllerInputID Button)
{
switch (Button)
{
case ControllerInputID.A: return GpState.Buttons.A == ButtonState.Pressed;
case ControllerInputID.B: return GpState.Buttons.B == ButtonState.Pressed;
case ControllerInputID.X: return GpState.Buttons.X == ButtonState.Pressed;
case ControllerInputID.Y: return GpState.Buttons.Y == ButtonState.Pressed;
case ControllerInputID.LStick: return GpState.Buttons.LeftStick == ButtonState.Pressed;
case ControllerInputID.RStick: return GpState.Buttons.RightStick == ButtonState.Pressed;
case ControllerInputID.LShoulder: return GpState.Buttons.LeftShoulder == ButtonState.Pressed;
case ControllerInputID.RShoulder: return GpState.Buttons.RightShoulder == ButtonState.Pressed;
case ControllerInputID.DPadUp: return GpState.DPad.Up == ButtonState.Pressed;
case ControllerInputID.DPadDown: return GpState.DPad.Down == ButtonState.Pressed;
case ControllerInputID.DPadLeft: return GpState.DPad.Left == ButtonState.Pressed;
case ControllerInputID.DPadRight: return GpState.DPad.Right == ButtonState.Pressed;
case ControllerInputID.Start: return GpState.Buttons.Start == ButtonState.Pressed;
case ControllerInputID.Back: return GpState.Buttons.Back == ButtonState.Pressed;
case ControllerInputID.LTrigger: return GpState.Triggers.Left >= TriggerThreshold;
case ControllerInputID.RTrigger: return GpState.Triggers.Right >= TriggerThreshold;
//Using thumbsticks as buttons is not common, but it would be nice not to ignore them
case ControllerInputID.LJoystick:
return GpState.ThumbSticks.Left.X >= Deadzone ||
GpState.ThumbSticks.Left.Y >= Deadzone;
case ControllerInputID.RJoystick:
return GpState.ThumbSticks.Right.X >= Deadzone ||
GpState.ThumbSticks.Right.Y >= Deadzone;
default:
return false;
}
}
}
}