HID Game Controllers and DirectInput
Updated: December 4, 2001
On This Page
Purpose and Terms
When designing a game controller compliant with USB Device Class Definition for Human Interface Devices (HID), Version 1.11, care should be taken to ensure that the device expresses its capabilities in a manner that applications can exploit. This article briefly outlines issues that should be taken into consideration to allow the device to be used by the widest range of applications across a variety of operating system platforms. Development work for this at Microsoft applies specifically to the Microsoft Windows family of operating systems.
Because input devices can be oriented in several attitudes, this article will attempt to avoid using terms such as "up" and "left." Instead, compass directions will be used ("north," "west," and so on). For a control mounted on a horizontal surface, "north" is typically represented by motion away from the user. For a control mounted on a vertical surface, "north" is typically represented by motion away from the earth. In general, devices should choose a northerly direction that is intuitively obvious to the user.
Device Usage and Usage Page
For Microsoft DirectInput to recognize a HID game controller as a joystick or game pad, it must declare its top-level collection as belonging to the Generic Desktop Page (0x01), and deploy usage Joystick (0x04) or Game Pad (0x05), respectively.
Although devices declared otherwise will still be accessible to DirectInput applications that request non-joystick-compatible devices, the vast majority of gaming applications restrict themselves to joystick-compatible input devices.
Logical and Physical Ranges
Absolute axes on gaming devices should express their physical ranges entirely with non-negative integers. Historically, calibration information has been expressed in unspecified time units, indicating how long it takes the joystick game port capacitor to charge after a discharge. Consequently, applications have assumed that calibration values are never negative.
Logical ranges, of course, can indeed be negative. It is recommended that the device translate its logical range by the minimum value, thereby making all physical values non-negative. For example, a joystick might report its X-axis with the logical range -512 to +511. A corresponding physical range of 0 to +1023 would retain full resolution while ensuring that the resulting physical values are non-negative.
It is also recommended that the logical range accurately describes the full range of motion of the control, and that the center position of the control lies at the midpoint between the minimum and maximum values. When DirectInput first encounters a device, it uses the logical range information as the basis for the default calibration. If a device conforms to this recommendation, the end user is relieved of the responsibility of calibration, allowing your device to be truly Plug and Play.
Absolute versus Relative
Applications assume that all axes on a game controller return absolute coordinates rather than relative coordinates. If a device reports its axes as relative, applications that use DirectInput will receive integrated values, but applications that use the earlier multimedia APIs to access the device will receive non-integrated deltas and will likely not handle the values properly. Furthermore, even applications that use DirectInput typically do not expect to receive unrestricted values (as would result from integration of a relative control).
HID and DirectInput
Beginning with Windows 98 and Windows 2000, DirectInput maps HID usages to its own concept of axis semantics, named X, Y, Z, Rx, Ry, Rz (rotations), and Slider. Again, each application is free to apply arbitrary semantics to each of these axis types. Table 1 describes how DirectInput maps HID usages to axis types.
Table 1. DirectInput Mapping of HID Usages to Axis Types
Although usages not listed in the above table will still be accessible through DirectInput, few game applications will take advantage of their existence.
DirectInput treats any usage on any usage page with bit size of unity as a button. Furthermore, any usage on the Button page is treated as a button, even if its bit size is greater than unity. Under such conditions, DirectInput treats the button as a "button with intermediate positions." Such a button can report to the application states such as "half-pressed."
DirectInput does not limit the number of usages that can map to each type of axis. Applications designed for DirectInput typically request up to 128 buttons, four points of view (POVs), two sliders, and one each of X, Y, Z, Rx, Ry, and Rz.
X and Y axes must report their values as increasing when the control's position is moved to the east and south, respectively. This requirement is in agreement with the USB HID specification.
Hat switch controls must report a Null value when not pressed. When pressed, the logical minimum value represents north, and increasing logical values represent directions equally spaced clockwise around the compass. For example, Table 2 describes two different types of hat switches, one with eight positions and one with four positions.
Table 2. Hat Switches with 8 and 4 Positions
Devices are strongly recommended not to report logical ranges with higher resolution than physically supported by the device. For example, a device whose hat switch supports four positions could in principle report itself as if it were an 8-position hat switch. However, devices that do so will mislead applications into believing that the control supports a higher degree of resolution than it actually does. (DirectInput provides a method for applications to query the resolution of a hat switch, and DirectInput relies on the accuracy of the values in the report descriptor to report the resolution accurately.)
DirectInput requires that the hat switch reside in its own capability descriptor. Do not combine the hat switch capability with capabilities for adjacent usages (Wheel and Counted Buffer).
HID and the Earlier Multimedia APIs in Windows 98
In Windows 98, the HID-to-legacy mapper (Joyhid.vxd, which is a Vjoyd.vxd minidriver) maps HID usages to the "classical" joystick axes X, Y, Z, R, U, and V. Each application is free to apply arbitrary semantics to each of these axes, although the X and Y axes are customarily used for two-dimensional motion control and the R control is customarily used as a rudder. The Z control is often used as a throttle.
Table 3 describes how JOYHID maps HID usages to "classical" joystick axes, buttons, and POV controls.
Table 3. JOYHID Mapping of HID Usages to Joystick Axes, Buttons, and POV Controls
If more than one control can map to an axis or button or POV, then the first one on the list is used and the others are ignored. For example, if a joystick has both a slider and a dial, then the slider will be mapped to the classical axis U, and the dial will be ignored.
As a special case, a throttle will be mapped to the Z-axis unless the Z-axis has already been claimed by the Z control, in which case it will be mapped to the U-axis. (In such case, the throttle will displace any slider or dial that would otherwise be mapped to the U-axis.)
For buttons, all usages reported on the Button page (0x09) will be mapped, but they must be consecutively numbered starting from Usage ID 0x01 (Button 1). The requirements on X-axis, Y-axis, and hat switch controls that apply to DirectInput also apply here.
Any usage that does not appear in Table 3 is ignored by Joyhid.vxd.
USB Device Class Definition for Human Interface Devices (HID), Version 1.11