Discussion in 'Engineering & Reverse Engineering' started by Tweaker, May 29, 2008.

1. ### Cokie

C. Okie Member
49
7
8
So it appears that the sine wave table in sonic 2 is slightly off. Please let me know if I understand this correctly. The input in calcsine, a hex byte 0-FF is the hex-angle. To get the real angle ( clockwise ) you multiply the hex-angle by 1.40625 (360/256) . the output for the sine value will be sine(hex-angle*1.40625) * 255 as a signed word value that is referenced from the sine wave table . if the hex angle was 1 then sin(1.40625) *255 isn't the word of exactly 6 ( 0006) but rather 6.258.. Did they simply round or am I misunderstanding it. Also couldn't the sinewave table be packed to one mathematical quadrant of 0-90 degrees if you did some post processing to the lookup table

The sonic 2 disassembly says the sine and cos output is sin and cos of angle times 255 . isn't it multiplied rather by 256 ?

Last edited by a moderator: Sep 11, 2022
2. ### MarkeyJester

Time to Grow Up. Resident Jester
2,122
248
43
Japan
The range doesn't have to be 360.

It became 360 due to several historical instances, some involving the revolusion of the earth around the sun, others include equal divisors resulting in whole quotients and thus ease of use in decidmal, and there are theories it benefitted the Sumerians and Babylonians with their sexagesimal system (base 60).

The truth is; it's a matter of perspective. You are not dealing with base 10 anymore, even writing base 10 in source, the digital interpretation is base 2 (or base 16, a multiple of 2), so the divisor and number system reasons fall flat. The range of the sinewave table matches the range of a byte, with a repeat of the first quarter on the end.

The reason; CPU speed.

It is quicker to treat the range from 00 to FF, and allow overflow of the quotient back to 00 without the need of additional instructions (such as divu with the remainder), and to allow cos overflow if you read the last quarter. Further complications with divu arrive when you overflow 65535 to 0 (FFFF to 0000) or 4294967295 to 0 (FFFFFFFF to 0), the remainder won't save you here.

There is no reason to convert between the historical 360 range, you should be writing it as byte range, reading as byte range, and processing as byte range. In a computer game there is little reason to want historic range, the only reason would be to display the historic range on-screen for the player (perhaps a ship driving game), but this involes converting only the angle for display itself, not for reading the sine positions for actual calculation.

The short story is, you've been brought up to believe 360 is the correct and only method due to historic instances, and in order to take advantage of base 2 (16) machines, you are going to have to re-learn the angle range in byte form and really start thinking outside the box.

3. ### Brainulator

Regular garden-variety member Member
What are the exact differences between regular Kosinski and Kosinski+ (Plus)? My understanding is that the latter is meant to improve compression speed without compromising the compression ratio, resulting in at least two differences, at least as far as the 68000 is involved:
• Descriptor fields are 8-bit rather than 16-bit
• Descriptor fields are written in big-endian bit order rather than little-endian order
Is there anything else I missed?

4. ### Cokie

C. Okie Member
49
7
8
I understand that 0x0 to 0x1FF is the sin values with 0x80 to 0x280 is cosine. But can you please clarify what you mean the table matches the range of a byte

Also want to make sure I understand correctly each cosine and cosine value is a signed word . Making 0x100 ( 256 ) two byte signed sin and cos values

Last edited by a moderator: Sep 13, 2022
5. ### Devon

There's nothing left but faith Tech Member
867
610
93
One sine cycle in the Genesis Sonic games is 0x100 values, and each value is a 16-bit word, so that's 0x200 bytes. The last 0x80 bytes is merely just the start of another cycle so that the cosine can easily be calculated by just offsetting the angle value (which is what's dictating the "byte range" in the first place, since the input angle value is just a byte).

6. ### Cokie

C. Okie Member
49
7
8
So that last 0x80 is the end and last values in the cosine table ? Never mind figured out .

Couldn’t the sine of 0 - 90 only been stored in tanks reducing space and then assembly code could have calculate both sine and cosine with just that by first negating sin value if in quadrant 2 or 3 and negating the cosine if in quadrant 2 and 3 . And start from the start or end of the table when doing indirect reference to depending on if quadrant as well since the sine (89) equals sine(91) . Wouldn’t that result in only 0x80 bytes of space rather than 0x280 . Don’t know it’s practical .

Last edited by a moderator: Sep 13, 2022
7. ### Devon

There's nothing left but faith Tech Member
867
610
93
That's actually what Sonic CD does in the title screen and special stages for its sine function (although, its range is 0-0x1FF instead of 0-0xFF). Of course, doing it this way is slower, and for some applications, may not be desirable, particularly with more time critical stuff. It's a matter of time vs. space.

8. ### Cokie

C. Okie Member
49
7
8
Ah . And the s2 disassembly says the output is sin and cos time 255 shouldn’t it be times 256

9. ### Devon

There's nothing left but faith Tech Member
867
610
93
Yes, considering that sin(90deg) = 0x100 here. The sine table is in 8.8 fixed point format.

