A new year has begun and so we implemented new features as DirectX 11 and XInput. As DirectInput is depricated and not usable in windows 8 store games, it is still supported on windows 7 and 8. The Xbox 360 controller works also with DirectInput, but the two triggers on the back of the controller act as one axis. You can only use one trigger at a time which is rater inconvenient.
Therefor we implemented XInput to use all the Xbox 360 controller features like the two triggers on the back and the vibration function which. We choose to redirect all input of the Xbox controller to the game itself and not go though our input action mapper. This has some advantages as well as disadvantages. We can directly read the players input for each controller, but in the game we need to map the keys for the Xbox 360 controller separately, where the mapping was automatic for keyboard, mouse and DirectInput controller. We might change this in the future as the mapping turned out to be really convenient and versatile. We could for example map player 1 and player 2 to the same controller, a combination of a controller and a keyboard and/or mouse. The mapping function looks like this:
void MapInput(string action, string device, string button);
This is universal for DirectInput, mouse and keyboard. Action is a user defined string, device is the device, “kb” for keyboard, “mouse” for mouse, “joy1″ for joystick 1, “joy2″ for joystick 2 and to forth… with a support of maximum 10 joysticks.
To read the input we have a function:
bool GetInput(string action, out ActionBinding binding);
which returns a bool if the key is down or not and where action is the user defined string (e.g. “Jump”, or “Shoot”). The interesting part is the ActionBinding. This struct returns a few parameters like if the button that was press is a digital or an analog axis and if the key was pressed. This means if the key was up the previous frame and this frame its down, pressed is true. If the key was down the previous frame, and now it’s still down, false is returned. This is a simple event that can be used to prevent repeated actions while the key is down. It’s only fired once, and reset when the user release the button. For analog axis this is different, the pressed is never fired and the down state is always true except when the stick is perfectly centered.
As XInput defines 4 controllers and we want the controllers to be able to vibrate, this interface would be too generic as every action can be mapped to every available button or axis and the engine does not distinguish between different controllers.
We are able to enumerate devices, and maybe we can put a limit per controller on a player when we do the input mapping in-game. But this needs to be dynamic as player 1 may want to play with the keyboard and player 2 with a game pad or the other way around. Or maybe both players want to play with different gamepads. Also I do not want the user to continuously remap the controls when something is changed. This is still something we need to work out.