A game about forced loneliness, made by TACStudios
1// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled.
2#if UNITY_INPUT_SYSTEM_ENABLE_XR && (ENABLE_VR || UNITY_GAMECORE) || PACKAGE_DOCS_GENERATION
3using System.Runtime.InteropServices;
4using UnityEngine.InputSystem.LowLevel;
5using UnityEngine.InputSystem.Utilities;
6
7namespace UnityEngine.InputSystem.XR.Haptics
8{
9 /// <summary>
10 /// Describes the haptic capabilities of a specific device.
11 /// </summary>
12 public struct HapticCapabilities
13 {
14 /// <summary>
15 /// Initializes and returns an instance of <see cref="HapticCapabilities"/>.
16 /// </summary>
17 /// <param name="numChannels">The number of haptic channels available on this device.</param>
18 /// <param name="supportsImpulse">This device supports sending a haptic impulse.</param>
19 /// <param name="supportsBuffer">This device supports sending a haptic buffer.</param>
20 /// <param name="frequencyHz">The buffer frequency the device operates at in Hertz.</param>
21 /// <param name="maxBufferSize">The max amount of buffer data that can be stored by the device.</param>
22 /// <param name="optimalBufferSize">The optimal size of a device's buffer, taking into account frequency and latency.</param>
23 public HapticCapabilities(uint numChannels, bool supportsImpulse, bool supportsBuffer, uint frequencyHz, uint maxBufferSize, uint optimalBufferSize)
24 {
25 this.numChannels = numChannels;
26 this.supportsImpulse = supportsImpulse;
27 this.supportsBuffer = supportsBuffer;
28 this.frequencyHz = frequencyHz;
29 this.maxBufferSize = maxBufferSize;
30 this.optimalBufferSize = optimalBufferSize;
31 }
32
33 /// <summary>
34 /// Deprecated. Use <see cref="HapticCapabilities(uint, bool, bool, uint, uint, uint)"/> instead.
35 /// This constructor did not match the native haptic capabilities struct and was missing properties.
36 /// </summary>
37 /// <param name="numChannels">The number of haptic channels available on this device.</param>
38 /// <param name="frequencyHz">The buffer frequency the device operates at in Hertz.</param>
39 /// <param name="maxBufferSize">The max amount of buffer data that can be stored by the device.</param>
40 public HapticCapabilities(uint numChannels, uint frequencyHz, uint maxBufferSize)
41 : this(numChannels, false, false, frequencyHz, maxBufferSize, 0U)
42 {
43 }
44
45 /// <summary>
46 /// The number of haptic channels available on this device.
47 /// </summary>
48 public uint numChannels { get; }
49
50 /// <summary>
51 /// This device supports sending a haptic impulse.
52 /// </summary>
53 /// <seealso cref="SendHapticImpulseCommand"/>
54 public bool supportsImpulse { get; }
55
56 /// <summary>
57 /// This device supports sending a haptic buffer.
58 /// </summary>
59 /// <seealso cref="SendBufferedHapticCommand"/>
60 public bool supportsBuffer { get; }
61
62 /// <summary>
63 /// The buffer frequency the device operates at in Hertz. This impacts how fast the device consumes buffered haptic data.
64 /// </summary>
65 /// <remarks>
66 /// This value is greater than 0 if <see cref="supportsBuffer"/> is <see langword="true"/>, and 0 otherwise.
67 /// </remarks>
68 public uint frequencyHz { get; }
69
70 /// <summary>
71 /// The max amount of buffer data that can be stored by the device.
72 /// </summary>
73 public uint maxBufferSize { get; }
74
75 /// <summary>
76 /// The optimal size of a device's buffer, taking into account frequency and latency.
77 /// </summary>
78 public uint optimalBufferSize { get; }
79 }
80
81 /// <summary>
82 /// Input device command struct for retrieving the haptic capabilities of a device.
83 /// </summary>
84 [StructLayout(LayoutKind.Explicit, Size = kSize)]
85 public struct GetHapticCapabilitiesCommand : IInputDeviceCommandInfo
86 {
87 static FourCC Type => new FourCC('X', 'H', 'C', '0');
88
89 // 20 bytes of data from uint(4) + bool(1) + bool(1) + padding + uint(4) + uint(4) + uint(4)
90 const int kSize = InputDeviceCommand.kBaseCommandSize + 20;
91
92 /// <inheritdoc />
93 public FourCC typeStatic => Type;
94
95 [FieldOffset(0)]
96 InputDeviceCommand baseCommand;
97
98 /// <summary>
99 /// The number of haptic channels available on this device.
100 /// </summary>
101 [FieldOffset(InputDeviceCommand.kBaseCommandSize)]
102 public uint numChannels;
103
104 /// <summary>
105 /// This device supports sending a haptic impulse.
106 /// </summary>
107 /// <seealso cref="SendHapticImpulseCommand"/>
108 [FieldOffset(InputDeviceCommand.kBaseCommandSize + 4)]
109 public bool supportsImpulse;
110
111 /// <summary>
112 /// This device supports sending a haptic buffer.
113 /// </summary>
114 /// <seealso cref="SendBufferedHapticCommand"/>
115 [FieldOffset(InputDeviceCommand.kBaseCommandSize + 5)]
116 public bool supportsBuffer;
117
118 /// <summary>
119 /// The buffer frequency the device operates at in Hertz. This impacts how fast the device consumes buffered haptic data.
120 /// </summary>
121 /// <remarks>
122 /// This value is greater than 0 if <see cref="supportsBuffer"/> is <see langword="true"/>, and 0 otherwise.
123 /// </remarks>
124 [FieldOffset(InputDeviceCommand.kBaseCommandSize + 8)]
125 public uint frequencyHz;
126
127 /// <summary>
128 /// The max amount of buffer data that can be stored by the device.
129 /// </summary>
130 [FieldOffset(InputDeviceCommand.kBaseCommandSize + 12)]
131 public uint maxBufferSize;
132
133 /// <summary>
134 /// The optimal size of a device's buffer, taking into account frequency and latency.
135 /// </summary>
136 [FieldOffset(InputDeviceCommand.kBaseCommandSize + 16)]
137 public uint optimalBufferSize;
138
139 /// <summary>
140 /// The haptic capabilities of the device, populated after this command is executed.
141 /// </summary>
142 public HapticCapabilities capabilities => new HapticCapabilities(numChannels, supportsImpulse, supportsBuffer, frequencyHz, maxBufferSize, optimalBufferSize);
143
144 /// <summary>
145 /// Creates and returns a new initialized input device command struct for retrieving
146 /// the haptic capabilities of a device when executed.
147 /// </summary>
148 /// <returns>Returns a new command struct with the data header initialized, making it ready to execute.</returns>
149 /// <seealso cref="InputDevice.ExecuteCommand{TCommand}(ref TCommand)"/>
150 public static GetHapticCapabilitiesCommand Create()
151 {
152 return new GetHapticCapabilitiesCommand
153 {
154 baseCommand = new InputDeviceCommand(Type, kSize),
155 };
156 }
157 }
158}
159#endif