summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Dubé <159546+serprex@users.noreply.github.com>2026-07-25 14:32:50 +0000
committerGitHub <noreply@github.com>2026-07-25 10:32:50 -0400
commitf11371f75e3a2f252a14d253311bd291b2110863 (patch)
tree49c8f192b278a14a6ddd83316070552eed44976a
parentc03a59dae6cded706dfe51c78dd62fd5c76ec93c (diff)
Port LERP interpolation improvements from ship (#1812)
m---------libultraship0
-rw-r--r--mm/2s2h/BenPort.cpp33
-rw-r--r--mm/2s2h/BenPort.h1
-rw-r--r--mm/include/gfx.h5
-rw-r--r--mm/src/code/stubs.c5
-rw-r--r--mm/src/code/z_rcp.c99
-rw-r--r--mm/src/code/z_scene_proc.c4
-rw-r--r--mm/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c8
-rw-r--r--mm/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c2
-rw-r--r--mm/src/overlays/actors/ovl_En_Stream/z_en_stream.c4
-rw-r--r--mm/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c4
-rw-r--r--mm/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c2
-rw-r--r--mm/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c4
-rw-r--r--mm/src/overlays/actors/ovl_Obj_Toudai/z_obj_toudai.c2
-rw-r--r--mm/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.c6
-rw-r--r--mm/src/overlays/effects/ovl_Effect_Ss_Ice_Smoke/z_eff_ss_ice_smoke.c2
16 files changed, 89 insertions, 92 deletions
diff --git a/libultraship b/libultraship
-Subproject 621f09baac0753e422c2e5d6cb27fdf4d979025
+Subproject 0eae41abee09eae82195c035cdff46667e5c62c
diff --git a/mm/2s2h/BenPort.cpp b/mm/2s2h/BenPort.cpp
index faaaa1006..4e611479d 100644
--- a/mm/2s2h/BenPort.cpp
+++ b/mm/2s2h/BenPort.cpp
@@ -734,11 +734,6 @@ extern "C" uint32_t Ship_GetInterpolationFPS() {
return OTRGlobals::Instance->GetInterpolationFPS();
}
-// Number of interpolated frames
-extern "C" uint32_t Ship_GetInterpolationFrameCount() {
- return ceil((float)Ship_GetInterpolationFPS() / 20.0f);
-}
-
struct ExtensionEntry {
std::string path;
std::string ext;
@@ -1160,7 +1155,8 @@ extern "C" void Graph_StartFrame() {
#endif
}
-void RunCommands(Gfx* Commands, const std::vector<std::unordered_map<Mtx*, MtxF>>& mtx_replacements) {
+// Interpolated frames of a tick are evenly spaced numerators time+step, time+2*step, ... over denom.
+void RunCommands(Gfx* Commands, int time, int step, int denom, int count) {
auto wnd = std::dynamic_pointer_cast<Fast::Fast3dWindow>(OTRGlobals::Instance->context->GetWindow());
if (wnd == nullptr) {
@@ -1176,8 +1172,12 @@ void RunCommands(Gfx* Commands, const std::vector<std::unordered_map<Mtx*, MtxF>
UIWidgets::Colors themeColor =
static_cast<UIWidgets::Colors>(CVarGetInteger("gSettings.Menu.Theme", UIWidgets::Colors::LightBlue));
ImGui::PushStyleColor(ImGuiCol_TitleBgActive, UIWidgets::ColorValues.at(themeColor));
- for (const auto& m : mtx_replacements) {
- wnd->DrawAndRunGraphicsCommands(Commands, m);
+ for (int i = 0; i < count; i++) {
+ time += step;
+ std::unordered_map<Mtx*, MtxF> mtx_replacements =
+ (time == denom) ? std::unordered_map<Mtx*, MtxF>() : FrameInterpolation_Interpolate((float)time / denom);
+ intp->mInterpolationT = (float)time / denom;
+ wnd->DrawAndRunGraphicsCommands(Commands, mtx_replacements);
intp->mInterpolationIndex++;
}
ImGui::PopStyleColor();
@@ -1191,7 +1191,6 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
}
audio.cv_to_thread.notify_one();
- std::vector<std::unordered_map<Mtx*, MtxF>> mtx_replacements;
int target_fps = OTRGlobals::Instance->GetInterpolationFPS();
static int last_fps;
static int last_update_rate;
@@ -1211,13 +1210,11 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
// time_base = fps * original_fps (one second)
int next_original_frame = fps;
+ int start_time = time;
+ int count = 0;
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();
- }
+ count++;
}
time -= fps;
@@ -1226,13 +1223,15 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
wnd->SetTargetFps(fps);
}
+ int step = original_fps;
// When the gfx debugger is active, only run with the final mtx
if (GfxDebuggerIsDebugging()) {
- mtx_replacements.clear();
- mtx_replacements.emplace_back();
+ start_time = next_original_frame;
+ step = 0;
+ count = 1;
}
- RunCommands(commands, mtx_replacements);
+ RunCommands(commands, start_time, step, next_original_frame, count);
last_fps = fps;
last_update_rate = R_UPDATE_RATE;
diff --git a/mm/2s2h/BenPort.h b/mm/2s2h/BenPort.h
index 36f0e04f2..b6acbabca 100644
--- a/mm/2s2h/BenPort.h
+++ b/mm/2s2h/BenPort.h
@@ -168,7 +168,6 @@ void Controller_UnblockGameInput();
void Overlay_DisplayText(float duration, const char* text);
void Overlay_DisplayText_Seconds(int seconds, const char* text);
uint32_t Ship_GetInterpolationFPS();
-uint32_t Ship_GetInterpolationFrameCount();
void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* replacement);
void Gfx_UnregisterBlendedTexture(const char* name);
diff --git a/mm/include/gfx.h b/mm/include/gfx.h
index d7409720f..32e19211e 100644
--- a/mm/include/gfx.h
+++ b/mm/include/gfx.h
@@ -99,6 +99,9 @@ Gfx* Gfx_TwoTexScrollEx(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1, s32
u32 y2, s32 width2, s32 height2, s32 xStep1, s32 yStep1, s32 xStep2, s32 yStep2);
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_TwoTexScrollEnvColorEx(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, s32 xStep1,
+ s32 yStep1, s32 xStep2, s32 yStep2);
Gfx* Gfx_EnvColor(GraphicsContext* gfxCtx, s32 r, s32 g, s32 b, s32 a);
Gfx* Gfx_PrimColor(GraphicsContext* gfxCtx, s32 lodfrac, s32 r, s32 g, s32 b, s32 a);
void func_8012CF0C(GraphicsContext* gfxCtx, s32 clearFb, s32 clearZb, u8 r, u8 g, u8 b);
@@ -110,6 +113,8 @@ void gSPSegmentLoadRes(void* value, int segNum, uintptr_t target);
// void gDPSetTextureImageFB(Gfx* pkt, u32 format, u32 size, u32 width, int fb);
void gSPDisplayList(Gfx* pkt, Gfx* dl);
void gDPSetTileSizeInterp(Gfx* pkt, int t, float uls, float ult, float lrs, float lrt);
+void gDPSetTileSizeLerp(Gfx* pkt, int t, float uls0, float ult0, float lrs0, float lrt0, float uls1, float ult1,
+ float lrs1, float lrt1);
void gSPDisplayListOffset(Gfx* pkt, Gfx* dl, int offset);
void gSPVertex(Gfx* pkt, uintptr_t v, int n, int v0);
void gSPInvalidateTexCache(Gfx* pkt, uintptr_t texAddr);
diff --git a/mm/src/code/stubs.c b/mm/src/code/stubs.c
index 9e34b8040..4425cf74e 100644
--- a/mm/src/code/stubs.c
+++ b/mm/src/code/stubs.c
@@ -214,6 +214,11 @@ void gDPSetTileSizeInterp(Gfx* pkt, int t, float uls, float ult, float lrs, floa
pkt++;
}
+void gDPSetTileSizeLerp(Gfx* pkt, int t, float uls0, float ult0, float lrs0, float lrt0, float uls1, float ult1,
+ float lrs1, float lrt1) {
+ __gDPSetTileSizeLerp(pkt, t, uls0, ult0, lrs0, lrt0, uls1, ult1, lrs1, lrt1);
+}
+
void gSPDisplayListOffset(Gfx* pkt, Gfx* dl, int offset) {
char* imgData = (char*)dl;
diff --git a/mm/src/code/z_rcp.c b/mm/src/code/z_rcp.c
index d53e0d69e..45744fc59 100644
--- a/mm/src/code/z_rcp.c
+++ b/mm/src/code/z_rcp.c
@@ -1377,33 +1377,18 @@ Gfx* func_8012CB28(GraphicsContext* gfxCtx, u32 x, u32 y) {
}
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));
+ Gfx* gfx = GRAPH_ALLOC(gfxCtx, 7 * sizeof(Gfx));
x %= 2048;
y %= 2048;
- 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++]);
+ s32 xEnd = (s32)x + xStep;
+ s32 yEnd = (s32)y + yStep;
- 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++]);
+ gDPTileSync(&gfx[0]);
+ gDPSetTileSizeLerp(&gfx[1], 0, x, y, (x + ((width - 1) << 2)), (y + ((height - 1) << 2)), xEnd, yEnd,
+ (xEnd + ((width - 1) << 2)), (yEnd + ((height - 1) << 2)));
+ gSPEndDisplayList(&gfx[6]);
return gfx;
}
@@ -1423,46 +1408,24 @@ Gfx* Gfx_TexScroll(GraphicsContext* gfxCtx, u32 x, u32 y, s32 width, s32 height)
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));
+ Gfx* gfx = GRAPH_ALLOC(gfxCtx, 12 * sizeof(Gfx));
x1 %= 2048;
y1 %= 2048;
x2 %= 2048;
y2 %= 2048;
- 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;
+ s32 x1End = (s32)x1 + xStep1;
+ s32 y1End = (s32)y1 + yStep1;
+ s32 x2End = (s32)x2 + xStep2;
+ s32 y2End = (s32)y2 + yStep2;
- x1Flt += xInc1;
- x2Flt += xInc2;
- y1Flt += yInc1;
- y2Flt += yInc2;
- }
- gSPEndDisplayList(&gfx[index]);
+ gDPTileSync(&gfx[0]);
+ gDPSetTileSizeLerp(&gfx[1], tile1, x1, y1, (x1 + ((width1 - 1) << 2)), (y1 + ((height1 - 1) << 2)), x1End, y1End,
+ (x1End + ((width1 - 1) << 2)), (y1End + ((height1 - 1) << 2)));
+ gDPSetTileSizeLerp(&gfx[6], tile2, x2, y2, (x2 + ((width2 - 1) << 2)), (y2 + ((height2 - 1) << 2)), x2End, y2End,
+ (x2End + ((width2 - 1) << 2)), (y2End + ((height2 - 1) << 2)));
+ gSPEndDisplayList(&gfx[11]);
return gfx;
}
@@ -1504,6 +1467,32 @@ Gfx* Gfx_TwoTexScrollEnvColor(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1
return gfx;
}
+Gfx* Gfx_TwoTexScrollEnvColorEx(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, s32 xStep1,
+ s32 yStep1, s32 xStep2, s32 yStep2) {
+ Gfx* gfx = GRAPH_ALLOC(gfxCtx, 13 * sizeof(Gfx));
+
+ x1 %= 2048;
+ y1 %= 2048;
+ x2 %= 2048;
+ y2 %= 2048;
+
+ s32 x1End = (s32)x1 + xStep1;
+ s32 y1End = (s32)y1 + yStep1;
+ s32 x2End = (s32)x2 + xStep2;
+ s32 y2End = (s32)y2 + yStep2;
+
+ gDPTileSync(&gfx[0]);
+ gDPSetTileSizeLerp(&gfx[1], tile1, x1, y1, (x1 + ((width1 - 1) << 2)), (y1 + ((height1 - 1) << 2)), x1End, y1End,
+ (x1End + ((width1 - 1) << 2)), (y1End + ((height1 - 1) << 2)));
+ gDPSetTileSizeLerp(&gfx[6], tile2, x2, y2, (x2 + ((width2 - 1) << 2)), (y2 + ((height2 - 1) << 2)), x2End, y2End,
+ (x2End + ((width2 - 1) << 2)), (y2End + ((height2 - 1) << 2)));
+ gDPSetEnvColor(&gfx[11], r, g, b, a);
+ gSPEndDisplayList(&gfx[12]);
+
+ return gfx;
+}
+
Gfx* Gfx_EnvColor(GraphicsContext* gfxCtx, s32 r, s32 g, s32 b, s32 a) {
Gfx* gfx = GRAPH_ALLOC(gfxCtx, 2 * sizeof(Gfx));
diff --git a/mm/src/code/z_scene_proc.c b/mm/src/code/z_scene_proc.c
index 1abaaa381..329574787 100644
--- a/mm/src/code/z_scene_proc.c
+++ b/mm/src/code/z_scene_proc.c
@@ -57,8 +57,8 @@ void Scene_DrawConfigDefault(PlayState* play) {
* Returns a pointer to a single layer texture scroll displaylist.
*/
Gfx* AnimatedMat_TexScroll(PlayState* play, AnimatedMatTexScrollParams* params) {
- return Gfx_TexScroll(play->state.gfxCtx, params->xStep * sMatAnimStep, -(params->yStep * sMatAnimStep),
- params->width, params->height);
+ return Gfx_TexScrollEx(play->state.gfxCtx, params->xStep * sMatAnimStep, -(params->yStep * sMatAnimStep),
+ params->width, params->height, params->xStep, -(params->yStep));
}
/**
diff --git a/mm/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c b/mm/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c
index 9d4ced318..95c5cfb11 100644
--- a/mm/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c
+++ b/mm/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c
@@ -1210,8 +1210,8 @@ void EnFishing_DrawEffects(FishingEffect* effect, PlayState* play) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 40, 90, 80, effect->alpha);
gSPSegment(POLY_OPA_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, effect->timer + (i * 3), (effect->timer + (i * 3)) * 5,
- 32, 64, 1, 0, 0, 32, 32));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, effect->timer + (i * 3), (effect->timer + (i * 3)) * 5,
+ 32, 64, 1, 0, 0, 32, 32, 1, 5, 0, 0));
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
@@ -1346,8 +1346,8 @@ void EnFishing_DrawStreamSplash(PlayState* play) {
OPEN_DISPS(play->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x09,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, play->gameplayFrames * 1, play->gameplayFrames * 8, 32, 64, 1,
- -play->gameplayFrames * 2, 0, 16, 16));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, play->gameplayFrames * 1, play->gameplayFrames * 8, 32, 64, 1,
+ -play->gameplayFrames * 2, 0, 16, 16, 1, 8, -2, 0));
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, 50);
diff --git a/mm/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c b/mm/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c
index f3eb9e06a..29c870fb4 100644
--- a/mm/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c
+++ b/mm/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c
@@ -1755,7 +1755,7 @@ void EnSob1_BombShopkeeper_Draw(Actor* thisx, PlayState* play) {
Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);
MATRIX_FINALIZE_AND_LOAD(POLY_XLU_DISP++, play->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, -frames * 20, 32, 128));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, -frames * 20, 32, 128, 0, 0, 0, -20));
gDPSetPrimColor(POLY_XLU_DISP++, 128, 128, 255, 255, 0, 255);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0);
diff --git a/mm/src/overlays/actors/ovl_En_Stream/z_en_stream.c b/mm/src/overlays/actors/ovl_En_Stream/z_en_stream.c
index b71f86a4a..24669bb2f 100644
--- a/mm/src/overlays/actors/ovl_En_Stream/z_en_stream.c
+++ b/mm/src/overlays/actors/ovl_En_Stream/z_en_stream.c
@@ -140,8 +140,8 @@ void EnStream_Draw(Actor* thisx, PlayState* play) {
MATRIX_FINALIZE_AND_LOAD(&gfx[0], play->state.gfxCtx);
multipliedFrames = frames * 20;
gSPSegment(&gfx[1], 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, frames * 30, -multipliedFrames, 64, 64, 1, multipliedFrames,
- -multipliedFrames, 64, 64));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, frames * 30, -multipliedFrames, 64, 64, 1, multipliedFrames,
+ -multipliedFrames, 64, 64, 30, -20, 20, -20));
gSPDisplayList(&gfx[2], gWaterVortexDL);
POLY_XLU_DISP = &gfx[3];
diff --git a/mm/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c b/mm/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c
index 87f7323a7..34670a16f 100644
--- a/mm/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c
+++ b/mm/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c
@@ -544,8 +544,8 @@ void func_80A5A184(Actor* thisx, PlayState* play2) {
gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, (u8)ptr->unk_38, 0, 0, (u8)ptr->unk_3C);
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, (ptr->unk_01 * -20) & 0x1FF,
- 0x20, 0x80));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, (ptr->unk_01 * -20) & 0x1FF,
+ 0x20, 0x80, 0, 0, 0, -20));
Matrix_Translate(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW);
diff --git a/mm/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c b/mm/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c
index 546bc2dce..5d84acd3d 100644
--- a/mm/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c
+++ b/mm/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c
@@ -46,7 +46,7 @@ void ObjFunen_Draw(Actor* thisx, PlayState* play) {
temp = -(play->gameplayFrames & 0x7FFFFFFF) & 0x7F;
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, temp, 0x20, 0x20, 1, 0, temp, 0x20, 0x20));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0, temp, 0x20, 0x20, 1, 0, temp, 0x20, 0x20, 0, -1, 0, -1));
gSPDisplayList(POLY_XLU_DISP++, gStoneTowerSmokeDL);
CLOSE_DISPS(play->state.gfxCtx);
}
diff --git a/mm/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c b/mm/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c
index dbafae07a..e341ff497 100644
--- a/mm/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c
+++ b/mm/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c
@@ -259,8 +259,8 @@ void ObjRaillift_Draw(Actor* thisx, PlayState* play) {
Gfx_SetupDL25_Opa(play->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08,
- Gfx_TwoTexScrollEnvColor(play->state.gfxCtx, 0, play->gameplayFrames, 0, 32, 32, 1, 0, 0, 32, 32, 0, 0,
- 0, 160));
+ Gfx_TwoTexScrollEnvColorEx(play->state.gfxCtx, 0, play->gameplayFrames, 0, 32, 32, 1, 0, 0, 32, 32, 0, 0,
+ 0, 160, 1, 0, 0, 0));
MATRIX_FINALIZE_AND_LOAD(POLY_OPA_DISP++, play->state.gfxCtx);
gSPDisplayList(POLY_OPA_DISP++, object_raillift_DL_004BF0);
diff --git a/mm/src/overlays/actors/ovl_Obj_Toudai/z_obj_toudai.c b/mm/src/overlays/actors/ovl_Obj_Toudai/z_obj_toudai.c
index f5f9d5a44..55a2b65fe 100644
--- a/mm/src/overlays/actors/ovl_Obj_Toudai/z_obj_toudai.c
+++ b/mm/src/overlays/actors/ovl_Obj_Toudai/z_obj_toudai.c
@@ -73,7 +73,7 @@ void func_80A33BB4(ObjToudai* this, PlayState* play) {
Gfx_SetupDL25_Opa(play->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, sp57, 0x20, 0x80, 1, 0, sp56, 0x20, 0x20));
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0, sp57, 0x20, 0x80, 1, 0, sp56, 0x20, 0x20, 0, 2, 0, 1));
gSPSegment(POLY_XLU_DISP++, 0x09, Lib_SegmentedToVirtual(this->unk_148));
MATRIX_FINALIZE_AND_LOAD(POLY_XLU_DISP++, play->state.gfxCtx);
gSPDisplayList(POLY_XLU_DISP++, object_f53_obj_DL_0023B0);
diff --git a/mm/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.c b/mm/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.c
index 7716eb6d7..d400bf560 100644
--- a/mm/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.c
+++ b/mm/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.c
@@ -91,9 +91,9 @@ void EffectSsEnFire_Draw(PlayState* play, u32 index, EffectSs* this) {
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
gDPSetEnvColor(POLY_XLU_DISP++, redGreen * 12.7f, 0, 0, 0);
gDPSetPrimColor(POLY_XLU_DISP++, 0x0, 0x80, redGreen * 12.7f, redGreen * 12.7f, 0, 255);
- gSPSegment(
- POLY_XLU_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, (this->rScroll * -20) & 0x1FF, 0x20, 0x80));
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, (this->rScroll * -20) & 0x1FF, 0x20,
+ 0x80, 0, 0, 0, -20));
if ((this->rFlags & 0x7FFF) || (this->life < 18)) {
gSPDisplayList(POLY_XLU_DISP++, gEffFire2DL);
diff --git a/mm/src/overlays/effects/ovl_Effect_Ss_Ice_Smoke/z_eff_ss_ice_smoke.c b/mm/src/overlays/effects/ovl_Effect_Ss_Ice_Smoke/z_eff_ss_ice_smoke.c
index 3b02b4223..c4d11b057 100644
--- a/mm/src/overlays/effects/ovl_Effect_Ss_Ice_Smoke/z_eff_ss_ice_smoke.c
+++ b/mm/src/overlays/effects/ovl_Effect_Ss_Ice_Smoke/z_eff_ss_ice_smoke.c
@@ -56,7 +56,7 @@ void EffectSsIceSmoke_Draw(PlayState* play, u32 index, EffectSs* this) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 235, 235, this->rAlpha);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, this->rScrollX * this->life, this->rScrollY * this->life, 0x20,
- 0x40, 1, 0, 0, 0x20, 0x20, -1, -1, 0, 0));
+ 0x40, 1, 0, 0, 0x20, 0x20, -this->rScrollX, -this->rScrollY, 0, 0));
Matrix_Translate(this->pos.x, this->pos.y, this->pos.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
scale = this->rScale * 0.0001f;