gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > I understand the concept, but fixed point is the problem...

#39150 - LOst? - Tue Apr 05, 2005 5:34 am

For you people that underastand Outrun game technology, and how to make it come true by using fixed point math, a little help would be nice.

It doesn't matter how much I debug the game, there is a pre-calced table with values it seems to use. Now how do I get from here to there?

Look at this picture I drew so nicely for you:
[Images not permitted - Click here to view it]
What you see is a map on the left, and the display output on the right.

p1 and p2 are simply relative coordinates on the map which is used to get the distance in between them. I get it by doing this:

p2 - p1 = pixel distance

The result is then divided by the distance I want it to be drawn on the display... right?

Let's take a sample. Say p1 = 10 and p2 = 80:

80 - 10 = 70

And the draw distance is 128:

70 / 128 = 0.546875

So the concept is easy, I move the map vertically with the speed of 0.546875 during HBlank. Easy! Well, no. Because how much I try to convert that value into fixed point I fail.

First off, I usually use 8 bits for the decimal point... But maybe that's the problem? Hell I have no idea how to even convert this thing to fixed point. What's the secret? Just a wild guess here:

0.546875 * 256 = 140

140 * 128 = 0x4600 which is 70.0

Why does it work now? Crap >.<;;

Anyway, I need help. I was just lucky this time. Next time I will get into problems so tell me how this should be done from your point of view.

#39151 - tepples - Tue Apr 05, 2005 5:42 am

When you divide in fixed point, you have to multiply by your denominator (which is 256 if you're using .8 binary fixed-point) first.

So you'd do (70 * 256) / 128
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#39152 - LOst? - Tue Apr 05, 2005 5:46 am

tepples wrote:
When you divide in fixed point, you have to multiply by your denominator (which is 256 if you're using .8 binary fixed-point) first.

So you'd do (70 * 256) / 128


So that's the secret. That way I will be able to skip the floating point result?

I sat down for a few hours trying all kind of stuff like this:
70 * 0x100 / 128 * 0x100

With very odd results. The main thing is to avoid the floating point and only use fixed point, even pre-calced tables. That will be a challenge for me. Thank you for your quick help tepples!

#39170 - tepples - Tue Apr 05, 2005 3:03 pm

LOst? wrote:
tepples wrote:
When you divide in fixed point, you have to multiply by your denominator (which is 256 if you're using .8 binary fixed-point) first.

So you'd do (70 * 256) / 128


So that's the secret. That way I will be able to skip the floating point result?

Yes.

Quote:
I sat down for a few hours trying all kind of stuff like this:
70 * 0x100 / 128 * 0x100

No, 70 * 0x100 / 128. You multiply only the numerator.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#39175 - poslundc - Tue Apr 05, 2005 4:03 pm

Multiplication: precision of the result is the sum of the precisions of the two operands. eg. 24.8 * 24.8 = 16.16 result

Division: precision of the result is the difference of the precisions of the two operands. eg. 24.8 / 24.8 = 32.0 result.

Prescaling/shifting your numerator before dividing lets you maintain precision across the divide.

(24.8 << 8) = 16.16
16.16 / 24.8 = 24.8

It's the same as with decimal math. 1/3 = 0 in integer terms. But if you multiply the numerator by 100 to shift it two decimal places, you get 100/3 = 33, or two decimal places worth of precision.

Dan.