diff options
| author | Eblo <7004497+Eblo@users.noreply.github.com> | 2026-01-20 20:27:47 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-20 20:27:47 -0500 |
| commit | a4360a25cd3dfec3653890f86b812facfa6ddee3 (patch) | |
| tree | 5298f3ff34f80a3798caf7f16755ea4604ffd2b8 /mm/src/code | |
| parent | d7bd6f9c7df615cd1b41a5b482e2589a6a03cca0 (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.c | 14 | ||||
| -rw-r--r-- | mm/src/code/z_actor.c | 13 | ||||
| -rw-r--r-- | mm/src/code/z_draw.c | 34 | ||||
| -rw-r--r-- | mm/src/code/z_fireobj.c | 3 | ||||
| -rw-r--r-- | mm/src/code/z_kankyo.c | 5 | ||||
| -rw-r--r-- | mm/src/code/z_rcp.c | 82 | ||||
| -rw-r--r-- | mm/src/code/z_scene_proc.c | 7 |
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)); } /** |
