XboxGamepadMacOS.cs 12 KB

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. buttons |= (ushort)((uint)1 << (int)button);
  91. return this;
  92. }
  93. }
  94. [StructLayout(LayoutKind.Explicit)]
  95. internal struct XInputControllerWirelessOSXState : IInputStateTypeInfo
  96. {
  97. public static FourCC kFormat => new FourCC('H', 'I', 'D');
  98. public enum Button
  99. {
  100. Start = 11,
  101. Select = 16,
  102. LeftThumbstickPress = 13,
  103. RightThumbstickPress = 14,
  104. LeftShoulder = 6,
  105. RightShoulder = 7,
  106. A = 0,
  107. B = 1,
  108. X = 3,
  109. Y = 4,
  110. }
  111. [FieldOffset(0)]
  112. private byte padding;
  113. [InputControl(name = "leftStick", layout = "Stick", format = "VC2S")]
  114. [InputControl(name = "leftStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
  115. [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")]
  116. [InputControl(name = "leftStick/right", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1")]
  117. [InputControl(name = "leftStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
  118. [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")]
  119. [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")]
  120. [FieldOffset(1)] public ushort leftStickX;
  121. [FieldOffset(3)] public ushort leftStickY;
  122. [InputControl(name = "rightStick", layout = "Stick", format = "VC2S")]
  123. [InputControl(name = "rightStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
  124. [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")]
  125. [InputControl(name = "rightStick/right", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1")]
  126. [InputControl(name = "rightStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
  127. [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")]
  128. [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")]
  129. [FieldOffset(5)] public ushort rightStickX;
  130. [FieldOffset(7)] public ushort rightStickY;
  131. [InputControl(name = "leftTrigger", format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=0.01560998")]
  132. [FieldOffset(9)] public ushort leftTrigger;
  133. [InputControl(name = "rightTrigger", format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=0.01560998")]
  134. [FieldOffset(11)] public ushort rightTrigger;
  135. [InputControl(name = "dpad", format = "BIT", layout = "Dpad", sizeInBits = 4, defaultState = 8)]
  136. [InputControl(name = "dpad/up", format = "BIT", layout = "DiscreteButton", parameters = "minValue=8,maxValue=2,nullValue=0,wrapAtValue=9", bit = 0, sizeInBits = 4)]
  137. [InputControl(name = "dpad/right", format = "BIT", layout = "DiscreteButton", parameters = "minValue=2,maxValue=4", bit = 0, sizeInBits = 4)]
  138. [InputControl(name = "dpad/down", format = "BIT", layout = "DiscreteButton", parameters = "minValue=4,maxValue=6", bit = 0, sizeInBits = 4)]
  139. [InputControl(name = "dpad/left", format = "BIT", layout = "DiscreteButton", parameters = "minValue=6, maxValue=8", bit = 0, sizeInBits = 4)]
  140. [FieldOffset(13)]
  141. public byte dpad;
  142. [InputControl(name = "start", bit = (uint)Button.Start, displayName = "Start")]
  143. [InputControl(name = "select", bit = (uint)Button.Select, displayName = "Select")]
  144. [InputControl(name = "leftStickPress", bit = (uint)Button.LeftThumbstickPress)]
  145. [InputControl(name = "rightStickPress", bit = (uint)Button.RightThumbstickPress)]
  146. [InputControl(name = "leftShoulder", bit = (uint)Button.LeftShoulder)]
  147. [InputControl(name = "rightShoulder", bit = (uint)Button.RightShoulder)]
  148. [InputControl(name = "buttonSouth", bit = (uint)Button.A, displayName = "A")]
  149. [InputControl(name = "buttonEast", bit = (uint)Button.B, displayName = "B")]
  150. [InputControl(name = "buttonWest", bit = (uint)Button.X, displayName = "X")]
  151. [InputControl(name = "buttonNorth", bit = (uint)Button.Y, displayName = "Y")]
  152. [FieldOffset(14)]
  153. public uint buttons;
  154. public FourCC format => kFormat;
  155. public XInputControllerWirelessOSXState WithButton(Button button)
  156. {
  157. buttons |= (uint)1 << (int)button;
  158. return this;
  159. }
  160. public XInputControllerWirelessOSXState WithDpad(byte value)
  161. {
  162. dpad = value;
  163. return this;
  164. }
  165. public static XInputControllerWirelessOSXState defaultState => new XInputControllerWirelessOSXState
  166. {
  167. rightStickX = 32767,
  168. rightStickY = 32767,
  169. leftStickX = 32767,
  170. leftStickY = 32767
  171. };
  172. }
  173. }
  174. namespace UnityEngine.InputSystem.XInput
  175. {
  176. /// <summary>
  177. /// A wired Xbox Gamepad connected to a macOS computer.
  178. /// </summary>
  179. /// <remarks>
  180. /// An Xbox 360 or Xbox one wired gamepad connected to a mac.
  181. /// These controllers don't work on a mac out of the box, but require a driver like https://github.com/360Controller/
  182. /// to work.
  183. /// </remarks>
  184. [InputControlLayout(displayName = "Xbox Controller", stateType = typeof(XInputControllerOSXState), hideInUI = true)]
  185. [Preserve]
  186. public class XboxGamepadMacOS : XInputController
  187. {
  188. }
  189. /// <summary>
  190. /// A wireless Xbox One Gamepad connected to a macOS computer.
  191. /// </summary>
  192. /// <remarks>
  193. /// An Xbox One wireless gamepad connected to a mac using Bluetooth.
  194. /// Note: only the latest version of Xbox One wireless gamepads support Bluetooth. Older models only work
  195. /// with a proprietary Xbox wireless protocol, and cannot be used on a Mac.
  196. /// Unlike wired controllers, bluetooth-cabable Xbox One controllers do not need a custom driver to work on macOS.
  197. /// </remarks>
  198. [InputControlLayout(displayName = "Wireless Xbox Controller", stateType = typeof(XInputControllerWirelessOSXState), hideInUI = true)]
  199. [Preserve]
  200. public class XboxOneGampadMacOSWireless : XInputController
  201. {
  202. }
  203. }
  204. #endif // UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX