While looking for a way to use my joypad in a C# application, everything I found used DirectInput to do it. As it turns out however, a single simple Windows API call is all that is needed:
internal enum JoypadErrors : uint
{
None = 0, //NOERROR
BadDeviceID = 2,
InvalidParameter = 11,
BadParameter = 165, //PARMS
Fault = 166, //NOCANDO
Unplugged = 167
}
[Flags]
internal enum JoypadFlags : uint //Calibration flags left out.
{
X = 1,
Y = 2,
Z = 4,
R = 8,
U = 16,
V = 32,
POV = 64,
Buttons = 128,
RawData = 256,
POVCTS = 512,
Centered = 1024,
All = X | Y | Z | R | U | V | POV | Buttons
}
[Flags]
internal enum JoypadButtons : uint
{
I = 1,
II = 2,
III = 4,
IV = 8,
V = 16,
VI = 32,
VII = 64,
VIII = 128,
IX = 256,
X = 512,
XI = 1024,
XII = 2048,
XIII = 4096,
XIV = 8192,
XV = 16384,
XVI = 32768
//This goes on until button 32.
}
internal struct JoyInfoEx
{
public int Size;
public JoypadFlags Flags;
public int X;
public int Y;
public int Z;
public int R;
public int U;
public int V;
public JoypadButtons Buttons;
public int ButtonNumber;
public int POV;
public int Reserved1;
public int Reserved2;
}
[DllImport("winmm", EntryPoint = "joyGetPosEx", SetLastError = true)]
private static extern JoypadErrors JoyGetPosEx(uint id, ref JoyInfoEx info);
You ask this function for the current state of the joypad's controls like so:
var info = new JoyInfoEx(); info.Size = Marshal.SizeOf(info); //Don't forget. info.Flags = JoypadFlags.All; //What you want to get. var result = JoyGetPosEx(0, ref info); //And that's it.
What do the received values mean? This is how they map to my Trustmaster Firestorm:

The point-of-view control returns a value between 0 and 31500, representing an angle in degrees. When unused, it returns 65565.
The left and right stick both have two axes. They all return a value between 0 and 65565. When centered on an axis, it's value is 32767.
And thats all there's to it. You get to work with the values you got.