🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Raw Input Axis center

Started by
5 comments, last by ddlox 3 years, 7 months ago

I'm using Raw Input to read a HOTAS throttle and joystick that I have. There are button and axis readings, and the axis data comes across as an integer that fulfills a certain bit precision. For instance, some axis data comes across as 10 bit data, so it spans the range of 0 - 1023. (16 bit data comes across as 0 - 65535, etc.)

That's fine, but some of these axes are "centered". For instance, my throttle has a 10-bit left-right paddle that starts out giving me a reading of 512. Toggling it left produces values down to 0, and toggling it right produces values up to 1023. But that's unbalanced. It means if I just offset by -512 and divide by 512, I'll get values from -1.0f to 0.998f

Is there a good way to remap this axis data to -1.0 to 1.0 for bipolar values like this?

Advertisement

sounds like this is what u want:

// pseudo in c++
float remap(float value,
          float from1, float to1, // range 1
          float from2, float to2) // range 2
{
    float newvalue =
      from2 + (to2 - from2) * ((value - from1) / (to1 - from1));
    return newvalue;
}

try this ;

Until then ?

If I do that it won't cleanly sit at 0 when it's reading 512.

Except, I guess the hardware itself isn't giving me a 0 reading. It really wants to be 511.5, but is surprisingly rounding up. I suppose I could add that 0.5 in to supplement the remapping… but since I'm always going to have an inner dead zone anyway, perhaps I'll just move forward as-is

indeed because the mapping is not a 1-to-1 conversion (it's a translation and a scale);

so instead you could just rescale this way instead of mapping:

float rescale(float v, float new_min, float new_max, float old_min, float old_max)
{
    float t = v / (old_max - old_min + 1); // notice the +1 to tell u how many values this range has;
    return new_min + t * (new_max - new_min); // this is a lerp effectively into the new range;
}

then u could test these out:


    cout<< rescale(0,-1,1,0,1023) << endl; // -1
    cout<< rescale(512,-1,1,0,1023)<< endl; // 0
    cout<< rescale(1023,-1,1,0,1023)<< endl; // 0.99whatever
    cout<< rescale(1024,-1,1,0,1023)<< endl; // 1

see how it goes ?

If the range is 0 to 1023, you must divide by 1023, not by 1024 (or 512). 0/1023=0, 1023/1023=1.
However, with an even number of input values (1024) you aren't going to have a neutral value: 511 is less than half and 512 is more than half. A dead zone around 511.5 is mathematically required.

Omae Wa Mou Shindeiru

@lorenzogatti Funlymunke wanted a solution that sits 512 at 0 cleanly:

Funkymunky said:
If I do that it won't cleanly sit at 0 when it's reading 512.

hence the + 1 in the rescale( );

it's all about monkeying about ?

This topic is closed to new replies.

Advertisement