Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

479 lines
12 KiB

<HTML>
<HEAD>
<TITLE>Designing HID Gaming Devices for DirectInput</TITLE>
</HEAD>
<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#808080 ALINK=#000000>
<H2>Designing HID Gaming Devices for DirectInput 5.0x and Beyond</H2>
<ADDRESS>
Raymond Chen<br>
Microsoft Corporation<br>
4 November 1997
</ADDRESS>
<h3>Abstract</h3>
<p>
When designing a game controller compliant with the
Human Interface Devices (HID)
firmware specification,
<!-- version 1.0 -->
care should be taken to ensure that the device
expresses its capabilities in a manner that
applications can exploit.
This document 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.
<h3>Definitions</h3>
<p>
Since input devices can be oriented in several attitudes,
this document will attempt to avoid using terms such as
"up" and "left". Instead, compass directions will be used
("north", "west", <i>etc</i>.)
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.
<h3>Device Usage and Usage Page</h3>
<p>
For DirectInput to recognize a HID game controller
as a joystick or gamepad,
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.
<p>
Although devices declared otherwise will still
be accessible to DirectInput applications
which request non-joystick-compatible devices, the vast majority
of gaming applications
restrict themselves to joystick-compatible input
devices.
<h3>Logical and Physical Ranges</h3>
<p>
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 gameport capacitor to charge after a discharge.
Consequently, applications have assumed that calibration values
are never negative.
<p>
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.
<p>
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 lie 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.
<h3>Absolute <i>versus</i> Relative</h3>
<p>
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 which use
DirectInput will receive integrated values, but applications which
use the old Multimedia functions to access the device will receive
non-integrated deltas and will likely not handle the values properly.
Furthermore, even applications which use DirectInput typically do
not expect to receive unrestricted values (as would result from
integration of a relative control).
<h3>HID and DirectInput</h3>
<p>
Beginning with Windows 98 and Windows NT 5.0,
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.
<p>
The following table describes how DirectInput maps HID
usages to axis types.
<p align=center>
<table border>
<tr>
<th>Usage Page</th>
<th>Usage</th>
<th>DirectInput</th>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x30 (X)</td>
<td align=center>X</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x31 (Y)</td>
<td align=center>Y</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x32 (Z)</td>
<td align=center>Z</td>
</tr>
<tr>
<td>0x02 (Simulation)</td>
<td>0xBA (Rudder)</td>
<td align=center>Z</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x33 (RX)</td>
<td align=center>Rx</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x34 (RY)</td>
<td align=center>Ry</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x35 (RZ)</td>
<td align=center>Rz</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x36 (Slider)</td>
<td align=center>Slider</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x37 (Dial)</td>
<td align=center>Slider</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x38 (Wheel)</td>
<td align=center>Slider</td>
</tr>
<tr>
<td>0x02 (Simulation)</td>
<td>0xBB (Throttle)</td>
<td align=center>Slider</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x39 (Hatswitch)</td>
<td align=center>POV</td>
</tr>
<tr>
<td>0x09 (Button)</td>
<td>any</td>
<td align=center>Buttons</td>
</tr>
<tr>
<td>any</td>
<td>any (see below)</td>
<td align=center>Buttons</td>
</tr>
</table></p>
<p>
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".
<p>
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 POV's, two sliders, and one
each of X, Y, Z, Rx, Ry, and Rz.
<p>
X and Y axes must report their values as increasing east and south,
respectively. This requirement is in agreement with the HID specification.
<p>
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, the following two tables describe two different
types of Hat Switches, one with eight positions and one with four positions.
<p align=center>
<table border>
<tr>
<th>Value</th>
<th>8-direction</th>
<th>4-direction</th>
</tr>
<tr>
<td>Logical Minimum</td>
<td align=right>0</td>
<td align=right>0</td>
</tr>
<tr>
<td>Logical Maximum</td>
<td align=right>7</td>
<td align=right>3</td>
</tr>
<tr>
<td>Null value</td>
<td align=right>-1</td>
<td align=right>-1</td>
</tr>
<tr>
<td>North</td>
<td align=right>0</td>
<td align=right>0</td>
</tr>
<tr>
<td>Northeast</td>
<td align=right>1</td>
<td align=right>N/A</td>
</tr>
<tr>
<td>East</td>
<td align=right>2</td>
<td align=right>1</td>
</tr>
<tr>
<td>Southeast</td>
<td align=right>3</td>
<td align=right>N/A</td>
</tr>
<tr>
<td>South</td>
<td align=right>4</td>
<td align=right>2</td>
</tr>
<tr>
<td>Southwest</td>
<td align=right>5</td>
<td align=right>N/A</td>
</tr>
<tr>
<td>West</td>
<td align=right>6</td>
<td align=right>3</td>
</tr>
<tr>
<td>Northwest</td>
<td align=right>7</td>
<td align=right>N/A</td>
</tr>
</table></p>
<p>
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 compass directions
could in principle report itself as if it were an 8-direction Hat Switch.
However, devices which 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.)
<p>
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).
<p>
Although usages not listed in the above table will still be
accessible via DirectInput,
few game applications will take advantage of their existence.
<h3>HID and Legacy Game Controller API's in Windows 98</h3>
<p>
In Windows 98, the HID-to-legacy mapper (JoyHID.VxD)
maps
HID usages to the "classical" joystick axes, named 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 as a rudder. The Z control
is often used as a throttle.
<p>
(The issue of allowing applications to assign semantics to controls
in an intelligent manner is the subject of a separate document.)
<p>
The following table describes how JOYHID maps HID
usages to "classical" joystick axes, buttons, and POV controllers.
<p align=center>
<table border>
<tr>
<th>Usage Page</th>
<th>Usage</th>
<th>JoyHID.VxD</th>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x30 (X)</td>
<td align=center>X</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x31 (Y)</td>
<td align=center>Y</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x32 (Z)</td>
<td align=center>Z</td>
</tr>
<tr>
<td>0x02 (Simulation)</td>
<td>0xBB (Throttle)</td>
<td align=center>Z or U</td>
</tr>
<tr>
<td>0x02 (Simulation)</td>
<td>0xBA (Rudder)</td>
<td align=center>R</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x35 (RZ)</td>
<td align=center>R</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x36 (Slider)</td>
<td align=center>U</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x37 (Dial)</td>
<td align=center>U</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x33 (RX)</td>
<td align=center>V</td>
</tr>
<tr>
<td>0x09 (Button)</td>
<td>any</td>
<td align=center>Buttons</td>
</tr>
<tr>
<td>0x01 (Generic)</td>
<td>0x39 (Hatswitch)</td>
<td align=center>POV</td>
</tr>
</table></p>
<p>
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 classical axis U, and the dial will be
ignored.
<p>
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.)
<p>
For buttons, all usages reported on the Button page (0x09) will be
reported, but they must be consecutively numbered starting from zero.
<p>
The requirements on X-axis, Y-axis, and Hat Switch controls
which apply to DirectInput also apply here.
<p>
Any usages that do not appear in the above table are ignored by JoyHID.VxD.
<h3>References</h3>
<p>
<cite>
<a href=http://www.usb.org/>Universal Serial Bus</a>
HID Usage Tables</cite>, Version 1.0,
USB Implementers Forum.
<p>
<cite>
<a href=http://www.microsoft.com/directx/resources/dx5ddk.htm>
DirectX 5.0 DDK</a>
</cite>, Microsoft Corporation.
<p>
<cite>
<a href=http://www.microsoft.com/directx/resources/dx5sdk.htm>
DirectX 5.0 SDK</a>
</cite>, Microsoft Corporation.
</BODY>
</HTML>