Martin Suchan – BloQ Random #WPdev stuff

11Jun/141

Xbox 360 Controller API for Windows Store apps

In Windows Store apps for Windows 8.1 there are four basic input methods - touch, mouse, stylus and keyboard. In most of scenarios these input methods are all you need, but in case you want to offer more natural experience for controlling games on Windows 8.1, you can also add support for Xbox 360 and Xbox One controllers.

In this dev article I'll show you, how to use in any C#/XAML app or game for Windows 8.1 the Xbox 360 Controller API, how to detect presence of such controller and how to poll for current state of all buttons.

Without much ado, let's start with the main fact - for accessing the Xbox Controller in Windows Store apps you can use the XInput Game Controller API:

XInput is a cross-platform API that has shipped for use on Xbox 360 as well as versions of Windows, including Windows XP, Windows Vista, Windows 7, and Windows 8. On Xbox 360, XInput ships as a static library that is compiled into the main game executable. On Windows, XInput is provided as a DLL that is installed into the system folders of the operating system.

The good think is the API is just there, waiting to be used, the bad think is it's not accessible directly from C#/XAML or JavaScript/HTML5 apps. But thanks to the possibilities of Windows Runtime, you can easily create Windows Runtime Component in C++ wrapping the XInput API into more convenient class, that can be directly used from any Windows Store app.

In case you are wondering what is Windows Runtime Component, it's a special kind of library, that can be created in either C++, C# or JavaScript and that can be consumed also in any Windows 8.1 C#, JavaScript or C++ app. The difference between standard library and Windows Runtime Component is, that if you create standard library in C#, you cannot use it in JavaScript or C++ application. Windows Runtime Components can be used in all Windows Store project types thanks to a unique feature called language projection that allows Windows Runtime Components (both native and managed) to be accessed from any language that supports Windows Store app development. More details about creating and using these components can be found on this great MSDN article.

Sadly, I'm not a strong C++ developer, but thanks to this simple XInput and JavaScript controller sketch sample that contains already wrapped XInput API, you have already half work done.

 

So you got library with wrapped XInput, but what it contains and how to use it?

In the XInput sample you can access the XInput class wrapped into Controller object with these methods:

public sealed class Controller
{
    public Controller(uint index);
    public void SetState(ushort leftSpeed, ushort rightSpeed);
    public State GetState();
}

The first one is just a constructor with parameter identifying the n-th attached controller. Yes, you can handle input from more than one controller in your app.
The second method can be used for vibrating the controller - here I discovered that the Xbox controller actualy got two vibrating motors and not just one. I'm not going to cover usage of this API for vibration, I guess you can figure it out, how it works.
The third method is the most interesting here, it returns State object of the controller, that contains a snapshot of all buttons, triggers and pads from the moment the method was called.

As you may have guessed already, for accessing the Xbox controller state you don't use any events and notification just like you use in the XAML world. Instead you have to use polling and ask for the current state of all buttons in each moment. In the world of game development this is much more common approach, having a game update loop and asking for changes in each frame.

 

Speaking of GetState method, let's see what the State object contains:

public value struct State
{
    uint controllerId;
    uint packetNumber;
 
    bool connected;
    bool a;
    bool b;
    bool x;
    bool y;
    bool dpad_up;
    bool dpad_down;
    bool dpad_left;
    bool dpad_right;
    bool left_thumb;
    bool right_thumb;
    bool left_shoulder;
    bool right_shoulder;
    bool start;
    bool back;
 
    byte LeftTrigger;
    byte RightTrigger;
    short LeftThumbX;
    short LeftThumbY;
    short RightThumbX;
    short RightThumbY;
}

Most of these properties are quite self-explanatory:

The connected property is the most important, it tells us, if the Xbox controller is actually attached and drivers properly installed.

a, b, x, y, dpad_up, dpad_down, dpad_left, dpad_right, left_shoulder, right_shoulder, start and back, for these buttons you just receive bool value, if the given button is pressed in the exact moment or not.

left_thumb and right_thumb properties were not working in my sample, but instead I was able to read the values of left and right trigger using LeftTrigger and RightTrigger properties. Both triggers return byte value of how much is the trigger currently pressed.

Finally LeftThumbX, RightThumbX, LeftThumbY and RightThumbY contain short values with X and Y coordinates of the actual position of both thumb sticks on the controller.

XboxControllerDemoSide note: If you want to use Xbox controller on Windows machine, or tablet, you need to have either special Xbox 360 Controller for Windows, either wired or wireless, or any actual Xbox 360 wireless controller + Xbox 360 Wireless Gaming Receiver. It should be also possible now to use the Xbox One controller in a similar manner - not tested. What is also interesting here, that you can use the wireless gaming receiver not just on full Windows 8 operating system, but also on Windows RT! That's right, you can connect it to your Surface RT and play games on your Surface RT tablet using Xbox controller, how cool is that?

 

For detecting state of all buttons and actually testing how it all works, I've created simple sample based on the original XInput and JavaScript controller sketch sample, but in my case I use C# app:

In the sample application I've used picture of Xbox 360 controller with overlay rectangles and circles for indicating which button is currently pressed. For the thumbs I've used thin rectangles with RenderTransform to indicate the force vector.

Then I use 33ms infinite while loop to simulate 30FPS game loop, in which I am updating the visibility of buttons and the Rotation of the thumbs.

It all works surprisingly well together, I was even able in just one afternoon to put together sample with a tiny tank, that can be steered using the left thumb, and with a double-barreled cannon on the top, that can be aimed using the right thumb. It almost looks like a game, only without enemies and shooting 🙂

 

If you are interested, here's a snippet how I convert the raw thumb X and Y numbers into angle and velocity for the tank:

public const double Rad = 57.2957795;
public const double ForceThreshold = 10;
 
// Thumb values are provided as two coordinates, both with values in range (-32768,32767)
LeftThumb = Math.Atan2(state.LeftThumbX, state.LeftThumbY)*Rad;
RightThumb = Math.Atan2(state.RightThumbX, state.RightThumbY)*Rad;
double leftForce = Math.Sqrt(state.LeftThumbX*state.LeftThumbX + state.LeftThumbY*state.LeftThumbY)/512;
double rightForce = Math.Sqrt(state.RightThumbX*state.RightThumbX + state.RightThumbY*state.RightThumbY)/512;
 
// we use custom threshold to detect thumb position larger than X
LeftThumbForce = leftForce > ForceThreshold ? leftForce : 0;
RightThumbForce = rightForce > ForceThreshold ? rightForce : 0;

As you can see, no rocket science, just good old trigonometry.

Note the XInput API got a few more properties and methods, that can be used. If you want to create actual game for the Xbox Controller, I'd probably recommend reading thoroughly the documentation, so you won't be surprised if anything goes wrong.

 

Summary: Goal of this article was just to find out, how easy it is to handle input from Xbox controller in Windows 8.1 Store apps. The result - it's easier than expected.
The other reason for doing this is also to get a bit of a head start with developing Universal Apps for Xbox One. Right now we only know, that it should be possible sometime in the future. With the fact, that Xbox controller is mostly the only way of input on Xbox, it may be useful to adapt your Windows 8.1 games and apps to Xbox Controller right now, and as soon as the Xbox One SDK is ready, it should be quite easy to port your app for it. In the best case scenario, you'll just provide icons in new sizes, recompile your project and all will be working as expected.

The sample is available here on GitHub!

If you like the article, or if you find a bug, please, let me know, thanks 🙂