for my current project I use gamepad. I was successfull in hooking it up in C# through SlimDX. Everything works fine, only problem is that thumbsticks don't fully use the active range.

If I move stick all the way to left on X axis, I get maximum value half-way through. Then the driver clips the values returned.

I understand, why this happens. The driver operates in square area, but the stick in circle.

The red square marks values I get from driver. The blue area represents actuall physical range of sticks and the green one is what I want to get from the gamepad. I get these readings in calibration utility and in my program too.

My question is: is this normal behaviour for gamepads? Do I have to buy better one? Currently I'm using really cheap one - Genius MaxFire Grandias 12, as I don't want to invest much into this.

-

To answer this you need to think of the simple idea of what a controller needs to be capable of doing and why.

• It needs to report on an axis - X and Y - to allow game devs to use raw direction values AND scaled direction values - typically lets say this would be a raw range of -141 to 141 and a scaled direction value of -100 to 100
• It needs to have physical movement of an analogue nature to allow values more than -1 to 1, very few games would benefit from a stick being Digital - bar fighting games. This allows devs to make characters walk slow (x<30) normal (30
• It often needs circular boundaries to make moving from one angle to another smooth. Making movement of the stick smoother from corner to corner allows players more control whilst not sacrificing accuracy

Now looking at your diagram is actually all we need to do to show why using the red square is the best convention and why having the dead zone arcs at north east south west positions of that square are necessary. I'll use my best PhotoShop skills to show you.

If I have a game which my speed is linear in each direction based on the raw individual values from the stick for both x and y (let the range on the red square x and y be -100 to 100) then I have this situation:

Bob is wearing a magic hat that allows him to float in any direction and at a constant x and y speed (because his hat has thrusters on the north and south sides as well as on the east and west sides) meaning he can move 100 units/s in both north and east directions at once.

This is brilliant! Our controller square input allows us to do this and more importantly should Bobs hat magically only have one thruster that can go a maximum of 100 units a second well that's okay. We can then give him a direction using inverse tan:

``````θ = tan-1 ( 100 / 100 ) = 45°
``````

And it can only go 100 units a second so we simply clamp the speed after putting Pythagoras' awesome theorem on that x and y:

``````int pythagThatSpeed (x,y) {return sqrt((x^2) + (y^2));}
speed = clamp(100,pythagThatSpeed(x,y);
``````

Meanwhile in circular input land we have this layout:

Now Bobs first hat with 4 thrusters cannot reach its maximum speed at the NorthEast angle! What happened? Well as we have restricted our range of input to a circle we are not allowing x reaching 100 at the same time as y reaching 100.

In the picture above you can see that bob has to move at 70 units x and 70 units y per meaning he cannot reach his max speed of 141. Even if we were to use Bobs second space ship that can only use one thruster then it has a value of 99 units speed NorthEast (using appropriate integer rounding) meaning his max speed isn't even accurate with his second magical hat.

Well with the circular input we would have to change the way a pad reports to a computer in order to do this without a lot more maths than a simple Pythagoras theory and tan-1(x,y) function. Using the scaled directional values reported by the controller instead of the raw values means we don't restrict our selves with dead zones like we see in the green square of your diagram.

If you were to use the blue circle values resulting from using raw values from the controller you could use polar coordinates instead, giving us the angle and the magnitude of input. However as it stands if you were to restrict yourselves to a circular input you would have to add in extra clamp functions to your x and y inputs from the controller to make it a range of -70 to 70 in order to do what we did with Bobs first magic hat taking us right back to this:

Which looks awfully familiar.

And this is why we have square inputs on controllers that clip "half way" and raw inputs. We use the scaled ones to give ourselves a more flexible set of x and y values in development.

-
Great explanation, as I said I understand the math behind this. But given I have never used GP before I was kinda surprised by size of the clip-zone. If I move stick from neutral position on X axis by 25° I can go another 25° - but values are clipped then. Given your answer I asume, this is same for others gamepads as well. – jnovacho Jul 20 '13 at 13:46
Well, no one will dare reuse your images :) +1 – Byte56 Jul 20 '13 at 14:31
@Byte56 Well I don't mind if they do but it makes sure that people recognise bob and his hat. I'm glad you found the answer useful - You can safely assume this is the same with most pads as those which aren't setup to read a scaled input instead of the raw "circular" input by default are not going to work properly in most games that need that 100% range at angles (like in my second image) So use Pythagoras and inverse tan equations if you want to transform the Cartesian coordinates to Polar angle and magnitude for use in your games. – Blue Jul 20 '13 at 14:56