@@ -103,6 +103,101 @@ public XInputControllerOSXState WithButton(Button button)
103103 }
104104 }
105105
106+ // macOS's native bit mapping for Xbox Controllers connected via USB
107+ [ StructLayout ( LayoutKind . Explicit ) ]
108+ internal struct XInputControllerNativeOSXState : IInputStateTypeInfo
109+ {
110+ public static FourCC kFormat => new FourCC ( 'H' , 'I' , 'D' ) ;
111+
112+ public enum Button
113+ {
114+ Start = 2 ,
115+ Select = 3 ,
116+ A = 4 ,
117+ B = 5 ,
118+ X = 6 ,
119+ Y = 7 ,
120+ DPadUp = 8 ,
121+ DPadDown = 9 ,
122+ DPadLeft = 10 ,
123+ DPadRight = 11 ,
124+ LeftShoulder = 12 ,
125+ RightShoulder = 13 ,
126+ LeftThumbstickPress = 14 ,
127+ RightThumbstickPress = 15 ,
128+ }
129+
130+ // IL2CPP on 2021 doesn't respect the FieldOffsets - as such, we need some padding fields
131+ #if UNITY_2021 && ENABLE_IL2CPP
132+ [ FieldOffset ( 0 ) ]
133+ private uint padding ;
134+ #endif
135+
136+ [ InputControl ( name = "buttonSouth" , bit = ( uint ) Button . A , displayName = "A" ) ]
137+ [ InputControl ( name = "buttonEast" , bit = ( uint ) Button . B , displayName = "B" ) ]
138+ [ InputControl ( name = "buttonWest" , bit = ( uint ) Button . X , displayName = "X" ) ]
139+ [ InputControl ( name = "buttonNorth" , bit = ( uint ) Button . Y , displayName = "Y" ) ]
140+ [ InputControl ( name = "start" , bit = ( uint ) Button . Start , displayName = "Start" ) ]
141+ [ InputControl ( name = "select" , bit = ( uint ) Button . Select , displayName = "Select" ) ]
142+ [ InputControl ( name = "dpad" , layout = "Dpad" , sizeInBits = 4 , bit = 0 ) ]
143+ [ InputControl ( name = "dpad/up" , bit = ( uint ) Button . DPadUp ) ]
144+ [ InputControl ( name = "dpad/down" , bit = ( uint ) Button . DPadDown ) ]
145+ [ InputControl ( name = "dpad/left" , bit = ( uint ) Button . DPadLeft ) ]
146+ [ InputControl ( name = "dpad/right" , bit = ( uint ) Button . DPadRight ) ]
147+ [ InputControl ( name = "leftStickPress" , bit = ( uint ) Button . LeftThumbstickPress ) ]
148+ [ InputControl ( name = "rightStickPress" , bit = ( uint ) Button . RightThumbstickPress ) ]
149+ [ InputControl ( name = "leftShoulder" , bit = ( uint ) Button . LeftShoulder ) ]
150+ [ InputControl ( name = "rightShoulder" , bit = ( uint ) Button . RightShoulder ) ]
151+ [ FieldOffset ( 4 ) ]
152+ public ushort buttons ;
153+
154+ [ InputControl ( name = "leftTrigger" , format = "BYTE" ) ]
155+ [ FieldOffset ( 6 ) ] public byte leftTrigger ;
156+
157+ #if UNITY_2021 && ENABLE_IL2CPP
158+ [ FieldOffset ( 7 ) ]
159+ private byte triggerPadding ;
160+ #endif
161+
162+ [ InputControl ( name = "rightTrigger" , format = "BYTE" ) ]
163+ [ FieldOffset ( 8 ) ] public byte rightTrigger ;
164+
165+ #if UNITY_2021 && ENABLE_IL2CPP
166+ [ FieldOffset ( 9 ) ]
167+ private byte triggerPadding2 ;
168+ #endif
169+
170+
171+ [ InputControl ( name = "leftStick" , layout = "Stick" , format = "VC2S" ) ]
172+ [ InputControl ( name = "leftStick/x" , offset = 0 , format = "SHRT" , parameters = "" ) ]
173+ [ InputControl ( name = "leftStick/left" , offset = 0 , format = "SHRT" , parameters = "" ) ]
174+ [ InputControl ( name = "leftStick/right" , offset = 0 , format = "SHRT" , parameters = "" ) ]
175+ [ InputControl ( name = "leftStick/y" , offset = 2 , format = "SHRT" , parameters = "" ) ]
176+ [ InputControl ( name = "leftStick/up" , offset = 2 , format = "SHRT" , parameters = "clamp=1,clampMin=0,clampMax=1,invert=false" ) ]
177+ [ InputControl ( name = "leftStick/down" , offset = 2 , format = "SHRT" , parameters = "clamp=1,clampMin=-1,clampMax=0,invert=true" ) ]
178+ [ FieldOffset ( 10 ) ] public short leftStickX ;
179+ [ FieldOffset ( 12 ) ] public short leftStickY ;
180+
181+ [ InputControl ( name = "rightStick" , layout = "Stick" , format = "VC2S" ) ]
182+ [ InputControl ( name = "rightStick/x" , offset = 0 , format = "SHRT" , parameters = "" ) ]
183+ [ InputControl ( name = "rightStick/left" , offset = 0 , format = "SHRT" , parameters = "" ) ]
184+ [ InputControl ( name = "rightStick/right" , offset = 0 , format = "SHRT" , parameters = "" ) ]
185+ [ InputControl ( name = "rightStick/y" , offset = 2 , format = "SHRT" , parameters = "" ) ]
186+ [ InputControl ( name = "rightStick/up" , offset = 2 , format = "SHRT" , parameters = "clamp=1,clampMin=0,clampMax=1,invert=false" ) ]
187+ [ InputControl ( name = "rightStick/down" , offset = 2 , format = "SHRT" , parameters = "clamp=1,clampMin=-1,clampMax=0,invert=true" ) ]
188+ [ FieldOffset ( 14 ) ] public short rightStickX ;
189+ [ FieldOffset ( 16 ) ] public short rightStickY ;
190+
191+ public FourCC format => kFormat ;
192+
193+ public XInputControllerNativeOSXState WithButton ( Button button )
194+ {
195+ Debug . Assert ( ( int ) button < 16 , $ "A maximum of 16 buttons is supported for this layout.") ;
196+ buttons |= ( ushort ) ( 1U << ( int ) button ) ;
197+ return this ;
198+ }
199+ }
200+
106201 [ StructLayout ( LayoutKind . Explicit ) ]
107202 internal struct XInputControllerWirelessOSXState : IInputStateTypeInfo
108203 {
@@ -296,22 +391,37 @@ namespace UnityEngine.InputSystem.XInput
296391 /// </summary>
297392 /// <remarks>
298393 /// An Xbox 360 or Xbox one wired gamepad connected to a mac.
299- /// These controllers don't work on a mac out of the box, but require a driver like https://github.com/360Controller/
300- /// to work.
394+ /// This layout is used for macOS versions when https://github.com/360Controller/ was required
395+ /// On modern macOS versions, you will instead get a device with class XboxGamepadMacOSNative
301396 /// </remarks>
302397 [ InputControlLayout ( displayName = "Xbox Controller" , stateType = typeof ( XInputControllerOSXState ) , hideInUI = true ) ]
303398 public class XboxGamepadMacOS : XInputController
304399 {
305400 }
306401
402+ /// <summary>
403+ /// A wired Xbox Gamepad connected to a macOS computer
404+ /// </summary>
405+ /// <remarks>
406+ /// An Xbox 360 or Xbox One wired gamepad connected ot a Mac.
407+ /// This layout is used on modern macOS systems. It is different from <see cref="XboxGamepadMacOS"/>, due to that working with older
408+ /// systems that are using the 360Controller driver.
409+ /// macOS's native controller support provides a bit mapping which is different to 360Controller's mapping
410+ /// As such this is a new device, in order to not break existing projects.
411+ /// </remarks>
412+ [ InputControlLayout ( displayName = "Xbox Controller" , stateType = typeof ( XInputControllerNativeOSXState ) , hideInUI = true ) ]
413+ public class XboxGamepadMacOSNative : XInputController
414+ {
415+ }
416+
307417 /// <summary>
308418 /// A wireless Xbox One Gamepad connected to a macOS computer.
309419 /// </summary>
310420 /// <remarks>
311421 /// An Xbox One wireless gamepad connected to a mac using Bluetooth.
312422 /// Note: only the latest version of Xbox One wireless gamepads support Bluetooth. Older models only work
313423 /// with a proprietary Xbox wireless protocol, and cannot be used on a Mac.
314- /// Unlike wired controllers, bluetooth-cabable Xbox One controllers do not need a custom driver to work on macOS.
424+ /// Unlike wired controllers, bluetooth-cabable Xbox One controllers do not need a custom driver to work on older macOS versions
315425 /// </remarks>
316426 [ InputControlLayout ( displayName = "Wireless Xbox Controller" , stateType = typeof ( XInputControllerWirelessOSXState ) , hideInUI = true ) ]
317427 public class XboxOneGampadMacOSWireless : XInputController
@@ -328,7 +438,7 @@ public class XboxOneGampadMacOSWireless : XInputController
328438 /// that some Xbox One and Xbox Series controller share the same mappings so this combines them all.
329439 /// Note: only the latest version of Xbox One wireless gamepads support Bluetooth. Older models only work
330440 /// with a proprietary Xbox wireless protocol, and cannot be used on a Mac.
331- /// Unlike wired controllers, bluetooth-cabable Xbox One controllers do not need a custom driver to work on macOS.
441+ /// Unlike wired controllers, bluetooth-cabable Xbox One controllers do not need a custom driver to work on older macOS versions
332442 /// </remarks>
333443 [ InputControlLayout ( displayName = "Wireless Xbox Controller" , stateType = typeof ( XInputControllerWirelessOSXStateV2 ) , hideInUI = true ) ]
334444 public class XboxGamepadMacOSWireless : XInputController
0 commit comments