I'm having a hard time determining whether or not I should use fixed point or floating point numbers for my game. I'm using a rotated tile map so I'm going to be using a lot of trig functions. I am aware of the fact that modern day FPUs are fast enough that using fixed point numbers isn't necessary anymore, but Allegros fixed point trig functions are considerably faster than the standard C ones. Also, I am worried about float to int performance issues. I've read that such conversions are quite slow, but are fixed point conversions any faster? Or is that something I should not worry about. I was thinking about making a sin/cos lookup table, but in the process of using it I'd be casting a float to an int. Is that going to be an issue? Or am I blowing this performance thing out of proportion?

Thanks!

]]>Although most will tell you that in nowadays computers you should use floats, I would tell you to think something: will your game run in a slow computer? (in other words, your minimun requirement). If you want to run the game under DOS in a 233MHz, you should use fixed points. If you plan on running the game on >1GHz computers, just go with floats.

]]>yes i'd say the only case where you could use fixed is for angles like in rotate_sprite() etc...

]]>float.

fixed is for like P1's

]]>Okay, so I converted all my fixed math to floating point math, and pretty much everything is just as good as better, but what kills my FPS is the float to in conversions. When I draw my rotated tile map, I use two casts, and that's enough to lower my FPS from like, 320 to 180. Since I loop through every pixel on the screen, that's using 153,600 float to int casts each time I draw the map. However, if I use floats throughout the rest of my program, and switch to fixed math for my drawing code, overall I get a 20 FPS increase. This, of course, means I need to convert my normal 360 degrees into allegros 256 degrees, but since I precalculate the sine and cosine at the beginning of the function this doesn't seem to make a difference.

Here's my code:

1 | void DrawMap(BITMAP *dest, View &view) { |

2 | fixed sine = fsin(ftofix(-view.angle * 256.0f/360.0f)), cosine = fcos(ftofix(-view.angle * 256.0f/360.0f)); |

3 | int viewX = (int)view.pos.x, viewY = (int)view.pos.y; |

4 | int rotateX = -view.rotateX, rotateY = -view.rotateY; |

5 | unsigned int destW = dest->w, destH = dest->h; |

6 | int c; // Color |

7 | int sx, sy; // Source pixel |

8 | int tx, ty; // Tile coordinates |

9 | |

10 | for (int screen_y = 0, cy = rotateY; screen_y < destH; ++ screen_y, ++ cy) { |

11 | for (int screen_x = 0, cx = rotateX; screen_x < destW; ++ screen_x, ++ cx) { |

12 | sx = fixtoi(cx*cosine - cy*sine) + viewX; |

13 | sy = fixtoi(cx*sine + cy*cosine) + viewY; |

14 | |

15 | if (sx >= 0 && sy >= 0) { |

16 | tx = sx >> 4; |

17 | ty = sy >> 4; |

18 | |

19 | if (tx < MAP_W && ty < MAP_H) { |

20 | Pixel(dest, screen_x, screen_y) = Pixel(tile[GetTile(tx, ty)], sx & 15, sy & 15); |

21 | } |

22 | } |

23 | } |

24 | } |

25 | } |

Anyway, I guess I'll just use floats and switch to fixed for those tight loops. Thanks for all your answers!

[edit]

Hmm... it's not letting me give anyone credit. Maybe it's broken, or maybe I chose the wrong thread type.

The Allegro fixed point trig __already__ uses lookup tables.

You can get a slight speedup at times (always profile to be sure) if you mix fixed point and floating point, e.g. have some integer stuff shifting and adding while some floating point divide is going on. Also, there's an old (I don't know if it's still valid) trick to convert float to int and back again by having a temporary double that you store the product of your float and a const, then grab the lower 32 bits of the mantissa (you need a union to do this) which is your integer. I forget the exact value of the const, but it's a power of two.

]]>I've been experimenting with different techniques, but I've only been comparing them by FPS differences. I've never used profiling, perhaps I should check it out.

That seems like quite a lot just to convert a float to an int... would that really be faster?

And I wonder, are the ftofix and fixtof functions very slow?

]]>I hinghly doubt floats vs fixed makes big difference if you use them to calculate rotated sprites. Most probably drawing one rotated sprite is about as fast as couple hundred or thouseand float or fixed computations.

]]>If the calculus you do with the angles can be optimized to bit operations (that is: >>, <<, &, |, ^) may be fixed would be faster.

]]>