480 lines
12 KiB
HTML
480 lines
12 KiB
HTML
<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>
|