Writing a driver for the Steel Battalion controller

Oscar Sebio Cajaraville
6 min readSep 10, 2019

--

Steel Battalion is a mech combat game released in 2002 for the original XBox, known to this day for its massive controller, complete with two sticks, pedals, and more buttons you can count. Recently I got my hands on one such controller, and I ended up writing a driver to make it work on a modern PC.

Steel Battalion Controller (picture by John Tregoning)

Why do this?

I’m a developer workinkg on BH Trials, a game where you control a backhoe digger that has no brakes, steering or engine. Everything you do — drag the vehicle around, reach out for levers, move obstacles away — you do using the vehicle’s arms, often at once, in a choreographed series of moves. Getting the controls right is critical to the game, and I’ve spent a lot of time figuring them out.

Not long ago, while in a conversation with Jose, who is doing all the audio for the game, I said in passing how it would be great to play the game with two joysticks, as it would be the most similar to how the real machine operates. He replied that he knew of a couple vintage dual-joysticks that could work, and insisted that I should try get a PlayStation Analog Joystick. I said that I have plenty of other work on the game and didn’t feel like supporting an obscure controller, but a few days later he showed up with a military-looking cardboard box containing the biggest controller I’ve ever seen, and I caved.

How did I do it?

Steel Battalion is a game for the original XBox and it doesn’t connect to a PC right away.

Fortunately enough, the XBox is essentially a PC, and the controllers are standard USB 1.0, just with a different end plug; it took me about five minutes of online research to find a ready-made adaptor for a reasonable price.

I didn’t want to wait for delivery, though, so I ended up doing something else. The last part of the Xbox controller’s cable is detachable, to avoid pulling the console if you step on it. This is the same for the XBox 360, which uses standard USB ports. With a small modification, I managed to connect the 360’s breakaway to the original Xbox controller, then connect the controller to the PC.

Once the controller is connected, Windows will detect it as an unknown USB device because it can’t find any drivers for it, and it is not HID complaint.

The USB-HID specifictacion allows an USB device to tell the system about its behavior; eg. the device can say it is a gamepad with these many buttons and these many axes. This is the most common way for games and other programs to implement generic input devices, and it’s the approach I took.

Writing the Driver

I had never written a Windows driver before, so I expected a great deal of pain. I could foresee a long system configuration, blindly writing code that I half understood and trying to debug problems in code that runs in kernel mode. I n handsight I was right, but the process was more enjoyable than I anticipated.

There is a lot of information about writing drivers provided by Microsoft itself. Too much, to be fair, for someone wanting to have something working quickly, so I went directly to the examples.

I searched for and example as similar as possible to what I wanted to do, to use as a starting point. The HIDUSBFX2 sample demonstrates how to map a non-HID compliant USB device to one that is, which is exactly what I was thinking of doing.

To compile the project you need the usual stuff: Visual Studio, the Windows SDK, and the Windows Driver Kit. Once I got it to compile, I started stripping down the code. I won’t get into the driver code here, but I will explain a little bit how the USB communication works and how I got the information I needed to implement the driver.

Part of the information USB devices provide the system with is how to read and write data from and to them. This information is provided as an “endpoint descriptor”. We can take a look at these descriptors using a program such as USB Device Monitor Studio.

As we can see, the Steel Battalion Controller has two endpoints, One for reading and one for writing. I was interested in reading any information that the device would send. After many captures while pushing buttons and moving levers in the controller, I decyphered the 32 bytes as follows:

Steel Battalion Controller Input Data

I then had to write a HID Report to give meaning to that data. To that effect, I had to create a HID Report Descriptor. The USB consortium provides a HID descriptor tool to create this information. Mine looks like this:

Steel Battalion Driver HID Report Descriptor

You might have noticed that the descriptor doesn’t match the data exactly. I found problems with signed values on some of the axes, so I decided to convert all of them to unsigned, and simplify the report a little bit.

After all this work, now Windows detects the controller as a gamepad, one that has many buttons and axes (some of with have a specific use such as a throttle or a brake), and other less common features, like a shifter and a “weapon select” dial.

Steel Battalion as a game controller in Windows

Using the Controller

The game already supports HID devices such as DualShock controllers, so once the Steel Battalion controller was properly detected, the rest was relatively easy — a matter of finding a good mapping.

Remember, the excuse for all this work was to play BH Trials with a dual joystick — here it is!

Steel Battalion controller working on BH Trials

Caveats

Windows 10 drivers need to be signed with a certificate from a trusted certification authority, which costs several hundreds of dollars. On top of that, in the latest versions they also need to be certified by Microsoft itself. At the moment I don’t think I can justify the expense, but there is a workaround.

You can still use the driver setting the operative system in “test signing” mode. You will need to restart the system to enable the mode and you’ll probably want to go back to normal mode once you finish using it. It is not optimal, but it’s not difficult either.

Using the driver yourself

The code and binaries for the driver are available on github/steelbattaliondriver. If you want a step-by-step guide on how to install it, I wrote one here: How to use the Steel Battalion Controller on Windows 10

--

--