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
This commit is contained in:
MegaMech
2025-06-15 22:17:24 -06:00
committed by GitHub
parent 547d651cc4
commit 9fe391a2a4
11 changed files with 135 additions and 33 deletions
+18 -8
View File
@@ -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);
}
return 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 displayListHead;
}
void ApplyMatrixTransformations(Mat4 mtx, FVector pos, IRotator rot, FVector scale) {
+2 -1
View File
@@ -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);
+1 -1
View File
@@ -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) {
+1
View File
@@ -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;
+28 -15
View File
@@ -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) {
+1
View File
@@ -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;
+2
View File
@@ -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);
}
+61 -4
View File
@@ -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,10 +143,19 @@ 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;
@@ -208,6 +220,14 @@ union Data {
s16 rot;
} set_orientation_matrix_data;
struct {
Mat4* matrix;
f32 x;
f32 y;
f32 arg3;
f32 arg4;
} matrix_text;
struct {
label key;
size_t idx;
@@ -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 = { *((Vec3fInterp*) &pos), *((Vec3sInterp*) &orientation) };
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::SetMatrixPosRotScaleXY).matrix_pos_rot_scale_xy = { matrix, x, y, angle, scale };
}
void FrameInterpolation_RecordMatrixMultVec3f(Mat4* matrix, Vec3f src, Vec3f dest) {
+6 -2
View File
@@ -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);
+11 -2
View File
@@ -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;
+4
View File
@@ -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);