NpadController.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. using OpenTK;
  2. using OpenTK.Input;
  3. using Ryujinx.HLE.Input;
  4. using System;
  5. namespace Ryujinx.UI.Input
  6. {
  7. public enum ControllerInputId
  8. {
  9. Button0,
  10. Button1,
  11. Button2,
  12. Button3,
  13. Button4,
  14. Button5,
  15. Button6,
  16. Button7,
  17. Button8,
  18. Button9,
  19. Button10,
  20. Button11,
  21. Button12,
  22. Button13,
  23. Button14,
  24. Button15,
  25. Button16,
  26. Button17,
  27. Button18,
  28. Button19,
  29. Button20,
  30. Axis0,
  31. Axis1,
  32. Axis2,
  33. Axis3,
  34. Axis4,
  35. Axis5,
  36. Hat0Up,
  37. Hat0Down,
  38. Hat0Left,
  39. Hat0Right,
  40. Hat1Up,
  41. Hat1Down,
  42. Hat1Left,
  43. Hat1Right,
  44. Hat2Up,
  45. Hat2Down,
  46. Hat2Left,
  47. Hat2Right,
  48. }
  49. public struct NpadControllerLeft
  50. {
  51. public ControllerInputId Stick;
  52. public ControllerInputId StickButton;
  53. public ControllerInputId ButtonMinus;
  54. public ControllerInputId ButtonL;
  55. public ControllerInputId ButtonZl;
  56. public ControllerInputId DPadUp;
  57. public ControllerInputId DPadDown;
  58. public ControllerInputId DPadLeft;
  59. public ControllerInputId DPadRight;
  60. }
  61. public struct NpadControllerRight
  62. {
  63. public ControllerInputId Stick;
  64. public ControllerInputId StickY;
  65. public ControllerInputId StickButton;
  66. public ControllerInputId ButtonA;
  67. public ControllerInputId ButtonB;
  68. public ControllerInputId ButtonX;
  69. public ControllerInputId ButtonY;
  70. public ControllerInputId ButtonPlus;
  71. public ControllerInputId ButtonR;
  72. public ControllerInputId ButtonZr;
  73. }
  74. public class NpadController
  75. {
  76. /// <summary>
  77. /// Enables or disables controller support
  78. /// </summary>
  79. public bool Enabled { get; private set; }
  80. /// <summary>
  81. /// Controller Device Index
  82. /// </summary>
  83. public int Index { get; private set; }
  84. /// <summary>
  85. /// Controller Analog Stick Deadzone
  86. /// </summary>
  87. public float Deadzone { get; private set; }
  88. /// <summary>
  89. /// Controller Trigger Threshold
  90. /// </summary>
  91. public float TriggerThreshold { get; private set; }
  92. /// <summary>
  93. /// Left JoyCon Controller Bindings
  94. /// </summary>
  95. public NpadControllerLeft LeftJoycon { get; private set; }
  96. /// <summary>
  97. /// Right JoyCon Controller Bindings
  98. /// </summary>
  99. public NpadControllerRight RightJoycon { get; private set; }
  100. public NpadController(
  101. bool enabled,
  102. int index,
  103. float deadzone,
  104. float triggerThreshold,
  105. NpadControllerLeft leftJoycon,
  106. NpadControllerRight rightJoycon)
  107. {
  108. Enabled = enabled;
  109. Index = index;
  110. Deadzone = deadzone;
  111. TriggerThreshold = triggerThreshold;
  112. LeftJoycon = leftJoycon;
  113. RightJoycon = rightJoycon;
  114. }
  115. public void SetEnabled(bool enabled)
  116. {
  117. Enabled = enabled;
  118. }
  119. public ControllerButtons GetButtons()
  120. {
  121. if (!Enabled)
  122. {
  123. return 0;
  124. }
  125. JoystickState joystickState = Joystick.GetState(Index);
  126. ControllerButtons buttons = 0;
  127. if (IsActivated(joystickState, LeftJoycon.DPadUp)) buttons |= ControllerButtons.DpadUp;
  128. if (IsActivated(joystickState, LeftJoycon.DPadDown)) buttons |= ControllerButtons.DpadDown;
  129. if (IsActivated(joystickState, LeftJoycon.DPadLeft)) buttons |= ControllerButtons.DpadLeft;
  130. if (IsActivated(joystickState, LeftJoycon.DPadRight)) buttons |= ControllerButtons.DPadRight;
  131. if (IsActivated(joystickState, LeftJoycon.StickButton)) buttons |= ControllerButtons.StickLeft;
  132. if (IsActivated(joystickState, LeftJoycon.ButtonMinus)) buttons |= ControllerButtons.Minus;
  133. if (IsActivated(joystickState, LeftJoycon.ButtonL)) buttons |= ControllerButtons.L;
  134. if (IsActivated(joystickState, LeftJoycon.ButtonZl)) buttons |= ControllerButtons.Zl;
  135. if (IsActivated(joystickState, RightJoycon.ButtonA)) buttons |= ControllerButtons.A;
  136. if (IsActivated(joystickState, RightJoycon.ButtonB)) buttons |= ControllerButtons.B;
  137. if (IsActivated(joystickState, RightJoycon.ButtonX)) buttons |= ControllerButtons.X;
  138. if (IsActivated(joystickState, RightJoycon.ButtonY)) buttons |= ControllerButtons.Y;
  139. if (IsActivated(joystickState, RightJoycon.StickButton)) buttons |= ControllerButtons.StickRight;
  140. if (IsActivated(joystickState, RightJoycon.ButtonPlus)) buttons |= ControllerButtons.Plus;
  141. if (IsActivated(joystickState, RightJoycon.ButtonR)) buttons |= ControllerButtons.R;
  142. if (IsActivated(joystickState, RightJoycon.ButtonZr)) buttons |= ControllerButtons.Zr;
  143. return buttons;
  144. }
  145. private bool IsActivated(JoystickState joystickState,ControllerInputId controllerInputId)
  146. {
  147. if (controllerInputId <= ControllerInputId.Button20)
  148. {
  149. return joystickState.IsButtonDown((int)controllerInputId);
  150. }
  151. else if (controllerInputId <= ControllerInputId.Axis5)
  152. {
  153. int axis = controllerInputId - ControllerInputId.Axis0;
  154. return Math.Abs(joystickState.GetAxis(axis)) > Deadzone;
  155. }
  156. else if (controllerInputId <= ControllerInputId.Hat2Right)
  157. {
  158. int hat = (controllerInputId - ControllerInputId.Hat0Up) / 4;
  159. int baseHatId = (int)ControllerInputId.Hat0Up + (hat * 4);
  160. JoystickHatState hatState = joystickState.GetHat((JoystickHat)hat);
  161. if (hatState.IsUp && ((int)controllerInputId % baseHatId == 0)) return true;
  162. if (hatState.IsDown && ((int)controllerInputId % baseHatId == 1)) return true;
  163. if (hatState.IsLeft && ((int)controllerInputId % baseHatId == 2)) return true;
  164. if (hatState.IsRight && ((int)controllerInputId % baseHatId == 3)) return true;
  165. }
  166. return false;
  167. }
  168. public (short, short) GetLeftStick()
  169. {
  170. if (!Enabled)
  171. {
  172. return (0, 0);
  173. }
  174. return GetStick(LeftJoycon.Stick);
  175. }
  176. public (short, short) GetRightStick()
  177. {
  178. if (!Enabled)
  179. {
  180. return (0, 0);
  181. }
  182. return GetStick(RightJoycon.Stick);
  183. }
  184. private (short, short) GetStick(ControllerInputId stickInputId)
  185. {
  186. if (stickInputId < ControllerInputId.Axis0 || stickInputId > ControllerInputId.Axis5)
  187. {
  188. return (0, 0);
  189. }
  190. JoystickState jsState = Joystick.GetState(Index);
  191. int xAxis = stickInputId - ControllerInputId.Axis0;
  192. float xValue = jsState.GetAxis(xAxis);
  193. float yValue = 0 - jsState.GetAxis(xAxis + 1); // Invert Y-axis
  194. return ApplyDeadzone(new Vector2(xValue, yValue));
  195. }
  196. private (short, short) ApplyDeadzone(Vector2 axis)
  197. {
  198. return (ClampAxis(MathF.Abs(axis.X) > Deadzone ? axis.X : 0f),
  199. ClampAxis(MathF.Abs(axis.Y) > Deadzone ? axis.Y : 0f));
  200. }
  201. private static short ClampAxis(float value)
  202. {
  203. if (value <= -short.MaxValue)
  204. {
  205. return -short.MaxValue;
  206. }
  207. else
  208. {
  209. return (short)(value * short.MaxValue);
  210. }
  211. }
  212. }
  213. }