Skip to content

Commit ea1676c

Browse files
Add new SwitchProControlleriOS device for iOS, which has swapped face buttons
Also includes new state, for any devices which use the Nintendo-y button bindings
1 parent f9ea658 commit ea1676c

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

Packages/com.unity.inputsystem/InputSystem/Plugins/iOS/IOSGameController.cs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#if UNITY_EDITOR || UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS || PACKAGE_DOCS_GENERATION
22
using System.Runtime.InteropServices;
3+
using UnityEngine.InputSystem.Controls;
34
using UnityEngine.InputSystem.DualShock;
45
using UnityEngine.InputSystem.Layouts;
56
using UnityEngine.InputSystem.LowLevel;
@@ -95,6 +96,66 @@ public iOSGameControllerState WithAxis(iOSAxis axis, float value)
9596
return this;
9697
}
9798
}
99+
100+
/// <summary>
101+
/// State for iOS Gamepads using a layout where B button is south, A is east, X is north, and Y is west
102+
/// This layout is typically seen on Nintendo gamepads, such as the Switch Pro Controller.
103+
/// </summary>
104+
[StructLayout(LayoutKind.Sequential)]
105+
internal unsafe struct iOSGameControllerStateSwappedFaceButtons : IInputStateTypeInfo
106+
{
107+
public static FourCC kFormat = new FourCC('I', 'G', 'C', ' ');
108+
public const int MaxButtons = (int)iOSButton.Select + 1;
109+
public const int MaxAxis = (int)iOSAxis.RightStickY + 1;
110+
111+
[InputControl(name = "dpad")]
112+
[InputControl(name = "dpad/up", bit = (uint)iOSButton.DpadUp)]
113+
[InputControl(name = "dpad/right", bit = (uint)iOSButton.DpadRight)]
114+
[InputControl(name = "dpad/down", bit = (uint)iOSButton.DpadDown)]
115+
[InputControl(name = "dpad/left", bit = (uint)iOSButton.DpadLeft)]
116+
[InputControl(name = "buttonSouth", bit = (uint)iOSButton.B)]
117+
[InputControl(name = "buttonWest", bit = (uint)iOSButton.Y)]
118+
[InputControl(name = "buttonNorth", bit = (uint)iOSButton.X)]
119+
[InputControl(name = "buttonEast", bit = (uint)iOSButton.A)]
120+
[InputControl(name = "leftStickPress", bit = (uint)iOSButton.LeftStick)]
121+
[InputControl(name = "rightStickPress", bit = (uint)iOSButton.RightStick)]
122+
[InputControl(name = "leftShoulder", bit = (uint)iOSButton.LeftShoulder)]
123+
[InputControl(name = "rightShoulder", bit = (uint)iOSButton.RightShoulder)]
124+
[InputControl(name = "start", bit = (uint)iOSButton.Start)]
125+
[InputControl(name = "select", bit = (uint)iOSButton.Select)]
126+
public uint buttons;
127+
128+
[InputControl(name = "leftTrigger", offset = sizeof(uint) + sizeof(float) * (uint)iOSButton.LeftTrigger)]
129+
[InputControl(name = "rightTrigger", offset = sizeof(uint) + sizeof(float) * (uint)iOSButton.RightTrigger)]
130+
public fixed float buttonValues[MaxButtons];
131+
132+
private const uint kAxisOffset = sizeof(uint) + sizeof(float) * MaxButtons;
133+
[InputControl(name = "leftStick", offset = (uint)iOSAxis.LeftStickX * sizeof(float) + kAxisOffset)]
134+
[InputControl(name = "rightStick", offset = (uint)iOSAxis.RightStickX * sizeof(float) + kAxisOffset)]
135+
public fixed float axisValues[MaxAxis];
136+
137+
public FourCC format => kFormat;
138+
139+
public iOSGameControllerStateSwappedFaceButtons WithButton(iOSButton button, bool value = true, float rawValue = 1.0f)
140+
{
141+
buttonValues[(int)button] = rawValue;
142+
143+
Debug.Assert((int)button < 32, $"Expected button < 32, so we fit into the 32 bit wide bitmask");
144+
var bit = 1U << (int)button;
145+
if (value)
146+
buttons |= bit;
147+
else
148+
buttons &= ~bit;
149+
150+
return this;
151+
}
152+
153+
public iOSGameControllerStateSwappedFaceButtons WithAxis(iOSAxis axis, float value)
154+
{
155+
axisValues[(int)axis] = value;
156+
return this;
157+
}
158+
}
98159
}
99160

100161
namespace UnityEngine.InputSystem.iOS
@@ -134,5 +195,41 @@ public class DualShock4GampadiOS : DualShockGamepad
134195
public class DualSenseGampadiOS : DualShockGamepad
135196
{
136197
}
198+
199+
/// <summary>
200+
/// A Switch Pro Controller connected to an iOS device.
201+
/// If you use InputSystem.GetDevice, you must query for this class rather than Gamepad in order for aButton, bButton, yButton and xButton to be correct
202+
/// </summary>
203+
[InputControlLayout(stateType = typeof(iOSGameControllerStateSwappedFaceButtons), displayName = "iOS Switch Pro Controller Gamepad")]
204+
public class SwitchProControlleriOS : Gamepad
205+
{
206+
/// <summary>
207+
/// A Button for a Nintendo Switch Pro Controller.
208+
/// If querying via script, ensure you cast the device to SwitchProControlleriOS, rather than using the Gamepad class.
209+
/// The gamepad class will return the state of buttonSouth, whereas this class returns the state of buttonEast
210+
/// </summary>
211+
public new ButtonControl aButton => buttonEast;
212+
213+
/// <summary>
214+
/// A Button for a Nintendo Switch Pro Controller.
215+
/// If querying via script, ensure you cast the device to SwitchProControlleriOS, rather than using the Gamepad class.
216+
/// The gamepad class will return the state of buttonEast, whereas this class returns the state of buttonSouth
217+
/// </summary>
218+
public new ButtonControl bButton => buttonSouth;
219+
220+
/// <summary>
221+
/// A Button for a Nintendo Switch Pro Controller.
222+
/// If querying via script, ensure you cast the device to SwitchProControlleriOS, rather than using the Gamepad class.
223+
/// The gamepad class will return the state of buttonNorth, whereas this class returns the state of buttonWest
224+
/// </summary>
225+
public new ButtonControl yButton => buttonWest;
226+
227+
/// <summary>
228+
/// A Button for a Nintendo Switch Pro Controller.
229+
/// If querying via script, ensure you cast the device to SwitchProControlleriOS, rather than using the Gamepad class.
230+
/// The gamepad class will return the state of buttonWest, whereas this class returns the state of buttonNorth
231+
/// </summary>
232+
public new ButtonControl xButton => buttonNorth;
233+
}
137234
}
138235
#endif // UNITY_EDITOR || UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS

Packages/com.unity.inputsystem/InputSystem/Plugins/iOS/iOSSupport.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ public static void Initialize()
3737
.WithDeviceClass("iOSGameController")
3838
.WithProduct("DualSense Wireless Controller"));
3939

40+
InputSystem.RegisterLayout<SwitchProControlleriOS>("SwitchProGamepadiOS",
41+
matches: new InputDeviceMatcher()
42+
.WithInterface("iOS")
43+
.WithDeviceClass("iOSGameController")
44+
.WithProduct("Pro Controller"));
45+
4046
InputSystem.RegisterLayoutMatcher("GravitySensor",
4147
new InputDeviceMatcher()
4248
.WithInterface("iOS")

0 commit comments

Comments
 (0)