No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

XboxGamepadMacOS.cs 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. #if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX || PACKAGE_DOCS_GENERATION
  2. using System.Runtime.InteropServices;
  3. using UnityEngine.InputSystem.Layouts;
  4. using UnityEngine.InputSystem.LowLevel;
  5. using UnityEngine.InputSystem.XInput.LowLevel;
  6. using UnityEngine.InputSystem.Utilities;
  7. using UnityEngine.Scripting;
  8. namespace UnityEngine.InputSystem.XInput.LowLevel
  9. {
  10. // Xbox one controller on OSX. State layout can be found here:
  11. // https://github.com/360Controller/360Controller/blob/master/360Controller/ControlStruct.h
  12. // struct InputReport
  13. // {
  14. // byte command;
  15. // byte size;
  16. // short buttons;
  17. // byte triggerLeft;
  18. // byte triggerRight;
  19. // short leftX;
  20. // short leftY;
  21. // short rightX;
  22. // short rightY;
  23. // }
  24. // Report size is 14 bytes. First two bytes are header information for the report.
  25. [StructLayout(LayoutKind.Explicit)]
  26. internal struct XInputControllerOSXState : IInputStateTypeInfo
  27. {
  28. public static FourCC kFormat => new FourCC('H', 'I', 'D');
  29. public enum Button
  30. {
  31. DPadUp = 0,
  32. DPadDown = 1,
  33. DPadLeft = 2,
  34. DPadRight = 3,
  35. Start = 4,
  36. Select = 5,
  37. LeftThumbstickPress = 6,
  38. RightThumbstickPress = 7,
  39. LeftShoulder = 8,
  40. RightShoulder = 9,
  41. A = 12,
  42. B = 13,
  43. X = 14,
  44. Y = 15,
  45. }
  46. [FieldOffset(0)]
  47. private ushort padding;
  48. [InputControl(name = "dpad", layout = "Dpad", sizeInBits = 4, bit = 0)]
  49. [InputControl(name = "dpad/up", bit = (uint)Button.DPadUp)]
  50. [InputControl(name = "dpad/down", bit = (uint)Button.DPadDown)]
  51. [InputControl(name = "dpad/left", bit = (uint)Button.DPadLeft)]
  52. [InputControl(name = "dpad/right", bit = (uint)Button.DPadRight)]
  53. [InputControl(name = "start", bit = (uint)Button.Start, displayName = "Start")]
  54. [InputControl(name = "select", bit = (uint)Button.Select, displayName = "Select")]
  55. [InputControl(name = "leftStickPress", bit = (uint)Button.LeftThumbstickPress)]
  56. [InputControl(name = "rightStickPress", bit = (uint)Button.RightThumbstickPress)]
  57. [InputControl(name = "leftShoulder", bit = (uint)Button.LeftShoulder)]
  58. [InputControl(name = "rightShoulder", bit = (uint)Button.RightShoulder)]
  59. [InputControl(name = "buttonSouth", bit = (uint)Button.A, displayName = "A")]
  60. [InputControl(name = "buttonEast", bit = (uint)Button.B, displayName = "B")]
  61. [InputControl(name = "buttonWest", bit = (uint)Button.X, displayName = "X")]
  62. [InputControl(name = "buttonNorth", bit = (uint)Button.Y, displayName = "Y")]
  63. [FieldOffset(2)]
  64. public ushort buttons;
  65. [InputControl(name = "leftTrigger", format = "BYTE")]
  66. [FieldOffset(4)] public byte leftTrigger;
  67. [InputControl(name = "rightTrigger", format = "BYTE")]
  68. [FieldOffset(5)] public byte rightTrigger;
  69. [InputControl(name = "leftStick", layout = "Stick", format = "VC2S")]
  70. [InputControl(name = "leftStick/x", offset = 0, format = "SHRT", parameters = "")]
  71. [InputControl(name = "leftStick/left", offset = 0, format = "SHRT", parameters = "")]
  72. [InputControl(name = "leftStick/right", offset = 0, format = "SHRT", parameters = "")]
  73. [InputControl(name = "leftStick/y", offset = 2, format = "SHRT", parameters = "invert")]
  74. [InputControl(name = "leftStick/up", offset = 2, format = "SHRT", parameters = "clamp=1,clampMin=-1,clampMax=0,invert=true")]
  75. [InputControl(name = "leftStick/down", offset = 2, format = "SHRT", parameters = "clamp=1,clampMin=0,clampMax=1,invert=false")]
  76. [FieldOffset(6)] public short leftStickX;
  77. [FieldOffset(8)] public short leftStickY;
  78. [InputControl(name = "rightStick", layout = "Stick", format = "VC2S")]
  79. [InputControl(name = "rightStick/x", offset = 0, format = "SHRT", parameters = "")]
  80. [InputControl(name = "rightStick/left", offset = 0, format = "SHRT", parameters = "")]
  81. [InputControl(name = "rightStick/right", offset = 0, format = "SHRT", parameters = "")]
  82. [InputControl(name = "rightStick/y", offset = 2, format = "SHRT", parameters = "invert")]
  83. [InputControl(name = "rightStick/up", offset = 2, format = "SHRT", parameters = "clamp=1,clampMin=-1,clampMax=0,invert=true")]
  84. [InputControl(name = "rightStick/down", offset = 2, format = "SHRT", parameters = "clamp=1,clampMin=0,clampMax=1,invert=false")]
  85. [FieldOffset(10)] public short rightStickX;
  86. [FieldOffset(12)] public short rightStickY;
  87. public FourCC format => kFormat;
  88. public XInputControllerOSXState WithButton(Button button)
  89. {
  90. Debug.Assert((int)button < 16, $"Expected button < 16, so we fit into the 16 bit wide bitmask");
  91. buttons |= (ushort)(1U << (int)button);
  92. return this;
  93. }
  94. }
  95. [StructLayout(LayoutKind.Explicit)]
  96. internal struct XInputControllerWirelessOSXState : IInputStateTypeInfo
  97. {
  98. public static FourCC kFormat => new FourCC('H', 'I', 'D');
  99. public enum Button
  100. {
  101. Start = 11,
  102. Select = 16,
  103. LeftThumbstickPress = 13,
  104. RightThumbstickPress = 14,
  105. LeftShoulder = 6,
  106. RightShoulder = 7,
  107. A = 0,
  108. B = 1,
  109. X = 3,
  110. Y = 4,
  111. }
  112. [FieldOffset(0)]
  113. private byte padding;
  114. [InputControl(name = "leftStick", layout = "Stick", format = "VC2S")]
  115. [InputControl(name = "leftStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
  116. [InputControl(name = "leftStick/left", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0,clampMax=0.5,invert")]
  117. [InputControl(name = "leftStick/right", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1")]
  118. [InputControl(name = "leftStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
  119. [InputControl(name = "leftStick/up", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0,clampMax=0.5,invert")]
  120. [InputControl(name = "leftStick/down", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1,invert=false")]
  121. [FieldOffset(1)] public ushort leftStickX;
  122. [FieldOffset(3)] public ushort leftStickY;
  123. [InputControl(name = "rightStick", layout = "Stick", format = "VC2S")]
  124. [InputControl(name = "rightStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
  125. [InputControl(name = "rightStick/left", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0,clampMax=0.5,invert")]
  126. [InputControl(name = "rightStick/right", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1")]
  127. [InputControl(name = "rightStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
  128. [InputControl(name = "rightStick/up", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0,clampMax=0.5,invert")]
  129. [InputControl(name = "rightStick/down", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1,invert=false")]
  130. [FieldOffset(5)] public ushort rightStickX;
  131. [FieldOffset(7)] public ushort rightStickY;
  132. [InputControl(name = "leftTrigger", format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=0.01560998")]
  133. [FieldOffset(9)] public ushort leftTrigger;
  134. [InputControl(name = "rightTrigger", format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=0.01560998")]
  135. [FieldOffset(11)] public ushort rightTrigger;
  136. [InputControl(name = "dpad", format = "BIT", layout = "Dpad", sizeInBits = 4, defaultState = 8)]
  137. [InputControl(name = "dpad/up", format = "BIT", layout = "DiscreteButton", parameters = "minValue=8,maxValue=2,nullValue=0,wrapAtValue=9", bit = 0, sizeInBits = 4)]
  138. [InputControl(name = "dpad/right", format = "BIT", layout = "DiscreteButton", parameters = "minValue=2,maxValue=4", bit = 0, sizeInBits = 4)]
  139. [InputControl(name = "dpad/down", format = "BIT", layout = "DiscreteButton", parameters = "minValue=4,maxValue=6", bit = 0, sizeInBits = 4)]
  140. [InputControl(name = "dpad/left", format = "BIT", layout = "DiscreteButton", parameters = "minValue=6, maxValue=8", bit = 0, sizeInBits = 4)]
  141. [FieldOffset(13)]
  142. public byte dpad;
  143. [InputControl(name = "start", bit = (uint)Button.Start, displayName = "Start")]
  144. [InputControl(name = "select", bit = (uint)Button.Select, displayName = "Select")]
  145. [InputControl(name = "leftStickPress", bit = (uint)Button.LeftThumbstickPress)]
  146. [InputControl(name = "rightStickPress", bit = (uint)Button.RightThumbstickPress)]
  147. [InputControl(name = "leftShoulder", bit = (uint)Button.LeftShoulder)]
  148. [InputControl(name = "rightShoulder", bit = (uint)Button.RightShoulder)]
  149. [InputControl(name = "buttonSouth", bit = (uint)Button.A, displayName = "A")]
  150. [InputControl(name = "buttonEast", bit = (uint)Button.B, displayName = "B")]
  151. [InputControl(name = "buttonWest", bit = (uint)Button.X, displayName = "X")]
  152. [InputControl(name = "buttonNorth", bit = (uint)Button.Y, displayName = "Y")]
  153. [FieldOffset(14)]
  154. public uint buttons;
  155. public FourCC format => kFormat;
  156. public XInputControllerWirelessOSXState WithButton(Button button)
  157. {
  158. Debug.Assert((int)button < 32, $"Expected button < 32, so we fit into the 32 bit wide bitmask");
  159. buttons |= 1U << (int)button;
  160. return this;
  161. }
  162. public XInputControllerWirelessOSXState WithDpad(byte value)
  163. {
  164. dpad = value;
  165. return this;
  166. }
  167. public static XInputControllerWirelessOSXState defaultState => new XInputControllerWirelessOSXState
  168. {
  169. rightStickX = 32767,
  170. rightStickY = 32767,
  171. leftStickX = 32767,
  172. leftStickY = 32767
  173. };
  174. }
  175. }
  176. namespace UnityEngine.InputSystem.XInput
  177. {
  178. /// <summary>
  179. /// A wired Xbox Gamepad connected to a macOS computer.
  180. /// </summary>
  181. /// <remarks>
  182. /// An Xbox 360 or Xbox one wired gamepad connected to a mac.
  183. /// These controllers don't work on a mac out of the box, but require a driver like https://github.com/360Controller/
  184. /// to work.
  185. /// </remarks>
  186. [InputControlLayout(displayName = "Xbox Controller", stateType = typeof(XInputControllerOSXState), hideInUI = true)]
  187. public class XboxGamepadMacOS : XInputController
  188. {
  189. }
  190. /// <summary>
  191. /// A wireless Xbox One Gamepad connected to a macOS computer.
  192. /// </summary>
  193. /// <remarks>
  194. /// An Xbox One wireless gamepad connected to a mac using Bluetooth.
  195. /// Note: only the latest version of Xbox One wireless gamepads support Bluetooth. Older models only work
  196. /// with a proprietary Xbox wireless protocol, and cannot be used on a Mac.
  197. /// Unlike wired controllers, bluetooth-cabable Xbox One controllers do not need a custom driver to work on macOS.
  198. /// </remarks>
  199. [InputControlLayout(displayName = "Wireless Xbox Controller", stateType = typeof(XInputControllerWirelessOSXState), hideInUI = true)]
  200. public class XboxOneGampadMacOSWireless : XInputController
  201. {
  202. }
  203. }
  204. #endif // UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX