NpadController.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 StickButton;
  65. public ControllerInputId ButtonA;
  66. public ControllerInputId ButtonB;
  67. public ControllerInputId ButtonX;
  68. public ControllerInputId ButtonY;
  69. public ControllerInputId ButtonPlus;
  70. public ControllerInputId ButtonR;
  71. public ControllerInputId ButtonZr;
  72. }
  73. public class NpadController
  74. {
  75. /// <summary>
  76. /// Enables or disables controller support
  77. /// </summary>
  78. public bool Enabled { get; private set; }
  79. /// <summary>
  80. /// Controller Device Index
  81. /// </summary>
  82. public int Index { get; private set; }
  83. /// <summary>
  84. /// Controller Analog Stick Deadzone
  85. /// </summary>
  86. public float Deadzone { get; private set; }
  87. /// <summary>
  88. /// Controller Trigger Threshold
  89. /// </summary>
  90. public float TriggerThreshold { get; private set; }
  91. /// <summary>
  92. /// Left JoyCon Controller Bindings
  93. /// </summary>
  94. public NpadControllerLeft LeftJoycon { get; private set; }
  95. /// <summary>
  96. /// Right JoyCon Controller Bindings
  97. /// </summary>
  98. public NpadControllerRight RightJoycon { get; private set; }
  99. public NpadController(
  100. bool enabled,
  101. int index,
  102. float deadzone,
  103. float triggerThreshold,
  104. NpadControllerLeft leftJoycon,
  105. NpadControllerRight rightJoycon)
  106. {
  107. Enabled = enabled;
  108. Index = index;
  109. Deadzone = deadzone;
  110. TriggerThreshold = triggerThreshold;
  111. LeftJoycon = leftJoycon;
  112. RightJoycon = rightJoycon;
  113. }
  114. public void SetEnabled(bool enabled)
  115. {
  116. Enabled = enabled;
  117. }
  118. public ControllerButtons GetButtons()
  119. {
  120. if (!Enabled)
  121. {
  122. return 0;
  123. }
  124. JoystickState joystickState = Joystick.GetState(Index);
  125. ControllerButtons buttons = 0;
  126. if (IsActivated(joystickState, LeftJoycon.DPadUp)) buttons |= ControllerButtons.DpadUp;
  127. if (IsActivated(joystickState, LeftJoycon.DPadDown)) buttons |= ControllerButtons.DpadDown;
  128. if (IsActivated(joystickState, LeftJoycon.DPadLeft)) buttons |= ControllerButtons.DpadLeft;
  129. if (IsActivated(joystickState, LeftJoycon.DPadRight)) buttons |= ControllerButtons.DPadRight;
  130. if (IsActivated(joystickState, LeftJoycon.StickButton)) buttons |= ControllerButtons.StickLeft;
  131. if (IsActivated(joystickState, LeftJoycon.ButtonMinus)) buttons |= ControllerButtons.Minus;
  132. if (IsActivated(joystickState, LeftJoycon.ButtonL)) buttons |= ControllerButtons.L;
  133. if (IsActivated(joystickState, LeftJoycon.ButtonZl)) buttons |= ControllerButtons.Zl;
  134. if (IsActivated(joystickState, RightJoycon.ButtonA)) buttons |= ControllerButtons.A;
  135. if (IsActivated(joystickState, RightJoycon.ButtonB)) buttons |= ControllerButtons.B;
  136. if (IsActivated(joystickState, RightJoycon.ButtonX)) buttons |= ControllerButtons.X;
  137. if (IsActivated(joystickState, RightJoycon.ButtonY)) buttons |= ControllerButtons.Y;
  138. if (IsActivated(joystickState, RightJoycon.StickButton)) buttons |= ControllerButtons.StickRight;
  139. if (IsActivated(joystickState, RightJoycon.ButtonPlus)) buttons |= ControllerButtons.Plus;
  140. if (IsActivated(joystickState, RightJoycon.ButtonR)) buttons |= ControllerButtons.R;
  141. if (IsActivated(joystickState, RightJoycon.ButtonZr)) buttons |= ControllerButtons.Zr;
  142. return buttons;
  143. }
  144. private bool IsActivated(JoystickState joystickState,ControllerInputId controllerInputId)
  145. {
  146. if (controllerInputId <= ControllerInputId.Button20)
  147. {
  148. return joystickState.IsButtonDown((int)controllerInputId);
  149. }
  150. else if (controllerInputId <= ControllerInputId.Axis5)
  151. {
  152. int axis = controllerInputId - ControllerInputId.Axis0;
  153. return joystickState.GetAxis(axis) > TriggerThreshold;
  154. }
  155. else if (controllerInputId <= ControllerInputId.Hat2Right)
  156. {
  157. int hat = (controllerInputId - ControllerInputId.Hat0Up) / 4;
  158. int baseHatId = (int)ControllerInputId.Hat0Up + (hat * 4);
  159. JoystickHatState hatState = joystickState.GetHat((JoystickHat)hat);
  160. if (hatState.IsUp && ((int)controllerInputId % baseHatId == 0)) return true;
  161. if (hatState.IsDown && ((int)controllerInputId % baseHatId == 1)) return true;
  162. if (hatState.IsLeft && ((int)controllerInputId % baseHatId == 2)) return true;
  163. if (hatState.IsRight && ((int)controllerInputId % baseHatId == 3)) return true;
  164. }
  165. return false;
  166. }
  167. public (short, short) GetLeftStick()
  168. {
  169. if (!Enabled)
  170. {
  171. return (0, 0);
  172. }
  173. return GetStick(LeftJoycon.Stick);
  174. }
  175. public (short, short) GetRightStick()
  176. {
  177. if (!Enabled)
  178. {
  179. return (0, 0);
  180. }
  181. return GetStick(RightJoycon.Stick);
  182. }
  183. private (short, short) GetStick(ControllerInputId stickInputId)
  184. {
  185. if (stickInputId < ControllerInputId.Axis0 || stickInputId > ControllerInputId.Axis5)
  186. {
  187. return (0, 0);
  188. }
  189. JoystickState jsState = Joystick.GetState(Index);
  190. int xAxis = stickInputId - ControllerInputId.Axis0;
  191. float xValue = jsState.GetAxis(xAxis);
  192. float yValue = 0 - jsState.GetAxis(xAxis + 1); // Invert Y-axis
  193. return ApplyDeadzone(new Vector2(xValue, yValue));
  194. }
  195. private (short, short) ApplyDeadzone(Vector2 axis)
  196. {
  197. return (ClampAxis(MathF.Abs(axis.X) > Deadzone ? axis.X : 0f),
  198. ClampAxis(MathF.Abs(axis.Y) > Deadzone ? axis.Y : 0f));
  199. }
  200. private static short ClampAxis(float value)
  201. {
  202. if (value <= -short.MaxValue)
  203. {
  204. return -short.MaxValue;
  205. }
  206. else
  207. {
  208. return (short)(value * short.MaxValue);
  209. }
  210. }
  211. }
  212. }