SwitchProControllerHID.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_WSA || PACKAGE_DOCS_GENERATION
  2. using System;
  3. using System.Runtime.InteropServices;
  4. using UnityEngine.InputSystem.Controls;
  5. using UnityEngine.InputSystem.Layouts;
  6. using UnityEngine.InputSystem.LowLevel;
  7. using UnityEngine.InputSystem.Switch.LowLevel;
  8. using UnityEngine.InputSystem.Utilities;
  9. ////REVIEW: The Switch controller can be used to point at things; can we somehow help leverage that?
  10. namespace UnityEngine.InputSystem.Switch.LowLevel
  11. {
  12. #if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_WSA
  13. /// <summary>
  14. /// Structure of HID input reports for Switch Pro controllers.
  15. /// </summary>
  16. [StructLayout(LayoutKind.Explicit, Size = 20)]
  17. internal struct SwitchProControllerHIDInputState : IInputStateTypeInfo
  18. {
  19. public FourCC format => new FourCC('H', 'I', 'D');
  20. [InputControl(name = "dpad", format = "BIT", layout = "Dpad", bit = 24, sizeInBits = 4, defaultState = 8)]
  21. [InputControl(name = "dpad/up", format = "BIT", layout = "DiscreteButton", parameters = "minValue=7,maxValue=1,nullValue=8,wrapAtValue=7", bit = 24, sizeInBits = 4)]
  22. [InputControl(name = "dpad/right", format = "BIT", layout = "DiscreteButton", parameters = "minValue=1,maxValue=3", bit = 24, sizeInBits = 4)]
  23. [InputControl(name = "dpad/down", format = "BIT", layout = "DiscreteButton", parameters = "minValue=3,maxValue=5", bit = 24, sizeInBits = 4)]
  24. [InputControl(name = "dpad/left", format = "BIT", layout = "DiscreteButton", parameters = "minValue=5, maxValue=7", bit = 24, sizeInBits = 4)]
  25. [InputControl(name = "buttonNorth", displayName = "X", shortDisplayName = "X", bit = (uint)Button.North)]
  26. [InputControl(name = "buttonSouth", displayName = "B", shortDisplayName = "B", bit = (uint)Button.South, usage = "Back")]
  27. [InputControl(name = "buttonWest", displayName = "Y", shortDisplayName = "Y", bit = (uint)Button.West, usage = "SecondaryAction")]
  28. [InputControl(name = "buttonEast", displayName = "A", shortDisplayName = "A", bit = (uint)Button.East, usage = "PrimaryAction")]
  29. [InputControl(name = "leftStickPress", displayName = "Left Stick", bit = (uint)Button.StickL)]
  30. [InputControl(name = "rightStickPress", displayName = "Right Stick", bit = (uint)Button.StickR)]
  31. [InputControl(name = "leftShoulder", displayName = "L", shortDisplayName = "L", bit = (uint)Button.L)]
  32. [InputControl(name = "rightShoulder", displayName = "R", shortDisplayName = "R", bit = (uint)Button.R)]
  33. [InputControl(name = "leftTrigger", displayName = "ZL", shortDisplayName = "ZL", format = "BIT", bit = (uint)Button.ZL)]
  34. [InputControl(name = "rightTrigger", displayName = "ZR", shortDisplayName = "ZR", format = "BIT", bit = (uint)Button.ZR)]
  35. [InputControl(name = "start", displayName = "Plus", bit = (uint)Button.Plus, usage = "Menu")]
  36. [InputControl(name = "select", displayName = "Minus", bit = (uint)Button.Minus)]
  37. [FieldOffset(0)]
  38. public uint buttons;
  39. [InputControl(name = "leftStick", format = "VC2S", layout = "Stick")]
  40. [InputControl(name = "leftStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0.15,normalizeMax=0.85,normalizeZero=0.5")]
  41. [InputControl(name = "leftStick/left", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0.15,normalizeMax=0.85,normalizeZero=0.5,clamp=1,clampMin=0.15,clampMax=0.5,invert")]
  42. [InputControl(name = "leftStick/right", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0.15,normalizeMax=0.85,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=0.85")]
  43. [InputControl(name = "leftStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0.15,normalizeMax=0.85,normalizeZero=0.5")]
  44. [InputControl(name = "leftStick/up", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0.15,normalizeMax=0.85,normalizeZero=0.5,clamp=1,clampMin=0.15,clampMax=0.5,invert")]
  45. [InputControl(name = "leftStick/down", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0.15,normalizeMax=0.85,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=0.85,invert=false")]
  46. [FieldOffset(4)] public ushort leftStickX;
  47. [FieldOffset(6)] public ushort leftStickY;
  48. [InputControl(name = "rightStick", format = "VC2S", layout = "Stick")]
  49. [InputControl(name = "rightStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0.15,normalizeMax=0.85,normalizeZero=0.5")]
  50. [InputControl(name = "rightStick/left", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0.15,normalizeMax=0.85,normalizeZero=0.5,clamp=1,clampMin=0,clampMax=0.5,invert")]
  51. [InputControl(name = "rightStick/right", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0.15,normalizeMax=0.85,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1")]
  52. [InputControl(name = "rightStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0.15,normalizeMax=0.85,normalizeZero=0.5")]
  53. [InputControl(name = "rightStick/up", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0.15,normalizeMax=0.85,normalizeZero=0.5,clamp=1,clampMin=0.15,clampMax=0.5,invert")]
  54. [InputControl(name = "rightStick/down", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0.15,normalizeMax=0.85,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=0.85,invert=false")]
  55. [FieldOffset(8)] public ushort rightStickX;
  56. [FieldOffset(10)] public ushort rightStickY;
  57. public float leftTrigger => ((buttons & (1 << (int)Button.ZL)) != 0) ? 1f : 0f;
  58. public float rightTrigger => ((buttons & (1 << (int)Button.ZR)) != 0) ? 1f : 0f;
  59. public enum Button
  60. {
  61. North = 11,
  62. South = 8,
  63. West = 10,
  64. East = 9,
  65. StickL = 18,
  66. StickR = 19,
  67. L = 12,
  68. R = 13,
  69. ZL = 14,
  70. ZR = 15,
  71. Plus = 17,
  72. Minus = 16,
  73. X = North,
  74. B = South,
  75. Y = West,
  76. A = East,
  77. }
  78. public SwitchProControllerHIDInputState WithButton(Button button, bool value = true)
  79. {
  80. var bit = (uint)1 << (int)button;
  81. if (value)
  82. buttons |= bit;
  83. else
  84. buttons &= ~bit;
  85. // dpad default state
  86. buttons |= 8 << 24;
  87. leftStickX = 0x8000;
  88. leftStickY = 0x8000;
  89. rightStickX = 0x8000;
  90. rightStickY = 0x8000;
  91. return this;
  92. }
  93. }
  94. #endif
  95. }
  96. namespace UnityEngine.InputSystem.Switch
  97. {
  98. #if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_WSA || PACKAGE_DOCS_GENERATION
  99. /// <summary>
  100. /// A Nintendo Switch Pro controller connected to a desktop mac/windows PC using the HID interface.
  101. /// </summary>
  102. [InputControlLayout(stateType = typeof(SwitchProControllerHIDInputState), displayName = "Switch Pro Controller")]
  103. [Scripting.Preserve]
  104. public class SwitchProControllerHID : Gamepad
  105. {
  106. }
  107. #endif
  108. }
  109. #endif // UNITY_EDITOR || UNITY_SWITCH