summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMegaMech <MegaMech@users.noreply.github.com>2025-06-15 22:17:24 -0600
committerGitHub <noreply@github.com>2025-06-15 22:17:24 -0600
commit9fe391a2a4617cdb6ce3b2ab743183756f2ca9bd (patch)
treeef05cdebfde9874e3a4fd890b391d37232786d4b /src
parent547d651cc470503867a4e2e060536ca768dbb1ec (diff)
Fix More Interpolation (#220)
* Fix SetTextMatrix Interpolation (flashing text) * Interpolate pause menu item box * Interp mtxf_translation_x_y_rotate_z_scale_x_y * Fix billboarding for freecam * Fix menus battle mode back to grand prix bug * Fix snow interp * interp star clouds
Diffstat (limited to 'src')
-rw-r--r--src/engine/Matrix.cpp26
-rw-r--r--src/engine/Matrix.h3
-rw-r--r--src/engine/courses/FrappeSnowland.cpp2
-rw-r--r--src/math_util_2.c1
-rw-r--r--src/menu_items.c43
-rw-r--r--src/menus.c1
-rw-r--r--src/os/guMtxCatL.c2
-rw-r--r--src/port/interpolation/FrameInterpolation.cpp65
-rw-r--r--src/port/interpolation/FrameInterpolation.h8
-rw-r--r--src/racing/actors.c13
-rw-r--r--src/render_objects.c4
11 files changed, 135 insertions, 33 deletions
diff --git a/src/engine/Matrix.cpp b/src/engine/Matrix.cpp
index 671489413..b55a9b89f 100644
--- a/src/engine/Matrix.cpp
+++ b/src/engine/Matrix.cpp
@@ -35,8 +35,8 @@ void AddMatrixFixed(std::vector<Mtx>& stack, s32 flags) {
}
// Used in func_80095BD0
-Mtx* SetTextMatrix(f32 arg1, f32 arg2, f32 arg3, f32 arg4) {
- Mat4 mf;
+void SetTextMatrix(Mat4 mf, f32 x, f32 y, f32 arg3, f32 arg4) {
+ FrameInterpolation_Record_SetTextMatrix((Mat4*)&mf, x, y, arg3, arg4);
mf[0][0] = arg3;
mf[0][1] = 0.0f;
mf[0][2] = 0.0f;
@@ -49,15 +49,25 @@ Mtx* SetTextMatrix(f32 arg1, f32 arg2, f32 arg3, f32 arg4) {
mf[2][1] = 0.0f;
mf[2][2] = 1.0f;
mf[2][3] = 0.0f;
- mf[3][0] = arg1;
- mf[3][1] = arg2;
+ mf[3][0] = x;
+ mf[3][1] = y;
mf[3][2] = 0.0f;
mf[3][3] = 1.0f;
- Mtx* mtx = GetMatrix(gWorldInstance.Mtx.Effects);
- FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mf, mtx);
- guMtxF2L(mf, mtx);
+}
+
+// AddMatrix but with custom gfx ptr arg and flags are predefined
+Gfx* AddTextMatrix(Gfx* displayListHead, Mat4 mtx) {
+ // Push a new matrix to the stack
+ gWorldInstance.Mtx.Effects.emplace_back();
+
+ // Convert to a fixed-point matrix
+ FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mtx, &gWorldInstance.Mtx.Effects.back());
+ guMtxF2L(mtx, &gWorldInstance.Mtx.Effects.back());
+
+ // Load the matrix
+ gSPMatrix(displayListHead++, &gWorldInstance.Mtx.Effects.back(), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
- return mtx;
+ return displayListHead;
}
void ApplyMatrixTransformations(Mat4 mtx, FVector pos, IRotator rot, FVector scale) {
diff --git a/src/engine/Matrix.h b/src/engine/Matrix.h
index 180ebfb16..a1e943a40 100644
--- a/src/engine/Matrix.h
+++ b/src/engine/Matrix.h
@@ -17,7 +17,8 @@ void AddObjectMatrix(Mat4 mtx, s32 flags);
void AddEffectMatrix(Mat4 mtx, s32 flags);
void AddEffectMatrixOrtho(void);
void AddEffectMatrixFixed(s32 flags);
-Mtx* SetTextMatrix(f32 arg1, f32 arg2, f32 arg3, f32 arg4);
+void SetTextMatrix(Mat4 mf, f32 arg1, f32 arg2, f32 arg3, f32 arg4);
+Gfx* AddTextMatrix(Gfx* displayListHead, Mat4 mtx);
Mtx* GetEffectMatrix(void);
void ClearHudMatrixPool(void);
void ClearEffectsMatrixPool(void);
diff --git a/src/engine/courses/FrappeSnowland.cpp b/src/engine/courses/FrappeSnowland.cpp
index 16b9b7380..66a1f9b1a 100644
--- a/src/engine/courses/FrappeSnowland.cpp
+++ b/src/engine/courses/FrappeSnowland.cpp
@@ -178,7 +178,6 @@ void FrappeSnowland::BeginPlay() {
void FrappeSnowland::InitClouds() {
s32 var_s0;
s32 var_s4;
-
if (gPlayerCount == 1) {
var_s4 = 0x32;
} else {
@@ -189,6 +188,7 @@ void FrappeSnowland::InitClouds() {
}
D_8018D1F8 += var_s0;
D_8018D1F0 = var_s0;
+ D_8018D230 = 0; // This must be turned off or mayhem ensues
}
void FrappeSnowland::UpdateClouds(s32 sp1C, Camera* camera) {
diff --git a/src/math_util_2.c b/src/math_util_2.c
index b113c6a5d..1431d8ada 100644
--- a/src/math_util_2.c
+++ b/src/math_util_2.c
@@ -579,6 +579,7 @@ UNUSED void mtxf_rotate_z_scale_x_y(Mat4 dest, u16 angle, f32 scale) {
void mtxf_translation_x_y_rotate_z_scale_x_y(Mat4 dest, s32 x, s32 y, u16 angle, f32 scale) {
f32 sin_theta = sins(angle);
f32 cos_theta = coss(angle) * scale;
+ FrameInterpolation_RecordMatrixPosRotScaleXY(dest, x, y, angle, scale);
dest[2][0] = 0.0f;
dest[0][0] = cos_theta;
diff --git a/src/menu_items.c b/src/menu_items.c
index d65e4b2a4..6be566b08 100644
--- a/src/menu_items.c
+++ b/src/menu_items.c
@@ -47,6 +47,7 @@
#include "engine/courses/Course.h"
#include "engine/Matrix.h"
#include "src/engine/HM_Intro.h"
+#include "src/port/interpolation/FrameInterpolation.h"
const char* GetCupName(void);
@@ -2716,9 +2717,13 @@ Gfx* func_80095BD0(Gfx* displayListHead, u8* arg1, f32 arg2, f32 arg3, u32 arg4,
if (gMatrixEffectCount < 0) {
rmonPrintf("effectcount < 0 !!!!!!(kawano)\n");
}
+ FrameInterpolation_RecordOpenChild("flashing_text", TAG_LETTER((uintptr_t)&arg1 << 8) + (arg4 + arg5));
+ Mat4 mf;
+ SetTextMatrix(mf, arg2, arg3, arg6, arg7);
// func_80095AE0(&gGfxPool->mtxEffect[gMatrixEffectCount], arg2, arg3, arg6, arg7);
- Mtx* mtx = SetTextMatrix(arg2, arg3, arg6, arg7);
- gSPMatrix(displayListHead++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ displayListHead = AddTextMatrix(displayListHead, mf);
+ //gSPMatrix(displayListHead++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gMKLoadTextureTile_4b(displayListHead++, arg1, G_IM_FMT_I, arg4, 0, 0, 0, arg4, arg5, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
switch (arg4) {
@@ -2735,28 +2740,32 @@ Gfx* func_80095BD0(Gfx* displayListHead, u8* arg1, f32 arg2, f32 arg3, u32 arg4,
var_a1 = D_02007DF8;
break;
}
-
- return func_800959F8(displayListHead, var_a1);
+ displayListHead = func_800959F8(displayListHead, var_a1);
+ FrameInterpolation_RecordCloseChild();
+ return displayListHead;
}
+// Time trials text box
Gfx* func_80095BD0_wide_right(Gfx* displayListHead, u8* arg1, f32 arg2, f32 arg3, u32 arg4, u32 arg5, f32 arg6,
f32 arg7) {
Vtx* var_a1;
// A match is a match, but why are goto's required here?
if (gMatrixEffectCount >= 0x2F7) {
- goto func_80095BD0_label1;
+ rmonPrintf("func_80095BD0_wide_right: MAX effectcount(760) over!!!!(kawano)\n");
+ return displayListHead;
}
if (gMatrixEffectCount < 0) {
- rmonPrintf("effectcount < 0 !!!!!!(kawano)\n");
+ rmonPrintf("func_80095BD0_wide_right: effectcount < 0 !!!!!!(kawano)\n");
}
- goto func_80095BD0_label2;
-func_80095BD0_label1:
- rmonPrintf("MAX effectcount(760) over!!!!(kawano)\n");
- return displayListHead;
-func_80095BD0_label2:
- func_80095AE0(&gGfxPool->mtxEffect[gMatrixEffectCount], OTRGetDimensionFromRightEdge(arg2), arg3, arg6, arg7);
- gSPMatrix(displayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]),
- G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ FrameInterpolation_RecordOpenChild("flashing_text_wide_right", TAG_LETTER((uintptr_t)&arg1 << 8) + (arg4 + arg5));
+ Mat4 mf;
+ SetTextMatrix(mf, OTRGetDimensionFromRightEdge(arg2), arg3, arg6, arg7);
+ //func_80095AE0(&gGfxPool->mtxEffect[gMatrixEffectCount], OTRGetDimensionFromRightEdge(arg2), arg3, arg6, arg7);
+
+ displayListHead = AddTextMatrix(displayListHead, mf);
+ // gSPMatrix(displayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]),
+ // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gMKLoadTextureTile_4b(displayListHead++, arg1, G_IM_FMT_I, arg4, 0, 0, 0, arg4, arg5, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
switch (arg4) {
@@ -2774,7 +2783,9 @@ func_80095BD0_label2:
break;
}
- return func_800959F8(displayListHead, var_a1);
+ displayListHead = func_800959F8(displayListHead, var_a1);
+ FrameInterpolation_RecordCloseChild();
+ return displayListHead;
}
// Player select menu character border
@@ -8333,6 +8344,7 @@ void pause_menu_item_box_cursor(MenuItem* arg0, Unk_D_800E70A0* arg1) {
static float x2, y2, z2;
static float x1, y1, z1;
+ FrameInterpolation_RecordOpenChild("pause_menu_item_box", TAG_OBJECT(arg0));
mtx = GetEffectMatrix();
mtx2 = GetEffectMatrix();
if (arg0->paramf > 1.5) {
@@ -8370,6 +8382,7 @@ void pause_menu_item_box_cursor(MenuItem* arg0, Unk_D_800E70A0* arg1) {
gDPNoOp(gDisplayListHead++);
gDPSetRenderMode(gDisplayListHead++, G_RM_CLD_SURF, G_RM_CLD_SURF2);
gSPDisplayList(gDisplayListHead++, D_0D003090);
+ FrameInterpolation_RecordCloseChild();
}
void func_800A69C8(UNUSED MenuItem* arg0) {
diff --git a/src/menus.c b/src/menus.c
index ce9f0a643..edc56494f 100644
--- a/src/menus.c
+++ b/src/menus.c
@@ -2010,6 +2010,7 @@ void load_menu_states(s32 menuSelection) {
} else {
if (GetCup() == GetBattleCup()) {
CM_SetCup(GetMushroomCup());
+ CM_SetCupIndex(MUSHROOM_CUP);
// gCupSelection = MUSHROOM_CUP;
}
gSubMenuSelection = SUB_MENU_MAP_SELECT_CUP;
diff --git a/src/os/guMtxCatL.c b/src/os/guMtxCatL.c
index cef956954..1ca1b5a28 100644
--- a/src/os/guMtxCatL.c
+++ b/src/os/guMtxCatL.c
@@ -31,6 +31,7 @@
*/
#include <libultraship.h>
+#include "port/interpolation/FrameInterpolation.h"
// void guMtxXFMF(Mtx*, float, float, float, float*, float*, float*);
void guMtxCatF(float mf[4][4], float nf[4][4], float res[4][4]);
@@ -43,6 +44,7 @@ void guMtxCatL(Mtx* m, Mtx* n, Mtx* res) {
guMtxCatF(mf, nf, resf);
+ FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)resf, res);
guMtxF2L(resf, res);
}
diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp
index 836e6c70c..438c10c0a 100644
--- a/src/port/interpolation/FrameInterpolation.cpp
+++ b/src/port/interpolation/FrameInterpolation.cpp
@@ -7,6 +7,7 @@
#include "port/Engine.h"
#include "FrameInterpolation.h"
#include "matrix.h"
+#include "engine/Matrix.h"
extern "C" {
#include "math_util.h"
@@ -81,7 +82,9 @@ enum class Op {
SkinMatrixMtxFToMtx,
SetTransformMatrix,
SetMatrixTransformation,
- SetTranslateRotate
+ SetTranslateRotate,
+ SetTextMatrix,
+ SetMatrixPosRotScaleXY,
};
typedef pair<const void*, uintptr_t> label;
@@ -140,12 +143,21 @@ union Data {
} matrix_mult_4x4;
struct {
+ Mat4* matrix;
Vec3fInterp pos;
Vec3sInterp orientation;
} matrix_pos_rot_xyz;
struct {
Mat4* matrix;
+ s32 x;
+ s32 y;
+ u16 angle;
+ f32 scale;
+ } matrix_pos_rot_scale_xy;
+
+ struct {
+ Mat4* matrix;
Vec3f translation;
Vec3s rotation;
} matrix_translate_rotate_zyx;
@@ -209,6 +221,14 @@ union Data {
} set_orientation_matrix_data;
struct {
+ Mat4* matrix;
+ f32 x;
+ f32 y;
+ f32 arg3;
+ f32 arg4;
+ } matrix_text;
+
+ struct {
label key;
size_t idx;
} open_child;
@@ -254,6 +274,7 @@ struct InterpolateCtx {
Mat3 tmp_mat3;
Vec3f tmp_vec3f, tmp_vec3f2;
Vec3s tmp_vec3s;
+ int32_t tmp32[2];
MtxF actor_mtx;
MtxF* new_replacement(Mtx* addr) {
@@ -276,6 +297,10 @@ struct InterpolateCtx {
return w * o + step * n;
}
+ s32 lerp_s32(s32 o, s32 n) {
+ 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]);
@@ -400,7 +425,6 @@ struct InterpolateCtx {
break;
case Op::MatrixTranslate:
-
Vec3f temp;
temp[0] = lerp(old_op.matrix_translate.b.x, new_op.matrix_translate.b.x);
@@ -533,6 +557,27 @@ struct InterpolateCtx {
mtxf_translate_rotate(*gInterpolationMatrix, tmp_vec3f, tmp_vec3s);
break;
}
+ case Op::SetTextMatrix: {
+
+ tmp_vec3f[0] = lerp(old_op.matrix_text.x, new_op.matrix_text.x);
+ tmp_vec3f[1] = lerp(old_op.matrix_text.y, new_op.matrix_text.y);
+ tmp_vec3f[2] = lerp(old_op.matrix_text.arg3, new_op.matrix_text.arg3);
+ tmp_vec3f2[0] = lerp(old_op.matrix_text.arg4, new_op.matrix_text.arg4);
+
+ SetTextMatrix(*gInterpolationMatrix, tmp_vec3f[0], tmp_vec3f[1], tmp_vec3f[2], tmp_vec3f2[0]);
+ break;
+ }
+ case Op::SetMatrixPosRotScaleXY: {
+ tmp32[0] = lerp_s32(old_op.matrix_pos_rot_scale_xy.x, new_op.matrix_pos_rot_scale_xy.x);
+ tmp32[1] = lerp_s32(old_op.matrix_pos_rot_scale_xy.y, new_op.matrix_pos_rot_scale_xy.y);
+
+ tmp_vec3s[0] = lerp_s16(old_op.matrix_pos_rot_scale_xy.angle, new_op.matrix_pos_rot_scale_xy.angle);
+
+ tmp_vec3f[0] = lerp(old_op.matrix_pos_rot_scale_xy.scale, new_op.matrix_pos_rot_scale_xy.scale);
+
+ mtxf_translation_x_y_rotate_z_scale_x_y(*gInterpolationMatrix, tmp32[0], tmp32[1], tmp_vec3s[0], tmp_vec3f[0]);
+ break;
+ }
}
}
}
@@ -605,6 +650,12 @@ int FrameInterpolation_GetCameraEpoch(void) {
return (int) camera_epoch;
}
+void FrameInterpolation_Record_SetTextMatrix(Mat4* matrix, f32 x, f32 y, f32 arg3, f32 arg4) {
+ if (!is_recording)
+ return;
+ append(Op::SetTextMatrix).matrix_text = {matrix, x, y, arg3, arg4};
+}
+
void FrameInterpolation_RecordActorPosRotMatrix(void) {
if (!is_recording)
return;
@@ -689,10 +740,16 @@ void FrameInterpolation_RecordCalculateOrientationMatrix(Mat3* dest, f32 x, f32
// Make a template for deref
-void FrameInterpolation_RecordMatrixPosRotXYZ(Mat4 out, Vec3f pos, Vec3s orientation) {
+void FrameInterpolation_RecordMatrixPosRotXYZ(Mat4* out, Vec3f pos, Vec3s orientation) {
+ if (!is_recording)
+ return;
+ append(Op::MatrixPosRotXYZ).matrix_pos_rot_xyz = { out, *((Vec3fInterp*) &pos), *((Vec3sInterp*) &orientation) };
+}
+
+void FrameInterpolation_RecordMatrixPosRotScaleXY(Mat4* matrix, s32 x, s32 y, u16 angle, f32 scale) {
if (!is_recording)
return;
- append(Op::MatrixPosRotXYZ).matrix_pos_rot_xyz = { *((Vec3fInterp*) &pos), *((Vec3sInterp*) &orientation) };
+ append(Op::SetMatrixPosRotScaleXY).matrix_pos_rot_scale_xy = { matrix, x, y, angle, scale };
}
void FrameInterpolation_RecordMatrixMultVec3f(Mat4* matrix, Vec3f src, Vec3f dest) {
diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h
index c59743681..30187c808 100644
--- a/src/port/interpolation/FrameInterpolation.h
+++ b/src/port/interpolation/FrameInterpolation.h
@@ -18,7 +18,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_LETTER(x) ((u32)0x30000000 | (u32) (uintptr_t) (x))
#define TAG_OBJECT(x) ((u32)0x40000000 | (u32) (uintptr_t) (x))
void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate);
@@ -39,7 +39,11 @@ int FrameInterpolation_GetCameraEpoch(void);
void FrameInterpolation_RecordActorPosRotMatrix(void);
-void FrameInterpolation_RecordMatrixPosRotXYZ(Mat4 out, Vec3f pos, Vec3s orientation);
+void FrameInterpolation_RecordMatrixPosRotXYZ(Mat4* out, Vec3f pos, Vec3s orientation);
+
+void FrameInterpolation_RecordMatrixPosRotScaleXY(Mat4* matrix, s32 x, s32 y, u16 angle, f32 scale);
+
+void FrameInterpolation_Record_SetTextMatrix(Mat4* matrix, f32 x, f32 y, f32 arg3, f32 arg4);
void FrameInterpolation_RecordMatrixPush(Mat4* matrix);
diff --git a/src/racing/actors.c b/src/racing/actors.c
index 137e3556e..0d6bd0ee4 100644
--- a/src/racing/actors.c
+++ b/src/racing/actors.c
@@ -2429,8 +2429,17 @@ void render_course_actors(struct UnkStruct_800DC5EC* arg0) {
struct Actor* actor;
UNUSED Vec3f sp4C = { 0.0f, 5.0f, 10.0f };
- f32 sp48 = sins(camera->rot[1] - 0x8000); // unk26;
- f32 temp_f0 = coss(camera->rot[1] - 0x8000);
+
+ // Freecam rotY is reversed in the engine for whatever reason
+ f32 sp48 = 0;
+ f32 temp_f0 = 0;
+ if (CVarGetInteger("gFreecam", 0) == true) {
+ sp48 = sins(-camera->rot[1] - 0x8000);
+ temp_f0 = coss(-camera->rot[1] - 0x8000);
+ } else {
+ sp48 = sins(camera->rot[1] - 0x8000);
+ temp_f0 = coss(camera->rot[1] - 0x8000);
+ }
sBillBoardMtx[0][0] = temp_f0;
sBillBoardMtx[0][2] = -sp48;
diff --git a/src/render_objects.c b/src/render_objects.c
index 7aa06dcaf..e0097750e 100644
--- a/src/render_objects.c
+++ b/src/render_objects.c
@@ -3527,7 +3527,11 @@ 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];
+ FrameInterpolation_RecordOpenChild("stars_cloud", TAG_OBJECT(object));
+
func_800519D4(objectIndex, object->unk_09C, arg0 - object->unk_09E);
+ FrameInterpolation_RecordCloseChild();
+
}
} else {
func_8004B6C4(255, 255, 255);