I think that XNA’s implementation of the XInput API for Xbox 360 controllers is terrific. Simple, complete, ready to use. So when I wanted to add gamepad support (including analog input and vibration) to Super HYPERCUBE, a TV3D 6.5 game, I just added a reference to the XNA Framework assembly and carried on like I did in Fez. But I realize that referencing XNA just for controller support is silly, and I don’t want to assume that it’s installed on clients, nor force-install the redistributable.
So I recently looked for a more proper solution. It looks like MDX 2.0 Beta had support for XInput, but it’s been discontinued in favor of XNA for some time. There is also a handful of managed wrappers around the XInput native DLL that use P/Invokes… wasn’t too keen on that either.
Then I recalled that SlimDX is the community-maintained successor to MDX, and that it’s awesome. And as a matter of fact, it has complete support for XInput! So might as well use that.
But SlimDX is, well, slim. It’s a very thin wrapper and doesn’t do any normalization or dead zone detection for thumbsticks. It’s not much of a bother to do yourself, but I figured I’d post my code as a reference to people who want to use SlimDX’s XInput implementation in the real world.
Details
My dead zone code is based around the “Getting Started With XInput” guide on MSDN, but given the C#3/SlimDX beautifying treatment. :)
I also found that analog triggers on my controllers did not need dead zones, but if you want to use them as binary buttons, you can check against the appropriate SlimDX constant.
My “state class” does not wrap everything that the SlimDX Controller class exposes, like voice support, battery information, etc. So I made the local Controller instance a public readonly member, and you can access it to query whatever other information you need. Or of course you can add the getters/state variables that you need.
Download
GamepadState.cs (C#3 – 5 Kb, SlimDX March 2009 SP1 SDK or later needed)
Just the dead zone code
If you’re only looking for that, here it is :
var gamepadState = Controller.GetState().Gamepad; var leftStick = Normalize(gamepadState.LeftThumbX, gamepadState.LeftThumbY, Gamepad.GamepadLeftThumbDeadZone); var rightStick = Normalize(gamepadState.RightThumbX, gamepadState.RightThumbY, Gamepad.GamepadRightThumbDeadZone), } static Vector2 Normalize(short rawX, short rawY, short threshold) { var value = new Vector2(rawX, rawY); var magnitude = value.Length(); var direction = value / (magnitude == 0 ? 1 : magnitude); var normalizedMagnitude = 0.0f; if (magnitude - threshold > 0) normalizedMagnitude = Math.Min((magnitude - threshold) / (short.MaxValue - threshold), 1); return direction * normalizedMagnitude; }
You should contact Promit and see if they would like something added to SlimDX to do this… its OpenSource and this would be a useful addition for most people.
Thanks for the suggestion ZMan, I just did. :)
How does your mdx game loop look like? My do while is eating my cpu.
I never worked directly with MDX, but for SlimDX I use the MessagePump class and hooks to Application.Idle similar to what Tom Miller prescribed back in 2005… see http://blogs.msdn.com/tmiller/archive/2005/05/05/415008.aspx
Just wanted to say thanks for creating and posting this. It is a beautiful wrapper for the SlimDX Xinput and literally took only seconds to get working in my code after having spent hours and hours trying to make something of my own that worked.
This was exactly what I needed for making a plugin for vvvv (which is a really nice visual programming language: http://vvvv.org).
Worked flawlessly, thank you very much!
r.
Hello;
I have question (if you are avaliable) for an alternative way to send input to UDK from an WPF applicaiton. I achived to send some keyboard keys like W,A,S,D by SendKeys.SendWait method. But when I try to send key combination like WandA movement of Character is so stuttering. Is there more proper way to do that? I searched alot on the internet for some similar scenario last 2 days but none found.
(Note Especially I am planning to use xbox 360 controller library to send inputs as a xbox 360 input(I don’t know it is possible), Because UDK recognize the xbox 360 controller input without any issue. Also there are some emulators for xbox 360 controller on the internet. Someone might be familiar with similar scenario.)
Thanks for reply.
Hi,
I’ve never used UDK or WPF, so I’m afraid I can’t really answer your question… Sorry!
@Ismail: you should ask this question on UDK (Unreal Development Kit) forums. They can help you alot regarding this.
Hey, thanks so much for this. I was in a very similar situation. I’m trying out WPF to see if it’s a suitable platform for some simple game ideas, and since I only needed the gamepad support, I really didn’t want to have to pile XNA on top of everything else.
Also on a side note, if you’ll forgive my geeking out for a minute. I absolutely loved Fez and IGTM, so you know… gj! on both I guess.
Your code is not working, as I expected.
Anything I can do to help?
Hey, I’m really new to using C# and this is causing me a ton of confusion. I get what the function of the class is doing but how do you implement this? Basically how do I make it so that when I press a button it does something.
Hey! This is pretty old code so I’m not 100% sure it still works as advertised with the latest SlimDX code. But if you get to a state where the code does compile, here’s some sample usage :
// create the state object (can be done once at initialization time)
var state = new GamepadState(UserIndex.Any);
// update (should be done once per frame)
state.Update();
// if A button is held
if (state.A)
{
// do something
}
Hope this helps!