Skip to content

Instantly share code, notes, and snippets.

@aji

aji/speed.c Secret

Last active January 24, 2017 03:39
Show Gist options
  • Save aji/901f6ceb6462fb09d807944ebe4beb1b to your computer and use it in GitHub Desktop.
Save aji/901f6ceb6462fb09d807944ebe4beb1b to your computer and use it in GitHub Desktop.
// at 0x276e8 is a sin table where 0x800 = 360 degrees
a0 = 0x276e8 + a6[0x32]; // direction
d0 = a0[0]; // word
d1 = a0[0x200]; // word
// this makes d0 = sin(th) and d1 = sin(th+0x200) = sin(th+90deg) = cos(th)
// where th is the direction sonic is facing.
d4 = d2 = (a6[0x12] >> 4); // X speed (long read)
d5 = d3 = (a6[0x1a] >> 4); // Y speed (long read)
// the multiplication here uses regular muls instructions,
// which only multiply the lower word of each operand. however,
// the X/Y speed values during gameplay only use their lower 20
// bits, and the values are right shifted by 4 bits above to
// make them signed 16 bit values.
// notice that the following code is multiplying Sonic's X and Y world
// speeds by a rotation matrix:
// d5 = cos(th)*vy - sin(th)*vx; -> [ cos(th) -sin(th) ] [ vy ]
// d3 = sin(th)*vy + cos(th)*vx; [ sin(th) cos(th) ] [ vx ]
d3 = d0*d3 + d1*d2;
d5 = d1*d5 - d0*d4;
d2 = d3;
d3 = d5;
// we need to divide by 2^15, since we're essentially working with
// 15-bit fixed point values and need to shed the extra factor of
// 2^15 we acquired during the multiplications in the last step
d2 >>= 15; // arithmetic shift
d3 >>= 15; // arithmetic shift
if ((d7 & 0xf) != 0xf) {
d3 += a6[0x22];
}
if (d2 != 0) {
if (d2 >= 0) {
d2 -= a6[0x2a];
if (d2 < 0) d2 = 0;
} else {
d2 += a6[0x2a];
if (d2 > 0) d2 = 0;
}
}
if (d3 != 0) {
if (d3 >= 0) {
d3 -= a6[0x26];
if (d3 < 0) d3 = 0;
} else {
d3 += a6[0x26];
if (d3 > 0) d3 = 0;
}
}
d4 = a6[0x2e];
d5 = -d4;
if (d2 > d4) {
if (d2 > 0x7f00) {
d2 = 0x7f00;
} else {
d2 -= a6[0x22];
}
} else if (d2 < d5) {
if (d2 < -0x7f00) {
d2 = -0x7f00;
} else {
d2 += a6[0x22];
}
}
if (d3 > d4) {
if (d3 > 0x7f00) {
d3 = 0x7f00;
} else {
d3 -= a6[0x22];
}
} else if (d3 < d5) {
if (d3 < -0x7f00) {
d3 = -0x7f00;
} else {
d3 += a6[0x22];
}
}
loc_3510:
a6[0x20] = d2; // ???
a6[0x1e] = d3; // speed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment