A game about forced loneliness, made by TACStudios
1using System; 2using UnityEngine.InputSystem.Controls; 3using UnityEngine.InputSystem.Layouts; 4 5////TODO: expose user index 6 7////TODO: set displayNames of the controls according to Xbox controller standards 8 9namespace UnityEngine.InputSystem.XInput 10{ 11 /// <summary> 12 /// An XInput-compatible game controller. 13 /// </summary> 14 /// <remarks> 15 /// Note that on non-Microsoft platforms, XInput controllers will not actually use the XInput interface 16 /// but will rather be interfaced with through different APIs -- on OSX, for example, HID is used to 17 /// interface with Xbox controlllers. In those cases, XInput-specific functionality (like <see cref="Capabilities"/>) 18 /// will not be available. 19 /// 20 /// On Windows, XInput controllers will be reported with <see cref="InputDeviceDescription.interfaceName"/> 21 /// set to <c>"XInput"</c> and with a JSON representation of <a 22 /// href="https://docs.microsoft.com/en-us/windows/win32/api/xinput/ns-xinput-xinput_capabilities">XINPUT_CAPABILITIES</a> 23 /// available in <see cref="InputDeviceDescription.capabilities"/>. This means that you match on those 24 /// <c>subType</c> and/or <c>flags</c> for example. 25 /// 26 /// <example> 27 /// <code> 28 /// // Create an XInput-specific guitar layout subtype. 29 /// // NOTE: Works only on Windows. 30 /// InputSystem.RegisterLayout(@" 31 /// { 32 /// ""name"" : ""XInputGuitar"", 33 /// ""displayName"" : ""Guitar"", 34 /// ""extend"" : ""XInputController"", 35 /// ""device"" : { 36 /// ""interface"" : ""XInput"", 37 /// ""capabilities"" : [ 38 /// { ""path"" : ""subType"", ""value"" : ""6"" } 39 /// ] 40 /// } 41 /// } 42 /// "); 43 /// </code> 44 /// </example> 45 /// 46 /// Now, when an XInput controller is connected and reports itself with the 47 /// subtype "Guitar", it is turned into an "XInputGuitar" instead of an 48 /// "XInputController". 49 /// </remarks> 50 [InputControlLayout(displayName = "Xbox Controller")] 51 public class XInputController : Gamepad 52 { 53 /// <summary> 54 /// Same as <see cref="Gamepad.startButton"/>. 55 /// </summary> 56 /// <value>Same control as <see cref="Gamepad.startButton"/>.</value> 57 // Change the display names for the buttons to conform to Xbox conventions. 58 [InputControl(name = "buttonSouth", displayName = "A")] 59 [InputControl(name = "buttonEast", displayName = "B")] 60 [InputControl(name = "buttonWest", displayName = "X")] 61 [InputControl(name = "buttonNorth", displayName = "Y")] 62 [InputControl(name = "leftShoulder", displayName = "Left Bumper", shortDisplayName = "LB")] 63 [InputControl(name = "rightShoulder", displayName = "Right Bumper", shortDisplayName = "RB")] 64 [InputControl(name = "leftTrigger", shortDisplayName = "LT")] 65 [InputControl(name = "rightTrigger", shortDisplayName = "RT")] 66 // This follows Xbox One conventions; on Xbox 360, this is start=start and select=back. 67 [InputControl(name = "start", displayName = "Menu", alias = "menu")] 68 [InputControl(name = "select", displayName = "View", alias = "view")] 69 public ButtonControl menu { get; protected set; } 70 71 /// <summary> 72 /// Same as <see cref="Gamepad.selectButton"/> 73 /// </summary> 74 /// <value>Same control as <see cref="Gamepad.selectButton"/>.</value> 75 public ButtonControl view { get; protected set; } 76 77 /// <summary> 78 /// What specific kind of XInput controller this is. 79 /// </summary> 80 /// <value>XInput device subtype.</value> 81 /// <remarks> 82 /// When the controller is picked up through interfaces other than XInput or through old versions of 83 /// XInput, this will always be <see cref="DeviceSubType.Unknown"/>. Put another way, this value is 84 /// meaningful only on recent Microsoft platforms. 85 /// </remarks> 86 /// <seealso href="https://docs.microsoft.com/en-us/windows/win32/xinput/xinput-and-controller-subtypes"/> 87 public DeviceSubType subType 88 { 89 get 90 { 91 if (!m_HaveParsedCapabilities) 92 ParseCapabilities(); 93 return m_SubType; 94 } 95 } 96 97 /// <summary> 98 /// Return the device flags as reported by XInput. 99 /// </summary> 100 /// <value>XInput device flags.</value> 101 /// <seealso href="https://docs.microsoft.com/en-us/windows/win32/api/xinput/ns-xinput-xinput_capabilities"/> 102 public DeviceFlags flags 103 { 104 get 105 { 106 if (!m_HaveParsedCapabilities) 107 ParseCapabilities(); 108 return m_Flags; 109 } 110 } 111 112 /// <inheritdoc /> 113 protected override void FinishSetup() 114 { 115 base.FinishSetup(); 116 117 menu = startButton; 118 view = selectButton; 119 } 120 121 private bool m_HaveParsedCapabilities; 122 private DeviceSubType m_SubType; 123 private DeviceFlags m_Flags; 124 125 private void ParseCapabilities() 126 { 127 if (!string.IsNullOrEmpty(description.capabilities)) 128 { 129 var capabilities = JsonUtility.FromJson<Capabilities>(description.capabilities); 130 m_SubType = capabilities.subType; 131 m_Flags = capabilities.flags; 132 } 133 m_HaveParsedCapabilities = true; 134 } 135 136 /// <summary> 137 /// Controller type enumeration in <c>Type</c> field of <c>XINPUT_CAPABILITIES</c>. 138 /// </summary> 139 /// <remarks> 140 /// See <a href="https://docs.microsoft.com/en-us/windows/win32/api/xinput/ns-xinput-xinput_capabilities">MSDN</a>. 141 /// </remarks> 142 internal enum DeviceType 143 { 144 Gamepad = 0x00 145 } 146 147 /// <summary> 148 /// Controller subtype enumeration in <c>SubType</c> field of <c>XINPUT_CAPABILITIES</c>. 149 /// </summary> 150 /// <remarks> 151 /// See <a href="https://docs.microsoft.com/en-us/windows/win32/xinput/xinput-and-controller-subtypes">MSDN</a>. 152 /// </remarks> 153 public enum DeviceSubType 154 { 155 Unknown = 0x00, 156 Gamepad = 0x01, 157 Wheel = 0x02, 158 ArcadeStick = 0x03, 159 FlightStick = 0x04, 160 DancePad = 0x05, 161 Guitar = 0x06, 162 GuitarAlternate = 0x07, 163 DrumKit = 0x08, 164 GuitarBass = 0x0B, 165 ArcadePad = 0x13 166 } 167 168 /// <summary> 169 /// Controller flags in <c>Flags</c> field of <c>XINPUT_CAPABILITIES</c>. 170 /// </summary> 171 /// <remarks> 172 /// See <a href="https://docs.microsoft.com/en-us/windows/win32/api/xinput/ns-xinput-xinput_capabilities">MSDN</a>. 173 /// </remarks> 174 [Flags] 175 public new enum DeviceFlags 176 { 177 ForceFeedbackSupported = 0x01, 178 Wireless = 0x02, 179 VoiceSupported = 0x04, 180 PluginModulesSupported = 0x08, 181 NoNavigation = 0x10, 182 } 183 184 [Serializable] 185 internal struct Capabilities 186 { 187 public DeviceType type; 188 public DeviceSubType subType; 189 public DeviceFlags flags; 190 } 191 } 192}