johannes-fetz / joengine

Jo Engine is an open source 2D and 3D game engine for the Sega Saturn written in C under MIT license
http://jo-engine.org/
MIT License
205 stars 32 forks source link

DEGtoANG() is Too Slow #42

Closed slinga-homebrew closed 3 years ago

slinga-homebrew commented 3 years ago

DEGtoANG() is too slow. In my game I call jo_sprite_draw3D_and_rotate() which calls jo_sprite_draw_rotate() which calls slDispSprite(). Before calling slDispSprite the int angle parameter is converted into a degree by calling the DEGtoANG() function. Unfortunately this function is very slow and was introducing frame skips in my program. This is with one sprite being rotated every frame.

DEGtoANG(d) is defined as ((ANGLE)((65536.0 * (d)) / 360.0)).

Swapping it to:

((ANGLE)((182 * (d))

I received a significant speed improvement and my game was no longer experiencing frame skips. The obvious downside is that this is less accurate than what you are currently doing. Credit to @ponut64 for the suggested fix.

ponut64 commented 3 years ago

Sega's DEGtoANG conversion does seem to be meant to explicitly call forth GCC soft float to do its thing. The "patched" DEGtoANG suggested here can still do that, but only if the user specifically calls forth a floating point number.

Should be noted that ANGLE data is a short that expresses theta, as inidcated by 65536 / 360. That's about 182. If you go the other way around and divide 65536 by 182, the result is 360.08791208791208791208791208791.

This discrepancy's maximal error is an integer 16, or 0.087 degrees.

johannes-fetz commented 3 years ago

@slinga-homebrew @ponut64 Just add JO_COMPILE_WITH_FAST_BUT_LESS_ACCURATE_MATH = 1 in your makefile