• entries
222
608
• views
588402

# Controller input updates to Cogwheel

1004 views

I hope you all had a good Christmas and New Year period!

I received an Xbox 360 controller for Christmas, so have done a bit of work on Cogwheel to add support for it. (You can download a copy of the latest version 1.0.2.0 with SlimDX here).

The first issue to deal with was the D-pad on the Xbox 360 controller. When treated as a conventional joystick or DirectInput device the D-pad state is returned via the point-of-view (POV) hat. The joystick input source class couldn't raise events generated by the POV hat so support for that had to be added. This now allows other controllers that used the POV hat for slightly bizarre reasons (eg the faceplate buttons on the PlayStation controller when using PPJoy) to work too.

The second issue was the slightly odd way that the Xbox 360's DirectInput driver returns the state of the triggers - as a single axis, with one trigger moving the axis in one direction, the other trigger moving it in the other. You cannot differentiate between both triggers being held and both being released, as both states return 0. To get around this, I've added support for XInput devices, where all buttons and triggers operate independently.

The Xbox 360 controller now shows up twice in the UI - once as an XInput device and again as a conventional joystick. Fortunately, you can check if a device is an XInput device by the presence of IG_ in its device ID. Here's some C# code that can be used to check with a joystick is an XInput device or not.

using System.Globalization;using System.Management;using System.Text.RegularExpressions;namespace CogwheelSlimDX.JoystickInput {        ///     /// Provides methods for retrieving the state from a joystick.    ///     public class Joystick {        /* ... */        ///         /// Gets the vendor identifier of the .        ///         public ushort VendorId { get; private set; }        ///         /// Gets the product identifier of the .        ///         public ushort ProductId { get; private set; }        /* ... */        ///         /// Determines whether the device is an XInput device or not. Returns true if it is, false if it isn't.        ///         public bool IsXInputDevice {            get {                var ParseIds = new Regex(@"([VP])ID_([\da-fA-F]{4})"); // Used to grab the VID/PID components from the device ID string.                // Iterate over all PNP devices.                using (var QueryPnp = new ManagementObjectSearcher(@"\\.\root\cimv2", string.Format("Select * FROM Win32_PNPEntity"), new EnumerationOptions() { BlockSize = 20 })) {                    foreach (var PnpDevice in QueryPnp.Get()) {                        // Check if the DeviceId contains the tell-tale "IG_".                        var DeviceId = (string)PnpDevice.Properties["DeviceID"].Value;                        if (DeviceId.Contains("IG_")) {                            // Check the VID/PID components against the joystick's.                            var Ids = ParseIds.Matches(DeviceId);                            if (Ids.Count == 2) {                                ushort? VId = null, PId = null;                                foreach (Match M in Ids) {                                    ushort Value = ushort.Parse(M.Groups[2].Value, NumberStyles.HexNumber);                                    switch (M.Groups[1].Value) {                                        case "V": VId = Value; break;                                        case "P": PId = Value; break;                                    }                                }                                if (VId.HasValue && this.VendorId == VId && PId.HasValue && this.ProductId == PId) return true;                            }                        }                    }                }                return false;            }        }        /* ... */    }}

When the joysticks are enumerated they are only added to the input manager if they are not XInput devices.

To round up the entry, here's a screenshot of a minesweeper clone I've been working on in BBC BASIC.

You can view/download the code here and it will run in the shareware version of BBC BASIC for Windows. The code has been deliberately uglified (cramming multiple statements onto a single line, few comments, trimmed whitespace) to try and keep it within the shareware version's 8KB limit as this is a good limit to keep in mind for the TI-83+ version too.

There are no comments to display.

## Create an account

Register a new account