I recently started to play around with GBDK 2020. I implemented a simple (and possibly bad) sine / cosine function based on a lookup table.
The source and a compiled rom are here: https://github.com/sttng/gb-stuff/tree/ ... igonometry
Details:
The angle is defined as an UINT8 meaning a full circle (360°) equals to 255 or 0xFF. One nice side effect being that you can add/subtract angles and you get the modulo / wrap-arounds for free due to the data type UINT8 used. Consequently the smallest angle you can rotate is 360/256 = 1.4°.
For the first quarter (0° - 90° or first 64 values) I implemented a lookup table, which returns the corresponding sine or cosine values. For higher accuracy, these values are 'scaled' to +/- 127 (signed INT). So a sine of 90° will not return 1.000 but 127, a sine of 45° will not return 0.707.. but 89, etc. This also means that if you use the returned value you have to divide the result by 127 - make however sure to do the division as late as possible to keep some level of "accuracy". What do I mean with that ?
Example: 50*sin(45°); remember sin(45°) = 89 in my implementation
50 * (89/127) = 0 : in case you do the division 'early' as 89/127 = 0.
(50 * 89) / 127 = 35: in case you do the division late as 50 * 89 = 4450 and 4450 / 127 = 35.
By the way the mathematical correct result is 35.355339059327376220042218105242 if you check in your Windows Calculator.
A lookup table with only 64 is sufficient because for sine and cosine only the sign changes and the phase. So basically you only need the 1st quarter.
Usage:
Left/right: Rotate the player (small circle in the middle)
Up/down: Move into the direction of the small point
A/B: strafe
Now if only I could do a screen refresh every frame.
Anyway comments welcome. Feel free to use or modify it.
I currently thinking about a fixed point version which should increase the mini angle to 0.35° (so somehow 4x more accurate )