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