From 4b8996049508e69b9ea61c675a6ff3d91f630b59 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Thu, 15 May 2025 22:44:04 -0300 Subject: [PATCH 01/85] initial work --- src/math_util_2.c | 3 + src/math_util_2.h | 2 + src/port/Engine.h | 1 + src/port/interpolation/FrameInterpolation.cpp | 634 ++++++++++++++++++ src/port/interpolation/FrameInterpolation.h | 64 ++ 5 files changed, 704 insertions(+) create mode 100644 src/port/interpolation/FrameInterpolation.cpp create mode 100644 src/port/interpolation/FrameInterpolation.h diff --git a/src/math_util_2.c b/src/math_util_2.c index 444f3e4c6..067b34b21 100644 --- a/src/math_util_2.c +++ b/src/math_util_2.c @@ -18,6 +18,9 @@ #pragma intrinsic(sqrtf) +Mat4 sInterpolationMatrixStack[0x1000]; +Mat4* gInterpolationMatrix = &sInterpolationMatrixStack[0]; + UNUSED void operator_or(s32* arg0, s32 arg1) { *arg0 = (s32) (*arg0 | arg1); } diff --git a/src/math_util_2.h b/src/math_util_2.h index 75ad8e247..c616a1440 100644 --- a/src/math_util_2.h +++ b/src/math_util_2.h @@ -5,6 +5,8 @@ #include #include "camera.h" +extern Mat4* gInterpolationMatrix; + /* Function Prototypes */ // Unused functions diff --git a/src/port/Engine.h b/src/port/Engine.h index bd6cf1ce0..cd10ae431 100644 --- a/src/port/Engine.h +++ b/src/port/Engine.h @@ -59,6 +59,7 @@ class GameEngine { static void EndAudioFrame(); static void AudioExit(); + static uint32_t GetInterpolationFPS(); void StartFrame() const; static void RunCommands(Gfx* Commands); void ProcessFrame(void (*run_one_game_iter)()) const; diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp new file mode 100644 index 000000000..dcc49a025 --- /dev/null +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -0,0 +1,634 @@ +#include + +#include +#include +#include +#include +#include "port/Engine.h" + +#include "FrameInterpolation.h" + +/* +Frame interpolation. + +The idea of this code is to interpolate all matrices. + +The code contains two approaches. The first is to interpolate +all inputs in transformations, such as angles, scale and distances, +and then perform the same transformations with the interpolated values. +After evaluation for some reason some animations such rolling look strange. + +The second approach is to simply interpolate the final matrices. This will +more or less simply interpolate the world coordinates for movements. +This will however make rotations ~180 degrees get the "paper effect". +The mitigation is to identify this case for actors and interpolate the +matrix but in model coordinates instead, by "removing" the rotation- +translation before interpolating, create a rotation matrix with the +interpolated angle which is then applied to the matrix. + +Currently the code contains both methods but only the second one is currently +used. + +Both approaches build a tree of instructions, containing matrices +at leaves. Every node is built from OPEN_DISPS/CLOSE_DISPS and manually +inserted FrameInterpolation_OpenChild/FrameInterpolation_Close child calls. +These nodes contain information that should suffice to identify the matrix, +so we can find it in an adjacent frame. + +We can interpolate an arbitrary amount of frames between two original frames, +given a specific interpolation factor (0=old frame, 0.5=average of frames, +1.0=new frame). +*/ + +static bool invert_matrix(const float m[16], float invOut[16]); + +using namespace std; + +namespace { + +enum class Op { + Marker, + OpenChild, + CloseChild, + + MatrixPush, + MatrixPop, + MatrixPut, + MatrixMult, + MatrixTranslate, + MatrixScale, + MatrixRotate1Coord, + MatrixMultVec3fNoTranslate, + MatrixMultVec3f, + MatrixMtxFToMtx, + MatrixToMtx, + MatrixRotateAxis, + SkinMatrixMtxFToMtx +}; + +typedef pair label; + +union Data { + Data() { + } + + struct { + Mat4** matrix; + } matrix_ptr; + + struct { + const char* file; + int line; + } marker; + + struct { + Mat4* matrix; + MtxF mf; + u8 mode; + } matrix_mult; + + struct { + Mat4* matrix; + f32 x, y, z; + u8 mode; + } matrix_translate, matrix_scale; + + struct { + Mat4* matrix; + u32 coord; + f32 value; + u8 mode; + } matrix_rotate_1_coord; + + struct { + Mat4* matrix; + Vec3f src; + Vec3f dest; + } matrix_vec_translate; + + struct { + Mat4* matrix; + Vec3f src; + Vec3f dest; + } matrix_vec_no_translate; + + struct { + Mat4* matrix; + Vec3f translation; + Vec3s rotation; + } matrix_translate_rotate_zyx; + + struct { + Mat4* matrix; + f32 translateX, translateY, translateZ; + Vec3s rot; + // MtxF mtx; + bool has_mtx; + } matrix_set_translate_rotate_yxz; + + struct { + MtxF src; + Mtx* dest; + } matrix_mtxf_to_mtx; + + struct { + Mtx* dest; + MtxF src; + bool has_adjusted; + } matrix_to_mtx; + + struct { + MtxF mf; + } matrix_replace_rotation; + + struct { + f32 angle; + Vec3f axis; + u8 mode; + } matrix_rotate_axis; + + struct { + label key; + size_t idx; + } open_child; +}; + +struct Path { + map> children; + map> ops; + vector> items; +}; + +struct Recording { + Path root_path; +}; + +bool is_recording; +vector current_path; +uint32_t camera_epoch; +uint32_t previous_camera_epoch; +Recording current_recording; +Recording previous_recording; + +bool next_is_actor_pos_rot_matrix; +bool has_inv_actor_mtx; +MtxF inv_actor_mtx; +size_t inv_actor_mtx_path_index; + +Data& append(Op op) { + auto& m = current_path.back()->ops[op]; + current_path.back()->items.emplace_back(op, m.size()); + return m.emplace_back(); +} + +MtxF* Matrix_GetCurrent(){ + return (MtxF*) gInterpolationMatrix; +} + +struct InterpolateCtx { + float step; + float w; + unordered_map mtx_replacements; + MtxF tmp_mtxf, tmp_mtxf2; + Vec3f tmp_vec3f, tmp_vec3f2; + Vec3s tmp_vec3s; + MtxF actor_mtx; + + MtxF* new_replacement(Mtx* addr) { + return &mtx_replacements[addr]; + } + + void interpolate_mtxf(MtxF* res, MtxF* o, MtxF* n) { + for (size_t i = 0; i < 4; i++) { + for (size_t j = 0; j < 4; j++) { + res->mf[i][j] = w * o->mf[i][j] + step * n->mf[i][j]; + } + } + } + + float lerp(f32 o, f32 n) { + return w * o + step * n; + } + + void lerp_vec3f(Vec3f* res, Vec3f* o, Vec3f* n) { + *res[0] = lerp(*o[0], *n[0]); + *res[1] = lerp(*o[1], *n[1]); + *res[2] = lerp(*o[2], *n[2]); + } + + float interpolate_angle(f32 o, f32 n) { + if (o == n) + return n; + o = fmodf(o, 2 * M_PI); + if (o < 0.0f) { + o += 2 * M_PI; + } + n = fmodf(n, 2 * M_PI); + if (n < 0.0f) { + n += 2 * M_PI; + } + if (fabsf(o - n) > M_PI) { + if (o < n) { + o += 2 * M_PI; + } else { + n += 2 * M_PI; + } + } + if (fabsf(o - n) > M_PI / 2) { + // return n; + } + return lerp(o, n); + } + + s16 interpolate_angle(s16 os, s16 ns) { + if (os == ns) + return ns; + int o = (u16)os; + int n = (u16)ns; + u16 res; + int diff = o - n; + if (-0x8000 <= diff && diff <= 0x8000) { + if (diff < -0x4000 || diff > 0x4000) { + return ns; + } + res = (u16)(w * o + step * n); + } else { + if (o < n) { + o += 0x10000; + } else { + n += 0x10000; + } + diff = o - n; + if (diff < -0x4000 || diff > 0x4000) { + return ns; + } + res = (u16)(w * o + step * n); + } + if (os / 327 == ns / 327 && (s16)res / 327 != os / 327) { + int bp = 0; + } + return res; + } + + void interpolate_vecs(Vec3f* res, Vec3f* o, Vec3f* n) { + *res[0] = interpolate_angle(*o[0], *n[0]); + *res[1] = interpolate_angle(*o[1], *n[1]); + *res[2] = interpolate_angle(*o[2], *n[2]); + } + + void interpolate_angles(Vec3s* res, Vec3s* o, Vec3s* n) { + *res[0] = interpolate_angle(*o[0], *n[0]); + *res[1] = interpolate_angle(*o[1], *n[1]); + *res[2] = interpolate_angle(*o[2], *n[2]); + } + + void interpolate_branch(Path* old_path, Path* new_path) { + for (auto& item : new_path->items) { + Data& new_op = new_path->ops[item.first][item.second]; + + if (item.first == Op::OpenChild) { + if (auto it = old_path->children.find(new_op.open_child.key); + it != old_path->children.end() && new_op.open_child.idx < it->second.size()) { + interpolate_branch(&it->second[new_op.open_child.idx], + &new_path->children.find(new_op.open_child.key)->second[new_op.open_child.idx]); + } else { + interpolate_branch(&new_path->children.find(new_op.open_child.key)->second[new_op.open_child.idx], + &new_path->children.find(new_op.open_child.key)->second[new_op.open_child.idx]); + } + continue; + } + + if (auto it = old_path->ops.find(item.first); it != old_path->ops.end()) { + if (item.second < it->second.size()) { + Data& old_op = it->second[item.second]; + switch (item.first) { + case Op::OpenChild: + case Op::CloseChild: + case Op::Marker: + break; + + case Op::MatrixPush: + // Matrix_Push(&gInterpolationMatrix); + break; + + case Op::MatrixPop: + // Matrix_Pop(&gInterpolationMatrix); + break; + + // Unused on SF64 + // case Op::MatrixPut: + // interpolate_mtxf(&tmp_mtxf, &old_op.matrix_put.src, &new_op.matrix_put.src); + // Matrix_Put(&tmp_mtxf); + // break; + + case Op::MatrixMult: + interpolate_mtxf(&tmp_mtxf, &old_op.matrix_mult.mf, &new_op.matrix_mult.mf); + // Matrix_Mult(gInterpolationMatrix, (Matrix*) &tmp_mtxf, new_op.matrix_mult.mode); + break; + + case Op::MatrixTranslate: + // Matrix_Translate(gInterpolationMatrix, lerp(old_op.matrix_translate.x, new_op.matrix_translate.x), + // lerp(old_op.matrix_translate.y, new_op.matrix_translate.y), + // lerp(old_op.matrix_translate.z, new_op.matrix_translate.z), + // new_op.matrix_translate.mode); + break; + + case Op::MatrixScale: + // Matrix_Scale(gInterpolationMatrix, lerp(old_op.matrix_scale.x, new_op.matrix_scale.x), + // lerp(old_op.matrix_scale.y, new_op.matrix_scale.y), + // lerp(old_op.matrix_scale.z, new_op.matrix_scale.z), new_op.matrix_scale.mode); + break; + + case Op::MatrixRotate1Coord: { + float v = interpolate_angle(old_op.matrix_rotate_1_coord.value, + new_op.matrix_rotate_1_coord.value); + u8 mode = new_op.matrix_rotate_1_coord.mode; + switch (new_op.matrix_rotate_1_coord.coord) { + case 0: + // Matrix_RotateX(gInterpolationMatrix, v, mode); + break; + + case 1: + // Matrix_RotateY(gInterpolationMatrix, v, mode); + break; + + case 2: + // Matrix_RotateZ(gInterpolationMatrix, v, mode); + break; + } + break; + } + case Op::MatrixMultVec3fNoTranslate: { + interpolate_vecs(&tmp_vec3f, &old_op.matrix_vec_no_translate.src, &new_op.matrix_vec_no_translate.src); + interpolate_vecs(&tmp_vec3f2, &old_op.matrix_vec_no_translate.dest, &new_op.matrix_vec_no_translate.dest); + // Matrix_MultVec3fNoTranslate(gInterpolationMatrix, &tmp_vec3f, &tmp_vec3f2); + break; + } + case Op::MatrixMultVec3f: { + interpolate_vecs(&tmp_vec3f, &old_op.matrix_vec_translate.src, &new_op.matrix_vec_translate.src); + interpolate_vecs(&tmp_vec3f2, &old_op.matrix_vec_translate.dest, &new_op.matrix_vec_translate.dest); + // Matrix_MultVec3f(gInterpolationMatrix, &tmp_vec3f, &tmp_vec3f2); + break; + } + + case Op::MatrixMtxFToMtx: + interpolate_mtxf(new_replacement(new_op.matrix_mtxf_to_mtx.dest), + &old_op.matrix_mtxf_to_mtx.src, &new_op.matrix_mtxf_to_mtx.src); + break; + + case Op::MatrixToMtx: { + //*new_replacement(new_op.matrix_to_mtx.dest) = *Matrix_GetCurrent(); + if (old_op.matrix_to_mtx.has_adjusted && new_op.matrix_to_mtx.has_adjusted) { + interpolate_mtxf(&tmp_mtxf, &old_op.matrix_to_mtx.src, &new_op.matrix_to_mtx.src); + // Matrix_MtxFMtxFMult(&actor_mtx, &tmp_mtxf, + // new_replacement(new_op.matrix_to_mtx.dest)); + } else { + interpolate_mtxf(new_replacement(new_op.matrix_to_mtx.dest), &old_op.matrix_to_mtx.src, + &new_op.matrix_to_mtx.src); + } + break; + } + + case Op::MatrixRotateAxis: { + lerp_vec3f(&tmp_vec3f, &old_op.matrix_rotate_axis.axis, &new_op.matrix_rotate_axis.axis); + auto tmp = interpolate_angle(old_op.matrix_rotate_axis.angle, new_op.matrix_rotate_axis.angle); + // Matrix_RotateAxis((Matrix*) &tmp_vec3f, tmp, 1.0f, 1.0f, 1.0f, new_op.matrix_rotate_axis.mode); + break; + } + } + } + } + } + } +}; + +} // anonymous namespace + +unordered_map FrameInterpolation_Interpolate(float step) { + InterpolateCtx ctx; + ctx.step = step; + ctx.w = 1.0f - step; + ctx.interpolate_branch(&previous_recording.root_path, ¤t_recording.root_path); + return ctx.mtx_replacements; +} + +bool camera_interpolation = true; + +void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate) { + // camera_interpolation = shouldInterpolate; + is_recording = shouldInterpolate; +} + +void FrameInterpolation_StartRecord(void) { + previous_recording = move(current_recording); + current_recording = {}; + current_path.clear(); + current_path.push_back(¤t_recording.root_path); + if (!camera_interpolation) { + // default to interpolating + camera_interpolation = true; + is_recording = false; + return; + } + if (GameEngine::GetInterpolationFPS() != 20) { + is_recording = true; + } +} + +void FrameInterpolation_StopRecord(void) { + previous_camera_epoch = camera_epoch; + is_recording = false; +} + +void FrameInterpolation_RecordOpenChild(const void* a, int b) { + if (!is_recording) + return; + label key = { a, b }; + auto& m = current_path.back()->children[key]; + append(Op::OpenChild).open_child = { key, m.size() }; + current_path.push_back(&m.emplace_back()); +} + +void FrameInterpolation_RecordCloseChild(void) { + if (!is_recording) + return; + // append(Op::CloseChild); + if (has_inv_actor_mtx && current_path.size() == inv_actor_mtx_path_index) { + has_inv_actor_mtx = false; + } + current_path.pop_back(); +} + +void FrameInterpolation_DontInterpolateCamera(void) { + camera_epoch = previous_camera_epoch + 1; +} + +int FrameInterpolation_GetCameraEpoch(void) { + return (int)camera_epoch; +} + +void FrameInterpolation_RecordActorPosRotMatrix(void) { + if (!is_recording) + return; + next_is_actor_pos_rot_matrix = true; +} + +void FrameInterpolation_RecordMatrixPush(Mat4** matrix) { + if (!is_recording) + return; + + append(Op::MatrixPush).matrix_ptr = { matrix }; +} + +void FrameInterpolation_RecordMarker(const char* file, int line) { + if (!is_recording) + return; + + // append(Op::Marker).marker = { file, line }; +} + +void FrameInterpolation_RecordMatrixPop(Mat4** matrix) { + if (!is_recording) + return; + append(Op::MatrixPop).matrix_ptr = { matrix }; +} + +void FrameInterpolation_RecordMatrixPut(MtxF* src) { + if (!is_recording) + return; +// append(Op::MatrixPut).matrix_put = { matrix, *src }; +} + +void FrameInterpolation_RecordMatrixMult(Mat4* matrix, MtxF* mf, u8 mode) { + if (!is_recording) + return; + append(Op::MatrixMult).matrix_mult = { matrix, *mf, mode }; +} + +void FrameInterpolation_RecordMatrixTranslate(Mat4* matrix, f32 x, f32 y, f32 z, u8 mode) { + if (!is_recording) + return; + append(Op::MatrixTranslate).matrix_translate = { matrix, x, y, z, mode }; +} + +void FrameInterpolation_RecordMatrixScale(Mat4* matrix, f32 x, f32 y, f32 z, u8 mode) { + if (!is_recording) + return; + append(Op::MatrixScale).matrix_scale = { matrix, x, y, z, mode }; +} + +void FrameInterpolation_RecordMatrixMultVec3fNoTranslate(Mat4* matrix, Vec3f src, Vec3f dest){ + if (!is_recording) + return; + // append(Op::MatrixMultVec3fNoTranslate).matrix_vec_no_translate = { matrix, src, dest }; +} + +void FrameInterpolation_RecordMatrixMultVec3f(Mat4* matrix, Vec3f src, Vec3f dest){ + if (!is_recording) + return; + // append(Op::MatrixMultVec3f).matrix_vec_translate = { matrix, src, dest }; +} + +void FrameInterpolation_RecordMatrixRotate1Coord(Mat4* matrix, u32 coord, f32 value, u8 mode) { + if (!is_recording) + return; + append(Op::MatrixRotate1Coord).matrix_rotate_1_coord = { matrix, coord, value, mode }; +} + +void FrameInterpolation_RecordMatrixMtxFToMtx(MtxF* src, Mtx* dest) { + if (!is_recording) + return; + append(Op::MatrixMtxFToMtx).matrix_mtxf_to_mtx = { *src, dest }; +} + +void FrameInterpolation_RecordMatrixToMtx(Mtx* dest, char* file, s32 line) { + if (!is_recording) + return; + auto& d = append(Op::MatrixToMtx).matrix_to_mtx = { dest }; + if (has_inv_actor_mtx) { + d.has_adjusted = true; + // Matrix_MtxFMtxFMult(&inv_actor_mtx, Matrix_GetCurrent(), &d.src); + } else { + d.src = *Matrix_GetCurrent(); + } +} + +void FrameInterpolation_RecordMatrixRotateAxis(f32 angle, Vec3f* axis, u8 mode) { + if (!is_recording) + return; + // append(Op::MatrixRotateAxis).matrix_rotate_axis = { angle, axis, mode }; +} + +void FrameInterpolation_RecordSkinMatrixMtxFToMtx(MtxF* src, Mtx* dest) { + if (!is_recording) + return; + FrameInterpolation_RecordMatrixMtxFToMtx(src, dest); +} + +// https://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix +static bool invert_matrix(const float m[16], float invOut[16]) { + float inv[16], det; + int i; + + inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] + m[9] * m[7] * m[14] + + m[13] * m[6] * m[11] - m[13] * m[7] * m[10]; + + inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] - m[8] * m[7] * m[14] - + m[12] * m[6] * m[11] + m[12] * m[7] * m[10]; + + inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] + m[8] * m[7] * m[13] + + m[12] * m[5] * m[11] - m[12] * m[7] * m[9]; + + inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] - m[8] * m[6] * m[13] - + m[12] * m[5] * m[10] + m[12] * m[6] * m[9]; + + inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] - m[9] * m[3] * m[14] - + m[13] * m[2] * m[11] + m[13] * m[3] * m[10]; + + inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] + m[8] * m[3] * m[14] + + m[12] * m[2] * m[11] - m[12] * m[3] * m[10]; + + inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] - m[8] * m[3] * m[13] - + m[12] * m[1] * m[11] + m[12] * m[3] * m[9]; + + inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] + m[8] * m[2] * m[13] + + m[12] * m[1] * m[10] - m[12] * m[2] * m[9]; + + inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] + m[5] * m[3] * m[14] + + m[13] * m[2] * m[7] - m[13] * m[3] * m[6]; + + inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] - m[4] * m[3] * m[14] - + m[12] * m[2] * m[7] + m[12] * m[3] * m[6]; + + inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] + m[4] * m[3] * m[13] + + m[12] * m[1] * m[7] - m[12] * m[3] * m[5]; + + inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] - m[4] * m[2] * m[13] - + m[12] * m[1] * m[6] + m[12] * m[2] * m[5]; + + inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] - m[5] * m[3] * m[10] - + m[9] * m[2] * m[7] + m[9] * m[3] * m[6]; + + inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] + m[4] * m[3] * m[10] + + m[8] * m[2] * m[7] - m[8] * m[3] * m[6]; + + inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] - m[4] * m[3] * m[9] - + m[8] * m[1] * m[7] + m[8] * m[3] * m[5]; + + inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] + m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - + m[8] * m[2] * m[5]; + + det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12]; + + if (det == 0) { + return false; + } + + det = 1.0 / det; + + for (i = 0; i < 16; i++) { + invOut[i] = inv[i] * det; + } + + return true; +} \ No newline at end of file diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h new file mode 100644 index 000000000..2c5ab1278 --- /dev/null +++ b/src/port/interpolation/FrameInterpolation.h @@ -0,0 +1,64 @@ +#pragma once + +// #include "sf64math.h" +#include +#include +#include + +#ifdef __cplusplus + +#include + +std::unordered_map FrameInterpolation_Interpolate(float step); + +extern "C" { + +#endif + +void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate); + +void FrameInterpolation_StartRecord(void); + +void FrameInterpolation_StopRecord(void); + +void FrameInterpolation_RecordMarker(const char* file, int line); + +void FrameInterpolation_RecordOpenChild(const void* a, int b); + +void FrameInterpolation_RecordCloseChild(void); + +void FrameInterpolation_DontInterpolateCamera(void); + +int FrameInterpolation_GetCameraEpoch(void); + +void FrameInterpolation_RecordActorPosRotMatrix(void); + +//void FrameInterpolation_RecordMatrixPush(Matrix** mtx); + +//void FrameInterpolation_RecordMatrixPop(Matrix** mtx); + +//void FrameInterpolation_RecordMatrixMult(Matrix* matrix, MtxF* mf, u8 mode); + +//void FrameInterpolation_RecordMatrixTranslate(Matrix* matrix, f32 x, f32 y, f32 z, u8 mode); + +//void FrameInterpolation_RecordMatrixScale(Matrix* matrix, f32 x, f32 y, f32 z, u8 mode); + +//void FrameInterpolation_RecordMatrixRotate1Coord(Matrix* matrix, u32 coord, f32 value, u8 mode); + +void FrameInterpolation_RecordMatrixMtxFToMtx(MtxF* src, Mtx* dest); + +void FrameInterpolation_RecordMatrixToMtx(Mtx* dest, char* file, s32 line); + +void FrameInterpolation_RecordMatrixReplaceRotation(MtxF* mf); + +//void FrameInterpolation_RecordMatrixRotateAxis(f32 angle, Vec3f* axis, u8 mode); + +void FrameInterpolation_RecordSkinMatrixMtxFToMtx(MtxF* src, Mtx* dest); + +//void FrameInterpolation_RecordMatrixMultVec3f(Matrix* matrix, Vec3f src, Vec3f dest); + +//void FrameInterpolation_RecordMatrixMultVec3fNoTranslate(Matrix* matrix, Vec3f src, Vec3f dest); + +#ifdef __cplusplus +} +#endif \ No newline at end of file From bb55545f20151a4b05a7243cd2d568822175995d Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Thu, 15 May 2025 23:30:52 -0300 Subject: [PATCH 02/85] more work --- src/port/Engine.cpp | 53 +++++++++++++++++++ src/port/Engine.h | 1 + src/port/interpolation/FrameInterpolation.cpp | 4 +- src/port/interpolation/FrameInterpolation.h | 2 + 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 788af51ab..669e24504 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -24,6 +24,7 @@ #include "window/gui/resource/FontFactory.h" #include "SpaghettiGui.h" +#include "port/interpolation/FrameInterpolation.h" #include #include //#include @@ -225,6 +226,28 @@ bool GameEngine::GenAssetFile() { return extractor->GenerateOTR(); } +uint32_t GameEngine::GetInterpolationFPS() { + if (CVarGetInteger("gMatchRefreshRate", 0)) { + return Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); + + } else if (CVarGetInteger("gVsyncEnabled", 1) || + !Ship::Context::GetInstance()->GetWindow()->CanDisableVerticalSync()) { + return std::min(Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(), + CVarGetInteger("gInterpolationFPS", 60)); + } + + return CVarGetInteger("gInterpolationFPS", 60); +} + +uint32_t GameEngine::GetInterpolationFrameCount() +{ + return ceil((float)GetInterpolationFPS() / (60.0f / 2 /*gVIsPerFrame*/)); +} + +extern "C" uint32_t GameEngine_GetInterpolationFrameCount() { + return GameEngine::GetInterpolationFrameCount(); +} + void GameEngine::ShowMessage(const char* title, const char* message, SDL_MessageBoxFlags type) { #if defined(__SWITCH__) SPDLOG_ERROR(message); @@ -321,6 +344,36 @@ void GameEngine::RunCommands(Gfx* Commands) { } void GameEngine::ProcessGfxCommands(Gfx* commands) { + std::vector> mtx_replacements; + int target_fps = GameEngine::Instance->GetInterpolationFPS(); + static int last_fps; + static int last_update_rate; + static int time; + int fps = target_fps; + int original_fps = 60 / 2 /*gVIsPerFrame*/; + + if (target_fps == 20 || original_fps > target_fps) { + fps = original_fps; + } + + if (last_fps != fps || last_update_rate != 2 /*gVIsPerFrame*/) { + time = 0; + } + + // time_base = fps * original_fps (one second) + int next_original_frame = fps; + + while (time + original_fps <= next_original_frame) { + time += original_fps; + if (time != next_original_frame) { + mtx_replacements.push_back(FrameInterpolation_Interpolate((float) time / next_original_frame)); + } else { + mtx_replacements.emplace_back(); + } + } + + time -= fps; + auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); if (wnd != nullptr) { wnd->SetTargetFps(CVarGetInteger("gInterpolationFPS", 30)); diff --git a/src/port/Engine.h b/src/port/Engine.h index cd10ae431..4a4b25439 100644 --- a/src/port/Engine.h +++ b/src/port/Engine.h @@ -60,6 +60,7 @@ class GameEngine { static void AudioExit(); static uint32_t GetInterpolationFPS(); + static uint32_t GetInterpolationFrameCount(); void StartFrame() const; static void RunCommands(Gfx* Commands); void ProcessFrame(void (*run_one_game_iter)()) const; diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index dcc49a025..386561be8 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -5,7 +5,7 @@ #include #include #include "port/Engine.h" - +#include #include "FrameInterpolation.h" /* @@ -181,6 +181,8 @@ Data& append(Op op) { return m.emplace_back(); } +extern "C" {extern Mat4* gInterpolationMatrix;} + MtxF* Matrix_GetCurrent(){ return (MtxF*) gInterpolationMatrix; } diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 2c5ab1278..77d08b9c0 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -15,6 +15,8 @@ extern "C" { #endif + + void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate); void FrameInterpolation_StartRecord(void); From eaeff4e0e083e8974d0279cab52dd8d09a70f558 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Fri, 16 May 2025 00:24:15 -0300 Subject: [PATCH 03/85] progress --- src/port/Engine.cpp | 16 +++- src/port/Engine.h | 2 +- src/port/interpolation/FrameInterpolation.cpp | 78 ++++++++++++------- src/port/interpolation/FrameInterpolation.h | 2 +- src/port/ui/PortMenu.cpp | 30 +++---- src/racing/math_util.c | 1 + 6 files changed, 79 insertions(+), 50 deletions(-) diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 669e24504..debfad703 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -324,16 +324,24 @@ void GameEngine::StartFrame() const { // Instance->context->GetWindow()->MainLoop(run_one_game_iter); // } -void GameEngine::RunCommands(Gfx* Commands) { +void GameEngine::RunCommands(Gfx* Commands, const std::vector>& mtx_replacements) { auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); - if (nullptr == wnd) { + if (wnd == nullptr) { return; } + auto interpreter = wnd->GetInterpreterWeak().lock().get(); + + // Process window events for resize, mouse, keyboard events wnd->HandleEvents(); - wnd->DrawAndRunGraphicsCommands(Commands, {}); + interpreter->mInterpolationIndex = 0; + + for (const auto& m : mtx_replacements) { + wnd->DrawAndRunGraphicsCommands(Commands, m); + interpreter->mInterpolationIndex++; + } bool curAltAssets = CVarGetInteger("gEnhancements.Mods.AlternateAssets", 0); if (prevAltAssets != curAltAssets) { @@ -379,7 +387,7 @@ void GameEngine::ProcessGfxCommands(Gfx* commands) { wnd->SetTargetFps(CVarGetInteger("gInterpolationFPS", 30)); wnd->SetMaximumFrameLatency(1); } - RunCommands(commands); + RunCommands(commands, mtx_replacements); } // Audio diff --git a/src/port/Engine.h b/src/port/Engine.h index 4a4b25439..569009b00 100644 --- a/src/port/Engine.h +++ b/src/port/Engine.h @@ -62,7 +62,7 @@ class GameEngine { static uint32_t GetInterpolationFPS(); static uint32_t GetInterpolationFrameCount(); void StartFrame() const; - static void RunCommands(Gfx* Commands); + static void RunCommands(Gfx* Commands, const std::vector>& mtx_replacements); void ProcessFrame(void (*run_one_game_iter)()) const; static void Destroy(); static void ProcessGfxCommands(Gfx* commands); diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index 386561be8..12b57f4a9 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -5,6 +5,7 @@ #include #include #include "port/Engine.h" +#include #include #include "FrameInterpolation.h" @@ -89,8 +90,7 @@ union Data { struct { Mat4* matrix; - f32 x, y, z; - u8 mode; + Vec3f b; } matrix_translate, matrix_scale; struct { @@ -181,9 +181,12 @@ Data& append(Op op) { return m.emplace_back(); } -extern "C" {extern Mat4* gInterpolationMatrix;} +extern "C" { +extern Mat4* gInterpolationMatrix; +void mtxf_translate(Mat4, Vec3f); +} -MtxF* Matrix_GetCurrent(){ +MtxF* Matrix_GetCurrent() { return (MtxF*) gInterpolationMatrix; } @@ -245,15 +248,15 @@ struct InterpolateCtx { s16 interpolate_angle(s16 os, s16 ns) { if (os == ns) return ns; - int o = (u16)os; - int n = (u16)ns; + int o = (u16) os; + int n = (u16) ns; u16 res; int diff = o - n; if (-0x8000 <= diff && diff <= 0x8000) { if (diff < -0x4000 || diff > 0x4000) { return ns; } - res = (u16)(w * o + step * n); + res = (u16) (w * o + step * n); } else { if (o < n) { o += 0x10000; @@ -264,9 +267,9 @@ struct InterpolateCtx { if (diff < -0x4000 || diff > 0x4000) { return ns; } - res = (u16)(w * o + step * n); + res = (u16) (w * o + step * n); } - if (os / 327 == ns / 327 && (s16)res / 327 != os / 327) { + if (os / 327 == ns / 327 && (s16) res / 327 != os / 327) { int bp = 0; } return res; @@ -317,11 +320,11 @@ struct InterpolateCtx { // Matrix_Pop(&gInterpolationMatrix); break; - // Unused on SF64 - // case Op::MatrixPut: - // interpolate_mtxf(&tmp_mtxf, &old_op.matrix_put.src, &new_op.matrix_put.src); - // Matrix_Put(&tmp_mtxf); - // break; + // Unused on SF64 + // case Op::MatrixPut: + // interpolate_mtxf(&tmp_mtxf, &old_op.matrix_put.src, &new_op.matrix_put.src); + // Matrix_Put(&tmp_mtxf); + // break; case Op::MatrixMult: interpolate_mtxf(&tmp_mtxf, &old_op.matrix_mult.mf, &new_op.matrix_mult.mf); @@ -329,16 +332,26 @@ struct InterpolateCtx { break; case Op::MatrixTranslate: - // Matrix_Translate(gInterpolationMatrix, lerp(old_op.matrix_translate.x, new_op.matrix_translate.x), + // Matrix_Translate(gInterpolationMatrix, lerp(old_op.matrix_translate.x, + // new_op.matrix_translate.x), // lerp(old_op.matrix_translate.y, new_op.matrix_translate.y), // lerp(old_op.matrix_translate.z, new_op.matrix_translate.z), // new_op.matrix_translate.mode); + + Vec3f temp; + + temp[0] = lerp(old_op.matrix_translate.b[0], new_op.matrix_translate.b[0]); + temp[1] = lerp(old_op.matrix_translate.b[1], new_op.matrix_translate.b[1]); + temp[2] = lerp(old_op.matrix_translate.b[2], new_op.matrix_translate.b[2]); + + mtxf_translate(*gInterpolationMatrix, temp); break; case Op::MatrixScale: // Matrix_Scale(gInterpolationMatrix, lerp(old_op.matrix_scale.x, new_op.matrix_scale.x), // lerp(old_op.matrix_scale.y, new_op.matrix_scale.y), - // lerp(old_op.matrix_scale.z, new_op.matrix_scale.z), new_op.matrix_scale.mode); + // lerp(old_op.matrix_scale.z, new_op.matrix_scale.z), + // new_op.matrix_scale.mode); break; case Op::MatrixRotate1Coord: { @@ -361,14 +374,18 @@ struct InterpolateCtx { break; } case Op::MatrixMultVec3fNoTranslate: { - interpolate_vecs(&tmp_vec3f, &old_op.matrix_vec_no_translate.src, &new_op.matrix_vec_no_translate.src); - interpolate_vecs(&tmp_vec3f2, &old_op.matrix_vec_no_translate.dest, &new_op.matrix_vec_no_translate.dest); + interpolate_vecs(&tmp_vec3f, &old_op.matrix_vec_no_translate.src, + &new_op.matrix_vec_no_translate.src); + interpolate_vecs(&tmp_vec3f2, &old_op.matrix_vec_no_translate.dest, + &new_op.matrix_vec_no_translate.dest); // Matrix_MultVec3fNoTranslate(gInterpolationMatrix, &tmp_vec3f, &tmp_vec3f2); break; } case Op::MatrixMultVec3f: { - interpolate_vecs(&tmp_vec3f, &old_op.matrix_vec_translate.src, &new_op.matrix_vec_translate.src); - interpolate_vecs(&tmp_vec3f2, &old_op.matrix_vec_translate.dest, &new_op.matrix_vec_translate.dest); + interpolate_vecs(&tmp_vec3f, &old_op.matrix_vec_translate.src, + &new_op.matrix_vec_translate.src); + interpolate_vecs(&tmp_vec3f2, &old_op.matrix_vec_translate.dest, + &new_op.matrix_vec_translate.dest); // Matrix_MultVec3f(gInterpolationMatrix, &tmp_vec3f, &tmp_vec3f2); break; } @@ -393,8 +410,10 @@ struct InterpolateCtx { case Op::MatrixRotateAxis: { lerp_vec3f(&tmp_vec3f, &old_op.matrix_rotate_axis.axis, &new_op.matrix_rotate_axis.axis); - auto tmp = interpolate_angle(old_op.matrix_rotate_axis.angle, new_op.matrix_rotate_axis.angle); - // Matrix_RotateAxis((Matrix*) &tmp_vec3f, tmp, 1.0f, 1.0f, 1.0f, new_op.matrix_rotate_axis.mode); + auto tmp = + interpolate_angle(old_op.matrix_rotate_axis.angle, new_op.matrix_rotate_axis.angle); + // Matrix_RotateAxis((Matrix*) &tmp_vec3f, tmp, 1.0f, 1.0f, 1.0f, + // new_op.matrix_rotate_axis.mode); break; } } @@ -466,7 +485,7 @@ void FrameInterpolation_DontInterpolateCamera(void) { } int FrameInterpolation_GetCameraEpoch(void) { - return (int)camera_epoch; + return (int) camera_epoch; } void FrameInterpolation_RecordActorPosRotMatrix(void) { @@ -498,7 +517,7 @@ void FrameInterpolation_RecordMatrixPop(Mat4** matrix) { void FrameInterpolation_RecordMatrixPut(MtxF* src) { if (!is_recording) return; -// append(Op::MatrixPut).matrix_put = { matrix, *src }; + // append(Op::MatrixPut).matrix_put = { matrix, *src }; } void FrameInterpolation_RecordMatrixMult(Mat4* matrix, MtxF* mf, u8 mode) { @@ -507,25 +526,26 @@ void FrameInterpolation_RecordMatrixMult(Mat4* matrix, MtxF* mf, u8 mode) { append(Op::MatrixMult).matrix_mult = { matrix, *mf, mode }; } -void FrameInterpolation_RecordMatrixTranslate(Mat4* matrix, f32 x, f32 y, f32 z, u8 mode) { +void FrameInterpolation_RecordMatrixTranslate(Mat4* matrix, Vec3f b) { if (!is_recording) return; - append(Op::MatrixTranslate).matrix_translate = { matrix, x, y, z, mode }; + + append(Op::MatrixTranslate).matrix_translate = { matrix, b[0] }; } void FrameInterpolation_RecordMatrixScale(Mat4* matrix, f32 x, f32 y, f32 z, u8 mode) { if (!is_recording) return; - append(Op::MatrixScale).matrix_scale = { matrix, x, y, z, mode }; + // append(Op::MatrixScale).matrix_scale = { matrix, x, y, z, mode }; } -void FrameInterpolation_RecordMatrixMultVec3fNoTranslate(Mat4* matrix, Vec3f src, Vec3f dest){ +void FrameInterpolation_RecordMatrixMultVec3fNoTranslate(Mat4* matrix, Vec3f src, Vec3f dest) { if (!is_recording) return; // append(Op::MatrixMultVec3fNoTranslate).matrix_vec_no_translate = { matrix, src, dest }; } -void FrameInterpolation_RecordMatrixMultVec3f(Mat4* matrix, Vec3f src, Vec3f dest){ +void FrameInterpolation_RecordMatrixMultVec3f(Mat4* matrix, Vec3f src, Vec3f dest) { if (!is_recording) return; // append(Op::MatrixMultVec3f).matrix_vec_translate = { matrix, src, dest }; diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 77d08b9c0..72a1c9146 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -41,7 +41,7 @@ void FrameInterpolation_RecordActorPosRotMatrix(void); //void FrameInterpolation_RecordMatrixMult(Matrix* matrix, MtxF* mf, u8 mode); -//void FrameInterpolation_RecordMatrixTranslate(Matrix* matrix, f32 x, f32 y, f32 z, u8 mode); +void FrameInterpolation_RecordMatrixTranslate(Mat4* matrix, Vec3f b); //void FrameInterpolation_RecordMatrixScale(Matrix* matrix, f32 x, f32 y, f32 z, u8 mode); diff --git a/src/port/ui/PortMenu.cpp b/src/port/ui/PortMenu.cpp index b21ddc1fa..286d02aab 100644 --- a/src/port/ui/PortMenu.cpp +++ b/src/port/ui/PortMenu.cpp @@ -244,21 +244,21 @@ void PortMenu::AddSettings() { .DefaultValue(1)); #endif - // AddWidget(path, "Current FPS: %d", WIDGET_CVAR_SLIDER_INT) - // .CVar("gInterpolationFPS") - // .Callback([](WidgetInfo& info) { - // int32_t defaultValue = std::static_pointer_cast(info.options)->defaultValue; - // if (CVarGetInteger(info.cVar, defaultValue) == defaultValue) { - // info.name = "Current FPS: Original (%d)"; - // } else { - // info.name = "Current FPS: %d"; - // } - // }) - // .PreFunc([](WidgetInfo& info) { - // if (mPortMenu->disabledMap.at(DISABLE_FOR_MATCH_REFRESH_RATE_ON).active) - // info.activeDisables.push_back(DISABLE_FOR_MATCH_REFRESH_RATE_ON); - // }) - // .Options(IntSliderOptions().Tooltip(tooltip).Min(20).Max(maxFps).DefaultValue(20)); + AddWidget(path, "Current FPS: %d", WIDGET_CVAR_SLIDER_INT) + .CVar("gInterpolationFPS") + .Callback([](WidgetInfo& info) { + int32_t defaultValue = std::static_pointer_cast(info.options)->defaultValue; + if (CVarGetInteger(info.cVar, defaultValue) == defaultValue) { + info.name = "Current FPS: Original (%d)"; + } else { + info.name = "Current FPS: %d"; + } + }) + .PreFunc([](WidgetInfo& info) { + if (mPortMenu->disabledMap.at(DISABLE_FOR_MATCH_REFRESH_RATE_ON).active) + info.activeDisables.push_back(DISABLE_FOR_MATCH_REFRESH_RATE_ON); + }) + .Options(IntSliderOptions().Tooltip(tooltip).Min(20).Max(maxFps).DefaultValue(20)); AddWidget(path, "Match Refresh Rate", WIDGET_BUTTON) .Callback([](WidgetInfo& info) { int hz = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); diff --git a/src/racing/math_util.c b/src/racing/math_util.c index ac34ceda7..934865b08 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -222,6 +222,7 @@ UNUSED void add_translate_mat4_vec3f_lite(Mat4 mat, Mat4 dest, Vec3f pos) { // create a translation matrix void mtxf_translate(Mat4 dest, Vec3f b) { + FrameInterpolation_RecordMatrixTranslate(dest, b); mtxf_identity(dest); dest[3][0] = b[0]; dest[3][1] = b[1]; From d155bacadb38b1ed96065da2ad7de4f65f687e96 Mon Sep 17 00:00:00 2001 From: KiritoDv Date: Thu, 15 May 2025 22:43:52 -0600 Subject: [PATCH 04/85] Fixed slow fps --- src/main.c | 2 +- src/port/Engine.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 7b7e05cda..39eb51d84 100644 --- a/src/main.c +++ b/src/main.c @@ -647,7 +647,7 @@ void calculate_updaterate(void) { s32 total; // Get target FPS from configuration variable - s32 targetFPS = CVarGetInteger("gInterpolationFPS", 30); + s32 targetFPS = 30; if (targetFPS < 60) { targetFPS = 30; diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index debfad703..58e3920ea 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -388,6 +388,9 @@ void GameEngine::ProcessGfxCommands(Gfx* commands) { wnd->SetMaximumFrameLatency(1); } RunCommands(commands, mtx_replacements); + + last_fps = fps; + last_update_rate = 2; } // Audio From 09fb8d84210e82030da89cd9a5793fb6402a971f Mon Sep 17 00:00:00 2001 From: MegaMech Date: Fri, 16 May 2025 17:12:28 -0600 Subject: [PATCH 05/85] Add Lywx changes --- src/actors/mario_sign/render.inc.c | 5 +- src/actors/mario_sign/update.inc.c | 4 +- src/engine/Matrix.cpp | 2 + src/enhancements/collision_viewer.c | 2 + src/gbiMacro.c | 2 +- src/port/interpolation/FrameInterpolation.cpp | 86 +++- src/port/interpolation/FrameInterpolation.h | 14 +- src/port/interpolation/matrix.c | 450 ++++++++++++++++++ src/port/interpolation/matrix.h | 94 ++++ src/racing/framebuffer_effects.c | 4 +- src/racing/math_util.c | 11 +- src/racing/math_util.h | 10 +- src/racing/skybox_and_splitscreen.c | 12 +- 13 files changed, 652 insertions(+), 44 deletions(-) create mode 100644 src/port/interpolation/matrix.c create mode 100644 src/port/interpolation/matrix.h diff --git a/src/actors/mario_sign/render.inc.c b/src/actors/mario_sign/render.inc.c index 1c72c8394..7914a283f 100644 --- a/src/actors/mario_sign/render.inc.c +++ b/src/actors/mario_sign/render.inc.c @@ -14,7 +14,7 @@ void render_actor_mario_sign(Camera* arg0, UNUSED Mat4 arg1, struct Actor* arg2) Mat4 sp40; f32 unk; s16 temp = arg2->flags; - + FrameInterpolation_RecordOpenChild(arg2, 0); if (temp & 0x800) { return; } @@ -31,4 +31,7 @@ void render_actor_mario_sign(Camera* arg0, UNUSED Mat4 arg1, struct Actor* arg2) gSPDisplayList(gDisplayListHead++, d_course_mario_raceway_dl_sign); } } + + FrameInterpolation_RecordCloseChild(); + } diff --git a/src/actors/mario_sign/update.inc.c b/src/actors/mario_sign/update.inc.c index 6a061eddd..7a85e8ac5 100644 --- a/src/actors/mario_sign/update.inc.c +++ b/src/actors/mario_sign/update.inc.c @@ -11,10 +11,10 @@ void update_actor_mario_sign(struct Actor* arg0) { arg0->pos[1] += 4.0f; if (arg0->pos[1] > 800.0f) { arg0->flags |= 0x800; - arg0->rot[1] += 1820; + arg0->rot[1] += 4; } } else { - arg0->rot[1] += 182; + arg0->rot[1] += 4; } } } diff --git a/src/engine/Matrix.cpp b/src/engine/Matrix.cpp index 1f2301258..44e5f081d 100644 --- a/src/engine/Matrix.cpp +++ b/src/engine/Matrix.cpp @@ -1,6 +1,7 @@ #include #include #include "engine/World.h" +#include "src/port/interpolation/FrameInterpolation.h" extern "C" { #include "common_structs.h" @@ -16,6 +17,7 @@ void AddMatrix(std::vector& stack, Mat4 mtx, s32 flags) { stack.emplace_back(); // Convert to a fixed-point matrix + FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mtx, &stack.back()); guMtxF2L(mtx, &stack.back()); // Load the matrix diff --git a/src/enhancements/collision_viewer.c b/src/enhancements/collision_viewer.c index fd7c542e0..f45a9872f 100644 --- a/src/enhancements/collision_viewer.c +++ b/src/enhancements/collision_viewer.c @@ -4,6 +4,8 @@ #include "code_800029B0.h" #include "mk64.h" #include "main.h" +#include +#include #include "collision_viewer.h" #include "math_util.h" diff --git a/src/gbiMacro.c b/src/gbiMacro.c index 5fa0ab171..007d7d281 100644 --- a/src/gbiMacro.c +++ b/src/gbiMacro.c @@ -18,5 +18,5 @@ UNUSED void gfx_func_80040D00(void) { guOrtho(&gGfxPool->mtxScreen, 0.0f, SCREEN_WIDTH, 0.0f, SCREEN_HEIGHT, -1.0f, 1.0f, 1.0f); gSPPerspNormalize(gDisplayListHead++, 0xFFFF); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(gGfxPool), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gIdentityMatrix), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + //gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gIdentityMatrix), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); } diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index 12b57f4a9..9064cdb04 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -8,6 +8,7 @@ #include #include #include "FrameInterpolation.h" +#include "matrix.h" /* Frame interpolation. @@ -59,6 +60,8 @@ enum class Op { MatrixTranslate, MatrixScale, MatrixRotate1Coord, + MatrixMult4x4, + MatrixPosRotXYZ, MatrixMultVec3fNoTranslate, MatrixMultVec3f, MatrixMtxFToMtx, @@ -90,14 +93,13 @@ union Data { struct { Mat4* matrix; - Vec3f b; + Vec3fInterp b; } matrix_translate, matrix_scale; struct { Mat4* matrix; u32 coord; - f32 value; - u8 mode; + s16 value; } matrix_rotate_1_coord; struct { @@ -112,6 +114,17 @@ union Data { Vec3f dest; } matrix_vec_no_translate; + struct { + Mat4* dest; + Mat4 mtx1; + Mat4 mtx2; + } matrix_mult_4x4; + + struct { + Vec3fInterp pos; + Vec3sInterp orientation; + } matrix_pos_rot_xyz; + struct { Mat4* matrix; Vec3f translation; @@ -215,6 +228,10 @@ struct InterpolateCtx { return w * o + step * n; } + s16 lerp_s16(s16 o, s16 n) { + return w * o + step * n; + } + void lerp_vec3f(Vec3f* res, Vec3f* o, Vec3f* n) { *res[0] = lerp(*o[0], *n[0]); *res[1] = lerp(*o[1], *n[1]); @@ -332,20 +349,29 @@ struct InterpolateCtx { break; case Op::MatrixTranslate: - // Matrix_Translate(gInterpolationMatrix, lerp(old_op.matrix_translate.x, - // new_op.matrix_translate.x), - // lerp(old_op.matrix_translate.y, new_op.matrix_translate.y), - // lerp(old_op.matrix_translate.z, new_op.matrix_translate.z), - // new_op.matrix_translate.mode); Vec3f temp; - temp[0] = lerp(old_op.matrix_translate.b[0], new_op.matrix_translate.b[0]); - temp[1] = lerp(old_op.matrix_translate.b[1], new_op.matrix_translate.b[1]); - temp[2] = lerp(old_op.matrix_translate.b[2], new_op.matrix_translate.b[2]); + temp[0] = lerp(old_op.matrix_translate.b.x, new_op.matrix_translate.b.x); + temp[1] = lerp(old_op.matrix_translate.b.y, new_op.matrix_translate.b.y); + temp[2] = lerp(old_op.matrix_translate.b.z, new_op.matrix_translate.b.z); mtxf_translate(*gInterpolationMatrix, temp); break; + case Op::MatrixPosRotXYZ: + Vec3f tempF; + Vec3s tempS; + + tempF[0] = lerp(old_op.matrix_pos_rot_xyz.pos.x, new_op.matrix_pos_rot_xyz.pos.x); + tempF[1] = lerp(old_op.matrix_pos_rot_xyz.pos.y, new_op.matrix_pos_rot_xyz.pos.y); + tempF[2] = lerp(old_op.matrix_pos_rot_xyz.pos.z, new_op.matrix_pos_rot_xyz.pos.z); + + tempS[0] = lerp(old_op.matrix_pos_rot_xyz.orientation.x, new_op.matrix_pos_rot_xyz.orientation.x); + tempS[1] = lerp(old_op.matrix_pos_rot_xyz.orientation.y, new_op.matrix_pos_rot_xyz.orientation.y); + tempS[2] = lerp(old_op.matrix_pos_rot_xyz.orientation.z, new_op.matrix_pos_rot_xyz.orientation.z); + + mtxf_pos_rotation_xyz(*gInterpolationMatrix, tempF, tempS); + break; case Op::MatrixScale: // Matrix_Scale(gInterpolationMatrix, lerp(old_op.matrix_scale.x, new_op.matrix_scale.x), @@ -355,20 +381,19 @@ struct InterpolateCtx { break; case Op::MatrixRotate1Coord: { - float v = interpolate_angle(old_op.matrix_rotate_1_coord.value, + s16 v = interpolate_angle(old_op.matrix_rotate_1_coord.value, new_op.matrix_rotate_1_coord.value); - u8 mode = new_op.matrix_rotate_1_coord.mode; switch (new_op.matrix_rotate_1_coord.coord) { case 0: - // Matrix_RotateX(gInterpolationMatrix, v, mode); + mtxf_rotate_x(*gInterpolationMatrix, v); break; case 1: - // Matrix_RotateY(gInterpolationMatrix, v, mode); + mtxf_rotate_y(*gInterpolationMatrix, v); break; case 2: - // Matrix_RotateZ(gInterpolationMatrix, v, mode); + mtxf_s16_rotate_z(*gInterpolationMatrix, v); break; } break; @@ -445,12 +470,12 @@ void FrameInterpolation_StartRecord(void) { current_recording = {}; current_path.clear(); current_path.push_back(¤t_recording.root_path); - if (!camera_interpolation) { - // default to interpolating - camera_interpolation = true; - is_recording = false; - return; - } + // if (!camera_interpolation) { + // // default to interpolating + // camera_interpolation = true; + // is_recording = false; + // return; + // } if (GameEngine::GetInterpolationFPS() != 20) { is_recording = true; } @@ -530,7 +555,7 @@ void FrameInterpolation_RecordMatrixTranslate(Mat4* matrix, Vec3f b) { if (!is_recording) return; - append(Op::MatrixTranslate).matrix_translate = { matrix, b[0] }; + append(Op::MatrixTranslate).matrix_translate = { matrix, *((Vec3fInterp*) &b) }; } void FrameInterpolation_RecordMatrixScale(Mat4* matrix, f32 x, f32 y, f32 z, u8 mode) { @@ -542,7 +567,16 @@ void FrameInterpolation_RecordMatrixScale(Mat4* matrix, f32 x, f32 y, f32 z, u8 void FrameInterpolation_RecordMatrixMultVec3fNoTranslate(Mat4* matrix, Vec3f src, Vec3f dest) { if (!is_recording) return; - // append(Op::MatrixMultVec3fNoTranslate).matrix_vec_no_translate = { matrix, src, dest }; + //append(Op::MatrixMultVec3fNoTranslate).matrix_vec_no_translate = { matrix, src, dest }; +} + +// Make a template for deref + + +void FrameInterpolation_RecordMatrixPosRotXYZ(Mat4 out, Vec3f pos, Vec3s orientation) { + if (!is_recording) + return; + append(Op::MatrixPosRotXYZ).matrix_pos_rot_xyz = { *((Vec3fInterp*) &pos), *((Vec3sInterp*) &orientation) }; } void FrameInterpolation_RecordMatrixMultVec3f(Mat4* matrix, Vec3f src, Vec3f dest) { @@ -551,10 +585,10 @@ void FrameInterpolation_RecordMatrixMultVec3f(Mat4* matrix, Vec3f src, Vec3f des // append(Op::MatrixMultVec3f).matrix_vec_translate = { matrix, src, dest }; } -void FrameInterpolation_RecordMatrixRotate1Coord(Mat4* matrix, u32 coord, f32 value, u8 mode) { +void FrameInterpolation_RecordMatrixRotate1Coord(Mat4* matrix, u32 coord, s16 value) { if (!is_recording) return; - append(Op::MatrixRotate1Coord).matrix_rotate_1_coord = { matrix, coord, value, mode }; + append(Op::MatrixRotate1Coord).matrix_rotate_1_coord = { matrix, coord, value }; } void FrameInterpolation_RecordMatrixMtxFToMtx(MtxF* src, Mtx* dest) { diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 72a1c9146..7d2df76a8 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef __FRAME_INTERPOLATION_H +#define __FRAME_INTERPOLATION_H // #include "sf64math.h" #include @@ -12,11 +13,8 @@ std::unordered_map FrameInterpolation_Interpolate(float step); extern "C" { - #endif - - void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate); void FrameInterpolation_StartRecord(void); @@ -35,6 +33,8 @@ int FrameInterpolation_GetCameraEpoch(void); void FrameInterpolation_RecordActorPosRotMatrix(void); +void FrameInterpolation_RecordMatrixPosRotXYZ(Mat4 out, Vec3f pos, Vec3s orientation); + //void FrameInterpolation_RecordMatrixPush(Matrix** mtx); //void FrameInterpolation_RecordMatrixPop(Matrix** mtx); @@ -45,7 +45,7 @@ void FrameInterpolation_RecordMatrixTranslate(Mat4* matrix, Vec3f b); //void FrameInterpolation_RecordMatrixScale(Matrix* matrix, f32 x, f32 y, f32 z, u8 mode); -//void FrameInterpolation_RecordMatrixRotate1Coord(Matrix* matrix, u32 coord, f32 value, u8 mode); +void FrameInterpolation_RecordMatrixRotate1Coord(Mat4* matrix, u32 coord, s16 value); void FrameInterpolation_RecordMatrixMtxFToMtx(MtxF* src, Mtx* dest); @@ -63,4 +63,6 @@ void FrameInterpolation_RecordSkinMatrixMtxFToMtx(MtxF* src, Mtx* dest); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif + +#endif // __FRAME_INTERPOLATION_H \ No newline at end of file diff --git a/src/port/interpolation/matrix.c b/src/port/interpolation/matrix.c new file mode 100644 index 000000000..4f8a7839b --- /dev/null +++ b/src/port/interpolation/matrix.c @@ -0,0 +1,450 @@ +#include +#include +#include "matrix.h" +#include "common_structs.h" + +Mtx gIdentityMtx = gdSPDefMtx(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); +Matrix gIdentityMatrix = { { + { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f }, +} }; + +Matrix* gGfxMatrix; +Matrix sGfxMatrixStack[0x20]; +Matrix* gCalcMatrix; +Matrix sCalcMatrixStack[0x20]; + +Mtx gMainMatrixStack[0x480]; +Mtx* gGfxMtx; + +void Matrix_InitPerspective(Gfx** dList) { + u16 norm; + float near = 10.0f; + float far = 12800.0f; + float fov = 45.0f; + + guPerspective(gGfxMtx, &norm, fov, 320.0f / 240.0f, near, far, 1.0f); + gSPPerspNormalize((*dList)++, norm); + gSPMatrix((*dList)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + guLookAt(gGfxMtx, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -12800.0f, 0.0f, 1.0f, 0.0f); + gSPMatrix((*dList)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); + Matrix_Copy(gGfxMatrix, &gIdentityMatrix); +} + +void Matrix_InitOrtho(Gfx** dList) { + FrameInterpolation_RecordOpenChild("ortho", 0); + FrameInterpolation_RecordMarker(__FILE__, __LINE__); + guOrtho(gGfxMtx, -320.0f / 2, 320.0f / 2, -240.0f / 2, 240.0f / 2, 0.0f, 5.0f, 1.0f); + gSPMatrix((*dList)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + guLookAt(gGfxMtx, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -12800.0f, 0.0f, 1.0f, 0.0f); + gSPMatrix((*dList)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); + Matrix_Copy(gGfxMatrix, &gIdentityMatrix); + FrameInterpolation_RecordCloseChild(); +} + + +// Copies src Matrix into dst +void Matrix_Copy(Matrix* dst, Matrix* src) { + int32_t i; + + for (i = 0; i < 4; i++) { + dst->mf[i][0] = src->mf[i][0]; + dst->mf[i][1] = src->mf[i][1]; + dst->mf[i][2] = src->mf[i][2]; + dst->mf[i][3] = src->mf[i][3]; + } +} + +// Makes a copy of the stack's current matrix and puts it on the top of the stack +void Matrix_Push(Matrix** mtxStack) { + Matrix_Copy(*mtxStack + 1, *mtxStack); + (*mtxStack)++; +} + +// Removes the top matrix of the stack +void Matrix_Pop(Matrix** mtxStack) { + (*mtxStack)--; +} + +// Copies tf into mtx (MTXF_NEW) or applies it to mtx (MTXF_APPLY) +void Matrix_Mult(Matrix* mtx, Matrix* tf, u8 mode) { + f32 rx; + f32 ry; + f32 rz; + f32 rw; + s32 i0; + s32 i1; + s32 i2; + s32 i3; + + if (mode == 1) { + rx = mtx->mf[0][0]; + ry = mtx->mf[1][0]; + rz = mtx->mf[2][0]; + rw = mtx->mf[3][0]; + + for (i0 = 0; i0 < 4; i0++) { + mtx->mf[i0][0] = (rx * tf->mf[i0][0]) + (ry * tf->mf[i0][1]) + (rz * tf->mf[i0][2]) + (rw * tf->mf[i0][3]); + } + + rx = mtx->mf[0][1]; + ry = mtx->mf[1][1]; + rz = mtx->mf[2][1]; + rw = mtx->mf[3][1]; + + for (i1 = 0; i1 < 4; i1++) { + mtx->mf[i1][1] = (rx * tf->mf[i1][0]) + (ry * tf->mf[i1][1]) + (rz * tf->mf[i1][2]) + (rw * tf->mf[i1][3]); + } + + rx = mtx->mf[0][2]; + ry = mtx->mf[1][2]; + rz = mtx->mf[2][2]; + rw = mtx->mf[3][2]; + + for (i2 = 0; i2 < 4; i2++) { + mtx->mf[i2][2] = (rx * tf->mf[i2][0]) + (ry * tf->mf[i2][1]) + (rz * tf->mf[i2][2]) + (rw * tf->mf[i2][3]); + } + + rx = mtx->mf[0][3]; + ry = mtx->mf[1][3]; + rz = mtx->mf[2][3]; + rw = mtx->mf[3][3]; + + for (i3 = 0; i3 < 4; i3++) { + mtx->mf[i3][3] = (rx * tf->mf[i3][0]) + (ry * tf->mf[i3][1]) + (rz * tf->mf[i3][2]) + (rw * tf->mf[i3][3]); + } + } else { + Matrix_Copy(mtx, tf); + } +} + +// Creates a translation matrix in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY) +void Matrix_Translate(Matrix* mtx, f32 x, f32 y, f32 z, u8 mode) { + f32 rx; + f32 ry; + s32 i; + + if (mode == 1) { + for (i = 0; i < 4; i++) { + rx = mtx->mf[0][i]; + ry = mtx->mf[1][i]; + + mtx->mf[3][i] += (rx * x) + (ry * y) + (mtx->mf[2][i] * z); + } + } else { + mtx->mf[3][0] = x; + mtx->mf[3][1] = y; + mtx->mf[3][2] = z; + mtx->mf[0][1] = mtx->mf[0][2] = mtx->mf[0][3] = mtx->mf[1][0] = mtx->mf[1][2] = mtx->mf[1][3] = mtx->mf[2][0] = + mtx->mf[2][1] = mtx->mf[2][3] = 0.0f; + mtx->mf[0][0] = mtx->mf[1][1] = mtx->mf[2][2] = mtx->mf[3][3] = 1.0f; + } +} + +// Creates a scale matrix in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY) +void Matrix_Scale(Matrix* mtx, f32 xScale, f32 yScale, f32 zScale, u8 mode) { + f32 rx; + f32 ry; + s32 i; + + if (mode == 1) { + for (i = 0; i < 4; i++) { + rx = mtx->mf[0][i]; + ry = mtx->mf[1][i]; + + mtx->mf[0][i] = rx * xScale; + mtx->mf[1][i] = ry * yScale; + mtx->mf[2][i] *= zScale; + } + } else { + mtx->mf[0][0] = xScale; + mtx->mf[1][1] = yScale; + mtx->mf[2][2] = zScale; + mtx->mf[0][1] = mtx->mf[0][2] = mtx->mf[0][3] = mtx->mf[1][0] = mtx->mf[1][2] = mtx->mf[1][3] = mtx->mf[2][0] = + mtx->mf[2][1] = mtx->mf[2][3] = mtx->mf[3][0] = mtx->mf[3][1] = mtx->mf[3][2] = 0.0f; + mtx->mf[3][3] = 1.0f; + } +} + +// Creates rotation matrix about the X axis in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY) +void Matrix_RotateX(Matrix* mtx, f32 angle, u8 mode) { + f32 cs; + f32 sn; + f32 ry; + f32 rz; + s32 i; + + sn = sinf(angle); + cs = cosf(angle); + if (mode == 1) { + for (i = 0; i < 4; i++) { + ry = mtx->mf[1][i]; + rz = mtx->mf[2][i]; + + mtx->mf[1][i] = (ry * cs) + (rz * sn); + mtx->mf[2][i] = (rz * cs) - (ry * sn); + } + } else { + mtx->mf[1][1] = mtx->mf[2][2] = cs; + mtx->mf[1][2] = sn; + mtx->mf[2][1] = -sn; + mtx->mf[0][0] = mtx->mf[3][3] = 1.0f; + mtx->mf[0][1] = mtx->mf[0][2] = mtx->mf[0][3] = mtx->mf[1][0] = mtx->mf[1][3] = mtx->mf[2][0] = mtx->mf[2][3] = + mtx->mf[3][0] = mtx->mf[3][1] = mtx->mf[3][2] = 0.0f; + } +} + +// Creates rotation matrix about the Y axis in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY) +void Matrix_RotateY(Matrix* mtx, f32 angle, u8 mode) { + f32 cs; + f32 sn; + f32 rx; + f32 rz; + s32 i; + + sn = sinf(angle); + cs = cosf(angle); + if (mode == 1) { + for (i = 0; i < 4; i++) { + rx = mtx->mf[0][i]; + rz = mtx->mf[2][i]; + + mtx->mf[0][i] = (rx * cs) - (rz * sn); + mtx->mf[2][i] = (rx * sn) + (rz * cs); + } + } else { + mtx->mf[0][0] = mtx->mf[2][2] = cs; + mtx->mf[0][2] = -sn; + mtx->mf[2][0] = sn; + mtx->mf[1][1] = mtx->mf[3][3] = 1.0f; + mtx->mf[0][1] = mtx->mf[0][3] = mtx->mf[1][0] = mtx->mf[1][2] = mtx->mf[1][3] = mtx->mf[2][1] = mtx->mf[2][3] = + mtx->mf[3][0] = mtx->mf[3][1] = mtx->mf[3][2] = 0.0f; + } +} + +// Creates rotation matrix about the Z axis in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY) +void Matrix_RotateZ(Matrix* mtx, f32 angle, u8 mode) { + f32 cs; + f32 sn; + f32 rx; + f32 ry; + s32 i; + + sn = sinf(angle); + cs = cosf(angle); + if (mode == 1) { + for (i = 0; i < 4; i++) { + rx = mtx->mf[0][i]; + ry = mtx->mf[1][i]; + + mtx->mf[0][i] = (rx * cs) + (ry * sn); + mtx->mf[1][i] = (ry * cs) - (rx * sn); + } + } else { + mtx->mf[0][0] = mtx->mf[1][1] = cs; + mtx->mf[0][1] = sn; + mtx->mf[1][0] = -sn; + mtx->mf[2][2] = mtx->mf[3][3] = 1.0f; + mtx->mf[0][2] = mtx->mf[0][3] = mtx->mf[1][2] = mtx->mf[1][3] = mtx->mf[2][0] = mtx->mf[2][1] = mtx->mf[2][3] = + mtx->mf[3][0] = mtx->mf[3][1] = mtx->mf[3][2] = 0.0f; + } +} + +// Creates rotation matrix about a given vector axis in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY). +// The vector specifying the axis does not need to be a unit vector. +void Matrix_RotateAxis(Matrix* mtx, f32 angle, f32 axisX, f32 axisY, f32 axisZ, u8 mode) { + f32 rx; + f32 ry; + f32 rz; + f32 norm; + f32 cxx; + f32 cyx; + f32 czx; + f32 cxy; + f32 cyy; + f32 czy; + f32 cxz; + f32 cyz; + f32 czz; + f32 xx; + f32 yy; + f32 zz; + f32 xy; + f32 yz; + f32 xz; + f32 sinA; + f32 cosA; + + norm = sqrtf((axisX * axisX) + (axisY * axisY) + (axisZ * axisZ)); + if (norm != 0.0) { + axisX /= norm; + axisY /= norm; + axisZ /= norm; + sinA = sinf(angle); + cosA = cosf(angle); + xx = axisX * axisX; + yy = axisY * axisY; + zz = axisZ * axisZ; + xy = axisX * axisY; + yz = axisY * axisZ; + xz = axisX * axisZ; + + if (mode == 1) { + cxx = (1.0f - xx) * cosA + xx; + cyx = (1.0f - cosA) * xy + axisZ * sinA; + czx = (1.0f - cosA) * xz - axisY * sinA; + + cxy = (1.0f - cosA) * xy - axisZ * sinA; + cyy = (1.0f - yy) * cosA + yy; + czy = (1.0f - cosA) * yz + axisX * sinA; + + cxz = (1.0f - cosA) * xz + axisY * sinA; + cyz = (1.0f - cosA) * yz - axisX * sinA; + czz = (1.0f - zz) * cosA + zz; + + // loop doesn't seem to work here. + rx = mtx->mf[0][0]; + ry = mtx->mf[0][1]; + rz = mtx->mf[0][2]; + mtx->mf[0][0] = (rx * cxx) + (ry * cxy) + (rz * cxz); + mtx->mf[0][1] = (rx * cyx) + (ry * cyy) + (rz * cyz); + mtx->mf[0][2] = (rx * czx) + (ry * czy) + (rz * czz); + + rx = mtx->mf[1][0]; + ry = mtx->mf[1][1]; + rz = mtx->mf[1][2]; + mtx->mf[1][0] = (rx * cxx) + (ry * cxy) + (rz * cxz); + mtx->mf[1][1] = (rx * cyx) + (ry * cyy) + (rz * cyz); + mtx->mf[1][2] = (rx * czx) + (ry * czy) + (rz * czz); + + rx = mtx->mf[2][0]; + ry = mtx->mf[2][1]; + rz = mtx->mf[2][2]; + mtx->mf[2][0] = (rx * cxx) + (ry * cxy) + (rz * cxz); + mtx->mf[2][1] = (rx * cyx) + (ry * cyy) + (rz * cyz); + mtx->mf[2][2] = (rx * czx) + (ry * czy) + (rz * czz); + } else { + mtx->mf[0][0] = (1.0f - xx) * cosA + xx; + mtx->mf[0][1] = (1.0f - cosA) * xy + axisZ * sinA; + mtx->mf[0][2] = (1.0f - cosA) * xz - axisY * sinA; + mtx->mf[0][3] = 0.0f; + + mtx->mf[1][0] = (1.0f - cosA) * xy - axisZ * sinA; + mtx->mf[1][1] = (1.0f - yy) * cosA + yy; + mtx->mf[1][2] = (1.0f - cosA) * yz + axisX * sinA; + mtx->mf[1][3] = 0.0f; + + mtx->mf[2][0] = (1.0f - cosA) * xz + axisY * sinA; + mtx->mf[2][1] = (1.0f - cosA) * yz - axisX * sinA; + mtx->mf[2][2] = (1.0f - zz) * cosA + zz; + mtx->mf[2][3] = 0.0f; + + mtx->mf[3][0] = mtx->mf[3][1] = mtx->mf[3][2] = 0.0f; + mtx->mf[3][3] = 1.0f; + } + } +} + +// Converts the current Gfx matrix to a Mtx +void Matrix_ToMtx(Mtx* dest) { + // LTODO: We need to validate this + guMtxF2L(gGfxMatrix->mf, dest); +} + +// Converts the Mtx src to a Matrix, putting the result in dest +void Matrix_FromMtx(Mtx* src, Matrix* dest) { + guMtxF2L(src->m, dest->mf); +} + +// Applies the transform matrix mtx to the vector src, putting the result in dest +void Matrix_MultVec3f(Matrix* mtx, Vec3f* src, Vec3f* dest) { + *dest[0] = (mtx->mf[0][0] * *src[0]) + (mtx->mf[1][0] * *src[1]) + (mtx->mf[2][0] * *src[2]) + mtx->mf[3][0]; + *dest[1] = (mtx->mf[0][1] * *src[0]) + (mtx->mf[1][1] * *src[1]) + (mtx->mf[2][1] * *src[2]) + mtx->mf[3][1]; + *dest[2] = (mtx->mf[0][2] * *src[0]) + (mtx->mf[1][2] * *src[1]) + (mtx->mf[2][2] * *src[2]) + mtx->mf[3][2]; +} + +// Applies the linear part of the transformation matrix mtx to the vector src, ignoring any translation that mtx might +// have. Puts the result in dest. +void Matrix_MultVec3fNoTranslate(Matrix* mtx, Vec3f* src, Vec3f* dest) { + *dest[0] = (mtx->mf[0][0] * *src[0]) + (mtx->mf[1][0] * *src[1]) + (mtx->mf[2][0] * *src[2]); + *dest[1] = (mtx->mf[0][1] * *src[0]) + (mtx->mf[1][1] * *src[1]) + (mtx->mf[2][1] * *src[2]); + *dest[2] = (mtx->mf[0][2] * *src[0]) + (mtx->mf[1][2] * *src[1]) + (mtx->mf[2][2] * *src[2]); +} + +// Expresses the rotational part of the transform mtx as Tait-Bryan angles, in the yaw-pitch-roll (intrinsic YXZ) +// convention used in worldspace calculations +void Matrix_GetYRPAngles(Matrix* mtx, Vec3f* rot) { + Matrix invYP; + Vec3f origin = { 0.0f, 0.0f, 0.0f }; + Vec3f originP; + Vec3f zHat = { 0.0f, 0.0f, 1.0f }; + Vec3f zHatP; + Vec3f xHat = { 1.0f, 0.0f, 0.0f }; + Vec3f xHatP; + + Matrix_MultVec3fNoTranslate(mtx, &origin, &originP); + Matrix_MultVec3fNoTranslate(mtx, &zHat, &zHatP); + Matrix_MultVec3fNoTranslate(mtx, &xHat, &xHatP); + zHatP[0] -= originP[0]; + zHatP[1] -= originP[1]; + zHatP[2] -= originP[2]; + xHatP[0] -= originP[0]; + xHatP[1] -= originP[1]; + xHatP[2] -= originP[2]; + *rot[1] = atan2f(zHatP[0], zHatP[2]); + *rot[0] = -atan2f(zHatP[1], sqrtf(SQ(zHatP[0]) + SQ(zHatP[2]))); + Matrix_RotateX(&invYP, -*rot[0], MTXF_NEW); + Matrix_RotateY(&invYP, -*rot[1], MTXF_APPLY); + Matrix_MultVec3fNoTranslate(&invYP, &xHatP, &xHat); + *rot[0] *= M_RTOD; + *rot[1] *= M_RTOD; + *rot[2] = atan2f(xHat[1], xHat[0]) * M_RTOD; +} + +// Expresses the rotational part of the transform mtx as Tait-Bryan angles, in the extrinsic XYZ convention used in +// modelspace calculations +void Matrix_GetXYZAngles(Matrix* mtx, Vec3f* rot) { + Matrix invYZ; + Vec3f origin = { 0.0f, 0.0f, 0.0f }; + Vec3f originP; + Vec3f xHat = { 1.0f, 0.0f, 0.0f }; + Vec3f xHatP; + Vec3f yHat = { 0.0f, 1.0f, 0.0f }; + Vec3f yHatP; + + Matrix_MultVec3fNoTranslate(mtx, &origin, &originP); + Matrix_MultVec3fNoTranslate(mtx, &xHat, &xHatP); + Matrix_MultVec3fNoTranslate(mtx, &yHat, &yHatP); + xHatP[0] -= originP[0]; + xHatP[1] -= originP[1]; + xHatP[2] -= originP[2]; + yHatP[0] -= originP[0]; + yHatP[1] -= originP[1]; + yHatP[2] -= originP[2]; + *rot[2] = atan2f(xHatP[1], xHatP[0]); + *rot[1] = -atan2f(xHatP[2], sqrtf(SQ(xHatP[0]) + SQ(xHatP[1]))); + Matrix_RotateY(&invYZ, -*rot[1], MTXF_NEW); + Matrix_RotateZ(&invYZ, -*rot[2], MTXF_APPLY); + Matrix_MultVec3fNoTranslate(&invYZ, &yHatP, &yHat); + *rot[0] = atan2f(yHat[2], yHat[1]) * M_RTOD; + *rot[1] *= M_RTOD; + *rot[2] *= M_RTOD; +} + +// Creates a look-at matrix from Eye, At, and Up in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY). +// A look-at matrix is a rotation-translation matrix that maps y to Up, z to (At - Eye), and translates to Eye +void Matrix_LookAt(Matrix* mtx, f32 xEye, f32 yEye, f32 zEye, f32 xAt, f32 yAt, f32 zAt, f32 xUp, f32 yUp, f32 zUp, + u8 mode) { + Matrix lookAt; + + guLookAtF(lookAt.mf, xEye, yEye, zEye, xAt, yAt, zAt, xUp, yUp, zUp); + Matrix_Mult(mtx, &lookAt, mode); +} + +// Converts the current Gfx matrix to a Mtx and sets it to the display list +void Matrix_SetGfxMtx(Gfx** gfx) { + Matrix_ToMtx(gGfxMtx); + gSPMatrix((*gfx)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); +} \ No newline at end of file diff --git a/src/port/interpolation/matrix.h b/src/port/interpolation/matrix.h new file mode 100644 index 000000000..f71ef6ab0 --- /dev/null +++ b/src/port/interpolation/matrix.h @@ -0,0 +1,94 @@ +#pragma once + +#define MTXF_NEW 0 +#define MTXF_APPLY 1 +#include "common_structs.h" + +typedef struct { + float r; + float g; + float b; +} Color; + +typedef struct { + float x; + float y; + float z; +} Vec3fInterp; + +typedef struct { + s16 x; + s16 y; + s16 z; +} Vec3sInterp; + +typedef struct { + f32 m1; f32 m2; f32 m3; f32 m4; + f32 m5; f32 m6; f32 m7; f32 m8; +} Mat4Interp; + +#define M_PI 3.14159265358979323846f +#define M_RTOD (180.0f / M_PI) +#define SQ(val) ((val) * (val)) + +#define qs1616(e) ((s32) ((e) *0x00010000)) + +#define IPART(x) ((qs1616(x) >> 16) & 0xFFFF) +#define FPART(x) (qs1616(x) & 0xFFFF) + +#define gdSPDefMtx(xx, yx, zx, wx, xy, yy, zy, wy, xz, yz, zz, wz, xw, yw, zw, ww) \ + { \ + { \ + (IPART(xx) << 0x10) | IPART(xy), (IPART(xz) << 0x10) | IPART(xw), (IPART(yx) << 0x10) | IPART(yy), \ + (IPART(yz) << 0x10) | IPART(yw), (IPART(zx) << 0x10) | IPART(zy), (IPART(zz) << 0x10) | IPART(zw), \ + (IPART(wx) << 0x10) | IPART(wy), (IPART(wz) << 0x10) | IPART(ww), (FPART(xx) << 0x10) | FPART(xy), \ + (FPART(xz) << 0x10) | FPART(xw), (FPART(yx) << 0x10) | FPART(yy), (FPART(yz) << 0x10) | FPART(yw), \ + (FPART(zx) << 0x10) | FPART(zy), (FPART(zz) << 0x10) | FPART(zw), (FPART(wx) << 0x10) | FPART(wy), \ + (FPART(wz) << 0x10) | FPART(ww), \ + } \ + } + + +typedef MtxF Matrix; + +#ifdef __cplusplus +extern "C" { +#endif + +extern Mtx gIdentityMtx; +extern Matrix gIdentityMatrix; + +extern Matrix* gGfxMatrix; +extern Matrix sGfxMatrixStack[]; +extern Matrix* gCalcMatrix; +extern Matrix sCalcMatrixStack[]; + +extern Mtx gMainMatrixStack[]; +extern Mtx* gGfxMtx; + +void Matrix_InitPerspective(Gfx** dList); +void Matrix_InitOrtho(Gfx** dList); +void Matrix_Copy(Matrix* dst, Matrix* src); +void Matrix_Push(Matrix** mtxStack); +void Matrix_Pop(Matrix** mtxStack); +void Matrix_Mult(Matrix* mtx, Matrix* tf, u8 mode); +void Matrix_Translate(Matrix* mtx, f32 x, f32 y, f32 z, u8 mode); +void Matrix_Scale(Matrix* mtx, f32 xScale, f32 yScale, f32 zScale, u8 mode); +void Matrix_RotateX(Matrix* mtx, f32 angle, u8 mode); +void Matrix_RotateY(Matrix* mtx, f32 angle, u8 mode); +void Matrix_RotateZ(Matrix* mtx, f32 angle, u8 mode); +void Matrix_RotateAxis(Matrix* mtx, f32 angle, f32 axisX, f32 axisY, f32 axisZ, u8 mode); +void Matrix_ToMtx(Mtx* dest); +void Matrix_FromMtx(Mtx* src, Matrix* dest); +void Matrix_MultVec3f(Matrix* mtx, Vec3f* src, Vec3f* dest); +void Matrix_MultVec3fNoTranslate(Matrix* mtx, Vec3f* src, Vec3f* dest); +void Matrix_GetYRPAngles(Matrix* mtx, Vec3f* rot); +void Matrix_GetXYZAngles(Matrix* mtx, Vec3f* rot); +void Matrix_LookAt(Matrix* mtx, f32 xEye, f32 yEye, f32 zEye, f32 xAt, f32 yAt, f32 zAt, f32 xUp, f32 yUp, f32 zUp, + u8 mode); +void Matrix_SetGfxMtx(Gfx** gfx); +void Lights_SetOneLight(Gfx** dList, s32 dirX, s32 dirY, s32 dirZ, s32 colR, s32 colG, s32 colB, s32 ambR, s32 ambG, s32 ambB); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/racing/framebuffer_effects.c b/src/racing/framebuffer_effects.c index 9a166b448..a89df5b40 100644 --- a/src/racing/framebuffer_effects.c +++ b/src/racing/framebuffer_effects.c @@ -37,7 +37,7 @@ void FB_CreateFramebuffers(void) { void FB_CopyToFramebuffer(Gfx** gfxP, s32 fb_src, s32 fb_dest, u8 oncePerFrame, u8* hasCopied) { Gfx* gfx = *gfxP; - gSPMatrix(gfx++, &gIdentityMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gfx++, &gIdentityMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gDPSetOtherMode(gfx++, G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | @@ -110,7 +110,7 @@ void FB_WriteFramebufferSliceToCPU(Gfx** gfxP, void* buffer, u8 byteSwap) { void FB_DrawFromFramebuffer(Gfx** gfxP, s32 fb, u8 alpha) { Gfx* gfx = *gfxP; - gSPMatrix(gfx++, &gIdentityMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + //gSPMatrix(gfx++, &gIdentityMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gDPSetEnvColor(gfx++, 255, 255, 255, alpha); diff --git a/src/racing/math_util.c b/src/racing/math_util.c index 934865b08..f1dd6bf5d 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -9,15 +9,17 @@ #include "memory.h" #include "engine/Matrix.h" #include "port/Game.h" +#include +#include #pragma intrinsic(sqrtf, fabs) s32 D_802B91C0[2] = { 13, 13 }; Vec3f D_802B91C8 = { 0.0f, 0.0f, 0.0f }; -Mtx gIdentityMatrix = { - toFixedPointMatrix(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0), -}; +// Mtx gIdentityMatrix = { +// toFixedPointMatrix(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0), +// }; // This functions looks similar to a segment of code from func_802A4A0C in skybox_and_splitscreen.c UNUSED s32 func_802B4F60(UNUSED s32 arg0, Vec3f arg1, UNUSED s32 arg2, UNUSED f32 arg3, UNUSED f32 arg4) { @@ -349,6 +351,7 @@ void mtxf_rotate_x(Mat4 mat, s16 angle) { // create a rotation matrix around the y axis void mtxf_rotate_y(Mat4 mat, s16 angle) { + FrameInterpolation_RecordMatrixRotate1Coord(&mat, 1, angle); f32 sin_theta = sins(angle); f32 cos_theta = coss(angle); @@ -368,6 +371,7 @@ void mtxf_rotate_y(Mat4 mat, s16 angle) { // create a rotation matrix around the z axis void mtxf_s16_rotate_z(Mat4 mat, s16 angle) { + FrameInterpolation_RecordMatrixRotate1Coord(&mat, 2, angle); f32 sin_theta = sins(angle); f32 cos_theta = coss(angle); @@ -480,6 +484,7 @@ void mtxf_pos_rotation_xyz(Mat4 out, Vec3f pos, Vec3s orientation) { f32 cosine2; f32 sine3; f32 cosine3; + FrameInterpolation_RecordMatrixPosRotXYZ(out, pos, orientation); sine1 = sins(orientation[0]); cosine1 = coss(orientation[0]); diff --git a/src/racing/math_util.h b/src/racing/math_util.h index b767e9068..ec6c2f3c9 100644 --- a/src/racing/math_util.h +++ b/src/racing/math_util.h @@ -10,6 +10,10 @@ // #define min(a, b) ((a) <= (b) ? (a) : (b)) // #define max(a, b) ((a) > (b) ? (a) : (b)) +#ifdef __cplusplus +extern "C" { +#endif + #define sqr(x) ((x) * (x)) // Here to appease the pragma gods @@ -70,6 +74,10 @@ f32 is_within_render_distance(Vec3f, Vec3f, u16, f32, f32, f32); extern s32 D_802B91C0[]; extern Vec3f D_802B91C8; -extern Mtx gIdentityMatrix; +//extern Mtx gIdentityMatrix; + +#ifdef __cplusplus +} +#endif #endif // MATH_UTIL_H diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index 77b1c03ff..be56d22f1 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -397,6 +397,10 @@ void func_802A450C(Vtx* skybox) { skybox[7].v.cn[2] = prop->FloorTopLeft.b; } +Mtx gIdentityMatrix2 = { + toFixedPointMatrix(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0), +}; + void func_802A487C(Vtx* arg0, UNUSED struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, UNUSED s32 arg3, UNUSED f32* arg4) { @@ -409,7 +413,7 @@ void func_802A487C(Vtx* arg0, UNUSED struct UnkStruct_800DC5EC* arg1, UNUSED s32 gSPPerspNormalize(gDisplayListHead++, 0xFFFF); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxScreen), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - gSPMatrix(gDisplayListHead++, &gIdentityMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(gDisplayListHead++, &gIdentityMatrix2, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPVertex(gDisplayListHead++, &arg0[4], 4, 0); gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0); } @@ -476,7 +480,7 @@ void func_802A4A0C(Vtx* vtx, struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, U gSPPerspNormalize(gDisplayListHead++, 0xFFFF); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxScreen), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - gSPMatrix(gDisplayListHead++, &gIdentityMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(gDisplayListHead++, &gIdentityMatrix2, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPVertex(gDisplayListHead++, &vtx[0], 4, 0); gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0); if (GetCourse() == GetRainbowRoad()) { @@ -760,6 +764,8 @@ void render_screens(s32 mode, s32 cameraId, s32 playerId) { s32 screenId = 0; s32 screenMode = SCREEN_MODE_1P; + FrameInterpolation_StartRecord(); + switch (mode) { case RENDER_SCREEN_MODE_1P_PLAYER_ONE: func_802A53A4(); @@ -902,6 +908,8 @@ void render_screens(s32 mode, s32 cameraId, s32 playerId) { if (mode != RENDER_SCREEN_MODE_1P_PLAYER_ONE) { gNumScreens += 1; } + + FrameInterpolation_StopRecord(); } void func_802A74BC(void) { From 3ec090171861605939ccba121969f274d8b0e939 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Fri, 16 May 2025 19:06:17 -0600 Subject: [PATCH 06/85] Interp Works --- src/actors/mario_sign/render.inc.c | 15 ++++++++------- src/actors/mario_sign/update.inc.c | 4 ++-- src/actors/yoshi_egg/render.inc.c | 7 +++++++ src/animation.c | 6 +++++- src/engine/Matrix.cpp | 3 --- src/port/Engine.cpp | 1 + src/port/interpolation/FrameInterpolation.cpp | 12 ++++++------ src/port/interpolation/FrameInterpolation.h | 4 ++-- 8 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/actors/mario_sign/render.inc.c b/src/actors/mario_sign/render.inc.c index 7914a283f..84e1a8068 100644 --- a/src/actors/mario_sign/render.inc.c +++ b/src/actors/mario_sign/render.inc.c @@ -11,10 +11,9 @@ * @param arg2 */ void render_actor_mario_sign(Camera* arg0, UNUSED Mat4 arg1, struct Actor* arg2) { - Mat4 sp40; + Mat4 mtx; f32 unk; s16 temp = arg2->flags; - FrameInterpolation_RecordOpenChild(arg2, 0); if (temp & 0x800) { return; } @@ -24,14 +23,16 @@ void render_actor_mario_sign(Camera* arg0, UNUSED Mat4 arg1, struct Actor* arg2) unk = MAX(unk, 0.0f); } if (!(unk < 0.0f)) { + + FrameInterpolation_RecordMatrixPush(mtx); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); - mtxf_pos_rotation_xyz(sp40, arg2->pos, arg2->rot); - if (render_set_position(sp40, 0) != 0) { + mtxf_pos_rotation_xyz(mtx, arg2->pos, arg2->rot); + if (render_set_position(mtx, 0) != 0) { gSPDisplayList(gDisplayListHead++, d_course_mario_raceway_dl_sign); } + FrameInterpolation_RecordMatrixPop(mtx); + } - - FrameInterpolation_RecordCloseChild(); - } diff --git a/src/actors/mario_sign/update.inc.c b/src/actors/mario_sign/update.inc.c index 7a85e8ac5..6a061eddd 100644 --- a/src/actors/mario_sign/update.inc.c +++ b/src/actors/mario_sign/update.inc.c @@ -11,10 +11,10 @@ void update_actor_mario_sign(struct Actor* arg0) { arg0->pos[1] += 4.0f; if (arg0->pos[1] > 800.0f) { arg0->flags |= 0x800; - arg0->rot[1] += 4; + arg0->rot[1] += 1820; } } else { - arg0->rot[1] += 4; + arg0->rot[1] += 182; } } } diff --git a/src/actors/yoshi_egg/render.inc.c b/src/actors/yoshi_egg/render.inc.c index e38625df0..2e0fe8ac0 100644 --- a/src/actors/yoshi_egg/render.inc.c +++ b/src/actors/yoshi_egg/render.inc.c @@ -51,6 +51,9 @@ void render_actor_yoshi_egg(Camera* arg0, Mat4 arg1, struct YoshiValleyEgg* egg, sp5C[0] = 0; sp5C[1] = egg->eggRot; sp5C[2] = 0; + + FrameInterpolation_RecordMatrixPush(sp60); + mtxf_pos_rotation_xyz(sp60, egg->pos, sp5C); if (render_set_position(sp60, 0) == 0) { return; @@ -58,14 +61,18 @@ void render_actor_yoshi_egg(Camera* arg0, Mat4 arg1, struct YoshiValleyEgg* egg, gSPSetGeometryMode(gDisplayListHead++, G_LIGHTING); gSPDisplayList(gDisplayListHead++, d_course_yoshi_valley_dl_16D70); + FrameInterpolation_RecordMatrixPop(sp60); } else { arg1[3][0] = egg->pos[0]; arg1[3][1] = egg->pos[1]; arg1[3][2] = egg->pos[2]; + FrameInterpolation_RecordMatrixPush(arg1); + if (render_set_position(arg1, 0) != 0) { gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); gSPDisplayList(gDisplayListHead++, d_course_yoshi_valley_dl_egg_lod0); } + FrameInterpolation_RecordMatrixPop(arg1); } } diff --git a/src/animation.c b/src/animation.c index d81123ae9..92525dfc7 100644 --- a/src/animation.c +++ b/src/animation.c @@ -35,6 +35,9 @@ void convert_to_fixed_point_matrix_animation(Mtx* dest, Mat4 src) { } void mtxf_translate_rotate2(Mat4 dest, Vec3f pos, Vec3s angle) { + + FrameInterpolation_RecordMatrixPosRotXYZ(&dest, pos, angle); + f32 sx = sins(angle[0]); f32 cx = coss(angle[0]); @@ -92,7 +95,7 @@ void render_limb_or_add_mtx(Armature* arg0, s16* arg1, AnimationLimbVector arg2, } angle[i] = arg1[arg2[i].indexCycle + some_offset]; } - + FrameInterpolation_RecordMatrixPush(modelMatrix); mtxf_translate_rotate2(modelMatrix, pos, angle); //convert_to_fixed_point_matrix_animation(&gGfxPool->mtxHud[gMatrixHudCount], modelMatrix); sMatrixStackSize += 1; @@ -104,6 +107,7 @@ void render_limb_or_add_mtx(Armature* arg0, s16* arg1, AnimationLimbVector arg2, model = (virtualModel); gSPDisplayList(gDisplayListHead++, model); } + FrameInterpolation_RecordMatrixPop(modelMatrix); } void render_armature(Armature* animation, Animation* arg1, s16 timeCycle) { diff --git a/src/engine/Matrix.cpp b/src/engine/Matrix.cpp index 44e5f081d..e46804ad5 100644 --- a/src/engine/Matrix.cpp +++ b/src/engine/Matrix.cpp @@ -10,9 +10,6 @@ extern "C" { } void AddMatrix(std::vector& stack, Mat4 mtx, s32 flags) { - // Reserve space if needed to avoid reallocation overhead - stack.reserve(1000); - // Push a new matrix to the stack stack.emplace_back(); diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 58e3920ea..cc7d0755d 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -379,6 +379,7 @@ void GameEngine::ProcessGfxCommands(Gfx* commands) { mtx_replacements.emplace_back(); } } + // printf("mtxf size: %d\n", mtx_replacements.size()); time -= fps; diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index 9064cdb04..a674c1ff2 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -330,11 +330,11 @@ struct InterpolateCtx { break; case Op::MatrixPush: - // Matrix_Push(&gInterpolationMatrix); + Matrix_Push((Matrix**)&gInterpolationMatrix); break; case Op::MatrixPop: - // Matrix_Pop(&gInterpolationMatrix); + Matrix_Pop((Matrix**)&gInterpolationMatrix); break; // Unused on SF64 @@ -519,11 +519,11 @@ void FrameInterpolation_RecordActorPosRotMatrix(void) { next_is_actor_pos_rot_matrix = true; } -void FrameInterpolation_RecordMatrixPush(Mat4** matrix) { +void FrameInterpolation_RecordMatrixPush(Mat4* matrix) { if (!is_recording) return; - append(Op::MatrixPush).matrix_ptr = { matrix }; + append(Op::MatrixPush).matrix_ptr = { (Mat4**)matrix }; } void FrameInterpolation_RecordMarker(const char* file, int line) { @@ -533,10 +533,10 @@ void FrameInterpolation_RecordMarker(const char* file, int line) { // append(Op::Marker).marker = { file, line }; } -void FrameInterpolation_RecordMatrixPop(Mat4** matrix) { +void FrameInterpolation_RecordMatrixPop(Mat4* matrix) { if (!is_recording) return; - append(Op::MatrixPop).matrix_ptr = { matrix }; + append(Op::MatrixPop).matrix_ptr = { (Mat4**)matrix }; } void FrameInterpolation_RecordMatrixPut(MtxF* src) { diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 7d2df76a8..93f4dd0a9 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -35,9 +35,9 @@ void FrameInterpolation_RecordActorPosRotMatrix(void); void FrameInterpolation_RecordMatrixPosRotXYZ(Mat4 out, Vec3f pos, Vec3s orientation); -//void FrameInterpolation_RecordMatrixPush(Matrix** mtx); +void FrameInterpolation_RecordMatrixPush(Mat4* mtx); -//void FrameInterpolation_RecordMatrixPop(Matrix** mtx); +void FrameInterpolation_RecordMatrixPop(Mat4* mtx); //void FrameInterpolation_RecordMatrixMult(Matrix* matrix, MtxF* mf, u8 mode); From 6a6f4213cb124c3bc0eb33630f12271d341efbaa Mon Sep 17 00:00:00 2001 From: MegaMech Date: Fri, 16 May 2025 19:14:04 -0600 Subject: [PATCH 07/85] Test default tick/logic update --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 39eb51d84..01b09b7ca 100644 --- a/src/main.c +++ b/src/main.c @@ -686,7 +686,7 @@ void calculate_updaterate(void) { if (targetFPS < 60) { gTickLogic = 2; } else { - gTickLogic = 1; // Perform logic update + gTickLogic = 2; // Perform logic update } } @@ -694,8 +694,8 @@ void calculate_updaterate(void) { visualsAccumulator += total; // Increment for each frame if (visualsAccumulator >= visualsUpdateInterval) { // Check if it's time to update visuals visualsAccumulator -= visualsUpdateInterval; - gTickVisuals = 1; // Perform visual update } + gTickVisuals = 1; // Perform visual update } void display_debug_info(void) { From 7473382f06ac450df41dc14fb46e528dc1d31f11 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Fri, 16 May 2025 20:14:45 -0500 Subject: [PATCH 08/85] Added missing include (#202) * Added missing include * More missing includes --------- Co-authored-by: MegaMech --- src/actors/mario_sign/render.inc.c | 1 + src/actors/yoshi_egg/render.inc.c | 1 + src/animation.c | 1 + src/port/interpolation/matrix.c | 1 + src/racing/skybox_and_splitscreen.c | 1 + 5 files changed, 5 insertions(+) diff --git a/src/actors/mario_sign/render.inc.c b/src/actors/mario_sign/render.inc.c index 84e1a8068..0bf10bf88 100644 --- a/src/actors/mario_sign/render.inc.c +++ b/src/actors/mario_sign/render.inc.c @@ -1,6 +1,7 @@ #include #include #include +#include "port/interpolation/FrameInterpolation.h" /** * @brief Renders the Mario sign actor. diff --git a/src/actors/yoshi_egg/render.inc.c b/src/actors/yoshi_egg/render.inc.c index 2e0fe8ac0..f39524aa3 100644 --- a/src/actors/yoshi_egg/render.inc.c +++ b/src/actors/yoshi_egg/render.inc.c @@ -2,6 +2,7 @@ #include #include #include +#include "port/interpolation/FrameInterpolation.h" /** * @brief Renders the Yoshi egg actor. diff --git a/src/animation.c b/src/animation.c index 92525dfc7..ed290ef7a 100644 --- a/src/animation.c +++ b/src/animation.c @@ -8,6 +8,7 @@ #include #include "code_80057C60.h" #include "engine/Matrix.h" +#include "port/interpolation/FrameInterpolation.h" Vec3s sOriginalPosAnimation; s16 isNotTheFirst; diff --git a/src/port/interpolation/matrix.c b/src/port/interpolation/matrix.c index 4f8a7839b..5580975a5 100644 --- a/src/port/interpolation/matrix.c +++ b/src/port/interpolation/matrix.c @@ -2,6 +2,7 @@ #include #include "matrix.h" #include "common_structs.h" +#include "FrameInterpolation.h" Mtx gIdentityMtx = gdSPDefMtx(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); Matrix gIdentityMatrix = { { diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index be56d22f1..abc7c23aa 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -21,6 +21,7 @@ #include "engine/courses/Course.h" #include "port/Game.h" #include "math_util.h" +#include "port/interpolation/FrameInterpolation.h" Vp D_802B8880[] = { { { { 640, 480, 511, 0 }, { 640, 480, 511, 0 } } }, From 1a810d74cc8531ce486bcb1c399cc6798fa1b51d Mon Sep 17 00:00:00 2001 From: MegaMech Date: Fri, 16 May 2025 21:43:05 -0600 Subject: [PATCH 09/85] test --- src/actors/item_box/render.inc.c | 6 ++++++ src/actors/mario_sign/render.inc.c | 2 +- src/actors/yoshi_egg/render.inc.c | 4 ++-- src/animation.c | 2 +- src/engine/Matrix.cpp | 4 +++- src/port/interpolation/FrameInterpolation.cpp | 4 ++++ src/port/interpolation/FrameInterpolation.h | 2 +- src/racing/math_util.c | 2 ++ 8 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/actors/item_box/render.inc.c b/src/actors/item_box/render.inc.c index d4a96a0e3..fe793ba9a 100644 --- a/src/actors/item_box/render.inc.c +++ b/src/actors/item_box/render.inc.c @@ -1,6 +1,7 @@ #include #include #include +#include "port/interpolation/FrameInterpolation.h" /** * @brief Renders the item box actor. @@ -28,6 +29,11 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { temp_f0 = is_within_render_distance(camera->pos, item_box->pos, camera->rot[1], 0.0f, gCameraZoom[camera - camera1], 4000000.0f); + + FrameInterpolation_RecordMatrixPush(someMatrix1); + FrameInterpolation_RecordMatrixPush(someMatrix2); + + if (CVarGetInteger("gNoCulling", 0) == 1) { temp_f0 = CLAMP(temp_f0, 0.0f, 600000.0f); } diff --git a/src/actors/mario_sign/render.inc.c b/src/actors/mario_sign/render.inc.c index 0bf10bf88..559f3ec0b 100644 --- a/src/actors/mario_sign/render.inc.c +++ b/src/actors/mario_sign/render.inc.c @@ -33,7 +33,7 @@ void render_actor_mario_sign(Camera* arg0, UNUSED Mat4 arg1, struct Actor* arg2) if (render_set_position(mtx, 0) != 0) { gSPDisplayList(gDisplayListHead++, d_course_mario_raceway_dl_sign); } - FrameInterpolation_RecordMatrixPop(mtx); + //FrameInterpolation_RecordMatrixPop(mtx); } } diff --git a/src/actors/yoshi_egg/render.inc.c b/src/actors/yoshi_egg/render.inc.c index f39524aa3..e0e5aa89a 100644 --- a/src/actors/yoshi_egg/render.inc.c +++ b/src/actors/yoshi_egg/render.inc.c @@ -62,7 +62,7 @@ void render_actor_yoshi_egg(Camera* arg0, Mat4 arg1, struct YoshiValleyEgg* egg, gSPSetGeometryMode(gDisplayListHead++, G_LIGHTING); gSPDisplayList(gDisplayListHead++, d_course_yoshi_valley_dl_16D70); - FrameInterpolation_RecordMatrixPop(sp60); + // FrameInterpolation_RecordMatrixPop(sp60); } else { arg1[3][0] = egg->pos[0]; arg1[3][1] = egg->pos[1]; @@ -74,6 +74,6 @@ void render_actor_yoshi_egg(Camera* arg0, Mat4 arg1, struct YoshiValleyEgg* egg, gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); gSPDisplayList(gDisplayListHead++, d_course_yoshi_valley_dl_egg_lod0); } - FrameInterpolation_RecordMatrixPop(arg1); + //FrameInterpolation_RecordMatrixPop(arg1); } } diff --git a/src/animation.c b/src/animation.c index ed290ef7a..d2f33301c 100644 --- a/src/animation.c +++ b/src/animation.c @@ -108,7 +108,7 @@ void render_limb_or_add_mtx(Armature* arg0, s16* arg1, AnimationLimbVector arg2, model = (virtualModel); gSPDisplayList(gDisplayListHead++, model); } - FrameInterpolation_RecordMatrixPop(modelMatrix); + //FrameInterpolation_RecordMatrixPop(modelMatrix); } void render_armature(Armature* animation, Animation* arg1, s16 timeCycle) { diff --git a/src/engine/Matrix.cpp b/src/engine/Matrix.cpp index e46804ad5..f79bc27bf 100644 --- a/src/engine/Matrix.cpp +++ b/src/engine/Matrix.cpp @@ -11,10 +11,12 @@ extern "C" { void AddMatrix(std::vector& stack, Mat4 mtx, s32 flags) { // Push a new matrix to the stack + +//FrameInterpolation_RecordMatrixPush((Mat4*) &mtx); + stack.emplace_back(); // Convert to a fixed-point matrix - FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mtx, &stack.back()); guMtxF2L(mtx, &stack.back()); // Load the matrix diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index a674c1ff2..1ae649e0a 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -520,6 +520,10 @@ void FrameInterpolation_RecordActorPosRotMatrix(void) { } void FrameInterpolation_RecordMatrixPush(Mat4* matrix) { + if (is_recording) { + append(Op::MatrixPop).matrix_ptr = { (Mat4**)matrix }; + } + if (!is_recording) return; diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 93f4dd0a9..533178780 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -35,7 +35,7 @@ void FrameInterpolation_RecordActorPosRotMatrix(void); void FrameInterpolation_RecordMatrixPosRotXYZ(Mat4 out, Vec3f pos, Vec3s orientation); -void FrameInterpolation_RecordMatrixPush(Mat4* mtx); +void FrameInterpolation_RecordMatrixPush(Mat4* matrix); void FrameInterpolation_RecordMatrixPop(Mat4* mtx); diff --git a/src/racing/math_util.c b/src/racing/math_util.c index f1dd6bf5d..0f96c3117 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -190,6 +190,8 @@ void mtxf_identity(Mat4 mtx) { // Add a translation vector to a matrix, mat is the matrix to add, dest is the destination matrix, pos is the // translation vector void add_translate_mat4_vec3f(Mat4 mat, Mat4 dest, Vec3f pos) { + FrameInterpolation_RecordMatrixTranslate(dest, pos); + dest[3][0] = mat[3][0] + pos[0]; dest[3][1] = mat[3][1] + pos[1]; dest[3][2] = mat[3][2] + pos[2]; From 57a7a9a52d9a856efa11f0d999446bc39df4a713 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Fri, 16 May 2025 22:08:10 -0600 Subject: [PATCH 10/85] Revert "test" This reverts commit 1a810d74cc8531ce486bcb1c399cc6798fa1b51d. --- src/actors/item_box/render.inc.c | 6 ------ src/actors/mario_sign/render.inc.c | 2 +- src/actors/yoshi_egg/render.inc.c | 4 ++-- src/animation.c | 2 +- src/engine/Matrix.cpp | 4 +--- src/port/interpolation/FrameInterpolation.cpp | 4 ---- src/port/interpolation/FrameInterpolation.h | 2 +- src/racing/math_util.c | 2 -- 8 files changed, 6 insertions(+), 20 deletions(-) diff --git a/src/actors/item_box/render.inc.c b/src/actors/item_box/render.inc.c index fe793ba9a..d4a96a0e3 100644 --- a/src/actors/item_box/render.inc.c +++ b/src/actors/item_box/render.inc.c @@ -1,7 +1,6 @@ #include #include #include -#include "port/interpolation/FrameInterpolation.h" /** * @brief Renders the item box actor. @@ -29,11 +28,6 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { temp_f0 = is_within_render_distance(camera->pos, item_box->pos, camera->rot[1], 0.0f, gCameraZoom[camera - camera1], 4000000.0f); - - FrameInterpolation_RecordMatrixPush(someMatrix1); - FrameInterpolation_RecordMatrixPush(someMatrix2); - - if (CVarGetInteger("gNoCulling", 0) == 1) { temp_f0 = CLAMP(temp_f0, 0.0f, 600000.0f); } diff --git a/src/actors/mario_sign/render.inc.c b/src/actors/mario_sign/render.inc.c index 559f3ec0b..0bf10bf88 100644 --- a/src/actors/mario_sign/render.inc.c +++ b/src/actors/mario_sign/render.inc.c @@ -33,7 +33,7 @@ void render_actor_mario_sign(Camera* arg0, UNUSED Mat4 arg1, struct Actor* arg2) if (render_set_position(mtx, 0) != 0) { gSPDisplayList(gDisplayListHead++, d_course_mario_raceway_dl_sign); } - //FrameInterpolation_RecordMatrixPop(mtx); + FrameInterpolation_RecordMatrixPop(mtx); } } diff --git a/src/actors/yoshi_egg/render.inc.c b/src/actors/yoshi_egg/render.inc.c index e0e5aa89a..f39524aa3 100644 --- a/src/actors/yoshi_egg/render.inc.c +++ b/src/actors/yoshi_egg/render.inc.c @@ -62,7 +62,7 @@ void render_actor_yoshi_egg(Camera* arg0, Mat4 arg1, struct YoshiValleyEgg* egg, gSPSetGeometryMode(gDisplayListHead++, G_LIGHTING); gSPDisplayList(gDisplayListHead++, d_course_yoshi_valley_dl_16D70); - // FrameInterpolation_RecordMatrixPop(sp60); + FrameInterpolation_RecordMatrixPop(sp60); } else { arg1[3][0] = egg->pos[0]; arg1[3][1] = egg->pos[1]; @@ -74,6 +74,6 @@ void render_actor_yoshi_egg(Camera* arg0, Mat4 arg1, struct YoshiValleyEgg* egg, gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); gSPDisplayList(gDisplayListHead++, d_course_yoshi_valley_dl_egg_lod0); } - //FrameInterpolation_RecordMatrixPop(arg1); + FrameInterpolation_RecordMatrixPop(arg1); } } diff --git a/src/animation.c b/src/animation.c index d2f33301c..ed290ef7a 100644 --- a/src/animation.c +++ b/src/animation.c @@ -108,7 +108,7 @@ void render_limb_or_add_mtx(Armature* arg0, s16* arg1, AnimationLimbVector arg2, model = (virtualModel); gSPDisplayList(gDisplayListHead++, model); } - //FrameInterpolation_RecordMatrixPop(modelMatrix); + FrameInterpolation_RecordMatrixPop(modelMatrix); } void render_armature(Armature* animation, Animation* arg1, s16 timeCycle) { diff --git a/src/engine/Matrix.cpp b/src/engine/Matrix.cpp index f79bc27bf..e46804ad5 100644 --- a/src/engine/Matrix.cpp +++ b/src/engine/Matrix.cpp @@ -11,12 +11,10 @@ extern "C" { void AddMatrix(std::vector& stack, Mat4 mtx, s32 flags) { // Push a new matrix to the stack - -//FrameInterpolation_RecordMatrixPush((Mat4*) &mtx); - stack.emplace_back(); // Convert to a fixed-point matrix + FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mtx, &stack.back()); guMtxF2L(mtx, &stack.back()); // Load the matrix diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index 1ae649e0a..a674c1ff2 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -520,10 +520,6 @@ void FrameInterpolation_RecordActorPosRotMatrix(void) { } void FrameInterpolation_RecordMatrixPush(Mat4* matrix) { - if (is_recording) { - append(Op::MatrixPop).matrix_ptr = { (Mat4**)matrix }; - } - if (!is_recording) return; diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 533178780..93f4dd0a9 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -35,7 +35,7 @@ void FrameInterpolation_RecordActorPosRotMatrix(void); void FrameInterpolation_RecordMatrixPosRotXYZ(Mat4 out, Vec3f pos, Vec3s orientation); -void FrameInterpolation_RecordMatrixPush(Mat4* matrix); +void FrameInterpolation_RecordMatrixPush(Mat4* mtx); void FrameInterpolation_RecordMatrixPop(Mat4* mtx); diff --git a/src/racing/math_util.c b/src/racing/math_util.c index 0f96c3117..f1dd6bf5d 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -190,8 +190,6 @@ void mtxf_identity(Mat4 mtx) { // Add a translation vector to a matrix, mat is the matrix to add, dest is the destination matrix, pos is the // translation vector void add_translate_mat4_vec3f(Mat4 mat, Mat4 dest, Vec3f pos) { - FrameInterpolation_RecordMatrixTranslate(dest, pos); - dest[3][0] = mat[3][0] + pos[0]; dest[3][1] = mat[3][1] + pos[1]; dest[3][2] = mat[3][2] + pos[2]; From 881732eb8d1a5746c0fbb82d0319b5132d01419f Mon Sep 17 00:00:00 2001 From: MegaMech Date: Fri, 16 May 2025 22:23:15 -0600 Subject: [PATCH 11/85] Interp Item box --- src/actors/item_box/render.inc.c | 7 +++++++ src/engine/Matrix.cpp | 1 - src/port/interpolation/FrameInterpolation.h | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/actors/item_box/render.inc.c b/src/actors/item_box/render.inc.c index d4a96a0e3..0d02c3979 100644 --- a/src/actors/item_box/render.inc.c +++ b/src/actors/item_box/render.inc.c @@ -1,6 +1,7 @@ #include #include #include +#include "port/interpolation/FrameInterpolation.h" /** * @brief Renders the item box actor. @@ -26,6 +27,9 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { f32 temp_f2_2; f32 someMultiplier; + FrameInterpolation_RecordMatrixPush(someMatrix1); + FrameInterpolation_RecordMatrixPush(someMatrix2); + temp_f0 = is_within_render_distance(camera->pos, item_box->pos, camera->rot[1], 0.0f, gCameraZoom[camera - camera1], 4000000.0f); if (CVarGetInteger("gNoCulling", 0) == 1) { @@ -179,4 +183,7 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); } + + FrameInterpolation_RecordMatrixPop(someMatrix1); + FrameInterpolation_RecordMatrixPop(someMatrix2); } diff --git a/src/engine/Matrix.cpp b/src/engine/Matrix.cpp index e46804ad5..0104de47c 100644 --- a/src/engine/Matrix.cpp +++ b/src/engine/Matrix.cpp @@ -14,7 +14,6 @@ void AddMatrix(std::vector& stack, Mat4 mtx, s32 flags) { stack.emplace_back(); // Convert to a fixed-point matrix - FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mtx, &stack.back()); guMtxF2L(mtx, &stack.back()); // Load the matrix diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 93f4dd0a9..87012f66b 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -35,9 +35,9 @@ void FrameInterpolation_RecordActorPosRotMatrix(void); void FrameInterpolation_RecordMatrixPosRotXYZ(Mat4 out, Vec3f pos, Vec3s orientation); -void FrameInterpolation_RecordMatrixPush(Mat4* mtx); +void FrameInterpolation_RecordMatrixPush(Mat4* matrix); -void FrameInterpolation_RecordMatrixPop(Mat4* mtx); +void FrameInterpolation_RecordMatrixPop(Mat4* matrix); //void FrameInterpolation_RecordMatrixMult(Matrix* matrix, MtxF* mf, u8 mode); From 1c5bcd821c828e432779b99e2e3c3e47dbdd2c3d Mon Sep 17 00:00:00 2001 From: MegaMech Date: Fri, 16 May 2025 22:29:44 -0600 Subject: [PATCH 12/85] Actually interpolate item box --- src/racing/math_util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/racing/math_util.c b/src/racing/math_util.c index f1dd6bf5d..457975ebb 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -190,6 +190,7 @@ void mtxf_identity(Mat4 mtx) { // Add a translation vector to a matrix, mat is the matrix to add, dest is the destination matrix, pos is the // translation vector void add_translate_mat4_vec3f(Mat4 mat, Mat4 dest, Vec3f pos) { + FrameInterpolation_RecordMatrixTranslate(dest, pos); dest[3][0] = mat[3][0] + pos[0]; dest[3][1] = mat[3][1] + pos[1]; dest[3][2] = mat[3][2] + pos[2]; From 3f33446669aadcedd622476df1f5c734fda1f9e6 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Sat, 17 May 2025 01:48:08 -0300 Subject: [PATCH 13/85] fix clouds --- src/update_objects.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/update_objects.c b/src/update_objects.c index 73d0dcfdc..6d2b8a77a 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -40,6 +40,8 @@ #include #include "port/Game.h" +float OTRGetAspectRatio(void); + //! @todo unused? f32 D_800E43B0[] = { 65536.0, 0.0, 1.0, 0.0, 0.0, 65536.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; @@ -2455,20 +2457,28 @@ void update_snowflakes(void) { } void func_800788F8(s32 objectIndex, u16 rot, Camera* camera) { - s16 temp_v0; + s16 cameraRot; + // Adjustable culling factor + const float cullingFactor = OTRGetAspectRatio(); - temp_v0 = camera->rot[1] + rot; - if ((temp_v0 >= D_8018D210) && (D_8018D208 >= temp_v0)) { - gObjectList[objectIndex].unk_09C = (D_8018D218 + (D_8018D1E8 * temp_v0)); - set_object_flag(objectIndex, 0x00000010); - return; + // Calculate object's rotation relative to the camera + cameraRot = camera->rot[1] + rot; + + // Adjust bounds based on the culling factor + s16 adjustedLowerBound = (s16) (D_8018D210 * cullingFactor); + s16 adjustedUpperBound = (s16) (D_8018D208 * cullingFactor); + + // Check if the object is within the adjusted bounds + if ((cameraRot >= adjustedLowerBound) && (adjustedUpperBound >= cameraRot)) { + // Calculate and update the object's position + gObjectList[objectIndex].unk_09C = (D_8018D218 + (D_8018D1E8 * cameraRot)); + + // Mark the object as visible + set_object_flag(objectIndex, 0x10); + } else { + // If outside the bounds, mark the object as not visible + set_object_flag(objectIndex, 0x10); } - if (CVarGetInteger("gNoCulling", 0) == 1) { - gObjectList[objectIndex].unk_09C = (D_8018D218 + (D_8018D1E8 * temp_v0)); - set_object_flag(objectIndex, 0x00000010); - return; - } - clear_object_flag(objectIndex, 0x00000010); } void update_clouds(s32 arg0, Camera* arg1, CloudData* cloudList) { From 0cf96615541d5ea543104f521d02d91501b406b2 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Fri, 16 May 2025 23:01:22 -0600 Subject: [PATCH 14/85] interp player? --- src/render_player.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/render_player.c b/src/render_player.c index 1c4d78a7e..9267706db 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -1616,6 +1616,9 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) { s16 temp_v1; s16 thing; + FrameInterpolation_RecordMatrixPush(mtx); + + if (player->unk_044 & 0x2000) { sp14C[0] = 0; sp14C[1] = player->unk_048[screenId]; @@ -1743,6 +1746,8 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) { gSPDisplayList(gDisplayListHead++, common_square_plain_render); gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); + + FrameInterpolation_RecordMatrixPop(mtx); } void render_ghost(Player* player, s8 playerId, s8 screenId, s8 arg3) { From b551dd5f5466db60b226f83f9a6dc41ce29a4a2e Mon Sep 17 00:00:00 2001 From: MegaMech Date: Fri, 16 May 2025 23:35:21 -0600 Subject: [PATCH 15/85] Test 2 --- src/actors/falling_rock/render.inc.c | 19 ++++++++--- src/actors/item_box/render.inc.c | 47 +++++++++++++++++++++++++--- src/engine/Matrix.cpp | 1 + 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/src/actors/falling_rock/render.inc.c b/src/actors/falling_rock/render.inc.c index 20c6a49b3..c46fceaf3 100644 --- a/src/actors/falling_rock/render.inc.c +++ b/src/actors/falling_rock/render.inc.c @@ -1,6 +1,7 @@ #include #include #include +#include "port/interpolation/FrameInterpolation.h" /** * @brief Renders the falling rock actor. @@ -12,7 +13,7 @@ void render_actor_falling_rock(Camera* camera, struct FallingRock* rock) { Vec3s sp98; Vec3f sp8C; - Mat4 sp4C; + Mat4 mtx; f32 height; UNUSED s32 pad[4]; @@ -41,16 +42,24 @@ void render_actor_falling_rock(Camera* camera, struct FallingRock* rock) { sp98[1] = 0; sp98[2] = 0; sp8C[1] = height + 2.0f; - mtxf_pos_rotation_xyz(sp4C, sp8C, sp98); - if (render_set_position(sp4C, 0) == 0) { + FrameInterpolation_RecordMatrixPush(mtx); + + mtxf_pos_rotation_xyz(mtx, sp8C, sp98); + if (render_set_position(mtx, 0) == 0) { return; } gSPDisplayList(gDisplayListHead++, d_course_choco_mountain_dl_6F88); + FrameInterpolation_RecordMatrixPop(mtx); + } } - mtxf_pos_rotation_xyz(sp4C, rock->pos, rock->rot); - if (render_set_position(sp4C, 0) == 0) { + FrameInterpolation_RecordMatrixPush(mtx); + + mtxf_pos_rotation_xyz(mtx, rock->pos, rock->rot); + if (render_set_position(mtx, 0) == 0) { return; } gSPDisplayList(gDisplayListHead++, d_course_choco_mountain_dl_falling_rock); + FrameInterpolation_RecordMatrixPop(mtx); + } diff --git a/src/actors/item_box/render.inc.c b/src/actors/item_box/render.inc.c index 0d02c3979..347b2f276 100644 --- a/src/actors/item_box/render.inc.c +++ b/src/actors/item_box/render.inc.c @@ -27,8 +27,6 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { f32 temp_f2_2; f32 someMultiplier; - FrameInterpolation_RecordMatrixPush(someMatrix1); - FrameInterpolation_RecordMatrixPush(someMatrix2); temp_f0 = is_within_render_distance(camera->pos, item_box->pos, camera->rot[1], 0.0f, gCameraZoom[camera - camera1], 4000000.0f); @@ -43,6 +41,8 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { someVec2[0] = item_box->pos[0]; someVec2[1] = item_box->resetDistance + 2.0f; someVec2[2] = item_box->pos[2]; + FrameInterpolation_RecordMatrixPush(someMatrix1); + mtxf_pos_rotation_xyz(someMatrix1, someVec2, someRot); if (!render_set_position(someMatrix1, 0)) { @@ -50,8 +50,13 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D002EE8); + FrameInterpolation_RecordMatrixPop(someMatrix1); + someRot[1] = item_box->rot[1] * 2; someVec2[1] = item_box->pos[1]; + + FrameInterpolation_RecordMatrixPush(someMatrix1); + mtxf_pos_rotation_xyz(someMatrix1, someVec2, someRot); if (!render_set_position(someMatrix1, 0)) { @@ -59,8 +64,13 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, itemBoxQuestionMarkModel); + FrameInterpolation_RecordMatrixPop(someMatrix1); + } if (item_box->state == 5) { + FrameInterpolation_RecordMatrixPush(someMatrix1); + + mtxf_pos_rotation_xyz(someMatrix1, item_box->pos, item_box->rot); if (!render_set_position(someMatrix1, 0)) { @@ -68,8 +78,12 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, itemBoxQuestionMarkModel); + FrameInterpolation_RecordMatrixPop(someMatrix1); + } if (item_box->state != 3) { + FrameInterpolation_RecordMatrixPush(someMatrix1); + mtxf_pos_rotation_xyz(someMatrix1, item_box->pos, item_box->rot); if (!render_set_position(someMatrix1, 0)) { @@ -92,11 +106,15 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); gSPDisplayList(gDisplayListHead++, D_0D003090); + FrameInterpolation_RecordMatrixPop(someMatrix1); + } else { gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); gDPSetBlendMask(gDisplayListHead++, 0xFF); thing = item_box->someTimer; + FrameInterpolation_RecordMatrixPush(someMatrix2); + mtxf_pos_rotation_xyz(someMatrix1, item_box->pos, item_box->rot); if (thing < 10.0f) { someMultiplier = 1.0f; @@ -120,6 +138,11 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D003158); + FrameInterpolation_RecordMatrixPop(someMatrix2); + + FrameInterpolation_RecordMatrixPush(someMatrix2); + + temp_f2_2 = 0.8f * thing; temp_f12 = 0.5f * thing; someVec1[0] = temp_f2_2; @@ -132,10 +155,14 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D0031B8); + FrameInterpolation_RecordMatrixPop(someMatrix2); + temp_f0_2 = -0.5f * thing; someVec1[0] = temp_f2_2; someVec1[1] = 1.2f * thing; someVec1[2] = temp_f0_2; + FrameInterpolation_RecordMatrixPush(someMatrix2); + add_translate_mat4_vec3f(someMatrix1, someMatrix2, someVec1); if (!render_set_position(someMatrix2, 0)) { @@ -143,6 +170,8 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D003128); + FrameInterpolation_RecordMatrixPop(someMatrix2); + if (!(item_box->someTimer & 1)) { gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); } else { @@ -151,6 +180,8 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { someVec1[0] = 0.0f; someVec1[1] = 1.8f * thing; someVec1[2] = -1.0f * thing; + FrameInterpolation_RecordMatrixPush(someMatrix2); + add_translate_mat4_vec3f(someMatrix1, someMatrix2, someVec1); if (!render_set_position(someMatrix2, 0)) { @@ -158,10 +189,14 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D0031E8); + FrameInterpolation_RecordMatrixPop(someMatrix2); + temp_f0_3 = -0.8f * thing; someVec1[0] = temp_f0_3; someVec1[1] = 0.6f * thing; someVec1[2] = temp_f0_2; + FrameInterpolation_RecordMatrixPush(someMatrix2); + add_translate_mat4_vec3f(someMatrix1, someMatrix2, someVec1); if (!render_set_position(someMatrix2, 0)) { @@ -169,9 +204,13 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D003188); + FrameInterpolation_RecordMatrixPop(someMatrix2); + someVec1[0] = temp_f0_3; someVec1[1] = temp_f2; someVec1[2] = temp_f12; + FrameInterpolation_RecordMatrixPop(someMatrix2); + add_translate_mat4_vec3f(someMatrix1, someMatrix2, someVec1); if (!render_set_position(someMatrix2, 0)) { @@ -179,11 +218,11 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D0030F8); + FrameInterpolation_RecordMatrixPop(someMatrix2); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); } gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); } - FrameInterpolation_RecordMatrixPop(someMatrix1); - FrameInterpolation_RecordMatrixPop(someMatrix2); } diff --git a/src/engine/Matrix.cpp b/src/engine/Matrix.cpp index 0104de47c..e46804ad5 100644 --- a/src/engine/Matrix.cpp +++ b/src/engine/Matrix.cpp @@ -14,6 +14,7 @@ void AddMatrix(std::vector& stack, Mat4 mtx, s32 flags) { stack.emplace_back(); // Convert to a fixed-point matrix + FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mtx, &stack.back()); guMtxF2L(mtx, &stack.back()); // Load the matrix From bca4e1c98b331fe250236b67f60563219ca10638 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Fri, 16 May 2025 23:48:23 -0600 Subject: [PATCH 16/85] Fix mistake --- src/actors/item_box/render.inc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/actors/item_box/render.inc.c b/src/actors/item_box/render.inc.c index 347b2f276..62408bfd5 100644 --- a/src/actors/item_box/render.inc.c +++ b/src/actors/item_box/render.inc.c @@ -209,7 +209,8 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { someVec1[0] = temp_f0_3; someVec1[1] = temp_f2; someVec1[2] = temp_f12; - FrameInterpolation_RecordMatrixPop(someMatrix2); + FrameInterpolation_RecordMatrixPush(someMatrix2); + add_translate_mat4_vec3f(someMatrix1, someMatrix2, someVec1); From 8667da55b90a2884b24da41b4633ef80ff77763d Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Sat, 17 May 2025 03:07:04 -0300 Subject: [PATCH 17/85] tag and fix item boxes --- src/actors/item_box/render.inc.c | 31 ++++++++++++++++--------------- src/engine/Matrix.cpp | 1 + 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/actors/item_box/render.inc.c b/src/actors/item_box/render.inc.c index 0d02c3979..81670381e 100644 --- a/src/actors/item_box/render.inc.c +++ b/src/actors/item_box/render.inc.c @@ -3,6 +3,8 @@ #include #include "port/interpolation/FrameInterpolation.h" +#define TAG_ITEM_ADDR(x) ((u32) 0x10000000 | (u32) x) + /** * @brief Renders the item box actor. * @@ -27,8 +29,8 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { f32 temp_f2_2; f32 someMultiplier; - FrameInterpolation_RecordMatrixPush(someMatrix1); - FrameInterpolation_RecordMatrixPush(someMatrix2); + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild(TAG_ITEM_ADDR(item_box), 0); temp_f0 = is_within_render_distance(camera->pos, item_box->pos, camera->rot[1], 0.0f, gCameraZoom[camera - camera1], 4000000.0f); @@ -78,18 +80,18 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); - if ((item_box->rot[1] < 0xAA1) && (item_box->rot[1] > 0)) { - gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); - } else if ((item_box->rot[1] >= 0x6AA5) && (item_box->rot[1] < 0x754E)) { - gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); - } else if ((item_box->rot[1] >= 0x38E1) && (item_box->rot[1] < 0x438A)) { - gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); - } else if ((item_box->rot[1] >= 0xC711) && (item_box->rot[1] < 0xD1BA)) { - gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); - } else { + // if ((item_box->rot[1] < 0xAA1) && (item_box->rot[1] > 0)) { + // gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // } else if ((item_box->rot[1] >= 0x6AA5) && (item_box->rot[1] < 0x754E)) { + // gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // } else if ((item_box->rot[1] >= 0x38E1) && (item_box->rot[1] < 0x438A)) { + // gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // } else if ((item_box->rot[1] >= 0xC711) && (item_box->rot[1] < 0xD1BA)) { + // gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // } else { gDPSetBlendMask(gDisplayListHead++, 0xFF); gDPSetRenderMode(gDisplayListHead++, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2); - } + // } gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); gSPDisplayList(gDisplayListHead++, D_0D003090); } else { @@ -183,7 +185,6 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); } - - FrameInterpolation_RecordMatrixPop(someMatrix1); - FrameInterpolation_RecordMatrixPop(someMatrix2); + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } diff --git a/src/engine/Matrix.cpp b/src/engine/Matrix.cpp index 0104de47c..0c0ce260f 100644 --- a/src/engine/Matrix.cpp +++ b/src/engine/Matrix.cpp @@ -13,6 +13,7 @@ void AddMatrix(std::vector& stack, Mat4 mtx, s32 flags) { // Push a new matrix to the stack stack.emplace_back(); + FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mtx, &stack.back()); // Convert to a fixed-point matrix guMtxF2L(mtx, &stack.back()); From 06cb8a7c29976177a2d718d1f488b31cb37fbffc Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Sat, 17 May 2025 03:30:45 -0300 Subject: [PATCH 18/85] tag fake item box and whatever func_800696CC is --- src/actors/fake_item_box/render.inc.c | 6 ++++++ src/actors/item_box/render.inc.c | 2 +- src/code_80057C60.c | 12 ++++++++++-- src/port/interpolation/FrameInterpolation.h | 5 +++++ 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/actors/fake_item_box/render.inc.c b/src/actors/fake_item_box/render.inc.c index 7d0dab71e..ac1621b4f 100644 --- a/src/actors/fake_item_box/render.inc.c +++ b/src/actors/fake_item_box/render.inc.c @@ -2,6 +2,7 @@ #include #include #include +#include "port/interpolation/FrameInterpolation.h" /** * @brief Renders the fake item box actor. @@ -24,6 +25,9 @@ void render_actor_fake_item_box(Camera* camera, struct FakeItemBox* fakeItemBox) f32 temp_f2_2; f32 someMultiplier; + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild(TAG_ITEM_ADDR(fakeItemBox), 0); + if (is_within_render_distance(camera->pos, fakeItemBox->pos, camera->rot[1], 2500.0f, gCameraZoom[camera - camera1], 1000000.0f) < 0 && CVarGetInteger("gNoCulling", 0) == 0) { @@ -163,4 +167,6 @@ void render_actor_fake_item_box(Camera* camera, struct FakeItemBox* fakeItemBox) gSPDisplayList(gDisplayListHead++, D_0D0030F8); gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); } + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } diff --git a/src/actors/item_box/render.inc.c b/src/actors/item_box/render.inc.c index 77cbfbd8f..8c2591295 100644 --- a/src/actors/item_box/render.inc.c +++ b/src/actors/item_box/render.inc.c @@ -3,7 +3,7 @@ #include #include "port/interpolation/FrameInterpolation.h" -#define TAG_ITEM_ADDR(x) ((u32) 0x10000000 | (u32) x) + /** * @brief Renders the item box actor. diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 24ce0abe7..f9d56af83 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -39,6 +39,7 @@ #include #include "port/Game.h" #include "engine/Matrix.h" +#include "port/interpolation/FrameInterpolation.h" //! @warning this macro is undef'd at the end of this file #define MAKE_RGB(r, g, b) (((r) << 0x10) | ((g) << 0x08) | (b << 0x00)) @@ -769,7 +770,7 @@ void render_object_for_player(s32 cameraId) { render_object_leaf_particle(cameraId); if (D_80165730 != 0) { - //render_balloons_grand_prix(cameraId); + // render_balloons_grand_prix(cameraId); } if (gModeSelection == BATTLE) { CM_DrawBattleBombKarts(cameraId); @@ -1632,7 +1633,7 @@ void update_object(void) { // update_ferries_smoke_particle(); // break; // } - //if (D_80165730 != 0) { + // if (D_80165730 != 0) { // func_80074EE8(); // Grand prix balloons //} func_80076F2C(); @@ -5737,6 +5738,10 @@ void func_800696CC(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3, f32 arg4) sp54[0] = 0; sp54[1] = player->unk_048[arg3]; sp54[2] = 0; + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("func_800696CC", TAG_OBJECT(arg2)); + func_800652D4(sp5C, sp54, player->size * arg4); gSPDisplayList(gDisplayListHead++, D_0D008D58); gDPSetTextureLUT(gDisplayListHead++, G_TT_NONE); @@ -5748,6 +5753,9 @@ void func_800696CC(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3, f32 arg4) gSPVertex(gDisplayListHead++, D_800E87C0, 4, 0); gSPDisplayList(gDisplayListHead++, D_0D008DA0); gMatrixEffectCount += 1; + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 87012f66b..5d3f9cb35 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -10,11 +10,16 @@ #include + + std::unordered_map FrameInterpolation_Interpolate(float step); extern "C" { #endif +#define TAG_ITEM_ADDR(x) ((u32) 0x10000000 | (u32) x) +#define TAG_OBJECT(x) ((u32) 0x40000000 | (u32) (x)) + void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate); void FrameInterpolation_StartRecord(void); From 6d57a3c4de3aef9dee4958f6ff05658beb83fd21 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Sat, 17 May 2025 03:32:45 -0300 Subject: [PATCH 19/85] these aren't needed --- src/actors/item_box/render.inc.c | 34 ++------------------------------ 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/src/actors/item_box/render.inc.c b/src/actors/item_box/render.inc.c index 8c2591295..8d6bdea19 100644 --- a/src/actors/item_box/render.inc.c +++ b/src/actors/item_box/render.inc.c @@ -3,8 +3,6 @@ #include #include "port/interpolation/FrameInterpolation.h" - - /** * @brief Renders the item box actor. * @@ -45,7 +43,6 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { someVec2[0] = item_box->pos[0]; someVec2[1] = item_box->resetDistance + 2.0f; someVec2[2] = item_box->pos[2]; - FrameInterpolation_RecordMatrixPush(someMatrix1); mtxf_pos_rotation_xyz(someMatrix1, someVec2, someRot); @@ -54,13 +51,10 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D002EE8); - FrameInterpolation_RecordMatrixPop(someMatrix1); someRot[1] = item_box->rot[1] * 2; someVec2[1] = item_box->pos[1]; - FrameInterpolation_RecordMatrixPush(someMatrix1); - mtxf_pos_rotation_xyz(someMatrix1, someVec2, someRot); if (!render_set_position(someMatrix1, 0)) { @@ -68,13 +62,8 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, itemBoxQuestionMarkModel); - FrameInterpolation_RecordMatrixPop(someMatrix1); - } if (item_box->state == 5) { - FrameInterpolation_RecordMatrixPush(someMatrix1); - - mtxf_pos_rotation_xyz(someMatrix1, item_box->pos, item_box->rot); if (!render_set_position(someMatrix1, 0)) { @@ -82,11 +71,8 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, itemBoxQuestionMarkModel); - FrameInterpolation_RecordMatrixPop(someMatrix1); - } if (item_box->state != 3) { - FrameInterpolation_RecordMatrixPush(someMatrix1); mtxf_pos_rotation_xyz(someMatrix1, item_box->pos, item_box->rot); @@ -105,19 +91,17 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { // } else if ((item_box->rot[1] >= 0xC711) && (item_box->rot[1] < 0xD1BA)) { // gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); // } else { - gDPSetBlendMask(gDisplayListHead++, 0xFF); - gDPSetRenderMode(gDisplayListHead++, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2); + gDPSetBlendMask(gDisplayListHead++, 0xFF); + gDPSetRenderMode(gDisplayListHead++, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2); // } gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); gSPDisplayList(gDisplayListHead++, D_0D003090); - FrameInterpolation_RecordMatrixPop(someMatrix1); } else { gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); gDPSetBlendMask(gDisplayListHead++, 0xFF); thing = item_box->someTimer; - FrameInterpolation_RecordMatrixPush(someMatrix2); mtxf_pos_rotation_xyz(someMatrix1, item_box->pos, item_box->rot); if (thing < 10.0f) { @@ -142,10 +126,6 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D003158); - FrameInterpolation_RecordMatrixPop(someMatrix2); - - FrameInterpolation_RecordMatrixPush(someMatrix2); - temp_f2_2 = 0.8f * thing; temp_f12 = 0.5f * thing; @@ -159,13 +139,11 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D0031B8); - FrameInterpolation_RecordMatrixPop(someMatrix2); temp_f0_2 = -0.5f * thing; someVec1[0] = temp_f2_2; someVec1[1] = 1.2f * thing; someVec1[2] = temp_f0_2; - FrameInterpolation_RecordMatrixPush(someMatrix2); add_translate_mat4_vec3f(someMatrix1, someMatrix2, someVec1); @@ -174,7 +152,6 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D003128); - FrameInterpolation_RecordMatrixPop(someMatrix2); if (!(item_box->someTimer & 1)) { gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); @@ -184,7 +161,6 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { someVec1[0] = 0.0f; someVec1[1] = 1.8f * thing; someVec1[2] = -1.0f * thing; - FrameInterpolation_RecordMatrixPush(someMatrix2); add_translate_mat4_vec3f(someMatrix1, someMatrix2, someVec1); @@ -193,13 +169,11 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D0031E8); - FrameInterpolation_RecordMatrixPop(someMatrix2); temp_f0_3 = -0.8f * thing; someVec1[0] = temp_f0_3; someVec1[1] = 0.6f * thing; someVec1[2] = temp_f0_2; - FrameInterpolation_RecordMatrixPush(someMatrix2); add_translate_mat4_vec3f(someMatrix1, someMatrix2, someVec1); @@ -208,13 +182,10 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D003188); - FrameInterpolation_RecordMatrixPop(someMatrix2); someVec1[0] = temp_f0_3; someVec1[1] = temp_f2; someVec1[2] = temp_f12; - FrameInterpolation_RecordMatrixPush(someMatrix2); - add_translate_mat4_vec3f(someMatrix1, someMatrix2, someVec1); @@ -223,7 +194,6 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { } gSPDisplayList(gDisplayListHead++, D_0D0030F8); - FrameInterpolation_RecordMatrixPop(someMatrix2); gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); } From 6c5249c5b1c756a680176c1db1f8a8487ed469a8 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Sat, 17 May 2025 03:46:09 -0300 Subject: [PATCH 20/85] tag karts --- src/actors/fake_item_box/render.inc.c | 2 +- src/actors/item_box/render.inc.c | 2 +- src/engine/Matrix.cpp | 1 - src/render_player.c | 12 +++++++----- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/actors/fake_item_box/render.inc.c b/src/actors/fake_item_box/render.inc.c index ac1621b4f..3292b64e2 100644 --- a/src/actors/fake_item_box/render.inc.c +++ b/src/actors/fake_item_box/render.inc.c @@ -26,7 +26,7 @@ void render_actor_fake_item_box(Camera* camera, struct FakeItemBox* fakeItemBox) f32 someMultiplier; // @port: Tag the transform. - FrameInterpolation_RecordOpenChild(TAG_ITEM_ADDR(fakeItemBox), 0); + FrameInterpolation_RecordOpenChild("Fake Item Box", TAG_ITEM_ADDR(fakeItemBox)); if (is_within_render_distance(camera->pos, fakeItemBox->pos, camera->rot[1], 2500.0f, gCameraZoom[camera - camera1], 1000000.0f) < 0 && diff --git a/src/actors/item_box/render.inc.c b/src/actors/item_box/render.inc.c index 8d6bdea19..12cc17497 100644 --- a/src/actors/item_box/render.inc.c +++ b/src/actors/item_box/render.inc.c @@ -28,7 +28,7 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) { f32 someMultiplier; // @port: Tag the transform. - FrameInterpolation_RecordOpenChild(TAG_ITEM_ADDR(item_box), 0); + FrameInterpolation_RecordOpenChild("ItemBox", TAG_ITEM_ADDR(item_box)); temp_f0 = is_within_render_distance(camera->pos, item_box->pos, camera->rot[1], 0.0f, gCameraZoom[camera - camera1], 4000000.0f); diff --git a/src/engine/Matrix.cpp b/src/engine/Matrix.cpp index 13f768ec2..e46804ad5 100644 --- a/src/engine/Matrix.cpp +++ b/src/engine/Matrix.cpp @@ -13,7 +13,6 @@ void AddMatrix(std::vector& stack, Mat4 mtx, s32 flags) { // Push a new matrix to the stack stack.emplace_back(); - FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mtx, &stack.back()); // Convert to a fixed-point matrix FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mtx, &stack.back()); guMtxF2L(mtx, &stack.back()); diff --git a/src/render_player.c b/src/render_player.c index 9267706db..85c04f5b9 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -32,6 +32,7 @@ #include #include "port/Game.h" #include "engine/Matrix.h" +#include "port/interpolation/FrameInterpolation.h" s8 gRenderingFramebufferByPlayer[] = { 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02 }; @@ -722,7 +723,7 @@ const char** wheelPtr[] = { donkeykong_kart_wheels, wario_kart_wheels, peach_kart_wheels, bowser_kart_wheels, }; -s32 D_800DDE74[] = { 96, 128, 192, 256, 288, 384, 512, 544, 576, 0, 0}; +s32 D_800DDE74[] = { 96, 128, 192, 256, 288, 384, 512, 544, 576, 0, 0 }; void render_players_on_screen_two(void) { gPlayersToRenderCount = 0; @@ -1616,9 +1617,6 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) { s16 temp_v1; s16 thing; - FrameInterpolation_RecordMatrixPush(mtx); - - if (player->unk_044 & 0x2000) { sp14C[0] = 0; sp14C[1] = player->unk_048[screenId]; @@ -1674,6 +1672,9 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) { mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size); // convert_to_fixed_point_matrix(&gGfxPool->mtxKart[playerId + (screenId * 8)], mtx); + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Player", playerId | screenId << 8); + if ((player->effects & BOO_EFFECT) == BOO_EFFECT) { if (screenId == playerId) { AddKartMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -1747,7 +1748,8 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) { gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); - FrameInterpolation_RecordMatrixPop(mtx); + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } void render_ghost(Player* player, s8 playerId, s8 screenId, s8 arg3) { From 168390f3d7faadf270c629ef281d6dd36dcbbd81 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Sat, 17 May 2025 01:49:49 -0500 Subject: [PATCH 21/85] Slightly better falling rocks(still needs work) --- src/actors/falling_rock/render.inc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/actors/falling_rock/render.inc.c b/src/actors/falling_rock/render.inc.c index c46fceaf3..54f85bf06 100644 --- a/src/actors/falling_rock/render.inc.c +++ b/src/actors/falling_rock/render.inc.c @@ -17,6 +17,9 @@ void render_actor_falling_rock(Camera* camera, struct FallingRock* rock) { f32 height; UNUSED s32 pad[4]; + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("rock", TAG_ITEM_ADDR(rock)); //Not working properly just yet + if (rock->respawnTimer != 0) { return; } @@ -49,17 +52,15 @@ void render_actor_falling_rock(Camera* camera, struct FallingRock* rock) { return; } gSPDisplayList(gDisplayListHead++, d_course_choco_mountain_dl_6F88); - FrameInterpolation_RecordMatrixPop(mtx); - + FrameInterpolation_RecordMatrixPop(mtx); } } - FrameInterpolation_RecordMatrixPush(mtx); mtxf_pos_rotation_xyz(mtx, rock->pos, rock->rot); if (render_set_position(mtx, 0) == 0) { return; } gSPDisplayList(gDisplayListHead++, d_course_choco_mountain_dl_falling_rock); - FrameInterpolation_RecordMatrixPop(mtx); + FrameInterpolation_RecordCloseChild(); } From 1c83a7538b283f2d46a73b0391692369f1431b7c Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Sat, 17 May 2025 03:50:17 -0300 Subject: [PATCH 22/85] Tag Smoke and Dust --- src/code_80057C60.c | 6 ++++++ src/port/interpolation/FrameInterpolation.h | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index f9d56af83..840ea88c4 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -6574,6 +6574,10 @@ void func_8006D474(Player* player, s8 playerId, s8 screenId) { s16 var_s2; if ((player->unk_002 & (8 << (screenId * 4))) == (8 << (screenId * 4))) { for (var_s2 = 0; var_s2 < 10; var_s2++) { + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild( + "SmokeDust", TAG_SMOKE_DUST(((u32) player->unk_258[var_s2].unk_012 << 8) + (playerId << 16) + var_s2)); + switch (player->unk_258[var_s2].unk_012) { case 1: if (gActiveScreenMode == SCREEN_MODE_3P_4P_SPLITSCREEN) { @@ -6694,6 +6698,8 @@ void func_8006D474(Player* player, s8 playerId, s8 screenId) { } break; } + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } if ((gModeSelection == BATTLE) && (player->unk_002 & (2 << (screenId * 4)))) { diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 5d3f9cb35..016dc691a 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -17,8 +17,10 @@ std::unordered_map FrameInterpolation_Interpolate(float step); extern "C" { #endif -#define TAG_ITEM_ADDR(x) ((u32) 0x10000000 | (u32) x) -#define TAG_OBJECT(x) ((u32) 0x40000000 | (u32) (x)) +#define TAG_ITEM_ADDR(x) ((u32) 0x10000000 | (u32)x) +#define TAG_SMOKE_DUST(x) ((u32) 0x20000000 | (u32) (x)) +#define TAG_LETTER(x) ((u32)0x30000000 | (u32) (x)) +#define TAG_OBJECT(x) ((u32)0x40000000 | (u32)(x)) void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate); From 9cb954a2b025d2b3de0c7c74ae19077a1c80779f Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Sat, 17 May 2025 01:51:20 -0500 Subject: [PATCH 23/85] Removed unneeded code from falling_rock --- src/actors/falling_rock/render.inc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/actors/falling_rock/render.inc.c b/src/actors/falling_rock/render.inc.c index 54f85bf06..cc6f0592b 100644 --- a/src/actors/falling_rock/render.inc.c +++ b/src/actors/falling_rock/render.inc.c @@ -45,14 +45,12 @@ void render_actor_falling_rock(Camera* camera, struct FallingRock* rock) { sp98[1] = 0; sp98[2] = 0; sp8C[1] = height + 2.0f; - FrameInterpolation_RecordMatrixPush(mtx); mtxf_pos_rotation_xyz(mtx, sp8C, sp98); if (render_set_position(mtx, 0) == 0) { return; } gSPDisplayList(gDisplayListHead++, d_course_choco_mountain_dl_6F88); - FrameInterpolation_RecordMatrixPop(mtx); } } From 19d29604c094450a3a62f334db5b335322fd4b44 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Sat, 17 May 2025 03:54:53 -0300 Subject: [PATCH 24/85] tag whatever func_80051ABC is --- src/render_objects.c | 47 ++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/render_objects.c b/src/render_objects.c index cd9d8bf76..b2de13f7c 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -46,6 +46,8 @@ #include "engine/courses/Course.h" #include "engine/Matrix.h" +#include "port/interpolation/FrameInterpolation.h" + Lights1 D_800E45C0[] = { gdSPDefLights1(100, 0, 0, 100, 0, 0, 0, -120, 0), gdSPDefLights1(100, 100, 0, 255, 255, 0, 0, -120, 0), @@ -1679,7 +1681,7 @@ void render_texture_rectangle_wide_left(s32 x, s32 y, s32 width, s32 height, s32 if (gPlayerCount == 3) { // Center item in area of screen s32 center = (s32) ((OTRGetDimensionFromLeftEdge(SCREEN_WIDTH) - SCREEN_WIDTH) / 2) + - ((SCREEN_WIDTH / 4) + (SCREEN_WIDTH / 2)); + ((SCREEN_WIDTH / 4) + (SCREEN_WIDTH / 2)); s32 coordX = (s32) (center - (width / 2)) << 2; s32 coordX2 = (s32) (center + (width / 2)) << 2; gSPWideTextureRectangle(gDisplayListHead++, coordX, yl, coordX2, yh2, G_TX_RENDERTILE, arg4 << 5, @@ -2682,23 +2684,25 @@ void func_8004EB38(s32 playerId) { } if ((u8) temp_s0->unk_7E != 0) { func_8004C9D8_wide((s32) temp_s0->lapAfterImage1X, temp_s0->lapY + 3, 0x00000080, (u8*) common_texture_hud_lap, - 0x00000020, 8, 0x00000020, 8); + 0x00000020, 8, 0x00000020, 8); func_8004C9D8_wide(temp_s0->lapAfterImage1X + 0x1C, (s32) temp_s0->lapY, 0x00000080, - (u8*) gHudLapTextures[temp_s0->alsoLapCount], 0x00000020, 0x00000010, 0x00000020, 0x00000010); + (u8*) gHudLapTextures[temp_s0->alsoLapCount], 0x00000020, 0x00000010, 0x00000020, + 0x00000010); } if ((u8) temp_s0->unk_7F != 0) { func_8004C9D8_wide((s32) temp_s0->lapAfterImage2X, temp_s0->lapY + 3, 0x00000050, (u8*) common_texture_hud_lap, - 0x00000020, 8, 0x00000020, 8); + 0x00000020, 8, 0x00000020, 8); func_8004C9D8_wide(temp_s0->lapAfterImage2X + 0x1C, (s32) temp_s0->lapY, 0x00000050, - (u8*) gHudLapTextures[temp_s0->alsoLapCount], 0x00000020, 0x00000010, 0x00000020, 0x00000010); + (u8*) gHudLapTextures[temp_s0->alsoLapCount], 0x00000020, 0x00000010, 0x00000020, + 0x00000010); } } void func_8004ED40(s32 arg0) { func_8004A2F4(playerHUD[arg0].speedometerX, playerHUD[arg0].speedometerY, 0U, 1.0f, // RGBA - CM_GetProps()->Minimap.Colour.r, CM_GetProps()->Minimap.Colour.g, CM_GetProps()->Minimap.Colour.b, 0xFF, - LOAD_ASSET(common_texture_speedometer), LOAD_ASSET(D_0D0064B0), 64, 96, 64, 48); + CM_GetProps()->Minimap.Colour.r, CM_GetProps()->Minimap.Colour.g, CM_GetProps()->Minimap.Colour.b, + 0xFF, LOAD_ASSET(common_texture_speedometer), LOAD_ASSET(D_0D0064B0), 64, 96, 64, 48); func_8004A258(D_8018CFEC, D_8018CFF4, D_8016579E, 1.0f, common_texture_speedometer_needle, D_0D005FF0, 0x40, 0x20, 0x40, 0x20); } @@ -2708,14 +2712,14 @@ void func_8004EE54(s32 playerId) { if (gIsMirrorMode != 0) { func_8004D4E8(CM_GetProps()->Minimap.Pos[playerId].X, CM_GetProps()->Minimap.Pos[playerId].Y, (u8*) D_8018D240, // RGBA - CM_GetProps()->Minimap.Colour.r, CM_GetProps()->Minimap.Colour.g, CM_GetProps()->Minimap.Colour.b, 0xFF, - CM_GetProps()->Minimap.Width, CM_GetProps()->Minimap.Height, CM_GetProps()->Minimap.Width, + CM_GetProps()->Minimap.Colour.r, CM_GetProps()->Minimap.Colour.g, CM_GetProps()->Minimap.Colour.b, + 0xFF, CM_GetProps()->Minimap.Width, CM_GetProps()->Minimap.Height, CM_GetProps()->Minimap.Width, CM_GetProps()->Minimap.Height); } else { func_8004D37C(CM_GetProps()->Minimap.Pos[playerId].X, CM_GetProps()->Minimap.Pos[playerId].Y, (u8*) D_8018D240, // RGBA - CM_GetProps()->Minimap.Colour.r, CM_GetProps()->Minimap.Colour.g, CM_GetProps()->Minimap.Colour.b, 0xFF, - CM_GetProps()->Minimap.Width, CM_GetProps()->Minimap.Height, CM_GetProps()->Minimap.Width, + CM_GetProps()->Minimap.Colour.r, CM_GetProps()->Minimap.Colour.g, CM_GetProps()->Minimap.Colour.b, + 0xFF, CM_GetProps()->Minimap.Width, CM_GetProps()->Minimap.Height, CM_GetProps()->Minimap.Width, CM_GetProps()->Minimap.Height); } } @@ -2745,8 +2749,10 @@ void set_minimap_finishline_position(s32 playerId) { } // minimap center pos - minimap left edge + offset - var_f2 = (center - (CM_GetProps()->Minimap.Width / 2)) + CM_GetProps()->Minimap.PlayerX; // (center - (gMinimapWidth / 2)) + gMinimapPlayerX; - var_f0 = (CM_GetProps()->Minimap.Pos[playerId].Y - (CM_GetProps()->Minimap.Height / 2)) + CM_GetProps()->Minimap.PlayerY; // (gMinimapY[arg0] - (gMinimapHeight / 2)) + gMinimapPlayerY + var_f2 = (center - (CM_GetProps()->Minimap.Width / 2)) + + CM_GetProps()->Minimap.PlayerX; // (center - (gMinimapWidth / 2)) + gMinimapPlayerX; + var_f0 = (CM_GetProps()->Minimap.Pos[playerId].Y - (CM_GetProps()->Minimap.Height / 2)) + + CM_GetProps()->Minimap.PlayerY; // (gMinimapY[arg0] - (gMinimapHeight / 2)) + gMinimapPlayerY var_f2 += CM_GetProps()->Minimap.FinishlineX; var_f0 += CM_GetProps()->Minimap.FinishlineY; @@ -2780,7 +2786,8 @@ void func_8004F168(s32 arg0, s32 playerId, s32 characterId) { } temp_a0 = (center - (CM_GetProps()->Minimap.Width / 2)) + CM_GetProps()->Minimap.PlayerX + (s16) (thing0); - temp_a1 = (CM_GetProps()->Minimap.Pos[arg0].Y - (CM_GetProps()->Minimap.Height / 2)) + CM_GetProps()->Minimap.PlayerY + (s16) (thing1); + temp_a1 = (CM_GetProps()->Minimap.Pos[arg0].Y - (CM_GetProps()->Minimap.Height / 2)) + + CM_GetProps()->Minimap.PlayerY + (s16) (thing1); if (characterId != 8) { if ((gGPCurrentRaceRankByPlayerId[playerId] == 0) && (gModeSelection != 3) && (gModeSelection != 1)) { #if EXPLICIT_AND == 1 @@ -3465,7 +3472,14 @@ void func_80051ABC(s16 arg0, s32 arg1) { for (var_s0 = 0; var_s0 < D_8018D1F0; var_s0++) { objectIndex = D_8018CC80[arg1 + var_s0]; object = &gObjectList[objectIndex]; + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("func_80051ABC", TAG_OBJECT(object)); + func_800518F8(objectIndex, object->unk_09C, arg0 - object->unk_09E); + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } } @@ -4019,8 +4033,8 @@ void func_8005669C(s32 objectIndex, UNUSED s32 arg1, s32 arg2) { gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); } +Mat4 mtx; void func_800568A0(s32 objectIndex, s32 playerId) { - Mat4 mtx; Player* player; player = &gPlayerOne[playerId]; @@ -4040,13 +4054,12 @@ void func_800569F4(s32 playerIndex) { CM_DisplayBattleBombKart(playerIndex, 0); } - void func_80056A40(s32 playerIndex, s32 arg1) { CM_DisplayBattleBombKart(playerIndex, arg1); } void func_80056A94(s32 playerIndex) { - //func_80072428(gIndexObjectBombKart[playerIndex]); + // func_80072428(gIndexObjectBombKart[playerIndex]); CM_DisplayBattleBombKart(playerIndex, 0); } From 8b19fd8341e676651610887616185b254af38df9 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Sat, 17 May 2025 04:18:18 -0300 Subject: [PATCH 25/85] add missing rotate x coord --- src/port/interpolation/FrameInterpolation.cpp | 2 +- src/racing/math_util.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index a674c1ff2..4a6725cbe 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -530,7 +530,7 @@ void FrameInterpolation_RecordMarker(const char* file, int line) { if (!is_recording) return; - // append(Op::Marker).marker = { file, line }; + append(Op::Marker).marker = { file, line }; } void FrameInterpolation_RecordMatrixPop(Mat4* matrix) { diff --git a/src/racing/math_util.c b/src/racing/math_util.c index 457975ebb..1fb975048 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -333,6 +333,7 @@ void func_802B5794(Mat4 mtx, Vec3f from, Vec3f to) { // create a rotation matrix around the x axis void mtxf_rotate_x(Mat4 mat, s16 angle) { + FrameInterpolation_RecordMatrixRotate1Coord(&mat, 0, angle); f32 sin_theta = sins(angle); f32 cos_theta = coss(angle); From 860539a81c80c2734720d67b1cec581a91e3f87f Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Sat, 17 May 2025 02:54:36 -0500 Subject: [PATCH 26/85] GrandPrixBallon/kart shadow --- src/engine/objects/GrandPrixBalloons.cpp | 5 +++++ src/render_player.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/engine/objects/GrandPrixBalloons.cpp b/src/engine/objects/GrandPrixBalloons.cpp index 819bde1c6..bf55465b6 100644 --- a/src/engine/objects/GrandPrixBalloons.cpp +++ b/src/engine/objects/GrandPrixBalloons.cpp @@ -12,6 +12,7 @@ extern "C" { #include "math_util.h" #include "math_util_2.h" #include "menus.h" +#include "port/interpolation/FrameInterpolation.h" } size_t OGrandPrixBalloons::_count = 0; @@ -105,6 +106,8 @@ void OGrandPrixBalloons::func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 ver Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog); + FrameInterpolation_RecordOpenChild("Balloon", TAG_ITEM_ADDR(object)); //Not working properly just yet + if (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX) { object = &gObjectList[objectIndex]; D_80183E80[2] = (s16) (object->unk_084[6] + 0x8000); @@ -115,6 +118,8 @@ void OGrandPrixBalloons::func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 ver gSPVertex(gDisplayListHead++, (uintptr_t)&vtx[vertexIndex], 4, 0); gSPDisplayList(gDisplayListHead++, (Gfx*)common_rectangle_display); } + + FrameInterpolation_RecordCloseChild(); } void OGrandPrixBalloons::func_80074924(s32 objectIndex) { diff --git a/src/render_player.c b/src/render_player.c index 85c04f5b9..8efa7bcbe 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -1484,6 +1484,7 @@ void render_player_shadow(Player* player, s8 playerId, s8 screenId) { UNUSED Vec3f pad2; f32 var_f2; + FrameInterpolation_RecordOpenChild("Kart Shadow", TAG_ITEM_ADDR(player)); temp_t9 = (u16) (player->unk_048[screenId] + player->rotation[1] + player->unk_0C0) / 128; // << 7) & 0xFFFF; spC0 = -player->rotation[1] - player->unk_0C0; @@ -1547,6 +1548,7 @@ void render_player_shadow(Player* player, s8 playerId, s8 screenId) { gSPDisplayList(gDisplayListHead++, common_square_plain_render); gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); + FrameInterpolation_RecordCloseChild(); } void render_player_shadow_credits(Player* player, s8 playerId, s8 arg2) { From c7f67eae75d03c8e05fc31e29a0a982ea82d77d2 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Sat, 17 May 2025 03:06:29 -0500 Subject: [PATCH 27/85] Green shells tag, and added comments I neglected to add before. --- src/actors/falling_rock/render.inc.c | 3 ++- src/engine/objects/GrandPrixBalloons.cpp | 2 ++ src/racing/actors.c | 7 +++++++ src/render_player.c | 3 +++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/actors/falling_rock/render.inc.c b/src/actors/falling_rock/render.inc.c index cc6f0592b..9d50fd41c 100644 --- a/src/actors/falling_rock/render.inc.c +++ b/src/actors/falling_rock/render.inc.c @@ -59,6 +59,7 @@ void render_actor_falling_rock(Camera* camera, struct FallingRock* rock) { return; } gSPDisplayList(gDisplayListHead++, d_course_choco_mountain_dl_falling_rock); - FrameInterpolation_RecordCloseChild(); + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } diff --git a/src/engine/objects/GrandPrixBalloons.cpp b/src/engine/objects/GrandPrixBalloons.cpp index bf55465b6..e3d99f934 100644 --- a/src/engine/objects/GrandPrixBalloons.cpp +++ b/src/engine/objects/GrandPrixBalloons.cpp @@ -106,6 +106,7 @@ void OGrandPrixBalloons::func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 ver Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog); + // @port: Tag the transform. FrameInterpolation_RecordOpenChild("Balloon", TAG_ITEM_ADDR(object)); //Not working properly just yet if (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX) { @@ -119,6 +120,7 @@ void OGrandPrixBalloons::func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 ver gSPDisplayList(gDisplayListHead++, (Gfx*)common_rectangle_display); } + // @port Pop the transform id. FrameInterpolation_RecordCloseChild(); } diff --git a/src/racing/actors.c b/src/racing/actors.c index 9344bd3eb..ba9ae9307 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -34,6 +34,7 @@ #include #include #include "port/Game.h" +#include "port/interpolation/FrameInterpolation.h" // Appears to be textures // or tluts @@ -707,6 +708,9 @@ void render_actor_shell(Camera* camera, Mat4 matrix, struct ShellActor* shell) { //! @todo Is this making the shell spin? // Is it doing this by modifying a an address? uintptr_t phi_t3; + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Shell", TAG_ITEM_ADDR(shell)); f32 temp_f0 = is_within_render_distance(camera->pos, shell->pos, camera->rot[1], 0, gCameraZoom[camera - camera1], 490000.0f); @@ -749,6 +753,9 @@ void render_actor_shell(Camera* camera, Mat4 matrix, struct ShellActor* shell) { } else { gSPDisplayList(gDisplayListHead++, D_0D005368); } + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } UNUSED s16 D_802B8808[] = { 0x0014, 0x0028, 0x0000, 0x0000 }; diff --git a/src/render_player.c b/src/render_player.c index 8efa7bcbe..65545ebd7 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -1484,6 +1484,7 @@ void render_player_shadow(Player* player, s8 playerId, s8 screenId) { UNUSED Vec3f pad2; f32 var_f2; + // @port: Tag the transform. FrameInterpolation_RecordOpenChild("Kart Shadow", TAG_ITEM_ADDR(player)); temp_t9 = (u16) (player->unk_048[screenId] + player->rotation[1] + player->unk_0C0) / 128; // << 7) & 0xFFFF; spC0 = -player->rotation[1] - player->unk_0C0; @@ -1548,6 +1549,8 @@ void render_player_shadow(Player* player, s8 playerId, s8 screenId) { gSPDisplayList(gDisplayListHead++, common_square_plain_render); gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); + + // @port Pop the transform id. FrameInterpolation_RecordCloseChild(); } From af63558bac2647729af472f318958828289e8b17 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Sat, 17 May 2025 13:11:28 -0300 Subject: [PATCH 28/85] doesn't compile on win --- src/engine/objects/GrandPrixBalloons.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/engine/objects/GrandPrixBalloons.cpp b/src/engine/objects/GrandPrixBalloons.cpp index e3d99f934..eb6b311de 100644 --- a/src/engine/objects/GrandPrixBalloons.cpp +++ b/src/engine/objects/GrandPrixBalloons.cpp @@ -12,7 +12,8 @@ extern "C" { #include "math_util.h" #include "math_util_2.h" #include "menus.h" -#include "port/interpolation/FrameInterpolation.h" +// Doesn't seem to compile on Windows +// #include "port/interpolation/FrameInterpolation.h" } size_t OGrandPrixBalloons::_count = 0; @@ -107,7 +108,7 @@ void OGrandPrixBalloons::func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 ver Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog); // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("Balloon", TAG_ITEM_ADDR(object)); //Not working properly just yet + // FrameInterpolation_RecordOpenChild("Balloon", TAG_ITEM_ADDR(object)); //Not working properly just yet if (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX) { object = &gObjectList[objectIndex]; @@ -121,7 +122,7 @@ void OGrandPrixBalloons::func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 ver } // @port Pop the transform id. - FrameInterpolation_RecordCloseChild(); + // FrameInterpolation_RecordCloseChild(); } void OGrandPrixBalloons::func_80074924(s32 objectIndex) { From b57f562c8aa7510c933b8bfe5a3510f2e0b1f513 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sat, 17 May 2025 13:02:36 -0600 Subject: [PATCH 29/85] Fixes --- src/engine/objects/Lakitu.cpp | 6 +++++- src/math_util_2.c | 1 - src/math_util_2.h | 3 --- src/port/interpolation/FrameInterpolation.cpp | 2 +- src/port/interpolation/FrameInterpolation.h | 1 - src/racing/actors.c | 5 +++++ 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/engine/objects/Lakitu.cpp b/src/engine/objects/Lakitu.cpp index 12ca2d7db..92f164e95 100644 --- a/src/engine/objects/Lakitu.cpp +++ b/src/engine/objects/Lakitu.cpp @@ -2,6 +2,7 @@ #include #include "Lakitu.h" #include +#include "port/interpolation/FrameInterpolation.h" #include "port/Game.h" @@ -10,6 +11,7 @@ extern "C" { #include "main.h" #include "actors.h" #include "math_util.h" +#include "math_util_2.h" #include "sounds.h" #include "update_objects.h" #include "render_player.h" @@ -21,7 +23,6 @@ extern "C" { #include "code_80057C60.h" #include "defines.h" #include "code_80005FD0.h" -#include "math_util_2.h" #include "collision.h" #include "assets/bowsers_castle_data.h" #include "ceremony_and_credits.h" @@ -95,6 +96,8 @@ void OLakitu::Draw(s32 cameraId) { s32 objectIndex; Object* object; + FrameInterpolation_RecordOpenChild("Lakitu",(u32) 3939848893); + objectIndex = gIndexLakituList[cameraId]; camera = &camera1[cameraId]; if (is_obj_flag_status_active(objectIndex, 0x00000010) != 0) { @@ -126,6 +129,7 @@ void OLakitu::Draw(s32 cameraId) { } } } + FrameInterpolation_RecordCloseChild(); } void OLakitu::func_80079114(s32 objectIndex, s32 playerId, s32 arg2) { diff --git a/src/math_util_2.c b/src/math_util_2.c index 067b34b21..091bf9215 100644 --- a/src/math_util_2.c +++ b/src/math_util_2.c @@ -603,7 +603,6 @@ void func_80041D24(void) { } void guOrtho(Mtx*, f32, f32, f32, f32, f32, f32, f32); /* extern */ -extern s8 D_801658FE; void func_80041D34(void) { guOrtho(&D_80183D60, 0.0f, 320.0f, 240.0f, 0.0f, -1.0f, 1.0f, 1.0f); diff --git a/src/math_util_2.h b/src/math_util_2.h index c616a1440..604e28c02 100644 --- a/src/math_util_2.h +++ b/src/math_util_2.h @@ -84,7 +84,4 @@ void rsp_set_matrix_transformation_inverted_x_y_orientation(Vec3f, Vec3su, f32); void rsp_set_matrix_transl_rot_scale(Vec3f, Vec3f, f32); void rsp_set_matrix_gObjectList(s32); -/* This is where I'd put my static data, if I had any */ -extern s8 D_801658FE; - #endif // MATH_UTIL_2_H diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index 4a6725cbe..9df591f0c 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -6,7 +6,7 @@ #include #include "port/Engine.h" #include -#include +#include "math_util_2.h" #include "FrameInterpolation.h" #include "matrix.h" diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 016dc691a..d2a9a5fe3 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -4,7 +4,6 @@ // #include "sf64math.h" #include #include -#include #ifdef __cplusplus diff --git a/src/racing/actors.c b/src/racing/actors.c index ba9ae9307..266bd8d4b 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -2444,11 +2444,15 @@ void render_course_actors(struct UnkStruct_800DC5EC* arg0) { if (actor->flags == 0) { continue; } + + FrameInterpolation_RecordOpenChild(actor, i); + switch (actor->type) { default: // Draw custom actor CM_DrawActors(D_800DC5EC->camera, actor); break; case ACTOR_TREE_MARIO_RACEWAY: + render_actor_tree_mario_raceway(camera, sBillBoardMtx, actor); break; case ACTOR_TREE_YOSHI_VALLEY: @@ -2548,6 +2552,7 @@ void render_course_actors(struct UnkStruct_800DC5EC* arg0) { render_actor_yoshi_egg(camera, sBillBoardMtx, (struct YoshiValleyEgg*) actor, pathCounter); break; } + FrameInterpolation_RecordCloseChild(actor, i); } if (GetCourse() == GetMooMooFarm()) { render_cows(camera, sBillBoardMtx); From ea4117fb9f423d6c520ab7be78bf2337c391b1b9 Mon Sep 17 00:00:00 2001 From: KiritoDv Date: Sat, 17 May 2025 13:36:39 -0600 Subject: [PATCH 30/85] Disabled camera interpolation --- src/camera.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/camera.c b/src/camera.c index 953f1f96b..07003f07d 100644 --- a/src/camera.c +++ b/src/camera.c @@ -18,6 +18,7 @@ #include "spawn_players.h" #include "enhancements/freecam/freecam_engine.h" #include "enhancements/freecam/freecam.h" +#include "port/interpolation/FrameInterpolation.h" #include "engine/GameAPI.h" #include "port/Game.h" @@ -983,6 +984,7 @@ void func_8001EE98(Player* player, Camera* camera, s8 index) { break; } if (gIsGamePaused == 0) { + FrameInterpolation_ShouldInterpolateFrame(false); switch (D_80152300[cameraIndex]) { case 3: func_8001A588(&D_80152300[cameraIndex], camera, player, index, cameraIndex); @@ -1006,6 +1008,7 @@ void func_8001EE98(Player* player, Camera* camera, s8 index) { func_8001EA0C(camera, player, index); break; } + FrameInterpolation_ShouldInterpolateFrame(true); } } From 749dad19d918360c7bd8e15c75e070fae6b2a142 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sat, 17 May 2025 13:38:22 -0600 Subject: [PATCH 31/85] Balloons fixes --- src/engine/objects/GrandPrixBalloons.cpp | 14 ++++++++------ src/racing/actors.c | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/engine/objects/GrandPrixBalloons.cpp b/src/engine/objects/GrandPrixBalloons.cpp index eb6b311de..253c68464 100644 --- a/src/engine/objects/GrandPrixBalloons.cpp +++ b/src/engine/objects/GrandPrixBalloons.cpp @@ -3,6 +3,7 @@ #include "port/Game.h" #include "assets/other_textures.h" #include "assets/common_data.h" +#include "port/interpolation/FrameInterpolation.h" extern "C" { #include "update_objects.h" @@ -12,8 +13,6 @@ extern "C" { #include "math_util.h" #include "math_util_2.h" #include "menus.h" -// Doesn't seem to compile on Windows -// #include "port/interpolation/FrameInterpolation.h" } size_t OGrandPrixBalloons::_count = 0; @@ -36,6 +35,7 @@ OGrandPrixBalloons::OGrandPrixBalloons(const FVector& pos) { find_unused_obj_index(&gObjectParticle3[i]); init_object(gObjectParticle3[i], 0); } + // printf("primAlfa %d\n", object->primAlpha); } void OGrandPrixBalloons::Tick() { @@ -108,10 +108,10 @@ void OGrandPrixBalloons::func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 ver Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog); // @port: Tag the transform. - // FrameInterpolation_RecordOpenChild("Balloon", TAG_ITEM_ADDR(object)); //Not working properly just yet - + size_t i = 0; if (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX) { object = &gObjectList[objectIndex]; + FrameInterpolation_RecordOpenChild("Balloon", TAG_ITEM_ADDR((objectIndex << 8) + i++)); //Not working properly just yet D_80183E80[2] = (s16) (object->unk_084[6] + 0x8000); rsp_set_matrix_transformation(object->pos, (u16*) D_80183E80, object->sizeScaling); set_color_render((s32) object->unk_084[0], (s32) object->unk_084[1], (s32) object->unk_084[2], @@ -119,10 +119,10 @@ void OGrandPrixBalloons::func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 ver (s32) object->primAlpha); gSPVertex(gDisplayListHead++, (uintptr_t)&vtx[vertexIndex], 4, 0); gSPDisplayList(gDisplayListHead++, (Gfx*)common_rectangle_display); + FrameInterpolation_RecordCloseChild(); } // @port Pop the transform id. - // FrameInterpolation_RecordCloseChild(); } void OGrandPrixBalloons::func_80074924(s32 objectIndex) { @@ -195,7 +195,9 @@ void OGrandPrixBalloons::func_80074924(s32 objectIndex) { void OGrandPrixBalloons::func_80074D94(s32 objectIndex) { if (gObjectList[objectIndex].unk_0AE == 1) { - if ((_numBalloons2 <= gObjectList[objectIndex].offset[1]) && + //! @warning this fades out the balloons. Original game uses _numBalloons3 here but they disappear before off-screen. + // So _numBalloons replaces it for now. + if ((_numBalloons <= gObjectList[objectIndex].offset[1]) && (s16_step_down_towards(&gObjectList[objectIndex].primAlpha, 0, 8) != 0)) { func_80086F60(objectIndex); } diff --git a/src/racing/actors.c b/src/racing/actors.c index 266bd8d4b..65c734be3 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -2552,7 +2552,7 @@ void render_course_actors(struct UnkStruct_800DC5EC* arg0) { render_actor_yoshi_egg(camera, sBillBoardMtx, (struct YoshiValleyEgg*) actor, pathCounter); break; } - FrameInterpolation_RecordCloseChild(actor, i); + FrameInterpolation_RecordCloseChild(); } if (GetCourse() == GetMooMooFarm()) { render_cows(camera, sBillBoardMtx); From 1229a69f2c90385eb10f4743554cda8a3fd990da Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Sat, 17 May 2025 18:00:34 -0300 Subject: [PATCH 32/85] progress --- src/port/interpolation/FrameInterpolation.cpp | 66 +++++++++++++++---- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index 9df591f0c..70a7ccf01 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -67,7 +67,8 @@ enum class Op { MatrixMtxFToMtx, MatrixToMtx, MatrixRotateAxis, - SkinMatrixMtxFToMtx + SkinMatrixMtxFToMtx, + SetTransformMatrix }; typedef pair label; @@ -160,6 +161,14 @@ union Data { u8 mode; } matrix_rotate_axis; + struct { + Mat4 dest; + Vec3f orientationVector; + Vec3f positionVector; + u16 rotationAngle; + f32 scaleFactor; + } set_transform_matrix_data; + struct { label key; size_t idx; @@ -330,11 +339,11 @@ struct InterpolateCtx { break; case Op::MatrixPush: - Matrix_Push((Matrix**)&gInterpolationMatrix); + Matrix_Push((Matrix**) &gInterpolationMatrix); break; case Op::MatrixPop: - Matrix_Pop((Matrix**)&gInterpolationMatrix); + Matrix_Pop((Matrix**) &gInterpolationMatrix); break; // Unused on SF64 @@ -366,9 +375,12 @@ struct InterpolateCtx { tempF[1] = lerp(old_op.matrix_pos_rot_xyz.pos.y, new_op.matrix_pos_rot_xyz.pos.y); tempF[2] = lerp(old_op.matrix_pos_rot_xyz.pos.z, new_op.matrix_pos_rot_xyz.pos.z); - tempS[0] = lerp(old_op.matrix_pos_rot_xyz.orientation.x, new_op.matrix_pos_rot_xyz.orientation.x); - tempS[1] = lerp(old_op.matrix_pos_rot_xyz.orientation.y, new_op.matrix_pos_rot_xyz.orientation.y); - tempS[2] = lerp(old_op.matrix_pos_rot_xyz.orientation.z, new_op.matrix_pos_rot_xyz.orientation.z); + tempS[0] = + lerp(old_op.matrix_pos_rot_xyz.orientation.x, new_op.matrix_pos_rot_xyz.orientation.x); + tempS[1] = + lerp(old_op.matrix_pos_rot_xyz.orientation.y, new_op.matrix_pos_rot_xyz.orientation.y); + tempS[2] = + lerp(old_op.matrix_pos_rot_xyz.orientation.z, new_op.matrix_pos_rot_xyz.orientation.z); mtxf_pos_rotation_xyz(*gInterpolationMatrix, tempF, tempS); break; @@ -382,7 +394,7 @@ struct InterpolateCtx { case Op::MatrixRotate1Coord: { s16 v = interpolate_angle(old_op.matrix_rotate_1_coord.value, - new_op.matrix_rotate_1_coord.value); + new_op.matrix_rotate_1_coord.value); switch (new_op.matrix_rotate_1_coord.coord) { case 0: mtxf_rotate_x(*gInterpolationMatrix, v); @@ -441,6 +453,30 @@ struct InterpolateCtx { // new_op.matrix_rotate_axis.mode); break; } + + case Op::SetTransformMatrix: { + /* + Mat4 dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle, + f32 scaleFactor + + set_transform_matrix_data + */ + interpolate_mtxf(&tmp_mtxf, (MtxF *)&old_op.set_transform_matrix_data.dest, (MtxF *)&new_op.set_transform_matrix_data.dest); + Vec3f orientationVectorTemp; + lerp_vec3f(&orientationVectorTemp, &old_op.set_transform_matrix_data.orientationVector, + &new_op.set_transform_matrix_data.orientationVector); + Vec3f positionVector; + lerp_vec3f(&orientationVectorTemp, &old_op.set_transform_matrix_data.positionVector, + &new_op.set_transform_matrix_data.positionVector); + + u16 rotationAngleTemp = lerp_s16(old_op.set_transform_matrix_data.rotationAngle, + new_op.set_transform_matrix_data.rotationAngle); + f32 scaleFactorTemp = lerp(old_op.set_transform_matrix_data.scaleFactor, new_op.set_transform_matrix_data.scaleFactor); + + set_transform_matrix(tmp_mtxf.mf, orientationVectorTemp, positionVector, rotationAngleTemp, scaleFactorTemp); + + break; + } } } } @@ -523,7 +559,7 @@ void FrameInterpolation_RecordMatrixPush(Mat4* matrix) { if (!is_recording) return; - append(Op::MatrixPush).matrix_ptr = { (Mat4**)matrix }; + append(Op::MatrixPush).matrix_ptr = { (Mat4**) matrix }; } void FrameInterpolation_RecordMarker(const char* file, int line) { @@ -536,7 +572,7 @@ void FrameInterpolation_RecordMarker(const char* file, int line) { void FrameInterpolation_RecordMatrixPop(Mat4* matrix) { if (!is_recording) return; - append(Op::MatrixPop).matrix_ptr = { (Mat4**)matrix }; + append(Op::MatrixPop).matrix_ptr = { (Mat4**) matrix }; } void FrameInterpolation_RecordMatrixPut(MtxF* src) { @@ -554,7 +590,7 @@ void FrameInterpolation_RecordMatrixMult(Mat4* matrix, MtxF* mf, u8 mode) { void FrameInterpolation_RecordMatrixTranslate(Mat4* matrix, Vec3f b) { if (!is_recording) return; - + append(Op::MatrixTranslate).matrix_translate = { matrix, *((Vec3fInterp*) &b) }; } @@ -567,12 +603,18 @@ void FrameInterpolation_RecordMatrixScale(Mat4* matrix, f32 x, f32 y, f32 z, u8 void FrameInterpolation_RecordMatrixMultVec3fNoTranslate(Mat4* matrix, Vec3f src, Vec3f dest) { if (!is_recording) return; - //append(Op::MatrixMultVec3fNoTranslate).matrix_vec_no_translate = { matrix, src, dest }; + // append(Op::MatrixMultVec3fNoTranslate).matrix_vec_no_translate = { matrix, src, dest }; +} + +void FrameInterpolation_Record_set_transform_matrix(Mat4 dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle, + f32 scaleFactor) { + if (!is_recording) + return; + append(Op::SetTransformMatrix).set_transform_matrix_data = { dest[0][0], orientationVector[0], positionVector[0], rotationAngle, scaleFactor}; } // Make a template for deref - void FrameInterpolation_RecordMatrixPosRotXYZ(Mat4 out, Vec3f pos, Vec3s orientation) { if (!is_recording) return; From 6bcd9897dc2571c6267d2dad84abaed63eb1e4c4 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sat, 17 May 2025 15:52:29 -0600 Subject: [PATCH 33/85] set_transform_matrix compiles --- src/math_util_2.c | 2 ++ src/port/interpolation/FrameInterpolation.cpp | 12 +++++++----- src/port/interpolation/FrameInterpolation.h | 3 +++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/math_util_2.c b/src/math_util_2.c index 091bf9215..174d9095e 100644 --- a/src/math_util_2.c +++ b/src/math_util_2.c @@ -919,6 +919,8 @@ void set_transform_matrix(Mat4 dest, Vec3f orientationVector, Vec3f positionVect Vec3f sp38; Vec3f sp2C; + FrameInterpolation_Record_set_transform_matrix(dest, orientationVector, positionVector, rotationAngle, scaleFactor); + vec3f_set_xyz(sp44, sins(rotationAngle), 0.0f, coss(rotationAngle)); vec3f_normalize(orientationVector); vec3f_cross_product(sp38, orientationVector, sp44); diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index 70a7ccf01..65de693a4 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -5,11 +5,13 @@ #include #include #include "port/Engine.h" -#include -#include "math_util_2.h" #include "FrameInterpolation.h" #include "matrix.h" +extern "C" { +#include "math_util.h" +#include "math_util_2.h" +} /* Frame interpolation. @@ -162,7 +164,7 @@ union Data { } matrix_rotate_axis; struct { - Mat4 dest; + Mat4* dest; Vec3f orientationVector; Vec3f positionVector; u16 rotationAngle; @@ -606,11 +608,11 @@ void FrameInterpolation_RecordMatrixMultVec3fNoTranslate(Mat4* matrix, Vec3f src // append(Op::MatrixMultVec3fNoTranslate).matrix_vec_no_translate = { matrix, src, dest }; } -void FrameInterpolation_Record_set_transform_matrix(Mat4 dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle, +void FrameInterpolation_Record_set_transform_matrix(Mat4* dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle, f32 scaleFactor) { if (!is_recording) return; - append(Op::SetTransformMatrix).set_transform_matrix_data = { dest[0][0], orientationVector[0], positionVector[0], rotationAngle, scaleFactor}; + append(Op::SetTransformMatrix).set_transform_matrix_data = { dest, orientationVector[0], positionVector[0], (f32)rotationAngle, scaleFactor}; } // Make a template for deref diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index d2a9a5fe3..a70f3e7b0 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -67,6 +67,9 @@ void FrameInterpolation_RecordSkinMatrixMtxFToMtx(MtxF* src, Mtx* dest); //void FrameInterpolation_RecordMatrixMultVec3fNoTranslate(Matrix* matrix, Vec3f src, Vec3f dest); +void FrameInterpolation_Record_set_transform_matrix(Mat4* dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle, + f32 scaleFactor); + #ifdef __cplusplus } #endif From 640b8976ee6c657733bd8fd706a37d1757be5ec0 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sat, 17 May 2025 16:23:57 -0600 Subject: [PATCH 34/85] Compile setTransformMatrix --- src/port/interpolation/FrameInterpolation.cpp | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index 65de693a4..14f391cc6 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -165,8 +165,8 @@ union Data { struct { Mat4* dest; - Vec3f orientationVector; - Vec3f positionVector; + Vec3f* orientationVector; + Vec3f* positionVector; u16 rotationAngle; f32 scaleFactor; } set_transform_matrix_data; @@ -457,25 +457,17 @@ struct InterpolateCtx { } case Op::SetTransformMatrix: { - /* - Mat4 dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle, - f32 scaleFactor + lerp_vec3f(&tmp_vec3f, &old_op.set_transform_matrix_data.orientationVector[0], + &new_op.set_transform_matrix_data.orientationVector[0]); - set_transform_matrix_data - */ - interpolate_mtxf(&tmp_mtxf, (MtxF *)&old_op.set_transform_matrix_data.dest, (MtxF *)&new_op.set_transform_matrix_data.dest); - Vec3f orientationVectorTemp; - lerp_vec3f(&orientationVectorTemp, &old_op.set_transform_matrix_data.orientationVector, - &new_op.set_transform_matrix_data.orientationVector); - Vec3f positionVector; - lerp_vec3f(&orientationVectorTemp, &old_op.set_transform_matrix_data.positionVector, - &new_op.set_transform_matrix_data.positionVector); + lerp_vec3f(&tmp_vec3f2, &old_op.set_transform_matrix_data.positionVector[0], + &new_op.set_transform_matrix_data.positionVector[0]); u16 rotationAngleTemp = lerp_s16(old_op.set_transform_matrix_data.rotationAngle, new_op.set_transform_matrix_data.rotationAngle); f32 scaleFactorTemp = lerp(old_op.set_transform_matrix_data.scaleFactor, new_op.set_transform_matrix_data.scaleFactor); - set_transform_matrix(tmp_mtxf.mf, orientationVectorTemp, positionVector, rotationAngleTemp, scaleFactorTemp); + set_transform_matrix(*gInterpolationMatrix, tmp_vec3f, tmp_vec3f2, rotationAngleTemp, scaleFactorTemp); break; } @@ -612,7 +604,7 @@ void FrameInterpolation_Record_set_transform_matrix(Mat4* dest, Vec3f orientatio f32 scaleFactor) { if (!is_recording) return; - append(Op::SetTransformMatrix).set_transform_matrix_data = { dest, orientationVector[0], positionVector[0], (f32)rotationAngle, scaleFactor}; + append(Op::SetTransformMatrix).set_transform_matrix_data = { dest, (Vec3f*)&orientationVector[0], (Vec3f*)&positionVector[0], rotationAngle, scaleFactor}; } // Make a template for deref From 08ec787e79199d255f1886c7f2a69d66041015f1 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sat, 17 May 2025 17:37:21 -0600 Subject: [PATCH 35/85] More transforms interp --- src/code_80057C60.c | 6 +- src/math_util_2.c | 45 ++++----- src/math_util_2.h | 3 +- src/port/interpolation/FrameInterpolation.cpp | 92 +++++++++++++++---- src/port/interpolation/FrameInterpolation.h | 8 +- src/racing/math_util.c | 51 +++------- src/racing/math_util.h | 1 - src/render_player.c | 24 ++--- src/render_player.h | 1 - 9 files changed, 127 insertions(+), 104 deletions(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 840ea88c4..32b24029b 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -4971,7 +4971,7 @@ void func_800652D4(Vec3f arg0, Vec3s arg1, f32 arg2) { Mat4 mtx; mtxf_translate_rotate(mtx, arg0, arg1); - mtxf_scale2(mtx, arg2); + mtxf_scale(mtx, arg2); // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx); // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -6067,7 +6067,7 @@ void render_battle_balloon(Player* player, s8 arg1, s16 arg2, s8 arg3) { sp12C[2] = D_8018D7D0[arg1][arg2] - (D_8018D860[arg1][arg2] * coss(temp_t1)) - ((D_8018D890[arg1][arg2] * 8) * sins(temp_t1)); mtxf_translate_rotate(mtx, sp134, sp12C); - mtxf_scale2(mtx, var_f20); + mtxf_scale(mtx, var_f20); // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], sp140); // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), @@ -6192,7 +6192,7 @@ void render_balloon(Vec3f arg0, f32 arg1, s16 arg2, s16 arg3) { spF4[1] = camera1->rot[1]; spF4[2] = arg2; mtxf_translate_rotate(mtx, spFC, spF4); - mtxf_scale2(mtx, arg1); + mtxf_scale(mtx, arg1); // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], sp108); // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/src/math_util_2.c b/src/math_util_2.c index 174d9095e..d9770eddb 100644 --- a/src/math_util_2.c +++ b/src/math_util_2.c @@ -807,27 +807,29 @@ UNUSED void func_8004252C(Mat4 arg0, u16 arg1, u16 arg2) { arg0[2][2] = sp28 * cos_theta_y; } -void mtxf_set_matrix_transformation(Mat4 transformMatrix, Vec3f translationVector, Vec3su rotationVector, - f32 scalingFactor) { - f32 sinX = sins(rotationVector[0]); - f32 cosX = coss(rotationVector[0]); - f32 sinY = sins(rotationVector[1]); - f32 cosY = coss(rotationVector[1]); - f32 sinZ = sins(rotationVector[2]); - f32 cosZ = coss(rotationVector[2]); +void mtxf_set_matrix_transformation(Mat4 transformMatrix, Vec3f location, Vec3su rotation, + f32 scale) { - transformMatrix[0][0] = ((cosY * cosZ) + (sinX * sinY * sinZ)) * scalingFactor; - transformMatrix[1][0] = ((-cosY * sinZ) + (sinX * sinY * cosZ)) * scalingFactor; - transformMatrix[2][0] = (cosX * sinY) * scalingFactor; - transformMatrix[3][0] = translationVector[0]; - transformMatrix[0][1] = cosX * sinZ * scalingFactor; - transformMatrix[1][1] = cosX * cosZ * scalingFactor; - transformMatrix[2][1] = -sinX * scalingFactor; - transformMatrix[3][1] = translationVector[1]; - transformMatrix[0][2] = ((-sinY * cosZ) + (sinX * cosY * sinZ)) * scalingFactor; - transformMatrix[1][2] = ((sinY * sinZ) + (sinX * cosY * cosZ)) * scalingFactor; - transformMatrix[2][2] = cosX * cosY * scalingFactor; - transformMatrix[3][2] = translationVector[2]; + FrameInterpolation_RecordSetMatrixTransformation(transformMatrix, location, rotation, scale); + f32 sinX = sins(rotation[0]); + f32 cosX = coss(rotation[0]); + f32 sinY = sins(rotation[1]); + f32 cosY = coss(rotation[1]); + f32 sinZ = sins(rotation[2]); + f32 cosZ = coss(rotation[2]); + + transformMatrix[0][0] = ((cosY * cosZ) + (sinX * sinY * sinZ)) * scale; + transformMatrix[1][0] = ((-cosY * sinZ) + (sinX * sinY * cosZ)) * scale; + transformMatrix[2][0] = (cosX * sinY) * scale; + transformMatrix[3][0] = location[0]; + transformMatrix[0][1] = cosX * sinZ * scale; + transformMatrix[1][1] = cosX * cosZ * scale; + transformMatrix[2][1] = -sinX * scale; + transformMatrix[3][1] = location[1]; + transformMatrix[0][2] = ((-sinY * cosZ) + (sinX * cosY * sinZ)) * scale; + transformMatrix[1][2] = ((sinY * sinZ) + (sinX * cosY * cosZ)) * scale; + transformMatrix[2][2] = cosX * cosY * scale; + transformMatrix[3][2] = location[2]; transformMatrix[0][3] = 0.0f; transformMatrix[1][3] = 0.0f; transformMatrix[2][3] = 0.0f; @@ -919,8 +921,7 @@ void set_transform_matrix(Mat4 dest, Vec3f orientationVector, Vec3f positionVect Vec3f sp38; Vec3f sp2C; - FrameInterpolation_Record_set_transform_matrix(dest, orientationVector, positionVector, rotationAngle, scaleFactor); - + FrameInterpolation_RecordSetTransformMatrix(dest, orientationVector, positionVector, rotationAngle, scaleFactor); vec3f_set_xyz(sp44, sins(rotationAngle), 0.0f, coss(rotationAngle)); vec3f_normalize(orientationVector); vec3f_cross_product(sp38, orientationVector, sp44); diff --git a/src/math_util_2.h b/src/math_util_2.h index 604e28c02..5d0837dd9 100644 --- a/src/math_util_2.h +++ b/src/math_util_2.h @@ -77,7 +77,8 @@ void func_80042330_wide(s32, s32, u16, f32); void mtxf_set_matrix_transformation(Mat4, Vec3f, Vec3su, f32); void mtxf_set_matrix_scale_transl(Mat4, Vec3f, Vec3f, f32); void mtxf_set_matrix_gObjectList(s32, Mat4); -void set_transform_matrix(Mat4, Vec3f, Vec3f, u16, f32); +void set_transform_matrix(Mat4 dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle, + f32 scaleFactor); void vec3f_rotate_x_y(Vec3f, Vec3f, Vec3s); void rsp_set_matrix_transformation(Vec3f, Vec3su, f32); void rsp_set_matrix_transformation_inverted_x_y_orientation(Vec3f, Vec3su, f32); diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index 14f391cc6..268d323dc 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -70,7 +70,9 @@ enum class Op { MatrixToMtx, MatrixRotateAxis, SkinMatrixMtxFToMtx, - SetTransformMatrix + SetTransformMatrix, + SetMatrixTransformation, + CalculateOrientationMatrix }; typedef pair label; @@ -97,7 +99,12 @@ union Data { struct { Mat4* matrix; Vec3fInterp b; - } matrix_translate, matrix_scale; + } matrix_translate; + + struct { + Mat4* matrix; + f32 scale; + } matrix_scale; struct { Mat4* matrix; @@ -165,12 +172,27 @@ union Data { struct { Mat4* dest; - Vec3f* orientationVector; - Vec3f* positionVector; + Vec3f orientationVector; + Vec3f positionVector; u16 rotationAngle; f32 scaleFactor; } set_transform_matrix_data; + struct { + Mat4* dest; + Vec3f location; + Vec3su rotation; + f32 scale; + } set_matrix_transformation_data; + + struct { + Mat3* dest; + f32 arg1; + f32 arg2; + f32 arg3; + s16 rot; + } set_orientation_matrix_data; + struct { label key; size_t idx; @@ -219,6 +241,7 @@ struct InterpolateCtx { float w; unordered_map mtx_replacements; MtxF tmp_mtxf, tmp_mtxf2; + Mat3 tmp_mat3; Vec3f tmp_vec3f, tmp_vec3f2; Vec3s tmp_vec3s; MtxF actor_mtx; @@ -243,6 +266,12 @@ struct InterpolateCtx { return w * o + step * n; } + void lerp_vec3s(Vec3s* res, Vec3s o, Vec3s n) { + *res[0] = lerp_s16(o[0], n[0]); + *res[1] = lerp_s16(o[1], n[1]); + *res[2] = lerp_s16(o[2], n[2]); + } + void lerp_vec3f(Vec3f* res, Vec3f* o, Vec3f* n) { *res[0] = lerp(*o[0], *n[0]); *res[1] = lerp(*o[1], *n[1]); @@ -388,10 +417,7 @@ struct InterpolateCtx { break; case Op::MatrixScale: - // Matrix_Scale(gInterpolationMatrix, lerp(old_op.matrix_scale.x, new_op.matrix_scale.x), - // lerp(old_op.matrix_scale.y, new_op.matrix_scale.y), - // lerp(old_op.matrix_scale.z, new_op.matrix_scale.z), - // new_op.matrix_scale.mode); + mtxf_scale(*gInterpolationMatrix, lerp(old_op.matrix_scale.scale, new_op.matrix_scale.scale)); break; case Op::MatrixRotate1Coord: { @@ -457,11 +483,11 @@ struct InterpolateCtx { } case Op::SetTransformMatrix: { - lerp_vec3f(&tmp_vec3f, &old_op.set_transform_matrix_data.orientationVector[0], - &new_op.set_transform_matrix_data.orientationVector[0]); + lerp_vec3f(&tmp_vec3f, &old_op.set_transform_matrix_data.orientationVector, + &new_op.set_transform_matrix_data.orientationVector); - lerp_vec3f(&tmp_vec3f2, &old_op.set_transform_matrix_data.positionVector[0], - &new_op.set_transform_matrix_data.positionVector[0]); + lerp_vec3f(&tmp_vec3f2, &old_op.set_transform_matrix_data.positionVector, + &new_op.set_transform_matrix_data.positionVector); u16 rotationAngleTemp = lerp_s16(old_op.set_transform_matrix_data.rotationAngle, new_op.set_transform_matrix_data.rotationAngle); @@ -471,6 +497,27 @@ struct InterpolateCtx { break; } + + case Op::SetMatrixTransformation: { + + lerp_vec3f(&tmp_vec3f, &old_op.set_matrix_transformation_data.location, + &new_op.set_matrix_transformation_data.location); + + lerp_vec3s(&tmp_vec3s, *(Vec3s*)&old_op.set_matrix_transformation_data.rotation, + *(Vec3s*)&new_op.set_matrix_transformation_data.rotation); + + f32 scaleFactorTemp = lerp(old_op.set_matrix_transformation_data.scale, new_op.set_matrix_transformation_data.scale); + + mtxf_set_matrix_transformation(*gInterpolationMatrix, tmp_vec3f, *(Vec3su*)&tmp_vec3s, scaleFactorTemp); + break; + } + + case Op::CalculateOrientationMatrix: { + + + calculate_orientation_matrix(* tmp_mat3); + break; + } } } } @@ -588,10 +635,10 @@ void FrameInterpolation_RecordMatrixTranslate(Mat4* matrix, Vec3f b) { append(Op::MatrixTranslate).matrix_translate = { matrix, *((Vec3fInterp*) &b) }; } -void FrameInterpolation_RecordMatrixScale(Mat4* matrix, f32 x, f32 y, f32 z, u8 mode) { +void FrameInterpolation_RecordMatrixScale(Mat4* matrix, f32 scale) { if (!is_recording) return; - // append(Op::MatrixScale).matrix_scale = { matrix, x, y, z, mode }; + append(Op::MatrixScale).matrix_scale = { matrix, scale }; } void FrameInterpolation_RecordMatrixMultVec3fNoTranslate(Mat4* matrix, Vec3f src, Vec3f dest) { @@ -600,11 +647,24 @@ void FrameInterpolation_RecordMatrixMultVec3fNoTranslate(Mat4* matrix, Vec3f src // append(Op::MatrixMultVec3fNoTranslate).matrix_vec_no_translate = { matrix, src, dest }; } -void FrameInterpolation_Record_set_transform_matrix(Mat4* dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle, +void FrameInterpolation_RecordSetTransformMatrix(Mat4* dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle, f32 scaleFactor) { if (!is_recording) return; - append(Op::SetTransformMatrix).set_transform_matrix_data = { dest, (Vec3f*)&orientationVector[0], (Vec3f*)&positionVector[0], rotationAngle, scaleFactor}; + append(Op::SetTransformMatrix).set_transform_matrix_data = { dest, {orientationVector[0], orientationVector[1], orientationVector[2]}, { positionVector[0], positionVector[1], positionVector[2] }, rotationAngle, scaleFactor}; +} + + +void FrameInterpolation_RecordSetMatrixTransformation(Mat4* dest, Vec3f location, Vec3su rotation, f32 scale) { + if (!is_recording) + return; + append(Op::SetMatrixTransformation).set_matrix_transformation_data = { dest, {location[0], location[1], location[2]}, { rotation[0], rotation[1], rotation[2] }, scale}; +} + +void FrameInterpolation_RecordCalculateOrientationMatrix(Mat3* dest, f32 x, f32 y, f32 z, s16 rot) { + if (!is_recording) return; + + append(Op::SetMatrixTransformation).set_calculate_orientation_matrix_data = { dest, x, y, z, rot}; } // Make a template for deref diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index a70f3e7b0..bd544f621 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -49,7 +49,7 @@ void FrameInterpolation_RecordMatrixPop(Mat4* matrix); void FrameInterpolation_RecordMatrixTranslate(Mat4* matrix, Vec3f b); -//void FrameInterpolation_RecordMatrixScale(Matrix* matrix, f32 x, f32 y, f32 z, u8 mode); +void FrameInterpolation_RecordMatrixScale(Mat4* matrix, f32 scale); void FrameInterpolation_RecordMatrixRotate1Coord(Mat4* matrix, u32 coord, s16 value); @@ -67,9 +67,13 @@ void FrameInterpolation_RecordSkinMatrixMtxFToMtx(MtxF* src, Mtx* dest); //void FrameInterpolation_RecordMatrixMultVec3fNoTranslate(Matrix* matrix, Vec3f src, Vec3f dest); -void FrameInterpolation_Record_set_transform_matrix(Mat4* dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle, +void FrameInterpolation_RecordSetTransformMatrix(Mat4* dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle, f32 scaleFactor); +void FrameInterpolation_RecordSetMatrixTransformation(Mat4* dest, Vec3f location, Vec3su rotation, f32 scale); + +void FrameInterpolation_RecordCalculateOrientationMatrix(Mat3*, f32, f32, f32, s16); + #ifdef __cplusplus } #endif diff --git a/src/racing/math_util.c b/src/racing/math_util.c index 1fb975048..5c099dda7 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -391,39 +391,6 @@ void mtxf_s16_rotate_z(Mat4 mat, s16 angle) { */ } -void func_802B5B14(Vec3f b, Vec3s rotate) { - Mat4 mtx; - Vec3f copy; - - f32 sx = sins(rotate[0]); - f32 cx = coss(rotate[0]); - - f32 sy = sins(rotate[1]); - f32 cy = coss(rotate[1]); - - f32 sz = sins(rotate[2]); - f32 cz = coss(rotate[2]); - - copy[0] = b[0]; - copy[1] = b[1]; - - mtx[0][0] = cy * cz + sx * sy * sz; - mtx[1][0] = -cy * sz + sx * sy * cz; - mtx[2][0] = cx * sy; - - mtx[0][1] = cx * sz; - mtx[1][1] = cx * cz; - mtx[2][1] = -sx; - - mtx[0][2] = -sy * cz + sx * cy * sz; - mtx[1][2] = sy * sz + sx * cy * cz; - mtx[2][2] = cx * cy; - - b[0] = copy[0] * mtx[0][0] + copy[1] * mtx[0][1] + copy[1] * mtx[0][2]; - b[1] = copy[0] * mtx[1][0] + copy[1] * mtx[1][1] + copy[1] * mtx[1][2]; - 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); @@ -467,6 +434,7 @@ void set_track_light_direction(Lights1* addr, s16 pitch, s16 yaw, s32 numLights) // multiply a matrix with a number void mtxf_scale(Mat4 mat, f32 coef) { + FrameInterpolation_RecordMatrixScale(mat, coef); mat[0][0] *= coef; mat[1][0] *= coef; mat[2][0] *= coef; @@ -631,7 +599,9 @@ void func_802B64C4(Vec3f arg0, s16 arg1) { arg0[2] = sp2C * temp1 + (temp_f0 * temp3); } -void calculate_orientation_matrix(Mat3 dest, f32 arg1, f32 arg2, f32 arg3, s16 rotationAngle) { +// Rotates the object around the Y axis. +// x,y,z is a direction (not a rotator). +void calculate_orientation_matrix(Mat3 dest, f32 x, f32 y, f32 z, s16 rotationAngle) { Mat3 mtx_rot_y; Mat3 matrix; s32 i, j; @@ -642,6 +612,7 @@ void calculate_orientation_matrix(Mat3 dest, f32 arg1, f32 arg2, f32 arg3, s16 r UNUSED s32 pad[3]; f32 sinValue; f32 cossValue; + FrameInterpolation_RecordCalculateOrientationMatrix(dest, x, y, z, rotationAngle); sinValue = sins(rotationAngle); cossValue = coss(rotationAngle); @@ -657,7 +628,7 @@ void calculate_orientation_matrix(Mat3 dest, f32 arg1, f32 arg2, f32 arg3, s16 r mtx_rot_y[1][0] = 0; mtx_rot_y[0][1] = 0; - if (arg2 == 1) { // set matrix to identity + if (y == 1) { // set matrix to identity for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { @@ -665,7 +636,7 @@ void calculate_orientation_matrix(Mat3 dest, f32 arg1, f32 arg2, f32 arg3, s16 r } } - } else if (arg2 == -1) { // set matrix to identity with the second column negative + } else if (y == -1) { // set matrix to identity with the second column negative for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { @@ -676,10 +647,10 @@ void calculate_orientation_matrix(Mat3 dest, f32 arg1, f32 arg2, f32 arg3, s16 r matrix[1][1] = -1; } else { - a = (f32) - (360.0 - ((f64) (calculate_vector_angle_xy(arg2) * 180.0f) / M_PI)); - b = -arg3 / sqrtf((arg1 * arg1) + (arg3 * arg3)); + a = (f32) - (360.0 - ((f64) (calculate_vector_angle_xy(y) * 180.0f) / M_PI)); + b = -z / sqrtf((x * x) + (z * z)); c = 0; - d = arg1 / sqrtf((arg1 * arg1) + (arg3 * arg3)); + d = x / sqrtf((x * x) + (z * z)); calculate_rotation_matrix(matrix, a, b, c, d); } dest[0][0] = (mtx_rot_y[0][0] * matrix[0][0]) + (mtx_rot_y[0][1] * matrix[1][0]) + (mtx_rot_y[0][2] * matrix[2][0]); @@ -760,7 +731,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; diff --git a/src/racing/math_util.h b/src/racing/math_util.h index ec6c2f3c9..7c230ca87 100644 --- a/src/racing/math_util.h +++ b/src/racing/math_util.h @@ -42,7 +42,6 @@ void func_802B5794(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 set_track_light_direction(Lights1*, s16, s16, s32); diff --git a/src/render_player.c b/src/render_player.c index 65545ebd7..ff33db379 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -927,18 +927,6 @@ UNUSED void func_80021F50(Mat4 arg0, Vec3f arg1) { arg0[3][2] += arg1[2]; } -void mtxf_scale2(Mat4 arg0, f32 scale) { - arg0[0][0] *= scale; - arg0[1][0] *= scale; - arg0[2][0] *= scale; - arg0[0][1] *= scale; - arg0[1][1] *= scale; - arg0[2][1] *= scale; - arg0[0][2] *= scale; - arg0[1][2] *= scale; - arg0[2][2] *= scale; -} - /** * This function writes a fixed-point value to each Mtx entry. This is not how the Mtx struct works. * The first half of Mtx only holds s16 whole numbers and the second half holds the s16 decimal (fractional) parts. @@ -1523,7 +1511,7 @@ void render_player_shadow(Player* player, s8 playerId, s8 screenId) { spCC[1] = player->unk_074 + 1.0f; spCC[2] = player->pos[2] + ((spB0 * coss(spC0)) - (spAC * sins(spC0))); mtxf_translate_rotate(mtx, spCC, spC4); - mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size); + mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size); } // convert_to_fixed_point_matrix(&gGfxPool->mtxShadow[playerId + (screenId * 8)], mtx); @@ -1582,7 +1570,7 @@ void render_player_shadow_credits(Player* player, s8 playerId, s8 arg2) { spCC[1] = gObjectList[indexObjectList1[playerId]].pos[1] + sp94[playerId]; mtxf_translate_rotate(mtx, spCC, spC4); - mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size); + mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size); // convert_to_fixed_point_matrix(&gGfxPool->mtxShadow[playerId + (arg2 * 8)], mtx); // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxShadow[playerId + (arg2 * 8)]), @@ -1674,7 +1662,7 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) { #endif } mtxf_translate_rotate(mtx, sp154, sp14C); - mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size); + mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size); // convert_to_fixed_point_matrix(&gGfxPool->mtxKart[playerId + (screenId * 8)], mtx); // @port: Tag the transform. @@ -1801,7 +1789,7 @@ void render_ghost(Player* player, s8 playerId, s8 screenId, s8 arg3) { } mtxf_translate_rotate(mtx, spDC, spD4); - mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size); + mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size); // convert_to_fixed_point_matrix(&gGfxPool->mtxKart[playerId + (screenId * 8)], mtx); // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxKart[playerId + (screenId * 8)]), @@ -1847,7 +1835,7 @@ void func_80025DE8(Player* player, s8 playerId, s8 screenId, s8 arg3) { sp94[2] = player->unk_050[screenId]; mtxf_translate_rotate(mtx, sp9C, sp94); - mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size); + mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size); // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx); // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), @@ -1897,7 +1885,7 @@ void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 a } mtxf_translate_rotate(mtx, sp9C, sp94); - mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size); + mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size); // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx); // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), diff --git a/src/render_player.h b/src/render_player.h index 212f8810b..e11c7c3eb 100644 --- a/src/render_player.h +++ b/src/render_player.h @@ -29,7 +29,6 @@ void func_80021D40(void); void func_80021DA8(void); void mtxf_translate_rotate(Mat4, Vec3f, Vec3s); void func_80021F50(Mat4, Vec3f); -void mtxf_scale2(Mat4, f32); void failed_fixed_point_matrix_conversion(Mtx*, Mat4); void convert_to_fixed_point_matrix(Mtx*, Mat4); bool adjust_angle(s16*, s16, s16); From aaa232238dbafbc98c6cdafa5c7e7488350e34c4 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sat, 17 May 2025 18:15:50 -0600 Subject: [PATCH 36/85] Add more interps --- src/port/interpolation/FrameInterpolation.cpp | 26 +++++++++++++++---- src/port/interpolation/FrameInterpolation.h | 6 ++++- src/render_player.c | 6 +++-- src/render_player.h | 6 ++--- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index 268d323dc..c1d787119 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -11,6 +11,7 @@ extern "C" { #include "math_util.h" #include "math_util_2.h" +#include "render_player.h" } /* Frame interpolation. @@ -72,7 +73,7 @@ enum class Op { SkinMatrixMtxFToMtx, SetTransformMatrix, SetMatrixTransformation, - CalculateOrientationMatrix + SetTranslateRotate }; typedef pair label; @@ -185,6 +186,12 @@ union Data { f32 scale; } set_matrix_transformation_data; + struct { + Mat4* dest; + Vec3f location; + Vec3s rotation; + } set_translate_rotate_data; + struct { Mat3* dest; f32 arg1; @@ -384,7 +391,7 @@ struct InterpolateCtx { // break; case Op::MatrixMult: - interpolate_mtxf(&tmp_mtxf, &old_op.matrix_mult.mf, &new_op.matrix_mult.mf); + //interpolate_mtxf(&tmp_mtxf, &old_op.matrix_mult.mf, &new_op.matrix_mult.mf); // Matrix_Mult(gInterpolationMatrix, (Matrix*) &tmp_mtxf, new_op.matrix_mult.mode); break; @@ -512,10 +519,14 @@ struct InterpolateCtx { break; } - case Op::CalculateOrientationMatrix: { + case Op::SetTranslateRotate: { + lerp_vec3f(&tmp_vec3f, &old_op.set_translate_rotate_data.location, + &new_op.set_translate_rotate_data.location); + lerp_vec3s(&tmp_vec3s, old_op.set_translate_rotate_data.rotation, + new_op.set_translate_rotate_data.rotation); - calculate_orientation_matrix(* tmp_mat3); + mtxf_translate_rotate(*gInterpolationMatrix, tmp_vec3f, tmp_vec3s); break; } } @@ -654,6 +665,11 @@ void FrameInterpolation_RecordSetTransformMatrix(Mat4* dest, Vec3f orientationVe append(Op::SetTransformMatrix).set_transform_matrix_data = { dest, {orientationVector[0], orientationVector[1], orientationVector[2]}, { positionVector[0], positionVector[1], positionVector[2] }, rotationAngle, scaleFactor}; } +void FrameInterpolation_RecordTranslateRotate(Mat4* dest, Vec3f pos, Vec3s rotation) { + if (!is_recording) { return; } + + append(Op::SetTranslateRotate).set_translate_rotate_data = { dest, {pos[0], pos[1], pos[2]}, { rotation[0], rotation[1], rotation[2] }}; +} void FrameInterpolation_RecordSetMatrixTransformation(Mat4* dest, Vec3f location, Vec3su rotation, f32 scale) { if (!is_recording) @@ -664,7 +680,7 @@ void FrameInterpolation_RecordSetMatrixTransformation(Mat4* dest, Vec3f location void FrameInterpolation_RecordCalculateOrientationMatrix(Mat3* dest, f32 x, f32 y, f32 z, s16 rot) { if (!is_recording) return; - append(Op::SetMatrixTransformation).set_calculate_orientation_matrix_data = { dest, x, y, z, rot}; + // append(Op::SetMatrixTransformation).set_calculate_orientation_matrix_data = { dest, x, y, z, rot}; } // Make a template for deref diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index bd544f621..612db4160 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -74,8 +74,12 @@ void FrameInterpolation_RecordSetMatrixTransformation(Mat4* dest, Vec3f location void FrameInterpolation_RecordCalculateOrientationMatrix(Mat3*, f32, f32, f32, s16); +void FrameInterpolation_RecordTranslateRotate(Mat4* dest, Vec3f pos, Vec3s rotation); + +//void FrameInterpolation_func_80062B18(f32* arg0, f32* arg1, f32* arg2, arg3, arg4, arg5, arg6, arg7); + #ifdef __cplusplus } #endif -#endif // __FRAME_INTERPOLATION_H \ No newline at end of file +#endif // __FRAME_INTERPOLATION_H diff --git a/src/render_player.c b/src/render_player.c index ff33db379..d16c4380c 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -903,6 +903,8 @@ void mtxf_translate_rotate(Mat4 dest, Vec3f pos, Vec3s orientation) { f32 sinZ = sins(orientation[2]); f32 cosZ = coss(orientation[2]); + FrameInterpolation_RecordTranslateRotate(dest, pos, orientation); + dest[0][0] = (cosY * cosZ) + ((sinX * sinY) * sinZ); dest[1][0] = (-cosY * sinZ) + ((sinX * sinY) * cosZ); dest[2][0] = cosX * sinY; @@ -1609,7 +1611,8 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) { f32 sp140; s16 temp_v1; s16 thing; - + + FrameInterpolation_RecordOpenChild("Player", playerId | screenId << 8); if (player->unk_044 & 0x2000) { sp14C[0] = 0; sp14C[1] = player->unk_048[screenId]; @@ -1666,7 +1669,6 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) { // convert_to_fixed_point_matrix(&gGfxPool->mtxKart[playerId + (screenId * 8)], mtx); // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("Player", playerId | screenId << 8); if ((player->effects & BOO_EFFECT) == BOO_EFFECT) { if (screenId == playerId) { diff --git a/src/render_player.h b/src/render_player.h index e11c7c3eb..3f9d06406 100644 --- a/src/render_player.h +++ b/src/render_player.h @@ -1,5 +1,5 @@ -#ifndef CODE_8001F980_H -#define CODE_8001F980_H +#ifndef RENDER_PLAYER_H +#define RENDER_PLAYER_H #include #include "buffers.h" @@ -278,4 +278,4 @@ extern s16 D_80165150[4][8]; extern s16 D_80165190[4][8]; extern s16 D_801651D0[4][8]; -#endif +#endif // RENDER_PLAYER_H From 819c8fc4fc0081c76ead7b33b47109f654dbd5c9 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Sat, 17 May 2025 21:34:56 -0300 Subject: [PATCH 37/85] matrix --- src/engine/Matrix.cpp | 8 ++++++++ src/engine/World.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/engine/Matrix.cpp b/src/engine/Matrix.cpp index e46804ad5..e01df8954 100644 --- a/src/engine/Matrix.cpp +++ b/src/engine/Matrix.cpp @@ -136,6 +136,14 @@ extern "C" { AddMatrix(gWorldInstance.Mtx.Hud, mtx, flags); } + void AddPerspMatrix(Mat4 mtx, s32 flags) { + AddMatrix(gWorldInstance.Mtx.Persp, mtx, flags); + } + + void AddLookAtMatrix(Mat4 mtx, s32 flags) { + AddMatrix(gWorldInstance.Mtx.LookAt, mtx, flags); + } + void AddObjectMatrix(Mat4 mtx, s32 flags) { AddMatrix(gWorldInstance.Mtx.Objects, mtx, flags); } diff --git a/src/engine/World.h b/src/engine/World.h index bb8979090..915cacf27 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -46,6 +46,8 @@ class World { std::vector Shadows; std::vector Karts; std::vector Effects; + std::vector Persp; + std::vector LookAt; } Matrix; public: From 3c0ac691a7e3efe28b764392ddfc91cf4aba0b1c Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sat, 17 May 2025 18:35:09 -0600 Subject: [PATCH 38/85] Matrix multi interp --- src/port/interpolation/FrameInterpolation.cpp | 3 ++- src/port/interpolation/FrameInterpolation.h | 2 +- src/racing/math_util.c | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index c1d787119..4da081ac1 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -391,7 +391,8 @@ struct InterpolateCtx { // break; case Op::MatrixMult: - //interpolate_mtxf(&tmp_mtxf, &old_op.matrix_mult.mf, &new_op.matrix_mult.mf); + interpolate_mtxf(&tmp_mtxf, &old_op.matrix_mult.mf, &new_op.matrix_mult.mf); + mtxf_multiplication(*gInterpolationMatrix, tmp_mtxf.mf, new_op.matrix_mult.mf.mf); // Matrix_Mult(gInterpolationMatrix, (Matrix*) &tmp_mtxf, new_op.matrix_mult.mode); break; diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 612db4160..debb5b890 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -45,7 +45,7 @@ void FrameInterpolation_RecordMatrixPush(Mat4* matrix); void FrameInterpolation_RecordMatrixPop(Mat4* matrix); -//void FrameInterpolation_RecordMatrixMult(Matrix* matrix, MtxF* mf, u8 mode); +void FrameInterpolation_RecordMatrixMult(Mat4* matrix, MtxF* mf, u8 mode); void FrameInterpolation_RecordMatrixTranslate(Mat4* matrix, Vec3f b); diff --git a/src/racing/math_util.c b/src/racing/math_util.c index 5c099dda7..a67bc7f65 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -803,6 +803,9 @@ void func_802B6D58(Mat4 arg0, Vec3f arg1, Vec3f arg2) { void mtxf_multiplication(Mat4 dest, Mat4 mat1, Mat4 mat2) { Mat4 product; + + FrameInterpolation_RecordMatrixMult(dest, product, 0); + product[0][0] = (mat1[0][0] * mat2[0][0]) + (mat1[0][1] * mat2[1][0]) + (mat1[0][2] * mat2[2][0]) + (mat1[0][3] * mat2[3][0]); product[0][1] = From 1eba8ebc17ba71435f8d91b876c35d05f5735de0 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Mon, 19 May 2025 16:42:11 -0600 Subject: [PATCH 39/85] Fix interpolation camera bug --- src/camera.c | 146 +++++++++++++++++- src/camera.h | 2 + src/code_80057C60.c | 4 +- src/enhancements/freecam/freecam.cpp | 41 +++-- src/enhancements/freecam/freecam.h | 2 +- src/enhancements/freecam/freecam_engine.c | 4 +- src/main.c | 20 ++- src/os/guLookAtF.c | 1 + src/os/guPerspectiveF.c | 1 + src/port/interpolation/FrameInterpolation.cpp | 14 +- src/racing/render_courses.c | 7 + src/racing/skybox_and_splitscreen.c | 85 +++++++--- src/render_objects.c | 7 +- src/render_player.c | 9 +- src/spawn_players.c | 4 + 15 files changed, 281 insertions(+), 66 deletions(-) diff --git a/src/camera.c b/src/camera.c index 07003f07d..6591dc32e 100644 --- a/src/camera.c +++ b/src/camera.c @@ -25,11 +25,12 @@ f32 D_800DDB30[] = { 0.4f, 0.6f, 0.275f, 0.3f }; -Camera cameras[4]; +Camera cameras[5]; Camera* camera1 = &cameras[0]; Camera* camera2 = &cameras[1]; Camera* camera3 = &cameras[2]; Camera* camera4 = &cameras[3]; +Camera* gFreecamCamera = &cameras[4]; UNUSED s32 D_801649D0[2]; @@ -194,6 +195,146 @@ void camera_init(f32 posX, f32 posY, f32 posZ, UNUSED s16 rot, u32 arg4, s32 cam func_802B7F7C(camera->pos, camera->lookAt, camera->rot); } +// Many arrays are hard-coded to 4. Skip those. +void freecam_init(f32 posX, f32 posY, f32 posZ, UNUSED s16 rot, u32 arg4, s32 cameraId) { + Player* player = gPlayerOne; + Camera* camera = &cameras[cameraId]; + + camera->cameraId = cameraId; + + //D_80152300[cameraId] = arg4; + switch (arg4) { + case 0: + case 1: + case 3: + case 8: + case 9: + case 10: + D_80164A89 = 0; + camera->pos[0] = posX; + camera->pos[1] = posY; + camera->pos[2] = posZ; + camera->someBitFlags = 0; + camera->lookAt[0] = 0.0f; + camera->lookAt[2] = 150.0f; + camera->lookAt[1] = posY - 3.0; + camera->up[0] = 0.0f; + camera->up[1] = 1.0f; + camera->up[2] = 0.0f; + camera->playerId = (s16) 0; + camera->unk_B0 = 0; + camera->unk_A0 = 0.0f; + + // D_801649D8[cameraId] = 20.0f; + // D_801649E8[cameraId] = 10.0f; + // D_801649F8[cameraId] = 7.0f; + // D_80164A2C = 0; + // D_80164A30 = 30.0f; + // D_80164A38[cameraId] = 0.0f; + // D_80164A48[cameraId] = 0.0f; + + // D_80164A90[cameraId] = 0.0f; + // D_80164AA0[cameraId] = 0.0f; + // D_80164A78[cameraId] = D_800DDB30[gActiveScreenMode]; + // D_80164A18[cameraId] = 0; + // D_80164A08[cameraId] = 0; + // D_80164498[cameraId] = 0.0f; + camera->unk_94.unk_8 = 0; + camera->unk_94.unk_0 = 0.0f; + + player += cameraId; + camera->unk_2C = player->rotation[1]; + camera->unk_AC = player->rotation[1]; + switch (gActiveScreenMode) { + case SCREEN_MODE_1P: + case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: + if (gModeSelection == BATTLE) { + camera->unk_30[0] = 0.0f; + camera->unk_30[1] = 11.6f; + camera->unk_30[2] = -38.5f; + camera->unk_3C[0] = 0.0f; + camera->unk_3C[1] = 0.0f; + camera->unk_3C[2] = 19.2f; + D_80164A88 = 0; + } else { + camera->unk_30[0] = 0.0f; + camera->unk_30[1] = 9.5f; + camera->unk_30[2] = -50.0f; + camera->unk_3C[0] = 0.0f; + camera->unk_3C[1] = 0.0f; + camera->unk_3C[2] = 70.0f; + } + break; + case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: + if (gModeSelection == BATTLE) { + camera->unk_30[0] = 0.0f; + camera->unk_30[1] = 11.6f; + camera->unk_30[2] = -38.5f; + camera->unk_3C[0] = 0.0f; + camera->unk_3C[1] = 0.0f; + camera->unk_3C[2] = 19.2f; + } else { + camera->unk_30[0] = 0.0f; + camera->unk_30[1] = 9.6f; + camera->unk_30[2] = -35.0f; + camera->unk_3C[0] = 0.0f; + camera->unk_3C[1] = 0.0f; + camera->unk_3C[2] = 30.0f; + } + break; + case SCREEN_MODE_3P_4P_SPLITSCREEN: + if (gModeSelection == BATTLE) { + camera->unk_30[0] = 0.0f; + camera->unk_30[1] = 11.6f; + camera->unk_30[2] = -38.5f; + camera->unk_3C[0] = 0.0f; + camera->unk_3C[1] = 0.0f; + camera->unk_3C[2] = 19.2f; + } else { + camera->unk_30[0] = 0.0f; + camera->unk_30[1] = 9.0f; + camera->unk_30[2] = -40.0f; + camera->unk_3C[0] = 0.0f; + camera->unk_3C[1] = 0.0f; + camera->unk_3C[2] = 18.0f; + } + break; + } + + //func_80014DE4(cameraId); + + // if (D_80164678[cameraId] == 0) { + if (D_80164A28 == 1) { + // gCameraZoom[cameraId] = 80.0f; + } else { + // gCameraZoom[cameraId] = 40.0f; + } + camera->unk_B4 = gCameraZoom[0]; + // } + // if (D_80164678[cameraId] == 1) { + // if (D_80164A28 == 1) { + // gCameraZoom[cameraId] = 100.0f; + // } else { + // gCameraZoom[cameraId] = 60.0f; + // } + // camera->unk_B4 = gCameraZoom[cameraId]; + // // } + // if (D_80164678[cameraId] == 2) { + // if (D_80164A28 == 1) { + // gCameraZoom[cameraId] = 100.0f; + // } else { + // gCameraZoom[cameraId] = 60.0f; + // } + // camera->unk_B4 = gCameraZoom[cameraId]; + // D_80164A38[cameraId] = 20.0f; + // D_80164A48[cameraId] = 1.5f; + // D_80164A78[cameraId] = 1.0f; + // } + break; + } + func_802B7F7C(camera->pos, camera->lookAt, camera->rot); +} + // Thwomp related void func_8001CA10(Camera* camera) { camera->unk_94.unk_8 = 0; @@ -994,7 +1135,8 @@ void func_8001EE98(Player* player, Camera* camera, s8 index) { func_8001E8E8(camera, player, index); break; } - freecam(camera, player, index); // Runs func_8001E45C when freecam is disabled + //freecam(camera, player, index); // Runs func_8001E45C when freecam is disabled + func_8001E45C(camera, player, index); break; case 8: func_8001E0C4(camera, player, index); diff --git a/src/camera.h b/src/camera.h index 6abeb3aad..56cc07a94 100644 --- a/src/camera.h +++ b/src/camera.h @@ -59,6 +59,7 @@ typedef struct { } Camera; /* size = 0xB8 */ void camera_init(f32, f32, f32, s16, u32, s32); +void freecam_init(f32 posX, f32 posY, f32 posZ, s16 rot, u32 arg4, s32 cameraId); void func_8001CA10(Camera*); void func_8001CA24(Player*, f32); void func_8001CA78(Player*, Camera*, Vec3f, f32*, f32*, f32*, s32, s32); @@ -81,6 +82,7 @@ extern Camera* camera1; extern Camera* camera2; extern Camera* camera3; extern Camera* camera4; +extern Camera* gFreecamCamera; // end of camera.c variables diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 32b24029b..23293b641 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -4967,9 +4967,10 @@ void func_800651F4(Player* player, UNUSED s8 arg1, UNUSED s8 arg2, s8 arg3) { } } +s32 D_func_800652D4_counter = 0; void func_800652D4(Vec3f arg0, Vec3s arg1, f32 arg2) { Mat4 mtx; - + FrameInterpolation_RecordOpenChild("some_thing", D_func_800652D4_counter++ << 8); mtxf_translate_rotate(mtx, arg0, arg1); mtxf_scale(mtx, arg2); // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx); @@ -4977,6 +4978,7 @@ void func_800652D4(Vec3f arg0, Vec3s arg1, f32 arg2) { // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); AddEffectMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + FrameInterpolation_RecordCloseChild(); } void func_8006538C(Player* player, s8 arg1, s16 arg2, s8 arg3) { diff --git a/src/enhancements/freecam/freecam.cpp b/src/enhancements/freecam/freecam.cpp index 86dfef575..4efc5fcfb 100644 --- a/src/enhancements/freecam/freecam.cpp +++ b/src/enhancements/freecam/freecam.cpp @@ -4,6 +4,7 @@ #include "port/Game.h" #include #include +#include "port/interpolation/FrameInterpolation.h" extern "C" { #include @@ -85,7 +86,7 @@ void freecam(Camera* camera, Player* player, s8 index) { if (enabled && (player == gPlayerOne)) { freecam_loop(camera, player, index); } else { - func_8001E45C(camera, player, index); + func_8001EE98(gPlayerOneCopy, camera, index); } } @@ -104,7 +105,6 @@ void freecam_loop(Camera* camera, Player* player, s8 index) { // Toggle freecam CVarSetInteger("gFreecam", !CVarGetInteger("gFreecam", 0)); } - // Calculate forward direction freecam_calculate_forward_vector_allow_rotation(camera, freeCam.forwardVector); @@ -389,24 +389,33 @@ void freecam_update_controller(void) { // Note that D Pad as stick code has been removed. So if it's needed, it needs to be put back in. } -void freecam_render_setup(void) { +Mtx fPersp; +Mtx fLookAt; +void freecam_render_setup(Camera* camera) { u16 perspNorm; Mat4 matrix; - init_rdp(); - func_802A53A4(); - init_rdp(); - func_80057FC4(0); + + Mat4 persp; + Mat4 lookAt; + gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH); gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK | G_CULL_BOTH | G_CULL_FRONT); - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, + + // Perspective (camera movement) + FrameInterpolation_RecordOpenChild("freecam_persp", FrameInterpolation_GetCameraEpoch()); + guPerspective(&fPersp, &perspNorm, gCameraZoom[0], gScreenAspect, CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); gSPPerspNormalize(gDisplayListHead++, perspNorm); - gSPMatrix(gDisplayListHead++, (&gGfxPool->mtxPersp[0]), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - guLookAt(&gGfxPool->mtxLookAt[0], camera1->pos[0], camera1->pos[1], camera1->pos[2], camera1->lookAt[0], - camera1->lookAt[1], camera1->lookAt[2], camera1->up[0], camera1->up[1], camera1->up[2]); - gSPMatrix(gDisplayListHead++, (&gGfxPool->mtxLookAt[0]), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); - render_set_position(matrix, 0); - init_rdp(); + gSPMatrix(gDisplayListHead++, (&fPersp), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + FrameInterpolation_RecordCloseChild(); + + // LookAt (camera rotation) + FrameInterpolation_RecordOpenChild("freecam_lookAt", FrameInterpolation_GetCameraEpoch()); + guLookAt(&fLookAt, camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0], + camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]); + gSPMatrix(gDisplayListHead++, (&fLookAt), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); + FrameInterpolation_RecordCloseChild(); + + gDPPipeSync(gDisplayListHead++); + } diff --git a/src/enhancements/freecam/freecam.h b/src/enhancements/freecam/freecam.h index db55866ed..86c42b0c9 100644 --- a/src/enhancements/freecam/freecam.h +++ b/src/enhancements/freecam/freecam.h @@ -13,7 +13,7 @@ void on_freecam(void); void off_freecam(void); void freecam_loop(Camera*, Player*, s8); void freecam_update_controller(void); -void freecam_render_setup(void); +void freecam_render_setup(Camera* camera); void freecam_mouse_manager(Camera*, Vec3f); void freecam_keyboard_manager(Camera*, Vec3f); diff --git a/src/enhancements/freecam/freecam_engine.c b/src/enhancements/freecam/freecam_engine.c index 350ab192b..56585e2f0 100644 --- a/src/enhancements/freecam/freecam_engine.c +++ b/src/enhancements/freecam/freecam_engine.c @@ -11,10 +11,10 @@ #include #include "freecam_engine.h" -FreeCam freeCam; - #include +FreeCam freeCam; + f32 gDampValue = 0.99f; f32 gRotDampValue = 0.96f; diff --git a/src/main.c b/src/main.c index 01b09b7ca..1b0b8a716 100644 --- a/src/main.c +++ b/src/main.c @@ -758,15 +758,18 @@ void process_game_tick(void) { func_800382DC(); } - // Editor requires this for camera movement. - func_8001EE98(gPlayerOneCopy, camera1, 0); - - if (gIsEditorPaused == true) { - return; - } - switch(gActiveScreenMode) { case SCREEN_MODE_1P: + if (CVarGetInteger("gFreecam", 0) == true) { + freecam(gFreecamCamera, gPlayerOneCopy, 0); + } else { + func_8001EE98(gPlayerOneCopy, camera1, 0); + } + + // Editor requires this so the camera keeps moving while the game is paused. + if (gIsEditorPaused == true) { + return; + } func_80028F70(); break; case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: @@ -930,6 +933,8 @@ void race_logic_loop(void) { */ void game_state_handler(void) { + FrameInterpolation_StartRecord(); + #if DVDL if ((gControllerOne->button & L_TRIG) && (gControllerOne->button & R_TRIG) && (gControllerOne->button & Z_TRIG) && (gControllerOne->button & A_BUTTON)) { @@ -966,6 +971,7 @@ void game_state_handler(void) { credits_loop(); break; } + FrameInterpolation_StopRecord(); } void interrupt_gfx_sptask(void) { diff --git a/src/os/guLookAtF.c b/src/os/guLookAtF.c index 1e391a37c..4b031d818 100644 --- a/src/os/guLookAtF.c +++ b/src/os/guLookAtF.c @@ -76,4 +76,5 @@ void guLookAt(Mtx* m, float xEye, float yEye, float zEye, float xAt, float yAt, guLookAtF(mf, xEye, yEye, zEye, xAt, yAt, zAt, xUp, yUp, zUp); guMtxF2L(mf, m); + FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mf, m); } diff --git a/src/os/guPerspectiveF.c b/src/os/guPerspectiveF.c index 062d42751..d02e33b20 100644 --- a/src/os/guPerspectiveF.c +++ b/src/os/guPerspectiveF.c @@ -37,4 +37,5 @@ void guPerspective(Mtx* m, u16* perspNorm, float fovy, float aspect, float near, float mat[4][4]; guPerspectiveF(mat, perspNorm, fovy, aspect, near, far, scale); guMtxF2L(mat, m); + FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mat, m); } diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index 4da081ac1..767b83316 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -550,7 +550,7 @@ unordered_map FrameInterpolation_Interpolate(float step) { bool camera_interpolation = true; void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate) { - // camera_interpolation = shouldInterpolate; + camera_interpolation = shouldInterpolate; is_recording = shouldInterpolate; } @@ -559,12 +559,12 @@ void FrameInterpolation_StartRecord(void) { current_recording = {}; current_path.clear(); current_path.push_back(¤t_recording.root_path); - // if (!camera_interpolation) { - // // default to interpolating - // camera_interpolation = true; - // is_recording = false; - // return; - // } + if (!camera_interpolation) { + // default to interpolating + camera_interpolation = true; + is_recording = false; + return; + } if (GameEngine::GetInterpolationFPS() != 20) { is_recording = true; } diff --git a/src/racing/render_courses.c b/src/racing/render_courses.c index 71b182544..1b1e7ec26 100644 --- a/src/racing/render_courses.c +++ b/src/racing/render_courses.c @@ -7,6 +7,7 @@ #include #include "../camera.h" #include "framebuffer_effects.h" +#include "port/interpolation/FrameInterpolation.h" #include "render_courses.h" #include "code_800029B0.h" @@ -240,9 +241,15 @@ void func_8029122C(struct UnkStruct_800DC5EC* arg0, s32 playerId) { G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); break; } + + FrameInterpolation_RecordOpenChild("track_water", playerId); + mtxf_identity(matrix); render_set_position(matrix, 0); + //FrameInterpolation_RecordCloseChild(); + CM_DrawWater(arg0, pathCounter, cameraRot, playerDirection); + FrameInterpolation_RecordCloseChild(); // switch (gCurrentCourseId) { // case COURSE_BOWSER_CASTLE: // if (gActiveScreenMode != SCREEN_MODE_1P) { diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index abc7c23aa..b5c2cb305 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -755,17 +755,45 @@ void func_802A5760(void) { } } -void render_screens(s32 mode, s32 cameraId, s32 playerId) { - UNUSED s32 pad[4]; +void setup_camera(Camera* camera, s32 playerId, s32 cameraId, struct UnkStruct_800DC5EC* screen) { + Mat4 matrix; u16 perspNorm; - UNUSED s32 pad2[2]; - UNUSED s32 pad3; + + if (CVarGetInteger("gFreecam", 0) == true) { + freecam_render_setup(gFreecamCamera); + return; + } + + FrameInterpolation_RecordOpenChild("camerapersp", FrameInterpolation_GetCameraEpoch()); + guPerspective(&gGfxPool->mtxPersp[cameraId], &perspNorm, gCameraZoom[cameraId], gScreenAspect, + CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); + + gSPPerspNormalize(gDisplayListHead++, perspNorm); + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[cameraId]), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + + guLookAt(&gGfxPool->mtxLookAt[cameraId], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0], + camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]); + if (D_800DC5C8 == 0) { + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]), + G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); + mtxf_identity(matrix); + render_set_position(matrix, 0); + } else { + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + } + FrameInterpolation_RecordCloseChild(); +} + +extern s32 D_func_800652D4_counter; +void render_screens(s32 mode, s32 cameraId, s32 playerId) { Mat4 matrix; s32 screenId = 0; s32 screenMode = SCREEN_MODE_1P; - - FrameInterpolation_StartRecord(); +D_func_800652D4_counter = 0; switch (mode) { case RENDER_SCREEN_MODE_1P_PLAYER_ONE: @@ -824,7 +852,14 @@ void render_screens(s32 mode, s32 cameraId, s32 playerId) { } struct UnkStruct_800DC5EC* screen = &D_8015F480[screenId]; - Camera* camera = &cameras[cameraId]; + Camera* camera; + + if (CVarGetInteger("gFreecam", 0) == true) { + camera = &gFreecamCamera; + cameraId = 4; + } else { + camera = &cameras[cameraId]; + } if (screenMode == SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL) { gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH); @@ -834,27 +869,28 @@ void render_screens(s32 mode, s32 cameraId, s32 playerId) { func_802A3730(screen); gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH); gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + //FrameInterpolation_RecordOpenChild("SCREENCAMERA", (playerId | cameraId) << 8); + + setup_camera(camera, playerId, cameraId, screen); // Setup camera perspective and lookAt +// render_course(screen); + +//FrameInterpolation_RecordOpenChild("track", 0); +//Mat4 trackMtx; +//mtxf_identity(trackMtx); +//AddObjectMatrix(trackMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); +render_course(screen); +//FrameInterpolation_RecordCloseChild(); + + + //Mat4 projectionF; + //Matrix_MtxToMtxF(&gGfxPool->mtxLookAt[cameraId], &projectionF); + // SkinMatrix_MtxFMtxFMult(&projectionF, &flipF, &projectionF); + // FrameInterpolation_RecordCloseChild(); - guPerspective(&gGfxPool->mtxPersp[cameraId], &perspNorm, gCameraZoom[cameraId], gScreenAspect, - CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); - gSPPerspNormalize(gDisplayListHead++, perspNorm); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[cameraId]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - guLookAt(&gGfxPool->mtxLookAt[cameraId], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0], - camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]); - if (D_800DC5C8 == 0) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } else { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - } - render_course(screen); if (D_800DC5C8 == 1) { + //PushLookAtMtx(gGfxPool->mtxLookAt[cameraId], G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); mtxf_identity(matrix); @@ -910,7 +946,6 @@ void render_screens(s32 mode, s32 cameraId, s32 playerId) { gNumScreens += 1; } - FrameInterpolation_StopRecord(); } void func_802A74BC(void) { diff --git a/src/render_objects.c b/src/render_objects.c index b2de13f7c..9a8c7400a 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3934,15 +3934,15 @@ void func_80055EF4(s32 objectIndex, UNUSED s32 arg1) { void render_object_neon(s32 cameraId) { Camera* camera; - s32 var_s2; s32 objectIndex; Object* object; camera = &camera1[cameraId]; - for (var_s2 = 0; var_s2 < 10; var_s2++) { - objectIndex = indexObjectList1[var_s2]; + for (size_t i = 0; i < 10; i++) { + objectIndex = indexObjectList1[i]; if (D_8018E838[cameraId] == 0) { object = &gObjectList[objectIndex]; + FrameInterpolation_RecordOpenChild(object, TAG_OBJECT((objectIndex << 8) + i)); if ((object->state >= 2) && (is_obj_index_flag_status_inactive(objectIndex, 0x00080000) != 0) && (is_object_visible_on_camera(objectIndex, camera, 0x2AABU) != 0)) { Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_hedgehog); @@ -3950,6 +3950,7 @@ void render_object_neon(s32 cameraId) { draw_2d_texture_at(object->pos, object->orientation, object->sizeScaling, (u8*) object->activeTLUT, object->activeTexture, vtx, 0x00000040, 0x00000040, 0x00000040, 0x00000020); } + FrameInterpolation_RecordCloseChild(); } } } diff --git a/src/render_player.c b/src/render_player.c index d16c4380c..b101e00b9 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -1611,8 +1611,8 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) { f32 sp140; s16 temp_v1; s16 thing; - - FrameInterpolation_RecordOpenChild("Player", playerId | screenId << 8); + + FrameInterpolation_RecordOpenChild("player_kart", playerId | screenId << 8); if (player->unk_044 & 0x2000) { sp14C[0] = 0; sp14C[1] = player->unk_048[screenId]; @@ -1836,6 +1836,9 @@ void func_80025DE8(Player* player, s8 playerId, s8 screenId, s8 arg3) { sp94[1] = player->unk_048[screenId]; sp94[2] = player->unk_050[screenId]; + FrameInterpolation_RecordOpenChild("player_boost", playerId | screenId << 8); + + mtxf_translate_rotate(mtx, sp9C, sp94); mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size); // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx); @@ -1867,6 +1870,8 @@ void func_80025DE8(Player* player, s8 playerId, s8 screenId, s8 arg3) { gSPDisplayList(gDisplayListHead++, common_square_plain_render); gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); gMatrixEffectCount += 1; + + FrameInterpolation_RecordCloseChild(); } void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 arg3) { diff --git a/src/spawn_players.c b/src/spawn_players.c index 5e623577b..569042ca6 100644 --- a/src/spawn_players.c +++ b/src/spawn_players.c @@ -1194,6 +1194,10 @@ void func_8003D080(void) { } else { func_8003C0F0(); } + + // Init free cam + freecam_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 4); + if (!gDemoMode) { switch (gActiveScreenMode) { case SCREEN_MODE_1P: From 23222922e68761c6d2aeeea276afbf8c9c672eb2 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Mon, 19 May 2025 19:14:51 -0500 Subject: [PATCH 40/85] Missing includes needed for Linux. --- src/main.c | 1 + src/math_util_2.c | 1 + src/os/guLookAtF.c | 1 + src/os/guPerspectiveF.c | 1 + src/racing/skybox_and_splitscreen.c | 1 + 5 files changed, 5 insertions(+) diff --git a/src/main.c b/src/main.c index 1b0b8a716..cd8b4f677 100644 --- a/src/main.c +++ b/src/main.c @@ -44,6 +44,7 @@ #include "buffers/gfx_output_buffer.h" #include #include "enhancements/freecam/freecam.h" +#include "port/interpolation/FrameInterpolation.h" #include "engine/wasm.h" #include "port/Game.h" #include "engine/Matrix.h" diff --git a/src/math_util_2.c b/src/math_util_2.c index d9770eddb..e4fc571d5 100644 --- a/src/math_util_2.c +++ b/src/math_util_2.c @@ -15,6 +15,7 @@ #include "port/Engine.h" #include "engine/Matrix.h" +#include "port/interpolation/FrameInterpolation.h" #pragma intrinsic(sqrtf) diff --git a/src/os/guLookAtF.c b/src/os/guLookAtF.c index 4b031d818..3163b89b4 100644 --- a/src/os/guLookAtF.c +++ b/src/os/guLookAtF.c @@ -11,6 +11,7 @@ **************************************************************************/ #include "libultra_internal.h" +#include "port/interpolation/FrameInterpolation.h" void guLookAtF(float mf[4][4], float xEye, float yEye, float zEye, float xAt, float yAt, float zAt, float xUp, float yUp, float zUp) { diff --git a/src/os/guPerspectiveF.c b/src/os/guPerspectiveF.c index d02e33b20..fc65c6e80 100644 --- a/src/os/guPerspectiveF.c +++ b/src/os/guPerspectiveF.c @@ -1,4 +1,5 @@ #include "libultra_internal.h" +#include "port/interpolation/FrameInterpolation.h" void guPerspectiveF(float mf[4][4], u16* perspNorm, float fovy, float aspect, float near, float far, float scale) { float yscale; diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index b5c2cb305..87fa1390f 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -21,6 +21,7 @@ #include "engine/courses/Course.h" #include "port/Game.h" #include "math_util.h" +#include "src/enhancements/freecam/freecam.h" #include "port/interpolation/FrameInterpolation.h" Vp D_802B8880[] = { From a822e89d633e0a459f63a01af3fa763bfe974f74 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Mon, 19 May 2025 20:31:06 -0500 Subject: [PATCH 41/85] Excluded access to HM64 Labs on Switch. --- src/port/ui/PortMenu.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/port/ui/PortMenu.cpp b/src/port/ui/PortMenu.cpp index 286d02aab..6f2a4ec48 100644 --- a/src/port/ui/PortMenu.cpp +++ b/src/port/ui/PortMenu.cpp @@ -368,6 +368,7 @@ void PortMenu::AddEnhancements() { .Options(FloatSliderOptions().Min(-50.0f).Max(50.0f).DefaultValue(0.0f) .Tooltip("When Disable Wall Collision are enable what is the minimal height you can get.")); + #if not defined(__SWITCH__) and not defined(__WIIU__) path = { "Enhancements", "HM64 Lab", SECTION_COLUMN_1 }; AddSidebarEntry("Enhancements", "HM64 Lab", 4); AddWidget(path, "Enable HM64 Labs", WIDGET_CVAR_CHECKBOX) @@ -380,6 +381,7 @@ void PortMenu::AddEnhancements() { Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Properties")->ToggleVisibility(); }) .Options(UIWidgets::CheckboxOptions({{ .tooltip = "Edit the universe!"}})); + #endif } #ifdef __SWITCH__ From 07d5640585d4a17a9637721105c3dcf3032797df Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 00:44:17 -0300 Subject: [PATCH 42/85] interpolation tags for various objects --- src/actors/cow/render.inc.c | 6 + src/code_80057C60.c | 26 +++++ src/engine/objects/GrandPrixBalloons.cpp | 29 +++-- src/engine/objects/Mole.cpp | 105 ++++++++++-------- src/port/interpolation/FrameInterpolation.cpp | 4 +- src/port/interpolation/FrameInterpolation.h | 2 +- src/racing/actors.c | 21 +++- 7 files changed, 131 insertions(+), 62 deletions(-) diff --git a/src/actors/cow/render.inc.c b/src/actors/cow/render.inc.c index e55154c03..af15363c4 100644 --- a/src/actors/cow/render.inc.c +++ b/src/actors/cow/render.inc.c @@ -19,6 +19,9 @@ void render_actor_cow(Camera* camera, Mat4 arg1, struct Actor* arg2) { return; } + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("render_actor_cow", TAG_OBJECT(arg2)); + arg1[3][0] = arg2->pos[0]; arg1[3][1] = arg2->pos[1]; arg1[3][2] = arg2->pos[2]; @@ -42,4 +45,7 @@ void render_actor_cow(Camera* camera, Mat4 arg1, struct Actor* arg2) { break; } } + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 23293b641..7e609859d 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -5101,6 +5101,13 @@ void func_80065AB0(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3) { spAC[0] = 0; spAC[1] = player->unk_048[arg3]; spAC[2] = 0; + + // // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("EEEEEEEEE", player->type << 8 | arg2 | var_s0 << 16); + + // @port Skip interpolation + // FrameInterpolation_ShouldInterpolateFrame(false); + func_800652D4(spB4, spAC, player->unk_258[10 + arg2].unk_00C * player->size); if (var_s0 == 0) { gSPDisplayList(gDisplayListHead++, D_0D008DB8); @@ -5120,6 +5127,11 @@ void func_80065AB0(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3) { gSPDisplayList(gDisplayListHead++, D_0D008E48); } gMatrixEffectCount += 1; + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); + // @port renable interpolation + // FrameInterpolation_ShouldInterpolateFrame(true); } } #else @@ -5670,6 +5682,10 @@ void func_800691B8(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3) { sp54[1] = player->unk_048[arg3]; player->unk_258[30 + arg2].unk_03A += 0x1C71; sp54[2] = player->unk_258[30 + arg2].unk_03A; + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("func_800691B8", TAG_OBJECT(arg2)); + func_800652D4(sp5C, sp54, player->size * 0.5); gSPDisplayList(gDisplayListHead++, D_0D008D58); gDPSetTextureLUT(gDisplayListHead++, G_TT_NONE); @@ -5681,6 +5697,9 @@ void func_800691B8(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3) { gSPVertex(gDisplayListHead++, D_800E87C0, 4, 0); gSPDisplayList(gDisplayListHead++, D_0D008DA0); gMatrixEffectCount++; + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } @@ -5774,6 +5793,10 @@ void func_80069938(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3) { sp54[0] = 0; sp54[1] = player->unk_048[arg3]; sp54[2] = player->unk_258[30 + arg2].unk_038; + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("func_80069938", TAG_OBJECT(arg2)); + func_800652D4(sp5C, sp54, player->unk_258[30 + arg2].unk_00C * player->size); gSPDisplayList(gDisplayListHead++, D_0D008D58); gDPSetTextureLUT(gDisplayListHead++, G_TT_NONE); @@ -5785,6 +5808,9 @@ void func_80069938(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3) { gSPVertex(gDisplayListHead++, D_800E87C0, 4, 0); gSPDisplayList(gDisplayListHead++, D_0D008DA0); gMatrixEffectCount += 1; + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } diff --git a/src/engine/objects/GrandPrixBalloons.cpp b/src/engine/objects/GrandPrixBalloons.cpp index 253c68464..544a3e4d1 100644 --- a/src/engine/objects/GrandPrixBalloons.cpp +++ b/src/engine/objects/GrandPrixBalloons.cpp @@ -35,7 +35,7 @@ OGrandPrixBalloons::OGrandPrixBalloons(const FVector& pos) { find_unused_obj_index(&gObjectParticle3[i]); init_object(gObjectParticle3[i], 0); } - // printf("primAlfa %d\n", object->primAlpha); + // printf("primAlfa %d\n", object->primAlpha); } void OGrandPrixBalloons::Tick() { @@ -75,7 +75,7 @@ void OGrandPrixBalloons::Draw(s32 cameraId) { return; } - gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007E98); + gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007E98); gDPLoadTLUT_pal256(gDisplayListHead++, gTLUTOnomatopoeia); func_8004B614(0, 0, 0, 0, 0, 0, 0); gDPSetAlphaCompare(gDisplayListHead++, G_AC_THRESHOLD); @@ -86,14 +86,14 @@ void OGrandPrixBalloons::Draw(s32 cameraId) { GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)); D_80183E80[0] = 0; D_80183E80[1] = 0x8000; - rsp_load_texture((uint8_t*)gTextureBalloon1, 64, 32); + rsp_load_texture((uint8_t*) gTextureBalloon1, 64, 32); for (var_s1 = 0; var_s1 < _numBalloons; var_s1++) { objectIndex = gObjectParticle3[var_s1]; if ((objectIndex != NULL_OBJECT_ID) && (gObjectList[objectIndex].state >= 2)) { OGrandPrixBalloons::func_80053D74(objectIndex, cameraId, 0); } } - rsp_load_texture((uint8_t*)gTextureBalloon2, 64, 32); + rsp_load_texture((uint8_t*) gTextureBalloon2, 64, 32); for (var_s1 = 0; var_s1 < _numBalloons; var_s1++) { objectIndex = gObjectParticle3[var_s1]; if ((objectIndex != NULL_OBJECT_ID) && (gObjectList[objectIndex].state >= 2)) { @@ -107,22 +107,25 @@ void OGrandPrixBalloons::func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 ver Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog); - // @port: Tag the transform. size_t i = 0; if (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX) { object = &gObjectList[objectIndex]; - FrameInterpolation_RecordOpenChild("Balloon", TAG_ITEM_ADDR((objectIndex << 8) + i++)); //Not working properly just yet + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Balloon", + TAG_ITEM_ADDR((objectIndex << 32) + i++)); // Not working properly just yet + D_80183E80[2] = (s16) (object->unk_084[6] + 0x8000); rsp_set_matrix_transformation(object->pos, (u16*) D_80183E80, object->sizeScaling); set_color_render((s32) object->unk_084[0], (s32) object->unk_084[1], (s32) object->unk_084[2], (s32) object->unk_084[3], (s32) object->unk_084[4], (s32) object->unk_084[5], (s32) object->primAlpha); - gSPVertex(gDisplayListHead++, (uintptr_t)&vtx[vertexIndex], 4, 0); - gSPDisplayList(gDisplayListHead++, (Gfx*)common_rectangle_display); + gSPVertex(gDisplayListHead++, (uintptr_t) &vtx[vertexIndex], 4, 0); + gSPDisplayList(gDisplayListHead++, (Gfx*) common_rectangle_display); + + // @port Pop the transform id. FrameInterpolation_RecordCloseChild(); } - - // @port Pop the transform id. } void OGrandPrixBalloons::func_80074924(s32 objectIndex) { @@ -195,7 +198,8 @@ void OGrandPrixBalloons::func_80074924(s32 objectIndex) { void OGrandPrixBalloons::func_80074D94(s32 objectIndex) { if (gObjectList[objectIndex].unk_0AE == 1) { - //! @warning this fades out the balloons. Original game uses _numBalloons3 here but they disappear before off-screen. + //! @warning this fades out the balloons. Original game uses _numBalloons3 here but they disappear before + //! off-screen. // So _numBalloons replaces it for now. if ((_numBalloons <= gObjectList[objectIndex].offset[1]) && (s16_step_down_towards(&gObjectList[objectIndex].primAlpha, 0, 8) != 0)) { @@ -219,7 +223,8 @@ void OGrandPrixBalloons::func_80074E28(s32 objectIndex) { case 0: break; case 3: - OGrandPrixBalloons::func_80041480(&gObjectList[objectIndex].unk_084[6], -0x1000, 0x1000, &gObjectList[objectIndex].unk_084[7]); + OGrandPrixBalloons::func_80041480(&gObjectList[objectIndex].unk_084[6], -0x1000, 0x1000, + &gObjectList[objectIndex].unk_084[7]); if (gObjectList[objectIndex].unk_0AE == 0) { func_80072428(objectIndex); } diff --git a/src/engine/objects/Mole.cpp b/src/engine/objects/Mole.cpp index 06bd5f56c..91eeabebf 100644 --- a/src/engine/objects/Mole.cpp +++ b/src/engine/objects/Mole.cpp @@ -21,6 +21,7 @@ extern "C" { #include "sounds.h" #include "external.h" } +#include "port/interpolation/FrameInterpolation.h" size_t OMole::_count = 0; @@ -145,7 +146,7 @@ void OMole::func_80081AFC(s32 objectIndex, s32 arg1) { // sp2C = D_8018D1B8; // break; // } - //sp2C[object->type] = 0; + // sp2C[object->type] = 0; } break; case 0: @@ -179,20 +180,20 @@ void OMole::func_8008153C(s32 objectIndex) { } u8* mole = (u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_dirt); - init_object(loopObjectIndex, 0); - gObjectList[loopObjectIndex].activeTLUT = d_course_moo_moo_farm_mole_dirt; - gObjectList[loopObjectIndex].tlutList = mole; - gObjectList[loopObjectIndex].sizeScaling = 0.15f; - gObjectList[loopObjectIndex].velocity[1] = random_int(0x000AU); - gObjectList[loopObjectIndex].velocity[1] = (gObjectList[loopObjectIndex].velocity[1] * 0.1) + 4.8; - gObjectList[loopObjectIndex].unk_034 = random_int(5U); - gObjectList[loopObjectIndex].unk_034 = (gObjectList[loopObjectIndex].unk_034 * 0.01) + 0.8; - gObjectList[loopObjectIndex].orientation[1] = (0x10000 / sp70) * var_s1; - gObjectList[loopObjectIndex].origin_pos[0] = gObjectList[objectIndex].origin_pos[0]; - gObjectList[loopObjectIndex].origin_pos[1] = gObjectList[objectIndex].origin_pos[1] - 13.0; - gObjectList[loopObjectIndex].origin_pos[2] = gObjectList[objectIndex].origin_pos[2]; - break; - } + init_object(loopObjectIndex, 0); + gObjectList[loopObjectIndex].activeTLUT = d_course_moo_moo_farm_mole_dirt; + gObjectList[loopObjectIndex].tlutList = mole; + gObjectList[loopObjectIndex].sizeScaling = 0.15f; + gObjectList[loopObjectIndex].velocity[1] = random_int(0x000AU); + gObjectList[loopObjectIndex].velocity[1] = (gObjectList[loopObjectIndex].velocity[1] * 0.1) + 4.8; + gObjectList[loopObjectIndex].unk_034 = random_int(5U); + gObjectList[loopObjectIndex].unk_034 = (gObjectList[loopObjectIndex].unk_034 * 0.01) + 0.8; + gObjectList[loopObjectIndex].orientation[1] = (0x10000 / sp70) * var_s1; + gObjectList[loopObjectIndex].origin_pos[0] = gObjectList[objectIndex].origin_pos[0]; + gObjectList[loopObjectIndex].origin_pos[1] = gObjectList[objectIndex].origin_pos[1] - 13.0; + gObjectList[loopObjectIndex].origin_pos[2] = gObjectList[objectIndex].origin_pos[2]; + break; + } } } @@ -243,21 +244,15 @@ void OMole::func_80081D34(s32 objectIndex) { } static const char* frames[] = { - gTextureMole1, - gTextureMole2, - gTextureMole3, - gTextureMole4, - gTextureMole5, - gTextureMole6, - gTextureMole7, - d_course_moo_moo_farm_mole_dirt, + gTextureMole1, gTextureMole2, gTextureMole3, gTextureMole4, + gTextureMole5, gTextureMole6, gTextureMole7, d_course_moo_moo_farm_mole_dirt, }; - void OMole::func_80081848(s32 objectIndex) { - init_texture_object(objectIndex, (u8*)d_course_moo_moo_farm_mole_tlut, (const char**) frames, 0x20U, (u16) 0x00000040); - //gObjectList[objectIndex].activeTexture = (const char*)d_course_moo_moo_farm_mole_frames; - //gObjectList[objectIndex].activeTLUT = (const char*)d_course_moo_moo_farm_mole_tlut; + init_texture_object(objectIndex, (u8*) d_course_moo_moo_farm_mole_tlut, (const char**) frames, 0x20U, + (u16) 0x00000040); + // gObjectList[objectIndex].activeTexture = (const char*)d_course_moo_moo_farm_mole_frames; + // gObjectList[objectIndex].activeTLUT = (const char*)d_course_moo_moo_farm_mole_tlut; gObjectList[objectIndex].sizeScaling = 0.15f; gObjectList[objectIndex].textureListIndex = 0; @@ -270,7 +265,6 @@ void OMole::func_80081848(s32 objectIndex) { object_next_state(objectIndex); } - void OMole::func_80081924(s32 objectIndex) { switch (gObjectList[objectIndex].unk_0AE) { case 1: @@ -307,7 +301,6 @@ void OMole::func_80081924(s32 objectIndex) { } } - void OMole::func_80081A88(s32 objectIndex) { switch (gObjectList[objectIndex].unk_0DD) { /* irregular */ case 0: @@ -333,6 +326,10 @@ void OMole::func_800821AC(s32 objectIndex, s32 arg1) { void OMole::func_80054E10(s32 objectIndex) { if (gObjectList[objectIndex].state > 0) { if (is_obj_flag_status_active(objectIndex, 0x00800000) != 0) { + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("func_80054E10", TAG_OBJECT(&gObjectList[objectIndex])); + D_80183E50[0] = gObjectList[objectIndex].pos[0]; D_80183E50[1] = gObjectList[objectIndex].surfaceHeight + 0.8; D_80183E50[2] = gObjectList[objectIndex].pos[2]; @@ -340,6 +337,9 @@ void OMole::func_80054E10(s32 objectIndex) { D_80183E70[1] = gObjectList[objectIndex].velocity[1]; D_80183E70[2] = gObjectList[objectIndex].velocity[2]; func_8004A9B8(gObjectList[objectIndex].sizeScaling); + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } } @@ -348,8 +348,8 @@ void OMole::func_80054E10(s32 objectIndex) { void OMole::func_80054EB8() { s32 someIndex; - //for (someIndex = 0; someIndex < NUM_TOTAL_MOLES; someIndex++) { - func_80054E10(_moleIndex); + // for (someIndex = 0; someIndex < NUM_TOTAL_MOLES; someIndex++) { + func_80054E10(_moleIndex); //} } @@ -360,13 +360,20 @@ void OMole::func_80054D00(s32 objectIndex, s32 cameraId) { if (gObjectList[objectIndex].state >= 3) { func_8008A364(objectIndex, cameraId, 0x2AABU, 0x0000012C); if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("func_80054D00", TAG_OBJECT(&gObjectList[objectIndex])); + D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0]; D_80183E80[1] = func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos); D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2]; func_80048130(gObjectList[objectIndex].pos, (u16*) D_80183E80, gObjectList[objectIndex].sizeScaling, - (u8*) gObjectList[objectIndex].activeTLUT, (u8*)gObjectList[objectIndex].activeTexture, - (Vtx*)LOAD_ASSET_RAW(D_0D0062B0), 0x00000020, 0x00000040, 0x00000020, 0x00000040, 5); + (u8*) gObjectList[objectIndex].activeTLUT, (u8*) gObjectList[objectIndex].activeTexture, + (Vtx*) LOAD_ASSET_RAW(D_0D0062B0), 0x00000020, 0x00000040, 0x00000020, 0x00000040, 5); + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } } @@ -374,22 +381,30 @@ void OMole::func_80054D00(s32 objectIndex, s32 cameraId) { void OMole::func_80054F04(s32 cameraId) { Camera* camera = &camera1[cameraId]; - gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0079C8); + gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D0079C8); load_texture_block_rgba16_mirror((u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_dirt), 0x00000010, 0x00000010); -if (_idx == 0) { - for (size_t i = 0; i < gObjectParticle2_SIZE; i++) { - s32 objectIndex = gObjectParticle2[i]; - Object* object = &gObjectList[objectIndex]; - if (object->state > 0) { - func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000000C8); - if ((is_obj_flag_status_active(objectIndex, VISIBLE) != 0) && (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) { - object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos); - rsp_set_matrix_gObjectList(objectIndex); - gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D006980); + if (_idx == 0) { + for (size_t i = 0; i < gObjectParticle2_SIZE; i++) { + s32 objectIndex = gObjectParticle2[i]; + Object* object = &gObjectList[objectIndex]; + if (object->state > 0) { + func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000000C8); + if ((is_obj_flag_status_active(objectIndex, VISIBLE) != 0) && + (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) { + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("func_80054F04", TAG_OBJECT(object) | (i << 32)); + + object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos); + rsp_set_matrix_gObjectList(objectIndex); + gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D006980); + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); + } } } } -} gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); } diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index 767b83316..3d1512f55 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -76,7 +76,7 @@ enum class Op { SetTranslateRotate }; -typedef pair label; +typedef pair label; union Data { Data() { @@ -575,7 +575,7 @@ void FrameInterpolation_StopRecord(void) { is_recording = false; } -void FrameInterpolation_RecordOpenChild(const void* a, int b) { +void FrameInterpolation_RecordOpenChild(const void* a, uintptr_t b) { if (!is_recording) return; label key = { a, b }; diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index debb5b890..06a7cf3d4 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -29,7 +29,7 @@ void FrameInterpolation_StopRecord(void); void FrameInterpolation_RecordMarker(const char* file, int line); -void FrameInterpolation_RecordOpenChild(const void* a, int b); +void FrameInterpolation_RecordOpenChild(const void* a, uintptr_t b); void FrameInterpolation_RecordCloseChild(void); diff --git a/src/racing/actors.c b/src/racing/actors.c index 65c734be3..d6fd2ade1 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -510,6 +510,7 @@ void render_cows(Camera* camera, Mat4 arg1) { gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2); var_s5 = NULL; var_s1 = var_t1; + while (var_s1->pos[0] != END_OF_SPAWN_DATA) { sp88[0] = var_s1->pos[0] * gCourseDirection; sp88[1] = var_s1->pos[1]; @@ -524,6 +525,12 @@ void render_cows(Camera* camera, Mat4 arg1) { arg1[3][0] = sp88[0]; arg1[3][1] = sp88[1]; arg1[3][2] = sp88[2]; + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("render_actor_cow", ((var_s1->pos[0] & 0xFFFF) << 32) | + ((var_s1->pos[1] & 0xFFFF) << 16) | + (var_s1->pos[2] & 0xFFFF)); + if ((gMatrixObjectCount < MTX_OBJECT_POOL_SIZE) && (render_set_position(arg1, 0) != 0)) { switch (var_s1->someId) { case 0: @@ -545,6 +552,9 @@ void render_cows(Camera* camera, Mat4 arg1) { } else { return; } + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } var_s1++; } @@ -655,6 +665,11 @@ void render_palm_trees(Camera* camera, Mat4 arg1) { continue; } + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("render_actor_cow", ((var_s1->pos[0] & 0xFFFF) << 32) | + ((var_s1->pos[1] & 0xFFFF) << 16) | + (var_s1->pos[2] & 0xFFFF)); + test &= 0xF; test = (s16) test; if (test == 6) { @@ -691,6 +706,8 @@ void render_palm_trees(Camera* camera, Mat4 arg1) { } var_s1++; } + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } @@ -708,7 +725,7 @@ void render_actor_shell(Camera* camera, Mat4 matrix, struct ShellActor* shell) { //! @todo Is this making the shell spin? // Is it doing this by modifying a an address? uintptr_t phi_t3; - + // @port: Tag the transform. FrameInterpolation_RecordOpenChild("Shell", TAG_ITEM_ADDR(shell)); @@ -2657,7 +2674,7 @@ void update_course_actors(void) { } const char* get_actor_name(s32 id) { - switch(id) { + switch (id) { case ACTOR_FALLING_ROCK: return "Falling Rock"; case ACTOR_GREEN_SHELL: From 6794a94e4d1eee5f3cb17534ccb0e20d08700164 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Mon, 19 May 2025 22:45:08 -0500 Subject: [PATCH 43/85] Bowser castle statue flame interpolated. --- src/render_objects.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/render_objects.c b/src/render_objects.c index 9a8c7400a..82922b11f 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3810,6 +3810,7 @@ void render_object_bowser_flame_particle(s32 objectIndex, s32 cameraId) { camera = &camera1[cameraId]; if (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX) { object = &gObjectList[objectIndex]; + FrameInterpolation_RecordOpenChild("Bowser Statue Flame", TAG_ITEM_ADDR(object)); if (object->unk_0D5 == 9) { func_8004B72C(0xFF, (s32) object->type, 0, (s32) object->unk_0A2, 0, 0, (s32) object->primAlpha); } else { @@ -3817,6 +3818,7 @@ void render_object_bowser_flame_particle(s32 objectIndex, s32 cameraId) { } D_80183E80[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos); func_800431B0(object->pos, D_80183E80, object->sizeScaling, D_0D005AE0); + FrameInterpolation_RecordCloseChild(); } } From f6a33bf4c6049acd50080db3a14826fd894062a9 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 01:04:45 -0300 Subject: [PATCH 44/85] tag hedgehogs --- src/engine/objects/Hedgehog.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/engine/objects/Hedgehog.cpp b/src/engine/objects/Hedgehog.cpp index ebc5b30bb..1c2aada9d 100644 --- a/src/engine/objects/Hedgehog.cpp +++ b/src/engine/objects/Hedgehog.cpp @@ -11,6 +11,7 @@ extern "C" { #include "code_80086E70.h" #include "code_80057C60.h" } +#include "port/interpolation/FrameInterpolation.h" size_t OHedgehog::_count = 0; @@ -25,7 +26,7 @@ OHedgehog::OHedgehog(const FVector& pos, const FVector2D& patrolPoint, s16 unk) gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = pos.x * xOrientation; gObjectList[objectId].pos[1] = gObjectList[objectId].surfaceHeight = pos.y + 6.0; gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = pos.z; - gObjectList[objectId].unk_0D5 = (u8)unk; + gObjectList[objectId].unk_0D5 = (u8) unk; gObjectList[objectId].unk_09C = patrolPoint.x * xOrientation; gObjectList[objectId].unk_09E = patrolPoint.z; @@ -38,10 +39,10 @@ void OHedgehog::Tick() { OHedgehog::func_800833D0(objectIndex, _idx); OHedgehog::func_80083248(objectIndex); OHedgehog::func_80083474(objectIndex); - + // This func clears a bit from all hedgehogs. This results in setting the height of all hedgehogs to zero. // The solution is to only clear the bit from the current instance; `self` or `this` - //func_80072120(indexObjectList2, NUM_HEDGEHOGS); + // func_80072120(indexObjectList2, NUM_HEDGEHOGS); clear_object_flag(objectIndex, 0x00600000); // The fix } @@ -78,7 +79,8 @@ void OHedgehog::func_800555BC(s32 objectIndex, s32 cameraId) { func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos); draw_2d_texture_at(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation, gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, - (u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 64, 64, 64, 32); + (u8*) gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 64, 64, 64, + 32); } } @@ -92,13 +94,20 @@ void OHedgehog::func_8004A870(s32 objectIndex, f32 arg1) { D_80183E50[0] = object->pos[0]; D_80183E50[1] = object->surfaceHeight + 0.8; D_80183E50[2] = object->pos[2]; + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("hedgehog", (uintptr_t) &gObjectList[objectIndex]); + set_transform_matrix(mtx, object->unk_01C, D_80183E50, 0U, arg1); // convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], mtx); // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); AddHudMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007B98); + gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007B98); + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } @@ -108,7 +117,8 @@ void OHedgehog::func_8008311C(s32 objectIndex, s32 arg1) { Object* object; Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog); - init_texture_object(objectIndex, (u8*)d_course_yoshi_valley_hedgehog_tlut, sHedgehogTexList, 0x40U, (u16) 0x00000040); + init_texture_object(objectIndex, (u8*) d_course_yoshi_valley_hedgehog_tlut, sHedgehogTexList, 0x40U, + (u16) 0x00000040); object = &gObjectList[objectIndex]; object->activeTLUT = d_course_yoshi_valley_hedgehog_tlut; object->activeTexture = d_course_yoshi_valley_hedgehog; From 140aa9014dd59419545668bba3f7535df08fe183 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 02:00:56 -0300 Subject: [PATCH 45/85] cloud interpolation --- src/render_objects.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/render_objects.c b/src/render_objects.c index 82922b11f..75ca5c768 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3425,18 +3425,53 @@ void render_object_snowflakes_particles(void) { gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); } -void func_800518F8(s32 objectIndex, s16 arg1, s16 arg2) { - UNUSED s32 pad[1]; +struct CloudInterpData { + s32 objectIndex; + s16 x; +}; + +struct CloudInterpData prevClouds[550] = { 0 }; + +void func_800518F8(s32 objectIndex, s16 x, s16 y) { + bool skipped = false; + + for (int cloudIdx = 0; cloudIdx < 550; cloudIdx++) { + if (objectIndex == prevClouds[cloudIdx].objectIndex) { + if (fabs(x - prevClouds[cloudIdx].x) > 550 / 2) { + // @port Skip interpolation + FrameInterpolation_ShouldInterpolateFrame(false); + skipped = true; + break; + } + } + } + if (gObjectList[objectIndex].status & 0x10) { + if (!skipped) { + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("func_800518F8", (uintptr_t) &gObjectList[objectIndex]); + } if (D_8018D228 != gObjectList[objectIndex].unk_0D5) { D_8018D228 = gObjectList[objectIndex].unk_0D5; func_80044DA0(gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].textureWidth, gObjectList[objectIndex].textureHeight); } - func_80042330_unchanged(arg1, arg2, 0U, gObjectList[objectIndex].sizeScaling); + func_80042330_unchanged(x, y, 0, gObjectList[objectIndex].sizeScaling); gSPVertex(gDisplayListHead++, gObjectList[objectIndex].vertex, 4, 0); gSPDisplayList(gDisplayListHead++, common_rectangle_display); + + if (skipped) { + // @port renable interpolation + FrameInterpolation_ShouldInterpolateFrame(true); + // printf("skipped!\n"); + } + else { + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); + } } + prevClouds[objectIndex].x = x; + prevClouds[objectIndex].objectIndex = objectIndex; } void func_800519D4(s32 objectIndex, s16 arg1, s16 arg2) { From c3c38b05fef78d81fc5031936f6feafe71fab54a Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Tue, 20 May 2025 00:16:00 -0500 Subject: [PATCH 46/85] Interpolated smoke particles from shells --- src/render_objects.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/render_objects.c b/src/render_objects.c index 75ca5c768..5c4af340c 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3905,6 +3905,7 @@ void render_object_smoke_particles(s32 cameraId) { Object* object; sp54 = &camera1[cameraId]; + FrameInterpolation_RecordOpenChild("SmokeParticles", TAG_OBJECT(sp54)); gSPDisplayList(gDisplayListHead++, D_0D007AE0); load_texture_block_i8_nomirror(common_texture_particle_smoke[D_80165598], 32, 32); func_8004B72C(255, 255, 255, 255, 255, 255, 255); @@ -3926,6 +3927,7 @@ void render_object_smoke_particles(s32 cameraId) { } } } + FrameInterpolation_RecordCloseChild(); } UNUSED void func_800557AC() { From 7717b9d674917b2c5c5f1e313140aef55258d013 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 02:36:09 -0300 Subject: [PATCH 47/85] cloud interpolation refactor --- src/render_objects.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/render_objects.c b/src/render_objects.c index 75ca5c768..ca1420cc5 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3430,27 +3430,28 @@ struct CloudInterpData { s16 x; }; -struct CloudInterpData prevClouds[550] = { 0 }; +struct CloudInterpData prevClouds[OBJECT_LIST_SIZE] = { 0 }; void func_800518F8(s32 objectIndex, s16 x, s16 y) { - bool skipped = false; - for (int cloudIdx = 0; cloudIdx < 550; cloudIdx++) { - if (objectIndex == prevClouds[cloudIdx].objectIndex) { - if (fabs(x - prevClouds[cloudIdx].x) > 550 / 2) { - // @port Skip interpolation - FrameInterpolation_ShouldInterpolateFrame(false); - skipped = true; - break; + // Search all recorded clouds for the one we're drawing + for (int i = 0; i < OBJECT_LIST_SIZE; i++) { + if (objectIndex == prevClouds[i].objectIndex) { + // Coincidence! + // Skip drawing the cloud this frame if it warped to the other side of the screen + if (fabs(x - prevClouds[i].x) > SCREEN_WIDTH / 2) { + prevClouds[objectIndex].x = x; + prevClouds[objectIndex].objectIndex = objectIndex; + return; } } } if (gObjectList[objectIndex].status & 0x10) { - if (!skipped) { - // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("func_800518F8", (uintptr_t) &gObjectList[objectIndex]); - } + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("func_800518F8", (uintptr_t) &gObjectList[objectIndex]); + if (D_8018D228 != gObjectList[objectIndex].unk_0D5) { D_8018D228 = gObjectList[objectIndex].unk_0D5; func_80044DA0(gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].textureWidth, @@ -3460,16 +3461,11 @@ void func_800518F8(s32 objectIndex, s16 x, s16 y) { gSPVertex(gDisplayListHead++, gObjectList[objectIndex].vertex, 4, 0); gSPDisplayList(gDisplayListHead++, common_rectangle_display); - if (skipped) { - // @port renable interpolation - FrameInterpolation_ShouldInterpolateFrame(true); - // printf("skipped!\n"); - } - else { - // @port Pop the transform id. - FrameInterpolation_RecordCloseChild(); - } + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } + + // Save current cloud index and x position prevClouds[objectIndex].x = x; prevClouds[objectIndex].objectIndex = objectIndex; } From 36a8c15404f5cbb17873eabea6016b696db3a7d9 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Tue, 20 May 2025 01:03:59 -0500 Subject: [PATCH 48/85] Interpolated snowflakes --- src/render_objects.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/render_objects.c b/src/render_objects.c index f6f37ba0f..863231f53 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3417,10 +3417,12 @@ void render_object_snowflakes_particles(void) { func_80044F34(D_0D0293D8, 0x10, 0x10); for (someIndex = 0; someIndex < NUM_SNOWFLAKES; someIndex++) { snowflakeIndex = gObjectParticle1[someIndex]; + FrameInterpolation_RecordOpenChild("SnowFlakes", snowflakeIndex); if (gObjectList[snowflakeIndex].state >= 2) { rsp_set_matrix_gObjectList(snowflakeIndex); gSPDisplayList(gDisplayListHead++, D_0D006980); } + FrameInterpolation_RecordCloseChild(); } gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); } From 0ec42de46ee6f03246825502a0491c3d991d2309 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Tue, 20 May 2025 01:31:32 -0500 Subject: [PATCH 49/85] Interpolated penguins, also added comment tags to places I missed. --- src/render_objects.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/render_objects.c b/src/render_objects.c index 863231f53..b6b849d31 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3417,11 +3417,15 @@ void render_object_snowflakes_particles(void) { func_80044F34(D_0D0293D8, 0x10, 0x10); for (someIndex = 0; someIndex < NUM_SNOWFLAKES; someIndex++) { snowflakeIndex = gObjectParticle1[someIndex]; + + // @port: Tag the transform. FrameInterpolation_RecordOpenChild("SnowFlakes", snowflakeIndex); if (gObjectList[snowflakeIndex].state >= 2) { rsp_set_matrix_gObjectList(snowflakeIndex); gSPDisplayList(gDisplayListHead++, D_0D006980); } + + // @port Pop the transform id. FrameInterpolation_RecordCloseChild(); } gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); @@ -3843,6 +3847,8 @@ void render_object_bowser_flame_particle(s32 objectIndex, s32 cameraId) { camera = &camera1[cameraId]; if (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX) { object = &gObjectList[objectIndex]; + + // @port: Tag the transform. FrameInterpolation_RecordOpenChild("Bowser Statue Flame", TAG_ITEM_ADDR(object)); if (object->unk_0D5 == 9) { func_8004B72C(0xFF, (s32) object->type, 0, (s32) object->unk_0A2, 0, 0, (s32) object->primAlpha); @@ -3851,6 +3857,8 @@ void render_object_bowser_flame_particle(s32 objectIndex, s32 cameraId) { } D_80183E80[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos); func_800431B0(object->pos, D_80183E80, object->sizeScaling, D_0D005AE0); + + // @port Pop the transform id. FrameInterpolation_RecordCloseChild(); } } @@ -3936,6 +3944,9 @@ void func_800557B4(s32 objectIndex, u32 arg1, u32 arg2) { Object* object; object = &gObjectList[objectIndex]; + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Penguin", (uintptr_t) object); if (object->state >= 2) { if (is_obj_flag_status_active(objectIndex, 0x00000020) != 0) { if (func_80072320(objectIndex, 4) != 0) { @@ -3958,6 +3969,9 @@ void func_800557B4(s32 objectIndex, u32 arg1, u32 arg2) { render_animated_model((Armature*) object->model, (Animation**) object->vertex, (s16) object->unk_0D8, (s16) object->textureListIndex); } + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } void func_80055EF4(s32 objectIndex, UNUSED s32 arg1) { From e3185e0caf3bb618ebc7b1ed862f1714054a1350 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 03:32:28 -0300 Subject: [PATCH 50/85] tag Snowman interpolation --- src/engine/objects/Snowman.cpp | 59 ++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/src/engine/objects/Snowman.cpp b/src/engine/objects/Snowman.cpp index 12beb9e47..7cbfc691d 100644 --- a/src/engine/objects/Snowman.cpp +++ b/src/engine/objects/Snowman.cpp @@ -11,6 +11,7 @@ extern "C" { #include "code_80086E70.h" #include "code_80057C60.h" } +#include "port/interpolation/FrameInterpolation.h" static const char* sSnowmanHeadList[] = { d_course_frappe_snowland_snowman_head }; @@ -27,7 +28,7 @@ OSnowman::OSnowman(const FVector& pos) { gObjectList[_headIndex].origin_pos[0] = pos.x * xOrientation; gObjectList[_headIndex].origin_pos[1] = pos.y + 5.0 + 3.0; gObjectList[_headIndex].origin_pos[2] = pos.z; - gObjectList[_headIndex].pos[0] = pos.x * xOrientation; + gObjectList[_headIndex].pos[0] = pos.x * xOrientation; gObjectList[_headIndex].pos[1] = pos.y + 5.0 + 3.0; gObjectList[_headIndex].pos[2] = pos.z; @@ -38,7 +39,7 @@ OSnowman::OSnowman(const FVector& pos) { gObjectList[_bodyIndex].origin_pos[2] = pos.z; gObjectList[_bodyIndex].unk_0D5 = 0; // Section Id no longer used. - gObjectList[_bodyIndex].pos[0] = pos.x * xOrientation; + gObjectList[_bodyIndex].pos[0] = pos.x * xOrientation; gObjectList[_bodyIndex].pos[1] = pos.y + 3.0; gObjectList[_bodyIndex].pos[2] = pos.z; @@ -71,14 +72,15 @@ void OSnowman::Tick() { } } - //for (var_s0 = 0; var_s0 < NUM_SNOWMEN; var_s0++) { + // for (var_s0 = 0; var_s0 < NUM_SNOWMEN; var_s0++) { var_s4 = _bodyIndex; var_s3 = _headIndex; OSnowman::func_80083A94(var_s3); // snowman head OSnowman::func_80083C04(var_s4); // snowman body if (is_obj_index_flag_status_inactive(var_s4, 0x00001000) != 0) { object = &gObjectList[var_s4]; - if ((are_players_in_course_section(object->unk_0D5 - 1, object->unk_0D5 + 1) != 0) && (func_80089B50(var_s4) != 0)) { + if ((are_players_in_course_section(object->unk_0D5 - 1, object->unk_0D5 + 1) != 0) && + (func_80089B50(var_s4) != 0)) { set_object_flag(var_s4, 0x00001000); clear_object_flag(var_s4, 0x00000010); func_800726CC(var_s4, 0x0000000A); @@ -93,6 +95,7 @@ void OSnowman::Tick() { } void OSnowman::Draw(s32 cameraId) { + OSnowman::DrawHead(cameraId); OSnowman::DrawBody(cameraId); } @@ -117,23 +120,29 @@ void OSnowman::DrawHead(s32 cameraId) { if (gObjectList[objectIndex].state >= 2) { func_8008A364(objectIndex, cameraId, 0x2AABU, 0x00000258); if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("OSnowman::DrawHead", (uintptr_t) &gObjectList[objectIndex]); + D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0]; D_80183E80[1] = func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos); D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2]; if (is_obj_flag_status_active(objectIndex, 0x00000010) != 0) { draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80, - gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, - (u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, - 0x00000040, 0x00000040, 0x00000040, 0x00000020); + gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, + (u8*) gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, + 0x00000040, 0x00000040, 0x00000040, 0x00000020); } objectIndex = _headIndex; D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0]; D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2]; - draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80, - gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, - (u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 0x00000040, - 0x00000040, 0x00000040, 0x00000020); + draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80, gObjectList[objectIndex].sizeScaling, + (u8*) gObjectList[objectIndex].activeTLUT, (u8*) gObjectList[objectIndex].activeTexture, + gObjectList[objectIndex].vertex, 0x00000040, 0x00000040, 0x00000040, 0x00000020); + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } } @@ -146,7 +155,8 @@ void OSnowman::DrawBody(s32 cameraId) { Object* object; sp44 = &camera1[cameraId]; - load_texture_and_tlut((u8*)d_course_frappe_snowland_snow_tlut, (u8*)d_course_frappe_snowland_snow, 0x00000020, 0x00000020); + load_texture_and_tlut((u8*) d_course_frappe_snowland_snow_tlut, (u8*) d_course_frappe_snowland_snow, 0x00000020, + 0x00000020); //! @todo quick hack to add the snow particles on hit. Need to separate into its own class if (_idx == 0) { @@ -157,9 +167,16 @@ void OSnowman::DrawBody(s32 cameraId) { if (object->state > 0) { func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000001F4); if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("OSnowman::DrawBody", (uintptr_t) object); + object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], sp44->pos); rsp_set_matrix_gObjectList(objectIndex); - gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0069E0); + gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D0069E0); + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } } @@ -215,7 +232,8 @@ void OSnowman::func_80083BE4(s32 objectIndex) { void OSnowman::func_80083868(s32 objectIndex) { Object* object; Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(D_0D0061B0); - init_texture_object(objectIndex, (u8*)d_course_frappe_snowland_snowman_tlut, (const char**)sSnowmanHeadList, 0x40U, (u16) 0x00000040); + init_texture_object(objectIndex, (u8*) d_course_frappe_snowland_snowman_tlut, (const char**) sSnowmanHeadList, + 0x40U, (u16) 0x00000040); object = &gObjectList[objectIndex]; object->vertex = vtx; object->sizeScaling = 0.1f; @@ -259,7 +277,8 @@ void OSnowman::func_80083948(s32 objectIndex) { break; } object_calculate_new_pos_offset(objectIndex); - OSnowman::func_80073D0C(objectIndex, &gObjectList[objectIndex].primAlpha, -0x00001000, 0x00001000, 0x00000400, 1, -1); + OSnowman::func_80073D0C(objectIndex, &gObjectList[objectIndex].primAlpha, -0x00001000, 0x00001000, 0x00000400, 1, + -1); gObjectList[objectIndex].orientation[2] = gObjectList[objectIndex].primAlpha + 0x8000; } @@ -285,7 +304,8 @@ static const char* sSnowmanBodyList[] = { d_course_frappe_snowland_snowman_body void OSnowman::func_80083B0C(s32 objectIndex) { Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog); - init_texture_object(objectIndex, (u8*)d_course_frappe_snowland_snowman_tlut, (const char**)sSnowmanBodyList, 0x40U, (u16) 0x00000040); + init_texture_object(objectIndex, (u8*) d_course_frappe_snowland_snowman_tlut, (const char**) sSnowmanBodyList, + 0x40U, (u16) 0x00000040); gObjectList[objectIndex].vertex = vtx; gObjectList[objectIndex].sizeScaling = 0.1f; gObjectList[objectIndex].textureListIndex = 0; @@ -299,16 +319,15 @@ void OSnowman::func_80083B0C(s32 objectIndex) { set_object_flag(objectIndex, 0x04000210); } - void OSnowman::func_80083538(s32 objectIndex, Vec3f arg1, s32 arg2, s32 arg3) { Object* object; init_object(objectIndex, 0); object = &gObjectList[objectIndex]; - object->activeTexture = (const char*)d_course_frappe_snowland_snow; - object->textureList = (const char**)d_course_frappe_snowland_snow; + object->activeTexture = (const char*) d_course_frappe_snowland_snow; + object->textureList = (const char**) d_course_frappe_snowland_snow; object->activeTLUT = d_course_frappe_snowland_snow_tlut; - object->tlutList = (u8*)d_course_frappe_snowland_snow_tlut; + object->tlutList = (u8*) d_course_frappe_snowland_snow_tlut; object->sizeScaling = random_int(0x0064U); object->sizeScaling = (object->sizeScaling * 0.001) + 0.05; object->velocity[1] = random_int(0x0014U); From a3e93e36db0e0542f232389445836a19dd62cb90 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Tue, 20 May 2025 02:01:52 -0500 Subject: [PATCH 51/85] Interpolated player reflection(sherbet land) --- src/render_player.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/render_player.c b/src/render_player.c index b101e00b9..c8b23d5a3 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -1891,6 +1891,9 @@ void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 a arg3 = 0; } + // @port: Tag the transform. + //FrameInterpolation_RecordOpenChild("PlayerReflection", playerId); + mtxf_translate_rotate(mtx, sp9C, sp94); mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size); // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx); @@ -1918,6 +1921,9 @@ void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 a gSPDisplayList(gDisplayListHead++, common_square_plain_render); gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); gMatrixEffectCount += 1; + + // @port Pop the transform id. + //FrameInterpolation_RecordCloseChild(); } void render_player(Player* player, s8 playerId, s8 screenId) { From 2bbc496bf2f9e404244fbd84e9ba88f5eb9af521 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Tue, 20 May 2025 02:04:48 -0500 Subject: [PATCH 52/85] Forgot to uncomment stuff while testing --- src/render_player.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/render_player.c b/src/render_player.c index c8b23d5a3..aaed5fe29 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -1892,7 +1892,7 @@ void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 a } // @port: Tag the transform. - //FrameInterpolation_RecordOpenChild("PlayerReflection", playerId); + FrameInterpolation_RecordOpenChild("PlayerReflection", playerId); mtxf_translate_rotate(mtx, sp9C, sp94); mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size); @@ -1923,7 +1923,7 @@ void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 a gMatrixEffectCount += 1; // @port Pop the transform id. - //FrameInterpolation_RecordCloseChild(); + FrameInterpolation_RecordCloseChild(); } void render_player(Player* player, s8 playerId, s8 screenId) { From a3319495706d9be84294d8f8a21a0ea6a83c02a4 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 16:32:26 -0300 Subject: [PATCH 53/85] better tag --- src/render_player.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render_player.c b/src/render_player.c index aaed5fe29..017b0fd18 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -1892,7 +1892,7 @@ void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 a } // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("PlayerReflection", playerId); + FrameInterpolation_RecordOpenChild("PlayerReflection", playerId | screenId << 8); mtxf_translate_rotate(mtx, sp9C, sp94); mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size); From 4a6ebfdc78452faced41470413e01fe21d54cbb1 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 16:48:25 -0300 Subject: [PATCH 54/85] tag leaves --- src/render_objects.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/render_objects.c b/src/render_objects.c index b6b849d31..edc8d69d6 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3387,15 +3387,19 @@ void func_800514BC(void) { } void render_object_leaf_particle(UNUSED s32 cameraId) { - s32 someIndex; + size_t i; s32 leafIndex; Object* object; gSPDisplayList(gDisplayListHead++, D_0D0079C8); gSPClearGeometryMode(gDisplayListHead++, G_CULL_BOTH); load_texture_block_rgba16_mirror((u8*) common_texture_particle_leaf, 0x00000020, 0x00000010); - for (someIndex = 0; someIndex < gLeafParticle_SIZE; someIndex++) { - leafIndex = gLeafParticle[someIndex]; + for (i = 0; i < gLeafParticle_SIZE; i++) { + leafIndex = gLeafParticle[i]; + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Leaves", leafIndex); + if (leafIndex != -1) { object = &gObjectList[leafIndex]; if ((object->state >= 2) && (object->unk_0D5 == 7) && (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) { @@ -3403,23 +3407,27 @@ void render_object_leaf_particle(UNUSED s32 cameraId) { gSPDisplayList(gDisplayListHead++, D_0D0069C8); } } + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); } void render_object_snowflakes_particles(void) { - s32 someIndex; + size_t i; s32 snowflakeIndex; gSPDisplayList(gDisplayListHead++, D_0D007AE0); gDPSetCombineLERP(gDisplayListHead++, 1, 0, SHADE, 0, 0, 0, 0, TEXEL0, 1, 0, SHADE, 0, 0, 0, 0, TEXEL0); func_80044F34(D_0D0293D8, 0x10, 0x10); - for (someIndex = 0; someIndex < NUM_SNOWFLAKES; someIndex++) { - snowflakeIndex = gObjectParticle1[someIndex]; + for (i = 0; i < NUM_SNOWFLAKES; i++) { + snowflakeIndex = gObjectParticle1[i]; // @port: Tag the transform. FrameInterpolation_RecordOpenChild("SnowFlakes", snowflakeIndex); + if (gObjectList[snowflakeIndex].state >= 2) { rsp_set_matrix_gObjectList(snowflakeIndex); gSPDisplayList(gDisplayListHead++, D_0D006980); @@ -3454,7 +3462,7 @@ void func_800518F8(s32 objectIndex, s16 x, s16 y) { } if (gObjectList[objectIndex].status & 0x10) { - + // @port: Tag the transform. FrameInterpolation_RecordOpenChild("func_800518F8", (uintptr_t) &gObjectList[objectIndex]); From 1fee189805ea668b0b294bc70d8593bb87e044ae Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Tue, 20 May 2025 14:50:12 -0500 Subject: [PATCH 55/85] Set the default FPS to 30 --- src/port/Engine.cpp | 6 +++--- src/port/interpolation/FrameInterpolation.cpp | 2 +- src/port/ui/PortMenu.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index cc7d0755d..c8734fab4 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -233,10 +233,10 @@ uint32_t GameEngine::GetInterpolationFPS() { } else if (CVarGetInteger("gVsyncEnabled", 1) || !Ship::Context::GetInstance()->GetWindow()->CanDisableVerticalSync()) { return std::min(Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(), - CVarGetInteger("gInterpolationFPS", 60)); + CVarGetInteger("gInterpolationFPS", 30)); } - return CVarGetInteger("gInterpolationFPS", 60); + return CVarGetInteger("gInterpolationFPS", 30); } uint32_t GameEngine::GetInterpolationFrameCount() @@ -360,7 +360,7 @@ void GameEngine::ProcessGfxCommands(Gfx* commands) { int fps = target_fps; int original_fps = 60 / 2 /*gVIsPerFrame*/; - if (target_fps == 20 || original_fps > target_fps) { + if (target_fps == 30 || original_fps > target_fps) { fps = original_fps; } diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index 3d1512f55..d0e0fe0f0 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -565,7 +565,7 @@ void FrameInterpolation_StartRecord(void) { is_recording = false; return; } - if (GameEngine::GetInterpolationFPS() != 20) { + if (GameEngine::GetInterpolationFPS() != 30) { is_recording = true; } } diff --git a/src/port/ui/PortMenu.cpp b/src/port/ui/PortMenu.cpp index 6f2a4ec48..cb709e16b 100644 --- a/src/port/ui/PortMenu.cpp +++ b/src/port/ui/PortMenu.cpp @@ -258,11 +258,11 @@ void PortMenu::AddSettings() { if (mPortMenu->disabledMap.at(DISABLE_FOR_MATCH_REFRESH_RATE_ON).active) info.activeDisables.push_back(DISABLE_FOR_MATCH_REFRESH_RATE_ON); }) - .Options(IntSliderOptions().Tooltip(tooltip).Min(20).Max(maxFps).DefaultValue(20)); + .Options(IntSliderOptions().Tooltip(tooltip).Min(30).Max(maxFps).DefaultValue(30)); AddWidget(path, "Match Refresh Rate", WIDGET_BUTTON) .Callback([](WidgetInfo& info) { int hz = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); - if (hz >= 20 && hz <= 360) { + if (hz >= 30 && hz <= 360) { CVarSetInteger("gInterpolationFPS", hz); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } From 2764ac65954104b368d0c386a78fbb9f82c91757 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 17:10:37 -0300 Subject: [PATCH 56/85] tag hud --- src/code_80057C60.c | 7 +++++++ src/render_objects.c | 46 +++++++++++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 7e609859d..0a8e22749 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -939,6 +939,10 @@ void func_80058F48(void) { void func_80058F78(void) { if (gHUDDisable == 0) { + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("HudMatrix", 0); + set_matrix_hud_screen(); if ((!gDemoMode) && (gIsHUDVisible != 0) && (D_801657D8 == 0)) { draw_item_window(PLAYER_ONE); @@ -951,6 +955,9 @@ void func_80058F78(void) { } } } + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } diff --git a/src/render_objects.c b/src/render_objects.c index edc8d69d6..e3a5d869d 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3051,47 +3051,57 @@ void func_8004FDB4(f32 arg0, f32 arg1, s16 arg2, s16 arg3, s16 characterId, s32 void func_80050320(void) { s16 temp_v0; s16 characterId; - s32 var_s0; + s32 i; s32 lapCount; s32 var_a0; if (D_801657E2 == 0) { - for (var_s0 = 0; var_s0 < 4; var_s0++) { + for (i = 0; i < 4; i++) { var_a0 = 0; - if (D_8018D050[var_s0] >= 0.0f) { - if (D_8018D078[var_s0] < 0.0) { + if (D_8018D050[i] >= 0.0f) { + if (D_8018D078[i] < 0.0) { var_a0 = 1; } - temp_v0 = gGPCurrentRacePlayerIdByRank[var_s0]; - characterId = gGPCurrentRaceCharacterIdByRank[var_s0]; + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("ranking portraits", i | var_a0 << 16); + + temp_v0 = gGPCurrentRacePlayerIdByRank[i]; + characterId = gGPCurrentRaceCharacterIdByRank[i]; lapCount = gLapCountByPlayerId[temp_v0]; if (characterId == gPlayerOne->characterId) { - func_8004FDB4(D_8018D028[var_s0], D_8018D050[var_s0], var_s0, lapCount, characterId, 0x000000FF, 1, - var_a0, 0); + func_8004FDB4(D_8018D028[i], D_8018D050[i], i, lapCount, characterId, 0x000000FF, 1, var_a0, 0); } else { - func_8004FDB4(D_8018D028[var_s0], D_8018D050[var_s0], var_s0, lapCount, characterId, D_8018D3E0, 0, - var_a0, 0); + func_8004FDB4(D_8018D028[i], D_8018D050[i], i, lapCount, characterId, D_8018D3E0, 0, var_a0, 0); } + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } } else { - for (var_s0 = 0; var_s0 < 8; var_s0++) { + for (i = 0; i < 8; i++) { var_a0 = 0; - if (D_8018D050[var_s0] >= 0.0f) { - if (D_8018D078[var_s0] <= 0.0) { + if (D_8018D050[i] >= 0.0f) { + if (D_8018D078[i] <= 0.0) { var_a0 = 1; } - temp_v0 = gGPCurrentRacePlayerIdByRank[var_s0]; + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("ranking portraits 2", i | var_a0 << 16); + + temp_v0 = gGPCurrentRacePlayerIdByRank[i]; // ???? characterId = (gPlayerOne + temp_v0)->characterId; lapCount = gLapCountByPlayerId[temp_v0]; if (temp_v0 == 0) { - func_8004FDB4(D_8018D028[var_s0], D_8018D050[var_s0], var_s0, lapCount, characterId, 0x000000FF, 1, - var_a0, 1); + func_8004FDB4(D_8018D028[i], D_8018D050[i], i, lapCount, characterId, 0x000000FF, 1, var_a0, 1); } else { - func_8004FDB4(D_8018D028[var_s0], D_8018D050[var_s0], var_s0, lapCount, characterId, 0x000000FF, 0, - var_a0, 1); + func_8004FDB4(D_8018D028[i], D_8018D050[i], i, lapCount, characterId, 0x000000FF, 0, var_a0, 1); } + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } } From 939064476c3bb774afd12d108081296cb4dc07dd Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Tue, 20 May 2025 16:09:51 -0500 Subject: [PATCH 57/85] Fixed "Match Refresh Rate" option --- src/port/Engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index c8734fab4..15acab0ac 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -385,7 +385,7 @@ void GameEngine::ProcessGfxCommands(Gfx* commands) { auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); if (wnd != nullptr) { - wnd->SetTargetFps(CVarGetInteger("gInterpolationFPS", 30)); + wnd->SetTargetFps(GetInterpolationFPS()); wnd->SetMaximumFrameLatency(1); } RunCommands(commands, mtx_replacements); From 8fb85b9e724af1a798522c1f60e86b845144875f Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 18:27:41 -0300 Subject: [PATCH 58/85] adjust draw distance --- src/racing/math_util.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/racing/math_util.c b/src/racing/math_util.c index a67bc7f65..43143fa7d 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -8,12 +8,14 @@ #include "math.h" #include "memory.h" #include "engine/Matrix.h" +#include "course.h" #include "port/Game.h" #include #include - #pragma intrinsic(sqrtf, fabs) +extern s16 gCurrentCourseId; + s32 D_802B91C0[2] = { 13, 13 }; Vec3f D_802B91C8 = { 0.0f, 0.0f, 0.0f }; @@ -55,7 +57,7 @@ s32 render_set_position(Mat4 mtx, s32 arg1) { if (gMatrixObjectCount >= MTX_OBJECT_POOL_SIZE) { return 0; } - //mtxf_to_mtx(&gGfxPool->mtxObject[gMatrixObjectCount], arg0); + // mtxf_to_mtx(&gGfxPool->mtxObject[gMatrixObjectCount], arg0); switch (arg1) { /* irregular */ case 0: AddObjectMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -1103,16 +1105,22 @@ s32 is_visible_between_angle(u16 arg0, u16 arg1, u16 arg2) { f32 is_within_render_distance(Vec3f cameraPos, Vec3f objectPos, u16 orientationY, f32 minDistance, f32 fov, f32 maxDistance) { u16 angleObject; - UNUSED u16 pad; u16 temp_v0; f32 distanceX; f32 distance; f32 distanceY; + f32 scaleFov; + f32 maxDistance2; s32 plus_fov_angle; s32 minus_fov_angle; u16 temp; - UNUSED s32 pad2[3]; - u16 extended_fov = ((u16) fov * 0xB6); + s32 count = 0; + + maxDistance *= 6.5f; + maxDistance2 = 1.0f; + scaleFov = 1.25; + + f32 extended_fov = ((f32) fov * 0xB6 * scaleFov); // Sets the Culling for objects on the left and right distanceX = objectPos[0] - cameraPos[0]; distanceX = distanceX * distanceX; @@ -1141,19 +1149,28 @@ f32 is_within_render_distance(Vec3f cameraPos, Vec3f objectPos, u16 orientationY if (minDistance == 0.0f) { if (is_visible_between_angle((orientationY + extended_fov), (orientationY - extended_fov), angleObject) == 1) { - return distance; + if (gCurrentCourseId == 0xB /* COURSE_KALAMARI_DESERT */) { + return distance / 6.5f; // set for better DD settings in Desert + } else { + return distance / 10.0f; // Items + } } return -1.0f; } if (is_visible_between_angle((u16) plus_fov_angle, (u16) minus_fov_angle, angleObject) == 1) { - return distance; + if (gCurrentCourseId == 0xB /* COURSE_KALAMARI_DESERT */) { + return distance / 2.0f; + } else { + return distance / 10.0f; // DD Vhicles + } } + temp_v0 = func_802B7CA8(minDistance / distance); temp = angleObject + temp_v0; if (is_visible_between_angle(plus_fov_angle, minus_fov_angle, temp) == 1) { - return distance; + return 0; } temp = angleObject - temp_v0; From 86dc0b0a998519ca33efaaafc2945c6b095de979 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 18:56:57 -0300 Subject: [PATCH 59/85] remove innecessary rock tag --- src/actors/falling_rock/render.inc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/actors/falling_rock/render.inc.c b/src/actors/falling_rock/render.inc.c index 9d50fd41c..e5ea29188 100644 --- a/src/actors/falling_rock/render.inc.c +++ b/src/actors/falling_rock/render.inc.c @@ -17,9 +17,6 @@ void render_actor_falling_rock(Camera* camera, struct FallingRock* rock) { f32 height; UNUSED s32 pad[4]; - // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("rock", TAG_ITEM_ADDR(rock)); //Not working properly just yet - if (rock->respawnTimer != 0) { return; } @@ -55,11 +52,10 @@ void render_actor_falling_rock(Camera* camera, struct FallingRock* rock) { } mtxf_pos_rotation_xyz(mtx, rock->pos, rock->rot); + if (render_set_position(mtx, 0) == 0) { return; } - gSPDisplayList(gDisplayListHead++, d_course_choco_mountain_dl_falling_rock); - // @port Pop the transform id. - FrameInterpolation_RecordCloseChild(); + gSPDisplayList(gDisplayListHead++, d_course_choco_mountain_dl_falling_rock); } From f11728b31da9b35c8fcbe69eca123d6887b764d8 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 19:00:55 -0300 Subject: [PATCH 60/85] rag rocks --- src/actors/falling_rock/render.inc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/actors/falling_rock/render.inc.c b/src/actors/falling_rock/render.inc.c index e5ea29188..35876e3a0 100644 --- a/src/actors/falling_rock/render.inc.c +++ b/src/actors/falling_rock/render.inc.c @@ -51,11 +51,17 @@ void render_actor_falling_rock(Camera* camera, struct FallingRock* rock) { } } - mtxf_pos_rotation_xyz(mtx, rock->pos, rock->rot); + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("rock", TAG_ITEM_ADDR(rock)); // Not working properly just yet + mtxf_pos_rotation_xyz(mtx, rock->pos, rock->rot); if (render_set_position(mtx, 0) == 0) { + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); return; } - gSPDisplayList(gDisplayListHead++, d_course_choco_mountain_dl_falling_rock); + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } From 64e2a39b446cd358181c0350660e98423d0914f1 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 19:01:56 -0300 Subject: [PATCH 61/85] better tag --- src/actors/falling_rock/render.inc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actors/falling_rock/render.inc.c b/src/actors/falling_rock/render.inc.c index 35876e3a0..d0d5aa0dc 100644 --- a/src/actors/falling_rock/render.inc.c +++ b/src/actors/falling_rock/render.inc.c @@ -52,7 +52,7 @@ void render_actor_falling_rock(Camera* camera, struct FallingRock* rock) { } // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("rock", TAG_ITEM_ADDR(rock)); // Not working properly just yet + FrameInterpolation_RecordOpenChild("rock", (uintptr_t) rock); mtxf_pos_rotation_xyz(mtx, rock->pos, rock->rot); if (render_set_position(mtx, 0) == 0) { From 46abc4f6fccfe8fd4c6c9c9b67e8ddcf0385f988 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Tue, 20 May 2025 17:03:04 -0500 Subject: [PATCH 62/85] Tagged player rank placement in HUD --- src/render_objects.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/render_objects.c b/src/render_objects.c index e3a5d869d..ec452f1e0 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -2629,6 +2629,8 @@ void draw_simplified_lap_count(s32 playerId) { } void func_8004E800(s32 playerId) { + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Player place HUD", playerId << 8); if (playerHUD[playerId].unk_81 != 0) { if (playerHUD[playerId].lapCount != 3) { func_8004A384(playerHUD[playerId].rankX + playerHUD[playerId].slideRankX, @@ -2644,6 +2646,8 @@ void func_8004E800(s32 playerId) { 0x00000040, 0x00000080, 0x00000040); } } + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } void func_8004E998(s32 playerId) { From 02d6c6fc99301ec282189285c44101a78804a063 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Tue, 20 May 2025 17:03:38 -0500 Subject: [PATCH 63/85] Tagged Bat, Boos, and TrashBin(Banshee Boardwalk objects) --- src/engine/objects/Bat.cpp | 9 +++++++++ src/engine/objects/Boos.cpp | 5 +++++ src/engine/objects/TrashBin.cpp | 8 ++++++++ 3 files changed, 22 insertions(+) diff --git a/src/engine/objects/Bat.cpp b/src/engine/objects/Bat.cpp index 764476064..2056a17f7 100644 --- a/src/engine/objects/Bat.cpp +++ b/src/engine/objects/Bat.cpp @@ -1,6 +1,7 @@ #include "Bat.h" #include "World.h" #include "CoreMath.h" +#include "port/interpolation/FrameInterpolation.h" extern "C" { #include "render_objects.h" @@ -113,6 +114,8 @@ void OBat::Draw(s32 cameraId) { D_80183E80[2] = gObjectList[objectIndex].orientation[2]; if ((D_8018CFB0 != 0) || (D_8018CFC8 != 0)) { for (var_s2 = 0; var_s2 < 40; var_s2++) { + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Bat set 1", var_s2); objectIndex = gObjectParticle2[var_s2]; if (objectIndex == -1) { continue; @@ -124,10 +127,14 @@ void OBat::Draw(s32 cameraId) { func_800431B0(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling, (Vtx*)D_0D0062B0); } + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } if ((D_8018CFE8 != 0) || (D_8018D000 != 0)) { for (var_s2 = 0; var_s2 < 30; var_s2++) { + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Bat set 2", var_s2); objectIndex = gObjectParticle3[var_s2]; if (objectIndex == -1) { continue; @@ -139,6 +146,8 @@ void OBat::Draw(s32 cameraId) { func_800431B0(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling, (Vtx*)D_0D0062B0); } + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } gSPTexture(gDisplayListHead++, 0x0001, 0x0001, 0, G_TX_RENDERTILE, G_OFF); diff --git a/src/engine/objects/Boos.cpp b/src/engine/objects/Boos.cpp index 5bdbd41cf..69bb95072 100644 --- a/src/engine/objects/Boos.cpp +++ b/src/engine/objects/Boos.cpp @@ -1,6 +1,7 @@ #include "Boos.h" #include "World.h" #include "CoreMath.h" +#include "port/interpolation/FrameInterpolation.h" extern "C" { #include "render_objects.h" @@ -82,6 +83,8 @@ void OBoos::Draw(s32 cameraId) { s32 objectIndex; for (size_t i = 0; i < _numBoos; i++) { + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Boo", i); objectIndex = _indices[i]; //indexObjectList3[i]; if (gObjectList[objectIndex].state >= 2) { temp_s2 = func_8008A364(objectIndex, cameraId, 0x4000U, 0x00000320); @@ -92,6 +95,8 @@ void OBoos::Draw(s32 cameraId) { func_800523B8(objectIndex, cameraId, temp_s2); } } + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } diff --git a/src/engine/objects/TrashBin.cpp b/src/engine/objects/TrashBin.cpp index c94d0352f..e721f299c 100644 --- a/src/engine/objects/TrashBin.cpp +++ b/src/engine/objects/TrashBin.cpp @@ -3,6 +3,7 @@ #include "TrashBin.h" #include "World.h" #include "port/Game.h" +#include "port/interpolation/FrameInterpolation.h" extern "C" { #include "main.h" @@ -62,11 +63,18 @@ void OTrashBin::Draw(s32 cameraId) { Mat4 mtx; Vec3f Pos = { _pos.x + 63, _pos.y + 12, _pos.z + 25 }; Vec3s Rot = { 0, 0x4000, 0 }; + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Bin", mtx); + mtxf_pos_rotation_xyz(mtx, Pos, Rot); //mtxf_scale(mtx, 1.0f); if (render_set_position(mtx, 0) != 0) { gSPDisplayList(gDisplayListHead++, BinMod); } + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } } From a364421b093fde425e4d8b11a8629b39ddb68288 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Tue, 20 May 2025 17:41:00 -0600 Subject: [PATCH 64/85] Refactor render_screens and fix editor raycast --- src/engine/editor/EditorMath.cpp | 8 ++-- src/racing/skybox_and_splitscreen.c | 60 ++++++++++------------------- 2 files changed, 24 insertions(+), 44 deletions(-) diff --git a/src/engine/editor/EditorMath.cpp b/src/engine/editor/EditorMath.cpp index 44923e08e..04a299563 100644 --- a/src/engine/editor/EditorMath.cpp +++ b/src/engine/editor/EditorMath.cpp @@ -31,9 +31,9 @@ bool IsInGameScreen() { // Define viewport boundaries auto gfx_current_game_window_viewport = GetInterpreter()->mGameWindowViewport; - int left = gfx_current_game_window_viewport.width; + int left = gfx_current_game_window_viewport.x; int right = left + OTRGetGameRenderWidth(); - int top = gfx_current_game_window_viewport.height; + int top = gfx_current_game_window_viewport.y; int bottom = top + OTRGetGameRenderHeight(); // Check if the mouse is within the game render area @@ -46,8 +46,8 @@ FVector ScreenRayTrace() { Ship::Coords mouse = wnd->GetMousePos(); auto gfx_current_game_window_viewport = GetInterpreter()->mGameWindowViewport; - mouse.x -= gfx_current_game_window_viewport.width; - mouse.y -= gfx_current_game_window_viewport.height; + mouse.x -= gfx_current_game_window_viewport.x; + mouse.y -= gfx_current_game_window_viewport.y; // Get screen dimensions uint32_t width = OTRGetGameViewportWidth(); uint32_t height = OTRGetGameViewportHeight(); diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index 87fa1390f..820d83ecb 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -756,6 +756,7 @@ void func_802A5760(void) { } } +// Setup the cameras perspective and lookAt (movement/rotation) void setup_camera(Camera* camera, s32 playerId, s32 cameraId, struct UnkStruct_800DC5EC* screen) { Mat4 matrix; u16 perspNorm; @@ -765,26 +766,19 @@ void setup_camera(Camera* camera, s32 playerId, s32 cameraId, struct UnkStruct_8 return; } - FrameInterpolation_RecordOpenChild("camerapersp", FrameInterpolation_GetCameraEpoch()); + // Setup perspective (camera movement) + FrameInterpolation_RecordOpenChild("camera", FrameInterpolation_GetCameraEpoch()); guPerspective(&gGfxPool->mtxPersp[cameraId], &perspNorm, gCameraZoom[cameraId], gScreenAspect, - CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); - + CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[cameraId]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + // Setup lookAt (camera rotation) guLookAt(&gGfxPool->mtxLookAt[cameraId], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0], camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]); - if (D_800DC5C8 == 0) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } else { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - - } + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]), + G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); FrameInterpolation_RecordCloseChild(); } @@ -870,36 +864,22 @@ D_func_800652D4_counter = 0; func_802A3730(screen); gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH); gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); - //FrameInterpolation_RecordOpenChild("SCREENCAMERA", (playerId | cameraId) << 8); - setup_camera(camera, playerId, cameraId, screen); // Setup camera perspective and lookAt -// render_course(screen); + // Setup camera perspective and lookAt + setup_camera(camera, playerId, cameraId, screen); + + // Create a matrix for the track and game objects + FrameInterpolation_RecordOpenChild("track", (playerId | cameraId) << 8); + Mat4 trackMatrix; + mtxf_identity(trackMatrix); + render_set_position(trackMatrix, 0); -//FrameInterpolation_RecordOpenChild("track", 0); -//Mat4 trackMtx; -//mtxf_identity(trackMtx); -//AddObjectMatrix(trackMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); -render_course(screen); -//FrameInterpolation_RecordCloseChild(); - - - //Mat4 projectionF; - //Matrix_MtxToMtxF(&gGfxPool->mtxLookAt[cameraId], &projectionF); - // SkinMatrix_MtxFMtxFMult(&projectionF, &flipF, &projectionF); - // FrameInterpolation_RecordCloseChild(); - - - - if (D_800DC5C8 == 1) { - //PushLookAtMtx(gGfxPool->mtxLookAt[cameraId], G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } + // Draw course and game objects + render_course(screen); render_course_actors(screen); CM_DrawStaticMeshActors(); render_object(mode); + switch (screenId) { case 0: render_players_on_screen_one(); @@ -946,7 +926,7 @@ render_course(screen); if (mode != RENDER_SCREEN_MODE_1P_PLAYER_ONE) { gNumScreens += 1; } - + FrameInterpolation_RecordCloseChild(); } void func_802A74BC(void) { From a33f296e0f0b55106d5f4744798e00b2fffd7620 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 21:50:52 -0300 Subject: [PATCH 65/85] better object interpolation --- src/math_util_2.c | 53 +++++++++++++++++++++++++++++++++----------- src/math_util_2.h | 2 +- src/render_objects.c | 24 +++++++++++--------- 3 files changed, 54 insertions(+), 25 deletions(-) diff --git a/src/math_util_2.c b/src/math_util_2.c index e4fc571d5..b113c6a5d 100644 --- a/src/math_util_2.c +++ b/src/math_util_2.c @@ -690,13 +690,13 @@ UNUSED void func_800421FC(s32 x, s32 y, f32 scale) { void func_80042330(s32 x, s32 y, u16 angle, f32 scale) { Mat4 matrix; - //printf("panel %d %d %d\n", x, (s32)OTRGetDimensionFromLeftEdge(x), (s32)OTRGetDimensionFromLeftEdge(0)); + // printf("panel %d %d %d\n", x, (s32)OTRGetDimensionFromLeftEdge(x), (s32)OTRGetDimensionFromLeftEdge(0)); if (gHUDModes != 2) { if (x < (SCREEN_WIDTH / 2)) { - x = (s32)OTRGetDimensionFromLeftEdge(x); + x = (s32) OTRGetDimensionFromLeftEdge(x); } else { - x = (s32)OTRGetDimensionFromRightEdge(x); + x = (s32) OTRGetDimensionFromRightEdge(x); } } @@ -710,7 +710,7 @@ void func_80042330(s32 x, s32 y, u16 angle, f32 scale) { void func_80042330_unchanged(s32 x, s32 y, u16 angle, f32 scale) { Mat4 matrix; - //printf("panel %d %d %d\n", x, (s32)OTRGetDimensionFromLeftEdge(x), (s32)OTRGetDimensionFromLeftEdge(0)); + // printf("panel %d %d %d\n", x, (s32)OTRGetDimensionFromLeftEdge(x), (s32)OTRGetDimensionFromLeftEdge(0)); mtxf_translation_x_y_rotate_z_scale_x_y(matrix, x, y, angle, scale); // convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); @@ -723,13 +723,13 @@ void func_80042330_unchanged(s32 x, s32 y, u16 angle, f32 scale) { // Allows a different way of lining up the portraits at the end of race sequence void func_80042330_portrait(s32 x, s32 y, u16 angle, f32 scale, s16 lapCount) { Mat4 matrix; - //printf("panel %d %d %d\n", x, (s32)OTRGetDimensionFromLeftEdge(x), (s32)OTRGetDimensionFromLeftEdge(0)); + // printf("panel %d %d %d\n", x, (s32)OTRGetDimensionFromLeftEdge(x), (s32)OTRGetDimensionFromLeftEdge(0)); if ((gHUDModes != 2) && (D_801657E2 == 0) || (CVarGetInteger("gImprovements", 0) == true)) { if (x < (SCREEN_WIDTH / 2)) { - x = (s32)OTRGetDimensionFromLeftEdge(x); + x = (s32) OTRGetDimensionFromLeftEdge(x); } else { - x = (s32)OTRGetDimensionFromRightEdge(x); + x = (s32) OTRGetDimensionFromRightEdge(x); } } @@ -745,9 +745,9 @@ void func_80042330_wide(s32 x, s32 y, u16 angle, f32 scale) { Mat4 matrix; if (x < (SCREEN_WIDTH / 2)) { - x = (s32)OTRGetDimensionFromLeftEdge(x); + x = (s32) OTRGetDimensionFromLeftEdge(x); } else { - x = (s32)OTRGetDimensionFromRightEdge(x); + x = (s32) OTRGetDimensionFromRightEdge(x); } mtxf_translation_x_y_rotate_z_scale_x_y(matrix, x, y, angle, scale); @@ -808,8 +808,7 @@ UNUSED void func_8004252C(Mat4 arg0, u16 arg1, u16 arg2) { arg0[2][2] = sp28 * cos_theta_y; } -void mtxf_set_matrix_transformation(Mat4 transformMatrix, Vec3f location, Vec3su rotation, - f32 scale) { +void mtxf_set_matrix_transformation(Mat4 transformMatrix, Vec3f location, Vec3su rotation, f32 scale) { FrameInterpolation_RecordSetMatrixTransformation(transformMatrix, location, rotation, scale); f32 sinX = sins(rotation[0]); @@ -864,7 +863,13 @@ void mtxf_set_matrix_scale_transl(Mat4 transformMatrix, Vec3f vec1, Vec3f vec2, * @param arg1 **/ -void mtxf_set_matrix_gObjectList(s32 objectIndex, Mat4 transformMatrix) { +struct ObjectInterpData2 { + s32 objectIndex; + f32 x, y; +}; +struct ObjectInterpData2 prevObject2[OBJECT_LIST_SIZE] = { 0 }; + +s32 mtxf_set_matrix_gObjectList(s32 objectIndex, Mat4 transformMatrix) { f32 sinX; Object* object = &gObjectList[objectIndex]; f32 sinY; @@ -896,6 +901,26 @@ void mtxf_set_matrix_gObjectList(s32 objectIndex, Mat4 transformMatrix) { transformMatrix[1][3] = 0.0f; transformMatrix[2][3] = 0.0f; transformMatrix[3][3] = 1.0f; + + // Search all recorded objects for the one we're drawing + for (int i = 0; i < OBJECT_LIST_SIZE; i++) { + if (objectIndex == prevObject2[i].objectIndex) { + // Coincidence! + // Skip drawing the object this frame if it warped to the other side of the screen + if ((fabsf(object->pos[0] - prevObject2[i].x) > 20) || (fabsf(object->pos[1] - prevObject2[i].y) > 20)) { + prevObject2[objectIndex].x = object->pos[0]; + prevObject2[objectIndex].y = object->pos[1]; + prevObject2[objectIndex].objectIndex = objectIndex; + // printf("IDX: %d X: %f Y: %f Z: %f\n", objectIndex, object->pos[0], object->pos[1], object->pos[2]); + return 1; + } + } + } + prevObject2[objectIndex].x = object->pos[0]; + prevObject2[objectIndex].y = object->pos[1]; + prevObject2[objectIndex].objectIndex = objectIndex; + + return 0; } UNUSED void mtxf_mult_first_column(Mat4 arg0, f32 arg1) { @@ -1065,7 +1090,9 @@ void rsp_set_matrix_transl_rot_scale(Vec3f arg0, Vec3f arg1, f32 arg2) { void rsp_set_matrix_gObjectList(s32 transformIndex) { Mat4 matrix; - mtxf_set_matrix_gObjectList(transformIndex, matrix); + if (mtxf_set_matrix_gObjectList(transformIndex, matrix)) { + return; + } // convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), diff --git a/src/math_util_2.h b/src/math_util_2.h index 5d0837dd9..52b436301 100644 --- a/src/math_util_2.h +++ b/src/math_util_2.h @@ -76,7 +76,7 @@ void func_80042330_portrait(s32, s32, u16, f32, s16); void func_80042330_wide(s32, s32, u16, f32); void mtxf_set_matrix_transformation(Mat4, Vec3f, Vec3su, f32); void mtxf_set_matrix_scale_transl(Mat4, Vec3f, Vec3f, f32); -void mtxf_set_matrix_gObjectList(s32, Mat4); +s32 mtxf_set_matrix_gObjectList(s32, Mat4); void set_transform_matrix(Mat4 dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle, f32 scaleFactor); void vec3f_rotate_x_y(Vec3f, Vec3f, Vec3s); diff --git a/src/render_objects.c b/src/render_objects.c index e3a5d869d..0bfef1437 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3449,23 +3449,24 @@ void render_object_snowflakes_particles(void) { gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); } -struct CloudInterpData { +struct ObjectInterpData { s32 objectIndex; - s16 x; + s16 x, y; }; -struct CloudInterpData prevClouds[OBJECT_LIST_SIZE] = { 0 }; +struct ObjectInterpData prevObject[OBJECT_LIST_SIZE] = { 0 }; void func_800518F8(s32 objectIndex, s16 x, s16 y) { - // Search all recorded clouds for the one we're drawing + // Search all recorded objects for the one we're drawing for (int i = 0; i < OBJECT_LIST_SIZE; i++) { - if (objectIndex == prevClouds[i].objectIndex) { + if (objectIndex == prevObject[i].objectIndex) { // Coincidence! - // Skip drawing the cloud this frame if it warped to the other side of the screen - if (fabs(x - prevClouds[i].x) > SCREEN_WIDTH / 2) { - prevClouds[objectIndex].x = x; - prevClouds[objectIndex].objectIndex = objectIndex; + // Skip drawing the object this frame if it warped to the other side of the screen + if ((fabs(x - prevObject[i].x) > SCREEN_WIDTH / 2) || (fabs(y - prevObject[i].y) > SCREEN_HEIGHT / 2)) { + prevObject[objectIndex].x = x; + prevObject[objectIndex].y = y; + prevObject[objectIndex].objectIndex = objectIndex; return; } } @@ -3490,8 +3491,9 @@ void func_800518F8(s32 objectIndex, s16 x, s16 y) { } // Save current cloud index and x position - prevClouds[objectIndex].x = x; - prevClouds[objectIndex].objectIndex = objectIndex; + prevObject[objectIndex].x = x; + prevObject[objectIndex].y = y; + prevObject[objectIndex].objectIndex = objectIndex; } void func_800519D4(s32 objectIndex, s16 arg1, s16 arg2) { From 11e4d2a6a9f727c7dc7262e69a28763e0c818fe5 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 21:53:41 -0300 Subject: [PATCH 66/85] shift is not needed here --- src/render_objects.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render_objects.c b/src/render_objects.c index e97e9ea1c..3211d0f9b 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -2630,7 +2630,7 @@ void draw_simplified_lap_count(s32 playerId) { void func_8004E800(s32 playerId) { // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("Player place HUD", playerId << 8); + FrameInterpolation_RecordOpenChild("Player place HUD", playerId); if (playerHUD[playerId].unk_81 != 0) { if (playerHUD[playerId].lapCount != 3) { func_8004A384(playerHUD[playerId].rankX + playerHUD[playerId].slideRankX, From f4f06585c758f2e1ce584496eeec4c65f8461a92 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 21:55:57 -0300 Subject: [PATCH 67/85] fix tag --- src/engine/objects/TrashBin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/objects/TrashBin.cpp b/src/engine/objects/TrashBin.cpp index e721f299c..361b93631 100644 --- a/src/engine/objects/TrashBin.cpp +++ b/src/engine/objects/TrashBin.cpp @@ -65,7 +65,7 @@ void OTrashBin::Draw(s32 cameraId) { Vec3s Rot = { 0, 0x4000, 0 }; // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("Bin", mtx); + FrameInterpolation_RecordOpenChild("Bin", (uintptr_t) object); mtxf_pos_rotation_xyz(mtx, Pos, Rot); //mtxf_scale(mtx, 1.0f); From 1024abdd4afcde0d71866e1b6344436a257ce29b Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 22:06:18 -0300 Subject: [PATCH 68/85] fix tags --- src/engine/objects/Bat.cpp | 55 ++++++++++++++++++--------------- src/engine/objects/Boos.cpp | 11 ++++--- src/engine/objects/TrashBin.cpp | 2 +- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/engine/objects/Bat.cpp b/src/engine/objects/Bat.cpp index 2056a17f7..e4f3a2086 100644 --- a/src/engine/objects/Bat.cpp +++ b/src/engine/objects/Bat.cpp @@ -23,7 +23,7 @@ OBat::OBat(const FVector& pos, const IRotator& rot) { Name = "Bat"; find_unused_obj_index(&_objectIndex); - init_texture_object(_objectIndex, (uint8_t*)d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U, + init_texture_object(_objectIndex, (uint8_t*) d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U, (u16) 0x00000040); gObjectList[_objectIndex].orientation[0] = rot.pitch; gObjectList[_objectIndex].orientation[1] = rot.roll; @@ -102,59 +102,64 @@ void OBat::Tick() { } void OBat::Draw(s32 cameraId) { - s32 var_s2; - s32 objectIndex; - Camera* temp_s7; + s32 i; + s32 objectIndex = _objectIndex; + Camera* cam = &camera1[cameraId]; - objectIndex = _objectIndex; - temp_s7 = &camera1[cameraId]; - OBat::func_80046F60((u8*)gObjectList[objectIndex].activeTLUT, (u8*)gObjectList[objectIndex].activeTexture, 0x00000020, 0x00000040, - 5); + OBat::func_80046F60((u8*) gObjectList[objectIndex].activeTLUT, (u8*) gObjectList[objectIndex].activeTexture, + 0x00000020, 0x00000040, 5); D_80183E80[0] = gObjectList[objectIndex].orientation[0]; D_80183E80[2] = gObjectList[objectIndex].orientation[2]; + if ((D_8018CFB0 != 0) || (D_8018CFC8 != 0)) { - for (var_s2 = 0; var_s2 < 40; var_s2++) { - // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("Bat set 1", var_s2); - objectIndex = gObjectParticle2[var_s2]; + for (i = 0; i < 40; i++) { + objectIndex = gObjectParticle2[i]; if (objectIndex == -1) { continue; } if ((gObjectList[objectIndex].state >= 2) && (gMatrixHudCount < 0x2EF)) { + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Bat set 1", (uintptr_t) &gObjectList[objectIndex]); + D_80183E80[1] = - func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], temp_s7->pos); + func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], cam->pos); func_800431B0(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling, - (Vtx*)D_0D0062B0); + (Vtx*) D_0D0062B0); + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } - // @port Pop the transform id. - FrameInterpolation_RecordCloseChild(); } } + if ((D_8018CFE8 != 0) || (D_8018D000 != 0)) { - for (var_s2 = 0; var_s2 < 30; var_s2++) { - // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("Bat set 2", var_s2); - objectIndex = gObjectParticle3[var_s2]; + for (i = 0; i < 30; i++) { + + objectIndex = gObjectParticle3[i]; if (objectIndex == -1) { continue; } if ((gObjectList[objectIndex].state >= 2) && (gMatrixHudCount < 0x2EF)) { + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Bat set 2", (uintptr_t) &gObjectList[objectIndex]); + D_80183E80[1] = - func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], temp_s7->pos); + func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], cam->pos); func_800431B0(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling, - (Vtx*)D_0D0062B0); + (Vtx*) D_0D0062B0); + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } - // @port Pop the transform id. - FrameInterpolation_RecordCloseChild(); } } gSPTexture(gDisplayListHead++, 0x0001, 0x0001, 0, G_TX_RENDERTILE, G_OFF); } void OBat::func_80046F60(u8* tlut, u8* arg1, s32 arg2, s32 arg3, s32 arg4) { - gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007D78); + gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007D78); gDPLoadTLUT_pal256(gDisplayListHead++, tlut); rsp_load_texture_mask(arg1, arg2, arg3, arg4); } diff --git a/src/engine/objects/Boos.cpp b/src/engine/objects/Boos.cpp index 69bb95072..5f02d7876 100644 --- a/src/engine/objects/Boos.cpp +++ b/src/engine/objects/Boos.cpp @@ -83,20 +83,23 @@ void OBoos::Draw(s32 cameraId) { s32 objectIndex; for (size_t i = 0; i < _numBoos; i++) { - // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("Boo", i); objectIndex = _indices[i]; //indexObjectList3[i]; if (gObjectList[objectIndex].state >= 2) { temp_s2 = func_8008A364(objectIndex, cameraId, 0x4000U, 0x00000320); if (CVarGetInteger("gNoCulling", 0) == 1) { temp_s2 = MIN(temp_s2, 0x15F91U); } + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Boo", (uintptr_t)&gObjectList[objectIndex]); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { func_800523B8(objectIndex, cameraId, temp_s2); } + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } - // @port Pop the transform id. - FrameInterpolation_RecordCloseChild(); } } diff --git a/src/engine/objects/TrashBin.cpp b/src/engine/objects/TrashBin.cpp index 361b93631..89ac5dae5 100644 --- a/src/engine/objects/TrashBin.cpp +++ b/src/engine/objects/TrashBin.cpp @@ -65,7 +65,7 @@ void OTrashBin::Draw(s32 cameraId) { Vec3s Rot = { 0, 0x4000, 0 }; // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("Bin", (uintptr_t) object); + FrameInterpolation_RecordOpenChild("OTrashBin", (uintptr_t) object); mtxf_pos_rotation_xyz(mtx, Pos, Rot); //mtxf_scale(mtx, 1.0f); From fd711e7c695144c473d4f2abb821cddb619544ff Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 22:24:10 -0300 Subject: [PATCH 69/85] mole comments --- src/engine/objects/Mole.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/Mole.cpp b/src/engine/objects/Mole.cpp index 91eeabebf..f623b1f52 100644 --- a/src/engine/objects/Mole.cpp +++ b/src/engine/objects/Mole.cpp @@ -323,6 +323,7 @@ void OMole::func_800821AC(s32 objectIndex, s32 arg1) { } } +// Holes void OMole::func_80054E10(s32 objectIndex) { if (gObjectList[objectIndex].state > 0) { if (is_obj_flag_status_active(objectIndex, 0x00800000) != 0) { @@ -362,7 +363,7 @@ void OMole::func_80054D00(s32 objectIndex, s32 cameraId) { if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("func_80054D00", TAG_OBJECT(&gObjectList[objectIndex])); + FrameInterpolation_RecordOpenChild("func_80054D00", (uintptr_t)&gObjectList[objectIndex]); D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0]; D_80183E80[1] = @@ -378,6 +379,7 @@ void OMole::func_80054D00(s32 objectIndex, s32 cameraId) { } } +// Mole rocks void OMole::func_80054F04(s32 cameraId) { Camera* camera = &camera1[cameraId]; From 0d6db3ad1ec2235d173142b94a2d8e7f264de3ab Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 20 May 2025 22:44:06 -0300 Subject: [PATCH 70/85] comment --- src/render_objects.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/render_objects.c b/src/render_objects.c index 3211d0f9b..515a319f9 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3514,6 +3514,7 @@ void func_800519D4(s32 objectIndex, s16 arg1, s16 arg2) { } } +// Render clouds void func_80051ABC(s16 arg0, s32 arg1) { s32 var_s0; s32 objectIndex; From 6f61776b910cea30f99edf6d087263fd4ca9a991 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Tue, 20 May 2025 22:21:38 -0500 Subject: [PATCH 71/85] Changed how shell flames are interpolated. --- src/render_objects.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/render_objects.c b/src/render_objects.c index 3211d0f9b..9492916f7 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3930,19 +3930,21 @@ void func_8005477C(s32 objectIndex, u8 arg1, Vec3f arg2) { void render_object_smoke_particles(s32 cameraId) { UNUSED s32 stackPadding[2]; Camera* sp54; - s32 var_s0; + s32 i; s32 objectIndex; Object* object; sp54 = &camera1[cameraId]; - FrameInterpolation_RecordOpenChild("SmokeParticles", TAG_OBJECT(sp54)); + gSPDisplayList(gDisplayListHead++, D_0D007AE0); load_texture_block_i8_nomirror(common_texture_particle_smoke[D_80165598], 32, 32); func_8004B72C(255, 255, 255, 255, 255, 255, 255); D_80183E80[0] = 0; D_80183E80[2] = 0x8000; - for (var_s0 = 0; var_s0 < gObjectParticle4_SIZE; var_s0++) { - objectIndex = gObjectParticle4[var_s0]; + for (i = 0; i < gObjectParticle4_SIZE; i++) { + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("SmokeParticles", (uintptr_t) i); + objectIndex = gObjectParticle4[i]; if (objectIndex != NULL_OBJECT_ID) { object = &gObjectList[objectIndex]; if (object->state >= 2) { @@ -3956,8 +3958,10 @@ void render_object_smoke_particles(s32 cameraId) { } } } + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } - FrameInterpolation_RecordCloseChild(); + } UNUSED void func_800557AC() { From ee9ca1a52e35b8480065bdde201f85be022e4677 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Tue, 20 May 2025 22:21:51 -0500 Subject: [PATCH 72/85] interpolated ended scene fireworks. --- src/ending/podium_ceremony_actors.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ending/podium_ceremony_actors.c b/src/ending/podium_ceremony_actors.c index 1e3911287..04edd018f 100644 --- a/src/ending/podium_ceremony_actors.c +++ b/src/ending/podium_ceremony_actors.c @@ -18,6 +18,7 @@ #include "code_80281C40.h" #include "math_util.h" #include +#include "port/interpolation/FrameInterpolation.h" #include "src/port/Game.h" #include "engine/Matrix.h" @@ -262,6 +263,9 @@ void render_fireworks(Vec3f arg0, f32 arg1, s32 rgb, s16 alpha) { void firework_update(Firework* actor) { s32 i; Vec3f pos; + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("render_fireworks", (uintptr_t) actor); if (actor->unk44 < 30) { for (i = 0; i < 10; i++) { pos[0] = actor->pos[0]; @@ -290,6 +294,8 @@ void firework_update(Firework* actor) { } } actor->unk44 += 1; + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } void unused_80280FA0(UNUSED CeremonyActor* actor) { From c97a211a91bff70905e5525fefc5dfa669fca984 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Tue, 20 May 2025 22:35:45 -0500 Subject: [PATCH 73/85] Tagged star particles in the ending scene --- src/engine/particles/StarEmitter.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/engine/particles/StarEmitter.cpp b/src/engine/particles/StarEmitter.cpp index 242e1a75a..7cb9d9979 100644 --- a/src/engine/particles/StarEmitter.cpp +++ b/src/engine/particles/StarEmitter.cpp @@ -1,6 +1,7 @@ #include "StarEmitter.h" +#include "port/interpolation/FrameInterpolation.h" extern "C" { #include "render_objects.h" @@ -107,9 +108,13 @@ void StarEmitter::Draw(s32 cameraId) { // func_80054BE8 D_80183E80[0] = 0; for (var_s0 = 0; var_s0 < gObjectParticle3_SIZE; var_s0++) { temp_a0 = ObjectIndex[var_s0]; + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("Ceremony Stars", (uintptr_t) &ObjectIndex[var_s0]); if ((temp_a0 != -1) && (gObjectList[temp_a0].state >= 2)) { StarEmitter::func_80054AFC(temp_a0, camera->pos); } + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } } From 622795584c1161b4a167575c78f0ff932318ca5f Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Tue, 20 May 2025 22:44:51 -0500 Subject: [PATCH 74/85] Shell flames handled better. --- src/render_objects.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/render_objects.c b/src/render_objects.c index f2fd0a67c..3b6aa44c6 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3943,11 +3943,11 @@ void render_object_smoke_particles(s32 cameraId) { D_80183E80[0] = 0; D_80183E80[2] = 0x8000; for (i = 0; i < gObjectParticle4_SIZE; i++) { - // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("SmokeParticles", (uintptr_t) i); objectIndex = gObjectParticle4[i]; if (objectIndex != NULL_OBJECT_ID) { object = &gObjectList[objectIndex]; + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild("SmokeParticles", (uintptr_t) object); if (object->state >= 2) { if (object->unk_0D8 == 3) { func_8008A364(objectIndex, cameraId, 0x4000U, 0x00000514); @@ -3958,11 +3958,10 @@ void render_object_smoke_particles(s32 cameraId) { func_8005477C(objectIndex, object->unk_0D8, sp54->pos); } } + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); } - // @port Pop the transform id. - FrameInterpolation_RecordCloseChild(); } - } UNUSED void func_800557AC() { From 1c5c8ceeeef3295c6ea46493ea0e445a71fee7c6 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Wed, 21 May 2025 01:19:49 -0300 Subject: [PATCH 75/85] this isn't needed --- src/camera.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/camera.c b/src/camera.c index 6591dc32e..01ece4a2b 100644 --- a/src/camera.c +++ b/src/camera.c @@ -1125,7 +1125,6 @@ void func_8001EE98(Player* player, Camera* camera, s8 index) { break; } if (gIsGamePaused == 0) { - FrameInterpolation_ShouldInterpolateFrame(false); switch (D_80152300[cameraIndex]) { case 3: func_8001A588(&D_80152300[cameraIndex], camera, player, index, cameraIndex); @@ -1150,7 +1149,6 @@ void func_8001EE98(Player* player, Camera* camera, s8 index) { func_8001EA0C(camera, player, index); break; } - FrameInterpolation_ShouldInterpolateFrame(true); } } From 756a05ad4d180f63b49f7db57891b8e7569a8328 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Wed, 21 May 2025 21:02:32 -0600 Subject: [PATCH 76/85] Fix multiplayer cameras --- src/main.c | 23 +++++++++++++---------- src/racing/skybox_and_splitscreen.c | 2 +- src/spawn_players.c | 6 +++--- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/main.c b/src/main.c index cd8b4f677..c3f6f27d7 100644 --- a/src/main.c +++ b/src/main.c @@ -759,18 +759,21 @@ void process_game_tick(void) { func_800382DC(); } + // This looks like it should be in the switch. + // But it needs to be here for player 1 to work in all modes. + if (CVarGetInteger("gFreecam", 0) == true) { + freecam(gFreecamCamera, gPlayerOneCopy, 0); + } else { + func_8001EE98(gPlayerOneCopy, camera1, 0); + } + + // Editor requires this so the camera keeps moving while the game is paused. + if (gIsEditorPaused == true) { + return; + } + switch(gActiveScreenMode) { case SCREEN_MODE_1P: - if (CVarGetInteger("gFreecam", 0) == true) { - freecam(gFreecamCamera, gPlayerOneCopy, 0); - } else { - func_8001EE98(gPlayerOneCopy, camera1, 0); - } - - // Editor requires this so the camera keeps moving while the game is paused. - if (gIsEditorPaused == true) { - return; - } func_80028F70(); break; case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index 820d83ecb..9a31c378a 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -767,7 +767,7 @@ void setup_camera(Camera* camera, s32 playerId, s32 cameraId, struct UnkStruct_8 } // Setup perspective (camera movement) - FrameInterpolation_RecordOpenChild("camera", FrameInterpolation_GetCameraEpoch()); + FrameInterpolation_RecordOpenChild("camera", (FrameInterpolation_GetCameraEpoch() | (((playerId | cameraId) << 8)))); guPerspective(&gGfxPool->mtxPersp[cameraId], &perspNorm, gCameraZoom[cameraId], gScreenAspect, CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); gSPPerspNormalize(gDisplayListHead++, perspNorm); diff --git a/src/spawn_players.c b/src/spawn_players.c index 569042ca6..92185f3d9 100644 --- a/src/spawn_players.c +++ b/src/spawn_players.c @@ -1195,9 +1195,6 @@ void func_8003D080(void) { func_8003C0F0(); } - // Init free cam - freecam_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 4); - if (!gDemoMode) { switch (gActiveScreenMode) { case SCREEN_MODE_1P: @@ -1293,6 +1290,9 @@ void func_8003D080(void) { } } + // Init free cam + freecam_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 4); + switch (gActiveScreenMode) { case SCREEN_MODE_1P: func_8003CD98(gPlayerOneCopy, camera1, 0, 0); // sic From 98d5844f9190d80a935182e86645052e4cf9eebe Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Wed, 21 May 2025 23:56:13 -0500 Subject: [PATCH 77/85] Fixed loading battle maps. --- src/engine/actors/Finishline.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/engine/actors/Finishline.cpp b/src/engine/actors/Finishline.cpp index 0680e60bd..33f12120f 100644 --- a/src/engine/actors/Finishline.cpp +++ b/src/engine/actors/Finishline.cpp @@ -6,6 +6,7 @@ #include "engine/Actor.h" #include "World.h" #include "assets/common_data.h" +#include "src/port/Game.h" extern "C" { #include "macros.h" @@ -20,6 +21,10 @@ extern f32 gKartGravityTable[]; AFinishline::AFinishline(std::optional pos) { Name = "Finishline"; + if (GetCup() == GetBattleCup()) { + return; + } + if (pos.has_value()) { // Set spawn point to the provided position Pos[0] = D_8015F8D0[0] = pos.value().x; From f6d1064a7a5395eaca40f08d099d8cc07badf02c Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Thu, 22 May 2025 00:16:21 -0500 Subject: [PATCH 78/85] Tagged battle balloons --- src/code_80057C60.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 0a8e22749..50622a10a 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -6101,6 +6101,10 @@ void render_battle_balloon(Player* player, s8 arg1, s16 arg2, s8 arg3) { sp12C[1] = player->unk_048[arg3]; sp12C[2] = D_8018D7D0[arg1][arg2] - (D_8018D860[arg1][arg2] * coss(temp_t1)) - ((D_8018D890[arg1][arg2] * 8) * sins(temp_t1)); + + // @port: Tag the transform. + FrameInterpolation_RecordOpenChild((uintptr_t) player, arg1 | arg2 << 16); + mtxf_translate_rotate(mtx, sp134, sp12C); mtxf_scale(mtx, var_f20); // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], sp140); @@ -6130,6 +6134,10 @@ void render_battle_balloon(Player* player, s8 arg1, s16 arg2, s8 arg3) { gSPVertex(gDisplayListHead++, gBalloonVertexPlane2, 4, 0); gSPDisplayList(gDisplayListHead++, common_square_plain_render); gSPTexture(gDisplayListHead++, 0x0001, 0x0001, 0, G_TX_RENDERTILE, G_OFF); + + // @port Pop the transform id. + FrameInterpolation_RecordCloseChild(); + gMatrixEffectCount++; } From 6ff80c5f08c0a9c4e57ec419d4e6dcd781bb5b45 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Thu, 22 May 2025 07:04:45 -0600 Subject: [PATCH 79/85] Some fixes for battle mode --- src/engine/World.cpp | 4 ++++ src/engine/World.h | 1 + src/menus.c | 1 + src/port/Game.cpp | 11 ++++++++--- src/port/Game.h | 2 ++ 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/engine/World.cpp b/src/engine/World.cpp index 8e20806ff..8137b3801 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -79,6 +79,10 @@ u32 World::PreviousCup() { return 0; } +void World::SetCupIndex(size_t index) { + CupIndex = index; +} + void World::SetCup(Cup* cup) { if (cup) { CurrentCup = cup; diff --git a/src/engine/World.h b/src/engine/World.h index 915cacf27..bc6845aae 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -82,6 +82,7 @@ public: void AddCup(Cup*); void SetCup(Cup* cup); + void SetCupIndex(size_t index); const char* GetCupName(); u32 GetCupIndex(); u32 NextCup(); diff --git a/src/menus.c b/src/menus.c index d921ac740..ce9f0a643 100644 --- a/src/menus.c +++ b/src/menus.c @@ -2005,6 +2005,7 @@ void load_menu_states(s32 menuSelection) { CM_SetCup(GetBattleCup()); // gCupSelection = BATTLE_CUP; D_800DC540 = 4; + CM_SetCupIndex(BATTLE_CUP); gSubMenuSelection = SUB_MENU_MAP_SELECT_BATTLE_COURSE; } else { if (GetCup() == GetBattleCup()) { diff --git a/src/port/Game.cpp b/src/port/Game.cpp index 2c0ec3a0a..33b4e9d16 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -244,6 +244,10 @@ u32 GetCupIndex(void) { return gWorldInstance.GetCupIndex(); } +void CM_SetCupIndex(size_t index) { + gWorldInstance.SetCupIndex(index); +} + const char* GetCupName(void) { return gWorldInstance.CurrentCup->Name; } @@ -394,10 +398,11 @@ void CM_BeginPlay() { if (course) { // Do not spawn finishline in credits or battle mode. And if bSpawnFinishline. - if ((gGamestate != CREDITS_SEQUENCE) && (gGamestate != BATTLE) && (course->bSpawnFinishline)) { - gWorldInstance.AddActor(new AFinishline(course->FinishlineSpawnPoint)); + if ((gGamestate != CREDITS_SEQUENCE) && (gModeSelection != BATTLE)) { + if (course->bSpawnFinishline) { + gWorldInstance.AddActor(new AFinishline(course->FinishlineSpawnPoint)); + } } - gEditor.AddLight("Sun", nullptr, D_800DC610[1].l->l.dir); course->BeginPlay(); diff --git a/src/port/Game.h b/src/port/Game.h index 2102cb7ea..2731372ca 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -51,6 +51,8 @@ void PreviousCourse(); void CM_SetCup(void*); +void CM_SetCupIndex(size_t index); + void CM_LoadTextures(); void CM_RenderCourse(struct UnkStruct_800DC5EC* arg0); From 89c046c22412f0171f1253bb3be79eeebb2f798c Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Thu, 22 May 2025 12:08:17 -0500 Subject: [PATCH 80/85] No longer needed changes toAFinishline with the changes mega made. --- src/engine/actors/Finishline.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/engine/actors/Finishline.cpp b/src/engine/actors/Finishline.cpp index 33f12120f..8d53527ad 100644 --- a/src/engine/actors/Finishline.cpp +++ b/src/engine/actors/Finishline.cpp @@ -21,10 +21,6 @@ extern f32 gKartGravityTable[]; AFinishline::AFinishline(std::optional pos) { Name = "Finishline"; - if (GetCup() == GetBattleCup()) { - return; - } - if (pos.has_value()) { // Set spawn point to the provided position Pos[0] = D_8015F8D0[0] = pos.value().x; From 180e2a20e9583bb3b4753ec9c8a000edb326b481 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Fri, 23 May 2025 06:41:07 -0600 Subject: [PATCH 81/85] Tag finishline --- src/engine/actors/Finishline.cpp | 7 +++++++ src/engine/actors/Finishline.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/engine/actors/Finishline.cpp b/src/engine/actors/Finishline.cpp index 33f12120f..4f76f3546 100644 --- a/src/engine/actors/Finishline.cpp +++ b/src/engine/actors/Finishline.cpp @@ -7,6 +7,7 @@ #include "World.h" #include "assets/common_data.h" #include "src/port/Game.h" +#include "port/interpolation/FrameInterpolation.h" extern "C" { #include "macros.h" @@ -18,6 +19,8 @@ extern f32 gKartHopInitialVelocityTable[]; extern f32 gKartGravityTable[]; } +size_t AFinishline::_count = 0; + AFinishline::AFinishline(std::optional pos) { Name = "Finishline"; @@ -58,6 +61,8 @@ void AFinishline::Draw(Camera *camera) { return; } + FrameInterpolation_RecordOpenChild("Finishline", _count); + mtxf_pos_rotation_xyz(mtx, Pos, Rot); maxObjectsReached = render_set_position(mtx, 0) == 0; @@ -79,6 +84,8 @@ void AFinishline::Draw(Camera *camera) { } else { gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D001BD8); } + + FrameInterpolation_RecordCloseChild(); } void AFinishline::Collision(Player* player, AActor* actor) {} diff --git a/src/engine/actors/Finishline.h b/src/engine/actors/Finishline.h index 61b561a5e..3c0e84de8 100644 --- a/src/engine/actors/Finishline.h +++ b/src/engine/actors/Finishline.h @@ -27,6 +27,7 @@ public: virtual void Collision(Player* player, AActor* actor) override; virtual bool IsMod() override; + static size_t _count; bool PickedUp = false; uint32_t Timer = 0; From 05b752d7b3af73b70bc903871541b014d8082c00 Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Fri, 23 May 2025 12:43:43 -0500 Subject: [PATCH 82/85] fix to make it compile with cmake 3.31 --- src/port/interpolation/FrameInterpolation.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index d0e0fe0f0..c86f63089 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -12,6 +12,9 @@ extern "C" { #include "math_util.h" #include "math_util_2.h" #include "render_player.h" + +extern Mat4* gInterpolationMatrix; +void mtxf_translate(Mat4, Vec3f); } /* Frame interpolation. @@ -234,11 +237,6 @@ Data& append(Op op) { return m.emplace_back(); } -extern "C" { -extern Mat4* gInterpolationMatrix; -void mtxf_translate(Mat4, Vec3f); -} - MtxF* Matrix_GetCurrent() { return (MtxF*) gInterpolationMatrix; } From af4535c3c578425a456c8c34c42f10108f94fd1c Mon Sep 17 00:00:00 2001 From: sitton76 <58642183+sitton76@users.noreply.github.com> Date: Fri, 23 May 2025 12:45:07 -0500 Subject: [PATCH 83/85] changed mtxf_multiplication() to fix vert explosion in Desert & DK parkway.(provided by Coco.) --- src/racing/math_util.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/racing/math_util.c b/src/racing/math_util.c index 43143fa7d..3682e07d5 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -804,43 +804,40 @@ void func_802B6D58(Mat4 arg0, Vec3f arg1, Vec3f arg2) { } void mtxf_multiplication(Mat4 dest, Mat4 mat1, Mat4 mat2) { - Mat4 product; + FrameInterpolation_RecordMatrixMult(dest, dest, 0); - FrameInterpolation_RecordMatrixMult(dest, product, 0); - - product[0][0] = + dest[0][0] = (mat1[0][0] * mat2[0][0]) + (mat1[0][1] * mat2[1][0]) + (mat1[0][2] * mat2[2][0]) + (mat1[0][3] * mat2[3][0]); - product[0][1] = + dest[0][1] = (mat1[0][0] * mat2[0][1]) + (mat1[0][1] * mat2[1][1]) + (mat1[0][2] * mat2[2][1]) + (mat1[0][3] * mat2[3][1]); - product[0][2] = + dest[0][2] = (mat1[0][0] * mat2[0][2]) + (mat1[0][1] * mat2[1][2]) + (mat1[0][2] * mat2[2][2]) + (mat1[0][3] * mat2[3][2]); - product[0][3] = + dest[0][3] = (mat1[0][0] * mat2[0][3]) + (mat1[0][1] * mat2[1][3]) + (mat1[0][2] * mat2[2][3]) + (mat1[0][3] * mat2[3][3]); - product[1][0] = + dest[1][0] = (mat1[1][0] * mat2[0][0]) + (mat1[1][1] * mat2[1][0]) + (mat1[1][2] * mat2[2][0]) + (mat1[1][3] * mat2[3][0]); - product[1][1] = + dest[1][1] = (mat1[1][0] * mat2[0][1]) + (mat1[1][1] * mat2[1][1]) + (mat1[1][2] * mat2[2][1]) + (mat1[1][3] * mat2[3][1]); - product[1][2] = + dest[1][2] = (mat1[1][0] * mat2[0][2]) + (mat1[1][1] * mat2[1][2]) + (mat1[1][2] * mat2[2][2]) + (mat1[1][3] * mat2[3][2]); - product[1][3] = + dest[1][3] = (mat1[1][0] * mat2[0][3]) + (mat1[1][1] * mat2[1][3]) + (mat1[1][2] * mat2[2][3]) + (mat1[1][3] * mat2[3][3]); - product[2][0] = + dest[2][0] = (mat1[2][0] * mat2[0][0]) + (mat1[2][1] * mat2[1][0]) + (mat1[2][2] * mat2[2][0]) + (mat1[2][3] * mat2[3][0]); - product[2][1] = + dest[2][1] = (mat1[2][0] * mat2[0][1]) + (mat1[2][1] * mat2[1][1]) + (mat1[2][2] * mat2[2][1]) + (mat1[2][3] * mat2[3][1]); - product[2][2] = + dest[2][2] = (mat1[2][0] * mat2[0][2]) + (mat1[2][1] * mat2[1][2]) + (mat1[2][2] * mat2[2][2]) + (mat1[2][3] * mat2[3][2]); - product[2][3] = + dest[2][3] = (mat1[2][0] * mat2[0][3]) + (mat1[2][1] * mat2[1][3]) + (mat1[2][2] * mat2[2][3]) + (mat1[2][3] * mat2[3][3]); - product[3][0] = + dest[3][0] = (mat1[3][0] * mat2[0][0]) + (mat1[3][1] * mat2[1][0]) + (mat1[3][2] * mat2[2][0]) + (mat1[3][3] * mat2[3][0]); - product[3][1] = + dest[3][1] = (mat1[3][0] * mat2[0][1]) + (mat1[3][1] * mat2[1][1]) + (mat1[3][2] * mat2[2][1]) + (mat1[3][3] * mat2[3][1]); - product[3][2] = + dest[3][2] = (mat1[3][0] * mat2[0][2]) + (mat1[3][1] * mat2[1][2]) + (mat1[3][2] * mat2[2][2]) + (mat1[3][3] * mat2[3][2]); - product[3][3] = + dest[3][3] = (mat1[3][0] * mat2[0][3]) + (mat1[3][1] * mat2[1][3]) + (mat1[3][2] * mat2[2][3]) + (mat1[3][3] * mat2[3][3]); - mtxf_copy_n_element((s32*) dest, (s32*) product, 16); } /** From 9363e3d77631b1028a765c075a00293bd20c9ba7 Mon Sep 17 00:00:00 2001 From: coco875 <59367621+coco875@users.noreply.github.com> Date: Fri, 23 May 2025 22:49:06 +0000 Subject: [PATCH 84/85] fix memory leaks, avoid invalidate texture (#207) * Fixed macos * More stupid fixes * update with main and update torch and lus and enable action on this branch * Update FrameInterpolation.h * Update FrameInterpolation.cpp * fix some memory leak * Update torch * Update torch * update torch and lus * reduce texture import * don't use fork of torch and lus * Update torch * Update torch --------- Co-authored-by: Lywx --- .github/workflows/main.yml | 2 +- libultraship | 2 +- src/code_800AF9B0.c | 8 ++--- src/engine/World.cpp | 3 ++ src/engine/World.h | 1 + src/engine/editor/Editor.cpp | 19 ++++++++--- src/engine/editor/Editor.h | 1 + src/engine/editor/EditorMath.cpp | 4 +-- src/port/Engine.cpp | 7 +++- src/port/Game.cpp | 33 ++++++++++++++++++ src/port/SpaghettiGui.cpp | 2 +- src/port/interpolation/FrameInterpolation.cpp | 5 +++ src/port/interpolation/FrameInterpolation.h | 2 +- .../resource/importers/AudioBankFactory.cpp | 1 + src/port/resource/type/AudioBank.cpp | 17 ++++++++++ src/port/resource/type/AudioBank.h | 1 + src/port/resource/type/AudioSample.cpp | 14 ++++++++ src/port/resource/type/AudioSample.h | 1 + src/render_player.c | 34 ++++++++++++------- torch | 2 +- 20 files changed, 130 insertions(+), 29 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 496346cb8..6bf2a4a5b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,7 +2,7 @@ name: GenerateBuilds on: push: - branches: ["main"] + branches: ["*"] concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/libultraship b/libultraship index d4a22ea7f..45c4f8d6c 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit d4a22ea7f78eb275b462ce542815d8368849d526 +Subproject commit 45c4f8d6c19c6176f5e0918917c655ea09ecc212 diff --git a/src/code_800AF9B0.c b/src/code_800AF9B0.c index 732a6e8e9..9876a40cb 100644 --- a/src/code_800AF9B0.c +++ b/src/code_800AF9B0.c @@ -34,15 +34,15 @@ Light D_800E8688 = { { s16 D_8018EDB0; s16 D_8018EDB2; s16 D_8018EDB4; -Vtx* D_8018EDB8; -Vtx* D_8018EDBC; +Vtx D_8018EDB8[480]; +Vtx D_8018EDBC[480]; /*** utils **/ #define SQ(x) ((x) * (x)) void func_800AF9B0(void) { - D_8018EDB8 = (void*) calloc(480, sizeof(Vtx)); - D_8018EDBC = (void*) calloc(480, sizeof(Vtx)); + // D_8018EDB8 = (void*) calloc(480, sizeof(Vtx)); + // D_8018EDBC = (void*) calloc(480, sizeof(Vtx)); } // could be a normal vertex, not a color... diff --git a/src/engine/World.cpp b/src/engine/World.cpp index 8137b3801..6620a2815 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -22,6 +22,9 @@ extern "C" { } World::World() {} +World::~World() { + CM_CleanWorld(); +} Course* CurrentCourse; Cup* CurrentCup; diff --git a/src/engine/World.h b/src/engine/World.h index bc6845aae..91287b162 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -52,6 +52,7 @@ class World { public: explicit World(); + ~World(); void AddCourse(Course* course); diff --git a/src/engine/editor/Editor.cpp b/src/engine/editor/Editor.cpp index 446da7487..23a947a09 100644 --- a/src/engine/editor/Editor.cpp +++ b/src/engine/editor/Editor.cpp @@ -30,6 +30,11 @@ namespace Editor { Editor::Editor() { } + Editor::~Editor() { + ClearObjects(); + ClearMatrixPool(); + } + void Editor::Load() { printf("Editor: Loading Editor...\n"); eObjectPicker.Load(); @@ -58,10 +63,16 @@ namespace Editor { Ship::Coords mousePos = wnd->GetMousePos(); bool isMouseDown = wnd->GetMouseState(Ship::LUS_MOUSE_BTN_LEFT); - eGameObjects.erase( - std::remove_if(eGameObjects.begin(), eGameObjects.end(), - [](const auto& object) { return (*object->DespawnFlag) == object->DespawnValue; }), - eGameObjects.end()); + auto it = std::remove_if(eGameObjects.begin(), eGameObjects.end(), + [](auto& object) { + if (*object->DespawnFlag == object->DespawnValue) { + delete object; // Free the pointed-to memory + return true; // Remove the pointer from the vector + } + return false; + }); + + eGameObjects.erase(it, eGameObjects.end()); if (isMouseDown && !wasMouseDown) { // Mouse just pressed (Pressed state) diff --git a/src/engine/editor/Editor.h b/src/engine/editor/Editor.h index 759c59355..60e578b21 100644 --- a/src/engine/editor/Editor.h +++ b/src/engine/editor/Editor.h @@ -14,6 +14,7 @@ namespace Editor { class Editor { public: Editor(); + ~Editor(); ObjectPicker eObjectPicker; std::vector eGameObjects; diff --git a/src/engine/editor/EditorMath.cpp b/src/engine/editor/EditorMath.cpp index 04a299563..f3833008b 100644 --- a/src/engine/editor/EditorMath.cpp +++ b/src/engine/editor/EditorMath.cpp @@ -352,8 +352,8 @@ bool IntersectRaySphere(const Ray& ray, const FVector& sphereCenter, float radiu // Transform a matrix to a matrix identity void Editor_MatrixIdentity(Mat4 mtx) { - register s32 i; - register s32 k; + s32 i; + s32 k; for (i = 0; i < 4; i++) { for (k = 0; k < 4; k++) { diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 15acab0ac..70ea4054c 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -298,6 +298,9 @@ void GameEngine::Destroy() { #ifdef __SWITCH__ Ship::Switch::Exit(); #endif + GameUI::Destroy(); + delete GameEngine::Instance; + GameEngine::Instance = nullptr; } bool ShouldClearTextureCacheAtEndOfFrame = false; @@ -509,7 +512,9 @@ ImFont* GameEngine::CreateFontWithSize(float size, std::string fontPath) { initData->Path = fontPath; std::shared_ptr fontData = std::static_pointer_cast( Ship::Context::GetInstance()->GetResourceManager()->LoadResource(fontPath, false, initData)); - font = mImGuiIo->Fonts->AddFontFromMemoryTTF(fontData->Data, fontData->DataSize, size); + char* fontDataPtr = (char*)malloc(fontData->DataSize); + memcpy(fontDataPtr, fontData->Data, fontData->DataSize); + font = mImGuiIo->Fonts->AddFontFromMemoryTTF(fontDataPtr, fontData->DataSize, size); } // FontAwesome fonts need to have their sizes reduced by 2.0f/3.0f in order to align correctly float iconFontSize = size * 2.0f / 3.0f; diff --git a/src/port/Game.cpp b/src/port/Game.cpp index 33b4e9d16..caccd9f90 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -198,6 +198,38 @@ void CustomEngineInit() { // gModelLoader.Load(); } +void CustomEngineDestroy() { + delete gMarioRaceway; + delete gChocoMountain; + delete gBowsersCastle; + delete gBansheeBoardwalk; + delete gYoshiValley; + delete gFrappeSnowland; + delete gKoopaTroopaBeach; + delete gRoyalRaceway; + delete gLuigiRaceway; + delete gMooMooFarm; + delete gToadsTurnpike; + delete gKalimariDesert; + delete gSherbetLand; + delete gRainbowRoad; + delete gWarioStadium; + delete gBlockFort; + delete gSkyscraper; + delete gDoubleDeck; + delete gDkJungle; + delete gBigDonut; + delete gPodiumCeremony; + delete gHarbour; + delete gTestCourse; + + delete gMushroomCup; + delete gFlowerCup; + delete gStarCup; + delete gSpecialCup; + delete gBattleCup; +} + extern "C" { void HM_InitIntro() { @@ -873,6 +905,7 @@ extern "C" while (WindowIsRunning()) { push_frame(); } + CustomEngineDestroy(); // GameEngine::Instance->ProcessFrame(push_frame); GameEngine::Instance->Destroy(); return 0; diff --git a/src/port/SpaghettiGui.cpp b/src/port/SpaghettiGui.cpp index 09ac63234..6c703456d 100644 --- a/src/port/SpaghettiGui.cpp +++ b/src/port/SpaghettiGui.cpp @@ -12,7 +12,7 @@ #include #include -#include "graphic/Fast3D/gfx_metal.h" +#include "graphic/Fast3D/backends/gfx_metal.h" #include #include #else diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index c86f63089..836e6c70c 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -52,6 +52,11 @@ static bool invert_matrix(const float m[16], float invOut[16]); using namespace std; +extern "C" { +extern Mat4* gInterpolationMatrix; +void mtxf_translate(Mat4, Vec3f); +} + namespace { enum class Op { diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 06a7cf3d4..c59743681 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -19,7 +19,7 @@ extern "C" { #define TAG_ITEM_ADDR(x) ((u32) 0x10000000 | (u32)x) #define TAG_SMOKE_DUST(x) ((u32) 0x20000000 | (u32) (x)) #define TAG_LETTER(x) ((u32)0x30000000 | (u32) (x)) -#define TAG_OBJECT(x) ((u32)0x40000000 | (u32)(x)) +#define TAG_OBJECT(x) ((u32)0x40000000 | (u32) (uintptr_t) (x)) void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate); diff --git a/src/port/resource/importers/AudioBankFactory.cpp b/src/port/resource/importers/AudioBankFactory.cpp index ee400c1b5..650767881 100644 --- a/src/port/resource/importers/AudioBankFactory.cpp +++ b/src/port/resource/importers/AudioBankFactory.cpp @@ -21,6 +21,7 @@ SM64::AudioBankFactoryV0::ReadResource(std::shared_ptr file, auto* instrument = new Instrument(); bool valid = reader->ReadUByte(); if(!valid){ + delete instrument; bank->instruments.push_back(nullptr); continue; } diff --git a/src/port/resource/type/AudioBank.cpp b/src/port/resource/type/AudioBank.cpp index f91b767d2..7cbe3073a 100644 --- a/src/port/resource/type/AudioBank.cpp +++ b/src/port/resource/type/AudioBank.cpp @@ -8,4 +8,21 @@ CtlEntry* AudioBank::GetPointer() { size_t AudioBank::GetPointerSize() { return sizeof(mData); } +AudioBank::~AudioBank() { + for (auto& instrument : instruments) { + if (instrument != nullptr) { + if (instrument->envelope != nullptr) { + delete[] instrument->envelope; + instrument->envelope = nullptr; + } + delete instrument; + } + + } + for (auto& drum : drums) { + delete drum; + } + instruments.clear(); + drums.clear(); +} } \ No newline at end of file diff --git a/src/port/resource/type/AudioBank.h b/src/port/resource/type/AudioBank.h index a8541fe84..b9beefa78 100644 --- a/src/port/resource/type/AudioBank.h +++ b/src/port/resource/type/AudioBank.h @@ -47,6 +47,7 @@ class AudioBank : public Ship::Resource { using Resource::Resource; AudioBank() : Resource(std::shared_ptr()) {} + ~AudioBank() override; CtlEntry* GetPointer(); size_t GetPointerSize(); diff --git a/src/port/resource/type/AudioSample.cpp b/src/port/resource/type/AudioSample.cpp index cbdbd6573..f9b087af7 100644 --- a/src/port/resource/type/AudioSample.cpp +++ b/src/port/resource/type/AudioSample.cpp @@ -8,4 +8,18 @@ AudioBankSample* AudioSample::GetPointer() { size_t AudioSample::GetPointerSize() { return sizeof(mData); } +AudioSample::~AudioSample() { + if (mData.sampleAddr != nullptr) { + // delete[] mData.sampleAddr; + mData.sampleAddr = nullptr; + } + if (mData.book->book != nullptr) { + delete[] mData.book->book; + mData.book->book = nullptr; + } + if (mData.loop->state != nullptr) { + delete[] mData.loop->state; + mData.loop->state = nullptr; + } +} } \ No newline at end of file diff --git a/src/port/resource/type/AudioSample.h b/src/port/resource/type/AudioSample.h index 35f1d8d33..2d6f46c96 100644 --- a/src/port/resource/type/AudioSample.h +++ b/src/port/resource/type/AudioSample.h @@ -34,6 +34,7 @@ class AudioSample : public Ship::Resource { using Resource::Resource; AudioSample() : Resource(std::shared_ptr()) {} + ~AudioSample() override; AudioBankSample* GetPointer(); size_t GetPointerSize(); diff --git a/src/render_player.c b/src/render_player.c index 017b0fd18..ca4247ef9 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -48,7 +48,6 @@ s16 gMatrixEffectCount; s32 D_80164AF4[3]; struct_D_802F1F80* gPlayerPalette; static const char* sKartUpperTexture; -static const char* sKartLowerTexture; u16 gPlayerRedEffect[8]; u16 gPlayerGreenEffect[8]; u16 gPlayerBlueEffect[8]; @@ -1600,6 +1599,19 @@ void render_player_shadow_credits(Player* player, s8 playerId, s8 arg2) { gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); } +Vtx player_vtx[] = { + { { { 9, 18, -6 }, 0, { 4032, 0 }, { 0xFF, 0xFF, 0xFF, 0xFF } } }, + { { { 9, 0, -6 }, 0, { 4032, 4032 }, { 0xFF, 0xFF, 0xFF, 0xFF } } }, + { { { -9, 18, -6 }, 0, { 0, 0 }, { 0xFF, 0xFF, 0xFF, 0xFF } } }, + { { { -9, 0, -6 }, 0, { 0, 4032 }, { 0xFF, 0xFF, 0xFF, 0xFF } } }, +}; +Vtx player_vtx_flip[] = { + { { { 9, 18, -6 }, 0, { 0, 0 }, { 0xFF, 0xFF, 0xFF, 0xFF } } }, + { { { 9, 0, -6 }, 0, { 0, 4032 }, { 0xFF, 0xFF, 0xFF, 0xFF } } }, + { { { -9, 18, -6 }, 0, { 4032, 0 }, { 0xFF, 0xFF, 0xFF, 0xFF } } }, + { { { -9, 0, -6 }, 0, { 4032, 4032 }, { 0xFF, 0xFF, 0xFF, 0xFF } } }, +}; + void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) { UNUSED s32 pad; Mat4 mtx; @@ -1727,19 +1739,15 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) { } // Render heads - gDPLoadTextureBlock(gDisplayListHead++, sKartUpperTexture, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, sKartUpperTexture, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 64, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); - gSPVertex(gDisplayListHead++, &D_800DDBB4[playerId][arg3], 4, 0); - gSPDisplayList(gDisplayListHead++, common_square_plain_render); - - // Render karts - u8* test = (u8*) LOAD_ASSET(sKartUpperTexture); - gDPLoadTextureBlock(gDisplayListHead++, test + 0x7C0, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, - G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, - G_TX_NOLOD); - gSPVertex(gDisplayListHead++, &D_800DDBB4[playerId][arg3 + 4], 4, 0); - gSPDisplayList(gDisplayListHead++, common_square_plain_render); + if (arg3 == 0) { + gSPVertex(gDisplayListHead++, player_vtx, 4, 0); + } else { + gSPVertex(gDisplayListHead++, player_vtx_flip, 4, 0); + } + gSP2Triangles(gDisplayListHead++, 0, 1, 2, 0, 1, 3, 2, 0); gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); @@ -1964,7 +1972,7 @@ void render_player(Player* player, s8 playerId, s8 screenId) { func_80025DE8(player, playerId, screenId, var_v1); } // Allows wheels to spin - gSPInvalidateTexCache(gDisplayListHead++, sKartLowerTexture); + gSPInvalidateTexCache(gDisplayListHead++, sKartUpperTexture); } void func_80026A48(Player* player, s8 arg1) { diff --git a/torch b/torch index 8e56ea029..f75facb20 160000 --- a/torch +++ b/torch @@ -1 +1 @@ -Subproject commit 8e56ea0294973b7c9f8f077a131b40fce13b8489 +Subproject commit f75facb20883570ed091e8ae733ec0539f606e57 From 2a0c0939c780babc45c8c22dfd6f94563485bae5 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Fri, 23 May 2025 16:53:14 -0600 Subject: [PATCH 85/85] Refactor World::Courses to unique_ptr (#211) * wip course unique ptr * Track unique_ptr : This probably compiles * Finish impl Courses as unique_ptr * Fix error * Fixes * More fixes * Cleanup * Remove old vars --------- Co-authored-by: MegaMech <7255464+MegaMech@users.noreply.github.com> --- src/actors/piranha_plant/render.inc.c | 2 +- src/actors/trees/render.inc.c | 2 +- src/audio/external.c | 22 +- src/camera.c | 6 +- src/code_800029B0.c | 8 +- src/code_80005FD0.c | 93 ++++---- src/code_80057C60.c | 108 ++++----- src/code_8006E9C0.c | 8 +- src/code_8006E9C0.h | 2 +- src/code_80086E70.c | 4 +- src/effects.c | 16 +- src/ending/code_80281780.c | 2 +- src/engine/World.cpp | 12 +- src/engine/World.h | 14 +- src/engine/objects/BombKart.cpp | 8 +- src/engine/objects/GrandPrixBalloons.cpp | 6 +- src/engine/objects/HotAirBalloon.cpp | 2 +- src/engine/objects/Lakitu.cpp | 4 +- src/engine/objects/TrashBin.cpp | 2 +- src/menu_items.c | 33 +-- src/player_controller.c | 20 +- src/port/Game.cpp | 279 ++++++++--------------- src/port/Game.h | 82 +++---- src/port/ui/ContentBrowser.cpp | 25 +- src/racing/actors.c | 24 +- src/racing/math_util.c | 6 +- src/racing/race_logic.c | 10 +- src/racing/render_courses.c | 6 +- src/racing/skybox_and_splitscreen.c | 4 +- src/render_objects.c | 24 +- src/render_player.c | 6 +- src/spawn_players.c | 22 +- src/staff_ghosts.c | 6 +- src/update_objects.c | 8 +- 34 files changed, 403 insertions(+), 473 deletions(-) diff --git a/src/actors/piranha_plant/render.inc.c b/src/actors/piranha_plant/render.inc.c index 23d018d1b..ed2281095 100644 --- a/src/actors/piranha_plant/render.inc.c +++ b/src/actors/piranha_plant/render.inc.c @@ -120,7 +120,7 @@ void render_actor_piranha_plant(Camera* arg0, Mat4 arg1, struct PiranhaPlant* ar G_TX_MIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); - if (GetCourse() == GetMarioRaceway()) { + if (IsMarioRaceway()) { gSPDisplayList(gDisplayListHead++, &d_course_mario_raceway_dl_piranha_plant); } else { gSPDisplayList(gDisplayListHead++, &d_course_royal_raceway_dl_piranha_plant); diff --git a/src/actors/trees/render.inc.c b/src/actors/trees/render.inc.c index cb54275c6..9939d14ef 100644 --- a/src/actors/trees/render.inc.c +++ b/src/actors/trees/render.inc.c @@ -202,7 +202,7 @@ void func_80299864(Camera* camera, Mat4 arg1, struct Actor* arg2) { // Unless both courses use this actor and use the same addr for the texture. // Just in-case changed the code into a switch to prevent future crashes. // This comment can be removed when this is confirmed to work. - if (GetCourse() == GetLuigiRaceway()) { + if (IsLuigiRaceway()) { gSPDisplayList(gDisplayListHead++, d_course_luigi_raceway_dl_FC70); } } diff --git a/src/audio/external.c b/src/audio/external.c index 97a2ce7f3..3ed17f5db 100644 --- a/src/audio/external.c +++ b/src/audio/external.c @@ -2647,11 +2647,11 @@ void func_800C847C(u8 playerId) { func_800C97C4(playerId); D_800E9F74[playerId] = 1; func_800C94A4(playerId); - if (((GetCourse() == GetChocoMountain()) || (GetCourse() == GetBowsersCastle()) || - (GetCourse() == GetBansheeBoardwalk()) || (GetCourse() == GetYoshiValley()) || - (GetCourse() == GetFrappeSnowland()) || (GetCourse() == GetKoopaTroopaBeach()) || - (GetCourse() == GetRoyalRaceway()) || (GetCourse() == GetSherbetLand()) || - (GetCourse() == GetDkJungle()) || (GetCourse() == GetBigDonut())) && + if (((IsChocoMountain()) || (IsBowsersCastle()) || + (IsBansheeBoardwalk()) || (IsYoshiValley()) || + (IsFrappeSnowland()) || (IsKoopaTroopaBeach()) || + (IsRoyalRaceway()) || (IsSherbetLand()) || + (IsDkJungle()) || (IsBigDonut())) && (D_800EA0EC[playerId] == 0)) { play_sound((gPlayers[playerId].characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x05), &D_800E9F7C[playerId].pos, playerId, &D_800EA1D4, &D_800EA1D4, @@ -2664,7 +2664,7 @@ void func_800C847C(u8 playerId) { D_800E9F74[playerId] = 2; func_800C94A4(playerId); D_800E9F74[playerId] = 0; - if ((GetCourse() == GetKoopaTroopaBeach()) && (D_800EA0EC[playerId] == 0)) { + if ((IsKoopaTroopaBeach()) && (D_800EA0EC[playerId] == 0)) { play_sound((gPlayers[playerId].characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x08), &D_800E9F7C[playerId].pos, playerId, &D_800EA1D4, &D_800EA1D4, (u8*) &D_800E9F7C[playerId].unk_14); @@ -2746,7 +2746,7 @@ void func_800C89E4(void) { } void func_800C8AE4(void) { - if (GetCourse() == GetLuigiRaceway()) { + if (IsLuigiRaceway()) { if (D_800EA184 != 0) { if ((u8) D_800EA16C == 0) { // Has to be this way, can't be D_800EA184++ @@ -2824,11 +2824,11 @@ void func_800C8CCC() { } void play_sound2(s32 soundBits) { - if ((soundBits == SOUND_ACTION_REV_ENGINE) && (GetCourse() == GetDkJungle())) { + if ((soundBits == SOUND_ACTION_REV_ENGINE) && (IsDkJungle())) { soundBits = SOUND_ARG_LOAD(0x49, 0x00, 0x80, 0x27); } - if ((soundBits == SOUND_ACTION_REV_ENGINE_2) && (GetCourse() == GetDkJungle())) { + if ((soundBits == SOUND_ACTION_REV_ENGINE_2) && (IsDkJungle())) { soundBits = SOUND_ARG_LOAD(0x49, 0x00, 0x80, 0x28); } play_sound(soundBits, &D_800EA1C8, 4, &D_800EA1D4, &D_800EA1D4, &D_800EA1DC); @@ -3467,7 +3467,9 @@ void func_800CAEC4(u8 playerId, f32 arg1) { arg1 = 0.0f; } D_800EA120[playerId] = arg1; - play_sound(gCurrentCourseId + 0x19007020, &D_800E9F7C[playerId].pos, playerId, &D_800EA1D4, + //! @warning this used to be gCurrentCourseId + 0x19007020 + // This may not be equivallent. + play_sound(GetCourseIndex() + 0x19007020, &D_800E9F7C[playerId].pos, playerId, &D_800EA1D4, &D_800EA120[playerId], (u8*) &D_800E9F7C[playerId].unk_14); break; default: diff --git a/src/camera.c b/src/camera.c index 01ece4a2b..6620c3ac0 100644 --- a/src/camera.c +++ b/src/camera.c @@ -383,7 +383,7 @@ void func_8001CA78(UNUSED Player* player, Camera* camera, Vec3f arg2, f32* arg3, arg2[2] = camera->lookAt[2]; calculate_orientation_matrix(sp74, 0, 1, 0, -0x00008000); mtxf_translate_vec3f_mat3(sp5C, sp74); - if (GetCourse() == GetToadsTurnpike()) { + if (IsToadsTurnpike()) { var_f14 = sp5C[0]; } else { var_f14 = sp5C[0] + temp_s2->posX; @@ -394,7 +394,7 @@ void func_8001CA78(UNUSED Player* player, Camera* camera, Vec3f arg2, f32* arg3, arg2[1] += (temp_f18 - camera->lookAt[1]) * 1; arg2[2] += (temp_f16 - camera->lookAt[2]) * 1; mtxf_translate_vec3f_mat3(sp68, sp74); - if (GetCourse() == GetToadsTurnpike()) { + if (IsToadsTurnpike()) { var_f14 = sp68[0]; } else { var_f14 = sp68[0] + temp_s2->posX; @@ -487,7 +487,7 @@ void func_8001CCEC(Player* player, Camera* camera, Vec3f arg2, f32* arg3, f32* a move_f32_towards(&D_80164AA0[index], 10, 0.02f); break; default: - if (GetCourse() == GetYoshiValley()) { + if (IsYoshiValley()) { move_f32_towards(&D_80164A90[index], 50, 0.04f); move_f32_towards(&D_80164AA0[index], 35, 0.04f); } else { diff --git a/src/code_800029B0.c b/src/code_800029B0.c index 73f104ed8..beba2e490 100644 --- a/src/code_800029B0.c +++ b/src/code_800029B0.c @@ -233,16 +233,18 @@ void setup_race(void) { // D_8015F8D0[1] = (f32) (D_80164490->posY - 15); // D_8015F8D0[2] = D_80164490->posZ; - // if (GetCourse() == GetToadsTurnpike()) { + // if (IsToadsTurnpike()) { // D_8015F8D0[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 138.0f : D_80164490->posX - 138.0f; - // } else if (GetCourse() == GetWarioStadium()) { + // } else if (IsWarioStadium()) { // D_8015F8D0[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 12.0f : D_80164490->posX - 12.0f; // } else { // D_8015F8D0[0] = D_80164490->posX; // } // } if (!gDemoMode) { - func_800CA008(gPlayerCountSelection1 - 1, gCurrentCourseId + 4); + //! @warning this used to be gCurrentCourseId + 4 + // Hopefully this is equivallent. + func_800CA008(gPlayerCountSelection1 - 1, GetCourseIndex() + 4); func_800CB2C4(); } diff --git a/src/code_80005FD0.c b/src/code_80005FD0.c index 6263883f2..3f8a0b1fc 100644 --- a/src/code_80005FD0.c +++ b/src/code_80005FD0.c @@ -1076,7 +1076,7 @@ void func_80008424(s32 playerId, f32 arg1, Player* player) { if (!(player->effects & 0x80) && !(player->effects & 0x40) && !(player->effects & 0x20000) && !(player->soundEffects & 0x400000) && !(player->soundEffects & 0x01000000) && !(player->soundEffects & 2) && !(player->soundEffects & 4)) { - if (GetCourse() == GetPodiumCeremony()) { + if (IsPodiumCeremony()) { func_80007FA4(playerId, player, var_f2); } else if ((bStopAICrossing[playerId] == 1) && !(player->effects & (STAR_EFFECT | BOO_EFFECT))) { decelerate_ai_player(player, 10.0f); @@ -1140,7 +1140,7 @@ void func_80008424(s32 playerId, f32 arg1, Player* player) { } if (var_a1 != 1) { if (var_f2 < arg1) { - if ((gDemoMode == 1) && (GetCourse() != GetPodiumCeremony())) { + if ((gDemoMode == 1) && (!IsPodiumCeremony())) { player_speed(player); } else if (D_80163330[playerId] == 1) { func_80007D04(playerId, player); @@ -1448,15 +1448,15 @@ void func_8000929C(s32 playerId, Player* player) { D_801630E2 = 1; func_80008F38(playerId); } - if (GetCourse() == GetPodiumCeremony()) { + if (IsPodiumCeremony()) { func_8000B95C(playerId, sSomeNearestWaypoint, D_80163448); return; } if ((sSomeNearestWaypoint < 0x14) || ((gWaypointCountByPathIndex[D_80163448] - 0x14) < sSomeNearestWaypoint) || - (GetCourse() == GetKalimariDesert())) { + (IsKalimariDesert())) { var_v1 = 0; var_t0 = 0; - if (GetCourse() == GetKalimariDesert()) { + if (IsKalimariDesert()) { D_801634EC = 0; if (player->effects & 0x200) { D_801634EC = 1; @@ -1510,7 +1510,7 @@ void func_8000929C(s32 playerId, Player* player) { } } D_80163450[playerId] = tempPos2; - if ((GetCourse() == GetYoshiValley()) && (D_801630E2 == 1)) { + if ((IsYoshiValley()) && (D_801630E2 == 1)) { func_80009000(playerId); if (((player->type & 0x4000) == 0) || (player->type & 0x1000)) { func_800090F0(playerId, player); @@ -1664,7 +1664,7 @@ void func_80009B60(s32 playerId) { if (!(player->unk_0CA & 2) && !(player->unk_0CA & 8)) { D_80163448 = gPathIndexByPlayerId[playerId]; func_80008DC0(D_80163448); - //if (GetCourse() == GetKalimariDesert()) { + //if (IsKalimariDesert()) { CM_VehicleCollision(playerId, player); //func_80012DC0(playerId, player); if (playerId == 0) { @@ -1672,9 +1672,9 @@ void func_80009B60(s32 playerId) { //func_80013054(); } //} - if (GetCourse() == GetDkJungle()) { + if (IsDkJungle()) { //func_80013854(player); - } else if (GetCourse() == GetToadsTurnpike()) { + } else if (IsToadsTurnpike()) { func_800148C4(playerId, player); func_80014A18(playerId, player); func_80014B6C(playerId, player); @@ -1685,11 +1685,11 @@ void func_80009B60(s32 playerId) { player->unk_044 &= ~0x0001; } func_8000929C(playerId, player); - if ((GetCourse() != GetPodiumCeremony()) && ((D_80163240[playerId] == 1) || (playerId == 0))) { + if ((!IsPodiumCeremony()) && ((D_80163240[playerId] == 1) || (playerId == 0))) { set_places(); } if (player->type & 0x1000) { - if ((D_801630E2 == 1) && (GetCourse() != GetPodiumCeremony())) { + if ((D_801630E2 == 1) && (!IsPodiumCeremony())) { kart_ai_behaviour(playerId); } if ((playerId & 1) != (D_80163378 & 1)) { @@ -1706,11 +1706,11 @@ void func_80009B60(s32 playerId) { break; } D_801631E0[playerId] = 0; - if ((player->effects & 0x1000) && (GetCourse() != GetPodiumCeremony())) { + if ((player->effects & 0x1000) && (!IsPodiumCeremony())) { D_801631E0[playerId] = 1; } - if ((D_801646CC == 1) || (player->type & 0x800) || (GetCourse() == GetPodiumCeremony())) { - if (GetCourse() != GetToadsTurnpike()) { + if ((D_801646CC == 1) || (player->type & 0x800) || (IsPodiumCeremony())) { + if (!IsToadsTurnpike()) { D_801634F8[playerId].unk4 = 0.0f; } D_801634F8[playerId].unkC = 0.0f; @@ -1731,9 +1731,9 @@ void func_80009B60(s32 playerId) { // Old vehicle draw method was here - if ((GetCourse() == GetYoshiValley()) || (GetCourse() == GetPodiumCeremony())) { + if ((IsYoshiValley()) || (IsPodiumCeremony())) { D_801634F8[playerId].unk4 = 0.0f; - } else if (GetCourse() == GetToadsTurnpike()) { + } else if (IsToadsTurnpike()) { // func_8001490C(playerId); // func_80014A60(playerId); // func_80014BB4(playerId); @@ -1840,10 +1840,10 @@ void func_80009B60(s32 playerId) { } D_801630B8[playerId] = func_8000B7E4(playerId, sSomeNearestWaypoint); func_8000D438(playerId, sSomeNearestWaypoint); - if (GetCourse() != GetPodiumCeremony()) { + if (!IsPodiumCeremony()) { if (D_80164450[playerId] < 0xB) { stackPadding1A = D_801630E0; - if ((D_80164450[playerId] > 0) && (GetCourse() == GetToadsTurnpike())) { + if ((D_80164450[playerId] > 0) && (IsToadsTurnpike())) { stackPadding1A += 0x14; stackPadding1A %= D_80164430; func_8000BBD8(stackPadding1A, 0.0f, 0); @@ -1877,7 +1877,7 @@ void func_80009B60(s32 playerId) { } } } - if (GetCourse() == GetPodiumCeremony()) { + if (IsPodiumCeremony()) { switch (D_80163410[playerId]) { /* switch 3; irregular */ case 3: /* switch 3 */ D_80162FA0[0] = D_80163418[playerId]; @@ -2297,7 +2297,7 @@ s16 find_closest_waypoint_track_section(f32 posX, f32 posY, f32 posZ, u16 trackS considerWaypoint = &pathWaypoints[0]; for (considerWaypointIndex = 0; considerWaypointIndex < pathWaypointCount; considerWaypointIndex++, considerWaypoint++) { - if ((considerWaypoint->trackSectionId == trackSectionId) || (GetCourse() == GetPodiumCeremony())) { + if ((considerWaypoint->trackSectionId == trackSectionId) || (IsPodiumCeremony())) { var_t1 = 1; x_dist = (f32) considerWaypoint->posX - posX; y_dist = (f32) considerWaypoint->posY - posY; @@ -2463,7 +2463,7 @@ void func_8000CBA4(UNUSED f32 posX, f32 posY, UNUSED f32 posZ, s16* waypointInde s16 var_v0; var_v0 = *waypointIndex; - if ((GetCourse() == GetWarioStadium()) && (var_v0 >= 0x475) && (var_v0 < 0x480) && (posY < 0.0f)) { + if ((IsWarioStadium()) && (var_v0 >= 0x475) && (var_v0 < 0x480) && (posY < 0.0f)) { var_v0 = 0x0398; } *waypointIndex = var_v0; @@ -2666,11 +2666,11 @@ void func_8000D438(s32 arg0, u16 arg1) { sp2C = func_8000D3B8(arg0); thing = arg1; - if (GetCourse() == GetPodiumCeremony()) { + if (IsPodiumCeremony()) { var_a2 = 1; - } else if (GetCourse() == GetToadsTurnpike()) { + } else if (IsToadsTurnpike()) { var_a2 = 7; - } else if (GetCourse() == GetYoshiValley()) { + } else if (IsYoshiValley()) { } else { if (temp_v1 < 6) { var_a2 = 8; @@ -2908,11 +2908,11 @@ void set_bomb_kart_spawn_positions(void) { for (var_s3 = 0; var_s3 < NUM_BOMB_KARTS_VERSUS; var_s3++) { //bombKartSpawn = &gBombKartSpawns[gCurrentCourseId][var_s3]; - if (GetCourse() == GetYoshiValley()) { + if (IsYoshiValley()) { startingXPos = bombKartSpawn->startingXPos; startingZPos = bombKartSpawn->startingZPos; startingYPos = spawn_actor_on_surface(startingXPos, 2000.0f, startingZPos); - } else if (GetCourse() == GetPodiumCeremony()) { + } else if (IsPodiumCeremony()) { temp_v0 = &D_80164550[3][bombKartSpawn->waypointIndex]; startingXPos = temp_v0->posX; startingYPos = temp_v0->posY; @@ -3014,7 +3014,7 @@ void func_8000DF8C(s32 bombKartId) { return; } - if (((bombKart->unk_4A != 1) || (GetCourse() == GetPodiumCeremony()))) { + if (((bombKart->unk_4A != 1) || (IsPodiumCeremony()))) { var_f22 = bombKart->bombPos[0]; var_f20 = bombKart->bombPos[1]; var_f24 = bombKart->bombPos[2]; @@ -3025,7 +3025,7 @@ void func_8000DF8C(s32 bombKartId) { var_s1 = bombKart->circleTimer; if ((sp7E != 0) && (sp7E != 4)) { if (1) {} - if (GetCourse() == GetPodiumCeremony()) { + if (IsPodiumCeremony()) { if (D_8016347E == 1) { var_v0 = gPlayerFour; temp_f0 = var_f22 - var_v0->pos[0]; @@ -3049,7 +3049,7 @@ void func_8000DF8C(s32 bombKartId) { if ((((temp_f0 * temp_f0) + (temp_f2 * temp_f2)) + (temp_f12 * temp_f12)) < 25.0f) { sp7E = 4; var_s1 = 0; - if (GetCourse() == GetFrappeSnowland()) { + if (IsFrappeSnowland()) { var_v0->soundEffects |= 0x01000000; } else { var_v0->soundEffects |= 0x400000; @@ -3466,7 +3466,7 @@ void func_8000F628(void) { D_80163050[i] = 0; D_80162FF8[i] = 0; D_80163010[i] = 0; - if (GetCourse() != GetPodiumCeremony()) { + if (!IsPodiumCeremony()) { func_8000B95C(i, 0, 0); } //! todo: @BUG this doesn't seem right. This variable is metadata. @@ -3551,7 +3551,7 @@ void func_8000F628(void) { } } } - if ((gDemoUseController == 1) && (GetCourse() != GetPodiumCeremony())) { + if ((gDemoUseController == 1) && (!IsPodiumCeremony())) { for (i = 0; i < NUM_PLAYERS; i++) { D_80163330[i] = 0; } @@ -3635,7 +3635,7 @@ void func_800100F0(s32 pathIndex) { if (CM_GetProps()->AIMaximumSeparation >= 1.0f) { pathDest = D_80164550[pathIndex]; bInvalidPath = 1; - if (GetCourse() != GetPodiumCeremony()) { + if (!IsPodiumCeremony()) { TrackWaypoint* pathSrc = CM_GetProps()->PathTable2[pathIndex]; if (pathSrc == NULL) { @@ -3879,7 +3879,7 @@ void func_80010E6C(s32 pathIndex) { } else { break; } - if (GetCourse() == GetPodiumCeremony()) { + if (IsPodiumCeremony()) { break; } } @@ -3934,7 +3934,7 @@ s32 func_80011014(TrackWaypoint* pathDest, TrackWaypoint* path, s32 numPathPoint var_s0 = 0; temp_f20 = (f32) path[0].posX; temp_f22 = (f32) path[0].posZ; - var_f28 = func_80010F40(temp_f20, 2000.0f, temp_f22, gCurrentCourseId, 0); + var_f28 = func_80010F40(temp_f20, 2000.0f, temp_f22, 0, 0); for (i = 0; i < numPathPoints; i++) { point1 = &path[i % numPathPoints]; @@ -3969,10 +3969,10 @@ s32 func_80011014(TrackWaypoint* pathDest, TrackWaypoint* path, s32 numPathPoint if (gIsMirrorMode) { // temp_f12 = -temp_f24_2; pathDest->posX = (s16) -temp_f24_2; - var_f20_2 = func_80010FA0(-temp_f24_2, var_f28, x1_2, gCurrentCourseId, var_s0); + var_f20_2 = func_80010FA0(-temp_f24_2, var_f28, x1_2, 0, var_s0); } else { pathDest->posX = (s16) temp_f24_2; - var_f20_2 = func_80010FA0(temp_f24_2, var_f28, x1_2, gCurrentCourseId, var_s0); + var_f20_2 = func_80010FA0(temp_f24_2, var_f28, x1_2, 0, var_s0); } pathDest->posZ = (s16) temp_f22; @@ -3982,11 +3982,11 @@ s32 func_80011014(TrackWaypoint* pathDest, TrackWaypoint* path, s32 numPathPoint var_f20_2 = var_f28; } else { - if (GetCourse() == GetRainbowRoad()) { + if (IsRainbowRoad()) { if (var_f20_2 < (var_f28 - 15.0)) { var_f20_2 = (f32) var_f28 - 15.0; } - } else if (GetCourse() == GetWarioStadium()) { + } else if (IsWarioStadium()) { if ((var_s0 >= 1140) && (var_s0 <= 1152)) { var_f20_2 = var_f28; } else { @@ -3994,7 +3994,7 @@ s32 func_80011014(TrackWaypoint* pathDest, TrackWaypoint* path, s32 numPathPoint var_f20_2 = (f32) (var_f28 - 4.0); } } - } else if (GetCourse() == GetDkJungle()) { + } else if (IsDkJungle()) { if ((var_s0 > 204) && (var_s0 < 220)) { var_f20_2 = var_f28; } else { @@ -4628,7 +4628,7 @@ void func_80013054(void) { void check_ai_crossing_distance(s32 playerId) { bStopAICrossing[playerId] = 0; - if (GetCourse() == GetKalimariDesert()) { + if (IsKalimariDesert()) { if ((!(D_801631E0[playerId] != 0)) || (set_vehicle_render_distance_flags(gPlayers[playerId].pos, TRAIN_CROSSING_AI_DISTANCE, 0))) { @@ -5819,7 +5819,7 @@ void func_80016C3C(UNUSED s32 playerId, UNUSED f32 arg1, s32 cameraId) { D_80164688[cameraId] = -0.1f; } D_80163DD8[cameraId] = 0; - if (GetCourse() == GetYoshiValley()) { + if (IsYoshiValley()) { D_80163DD8[cameraId] = random_int(4U); D_80164688[cameraId] = 0.0f; } @@ -5892,8 +5892,7 @@ void func_80017054(Camera* camera, UNUSED Player* player, UNUSED s32 index, s32 D_80163238 = playerId; sp56 = gNearestWaypointByCameraId[cameraId]; gNearestWaypointByCameraId[cameraId] = func_8000D33C(camera->pos[0], camera->pos[1], camera->pos[2], gNearestWaypointByCameraId[cameraId], pathIndex); - // if (GetCourse() == GetYoshiValley()) { - if (gCurrentCourseId == 4) { + if (IsYoshiValley()) { if ((sp56 != gNearestWaypointByCameraId[cameraId]) && (gNearestWaypointByCameraId[cameraId] == 1)) { pathIndex = (D_80163DD8[cameraId] = random_int(4U)); gNearestWaypointByCameraId[cameraId] = func_8000D33C(camera->pos[0], camera->pos[1], camera->pos[2], gNearestWaypointByCameraId[cameraId], pathIndex); @@ -6574,7 +6573,7 @@ void func_80019D2C(Camera* camera, Player* player, s32 arg2) { s32 nearestWaypoint; playerId = camera->playerId; - if ((D_80163378 != 0) && (GetCourse() == GetLuigiRaceway())) { + if ((D_80163378 != 0) && (IsLuigiRaceway())) { calculate_camera_up_vector(camera, arg2); nearestWaypoint = gNearestWaypointByPlayerId[playerId]; if (((nearestWaypoint >= 0x65) && (nearestWaypoint < 0xFA)) || @@ -6719,7 +6718,7 @@ void func_8001A220(UNUSED s32 arg0, s32 cameraId) { } s32 func_8001A310(s32 waypoint, s32 arg1) { - if ((GetCourse() == GetBowsersCastle()) && (arg1 != 0) && (waypoint >= 0xE7) && (waypoint < 0x1C2)) { + if ((IsBowsersCastle()) && (arg1 != 0) && (waypoint >= 0xE7) && (waypoint < 0x1C2)) { arg1 = 0; } return arg1; @@ -7500,7 +7499,7 @@ void func_8001BE78(void) { void func_8001C05C(void) { init_segment_racing(); gCurrentCourseId = COURSE_AWARD_CEREMONY; - SetCourseByClass(GetPodiumCeremony()); + SelectPodiumCeremony(); D_8016347C = 0; D_8016347E = 0; D_80163480 = 0; @@ -7573,7 +7572,7 @@ void func_8001C14C(void) { } void render_bomb_karts_wrap(s32 cameraId) { - if (GetCourse() == GetPodiumCeremony()) { + if (IsPodiumCeremony()) { if (gBombKarts[0].waypointIndex >= 16) { render_bomb_karts(PLAYER_FOUR); } diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 50622a10a..2ce053cac 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -778,7 +778,7 @@ void render_object_for_player(s32 cameraId) { } void render_snowing_effect(s32 playerId) { - if (GetCourse() == GetFrappeSnowland()) { + if (IsFrappeSnowland()) { if (gGamestate != 9) { if ((D_8015F894 == 0) && (gPlayerCountSelection1 == 1)) { render_object_snowflakes_particles(); @@ -1563,7 +1563,7 @@ void func_8005A3C0(void) { } void func_8005A71C(void) { - // if (GetCourse() == GetBowsersCastle()) { + // if (IsBowsersCastle()) { // func_80081210(); //} } @@ -1644,7 +1644,7 @@ void update_object(void) { // func_80074EE8(); // Grand prix balloons //} func_80076F2C(); - if ((s16) GetCourse() != GetFrappeSnowland()) { + if (!IsFrappeSnowland()) { update_leaf(); } } @@ -2596,7 +2596,7 @@ void func_8005CB60(s32 playerId, s32 lapCount) { case 1: /* switch 1 */ CM_ActivateSecondLapLakitu(playerId); // func_80079084(playerId); func_800C9060(playerId, SOUND_ARG_LOAD(0x19, 0x00, 0xF0, 0x15)); - if ((GetCourse() == GetLuigiRaceway()) && (D_80165898 == 0) && + if ((IsLuigiRaceway()) && (D_80165898 == 0) && (gModeSelection != (s32) TIME_TRIALS)) { D_80165898 = 1; } @@ -2618,7 +2618,7 @@ void func_8005CB60(s32 playerId, s32 lapCount) { if (D_8018D114 == 2) { D_80165800[playerId] = 0; } - if (GetCourse() == GetYoshiValley()) { + if (IsYoshiValley()) { playerHUD[playerId].unk_81 = 1; } playerHUD[playerId].lap1CompletionTimeX = 0x0140; @@ -2935,22 +2935,22 @@ void func_8005DAF4(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 func_8005D794(player, &player->unk_258[10 + arg1], var_f2, var_f12, var_f14, (s8) surfaceType, (s8) var_t3); func_8005D7D8(&player->unk_258[10 + arg1], 2, 0.46f); - if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { + if ((IsChocoMountain()) || (IsRoyalRaceway())) { func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080); } - if (GetCourse() == GetKalimariDesert()) { + if (IsKalimariDesert()) { func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080); } - if (GetCourse() == GetMooMooFarm()) { + if (IsMooMooFarm()) { func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080); } - if (GetCourse() == GetWarioStadium()) { + if (IsWarioStadium()) { func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080); } - if (GetCourse() == GetYoshiValley()) { + if (IsYoshiValley()) { func_8005DAD8(&player->unk_258[10 + arg1], 10, 0, 0x0080); } - if (GetCourse() == GetDkJungle()) { + if (IsDkJungle()) { func_8005DAD8(&player->unk_258[10 + arg1], 11, 0, 0x0080); } player->unk_258[10 + arg1].unk_03A = random_int(0x0010U); @@ -2959,22 +2959,22 @@ void func_8005DAF4(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 func_8005D794(player, &player->unk_258[10 + arg1], var_f2, var_f12, var_f14, (s8) surfaceType, (s8) var_t3); func_8005D7D8(&player->unk_258[10 + arg1], 2, 0.46f); - if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { + if ((IsChocoMountain()) || (IsRoyalRaceway())) { func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080); } - if (GetCourse() == GetKalimariDesert()) { + if (IsKalimariDesert()) { func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080); } - if (GetCourse() == GetMooMooFarm()) { + if (IsMooMooFarm()) { func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080); } - if (GetCourse() == GetWarioStadium()) { + if (IsWarioStadium()) { func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080); } - if (GetCourse() == GetYoshiValley()) { + if (IsYoshiValley()) { func_8005DAD8(&player->unk_258[10 + arg1], 10, 0, 0x0080); } - if (GetCourse() == GetDkJungle()) { + if (IsDkJungle()) { func_8005DAD8(&player->unk_258[10 + arg1], 11, 0, 0x0080); } player->unk_258[10 + arg1].unk_03A = random_int(0x0010U); @@ -3201,44 +3201,44 @@ void func_8005ED48(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 ((player->unk_258[10 + arg2].unk_01E > 0) || (player->unk_258[10 + arg2].unk_01C == 0))) { func_8005D794(player, &player->unk_258[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t3); func_8005D7D8(&player->unk_258[10 + arg1], 5, 0.46f); - if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { + if ((IsChocoMountain()) || (IsRoyalRaceway())) { func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080); } - if (GetCourse() == GetKalimariDesert()) { + if (IsKalimariDesert()) { func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080); } - if (GetCourse() == GetMooMooFarm()) { + if (IsMooMooFarm()) { func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080); } - if (GetCourse() == GetWarioStadium()) { + if (IsWarioStadium()) { func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080); } - if (GetCourse() == GetYoshiValley()) { + if (IsYoshiValley()) { func_8005DAD8(&player->unk_258[10 + arg1], 10, 0, 0x0080); } - if (GetCourse() == GetDkJungle()) { + if (IsDkJungle()) { func_8005DAD8(&player->unk_258[10 + arg1], 11, 0, 0x0080); } player->unk_258[10 + arg1].unk_03A = random_int(0x0010U); } else if (player->unk_258[10 + arg2].unk_01E > 0) { func_8005D794(player, &player->unk_258[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t3); func_8005D7D8(&player->unk_258[10 + arg1], 5, 0.46f); - if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { + if ((IsChocoMountain()) || (IsRoyalRaceway())) { func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080); } - if (GetCourse() == GetKalimariDesert()) { + if (IsKalimariDesert()) { func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080); } - if (GetCourse() == GetMooMooFarm()) { + if (IsMooMooFarm()) { func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080); } - if (GetCourse() == GetWarioStadium()) { + if (IsWarioStadium()) { func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080); } - if (GetCourse() == GetYoshiValley()) { + if (IsYoshiValley()) { func_8005DAD8(&player->unk_258[10 + arg1], 0x000A, 0, 0x0080); } - if (GetCourse() == GetDkJungle()) { + if (IsDkJungle()) { func_8005DAD8(&player->unk_258[10 + arg1], 0x000B, 0, 0x0080); } player->unk_258[10 + arg1].unk_03A = random_int(0x0010U); @@ -3402,44 +3402,44 @@ void func_8005F90C(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 ((player->unk_258[10 + arg2].unk_01E > 0) || (player->unk_258[10 + arg2].unk_01C == 0))) { func_8005D794(player, &player->unk_258[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); func_8005D7D8(&player->unk_258[10 + arg1], 4, 0.46f); - if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { + if ((IsChocoMountain()) || (IsRoyalRaceway())) { func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080); } - if (GetCourse() == GetKalimariDesert()) { + if (IsKalimariDesert()) { func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080); } - if (GetCourse() == GetMooMooFarm()) { + if (IsMooMooFarm()) { func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080); } - if (GetCourse() == GetWarioStadium()) { + if (IsWarioStadium()) { func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080); } - if (GetCourse() == GetYoshiValley()) { + if (IsYoshiValley()) { func_8005DAD8(&player->unk_258[10 + arg1], 0x000A, 0, 0x0080); } - if (GetCourse() == GetDkJungle()) { + if (IsDkJungle()) { func_8005DAD8(&player->unk_258[10 + arg1], 0x000B, 0, 0x0080); } player->unk_258[10 + arg1].unk_03A = random_int(0x0010U); } else if (player->unk_258[10 + arg2].unk_01E > 0) { func_8005D794(player, &player->unk_258[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); func_8005D7D8(&player->unk_258[10 + arg1], 4, 0.46f); - if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { + if ((IsChocoMountain()) || (IsRoyalRaceway())) { func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080); } - if (GetCourse() == GetKalimariDesert()) { + if (IsKalimariDesert()) { func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080); } - if (GetCourse() == GetMooMooFarm()) { + if (IsMooMooFarm()) { func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080); } - if (GetCourse() == GetWarioStadium()) { + if (IsWarioStadium()) { func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080); } - if (GetCourse() == GetYoshiValley()) { + if (IsYoshiValley()) { func_8005DAD8(&player->unk_258[10 + arg1], 0x000A, 0, 0x0080); } - if (GetCourse() == GetDkJungle()) { + if (IsDkJungle()) { func_8005DAD8(&player->unk_258[10 + arg1], 0x000B, 0, 0x0080); } player->unk_258[10 + arg1].unk_03A = random_int(0x0010U); @@ -3638,13 +3638,13 @@ void func_800608E0(Player* player, s16 arg1, UNUSED s32 arg2, s8 arg3, UNUSED s8 var_f0 = 0.0f; } sp4C = (D_801652A0[arg3] - player->pos[1]) - 3.0f; - if ((player->unk_0DE & 1) && (GetCourse() != GetKoopaTroopaBeach())) { + if ((player->unk_0DE & 1) && (!IsKoopaTroopaBeach())) { var_f0 = 2.5f; sp4C = (f32) ((f64) (D_801652A0[arg3] - player->pos[1]) + 0.1); } func_8005D794(player, &player->unk_258[arg1], 0.0f, 0.0f, 0.0f, (s8) 0, (s8) 0); func_8005D7D8(&player->unk_258[arg1], 3, var_f0); - if ((GetCourse() == GetBowsersCastle()) || (GetCourse() == GetBigDonut())) { + if ((IsBowsersCastle()) || (IsBigDonut())) { func_8005D800(&player->unk_258[arg1], 0, 0x00AF); } else { func_8005D800(&player->unk_258[arg1], 0x00FFFFFF, 0x00CF); @@ -3658,7 +3658,7 @@ void func_800608E0(Player* player, s16 arg1, UNUSED s32 arg2, s8 arg3, UNUSED s8 } void func_80060B14(Player* player, s16 arg1, s32 arg2, s8 arg3, s8 arg4) { - if ((GetCourse() != GetSkyscraper()) && (GetCourse() != GetRainbowRoad())) { + if ((!IsSkyscraper()) && (!IsRainbowRoad())) { if ((arg1 == 0) && ((player->unk_258[arg2].unk_01E > 0) || (player->unk_258[arg2].unk_01C == 0))) { func_800608E0(player, arg1, arg2, arg3, arg4); } else if (player->unk_258[arg2].unk_01E > 0) { @@ -3674,10 +3674,10 @@ void func_80060BCC(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 f32 sp48; f32 sp44; - if (GetCourse() == GetSkyscraper()) { + if (IsSkyscraper()) { return; } - if (GetCourse() == GetRainbowRoad()) { + if (IsRainbowRoad()) { return; } sp54 = random_int(0x0168U) - 0xB4; @@ -3712,7 +3712,7 @@ void func_80060F50(Player* player, s16 arg1, UNUSED s32 arg2, s8 arg3, UNUSED s8 func_8005D794(player, &player->unk_258[arg1], 0.0f, 0.0f, 0.0f, 0, 0); func_8005D7D8(&player->unk_258[arg1], 5, 4.0f); - if ((GetCourse() == GetBowsersCastle()) || (GetCourse() == GetBigDonut())) { + if ((IsBowsersCastle()) || (IsBigDonut())) { func_8005D800(&player->unk_258[arg1], 0xFF0000, 0xFF); } else { func_8005D800(&player->unk_258[arg1], 0xFFFFFF, 0xFF); @@ -4058,22 +4058,22 @@ void func_800624D8(Player* player, UNUSED s32 arg1, UNUSED s32 arg2, UNUSED s8 a switch (player->surfaceType) { case DIRT: for (var_s1 = 0; var_s1 < 10; var_s1++) { - if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { + if ((IsChocoMountain()) || (IsRoyalRaceway())) { func_8005DAD8(&player->unk_258[0x1E + var_s1], 1, 0, 0x00A8); } - if (GetCourse() == GetKalimariDesert()) { + if (IsKalimariDesert()) { func_8005DAD8(&player->unk_258[0x1E + var_s1], 7, 0, 0x00A8); } - if (GetCourse() == GetMooMooFarm()) { + if (IsMooMooFarm()) { func_8005DAD8(&player->unk_258[0x1E + var_s1], 8, 0, 0x00A8); } - if (GetCourse() == GetWarioStadium()) { + if (IsWarioStadium()) { func_8005DAD8(&player->unk_258[0x1E + var_s1], 9, 0, 0x00A8); } - if (GetCourse() == GetYoshiValley()) { + if (IsYoshiValley()) { func_8005DAD8(&player->unk_258[0x1E + var_s1], 0x000A, 0, 0x00A8); } - if (GetCourse() == GetDkJungle()) { + if (IsDkJungle()) { func_8005DAD8(&player->unk_258[0x1E + var_s1], 0x000B, 0, 0x00A8); } func_80062484(player, &player->unk_258[0x1E + var_s1], var_s1); @@ -4628,7 +4628,7 @@ void func_80064184(Player* player, s16 arg1, s8 arg2, UNUSED s8 arg3) { f32 sp3C; sp40 = D_801652A0[arg2] - player->pos[1] - 3.0f; - if (((player->unk_0DE & 1) != 0) && (GetCourse() != GetKoopaTroopaBeach())) { + if (((player->unk_0DE & 1) != 0) && (!IsKoopaTroopaBeach())) { sp40 = D_801652A0[arg2] - player->pos[1] + 0.1; } diff --git a/src/code_8006E9C0.c b/src/code_8006E9C0.c index d74346d00..55d08c423 100644 --- a/src/code_8006E9C0.c +++ b/src/code_8006E9C0.c @@ -162,7 +162,7 @@ void init_item_window(s32 objectIndex) { temp_v0->sizeScaling = 1.0f; } -void func_8006EEE8(s32 courseId) { +void get_minimap_properties() { D_8018D240 = (uintptr_t) CM_GetProps()->Minimap.Texture; // This is incredibly dumb. MinimapDimensions ought to be something more like // `u16 MinimapDimensions[][2]` but that doesn't match for some insane reason @@ -191,8 +191,8 @@ void func_8006F008(void) { xOrientation = -1.0f; } - if (GetCourse() != GetPodiumCeremony()) { - func_8006EEE8((s32) gCurrentCourseId); + if (!IsPodiumCeremony()) { + get_minimap_properties(); } // Flip the minimap player markers @@ -203,7 +203,7 @@ void func_8006F008(void) { switch(gPlayerCount) { case 2: // Set X coord - if (GetCourse() != GetToadsTurnpike()) { + if (!IsToadsTurnpike()) { CM_GetProps()->Minimap.Pos[PLAYER_ONE].X = 265; CM_GetProps()->Minimap.Pos[PLAYER_TWO].X = 265; } else { diff --git a/src/code_8006E9C0.h b/src/code_8006E9C0.h index e5e9bc8d3..e41f7da1e 100644 --- a/src/code_8006E9C0.h +++ b/src/code_8006E9C0.h @@ -11,7 +11,7 @@ void clear_object_list(void); u8* dma_misc_textures(u8*, u8*, u32, u32); void load_mario_kart_64_logo(void); void init_item_window(s32); -void func_8006EEE8(s32); +void get_minimap_properties(void); void func_8006EF60(void); void func_8006F008(void); void func_8006F824(s32); diff --git a/src/code_80086E70.c b/src/code_80086E70.c index 89f51308a..3b0b0d5a0 100644 --- a/src/code_80086E70.c +++ b/src/code_80086E70.c @@ -977,7 +977,7 @@ void func_80089020(s32 playerId, f32* arg1) { var_f2 = -*arg1; } if (player->effects & 0xC0) { - if (GetCourse() == GetSherbetLand()) { + if (IsSherbetLand()) { if (var_f2 <= 0.5) { var_f0 = 0.025f; } else if (var_f2 <= 2.0) { @@ -998,7 +998,7 @@ void func_80089020(s32 playerId, f32* arg1) { var_f0 = 0.25f; } } - } else if (GetCourse() == GetSherbetLand()) { + } else if (IsSherbetLand()) { if (var_f2 <= 0.5) { var_f0 = 0.025f; } else if (var_f2 <= 2.0) { diff --git a/src/effects.c b/src/effects.c index 06e476117..da583c0c4 100644 --- a/src/effects.c +++ b/src/effects.c @@ -1698,7 +1698,7 @@ void func_80090178(Player* player, s8 playerId, Vec3f arg2, Vec3f arg3) { f32 sp18[4] = { 10.0f, -10.0f, -575.0f, 575.0f }; f32 sp08[4] = { 575.0f, -575.0f, 10.0f, -10.0f }; - if (GetCourse() == GetYoshiValley()) { + if (IsYoshiValley()) { test = player->nearestWaypointId; temp_v1 = &D_80164550[gCopyPathIndexByPlayerId[playerId]][test]; arg2[0] = temp_v1->posX; @@ -1710,28 +1710,28 @@ void func_80090178(Player* player, s8 playerId, Vec3f arg2, Vec3f arg3) { arg3[0] = temp_v1->posX; arg3[1] = temp_v1->posY; arg3[2] = temp_v1->posZ; - } else if (GetCourse() == GetBlockFort()) { + } else if (IsBlockFort()) { arg2[0] = spF8[playerId]; arg2[1] = 0.0f; arg2[2] = spE8[playerId]; arg3[0] = spD8[playerId]; arg3[1] = 0.0f; arg3[2] = spC8[playerId]; - } else if (GetCourse() == GetSkyscraper()) { + } else if (IsSkyscraper()) { arg2[0] = spB8[playerId]; arg2[1] = 480.0f; arg2[2] = spA8[playerId]; arg3[0] = sp98[playerId]; arg3[1] = 480.0f; arg3[2] = sp88[playerId]; - } else if (GetCourse() == GetDoubleDeck()) { + } else if (IsDoubleDeck()) { arg2[0] = sp78[playerId]; arg2[1] = 0.0f; arg2[2] = sp68[playerId]; arg3[0] = sp58[playerId]; arg3[1] = 0.0f; arg3[2] = sp48[playerId]; - } else if (GetCourse() == GetBigDonut()) { + } else if (IsBigDonut()) { arg2[0] = sp38[playerId]; arg2[1] = 200.0f; arg2[2] = sp28[playerId]; @@ -1799,14 +1799,14 @@ void func_80090868(Player* player) { player->unk_0CA |= 2; player->unk_0C8 = 0; if ((player->unk_0DE & 1) == 1) { - if ((GetCourse() == GetBowsersCastle()) || (GetCourse() == GetBigDonut())) { + if ((IsBowsersCastle()) || (IsBigDonut())) { player->unk_0CA |= 0x1000; } else { player->unk_0CA |= 0x2000; } - if ((GetCourse() == GetSherbetLand()) || (GetCourse() == GetSkyscraper()) || - (GetCourse() == GetRainbowRoad())) { + if ((IsSherbetLand()) || (IsSkyscraper()) || + (IsRainbowRoad())) { player->unk_0CA &= ~0x3000; } } diff --git a/src/ending/code_80281780.c b/src/ending/code_80281780.c index 1085fb30c..83d75a63d 100644 --- a/src/ending/code_80281780.c +++ b/src/ending/code_80281780.c @@ -93,7 +93,7 @@ void setup_podium_ceremony(void) { Camera* camera = &cameras[0]; gCurrentCourseId = COURSE_ROYAL_RACEWAY; - SetCourseByClass(GetPodiumCeremony()); + SelectPodiumCeremony(); D_800DC5B4 = (u16) 1; gIsMirrorMode = 0; gGotoMenu = 0xFFFF; diff --git a/src/engine/World.cpp b/src/engine/World.cpp index 6620a2815..88c6717c6 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -29,8 +29,10 @@ World::~World() { Course* CurrentCourse; Cup* CurrentCup; -void World::AddCourse(Course* course) { - gWorldInstance.Courses.push_back(course); +Course* World::AddCourse(std::unique_ptr course) { + Course* ptr = course.get(); + gWorldInstance.Courses.push_back(std::move(course)); + return ptr; } void World::AddCup(Cup* cup) { @@ -97,7 +99,7 @@ void World::SetCourse(const char* name) { //! @todo Use content dictionary instead for (size_t i = 0; i < Courses.size(); i++) { if (strcmp(Courses[i]->Props.Name, name) == 0) { - CurrentCourse = Courses[i]; + CurrentCourse = Courses[i].get(); break; } } @@ -110,7 +112,7 @@ void World::NextCourse() { } else { CourseIndex = 0; } - gWorldInstance.CurrentCourse = Courses[CourseIndex]; + gWorldInstance.CurrentCourse = Courses[CourseIndex].get(); } void World::PreviousCourse() { @@ -119,7 +121,7 @@ void World::PreviousCourse() { } else { CourseIndex = Courses.size() - 1; } - gWorldInstance.CurrentCourse = Courses[CourseIndex]; + gWorldInstance.CurrentCourse = Courses[CourseIndex].get(); } AActor* World::AddActor(AActor* actor) { diff --git a/src/engine/World.h b/src/engine/World.h index 91287b162..f32cf00ff 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -54,7 +54,7 @@ public: explicit World(); ~World(); - void AddCourse(Course* course); + Course* AddCourse(std::unique_ptr course); AActor* AddActor(AActor* actor); struct Actor* AddBaseActor(); @@ -96,6 +96,16 @@ public: // These are only for browsing through the course list void SetCourse(const char*); + template + void SetCourseByType() { + for (const auto& course : Courses) { + if (dynamic_cast(course.get())) { + CurrentCourse = course.get(); + return; + } + } + printf("World::SetCourseByType() No course by the type found"); + } void NextCourse(void); void PreviousCourse(void); @@ -122,7 +132,7 @@ public: std::vector> Crossings; // Holds all available courses - std::vector Courses; + std::vector> Courses; size_t CourseIndex = 0; // For browsing courses. private: diff --git a/src/engine/objects/BombKart.cpp b/src/engine/objects/BombKart.cpp index 53b4a4262..8aaaae6cf 100644 --- a/src/engine/objects/BombKart.cpp +++ b/src/engine/objects/BombKart.cpp @@ -118,7 +118,7 @@ void OBombKart::Tick() { return; } - if (((Unk_4A != 1) || (GetCourse() == GetPodiumCeremony()))) { + if (((Unk_4A != 1) || (IsPodiumCeremony()))) { newPos[0] = Pos[0]; newPos[1] = Pos[1]; newPos[2] = Pos[2]; @@ -128,7 +128,7 @@ void OBombKart::Tick() { bounceTimer = BounceTimer; circleTimer = CircleTimer; if ((state != States::DISABLED) && (state != States::EXPLODE)) { - if (GetCourse() == GetPodiumCeremony()) { + if (IsPodiumCeremony()) { if (D_8016347E == 1) { player = gPlayerFour; temp_f0 = newPos[0] - player->pos[0]; @@ -152,7 +152,7 @@ void OBombKart::Tick() { if ((((temp_f0 * temp_f0) + (temp_f2 * temp_f2)) + (temp_f12 * temp_f12)) < 25.0f) { state = States::EXPLODE; circleTimer = 0; - if (GetCourse() == GetFrappeSnowland()) { + if (IsFrappeSnowland()) { player->soundEffects |= 0x01000000; } else { player->soundEffects |= 0x400000; @@ -346,7 +346,7 @@ void OBombKart::Draw(s32 cameraId) { return; } - if (GetCourse() == GetPodiumCeremony()) { + if (IsPodiumCeremony()) { if ((_idx == 0) && (WaypointIndex < 16)) { return; } else { diff --git a/src/engine/objects/GrandPrixBalloons.cpp b/src/engine/objects/GrandPrixBalloons.cpp index 544a3e4d1..2bd58ef13 100644 --- a/src/engine/objects/GrandPrixBalloons.cpp +++ b/src/engine/objects/GrandPrixBalloons.cpp @@ -139,7 +139,7 @@ void OGrandPrixBalloons::func_80074924(s32 objectIndex) { object = &gObjectList[objectIndex]; object->sizeScaling = 0.15f; - if (GetCourse() == GetMarioRaceway()) { + if (IsMarioRaceway()) { sp2C = random_int(0x00C8U); sp28 = random_int(_numBalloons3); sp24 = random_int(0x0096U); @@ -147,7 +147,7 @@ void OGrandPrixBalloons::func_80074924(s32 objectIndex) { object->origin_pos[0] = (f32) ((((f64) Pos.x + 100.0) - (f64) sp2C) * (f64) xOrientation); object->origin_pos[1] = (f32) (Pos.y + sp28); object->origin_pos[2] = (f32) (((f64) Pos.z + 200.0) - (f64) sp24); - } else if (GetCourse() == GetRoyalRaceway()) { + } else if (IsRoyalRaceway()) { sp2C = random_int(0x0168U); sp28 = random_int(_numBalloons3); sp24 = random_int(0x00B4U); @@ -155,7 +155,7 @@ void OGrandPrixBalloons::func_80074924(s32 objectIndex) { object->origin_pos[0] = (f32) ((((f64) Pos.x + 180.0) - (f64) sp2C) * (f64) xOrientation); object->origin_pos[1] = (f32) (Pos.y + sp28); object->origin_pos[2] = (f32) (((f64) Pos.z + 200.0) - (f64) sp24); - } else if (GetCourse() == GetLuigiRaceway()) { + } else if (IsLuigiRaceway()) { sp2C = random_int(0x012CU); sp28 = random_int(_numBalloons3); sp24 = random_int(0x0096U); diff --git a/src/engine/objects/HotAirBalloon.cpp b/src/engine/objects/HotAirBalloon.cpp index 4e337d98e..f1e367d8d 100644 --- a/src/engine/objects/HotAirBalloon.cpp +++ b/src/engine/objects/HotAirBalloon.cpp @@ -21,7 +21,7 @@ OHotAirBalloon::OHotAirBalloon(const FVector& pos) { D_80165898 = 0; // Spawn balloon on second lap. - if (GetCourse() == GetLuigiRaceway()) { + if (IsLuigiRaceway()) { _visible = (bool*)&D_80165898; } else { // Spawn balloon on race start bool mod = true; diff --git a/src/engine/objects/Lakitu.cpp b/src/engine/objects/Lakitu.cpp index 92f164e95..988d3bc22 100644 --- a/src/engine/objects/Lakitu.cpp +++ b/src/engine/objects/Lakitu.cpp @@ -297,7 +297,7 @@ void OLakitu::func_800729EC(s32 objectIndex) { D_8018D2BC = 1; D_8018D2A4 = 1; - if (GetCourse() != GetYoshiValley()) { + if (!IsYoshiValley()) { for (i = 0; i < gPlayerCount; i++) { playerHUD[i].unk_81 = temp_v1; } @@ -366,7 +366,7 @@ void OLakitu::func_800797AC(s32 playerId) { objectIndex = gIndexLakituList[playerId]; player = &gPlayerOne[playerId]; - //if ((GetCourse() == GetSherbetLand()) && (player->unk_0CA & 1)) { + //if ((IsSherbetLand()) && (player->unk_0CA & 1)) { if ((CM_GetProps()->LakituTowType == LakituTowType::ICE) && (player->unk_0CA & 1)) { init_object(objectIndex, 7); player->unk_0CA |= 0x10; diff --git a/src/engine/objects/TrashBin.cpp b/src/engine/objects/TrashBin.cpp index 89ac5dae5..57c702275 100644 --- a/src/engine/objects/TrashBin.cpp +++ b/src/engine/objects/TrashBin.cpp @@ -32,7 +32,7 @@ OTrashBin::OTrashBin(const FVector& pos, const IRotator& rotation, f32 scale, OT init_object(_objectIndex, 0); - if (GetCourse() != GetBansheeBoardwalk()) { + if (!IsBansheeBoardwalk()) { _drawBin = true; } } diff --git a/src/menu_items.c b/src/menu_items.c index 713250882..d65e4b2a4 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -2528,12 +2528,15 @@ void func_80095574(void) { } else { debug_print_str2(0x000000AA, 0x00000064, "off"); } - if ((gCurrentCourseId >= (NUM_COURSES - 1)) || (gCurrentCourseId < 0)) { - gCurrentCourseId = 0; - } + + // This reset is not necessary. It wraps around automatically. + // if ((GetCourseIndex() >= (NUM_COURSES - 1)) || (GetCourseIndex() < 0)) { + // gCurrentCourseId = 0; + // } print_str_num(0x00000050, 0x0000006E, "map_number", GetCourseIndex()); - // This isn't functionally equivallent, but who cares. - if (gCurrentCourseId < COURSE_TOADS_TURNPIKE) { + + // Bump the text over by 1 character width when the track id becomes two digits (10, 11, 12 etc.) + if (GetCourseIndex() < 10) { var_v0 = 0; } else { var_v0 = 8; @@ -4889,7 +4892,7 @@ void func_8009CE64(s32 arg0) { gCCSelection = (s32) 1; switch (gNextDemoId) { /* switch 4 */ case 0: /* switch 4 */ - SetCourseByClass(GetMarioRaceway()); + SelectMarioRaceway(); CM_SetCup(GetFlowerCup()); SetCupCursorPosition(COURSE_FOUR); gCurrentCourseId = 0; @@ -4900,7 +4903,7 @@ void func_8009CE64(s32 arg0) { gModeSelection = 0; break; case 1: /* switch 4 */ - SetCourseByClass(GetLuigiRaceway()); + SelectLuigiRaceway(); CM_SetCup(GetMushroomCup()); SetCupCursorPosition(COURSE_ONE); gCurrentCourseId = (s16) 1; @@ -4912,7 +4915,7 @@ void func_8009CE64(s32 arg0) { gModeSelection = 2; break; case 2: /* switch 4 */ - SetCourseByClass(GetKalimariDesert()); + SelectKalimariDesert(); CM_SetCup(GetMushroomCup()); SetCupCursorPosition(COURSE_FOUR); gCurrentCourseId = COURSE_KALIMARI_DESERT; @@ -4923,7 +4926,7 @@ void func_8009CE64(s32 arg0) { gModeSelection = 0; break; case 3: /* switch 4 */ - SetCourseByClass(GetWarioStadium()); + SelectWarioStadium(); CM_SetCup(GetStarCup()); SetCupCursorPosition(COURSE_ONE); gCurrentCourseId = 0x000E; @@ -4936,7 +4939,7 @@ void func_8009CE64(s32 arg0) { gModeSelection = (s32) 2; break; case 4: /* switch 4 */ - SetCourseByClass(GetBowsersCastle()); + SelectBowsersCastle(); CM_SetCup(GetStarCup()); SetCupCursorPosition(COURSE_FOUR); gCurrentCourseId = 2; @@ -4947,7 +4950,7 @@ void func_8009CE64(s32 arg0) { gModeSelection = 0; break; case 5: /* switch 4 */ - SetCourseByClass(GetSherbetLand()); + SelectSherbetLand(); CM_SetCup(GetFlowerCup()); SetCupCursorPosition(COURSE_TWO); gCurrentCourseId = 0x000C; @@ -5034,8 +5037,8 @@ void func_8009CE64(s32 arg0) { } } - if (GetCourse() == GetBlockFort() || GetCourse() == GetSkyscraper() || GetCourse() == GetDoubleDeck() || - GetCourse() == GetBigDonut()) { + if (IsBlockFort() || IsSkyscraper() || IsDoubleDeck() || + IsBigDonut()) { gModeSelection = BATTLE; if (gPlayerCountSelection1 == 1) { @@ -8230,7 +8233,9 @@ void func_800A6034(MenuItem* arg0) { set_text_color(TEXT_BLUE_GREEN_RED_CYCLE_2); print_text1_center_mode_2(arg0->column + 0x41, arg0->row + 0xA0, text, 0, 0.85f, 1.0f); text = CM_GetProps()->Name; - set_text_color((s32) gCurrentCourseId % 4); + //! @warning this used to be gCurrentCourseId % 4 + // Hopefully this is equivallent. + set_text_color((s32) GetCourseIndex() % 4); print_text1_center_mode_2(arg0->column + 0x41, arg0->row + 0xC3, text, 0, 0.65f, 0.85f); } } diff --git a/src/player_controller.c b/src/player_controller.c index df4b794bb..46038dbda 100644 --- a/src/player_controller.c +++ b/src/player_controller.c @@ -1711,7 +1711,7 @@ void func_8002C11C(Player* player) { } void func_8002C17C(Player* player, s8 playerId) { - if (GetCourse() == GetYoshiValley()) { + if (IsYoshiValley()) { if ((player->collision.surfaceDistance[2] >= 600.0f) && (D_80165330[playerId] == 0)) { D_80165330[playerId] = 1; gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; @@ -1724,7 +1724,7 @@ void func_8002C17C(Player* player, s8 playerId) { D_80165330[playerId] = 0; } } - } else if (GetCourse() == GetFrappeSnowland()) { + } else if (IsFrappeSnowland()) { if ((player->surfaceType == SNOW_OFFROAD) && (D_80165330[playerId] == 0)) { D_80165330[playerId] = 1; gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; @@ -1734,7 +1734,7 @@ void func_8002C17C(Player* player, s8 playerId) { gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; } - } else if (GetCourse() == GetRoyalRaceway()) { + } else if (IsRoyalRaceway()) { if (((player->effects & BOOST_RAMP_ASPHALT_EFFECT) != 0) && (D_80165330[playerId] == 0)) { D_80165330[playerId] = 1; gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; @@ -1744,7 +1744,7 @@ void func_8002C17C(Player* player, s8 playerId) { gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; } - } else if (GetCourse() == GetRainbowRoad()) { + } else if (IsRainbowRoad()) { if ((player->collision.surfaceDistance[2] >= 600.0f) && (D_80165330[playerId] == 0)) { D_80165330[playerId] = 1; gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; @@ -1778,9 +1778,9 @@ void func_8002C4F8(Player* player, s8 arg1) { if ((player->unk_0DE & 4) != 4) { player->unk_0DE |= 8; player->unk_0DE |= 4; - if ((GetCourse() != GetKoopaTroopaBeach()) && (GetCourse() != GetSkyscraper()) && - (GetCourse() != GetRainbowRoad()) && ((player->type & PLAYER_HUMAN) == PLAYER_HUMAN)) { - if ((GetCourse() == GetBowsersCastle()) || (GetCourse() == GetBigDonut())) { + if ((!IsKoopaTroopaBeach()) && (!IsSkyscraper()) && + (!IsRainbowRoad()) && ((player->type & PLAYER_HUMAN) == PLAYER_HUMAN)) { + if ((IsBowsersCastle()) || (IsBigDonut())) { func_800C9060((u8) arg1, 0x1900801CU); } else { func_800C9060((u8) arg1, 0x19008008U); @@ -1788,8 +1788,8 @@ void func_8002C4F8(Player* player, s8 arg1) { } } } - if ((GetCourse() == GetKoopaTroopaBeach()) || (GetCourse() == GetSkyscraper()) || - (GetCourse() == GetRainbowRoad())) { + if ((IsKoopaTroopaBeach()) || (IsSkyscraper()) || + (IsRainbowRoad())) { player->unk_0DE &= ~0x000C; } if ((player->boundingBoxSize < (D_801652A0[arg1] - player->pos[1])) && @@ -2254,7 +2254,7 @@ void func_8002D268(Player* player, UNUSED Camera* camera, s8 screenId, s8 player player->unk_DB4.unkC = 1.5f; if (((player->type & PLAYER_HUMAN) == PLAYER_HUMAN) && ((player->type & PLAYER_INVISIBLE_OR_BOMB) != PLAYER_INVISIBLE_OR_BOMB)) { - if (((player->unk_0C2 < 0xB) && (player->unk_0C2 >= 4)) && (GetCourse() == GetBowsersCastle())) { + if (((player->unk_0C2 < 0xB) && (player->unk_0C2 >= 4)) && (IsBowsersCastle())) { func_800CADD0((u8) playerId, player->unk_0C2 / 14.0f); } else { func_800CADD0((u8) playerId, player->unk_0C2 / 25.0f); diff --git a/src/port/Game.cpp b/src/port/Game.cpp index caccd9f90..4cea9c5e2 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -69,29 +69,7 @@ extern "C" void Timer_Update(); // Create the world instance World gWorldInstance; -MarioRaceway* gMarioRaceway; -ChocoMountain* gChocoMountain; -BowsersCastle* gBowsersCastle; -BansheeBoardwalk* gBansheeBoardwalk; -YoshiValley* gYoshiValley; -FrappeSnowland* gFrappeSnowland; -KoopaTroopaBeach* gKoopaTroopaBeach; -RoyalRaceway* gRoyalRaceway; -LuigiRaceway* gLuigiRaceway; -MooMooFarm* gMooMooFarm; -ToadsTurnpike* gToadsTurnpike; -KalimariDesert* gKalimariDesert; -SherbetLand* gSherbetLand; -RainbowRoad* gRainbowRoad; -WarioStadium* gWarioStadium; -BlockFort* gBlockFort; -Skyscraper* gSkyscraper; -DoubleDeck* gDoubleDeck; -DKJungle* gDkJungle; -BigDonut* gBigDonut; -PodiumCeremony* gPodiumCeremony; -Harbour* gHarbour; -TestCourse* gTestCourse; +std::unique_ptr gPodiumCeremony; Cup* gMushroomCup; Cup* gFlowerCup; @@ -108,65 +86,52 @@ Editor::Editor gEditor; s32 gTrophyIndex = NULL; void CustomEngineInit() { - - gMarioRaceway = new MarioRaceway(); - gChocoMountain = new ChocoMountain(); - gBowsersCastle = new BowsersCastle(); - gBansheeBoardwalk = new BansheeBoardwalk(); - gYoshiValley = new YoshiValley(); - gFrappeSnowland = new FrappeSnowland(); - gKoopaTroopaBeach = new KoopaTroopaBeach(); - gRoyalRaceway = new RoyalRaceway(); - gLuigiRaceway = new LuigiRaceway(); - gMooMooFarm = new MooMooFarm(); - gToadsTurnpike = new ToadsTurnpike(); - gKalimariDesert = new KalimariDesert(); - gSherbetLand = new SherbetLand(); - gRainbowRoad = new RainbowRoad(); - gWarioStadium = new WarioStadium(); - gBlockFort = new BlockFort(); - gSkyscraper = new Skyscraper(); - gDoubleDeck = new DoubleDeck(); - gDkJungle = new DKJungle(); - gBigDonut = new BigDonut(); - gPodiumCeremony = new PodiumCeremony(); - gHarbour = new Harbour(); - gTestCourse = new TestCourse(); - /* Add all courses to the global course list */ - gWorldInstance.AddCourse(gMarioRaceway); - gWorldInstance.AddCourse(gChocoMountain); - gWorldInstance.AddCourse(gBowsersCastle); - gWorldInstance.AddCourse(gBansheeBoardwalk); - gWorldInstance.AddCourse(gYoshiValley); - gWorldInstance.AddCourse(gFrappeSnowland); - gWorldInstance.AddCourse(gKoopaTroopaBeach); - gWorldInstance.AddCourse(gRoyalRaceway); - gWorldInstance.AddCourse(gLuigiRaceway); - gWorldInstance.AddCourse(gMooMooFarm); - gWorldInstance.AddCourse(gToadsTurnpike); - gWorldInstance.AddCourse(gKalimariDesert); - gWorldInstance.AddCourse(gSherbetLand); - gWorldInstance.AddCourse(gRainbowRoad); - gWorldInstance.AddCourse(gWarioStadium); - gWorldInstance.AddCourse(gBlockFort); - gWorldInstance.AddCourse(gSkyscraper); - gWorldInstance.AddCourse(gDoubleDeck); - gWorldInstance.AddCourse(gDkJungle); - gWorldInstance.AddCourse(gBigDonut); - gWorldInstance.AddCourse(gHarbour); - gWorldInstance.AddCourse(gTestCourse); + Course* mario = gWorldInstance.AddCourse(std::make_unique()); + Course* choco = gWorldInstance.AddCourse(std::make_unique()); + Course* bowser = gWorldInstance.AddCourse(std::make_unique()); + Course* banshee = gWorldInstance.AddCourse(std::make_unique()); + Course* yoshi = gWorldInstance.AddCourse(std::make_unique()); + Course* frappe = gWorldInstance.AddCourse(std::make_unique()); + Course* koopa = gWorldInstance.AddCourse(std::make_unique()); + Course* royal = gWorldInstance.AddCourse(std::make_unique()); + Course* luigi = gWorldInstance.AddCourse(std::make_unique()); + Course* mooMoo = gWorldInstance.AddCourse(std::make_unique()); + Course* toads = gWorldInstance.AddCourse(std::make_unique()); + Course* kalimari = gWorldInstance.AddCourse(std::make_unique()); + Course* sherbet = gWorldInstance.AddCourse(std::make_unique()); + Course* rainbow = gWorldInstance.AddCourse(std::make_unique()); + Course* wario = gWorldInstance.AddCourse(std::make_unique()); + Course* block = gWorldInstance.AddCourse(std::make_unique()); + Course* skyscraper = gWorldInstance.AddCourse(std::make_unique()); + Course* doubleDeck = gWorldInstance.AddCourse(std::make_unique()); + Course* dkJungle = gWorldInstance.AddCourse(std::make_unique()); + Course* bigDonut = gWorldInstance.AddCourse(std::make_unique()); + Course* harbour = gWorldInstance.AddCourse(std::make_unique()); + Course* testCourse = gWorldInstance.AddCourse(std::make_unique()); - gMushroomCup = new Cup("mk:mushroom_cup", "mushroom cup", - std::vector{ gLuigiRaceway, gMooMooFarm, gKoopaTroopaBeach, gKalimariDesert }); - gFlowerCup = new Cup("mk:flower_cup", "flower cup", - std::vector{ gToadsTurnpike, gFrappeSnowland, gChocoMountain, gMarioRaceway }); - gStarCup = new Cup("mk:star_cup", "star cup", - std::vector{ gWarioStadium, gSherbetLand, gRoyalRaceway, gBowsersCastle }); - gSpecialCup = new Cup("mk:special_cup", "special cup", - std::vector{ gDkJungle, gYoshiValley, gBansheeBoardwalk, gRainbowRoad }); - gBattleCup = - new Cup("mk:battle_cup", "battle", std::vector{ gBigDonut, gBlockFort, gDoubleDeck, gSkyscraper }); + gPodiumCeremony = std::make_unique(); + + // Construct cups with vectors of Course* (non-owning references) + gMushroomCup = new Cup("mk:mushroom_cup", "Mushroom Cup", { + luigi, mooMoo, koopa, kalimari + }); + + gFlowerCup = new Cup("mk:flower_cup", "Flower Cup", { + toads, frappe, choco, mario + }); + + gStarCup = new Cup("mk:star_cup", "Star Cup", { + wario, sherbet, royal, bowser + }); + + gSpecialCup = new Cup("mk:special_cup", "Special Cup", { + dkJungle, yoshi, banshee, rainbow + }); + + gBattleCup = new Cup("mk:battle_cup", "Battle Cup", { + bigDonut, block, doubleDeck, skyscraper + }); /* Instantiate Cups */ gWorldInstance.AddCup(gMushroomCup); @@ -176,7 +141,7 @@ void CustomEngineInit() { gWorldInstance.AddCup(gBattleCup); /* Set default course; mario raceway */ - gWorldInstance.CurrentCourse = gMarioRaceway; + SelectMarioRaceway(); gWorldInstance.CurrentCup = gMushroomCup; gWorldInstance.CurrentCup->CursorPosition = 3; gWorldInstance.CupIndex = 0; @@ -199,30 +164,6 @@ void CustomEngineInit() { } void CustomEngineDestroy() { - delete gMarioRaceway; - delete gChocoMountain; - delete gBowsersCastle; - delete gBansheeBoardwalk; - delete gYoshiValley; - delete gFrappeSnowland; - delete gKoopaTroopaBeach; - delete gRoyalRaceway; - delete gLuigiRaceway; - delete gMooMooFarm; - delete gToadsTurnpike; - delete gKalimariDesert; - delete gSherbetLand; - delete gRainbowRoad; - delete gWarioStadium; - delete gBlockFort; - delete gSkyscraper; - delete gDoubleDeck; - delete gDkJungle; - delete gBigDonut; - delete gPodiumCeremony; - delete gHarbour; - delete gTestCourse; - delete gMushroomCup; delete gFlowerCup; delete gStarCup; @@ -311,7 +252,7 @@ void SetCourseById(s32 course) { return; } gWorldInstance.CourseIndex = course; - gWorldInstance.CurrentCourse = gWorldInstance.Courses[gWorldInstance.CourseIndex]; + gWorldInstance.CurrentCourse = gWorldInstance.Courses[gWorldInstance.CourseIndex].get(); } void CM_VehicleCollision(s32 playerId, Player* player) { @@ -760,89 +701,51 @@ f32 CM_GetWaterLevel(Vec3f pos, Collision* collision) { return gWorldInstance.CurrentCourse->GetWaterLevel(fPos, collision); } -void* GetMarioRaceway(void) { - return gMarioRaceway; -} +// clang-format off +bool IsMarioRaceway() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsLuigiRaceway() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsChocoMountain() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsBowsersCastle() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsBansheeBoardwalk() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsYoshiValley() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsFrappeSnowland() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsKoopaTroopaBeach() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsRoyalRaceway() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsMooMooFarm() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsToadsTurnpike() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsKalimariDesert() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsSherbetLand() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsRainbowRoad() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsWarioStadium() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsBlockFort() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsSkyscraper() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsDoubleDeck() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsDkJungle() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsBigDonut() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } +bool IsPodiumCeremony() { return dynamic_cast(gWorldInstance.CurrentCourse) != nullptr; } -void* GetLuigiRaceway(void) { - return gLuigiRaceway; -} - -void* GetChocoMountain(void) { - return gChocoMountain; -} - -void* GetBowsersCastle(void) { - return gBowsersCastle; -} - -void* GetBansheeBoardwalk(void) { - return gBansheeBoardwalk; -} - -void* GetYoshiValley(void) { - return gYoshiValley; -} - -void* GetFrappeSnowland(void) { - return gFrappeSnowland; -} - -void* GetKoopaTroopaBeach(void) { - return gKoopaTroopaBeach; -} - -void* GetRoyalRaceway(void) { - return gRoyalRaceway; -} - -void* GetMooMooFarm(void) { - return gMooMooFarm; -} - -void* GetToadsTurnpike(void) { - return gToadsTurnpike; -} - -void* GetKalimariDesert(void) { - return gKalimariDesert; -} - -void* GetSherbetLand(void) { - return gSherbetLand; -} - -void* GetRainbowRoad(void) { - return gRainbowRoad; -} - -void* GetWarioStadium(void) { - return gWarioStadium; -} - -void* GetBlockFort(void) { - return gBlockFort; -} - -void* GetSkyscraper(void) { - return gSkyscraper; -} - -void* GetDoubleDeck(void) { - return gDoubleDeck; -} - -void* GetDkJungle(void) { - return gDkJungle; -} - -void* GetBigDonut(void) { - return gBigDonut; -} - -void* GetPodiumCeremony(void) { - return gPodiumCeremony; -} +void SelectMarioRaceway() { gWorldInstance.SetCourseByType(); } +void SelectLuigiRaceway() { gWorldInstance.SetCourseByType(); } +void SelectChocoMountain() { gWorldInstance.SetCourseByType(); } +void SelectBowsersCastle() { gWorldInstance.SetCourseByType(); } +void SelectBansheeBoardwalk() { gWorldInstance.SetCourseByType(); } +void SelectYoshiValley() { gWorldInstance.SetCourseByType(); } +void SelectFrappeSnowland() { gWorldInstance.SetCourseByType(); } +void SelectKoopaTroopaBeach() { gWorldInstance.SetCourseByType(); } +void SelectRoyalRaceway() { gWorldInstance.SetCourseByType(); } +void SelectMooMooFarm() { gWorldInstance.SetCourseByType(); } +void SelectToadsTurnpike() { gWorldInstance.SetCourseByType(); } +void SelectKalimariDesert() { gWorldInstance.SetCourseByType(); } +void SelectSherbetLand() { gWorldInstance.SetCourseByType(); } +void SelectRainbowRoad() { gWorldInstance.SetCourseByType(); } +void SelectWarioStadium() { gWorldInstance.SetCourseByType(); } +void SelectBlockFort() { gWorldInstance.SetCourseByType(); } +void SelectSkyscraper() { gWorldInstance.SetCourseByType(); } +void SelectDoubleDeck() { gWorldInstance.SetCourseByType(); } +void SelectDkJungle() { gWorldInstance.SetCourseByType(); } +void SelectBigDonut() { gWorldInstance.SetCourseByType(); } +void SelectPodiumCeremony() { gWorldInstance.CurrentCourse = gPodiumCeremony.get(); } +// clang-format on void* GetMushroomCup(void) { return gMushroomCup; diff --git a/src/port/Game.h b/src/port/Game.h index 2731372ca..14cc0edf6 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -157,47 +157,49 @@ void CM_CleanWorld(void); f32 CM_GetWaterLevel(Vec3f pos, Collision* collision); -void* GetMarioRaceway(void); +bool IsMarioRaceway(); +bool IsLuigiRaceway(); +bool IsChocoMountain(); +bool IsBowsersCastle(); +bool IsBansheeBoardwalk(); +bool IsYoshiValley(); +bool IsFrappeSnowland(); +bool IsKoopaTroopaBeach(); +bool IsRoyalRaceway(); +bool IsMooMooFarm(); +bool IsToadsTurnpike(); +bool IsKalimariDesert(); +bool IsSherbetLand(); +bool IsRainbowRoad(); +bool IsWarioStadium(); +bool IsBlockFort(); +bool IsSkyscraper(); +bool IsDoubleDeck(); +bool IsDkJungle(); +bool IsBigDonut(); +bool IsPodiumCeremony(); -void* GetLuigiRaceway(void); - -void* GetChocoMountain(void); - -void* GetBowsersCastle(void); - -void* GetBansheeBoardwalk(void); - -void* GetYoshiValley(void); - -void* GetFrappeSnowland(void); - -void* GetKoopaTroopaBeach(void); - -void* GetRoyalRaceway(void); - -void* GetMooMooFarm(void); - -void* GetToadsTurnpike(void); - -void* GetKalimariDesert(void); - -void* GetSherbetLand(void); - -void* GetRainbowRoad(void); - -void* GetWarioStadium(void); - -void* GetBlockFort(void); - -void* GetSkyscraper(void); - -void* GetDoubleDeck(void); - -void* GetDkJungle(void); - -void* GetBigDonut(void); - -void* GetPodiumCeremony(void); +void SelectMarioRaceway(); +void SelectLuigiRaceway(); +void SelectChocoMountain(); +void SelectBowsersCastle(); +void SelectBansheeBoardwalk(); +void SelectYoshiValley(); +void SelectFrappeSnowland(); +void SelectKoopaTroopaBeach(); +void SelectRoyalRaceway(); +void SelectMooMooFarm(); +void SelectToadsTurnpike(); +void SelectKalimariDesert(); +void SelectSherbetLand(); +void SelectRainbowRoad(); +void SelectWarioStadium(); +void SelectBlockFort(); +void SelectSkyscraper(); +void SelectDoubleDeck(); +void SelectDkJungle(); +void SelectBigDonut(); +void SelectPodiumCeremony(); void* GetMushroomCup(void); diff --git a/src/port/ui/ContentBrowser.cpp b/src/port/ui/ContentBrowser.cpp index 826477ea5..5390d8a9d 100644 --- a/src/port/ui/ContentBrowser.cpp +++ b/src/port/ui/ContentBrowser.cpp @@ -147,12 +147,13 @@ namespace Editor { } } + // When resetting the known content, we need to also pop the custom courses + // out of World::Courses vector. Otherwise, duplicate courses would show up for users. void ContentBrowserWindow::RemoveCustomTracksFromTrackList() { for (auto& track : Tracks) { auto it = gWorldInstance.Courses.begin(); while (it != gWorldInstance.Courses.end()) { - if (track.course == *it) { - delete *it; + if (track.course == it->get()) { it = gWorldInstance.Courses.erase(it); } else { ++it; @@ -233,27 +234,31 @@ namespace Editor { std::string name = dir.substr(dir.find_last_of('/') + 1); std::string sceneFile = dir + "/scene.json"; std::string minimapFile = dir + "/minimap.png"; + // The track has a valid scene file if (manager->HasFile(sceneFile)) { auto archive = manager->GetArchiveFromFile(sceneFile); - Course* course = new Course(); + auto course = std::make_unique(); course->LoadO2R(dir); - gWorldInstance.Courses.push_back(course); - LoadLevel(archive, course, sceneFile); - LoadMinimap(archive, course, minimapFile); - Tracks.push_back({course, sceneFile, name, dir, archive}); - } else { + gWorldInstance.Courses.push_back(std::move(course)); + LoadLevel(archive, course.get(), sceneFile); + LoadMinimap(archive, course.get(), minimapFile); + Tracks.push_back({course.get(), sceneFile, name, dir, archive}); + } else { // The track does not have a valid scene file const std::string file = dir + "/data_track_sections"; + // If the track has a data_track_sections file, + // then it must at least be a valid track. + // So lets add it as an uninitialized track. if (manager->HasFile(file)) { - Course* course = new Course(); + auto course = std::make_unique(); course->Id = (std::string("mods:") + name).c_str(); course->Props.SetText(course->Props.Name, name.c_str(), sizeof(course->Props.Name)); course->Props.SetText(course->Props.DebugName, name.c_str(), sizeof(course->Props.Name)); auto archive = manager->GetArchiveFromFile(file); - Tracks.push_back({course, "", name, dir, archive}); + Tracks.push_back({course.get(), "", name, dir, archive}); } else { printf("ContentBrowser.cpp: Track '%s' missing required track files. Cannot add to game\n Missing %s/data_track_sections file\n", name.c_str(), dir.c_str()); } diff --git a/src/racing/actors.c b/src/racing/actors.c index d6fd2ade1..137e3556e 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -944,15 +944,15 @@ void spawn_foliage(struct ActorSpawnData* actor) { position[2] = var_s3->pos[2]; position[1] = var_s3->pos[1]; - if (GetCourse() == GetMarioRaceway()) { + if (IsMarioRaceway()) { actorType = 2; - } else if (GetCourse() == GetBowsersCastle()) { + } else if (IsBowsersCastle()) { actorType = 0x0021; - } else if (GetCourse() == GetYoshiValley()) { + } else if (IsYoshiValley()) { actorType = 3; - } else if (GetCourse() == GetFrappeSnowland()) { + } else if (IsFrappeSnowland()) { actorType = 0x001D; - } else if (GetCourse() == GetRoyalRaceway()) { + } else if (IsRoyalRaceway()) { switch (var_s3->signedSomeId) { case 6: actorType = 0x001C; @@ -961,11 +961,11 @@ void spawn_foliage(struct ActorSpawnData* actor) { actorType = 4; break; } - } else if (GetCourse() == GetLuigiRaceway()) { + } else if (IsLuigiRaceway()) { actorType = 0x001A; - } else if (GetCourse() == GetMooMooFarm()) { + } else if (IsMooMooFarm()) { actorType = 0x0013; - } else if (GetCourse() == GetKalimariDesert()) { + } else if (IsKalimariDesert()) { switch (var_s3->signedSomeId) { case 5: actorType = 0x001E; @@ -1706,8 +1706,8 @@ bool collision_tree(Player* player, struct Actor* actor) { actorPos[0] = actor->pos[0]; actorPos[1] = actor->pos[1]; actorPos[2] = actor->pos[2]; - if (((GetCourse() == GetMarioRaceway()) || (GetCourse() == GetYoshiValley()) || - (GetCourse() == GetRoyalRaceway()) || (GetCourse() == GetLuigiRaceway())) && + if (((IsMarioRaceway()) || (IsYoshiValley()) || + (IsRoyalRaceway()) || (IsLuigiRaceway())) && (player->unk_094 > 1.0f)) { spawn_leaf(actorPos, 0); } @@ -2571,9 +2571,9 @@ void render_course_actors(struct UnkStruct_800DC5EC* arg0) { } FrameInterpolation_RecordCloseChild(); } - if (GetCourse() == GetMooMooFarm()) { + if (IsMooMooFarm()) { render_cows(camera, sBillBoardMtx); - } else if (GetCourse() == GetDkJungle()) { + } else if (IsDkJungle()) { render_palm_trees(camera, sBillBoardMtx); } } diff --git a/src/racing/math_util.c b/src/racing/math_util.c index 3682e07d5..127961703 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -14,8 +14,6 @@ #include #pragma intrinsic(sqrtf, fabs) -extern s16 gCurrentCourseId; - s32 D_802B91C0[2] = { 13, 13 }; Vec3f D_802B91C8 = { 0.0f, 0.0f, 0.0f }; @@ -1146,7 +1144,7 @@ f32 is_within_render_distance(Vec3f cameraPos, Vec3f objectPos, u16 orientationY if (minDistance == 0.0f) { if (is_visible_between_angle((orientationY + extended_fov), (orientationY - extended_fov), angleObject) == 1) { - if (gCurrentCourseId == 0xB /* COURSE_KALAMARI_DESERT */) { + if (IsKalimariDesert()) { return distance / 6.5f; // set for better DD settings in Desert } else { return distance / 10.0f; // Items @@ -1156,7 +1154,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) { - if (gCurrentCourseId == 0xB /* COURSE_KALAMARI_DESERT */) { + if (IsKalimariDesert()) { return distance / 2.0f; } else { return distance / 10.0f; // DD Vhicles diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index 4b9cf1af9..4247cd88c 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -418,7 +418,7 @@ void func_8028EC38(s32 arg0) { void func_8028EC98(s32 arg0) { - // We want music in mutilplayer + // We want music in multiplayer, so this was removed //if (gScreenModeSelection == SCREEN_MODE_3P_4P_SPLITSCREEN) { // return; //} @@ -897,9 +897,9 @@ void func_8028FCBC(void) { func_8028F914(); if (D_802BA034 == 1.0f) { if (gActiveScreenMode != SCREEN_MODE_1P) { - if (GetCourse() == GetLuigiRaceway()) { + if (IsLuigiRaceway()) { func_802A7940(); - } else if (GetCourse() == GetWarioStadium()) { + } else if (IsWarioStadium()) { func_802A7728(); } } @@ -909,7 +909,9 @@ void func_8028FCBC(void) { CM_SpawnStarterLakitu(); // func_80078F64(); if ((gModeSelection == TIME_TRIALS) && (D_80162DD6 == 0)) { phi_v0_4 = 0x1; - for (i = 0; i < gCurrentCourseId; i++) { + //! @warning this used to be < gCurrentCourseId + // Hopefully this is equivallent. + for (i = 0; i < GetCourseIndex(); i++) { phi_v0_4 <<= 1; } if ((D_8015F890 == 0) && (!(D_800DC5AC & phi_v0_4))) { diff --git a/src/racing/render_courses.c b/src/racing/render_courses.c index 1b1e7ec26..bf16380d3 100644 --- a/src/racing/render_courses.c +++ b/src/racing/render_courses.c @@ -133,7 +133,7 @@ void render_course_segments(const char* addr[], struct UnkStruct_800DC5EC* arg1) index = sp1E; } } else { - if (GetCourse() == GetBowsersCastle()) { + if (IsBowsersCastle()) { if ((temp_v0_3 >= 0x11) && (temp_v0_3 < 0x18)) { index = temp_v0_3; } else if ((temp_v0_3 == 255) && (sp1E != 255)) { @@ -143,7 +143,7 @@ void render_course_segments(const char* addr[], struct UnkStruct_800DC5EC* arg1) } else { index = arg1->pathCounter; } - } else if (GetCourse() == GetChocoMountain()) { + } else if (IsChocoMountain()) { if ((temp_v0_3 >= 0xE) && (temp_v0_3 < 0x16)) { index = temp_v0_3; } else if ((temp_v0_3 == 255) && (sp1E != 255)) { @@ -176,7 +176,7 @@ void render_course_segments(const char* addr[], struct UnkStruct_800DC5EC* arg1) index = ((index - 1) * 4) + direction; gSPDisplayList(gDisplayListHead++, addr[index]); - if (CVarGetInteger("gDisableLod", 1) == 1 && (GetCourse() == GetBowsersCastle()) && + if (CVarGetInteger("gDisableLod", 1) == 1 && (IsBowsersCastle()) && (index < 20 || index > 99)) { // always render higher version of bowser statue gDisplayListHead--; gSPDisplayList(gDisplayListHead++, d_course_bowsers_castle_dl_9148); // use credit version of the course diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index 9a31c378a..62399dfea 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -407,7 +407,7 @@ void func_802A487C(Vtx* arg0, UNUSED struct UnkStruct_800DC5EC* arg1, UNUSED s32 UNUSED f32* arg4) { init_rdp(); - if (GetCourse() != GetRainbowRoad()) { + if (!IsRainbowRoad()) { gDPSetRenderMode(gDisplayListHead++, G_RM_OPA_SURF, G_RM_OPA_SURF2); gSPClearGeometryMode(gDisplayListHead++, G_ZBUFFER | G_LIGHTING); @@ -485,7 +485,7 @@ void func_802A4A0C(Vtx* vtx, struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, U gSPMatrix(gDisplayListHead++, &gIdentityMatrix2, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPVertex(gDisplayListHead++, &vtx[0], 4, 0); gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0); - if (GetCourse() == GetRainbowRoad()) { + if (IsRainbowRoad()) { gSPVertex(gDisplayListHead++, &vtx[4], 4, 0); gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0); } diff --git a/src/render_objects.c b/src/render_objects.c index 3b6aa44c6..7aa06dcaf 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3013,7 +3013,7 @@ void draw_lap_count(s16 lapX, s16 lapY, s8 lap) { } void func_8004FDB4(f32 arg0, f32 arg1, s16 arg2, s16 arg3, s16 characterId, s32 arg5, s32 arg6, s32 arg7, s32 arg8) { - if ((GetCourse() == GetYoshiValley()) && (arg3 < 3) && (arg8 == 0)) { + if ((IsYoshiValley()) && (arg3 < 3) && (arg8 == 0)) { func_80042330((s32) arg0, (s32) arg1, 0U, 1.0f); gSPDisplayList(gDisplayListHead++, D_0D007DB8); func_8004B35C(0x000000FF, 0x000000FF, 0x000000FF, D_8018D3E0); @@ -3320,7 +3320,7 @@ void func_80050E34(s32 playerId, s32 arg1) { spB8 = 0; } - if ((GetCourse() == GetYoshiValley()) && (lapCount < 3)) { + if ((IsYoshiValley()) && (lapCount < 3)) { gSPDisplayList(gDisplayListHead++, D_0D007DB8); gDPLoadTLUT_pal256(gDisplayListHead++, common_tlut_portrait_bomb_kart_and_question_mark); rsp_load_texture(common_texture_portrait_question_mark, 0x00000020, 0x00000020); @@ -3553,16 +3553,16 @@ void func_80051C60(s16 arg0, s32 arg1) { Object* object; if (D_801658FE == 0) { - if (GetCourse() == GetKoopaTroopaBeach()) { + if (IsKoopaTroopaBeach()) { var_s5 = arg0; - } else if (GetCourse() == GetMooMooFarm()) { + } else if (IsMooMooFarm()) { var_s5 = arg0 - 16; - } else if (GetCourse() == GetYoshiValley()) { + } else if (IsYoshiValley()) { var_s5 = arg0 - 16; } else { var_s5 = arg0 + 16; } - } else if (GetCourse() == GetKoopaTroopaBeach()) { + } else if (IsKoopaTroopaBeach()) { var_s5 = arg0 * 2; } else { var_s5 = arg0 + 32; @@ -3596,11 +3596,11 @@ void func_80051EF8(void) { s16 temp_a0; temp_a0 = 0xF0 - D_800DC5EC->cameraHeight; - if (GetCourse() == GetKoopaTroopaBeach()) { + if (IsKoopaTroopaBeach()) { temp_a0 = temp_a0 - 0x30; - } else if (GetCourse() == GetMooMooFarm()) { + } else if (IsMooMooFarm()) { temp_a0 = temp_a0 - 0x40; - } else if (GetCourse() == GetYoshiValley()) { + } else if (IsYoshiValley()) { temp_a0 = temp_a0 - 0x40; } else { temp_a0 = temp_a0 - 0x30; @@ -3612,11 +3612,11 @@ void func_80051F9C(void) { s16 temp_a0; temp_a0 = 0xF0 - D_800DC5F0->cameraHeight; - if (GetCourse() == GetKoopaTroopaBeach()) { + if (IsKoopaTroopaBeach()) { temp_a0 = temp_a0 - 0x30; - } else if (GetCourse() == GetMooMooFarm()) { + } else if (IsMooMooFarm()) { temp_a0 = temp_a0 - 0x40; - } else if (GetCourse() == GetYoshiValley()) { + } else if (IsYoshiValley()) { temp_a0 = temp_a0 - 0x40; } else { temp_a0 = temp_a0 - 0x30; diff --git a/src/render_player.c b/src/render_player.c index ca4247ef9..5061826f6 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -1277,7 +1277,7 @@ void change_player_color_effect_cmy(UNUSED Player* player, s8 arg1, s32 arg2, f3 * Sort of an atmospheric effect. */ bool is_player_under_light_luigi_raceway(Player* player, s8 arg1) { - if (GetCourse() == GetLuigiRaceway()) { + if (IsLuigiRaceway()) { if (((gNearestWaypointByPlayerId[arg1] >= 0x14F) && (gNearestWaypointByPlayerId[arg1] < 0x158)) || ((gNearestWaypointByPlayerId[arg1] >= 0x15E) && (gNearestWaypointByPlayerId[arg1] < 0x164)) || ((gNearestWaypointByPlayerId[arg1] >= 0x169) && (gNearestWaypointByPlayerId[arg1] < 0x170)) || @@ -1295,7 +1295,7 @@ bool is_player_under_light_luigi_raceway(Player* player, s8 arg1) { } void render_light_environment_on_player(Player* player, s8 arg1) { - if (GetCourse() == GetBowsersCastle()) { + if (IsBowsersCastle()) { if (((gNearestWaypointByPlayerId[arg1] >= 0x15) && (gNearestWaypointByPlayerId[arg1] < 0x2A)) || ((gNearestWaypointByPlayerId[arg1] >= 0x14D) && (gNearestWaypointByPlayerId[arg1] < 0x15C)) || ((gNearestWaypointByPlayerId[arg1] >= 0x1D1) && (gNearestWaypointByPlayerId[arg1] < 0x1E4)) || @@ -1318,7 +1318,7 @@ void render_light_environment_on_player(Player* player, s8 arg1) { change_player_color_effect_cmy(player, arg1, 0, 0.3f); D_80164B80[arg1] = 0; } - } else if (GetCourse() == GetBansheeBoardwalk()) { + } else if (IsBansheeBoardwalk()) { if (((gNearestWaypointByPlayerId[arg1] >= 0xD) && (gNearestWaypointByPlayerId[arg1] < 0x15)) || ((gNearestWaypointByPlayerId[arg1] >= 0x29) && (gNearestWaypointByPlayerId[arg1] < 0x39)) || ((gNearestWaypointByPlayerId[arg1] >= 0x46) && (gNearestWaypointByPlayerId[arg1] < 0x4E)) || diff --git a/src/spawn_players.c b/src/spawn_players.c index 92185f3d9..96b6dcd2e 100644 --- a/src/spawn_players.c +++ b/src/spawn_players.c @@ -729,7 +729,7 @@ void spawn_players_versus_two_player(f32* arg0, f32* arg1, f32 arg2) { } void spawn_players_2p_battle(f32* arg0, f32* arg1, f32 arg2) { - if (GetCourse() == GetBigDonut()) { + if (IsBigDonut()) { spawn_player(gPlayerOne, 0, arg0[0], arg1[0], arg2, -16384.0f, gCharacterSelections[0], PLAYER_EXISTS | PLAYER_START_SEQUENCE | PLAYER_HUMAN); spawn_player(gPlayerTwo, 1, arg0[1], arg1[1], arg2, 16384.0f, gCharacterSelections[1], @@ -778,7 +778,7 @@ void func_8003B318(f32* arg0, f32* arg1, f32 arg2) { } void spawn_players_3p_battle(f32* arg0, f32* arg1, f32 arg2) { - if (GetCourse() == GetBigDonut()) { + if (IsBigDonut()) { spawn_player(gPlayerOne, 0, arg0[0], arg1[0], arg2, -16384.0f, gCharacterSelections[0], PLAYER_EXISTS | PLAYER_START_SEQUENCE | PLAYER_HUMAN); spawn_player(gPlayerTwo, 1, arg0[1], arg1[1], arg2, 16384.0f, gCharacterSelections[1], @@ -830,7 +830,7 @@ void func_8003B870(f32* arg0, f32* arg1, f32 arg2) { } void spawn_players_4p_battle(f32* arg0, f32* arg1, f32 arg2) { - if (GetCourse() == GetBigDonut()) { + if (IsBigDonut()) { spawn_player(gPlayerOne, 0, arg0[0], arg1[0], arg2, -16384.0f, gCharacterSelections[0], PLAYER_EXISTS | PLAYER_START_SEQUENCE | PLAYER_HUMAN); spawn_player(gPlayerTwo, 1, arg0[1], arg1[1], arg2, 16384.0f, gCharacterSelections[1], @@ -888,17 +888,17 @@ void func_8003C0F0(void) { if (gModeSelection == BATTLE) { func_8000EEDC(); - } else if (GetCourse() != GetPodiumCeremony()) { + } else if (!IsPodiumCeremony()) { func_8000F2DC(); sp5E = (f32) D_80164550[0][0].posX; sp5C = (f32) D_80164550[0][0].posZ; sp5A = (f32) D_80164550[0][0].posY; - if (GetCourse() == GetToadsTurnpike()) { + if (IsToadsTurnpike()) { sp5E = 0; } } - if ((gModeSelection != BATTLE) && (GetCourse() != GetPodiumCeremony())) { + if ((gModeSelection != BATTLE) && (!IsPodiumCeremony())) { switch (gActiveScreenMode) { case SCREEN_MODE_1P: switch (gModeSelection) { @@ -993,7 +993,7 @@ void func_8003C0F0(void) { } break; } - } else if (GetCourse() == GetBlockFort()) { + } else if (IsBlockFort()) { switch (gActiveScreenMode) { case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: @@ -1023,7 +1023,7 @@ void func_8003C0F0(void) { } break; } - } else if (GetCourse() == GetSkyscraper()) { + } else if (IsSkyscraper()) { switch (gActiveScreenMode) { case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: @@ -1053,7 +1053,7 @@ void func_8003C0F0(void) { } break; } - } else if (GetCourse() == GetDoubleDeck()) { + } else if (IsDoubleDeck()) { switch (gActiveScreenMode) { case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: @@ -1083,7 +1083,7 @@ void func_8003C0F0(void) { } break; } - } else if (GetCourse() == GetBigDonut()) { + } else if (IsBigDonut()) { switch (gActiveScreenMode) { case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: @@ -1200,7 +1200,7 @@ void func_8003D080(void) { case SCREEN_MODE_1P: switch (gModeSelection) { case GRAND_PRIX: - if (GetCourse() == GetToadsTurnpike()) { + if (IsToadsTurnpike()) { camera_init(0.0f, player->pos[1], D_80165230[7], player->rotation[1], 8, 0); } else { camera_init((D_80165210[7] + D_80165210[6]) / 2, player->pos[1], D_80165230[7], diff --git a/src/staff_ghosts.c b/src/staff_ghosts.c index 914809d38..c92892cdc 100644 --- a/src/staff_ghosts.c +++ b/src/staff_ghosts.c @@ -39,7 +39,7 @@ u32* D_80162DB4; s16 D_80162DB8; u32* D_80162DBC; -u16 D_80162DC0; +uintptr_t staff_ghost_track_ptr; StaffGhost* D_80162DC4; s32 D_80162DC8; s32 D_80162DCC; @@ -164,11 +164,11 @@ void func_80005310(void) { set_staff_ghost(); - if (D_80162DC0 != gCurrentCourseId) { + if (staff_ghost_track_ptr != (uintptr_t)GetCourse()) { D_80162DD4 = 1; } - D_80162DC0 = (u16) gCurrentCourseId; + staff_ghost_track_ptr = (uintptr_t)GetCourse(); D_80162DF0 = 0; D_80162DEC = 0; D_80162DF8 = 0; diff --git a/src/update_objects.c b/src/update_objects.c index 6d2b8a77a..0435a69d7 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -2106,19 +2106,19 @@ void init_object_leaf_particle(s32 objectIndex, Vec3f arg1, s32 num) { gObjectList[objectIndex].sizeScaling = 0.1f; gObjectList[objectIndex].surfaceHeight = arg1[1]; - if (GetCourse() == GetMarioRaceway()) { + if (IsMarioRaceway()) { object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 25.0, arg1[2], 0x14, 0x1E, 0x14); gObjectList[objectIndex].unk_034 = 1.5f; gObjectList[objectIndex].velocity[1] = 1.5f; - } else if (GetCourse() == GetYoshiValley()) { + } else if (IsYoshiValley()) { object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 25.0, arg1[2], 0x14, 0x1E, 0x14); gObjectList[objectIndex].unk_034 = 2.0f; gObjectList[objectIndex].velocity[1] = 2.0f; - } else if (GetCourse() == GetRoyalRaceway()) { + } else if (IsRoyalRaceway()) { object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 30.0, arg1[2], 0x10, 0x28, 0x10); gObjectList[objectIndex].unk_034 = 2.0f; gObjectList[objectIndex].velocity[1] = 2.0f; - } else if (GetCourse() == GetLuigiRaceway()) { + } else if (IsLuigiRaceway()) { object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 25.0, arg1[2], 0x14, 0x1E, 0x14); gObjectList[objectIndex].unk_034 = 1.5f; gObjectList[objectIndex].velocity[1] = 1.0f;