It seems that at least for Xbox 360 controllers the input from an analog stick should be normalized. That is, for example, if I push the stick to the "corners", the magnitude should be 1 instead of square root of 2.
There are games where this is problematic that I either cannot walk in diagonal directions or cannot run in perpendicular directions.
I changed the GetState function of AnalogStick class, on the "stable" branch. There ought to be a switch for this I think, but I don't want to find out where to add it. So I guess it's a good idea for some else to deal with the repository.
----
Guess I forgot to clamp the final results...
There are games where this is problematic that I either cannot walk in diagonal directions or cannot run in perpendicular directions.
I changed the GetState function of AnalogStick class, on the "stable" branch. There ought to be a switch for this I think, but I don't want to find out where to add it. So I guess it's a good idea for some else to deal with the repository.
Code:
void GetState(ControlState* const x, ControlState* const y)
{
ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State();
ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State();
ControlState radius = settings[SETTING_RADIUS]->value;
ControlState deadzone = settings[SETTING_DEADZONE]->value;
ControlState m = controls[4]->control_ref->State();
if (m)
{
radius *= 0.5;
}
ControlState max_a = std::max(std::abs(xx), std::abs(yy));
// Short circuit if within deadzone
// max_a == 0 check is not required if deadzone is alway non-negtive, but I don't know
if (max_a <= deadzone || max_a == 0)
{
*x = 0;
*y = 0;
}
// Scale down the value by the maximum magnitude on the current direction (distance(xx, yy) / max(abs(xx), abs(yy)))
else
{
ControlState dead_x = deadzone * (xx / max_a);
ControlState dead_y = deadzone * (yy / max_a);
xx = (xx > 0 ? xx - dead_x : xx + dead_x) / (1 - deadzone);
yy = (yy > 0 ? yy - dead_y : yy + dead_y) / (1 - deadzone);
ControlState scale = radius * max_a / std::sqrt(xx * xx + yy * yy);
*x = xx * scale;
*y = yy * scale;
}
}
----
Guess I forgot to clamp the final results...