DirectInput API Reference
The DirectInput API provides a unified interface for accessing input devices such as keyboards, mice, joysticks, gamepads, and other human interface devices (HIDs) on Windows. It allows applications to query device capabilities, set device properties, and receive input data.
Core Concepts
DirectInput operates on several key concepts:
- Devices: Represents a physical input hardware (e.g., a specific joystick).
- Cooperative Levels: Defines how an application interacts with input devices, especially in the presence of other applications. This includes foreground/background access and exclusive/non-exclusive modes.
- Device Objects: Specific elements within a device that provide input (e.g., a button on a joystick, the X-axis of a mouse).
- Effects: For devices that support force feedback, DirectInput allows applications to create and manage force feedback effects (e.g., vibration, spring force).
- DIJOYCONFIG and DIJOYSTATE: Structures used to configure and retrieve the state of joystick devices.
Key Interfaces and Structures
DirectInput exposes a set of COM interfaces and data structures essential for its operation:
Interfaces
IDirectInput8- The primary interface for interacting with DirectInput. Used to enumerate devices, create device objects, and manage global settings.
IDirectInputDevice8- Represents an individual input device. Used to acquire/unacquire devices, set cooperative levels, retrieve device capabilities, and get input data.
IDirectInputEffect- Represents a force feedback effect. Used to set effect parameters, start, stop, and download effects.
Structures
DIDEVICEINSTANCE- Contains information about a detected input device, including its name, instance GUID, and product GUID.
DIDEVCAPS- Describes the capabilities of an input device, such as the number of axes, buttons, and POVs it possesses.
DIJOYSTATE- Holds the current state of a joystick device, including the position of axes, buttons pressed, and POV hat positions.
DIENVELOPE- Defines the parameters for an envelope effect (attack, sustain, decay) in force feedback.
DICONSTANTFORCE- Defines parameters for a constant force effect in force feedback.
Common Operations
Enumerating Devices
To find available input devices, you typically use the EnumDevices method of the IDirectInput8 interface.
HRESULT EnumDevices(
DWORD dwDevType,
LPDIENUMDEVICESCALLBACK lpCallBack,
LPVOID pvRef,
DWORD dwFlags
);
The callback function receives a DIDEVICEINSTANCE structure for each enumerated device.
Acquiring and Unacquiring Devices
Before an application can read input from a device, it must acquire it using the Acquire method of the IDirectInputDevice8 interface. Conversely, it should release the device using Unacquire when it's no longer needed.
HRESULT Acquire();
HRESULT Unacquire();
Getting Device State
The GetDeviceState method of IDirectInputDevice8 is used to retrieve the current input state of a device. For joysticks, this typically populates a DIJOYSTATE structure.
HRESULT GetDeviceState(
DWORD cbData,
LPVOID lpvData
);
Example for a joystick:
DIJOYSTATE js;
// ... after acquiring the joystick device
hr = pJoystick->GetDeviceState(sizeof(DIJOYSTATE), &js);
if (SUCCEEDED(hr)) {
// Process js.lX, js.lY, js.rgbButtons, etc.
}
Setting Cooperative Levels
The SetCooperativeLevel method determines how your application shares input devices with others.
HRESULT SetCooperativeLevel(
HWND hwnd,
DWORD dwFlags
);
Common flags include DISCL_NONEXCLUSIVE, DISCL_EXCLUSIVE, DISCL_FOREGROUND, and DISCL_BACKGROUND.
Force Feedback
DirectInput supports force feedback devices, allowing for immersive experiences. This involves creating and managing effects.
Creating Effects
Use the CreateEffect method of IDirectInputDevice8 to create a force feedback effect.
HRESULT CreateEffect(
REFGUID rguid,
LPCDIEFFECTINFO lpdIeif,
LPDIRECTINPUTEFFECT* ppdeff,
LPUNKNOWN punkOuter
);
Managing Effects
Once created, effects can be configured, started, and stopped using methods on the IDirectInputEffect interface, such as SetParameters, Start, and Stop.
Considerations
- DirectInput is a COM-based API. Ensure proper COM initialization and uninitialization.
- Error handling is crucial. Always check the return values of DirectInput functions.
- For modern game development, consider using the newer Game Input API, which offers a more unified and performance-oriented approach.