@@ -111,7 +111,7 @@ internal struct XInputControllerWirelessOSXState : IInputStateTypeInfo
111111 public enum Button
112112 {
113113 Start = 11 ,
114- Select = 10 ,
114+ Select = 16 ,
115115 LeftThumbstickPress = 13 ,
116116 RightThumbstickPress = 14 ,
117117 LeftShoulder = 6 ,
@@ -194,6 +194,98 @@ public XInputControllerWirelessOSXState WithDpad(byte value)
194194 leftStickY = 32767
195195 } ;
196196 }
197+
198+ [ StructLayout ( LayoutKind . Explicit ) ]
199+ internal struct XInputControllerWirelessOSXStateV2 : IInputStateTypeInfo
200+ {
201+ public static FourCC kFormat => new FourCC ( 'H' , 'I' , 'D' ) ;
202+
203+ public enum Button
204+ {
205+ Start = 11 ,
206+ Select = 10 ,
207+ LeftThumbstickPress = 13 ,
208+ RightThumbstickPress = 14 ,
209+ LeftShoulder = 6 ,
210+ RightShoulder = 7 ,
211+ A = 0 ,
212+ B = 1 ,
213+ X = 3 ,
214+ Y = 4 ,
215+ }
216+ [ FieldOffset ( 0 ) ]
217+ private byte padding ;
218+
219+ [ InputControl ( name = "leftStick" , layout = "Stick" , format = "VC2S" ) ]
220+ [ InputControl ( name = "leftStick/x" , offset = 0 , format = "USHT" , parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5" ) ]
221+ [ 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" ) ]
222+ [ InputControl ( name = "leftStick/right" , offset = 0 , format = "USHT" , parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1" ) ]
223+ [ InputControl ( name = "leftStick/y" , offset = 2 , format = "USHT" , parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5" ) ]
224+ [ 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" ) ]
225+ [ 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" ) ]
226+ [ FieldOffset ( 1 ) ] public ushort leftStickX ;
227+ [ FieldOffset ( 3 ) ] public ushort leftStickY ;
228+
229+ [ InputControl ( name = "rightStick" , layout = "Stick" , format = "VC2S" ) ]
230+ [ InputControl ( name = "rightStick/x" , offset = 0 , format = "USHT" , parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5" ) ]
231+ [ 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" ) ]
232+ [ InputControl ( name = "rightStick/right" , offset = 0 , format = "USHT" , parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1" ) ]
233+ [ InputControl ( name = "rightStick/y" , offset = 2 , format = "USHT" , parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5" ) ]
234+ [ 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" ) ]
235+ [ 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" ) ]
236+ [ FieldOffset ( 5 ) ] public ushort rightStickX ;
237+ [ FieldOffset ( 7 ) ] public ushort rightStickY ;
238+
239+ [ InputControl ( name = "leftTrigger" , format = "USHT" , parameters = "normalize,normalizeMin=0,normalizeMax=0.01560998" ) ]
240+ [ FieldOffset ( 9 ) ] public ushort leftTrigger ;
241+ [ InputControl ( name = "rightTrigger" , format = "USHT" , parameters = "normalize,normalizeMin=0,normalizeMax=0.01560998" ) ]
242+ [ FieldOffset ( 11 ) ] public ushort rightTrigger ;
243+
244+ [ InputControl ( name = "dpad" , format = "BIT" , layout = "Dpad" , sizeInBits = 4 , defaultState = 8 ) ]
245+ [ InputControl ( name = "dpad/up" , format = "BIT" , layout = "DiscreteButton" , parameters = "minValue=8,maxValue=2,nullValue=0,wrapAtValue=9" , bit = 0 , sizeInBits = 4 ) ]
246+ [ InputControl ( name = "dpad/right" , format = "BIT" , layout = "DiscreteButton" , parameters = "minValue=2,maxValue=4" , bit = 0 , sizeInBits = 4 ) ]
247+ [ InputControl ( name = "dpad/down" , format = "BIT" , layout = "DiscreteButton" , parameters = "minValue=4,maxValue=6" , bit = 0 , sizeInBits = 4 ) ]
248+ [ InputControl ( name = "dpad/left" , format = "BIT" , layout = "DiscreteButton" , parameters = "minValue=6, maxValue=8" , bit = 0 , sizeInBits = 4 ) ]
249+ [ FieldOffset ( 13 ) ]
250+ public byte dpad ;
251+
252+ [ InputControl ( name = "start" , bit = ( uint ) Button . Start , displayName = "Start" ) ]
253+ [ InputControl ( name = "select" , bit = ( uint ) Button . Select , displayName = "Select" ) ]
254+ [ InputControl ( name = "leftStickPress" , bit = ( uint ) Button . LeftThumbstickPress ) ]
255+ [ InputControl ( name = "rightStickPress" , bit = ( uint ) Button . RightThumbstickPress ) ]
256+ [ InputControl ( name = "leftShoulder" , bit = ( uint ) Button . LeftShoulder ) ]
257+ [ InputControl ( name = "rightShoulder" , bit = ( uint ) Button . RightShoulder ) ]
258+ [ InputControl ( name = "buttonSouth" , bit = ( uint ) Button . A , displayName = "A" ) ]
259+ [ InputControl ( name = "buttonEast" , bit = ( uint ) Button . B , displayName = "B" ) ]
260+ [ InputControl ( name = "buttonWest" , bit = ( uint ) Button . X , displayName = "X" ) ]
261+ [ InputControl ( name = "buttonNorth" , bit = ( uint ) Button . Y , displayName = "Y" ) ]
262+
263+ [ FieldOffset ( 14 ) ]
264+ public uint buttons ;
265+
266+ public FourCC format => kFormat ;
267+
268+ public XInputControllerWirelessOSXStateV2 WithButton ( Button button )
269+ {
270+ Debug . Assert ( ( int ) button < 32 , $ "Expected button < 32, so we fit into the 32 bit wide bitmask") ;
271+ buttons |= 1U << ( int ) button ;
272+ return this ;
273+ }
274+
275+ public XInputControllerWirelessOSXStateV2 WithDpad ( byte value )
276+ {
277+ dpad = value ;
278+ return this ;
279+ }
280+
281+ public static XInputControllerWirelessOSXStateV2 defaultState => new XInputControllerWirelessOSXStateV2
282+ {
283+ rightStickX = 32767 ,
284+ rightStickY = 32767 ,
285+ leftStickX = 32767 ,
286+ leftStickY = 32767
287+ } ;
288+ }
197289}
198290namespace UnityEngine . InputSystem . XInput
199291{
@@ -223,5 +315,22 @@ public class XboxGamepadMacOS : XInputController
223315 public class XboxOneGampadMacOSWireless : XInputController
224316 {
225317 }
318+
319+ /// <summary>
320+ /// A wireless Xbox One or Xbox Series Gamepad connected to a macOS computer.
321+ /// </summary>
322+ /// <remarks>
323+ /// An Xbox One/Series wireless gamepad connected to a mac using Bluetooth.
324+ /// The reason this is different from <see cref="XboxOneGampadMacOSWireless"/> is that some Xbox Controllers have
325+ /// different View and Share button bit mapping. So we need to use a different layout for those controllers. It seems
326+ /// that some Xbox One and Xbox Series controller share the same mappings so this combines them all.
327+ /// Note: only the latest version of Xbox One wireless gamepads support Bluetooth. Older models only work
328+ /// with a proprietary Xbox wireless protocol, and cannot be used on a Mac.
329+ /// Unlike wired controllers, bluetooth-cabable Xbox One controllers do not need a custom driver to work on macOS.
330+ /// </remarks>
331+ [ InputControlLayout ( displayName = "Wireless Xbox Controller" , stateType = typeof ( XInputControllerWirelessOSXStateV2 ) , hideInUI = true ) ]
332+ public class XboxGamepadMacOSWireless : XInputController
333+ {
334+ }
226335}
227336#endif // UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
0 commit comments