10. ### Brainulator

Regular garden-variety member Member
Speaking of, any reason why -sin(\$13) is -\$75 while sin(\$13) is \$73? No other sine values do this.

11. ### Devon

There's nothing left but faith Tech Member
867
610
93
Because that's just how it's defined in the table. I dunno how exactly it was generated, but my best guess is that some kind of thing with rounding.

• Like x 1
• Agree x 1
• List
12. ### Cokie

C. Okie Member
49
7
8
When u say its 8.8 fixed point, do u mean a decimal where upper byte is integer a d the lower is the decimal ? I thought they were just signed word values. Like It is the approx result of sin or cos of hex_angle*1.40625 , multiplied by 256 so it turns to a word that spans from -\$100 to \$100.

13. ### Devon

There's nothing left but faith Tech Member
867
610
93
Yes.

That's how they get the fractional part to be visible in the table. The 68000 doesn't support floating point, so it has to be done that way.

14. ### Cokie

C. Okie Member
49
7
8
Im not following how its a 8.8 fixed value..specifically, i dont see how there is a decimal portion as the upper bytes are either FF (negative) or 00 or 01 ( in case if 0100) the lower bytes are the value or the (lower byte ) of the 2s complement of it. For instance 0006 is at offset 0x2 . how is there an integer and decimal portion if this it appears just a unsigned word ?

15. ### MainMemory

Kate the Wolf Tech Member
4,649
214
43
SonLVL
In an 8.8 fixed-point value, 8 bits are fractional and 8 bits are whole, so (1 << 8) or 0x100 is equivalent to 1.0 in floating-point.
Divide the value by 0x100 (256) to get the floating-point representation, 0.0234375. Conversely, conversion from floating-point to fixed-point can be done by multiplication.

16. ### nineko

I am the Holy Cat Tech Member
6,173
419
63
italy
In fixed-point values you simply have to change the meaning of the exponents when you convert from hexadecimal to decimal. In a 16-bit value, you'd normally say that the MSb is 2^15 and the LSb is 2^0, but they are 2^7 and 2^-8 here respectively.

Like MainMemory said, your \$0006 becomes 0.0234375. Why?

\$0006 = 0000 0000 0000 0110
0 × 2^-8 = 0
1 × 2^-7 = 0.0078125
1 × 2^-6 = 0.015625

0.0078125 + 0.015625 = 0.0234375

\$3C06 = 0011 1100 0000 0110

The fractional part is the same (0.0234375), while the integral part is 60, so you end up with 60.0234375.

In practice, you can also think at \$3C06 as 15366, and 15366/256 is (you guessed it) 60.0234375.

17. ### Devon

There's nothing left but faith Tech Member
867
610
93
The sine table is also still signed as well, so \$FFFA (-6) would come out as -0.0234375.

Sure, you could interpret the table as just sin(x) * 256 and call it a day, as that's technically correct, but I think considering the contexts that it usually gets used in (i.e. multiplying the ground speed value by the sine/cosine of the angle to get the actual X/Y speed, all 3 speed values being in 8.8 fixed point), I'd say it's "more accurate" to say it's in 8.8 fixed point.

There's not really any actual special technical thing that makes fixed point values stand out, except the context the values are used in. Sure, something like 0x002A * 0x0180, for example, is equal to 0x3F00, and then divide that by 0x100 to get 0x003F, but if I add in the context that 0x002A is the sine of an angle, and 0x0180 is some sort of speed value, both in 8.8 fixed point, then that overall operation can also mean 0.1640625 * 1.5 = 0.24609375, which in the context of a sine value and speed value, makes more sense to look at that way (by the way, multiplying 2 8.8 fixed point values gets you a 16.16 fixed point value, so diving it by 0x100 helps bring it back down to 8.8 fixed point, which you can see in the code that calculates the X/Y speeds from Sonic's ground speed and angle).

Last edited: Sep 15, 2022
18. ### Cokie

C. Okie Member
49
7
8
Thank you all for you excellent help , helped make sense of this

Also Lapper states the original games are clockwise where 45 degrees in clockwise would be 315 in CC. Why is this and how is used in application of the game?

Last edited by a moderator: Sep 16, 2022
19. ### Nik Pi

Member
When i try to insert new sprites in S3K, and save mapping and DPLC- sonmaped and flex2 saves that WRONG, and as result- you have a shit instead of ordered sprites..
What is going here? Why it happening?

20. ### Devon

There's nothing left but faith Tech Member
867
610
93
It's really to do with how the original games apply the movement angle. So, in general mathematics, sin(90 degrees) = 1, and positive Y values move upwards instead of downwards. However, in a game, you usually see positive Y values pointing DOWNWARDS instead. The Physics Guide has you negative the sine value so that 90 degrees points you upwards, like it would in a regular mathematical grid, but the original games don't do that. Instead, they set the collision blocks' angles to be counter clockwise, so that they push Sonic in the right direction.