summaryrefslogtreecommitdiff
path: root/mm/src/code
diff options
context:
space:
mode:
authorEblo <7004497+Eblo@users.noreply.github.com>2026-01-20 20:27:47 -0500
committerGitHub <noreply@github.com>2026-01-20 20:27:47 -0500
commita4360a25cd3dfec3653890f86b812facfa6ddee3 (patch)
tree5298f3ff34f80a3798caf7f16755ea4604ffd2b8 /mm/src/code
parentd7bd6f9c7df615cd1b41a5b482e2589a6a03cca0 (diff)
Texture scrolling interpolation, Take 2 (#1332)
* Scrolling texture interpolation Co-authored-by: Nicholas Estelami <NEstelami@users.noreply.github.com> * Interpolate remaining GIs * Clean up gDPSetTileSizeInterp --------- Co-authored-by: Nicholas Estelami <NEstelami@users.noreply.github.com>
Diffstat (limited to 'mm/src/code')
-rw-r--r--mm/src/code/stubs.c14
-rw-r--r--mm/src/code/z_actor.c13
-rw-r--r--mm/src/code/z_draw.c34
-rw-r--r--mm/src/code/z_fireobj.c3
-rw-r--r--mm/src/code/z_kankyo.c5
-rw-r--r--mm/src/code/z_rcp.c82
-rw-r--r--mm/src/code/z_scene_proc.c7
7 files changed, 117 insertions, 41 deletions
diff --git a/mm/src/code/stubs.c b/mm/src/code/stubs.c
index 9073dc1e5..9e34b8040 100644
--- a/mm/src/code/stubs.c
+++ b/mm/src/code/stubs.c
@@ -200,6 +200,20 @@ void gSPDisplayList(Gfx* pkt, Gfx* dl) {
__gSPDisplayList(pkt, dl);
}
+void gDPSetTileSizeInterp(Gfx* pkt, int t, float uls, float ult, float lrs, float lrt) {
+ __gDPSetTileSizeInterp(pkt, t, 0, 0, 0, 0);
+ pkt->words.w0 = _SHIFTL(G_SETTILESIZE_INTERP, 24, 8);
+ pkt++;
+
+ pkt->words.w0 = *(u32*)&uls;
+ pkt->words.w1 = *(u32*)&ult;
+ pkt++;
+
+ pkt->words.w0 = *(u32*)&lrs;
+ pkt->words.w1 = *(u32*)&lrt;
+ pkt++;
+}
+
void gSPDisplayListOffset(Gfx* pkt, Gfx* dl, int offset) {
char* imgData = (char*)dl;
diff --git a/mm/src/code/z_actor.c b/mm/src/code/z_actor.c
index 03148315c..37e1ad76a 100644
--- a/mm/src/code/z_actor.c
+++ b/mm/src/code/z_actor.c
@@ -5394,8 +5394,8 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[]
// Setup to draw ice over frozen actor
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, gameplayFrames & 0xFF, 32, 16, 1, 0,
- (gameplayFrames * 2) & 0xFF, 64, 32));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0, gameplayFrames & 0xFF, 32, 16, 1, 0,
+ (gameplayFrames * 2) & 0xFF, 64, 32, 0, 1, 0, 2));
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 170, 255, 255, 255);
gSPDisplayList(POLY_XLU_DISP++, gEffIceFragment2MaterialDL);
@@ -5452,8 +5452,8 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[]
FrameInterpolation_RecordOpenChild(bodyPartsPos, type);
twoTexScrollParam = ((bodyPartIndex * 3) + gameplayFrames);
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, twoTexScrollParam * 3, twoTexScrollParam * -12,
- 32, 64, 1, 0, 0, 32, 32));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, twoTexScrollParam * 3, twoTexScrollParam * -12,
+ 32, 64, 1, 0, 0, 32, 32, 3, -12, 0, 0));
Matrix_Translate(bodyPartsPos->x, bodyPartsPos->y, bodyPartsPos->z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
@@ -5500,8 +5500,9 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[]
gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, type, (u8)alpha);
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0,
- ((bodyPartIndex * 10 + gameplayFrames) * -20) & 0x1FF, 32, 128));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0,
+ ((bodyPartIndex * 10 + gameplayFrames) * -20) & 0x1FF, 32, 128, 0, 0,
+ 0, -20));
Matrix_RotateYF(M_PIf, MTXMODE_APPLY);
currentMatrix->mf[3][0] = bodyPartsPos->x;
diff --git a/mm/src/code/z_draw.c b/mm/src/code/z_draw.c
index 0624d2dd7..64f9f4551 100644
--- a/mm/src/code/z_draw.c
+++ b/mm/src/code/z_draw.c
@@ -412,8 +412,8 @@ void GetItem_DrawPoes(PlayState* play, s16 drawId) {
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].drawResources[1]);
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 0, play->state.frames * 0, 16,
- 32, 1, play->state.frames, -(play->state.frames * 6), 16, 32));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 0, play->state.frames * 0,
+ 16, 32, 1, play->state.frames, -(play->state.frames * 6), 16, 32, 0, 0, 1, -6));
Matrix_Push();
Matrix_ReplaceRotation(&play->billboardMtxF);
@@ -442,8 +442,8 @@ void GetItem_DrawFairyBottle(PlayState* play, s16 drawId) {
MATRIX_FINALIZE_AND_LOAD(POLY_XLU_DISP++, play->state.gfxCtx);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].drawResources[1]);
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 0, play->state.frames * 0, 32,
- 32, 1, play->state.frames, -(play->state.frames * 6), 32, 32));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 0, play->state.frames * 0,
+ 32, 32, 1, play->state.frames, -(play->state.frames * 6), 32, 320, 0, 0, 1, -6));
Matrix_Push();
Matrix_ReplaceRotation(&play->billboardMtxF);
@@ -469,8 +469,9 @@ void GetItem_DrawSkullToken(PlayState* play, s16 drawId) {
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 0, -(play->state.frames * 5),
- 32, 32, 1, play->state.frames * 0, play->state.frames * 0, 32, 64));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 0,
+ -(play->state.frames * 5), 32, 32, 1, play->state.frames * 0, play->state.frames * 0,
+ 32, 64, 0, -5, 0, 0));
MATRIX_FINALIZE_AND_LOAD(POLY_XLU_DISP++, play->state.gfxCtx);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].drawResources[1]);
@@ -503,8 +504,8 @@ void GetItem_DrawPotion(PlayState* play, s16 drawId) {
Gfx_SetupDL25_Opa(play->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, -play->state.frames, play->state.frames, 32, 32, 1,
- -play->state.frames, play->state.frames, 32, 32));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, G_TX_RENDERTILE, -play->state.frames, play->state.frames, 32, 32,
+ 1, -play->state.frames, play->state.frames, 32, 32, -1, 1, -1, 1));
MATRIX_FINALIZE_AND_LOAD(POLY_OPA_DISP++, play->state.gfxCtx);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].drawResources[1]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].drawResources[0]);
@@ -528,8 +529,8 @@ void GetItem_DrawGoronSword(PlayState* play, s16 drawId) {
Gfx_SetupDL25_Opa(play->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 1, play->state.frames * 0, 32,
- 32, 1, play->state.frames * 0, play->state.frames * 0, 32, 32));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 1, play->state.frames * 0,
+ 32, 32, 1, play->state.frames * 0, play->state.frames * 0, 32, 32, 1, 0, 0, 0));
MATRIX_FINALIZE_AND_LOAD(POLY_OPA_DISP++, play->state.gfxCtx);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].drawResources[0]);
@@ -544,8 +545,8 @@ void GetItem_DrawDekuNuts(PlayState* play, s16 drawId) {
Gfx_SetupDL25_Opa(play->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 6, play->state.frames * 6, 32,
- 32, 1, play->state.frames * 6, play->state.frames * 6, 32, 32));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 6, play->state.frames * 6,
+ 32, 32, 1, play->state.frames * 6, play->state.frames * 6, 32, 32, 6, 6, 6, 6));
MATRIX_FINALIZE_AND_LOAD(POLY_OPA_DISP++, play->state.gfxCtx);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].drawResources[0]);
@@ -560,8 +561,9 @@ void GetItem_DrawRecoveryHeart(PlayState* play, s16 drawId) {
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 0, -(play->state.frames * 3),
- 32, 32, 1, play->state.frames * 0, -(play->state.frames * 2), 32, 32));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 0,
+ -(play->state.frames * 3), 32, 32, 1, play->state.frames * 0,
+ -(play->state.frames * 2), 32, 32, 0, -3, 0, -2));
MATRIX_FINALIZE_AND_LOAD(POLY_XLU_DISP++, play->state.gfxCtx);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].drawResources[0]);
@@ -576,8 +578,8 @@ void GetItem_DrawFish(PlayState* play, s16 drawId) {
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 0, play->state.frames * 1, 32,
- 32, 1, play->state.frames * 0, play->state.frames * 1, 32, 32));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, G_TX_RENDERTILE, play->state.frames * 0, play->state.frames * 1,
+ 32, 32, 1, play->state.frames * 0, play->state.frames * 1, 32, 32, 0, 1, 0, 1));
MATRIX_FINALIZE_AND_LOAD(POLY_XLU_DISP++, play->state.gfxCtx);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].drawResources[0]);
diff --git a/mm/src/code/z_fireobj.c b/mm/src/code/z_fireobj.c
index 169619b55..dfa52bc87 100644
--- a/mm/src/code/z_fireobj.c
+++ b/mm/src/code/z_fireobj.c
@@ -144,7 +144,8 @@ void FireObj_Draw(PlayState* play, FireObj* fire) {
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, (fire->timer * -20) % 512U, 32, 128));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, (fire->timer * -20) % 512U, 32, 128, 0,
+ 0, 0, -20));
gDPSetPrimColor(POLY_XLU_DISP++, 0, fireColors->lod, fireColors->primColor.r, fireColors->primColor.g,
fireColors->primColor.b, fireColors->primColor.a);
diff --git a/mm/src/code/z_kankyo.c b/mm/src/code/z_kankyo.c
index 87129d15b..77da3e4e7 100644
--- a/mm/src/code/z_kankyo.c
+++ b/mm/src/code/z_kankyo.c
@@ -2967,8 +2967,9 @@ void Environment_DrawSandstorm(PlayState* play, u8 sandstormState) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, primColor.r, primColor.g, primColor.b, play->envCtx.sandstormPrimA);
gDPSetEnvColor(POLY_XLU_DISP++, envColor.r, envColor.g, envColor.b, play->envCtx.sandstormEnvA);
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, (u32)sp96 % 4096, 0, 512, 32, 1,
- (u32)sp94 % 4096, 4095 - ((u32)sp92 % 4096), 256, 64));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, G_TX_RENDERTILE, (u32)sp96 % 4096, 0, 512, 32, 1,
+ (u32)sp94 % 4096, 4095 - ((u32)sp92 % 4096), 256, 64, sp98, 0, sp98 * 1.5f,
+ -sp98));
gDPSetTextureLUT(POLY_XLU_DISP++, G_TT_NONE);
// #region 2S2H [Widescreen] Widescreen Sandstorm
// gSPDisplayList(POLY_XLU_DISP++, gFieldSandstormDL); // Original Dlist call
diff --git a/mm/src/code/z_rcp.c b/mm/src/code/z_rcp.c
index c099e1d1c..27cf58e6a 100644
--- a/mm/src/code/z_rcp.c
+++ b/mm/src/code/z_rcp.c
@@ -1376,37 +1376,93 @@ Gfx* func_8012CB28(GraphicsContext* gfxCtx, u32 x, u32 y) {
return Gfx_TexScroll(gfxCtx, x, y, 0, 0);
}
-Gfx* Gfx_TexScroll(GraphicsContext* gfxCtx, u32 x, u32 y, s32 width, s32 height) {
- Gfx* gfx = GRAPH_ALLOC(gfxCtx, 3 * sizeof(Gfx));
+Gfx* Gfx_TexScrollEx(GraphicsContext* gfxCtx, u32 x, u32 y, s32 width, s32 height, s32 xStep, s32 yStep) {
+ int interpFrames = Ship_GetInterpolationFrameCount();
+
+ Gfx* gfx = GRAPH_ALLOC(gfxCtx, (2 + (interpFrames * 4)) * sizeof(Gfx));
x %= 2048;
y %= 2048;
- gDPTileSync(&gfx[0]);
- gDPSetTileSize(&gfx[1], 0, x, y, (x + ((width - 1) << 2)), (y + ((height - 1) << 2)));
- gSPEndDisplayList(&gfx[2]);
+ float xFlt = (float)x;
+ float yFlt = (float)y;
+
+ float xInc = (float)xStep / (float)interpFrames;
+ float yInc = (float)yStep / (float)interpFrames;
+
+ int idx = 0;
+
+ gDPTileSync(&gfx[idx++]);
+
+ for (int i = 0; i < interpFrames; i++) {
+ gDPSetInterpolation(&gfx[idx++], i);
+ gDPSetTileSizeInterp(&gfx[idx], 0, xFlt, yFlt, (xFlt + ((width - 1) << 2)), (yFlt + ((height - 1) << 2)));
+ idx += 3;
+
+ xFlt += xInc;
+ yFlt += yInc;
+ }
+
+ gSPEndDisplayList(&gfx[idx++]);
return gfx;
}
-Gfx* Gfx_TwoTexScroll(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1, s32 width1, s32 height1, s32 tile2, u32 x2,
- u32 y2, s32 width2, s32 height2) {
- Gfx* gfx = GRAPH_ALLOC(gfxCtx, 5 * sizeof(Gfx));
+Gfx* Gfx_TexScroll(GraphicsContext* gfxCtx, u32 x, u32 y, s32 width, s32 height) {
+ Gfx_TexScrollEx(gfxCtx, x, y, width, height, 0, 0);
+}
+
+Gfx* Gfx_TwoTexScrollEx(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1, s32 width1, s32 height1, s32 tile2, u32 x2,
+ u32 y2, s32 width2, s32 height2, s32 xStep1, s32 yStep1, s32 xStep2, s32 yStep2) {
+ int interpFrames = Ship_GetInterpolationFrameCount();
+
+ Gfx* gfx = GRAPH_ALLOC(gfxCtx, (5 + (interpFrames * 7)) * sizeof(Gfx));
x1 %= 2048;
y1 %= 2048;
x2 %= 2048;
y2 %= 2048;
- gDPTileSync(&gfx[0]);
- gDPSetTileSize(&gfx[1], tile1, x1, y1, (x1 + ((width1 - 1) << 2)), (y1 + ((height1 - 1) << 2)));
- gDPTileSync(&gfx[2]);
- gDPSetTileSize(&gfx[3], tile2, x2, y2, (x2 + ((width2 - 1) << 2)), (y2 + ((height2 - 1) << 2)));
- gSPEndDisplayList(&gfx[4]);
+ float x1Flt = (float)x1;
+ float y1Flt = (float)y1;
+ float x2Flt = (float)x2;
+ float y2Flt = (float)y2;
+
+ int index = 0;
+
+ gDPTileSync(&gfx[index++]);
+
+ float xInc1 = (float)xStep1 / (float)interpFrames;
+ float yInc1 = (float)yStep1 / (float)interpFrames;
+
+ float xInc2 = (float)xStep2 / (float)interpFrames;
+ float yInc2 = (float)yStep2 / (float)interpFrames;
+
+ for (int i = 0; i < interpFrames; i++) {
+ gDPSetInterpolation(&gfx[index++], i);
+
+ gDPSetTileSizeInterp(&gfx[index], tile1, x1Flt, y1Flt, (x1Flt + ((width1 - 1) << 2)),
+ (y1Flt + ((height1 - 1) << 2)));
+ index += 3;
+ gDPSetTileSizeInterp(&gfx[index], tile2, x2Flt, y2Flt, (x2Flt + ((width2 - 1) << 2)),
+ (y2Flt + ((height2 - 1) << 2)));
+ index += 3;
+
+ x1Flt += xInc1;
+ x2Flt += xInc2;
+ y1Flt += yInc1;
+ y2Flt += yInc2;
+ }
+ gSPEndDisplayList(&gfx[index]);
return gfx;
}
+Gfx* Gfx_TwoTexScroll(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1, s32 width1, s32 height1, s32 tile2, u32 x2,
+ u32 y2, s32 width2, s32 height2) {
+ Gfx_TwoTexScrollEx(gfxCtx, tile1, x1, y1, width1, height1, tile2, x2, y2, width2, height2, 0, 0, 0, 0);
+}
+
Gfx* Gfx_TwoTexScrollEnvColor(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1, s32 width1, s32 height1, s32 tile2,
u32 x2, u32 y2, s32 width2, s32 height2, s32 r, s32 g, s32 b, s32 a) {
Gfx* gfx = GRAPH_ALLOC(gfxCtx, 6 * sizeof(Gfx));
diff --git a/mm/src/code/z_scene_proc.c b/mm/src/code/z_scene_proc.c
index ab21c94ff..1abaaa381 100644
--- a/mm/src/code/z_scene_proc.c
+++ b/mm/src/code/z_scene_proc.c
@@ -86,9 +86,10 @@ void AnimatedMat_DrawTexScroll(PlayState* play, s32 segment, void* params) {
* Returns a pointer to a two layer texture scroll displaylist.
*/
Gfx* AnimatedMat_TwoLayerTexScroll(PlayState* play, AnimatedMatTexScrollParams* params) {
- return Gfx_TwoTexScroll(play->state.gfxCtx, 0, params[0].xStep * sMatAnimStep, -(params[0].yStep * sMatAnimStep),
- params[0].width, params[0].height, 1, params[1].xStep * sMatAnimStep,
- -(params[1].yStep * sMatAnimStep), params[1].width, params[1].height);
+ return Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, params[0].xStep * sMatAnimStep, -(params[0].yStep * sMatAnimStep),
+ params[0].width, params[0].height, 1, params[1].xStep * sMatAnimStep,
+ -(params[1].yStep * sMatAnimStep), params[1].width, params[1].height, params[0].xStep,
+ -(params[0].yStep), params[1].xStep, -(params[1].yStep));
}
/**