XInput is a relatively new API to the DirectX SDK set of APIs (it was introduced in the December 2005 update). It handles communication with the Xbox 360 common controller when connected to a PC. When developing for the Xbox it also handles other input methods and I expect in the future it will replace DirectInput on the PC (with the addition of keyboard and mouse capabilities).
The Xbox 360 Controller
The controller for the PC is just the same as the Xbox 360 one, the only difference is the drivers that come with it. If you have the Xbox one you can get the correct PC drivers via Windows update.
The XInput API provides a means of reading input (buttons and voice input) and controlling the rumble packs. Note: as yet there is no way of controlling the central light and button. Voice input and output is available if a headset is connected to the controller. These devices can be queried using XInput for sound input and output devices for voice processing.
XInput Library Files
To use the XInput API you must link with Xinput.lib and include the XInput.h header file.
Reading the Xbox 360 Controller state
The Xbox 360 Controller has two analogue directional sticks, each with a digital button, two analogue triggers, a digital directional pad with four directions, and eight digital buttons.
XInput provides a function to query the controller state. The function is XInputGetState and on successful completion it will fill in a XINPUT_STATE structure with the controller state.
DWORD XInputGetState(DWORD index, XINPUT_STATE *state);
index – up to 4 controllers can be attached so this value ranges from 0 to 3 inclusive.
state – the state of each control (see below).
You should check the return value for an error. If the controller is not attached it will return ERROR_DEVICE_NOT_CONNECTED. Note that unlike most of the other DirectX APIs the XInput functions do not return an HRESULT.
State data is returned in the XINPUT_STATE structure. This structure contains another structure (XINPUT_GAMEPAD) and a packet number. The packet number changes whenever the controller changes state. This means that you can store the previous packet number and only need to react on controller states if a new packet number is different.
The XINPUT_GAMEPAD structure describes the current state of the Xbox 360 Controller. It has the following members:
- WORD wButtons – a bit mask specifying which of thedigital buttons are pressed. Possible flags are:
- BYTE bLeftTrigger – value of the left trigger analogue control (ranges from 0 to 255)
- BYTE bRightTrigger – value of the right trigger analogue control
- SHORT sThumbLX – left thumb stick X axis value. Ranges from -32768 to +32768. A value of 0 is middle.
- SHORT sThumbLY – left thumb stick Y axis value.
- SHORT sThumbRX – right thumb stick X axis value.
- SHORT sThumbRY – right thumb stick Y axis value.
Analogue controls suffer from not returning to a central 0 value (or even to the same value twice) hence the idea of a dead zone. This is a range of values that you consider to be zero. This prevents, for example, a spaceship flying off to the side even when the player is not touching the stick. The XINPUT header defines some reasonable dead zone ranges e.g XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE
Setting the Xbox 360 Controller State (Vibration)
The controller has two rumble packs (vibration motors) that can be controlled. The left one is a low frequency one while the right one is a high frequency one. The speed of each can be set using the XInputSetState function:
DWORD XInputSetState(DWORD index, XINPUT_VIBRATION *vibration)
index – specifies the controller, ranges from 0 to 3 inclusive.
vibration – pointer to a XINPUT_VIBRATION structure containing the vibration data to send to the controller (see below)
Again you need to check the return code in case the controller is not connected.
The XINPUT_VIBRATION structure has just two members:
- WORD wLeftMotorSpeed – the left motor speed. Ranges from 0 to 65535 (full speed).
- WORD wRightMotorSpeed – the right motor speed. Ranges from 0 to 65535 (full speed).
There are two more functions available in the API: XInputGetCapabilities and XInputGetDSoundAudioDeviceGUIDS. The first allows a controller to specify what it can do and if it has integrated voice support. The second function retrieves the sound device representing an attached headset for playing and recording sound.