diff --git a/src/actors/banana/update.inc.c b/src/actors/banana/update.inc.c index d3bbc6563..e96c2d502 100644 --- a/src/actors/banana/update.inc.c +++ b/src/actors/banana/update.inc.c @@ -72,7 +72,7 @@ void update_actor_banana(struct BananaActor* banana) { temp_f0 = (player->speed * 0.75f) + 3.5f + pad3; } vec3f_set(someVelocity, 0, pad3, temp_f0); - func_802B64C4(someVelocity, player->rotation[1] + player->unk_0C0); + vec3f_rotate_y(someVelocity, player->rotation[1] + player->unk_0C0); banana->velocity[0] = someVelocity[0]; banana->velocity[1] = someVelocity[1]; banana->velocity[2] = someVelocity[2]; @@ -121,7 +121,7 @@ void update_actor_banana(struct BananaActor* banana) { someVelocity[0] = 0.0f; someVelocity[1] = 0.0f; someVelocity[2] = -5.0f; - func_802B64C4(someVelocity, player->rotation[1] + player->unk_0C0); + vec3f_rotate_y(someVelocity, player->rotation[1] + player->unk_0C0); unkX = player->pos[0] + someVelocity[0]; unkY = player->pos[1] + someVelocity[1]; unkZ = player->pos[2] + someVelocity[2]; diff --git a/src/actors/blue_and_red_shells/update.inc.c b/src/actors/blue_and_red_shells/update.inc.c index c479ef3bd..d45f3e727 100644 --- a/src/actors/blue_and_red_shells/update.inc.c +++ b/src/actors/blue_and_red_shells/update.inc.c @@ -172,9 +172,9 @@ s16 func_802B3FD0(Player* owner, struct ShellActor* shell) { if (gPlayerBalloonCount[playerIndex] < 0) { continue; } - // func_802B51E8 is not quite a 3D distance function, it doubles (rather than squares) the Z difference of the + // dist_squared_bugged is not quite a 3D distance function, it doubles (rather than squares) the Z difference of the // positions - playerToShellDistance = func_802B51E8(player->pos, shell->pos); + playerToShellDistance = dist_squared_bugged(player->pos, shell->pos); if (playerToShellDistance < smallestDistance) { smallestDistance = playerToShellDistance; playerId = player - gPlayerOne; @@ -323,7 +323,7 @@ void update_actor_red_blue_shell(struct ShellActor* shell) { somePosVel[0] = 0.0f; somePosVel[1] = 0.0f; somePosVel[2] = height; - func_802B64C4(somePosVel, (s16) (player->rotation[1] + player->unk_0C0)); + vec3f_rotate_y(somePosVel, (s16) (player->rotation[1] + player->unk_0C0)); shell->velocity[0] = somePosVel[0]; shell->velocity[1] = somePosVel[1]; shell->velocity[2] = somePosVel[2]; diff --git a/src/actors/green_shell/update.inc.c b/src/actors/green_shell/update.inc.c index 8dd5e277d..8b9435cac 100644 --- a/src/actors/green_shell/update.inc.c +++ b/src/actors/green_shell/update.inc.c @@ -66,7 +66,7 @@ void update_actor_green_shell(struct ShellActor* shell) { somePosVel[0] = 0.0f; somePosVel[1] = 0.0f; somePosVel[2] = -var_f2; - func_802B64C4(somePosVel, player->rotation[1] + player->unk_0C0); + vec3f_rotate_y(somePosVel, player->rotation[1] + player->unk_0C0); shell->velocity[0] = somePosVel[0]; shell->velocity[1] = somePosVel[1]; shell->velocity[2] = somePosVel[2]; @@ -118,7 +118,7 @@ void update_actor_green_shell(struct ShellActor* shell) { somePosVel[0] = 0.0f; somePosVel[1] = 0.0f; somePosVel[2] = var_f2; - func_802B64C4(somePosVel, player->rotation[1] + player->unk_0C0); + vec3f_rotate_y(somePosVel, player->rotation[1] + player->unk_0C0); shell->velocity[0] = somePosVel[0]; shell->velocity[1] = somePosVel[1]; shell->velocity[2] = somePosVel[2]; diff --git a/src/camera.c b/src/camera.c index 4fb9bf656..56274ef69 100644 --- a/src/camera.c +++ b/src/camera.c @@ -185,7 +185,7 @@ void camera_init(f32 posX, f32 posY, f32 posZ, UNUSED s16 rot, u32 arg4, s32 cam } break; } - func_802B7F7C(camera->pos, camera->lookAt, camera->rot); + planar_angles(camera->pos, camera->lookAt, camera->rot); } void func_8001CA10(Camera* camera) { diff --git a/src/player_controller.c b/src/player_controller.c index c5d5282c1..6c319ee3f 100644 --- a/src/player_controller.c +++ b/src/player_controller.c @@ -728,9 +728,9 @@ void func_8002934C(Player* player, Camera* camera, s8 screenId, s8 playerId) { temp_f0 = player->unk_230 - player->unk_23C; if ((player->effects & 8) != 8) { if ((player->effects & LIGHTNING_EFFECT) == LIGHTNING_EFFECT) { - player->unk_0CC[screenId] = (s16) ((s32) (((f64) func_802B7C40(temp_f0 / temp_f2)) * 1.6)); + player->unk_0CC[screenId] = (s16) ((s32) (((f64) atan1s(temp_f0 / temp_f2)) * 1.6)); } else { - player->unk_0CC[screenId] = func_802B7C40(temp_f0 / temp_f2) * 2; + player->unk_0CC[screenId] = atan1s(temp_f0 / temp_f2) * 2; } } if ((player->effects & HIT_EFFECT) == HIT_EFFECT) { @@ -738,14 +738,14 @@ void func_8002934C(Player* player, Camera* camera, s8 screenId, s8 playerId) { } if ((player->effects & 8) != 8) { temp_f0 = player->unk_1F8 - player->unk_1FC; - player->unk_0D4[screenId] = (((func_802B7C40(temp_f0 / temp_f2)) * 0.9)); + player->unk_0D4[screenId] = (((atan1s(temp_f0 / temp_f2)) * 0.9)); } else { if (((player->animFrameSelector[screenId]) >= 0) && ((player->animFrameSelector[screenId]) < 0x101)) { var_f0 = player->oldPos[1] - player->pos[1]; } else { var_f0 = player->pos[1] - player->oldPos[1]; } - player->unk_0D4[screenId] = (s16) ((s32) (((f64) func_802B7C40(var_f0 / temp_f2)) * 0.5)); + player->unk_0D4[screenId] = (s16) ((s32) (((f64) atan1s(var_f0 / temp_f2)) * 0.5)); } if ((player->effects & HIT_EFFECT) == HIT_EFFECT) { player->unk_0D4[screenId] = (s16) ((s32) player->unk_D9C); @@ -930,16 +930,16 @@ void func_80029B4C(Player* player, UNUSED f32 arg1, f32 arg2, UNUSED f32 arg3) { } temp_f2_3 = ((gCharacterSize[player->characterId] * 18.0f) + 1.0f) * player->size; temp_f0_2 = player->unk_23C - player->unk_230; - player->unk_206 = -func_802B7C40(temp_f0_2 / temp_f2_3); + player->unk_206 = -atan1s(temp_f0_2 / temp_f2_3); if (((player->unk_0CA & 2) == 2) || (player->effects & 8)) { player->unk_206 = 0; } if ((player->effects & 8) != 8) { temp_f0_2 = player->unk_1F8 - player->unk_1FC; - move_s16_towards(&player->slopeAccel, func_802B7C40(temp_f0_2 / temp_f2_3), 0.5f); + move_s16_towards(&player->slopeAccel, atan1s(temp_f0_2 / temp_f2_3), 0.5f); } else { temp_f0_2 = player->oldPos[1] - arg2; - temp_v0 = func_802B7C40(temp_f0_2 / temp_f2_3); + temp_v0 = atan1s(temp_f0_2 / temp_f2_3); if (temp_f0_2 >= 0.0f) { temp_v0 /= 4; } else { @@ -1017,13 +1017,13 @@ void func_8002A194(Player* player, f32 arg1, f32 arg2, f32 arg3) { player->tyres[FRONT_LEFT].surfaceType = player->surfaceType; var_f20 = (gCharacterSize[player->characterId] * 18) + 1; temp_f0 = (player->unk_23C - player->unk_230); - player->unk_206 = -func_802B7C40(temp_f0 / var_f20); + player->unk_206 = -atan1s(temp_f0 / var_f20); if ((player->effects & 8) != 8) { temp_f0 = (player->unk_1F8 - player->unk_1FC); - move_s16_towards(&player->slopeAccel, func_802B7C40(temp_f0 / var_f20), 0.5f); + move_s16_towards(&player->slopeAccel, atan1s(temp_f0 / var_f20), 0.5f); } else { temp_f0 = player->oldPos[1] - arg2; - temp_v0 = func_802B7C40(temp_f0 / var_f20); + temp_v0 = atan1s(temp_f0 / var_f20); if (temp_f0 >= 0.0f) { var_a1 = temp_v0 * 2; } else { diff --git a/src/racing/actors_extended.c b/src/racing/actors_extended.c index 29419c63c..9874ab760 100644 --- a/src/racing/actors_extended.c +++ b/src/racing/actors_extended.c @@ -193,7 +193,7 @@ void func_802B0788(s16 rawStickY, struct BananaBunchParent* banana_bunch, Player var_f12 = (player->speed * 0.75f) + 4.5f + var_f0; } vec3f_set(velocity, 0.0f, var_f0, var_f12); - func_802B64C4(velocity, player->rotation[1] + player->unk_0C0); + vec3f_rotate_y(velocity, player->rotation[1] + player->unk_0C0); banana->velocity[0] = velocity[0]; banana->velocity[1] = velocity[1]; banana->velocity[2] = velocity[2]; @@ -431,7 +431,7 @@ void update_actor_triple_shell(TripleShellParent* parent, s16 shellType) { someVelocity[0] = 0; someVelocity[1] = 0; someVelocity[2] = 8; - func_802B64C4(someVelocity, player->rotation[1] + player->unk_0C0); + vec3f_rotate_y(someVelocity, player->rotation[1] + player->unk_0C0); shell->velocity[0] = someVelocity[0]; shell->velocity[1] = someVelocity[1]; shell->velocity[2] = someVelocity[2]; @@ -457,7 +457,7 @@ void update_actor_triple_shell(TripleShellParent* parent, s16 shellType) { someVelocity[0] = 0; someVelocity[1] = 0; someVelocity[2] = 8; - func_802B64C4(someVelocity, player->rotation[1] + player->unk_0C0); + vec3f_rotate_y(someVelocity, player->rotation[1] + player->unk_0C0); shell->velocity[0] = someVelocity[0]; shell->velocity[1] = someVelocity[1]; shell->velocity[2] = someVelocity[2]; @@ -483,7 +483,7 @@ void update_actor_triple_shell(TripleShellParent* parent, s16 shellType) { someVelocity[0] = 0; someVelocity[1] = 0; someVelocity[2] = 8; - func_802B64C4(someVelocity, player->rotation[1] + player->unk_0C0); + vec3f_rotate_y(someVelocity, player->rotation[1] + player->unk_0C0); shell->velocity[0] = someVelocity[0]; shell->velocity[1] = someVelocity[1]; shell->velocity[2] = someVelocity[2]; diff --git a/src/racing/math_util.c b/src/racing/math_util.c index cc3799832..ec39fae89 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -14,7 +14,7 @@ s32 D_802B91C0[2] = { 13, 13 }; Vec3f D_802B91C8 = { 0.0f, 0.0f, 0.0f }; -// This functions looks similar to a segment of code from func_802A4A0C in skybox_and_splitscreen.c +// This functions looks similar to a segment of code from render_skybox in skybox_and_splitscreen.c UNUSED s32 func_802B4F60(UNUSED s32 arg0, Vec3f arg1, UNUSED s32 arg2, UNUSED f32 arg3, UNUSED f32 arg4) { Mat4 sp30; f32 sp2C; @@ -70,7 +70,7 @@ s32 render_set_position(Mat4 arg0, s32 arg1) { return 1; } -f32 func_802B51E8(Vec3f arg0, Vec3f arg1) { +f32 dist_squared_bugged(Vec3f arg0, Vec3f arg1) { f32 sub_y; f32 sub_z; f32 sub_x; @@ -90,8 +90,8 @@ s32 get_angle_between_points(Vec3f arg0, Vec3f arg1) { return atan2s(temp_v1, temp_v2); } -// get_angle_between_points -u32 func_802B5258(Vec3f arg0, Vec3s arg1) { +// copy of get_angle_between_points +UNUSED u32 func_802B5258(Vec3f arg0, Vec3s arg1) { f32 temp_v1; f32 temp_v2; temp_v1 = arg1[0] - arg0[0]; @@ -229,7 +229,7 @@ void mtxf_translate(Mat4 dest, Vec3f b) { * @param homogeneousScale Scaling factor for homogeneous coordinates. Always 1.0 in game * Note the use of `2` which generates diff asm than just using floats (2.0f). */ -void get_projection_matrix(Mat4 projMat, u16* arg1, f32 vertFov, f32 aspectRatio, f32 near, f32 far, +void mtxf_projection(Mat4 projMat, u16* arg1, f32 vertFov, f32 aspectRatio, f32 near, f32 far, f32 homogeneousScale) { f32 half_cot; s32 row_idx, col_idx; @@ -264,65 +264,77 @@ void get_projection_matrix(Mat4 projMat, u16* arg1, f32 vertFov, f32 aspectRatio } // Appears to only be for the skybox. mtxf_lookat from sm64 with some modifications. -void func_802B5794(Mat4 mtx, Vec3f from, Vec3f to) { +/** + * @brief Create a lookat matrix (convert to coordinates relative to camera) + * @param mtx dummy matrix overwritten with lookat matrix + * @param from where the camera is looking from + * @param to where the camera is looking to + */ +void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to) { // register from sm64 but not required for matching. register f32 invLength; - f32 xColY; - f32 yColY; - f32 zColY; - f32 xColZ; - f32 yColZ; - f32 zColZ; - f32 xColX; - f32 yColX; - f32 zColX; - xColY = 0.0f; - yColY = 1.0f; - zColY = 0.0f; + // forward: direction camera lens is facing + // up: direction toward top of frame + // right: direction toward right of frame + f32 upX; + f32 upY; + f32 upZ; + f32 forwardX; + f32 forwardY; + f32 forwardZ; + f32 rightX; + f32 rightY; + f32 rightZ; - xColZ = to[0] - from[0]; - yColZ = to[1] - from[1]; - zColZ = to[2] - from[2]; + upX = 0.0f; + upY = 1.0f; + upZ = 0.0f; - invLength = -1.0 / sqrtf(xColZ * xColZ + yColZ * yColZ + zColZ * zColZ); - xColZ *= invLength; - yColZ *= invLength; - zColZ *= invLength; + forwardX = to[0] - from[0]; + forwardY = to[1] - from[1]; + forwardZ = to[2] - from[2]; - xColX = yColY * zColZ - zColY * yColZ; - yColX = zColY * xColZ - xColY * zColZ; - zColX = xColY * yColZ - yColY * xColZ; + invLength = -1.0 / sqrtf(forwardX * forwardX + forwardY * forwardY + forwardZ * forwardZ); + forwardX *= invLength; + forwardY *= invLength; + forwardZ *= invLength; - invLength = 1.0 / sqrtf(xColX * xColX + yColX * yColX + zColX * zColX); + // Cross product (creates vector perpendicular to forward and up) + rightX = upY * forwardZ - upZ * forwardY; + rightY = upZ * forwardX - upX * forwardZ; + rightZ = upX * forwardY - upY * forwardX; - xColX *= invLength; - yColX *= invLength; - zColX *= invLength; + invLength = 1.0 / sqrtf(rightX * rightX + rightY * rightY + rightZ * rightZ); - xColY = yColZ * zColX - zColZ * yColX; - yColY = zColZ * xColX - xColZ * zColX; - zColY = xColZ * yColX - yColZ * xColX; + rightX *= invLength; + rightY *= invLength; + rightZ *= invLength; - invLength = 1.0 / sqrtf(xColY * xColY + yColY * yColY + zColY * zColY); - xColY *= invLength; - yColY *= invLength; - zColY *= invLength; + // Cross product + upX = forwardY * rightZ - forwardZ * rightY; + upY = forwardZ * rightX - forwardX * rightZ; + upZ = forwardX * rightY - forwardY * rightX; - mtx[0][0] = xColX; - mtx[1][0] = yColX; - mtx[2][0] = zColX; - mtx[3][0] = -(from[0] * xColX + from[1] * yColX + from[2] * zColX); + invLength = 1.0 / sqrtf(upX * upX + upY * upY + upZ * upZ); + upX *= invLength; + upY *= invLength; + upZ *= invLength; - mtx[0][1] = xColY; - mtx[1][1] = yColY; - mtx[2][1] = zColY; - mtx[3][1] = -(from[0] * xColY + from[1] * yColY + from[2] * zColY); + mtx[0][0] = rightX; + mtx[1][0] = rightY; + mtx[2][0] = rightZ; + mtx[3][0] = -(from[0] * rightX + from[1] * rightY + from[2] * rightZ); - mtx[0][2] = xColZ; - mtx[1][2] = yColZ; - mtx[2][2] = zColZ; - mtx[3][2] = -(from[0] * xColZ + from[1] * yColZ + from[2] * zColZ); + mtx[0][1] = upX; + mtx[1][1] = upY; + mtx[2][1] = upZ; + mtx[3][1] = -(from[0] * upX + from[1] * upY + from[2] * upZ); + + mtx[0][2] = forwardX; + mtx[1][2] = forwardY; + mtx[2][2] = forwardZ; + mtx[3][2] = -(from[0] * forwardX + from[1] * forwardY + from[2] * forwardZ); mtx[0][3] = 0.0f; mtx[1][3] = 0.0f; @@ -420,18 +432,21 @@ void func_802B5B14(Vec3f b, Vec3s rotate) { b[2] = copy[0] * mtx[2][0] + copy[1] * mtx[2][1] + copy[1] * mtx[2][2]; } -void func_802B5CAC(s16 arg0, s16 arg1, Vec3f arg2) { - f32 sp2C = sins(arg1); - f32 sp28 = coss(arg1); - f32 sp24 = sins(arg0); - f32 temp_f10 = coss(arg0); + // rotates (0, 0, -1) about the x and y axis, in that order +void vec_unit_z_rotX_rotY(s16 rotY, s16 rotX, Vec3f arg2) { + f32 sinX = sins(rotX); + f32 cosX = coss(rotX); + f32 sinY = sins(rotY); + f32 cosY = coss(rotY); + + arg2[0] = cosX * sinY; + arg2[1] = sinX; + arg2[2] = -(cosX * cosY); + // (0, 0, -1) -> (0, sinX, -cosX) -> (cosX * sinY, sinX, -(cosX * cosY)) - arg2[0] = sp28 * sp24; - arg2[1] = sp2C; - arg2[2] = -(sp28 * temp_f10); } -void func_802B5D30(s16 arg0, s16 arg1, s32 arg2) { +UNUSED void func_802B5D30(s16 arg0, s16 arg1, s32 arg2) { set_course_lighting((Lights1*) 0x9000000, arg0, arg1, arg2); } @@ -624,17 +639,17 @@ void mtxf_translate_vec3f_mat4(Vec3f pos, Mat4 mat) { UNUSED void func_802B64B0(UNUSED s32 arg0, UNUSED s32 arg1, UNUSED s32 arg2, UNUSED s32 arg3) { } -void func_802B64C4(Vec3f arg0, s16 arg1) { - f32 sp2C = sins(arg1); - f32 temp_f0 = coss(arg1); +void vec3f_rotate_y(Vec3f vector, s16 rotationAngle) { + f32 sinAngle = sins(rotationAngle); + f32 cosAngle = coss(rotationAngle); - f32 temp1 = arg0[0]; - f32 temp2 = arg0[1]; - f32 temp3 = arg0[2]; + f32 temp1 = vector[0]; + f32 temp2 = vector[1]; + f32 temp3 = vector[2]; - arg0[0] = temp_f0 * temp1 - (sp2C * temp3); - arg0[1] = temp2; - arg0[2] = sp2C * temp1 + (temp_f0 * temp3); + vector[0] = cosAngle * temp1 - (sinAngle * temp3); + vector[1] = temp2; + vector[2] = sinAngle * temp1 + (cosAngle * temp3); } void calculate_orientation_matrix(Mat3 dest, f32 arg1, f32 arg2, f32 arg3, s16 rotationAngle) { @@ -766,7 +781,7 @@ void calculate_rotation_matrix(Mat3 destMatrix, s16 rotationAngle, f32 rotationX destMatrix[0][1] = temp + (rotationZ * sinValue); } -void func_802B6BC0(Mat4 arg0, s16 arg1, f32 arg2, f32 arg3, f32 arg4) { +UNUSED void func_802B6BC0(Mat4 arg0, s16 arg1, f32 arg2, f32 arg3, f32 arg4) { f32 sine; f32 cosine; f32 temp_f0; @@ -804,7 +819,7 @@ void func_802B6BC0(Mat4 arg0, s16 arg1, f32 arg2, f32 arg3, f32 arg4) { } // look like create a translation and rotation matrix with arg1 position and arg2 rotation -void func_802B6D58(Mat4 arg0, Vec3f arg1, Vec3f arg2) { +UNUSED void func_802B6D58(Mat4 arg0, Vec3f arg1, Vec3f arg2) { f32 sine1; f32 cosine1; f32 sine2; @@ -1025,7 +1040,7 @@ UNUSED void func_802B7C18(f32 arg0) { atan2f(arg0, 1.0f); } -s16 func_802B7C40(f32 arg0) { +s16 atan1s(f32 arg0) { return atan2s(arg0, 1.0f); } @@ -1033,8 +1048,13 @@ UNUSED void func_802B7C6C(f32 arg0) { atan2f(arg0, sqrtf(1.0 - (arg0 * arg0))); } -s16 func_802B7CA8(f32 arg0) { - return atan2s(arg0, sqrtf(1.0 - (arg0 * arg0))); +s16 asin1s(f32 sin_theta) { + return atan2s(sin_theta, sqrtf(1.0 - (sin_theta * sin_theta))); + /* atan(sin_theta / sqrt(1 - sin**2(theta))) + = atan(sin_theta / sqrt(cos**2(theta))) + = atan(sin_theta / cos_theta) + = atan(tan_theta) + = theta */ } f32 calculate_vector_angle_xy(f32 vectorX) { @@ -1077,22 +1097,22 @@ u16 random_int(u16 arg0) { return arg0 * (((f32) random_u16()) / 65535.0); } -s16 func_802B7F34(f32 arg0, f32 arg1, f32 arg2, f32 arg3) { - return atan2s(arg2 - arg0, arg3 - arg1); +s16 angle_from_coords(f32 vec0x, f32 vec0y, f32 vec1x, f32 vec1y) { + return atan2s(vec1x - vec0x, vec1y - vec0y); } -void func_802B7F7C(Vec3f arg0, Vec3f arg1, Vec3s dest) { - f32 x1 = arg0[0]; - f32 y1 = arg0[1]; - f32 z1 = arg0[2]; +void planar_angles(Vec3f from, Vec3f to, Vec3s rot_angles) { + f32 fromX = from[0]; + f32 fromY = from[1]; + f32 fromZ = from[2]; - f32 x2 = arg1[0]; - f32 y2 = arg1[1]; - f32 z2 = arg1[2]; + f32 toX = to[0]; + f32 toY = to[1]; + f32 toZ = to[2]; - dest[1] = func_802B7F34(z1, x1, z2, x2); - dest[0] = func_802B7F34(y1, z1, y2, z2); - dest[2] = func_802B7F34(x1, y1, x2, y2); + rot_angles[1] = angle_from_coords(fromZ, fromX, toZ, toX); + rot_angles[0] = angle_from_coords(fromY, fromZ, toY, toZ); + rot_angles[2] = angle_from_coords(fromX, fromY, toX, toY); } f32 sins(u16 arg0) { @@ -1181,7 +1201,7 @@ f32 is_within_render_distance(Vec3f cameraPos, Vec3f objectPos, u16 orientationY if (is_visible_between_angle((u16) plus_fov_angle, (u16) minus_fov_angle, angleObject) == 1) { return distance; } - temp_v0 = func_802B7CA8(minDistance / distance); + temp_v0 = asin1s(minDistance / distance); temp = angleObject + temp_v0; if (is_visible_between_angle(plus_fov_angle, minus_fov_angle, temp) == 1) { diff --git a/src/racing/math_util.h b/src/racing/math_util.h index 0ec5445a0..1fa92d52d 100644 --- a/src/racing/math_util.h +++ b/src/racing/math_util.h @@ -14,13 +14,12 @@ // Here to appease the pragma gods double fabs(double x); -void func_802B5794(Mat4, Vec3f, Vec3f); -s32 func_802B4F60(s32, Vec3f, s32, f32, f32); +void func_802B5794(Mat4, Vec3f, Vec3f); // Unused +s32 func_802B4F60(s32, Vec3f, s32, f32, f32); // Unused s32 render_set_position(Mat4, s32); -f32 func_802B51E8(Vec3f, Vec3f); +f32 dist_squared_bugged(Vec3f, Vec3f); s32 get_angle_between_points(Vec3f, Vec3f); -u32 func_802B5258(Vec3f, Vec3s); -void func_802B5794(Mat4, Vec3f, Vec3f); +u32 func_802B5258(Vec3f, Vec3s); // Unused void vec3f_set(Vec3f, f32, f32, f32); void vec3s_set(Vec3s, s16, s16, s16); void* vec3f_copy_return(Vec3f, Vec3f); @@ -32,36 +31,36 @@ void mtxf_identity(Mat4); void add_translate_mat4_vec3f(Mat4, Mat4, Vec3f); void add_translate_mat4_vec3f_lite(Mat4, Mat4, Vec3f); void mtxf_translate(Mat4, Vec3f); -void get_projection_matrix(Mat4, u16*, f32, f32, f32, f32, f32); -void func_802B5794(Mat4, Vec3f, Vec3f); +void mtxf_projection(Mat4, u16*, f32, f32, f32, f32, f32); +void mtxf_lookat(Mat4, Vec3f, Vec3f); void mtxf_rotate_x(Mat4, s16); void mtxf_rotate_y(Mat4, s16); void mtxf_s16_rotate_z(Mat4, s16); -void func_802B5B14(Vec3f b, Vec3s rotate); // unused -void func_802B5CAC(s16, s16, Vec3f); -void func_802B5D30(s16, s16, s32); +void func_802B5B14(Vec3f b, Vec3s rotate); // Unused +void func_802B5CAC(s16, s16, Vec3f); // Unused +void func_802B5D30(s16, s16, s32); // Unused void set_course_lighting(Lights1*, s16, s16, s32); void mtxf_scale(Mat4, f32); void mtxf_pos_rotation_xyz(Mat4, Vec3f, Vec3s); void mtxf_translate_vec3f_mat3(Vec3f, Mat3); void mtxf_translate_vec3f_mat4(Vec3f, Mat4); -void func_802B64C4(Vec3f, s16); +void vec3f_rotate_y(Vec3f, s16); void calculate_orientation_matrix(Mat3, f32, f32, f32, s16); void calculate_rotation_matrix(Mat3, s16, f32, f32, f32); -void func_802B6BC0(Mat4, s16, f32, f32, f32); -void func_802B6D58(Mat4, Vec3f, Vec3f); +void func_802B6BC0(Mat4, s16, f32, f32, f32); // Unused +void func_802B6D58(Mat4, Vec3f, Vec3f); // Unused void mtxf_multiplication(Mat4, Mat4, Mat4); void mtxf_to_mtx(Mtx*, Mat4); u16 atan2_lookup(f32, f32); u16 atan2s(f32, f32); f32 atan2f(f32, f32); -s16 func_802B7C40(f32); -s16 func_802B7CA8(f32); +s16 atan1s(f32); +s16 asin1s(f32); f32 calculate_vector_angle_xy(f32); u16 random_u16(void); u16 random_int(u16); -s16 func_802B7F34(f32, f32, f32, f32); -void func_802B7F7C(Vec3f, Vec3f, Vec3s); +s16 angle_from_coords(f32, f32, f32, f32); +void planar_angles(Vec3f, Vec3f, Vec3s); f32 sins(u16); f32 coss(u16); s32 is_visible_between_angle(u16, u16, u16); diff --git a/src/racing/render_courses.c b/src/racing/render_courses.c index 4cb202acb..506baa855 100644 --- a/src/racing/render_courses.c +++ b/src/racing/render_courses.c @@ -1509,7 +1509,7 @@ void course_generate_collision_mesh(void) { nullify_displaylist((uintptr_t) 0x070003C8); } parse_course_displaylists((uintptr_t) &d_course_choco_mountain_addr); - func_802B5CAC(0x238E, 0x31C7, D_8015F590); + vec_unit_z_rotX_rotY(0x238E, 0x31C7, D_8015F590); func_80295C6C(); D_8015F8E4 = -80.0f; break; diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index 81c034037..64ff0d184 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -23,7 +23,7 @@ Vp D_802B8880[] = { { { { 640, 480, 511, 0 }, { 640, 480, 511, 0 } } }, }; -Vtx D_802B8890[] = { +Vtx skyboxP1[] = { { { { SCREEN_WIDTH, SCREEN_HEIGHT, -1 }, 0, { 0, 0 }, { 0xC8, 0xC8, 0xFF, 0xFF } } }, { { { SCREEN_WIDTH, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, @@ -34,7 +34,7 @@ Vtx D_802B8890[] = { { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x00, 0xDC, 0x00, 0xFF } } }, }; -Vtx D_802B8910[] = { +Vtx skyboxP2[] = { { { { SCREEN_WIDTH, SCREEN_HEIGHT, -1 }, 0, { 0, 0 }, { 0xC8, 0xC8, 0xFF, 0xFF } } }, { { { SCREEN_WIDTH, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, @@ -45,7 +45,7 @@ Vtx D_802B8910[] = { { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x00, 0xDC, 0x00, 0xFF } } }, }; -Vtx D_802B8990[] = { +Vtx skyboxP3[] = { { { { SCREEN_WIDTH, SCREEN_HEIGHT, -1 }, 0, { 0, 0 }, { 0xC8, 0xC8, 0xFF, 0xFF } } }, { { { SCREEN_WIDTH, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, @@ -56,7 +56,7 @@ Vtx D_802B8990[] = { { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x00, 0xDC, 0x00, 0xFF } } }, }; -Vtx D_802B8A10[] = { +Vtx skyboxP4[] = { { { { SCREEN_WIDTH, SCREEN_HEIGHT, -1 }, 0, { 0, 0 }, { 0xC8, 0xC8, 0xFF, 0xFF } } }, { { { SCREEN_WIDTH, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, @@ -443,6 +443,7 @@ void course_set_skybox_colours(Vtx* skybox) { #endif } +// Almost identical to end of render_skybox void func_802A487C(Vtx* arg0, UNUSED struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, UNUSED s32 arg3, UNUSED f32* arg4) { @@ -461,46 +462,62 @@ void func_802A487C(Vtx* arg0, UNUSED struct UnkStruct_800DC5EC* arg1, UNUSED s32 } } -void func_802A4A0C(Vtx* vtx, struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, UNUSED s32 arg3, UNUSED f32* arg4) { +/** + * @brief Sets skybox horizon. Some coordinate transformations which can affect game physics and display of player sprite + * @param skybox player skybox + * @param arg1 something camera related + * @param arg2 unused + * @param arg3 unused + * @parma arg4 unused + */ +void render_skybox(Vtx* skybox, struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, UNUSED s32 arg3, + UNUSED f32* arg4) { Camera* camera = arg1->camera; - s16 temp_t5; - f32 temp_f0; + s16 horizonRow; + f32 homogFactor; UNUSED s32 pad[2]; UNUSED u16 pad2; u16 sp128; - Mat4 matrix1; - Mat4 matrix2; - Mat4 matrix3; - Vec3f sp5C; - f32 sp58; + Mat4 projMtx; + Mat4 lookAtMtx; + Mat4 lookAndProjMtx; + Vec3f horizonPoint; + f32 homogScale; - course_set_skybox_colours(vtx); - sp5C[0] = 0.0f; - sp5C[1] = 0.0f; - sp5C[2] = 30000.0f; - get_projection_matrix(matrix1, &sp128, camera->unk_B4, gScreenAspect, gCourseNearPersp, gCourseFarPersp, 1.0f); - func_802B5794(matrix2, camera->pos, camera->lookAt); - mtxf_multiplication(matrix3, matrix1, matrix2); + course_set_skybox_colours(skybox); - sp58 = ((matrix3[0][3] * sp5C[0]) + (matrix3[1][3] * sp5C[1]) + (matrix3[2][3] * sp5C[2])) + matrix3[3][3]; + // horizonPoint is an apparently arbitrary point on the horizon (technically, where y = 0). Used for skybox horizon + horizonPoint[0] = 0.0f; + horizonPoint[1] = 0.0f; + horizonPoint[2] = 30000.0f; + mtxf_projection(projMtx, &sp128, camera->unk_B4, gScreenAspect, gCourseNearPersp, gCourseFarPersp, 1.0f); + mtxf_lookat(lookAtMtx, camera->pos, camera->lookAt); + mtxf_multiplication(lookAndProjMtx, projMtx, lookAtMtx); - mtxf_translate_vec3f_mat4(sp5C, matrix3); + /* math would have been simpler if horizonPoint had an additional homogenous coordinate set to 1. Recreated here in + extra steps */ + homogScale = ((lookAndProjMtx[0][3] * horizonPoint[0]) + (lookAndProjMtx[1][3] * horizonPoint[1]) + + (lookAndProjMtx[2][3] * horizonPoint[2])) + + lookAndProjMtx[3][3]; + mtxf_translate_vec3f_mat4(horizonPoint, lookAndProjMtx); - temp_f0 = (1.0 / sp58); + homogFactor = (1.0 / homogScale); - sp5C[0] *= temp_f0; - sp5C[1] *= temp_f0; + horizonPoint[0] *= homogFactor; + horizonPoint[1] *= homogFactor; - sp5C[0] *= 160.0f; - sp5C[1] *= 120.0f; + horizonPoint[0] *= 160.0f; // SCREEN_WIDTH / 2 + horizonPoint[1] *= 120.0f; // SCREEN_HEIGHT / 2 - temp_t5 = 120 - (s16) sp5C[1]; - arg1->cameraHeight = temp_t5; - vtx[1].v.ob[1] = temp_t5; - vtx[2].v.ob[1] = temp_t5; - vtx[4].v.ob[1] = temp_t5; - vtx[7].v.ob[1] = temp_t5; + horizonRow = 120 - (s16) horizonPoint[1]; + arg1->cameraHeight = horizonRow; + skybox[1].v.ob[1] = horizonRow; + skybox[2].v.ob[1] = horizonRow; + skybox[4].v.ob[1] = horizonRow; + skybox[7].v.ob[1] = horizonRow; + + // this section reders the skybox. Unclear if it does anything else init_rdp(); gDPSetRenderMode(gDisplayListHead++, G_RM_OPA_SURF, G_RM_OPA_SURF2); gSPClearGeometryMode(gDisplayListHead++, G_ZBUFFER | G_LIGHTING); @@ -509,10 +526,10 @@ void func_802A4A0C(Vtx* vtx, struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, U gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxScreen), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&D_0D008E98), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPVertex(gDisplayListHead++, &vtx[0], 4, 0); + gSPVertex(gDisplayListHead++, &skybox[0], 4, 0); gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0); if (gCurrentCourseId == COURSE_RAINBOW_ROAD) { - gSPVertex(gDisplayListHead++, &vtx[4], 4, 0); + gSPVertex(gDisplayListHead++, &skybox[4], 4, 0); gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0); } } @@ -604,7 +621,7 @@ void func_802A4EF4(void) { break; } } - +// player 2 vertical void func_802A5004(void) { init_rdp(); @@ -616,13 +633,13 @@ void func_802A5004(void) { func_802A39E0(D_800DC5F0); if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8910, D_800DC5F0, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[1]); + render_skybox((Vtx*) skyboxP2, D_800DC5F0, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[1]); func_80057FC4(2); - func_802A487C((Vtx*) D_802B8910, D_800DC5F0, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[1]); + func_802A487C((Vtx*) skyboxP2, D_800DC5F0, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[1]); func_80093A30(2); } } - +// player 1 vertical void func_802A50EC(void) { init_rdp(); @@ -633,13 +650,13 @@ void func_802A50EC(void) { func_802A39E0(D_800DC5EC); if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8890, D_800DC5EC, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[0]); + render_skybox((Vtx*) skyboxP1, D_800DC5EC, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[0]); func_80057FC4(1); - func_802A487C((Vtx*) D_802B8890, D_800DC5EC, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[0]); + func_802A487C((Vtx*) skyboxP1, D_800DC5EC, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[0]); func_80093A30(1); } } - +// player 1 horizontal void func_802A51D4(void) { init_rdp(); @@ -650,13 +667,13 @@ void func_802A51D4(void) { gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8890, D_800DC5EC, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[0]); + render_skybox((Vtx*) skyboxP1, D_800DC5EC, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[0]); func_80057FC4(3); - func_802A487C((Vtx*) D_802B8890, D_800DC5EC, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[0]); + func_802A487C((Vtx*) skyboxP1, D_800DC5EC, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[0]); func_80093A30(3); } } - +// player 2 horizontal void func_802A52BC(void) { init_rdp(); @@ -667,13 +684,13 @@ void func_802A52BC(void) { gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8910, D_800DC5F0, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[1]); + render_skybox((Vtx*) skyboxP2, D_800DC5F0, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[1]); func_80057FC4(4); - func_802A487C((Vtx*) D_802B8910, D_800DC5F0, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[1]); + func_802A487C((Vtx*) skyboxP2, D_800DC5F0, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[1]); func_80093A30(4); } } - +// player 1 solo void func_802A53A4(void) { move_segment_table_to_dmem(); @@ -686,15 +703,15 @@ void func_802A53A4(void) { init_z_buffer(); select_framebuffer(); if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8890, D_800DC5EC, 0x140, 0xF0, &gCameraZoom[0]); + render_skybox((Vtx*) skyboxP1, D_800DC5EC, 0x140, 0xF0, &gCameraZoom[0]); if (gGamestate != CREDITS_SEQUENCE) { func_80057FC4(0); } - func_802A487C((Vtx*) D_802B8890, D_800DC5EC, 0x140, 0xF0, &gCameraZoom[0]); + func_802A487C((Vtx*) skyboxP1, D_800DC5EC, 0x140, 0xF0, &gCameraZoom[0]); func_80093A30(0); } } - +// player 1 3p 4p void func_802A54A8(void) { init_rdp(); @@ -705,13 +722,13 @@ void func_802A54A8(void) { gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8890, D_800DC5EC, 0x140, 0xF0, &gCameraZoom[0]); + render_skybox((Vtx*) skyboxP1, D_800DC5EC, 0x140, 0xF0, &gCameraZoom[0]); func_80057FC4(8); - func_802A487C((Vtx*) D_802B8890, D_800DC5EC, 0x140, 0xF0, &gCameraZoom[0]); + func_802A487C((Vtx*) skyboxP1, D_800DC5EC, 0x140, 0xF0, &gCameraZoom[0]); func_80093A30(8); } } - +// player 2 3p 4p void func_802A5590(void) { init_rdp(); @@ -722,13 +739,13 @@ void func_802A5590(void) { gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8910, D_800DC5F0, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[1]); + render_skybox((Vtx*) skyboxP2, D_800DC5F0, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[1]); func_80057FC4(9); - func_802A487C((Vtx*) D_802B8910, D_800DC5F0, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[1]); + func_802A487C((Vtx*) skyboxP2, D_800DC5F0, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[1]); func_80093A30(9); } } - +// player 3 3p4p void func_802A5678(void) { init_rdp(); @@ -739,13 +756,14 @@ void func_802A5678(void) { gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8990, D_800DC5F4, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[2]); + render_skybox((Vtx*) skyboxP3, D_800DC5F4, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[2]); func_80057FC4(10); - func_802A487C((Vtx*) D_802B8990, D_800DC5F4, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[2]); + func_802A487C((Vtx*) skyboxP3, D_800DC5F4, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[2]); func_80093A30(10); } } +// player 4 3p 4p void func_802A5760(void) { init_rdp(); @@ -774,9 +792,9 @@ void func_802A5760(void) { func_802A39E0(D_800DC5F8); if (D_800DC5B4 != 0) { - func_802A4A0C(D_802B8A10, D_800DC5F8, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[3]); + render_skybox(skyboxP4, D_800DC5F8, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[3]); func_80057FC4(11); - func_802A487C(D_802B8A10, D_800DC5F8, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[3]); + func_802A487C(skyboxP4, D_800DC5F8, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraZoom[3]); func_80093A30(11); } } diff --git a/src/racing/skybox_and_splitscreen.h b/src/racing/skybox_and_splitscreen.h index fee41aa4b..bc9f19639 100644 --- a/src/racing/skybox_and_splitscreen.h +++ b/src/racing/skybox_and_splitscreen.h @@ -8,7 +8,7 @@ /* Function Prototypes */ -void func_802A4A0C(Vtx*, struct UnkStruct_800DC5EC*, s32, s32, f32*); +void render_skybox(Vtx*, struct UnkStruct_800DC5EC*, s32, s32, f32*); void func_802A3730(struct UnkStruct_800DC5EC*); void func_802A38AC(void);