Then I stumble upon this piece of code...
int32_t speed_to_int(int32_t value) {
return (value + comma_offset) >> 8;
}
This function takes a 24.8 fixed comma value and returns an integer. This is used when calculating how much an object should move. The variable [font=courier new,courier,monospace]comma_offset[/font] is an offset calculated every frame used to fake sub-pixel accuracy (I know I could have just used fixed comma for everything, but that's another topic).
What's the issue here? That arithmetic (signed) bit shift doesn't behave exactly like division when it comes to negative integers: instead of rounding towards zero, it rounds away from zero, and the code relies on this behavior. I tried some quick tricks to get it to work with division but I couldn't get it working. Applying an offset doesn't work because positive integers still have to round towards zero.
So I was wondering: does anybody here know what'd be the way to implement the same behavior using pure arithmetic, and not abusing [font=courier new,courier,monospace]if[/font]? Not like I really need it (since like I said, the chances of this ever running on a processor not using two's complement is pretty much non-existent), but I'm curious as to what would be the approach - especially if it's something the compiler can understand and optimize into a bit shift where possible. Just going to stick to what I have for now because it works as intended and I have better things to do.
In case somebody wants to know how [font=courier new,courier,monospace]comma_offset[/font] is calculated, here we go, where [font=courier new,courier,monospace]game_anim[/font] is just a counter that goes up by 1 every frame:
comma_offset =
(game_anim & 0x80) >> 7 |
(game_anim & 0x40) >> 5 |
(game_anim & 0x20) >> 3 |
(game_anim & 0x10) >> 1 |
(game_anim & 0x08) << 1 |
(game_anim & 0x04) << 3 |
(game_anim & 0x02) << 5 |
(game_anim & 0x01) << 7;
PS: I had to reformat the code above because the editor decides to be idiotic with indentation while pasting.