Build a Game Steering Wheel Using an Arduino – Part 3

In part 2 of this series I built the circuit that I’ll be using for my controller based around an Arduino Pro Micro. In this part I’ll configure the driving simulation game Dirt 3 so that it works with the controller.

Configuring Dirt 3

Basic Configuration

In Dirt 3 game controllers are configured in files stored in:

C:\Program Files (x86)\Steam\steamapps\common\DiRT 3 Complete Edition\actionmap

In this directory there is a file for each controller and a master file called actionMapPaths.xml which is a a list of configuration files the game will load. Look through the existing controller configuration files and pick a device that is similar to the one that you are building and make a copy of that file. For example I picked the Logitech Driving Force GT USB which is defined in the file lg_driving_force_gt_usb.xml and made a copy called arduino_micro.xml.

In your device configuration file change the attributes in the root element called actionMapName and deviceName. The action map name seems to just be an arbitrary name used by Dirt 3. The device name however has to match the name of your gaming device in Windows. For the Pro Micro this seems to be Arduino Micro but I’m unable to confirm if that is always the case. The first line of your configuration file should look something like this:

<ActionMap actionMapName="arduino_micro" deviceName="Arduino Micro" priority="6">

The priority setting determines which controller Drit 3 will use as the default (I think) if you only have one controller connected it doesn’t matter what this value is set to. Now open the actionMapPaths.xml file and add a line that points to your configuration file like this:

<xmlreader processor="ActionMap2" filename="actionmap/arduino_micro.xml" map="UPDATE" pool="UPDATE_TEMPORARY" />

At this point you can now fire up Drit 3 and you should be able to select your breadboard rats nest as a game controller. Depending on which profile you copied you’ll find a varying number of buttons and controls work correctly. I found that steering worked correctly but everything else was mapped incorrectly.

Fine Tuning the Configuration

Every action in Dirt 3 has a name and one or more associated axes that control it and each axis has a calibrator associated with it. A simple configuration block for an action will look something like this:

<Action actionName="Steer Left">
  <Axis axisName="di_x_axis">
      <CalibratorSimple type="biDirectionalLower" deadZone="0.0" saturation="1.0" />
  </Axis>
</Action>

This says associate the x-axis of the controller with the Steer Left action in the game and use a simple calibrator to configure the axis. This action is actually a little more complex than the others as the x-axis needs to be mapped to both the Steer Left and the Steer Right actions in the game – you wouldn’t want separate controls to steering left and right!

Mapping a single axis to two in game controls is done by setting the type attribute of the calibration element. The type attribute can take a range of values:

  • biDirectionalLower
  • biDirectionalUpper
  • uniDirectionalPositive
  • uniDirectionalNegative

The uniDirectionalPositive and uniDirectionalNegative types tell the game to use the whole axis on the controller as the value for the action, this is what is needed for the accelerator and brake. For example an accelerator value of 0 from the controller should correspond to no acceleration in the game, a value of 1023 from the controller should correspond to maximum acceleration. If you find that your control works in reverse just swap uniDirectionalPositive for uniDirectionalNegative.

The biDirectionalLower and biDirectionalUpper types tell the game to accept only half the input from a given controller axis for input to that particular action. The controller outputs values from 0 to 1023 on the x-axis and a setting as shown above for the Steer Left action tells the game to accept only the values 0 to 512 for turning left with 512 being wheels straight ahead. As with the uniDirectional settings if you find the steering is back to front swap upper and lower in the settings to correct things.

As an aside… An interesting experiment might be to configure a single axis to control accelerator and brake. The upper half would be accelerator and the lower half brake. The peddle would have a spring that held the brake on full if your foot wasn’t on it, half way down would be zero brake, zero accelerator.

It’s now just a matter of going though the file configuring each of the buttons and axes on your controller to work with a game action. There are nearly a hundred actions so I won’t list them all here but you can download my configuration file which should be a good starting point – I don’t care about replay actions so I’ve just left those as they were when I copied the file.

Testing

Now that you have a wired and configured controller it’s time to plug it in and have a quick race. The controls should all work correctly but the car will be nearly undriveable steering with the knob of a potentiometer so it’s time to move on to part 4 where I build the actual steering wheel.

Update

Since writing this article I bought DiRT Rally which is basically a new and improved version of DiRT 3 (you can’t buy DiRT 3 on steam anymore it seems). I’m pleased to report that the set up for the controllers is very similar in DiRT Rally. The location of the configuration files has changed to C:\Program Files (x86)\Steam\steamapps\common\DiRT Rally\input the actionMapPaths.xml file is now called just paths.xml.

The toughest change is with the actual configuration file. Gone is the deviceName attribute in the ActionMap element in it’s place is a device_type attribute. This device_type attribute appears to take a GUID identifier for the device type although for some devices like XBox controllers it takes a string such as xinput_pad. I wasn’t sure what to put in this attribute so I opened up the Arduino Micro properties (from within Devices and Printers) and under Hardware > Details I just went through the list of properties the device has looking for GUID’s. There is a property called Class GUID which fitted the bill so I used that value. I was able to configure DiRT Rally to use my Arduino controller but I’m not convinced it’s correctly configured – the game recognised the various axes and buttons but seemed to think it was a mouse.