diff --git a/libultraship b/libultraship index 2bfbde3a72..c57da1b4af 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 2bfbde3a72c119f8073ad762ec6be131dff5df66 +Subproject commit c57da1b4afa775b24b58b2adf93d63d3b561bb65 diff --git a/soh/include/functions.h b/soh/include/functions.h index c96f3b23fb..1bec60eb8c 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -23,6 +23,8 @@ void gSPSegment(void* value, int segNum, uintptr_t target); void gSPSegmentLoadRes(void* value, int segNum, uintptr_t target); 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/soh/soh/GbiWrap.cpp b/soh/soh/GbiWrap.cpp index c16d46689b..28c5a7af22 100644 --- a/soh/soh/GbiWrap.cpp +++ b/soh/soh/GbiWrap.cpp @@ -91,6 +91,11 @@ extern "C" void gDPSetTileSizeInterp(Gfx* pkt, int t, float uls, float ult, floa pkt++; } +extern "C" 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); +} + extern "C" void gSPDisplayListOffset(Gfx* pkt, Gfx* dl, int offset) { char* imgData = (char*)dl; diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index c5e7164aa0..32b64fc504 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1793,6 +1793,7 @@ void RunCommands(Gfx* Commands, int time, int step, int denom, int count) { time += step; std::unordered_map mtx_replacements = (time == denom) ? std::unordered_map() : FrameInterpolation_Interpolate((float)time / denom); + intp->mInterpolationT = (float)time / denom; wnd->DrawAndRunGraphicsCommands(Commands, mtx_replacements); intp->mInterpolationIndex++; } @@ -2530,8 +2531,3 @@ bool SoH_HandleConfigDrop(char* filePath) { } return false; } - -// Number of interpolated frames -extern "C" uint32_t Ship_GetInterpolationFrameCount() { - return static_cast(ceil((float)OTRGlobals::Instance->GetInterpolationFPS() / 20.0f)); -} diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index abd40dd4ba..8e80660e31 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -135,8 +135,6 @@ void SaveManager_ThreadPoolWait(); GetItemID RetrieveGetItemIDFromItemID(ItemID itemID); RandomizerGet RetrieveRandomizerGetFromItemID(ItemID itemID); void Messagebox_ShowErrorBox(char* title, char* body); - -uint32_t Ship_GetInterpolationFrameCount(); #endif #ifdef __cplusplus diff --git a/soh/src/code/z_rcp.c b/soh/src/code/z_rcp.c index d358d4f44b..799f61cff2 100644 --- a/soh/src/code/z_rcp.c +++ b/soh/src/code/z_rcp.c @@ -1395,33 +1395,18 @@ Gfx* Gfx_TexScroll(GraphicsContext* gfxCtx, u32 x, u32 y, s32 width, s32 height) } 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; + s32 xEnd = (s32)x + xStep; + s32 yEnd = (s32)y + yStep; - 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++]); + 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; } @@ -1446,46 +1431,24 @@ Gfx* Gfx_TwoTexScroll(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1, s32 wi 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; + s32 x1End = (s32)x1 + xStep1; + s32 y1End = (s32)y1 + yStep1; + s32 x2End = (s32)x2 + xStep2; + s32 y2End = (s32)y2 + yStep2; - 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]); + 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; } @@ -1512,47 +1475,25 @@ Gfx* Gfx_TwoTexScrollEnvColor(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1 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) { - int interpFrames = Ship_GetInterpolationFrameCount(); - - Gfx* gfx = Graph_Alloc(gfxCtx, (6 + (interpFrames * 7)) * sizeof(Gfx)); + Gfx* gfx = Graph_Alloc(gfxCtx, 13 * 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; + s32 x1End = (s32)x1 + xStep1; + s32 y1End = (s32)y1 + yStep1; + s32 x2End = (s32)x2 + xStep2; + s32 y2End = (s32)y2 + yStep2; - 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; - } - gDPSetEnvColor(&gfx[index++], r, g, b, a); - 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)); + gDPSetEnvColor(&gfx[11], r, g, b, a); + gSPEndDisplayList(&gfx[12]); return gfx; } diff --git a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c index d88b3da71e..b0b79eaca9 100644 --- a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c +++ b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c @@ -5044,8 +5044,9 @@ void BossTw_DrawEffects(PlayState* play) { if (sp18F == 0) { gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gTwinrovaIceSurroundingPlayerMaterialDL)); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, 255); - gSPSegment(POLY_XLU_DISP++, 8, - Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, 0, 0x20, 0x20)); + gSPSegment( + POLY_XLU_DISP++, 8, + Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, 0, 0x20, 0x20, 0, 0, 0, 0)); sp18F++; BossTw_InitRand(1, 0x71AC, 0x263A); } @@ -5097,8 +5098,9 @@ void BossTw_DrawEffects(PlayState* play) { } gSPSegment(POLY_XLU_DISP++, 8, - Gfx_TwoTexScroll(play->state.gfxCtx, 0, (currentEffect->frame * 3) & 0x7F, - (-currentEffect->frame * 15) & 0xFF, 0x20, 0x40, 1, 0, 0, 0x20, 0x20)); + Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, (currentEffect->frame * 3) & 0x7F, + (-currentEffect->frame * 15) & 0xFF, 0x20, 0x40, 1, 0, 0, 0x20, 0x20, 3, -15, + 0, 0)); Matrix_Translate(currentEffect->pos.x, currentEffect->pos.y, currentEffect->pos.z, MTXMODE_NEW); Matrix_ReplaceRotation(&play->billboardMtxF); Matrix_Scale(currentEffect->workf[EFF_SCALE], currentEffect->workf[EFF_SCALE], 1.0f, MTXMODE_APPLY); diff --git a/soh/src/overlays/actors/ovl_En_Fz/z_en_fz.c b/soh/src/overlays/actors/ovl_En_Fz/z_en_fz.c index bbb7f7d96e..9c037ad6c1 100644 --- a/soh/src/overlays/actors/ovl_En_Fz/z_en_fz.c +++ b/soh/src/overlays/actors/ovl_En_Fz/z_en_fz.c @@ -886,8 +886,8 @@ void EnFz_DrawIceSmoke(EnFz* this, PlayState* play) { gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, iceSmoke->primAlpha); gSPSegment(POLY_XLU_DISP++, 0x08, - Gfx_TwoTexScroll(play->state.gfxCtx, 0, 3 * (iceSmoke->timer + (3 * i)), - 15 * (iceSmoke->timer + (3 * i)), 32, 64, 1, 0, 0, 32, 32)); + Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 3 * (iceSmoke->timer + (3 * i)), + 15 * (iceSmoke->timer + (3 * i)), 32, 64, 1, 0, 0, 32, 32, 3, 15, 0, 0)); Matrix_Translate(iceSmoke->pos.x, iceSmoke->pos.y, iceSmoke->pos.z, MTXMODE_NEW); Matrix_ReplaceRotation(&play->billboardMtxF); Matrix_Scale(iceSmoke->xyScale, iceSmoke->xyScale, 1.0f, MTXMODE_APPLY); diff --git a/soh/src/overlays/effects/ovl_Effect_Ss_En_Ice/z_eff_ss_en_ice.c b/soh/src/overlays/effects/ovl_Effect_Ss_En_Ice/z_eff_ss_en_ice.c index 3ba96fa69f..f301a5d228 100644 --- a/soh/src/overlays/effects/ovl_Effect_Ss_En_Ice/z_eff_ss_en_ice.c +++ b/soh/src/overlays/effects/ovl_Effect_Ss_En_Ice/z_eff_ss_en_ice.c @@ -122,8 +122,8 @@ void EffectSsEnIce_Draw(PlayState* play, u32 index, EffectSs* this) { Gfx_SetupDL_25Xlu(play->state.gfxCtx); func_8002EB44(&this->pos, &play->view.eye, &hiliteLightDir, play->state.gfxCtx); gSPSegment(POLY_XLU_DISP++, 0x08, - Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, gameplayFrames & 0xFF, 0x20, 0x10, 1, 0, - (gameplayFrames * 2) & 0xFF, 0x40, 0x20)); + Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0, gameplayFrames & 0xFF, 0x20, 0x10, 1, 0, + (gameplayFrames * 2) & 0xFF, 0x40, 0x20, 0, 1, 0, 2)); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, this->rPrimColorR, this->rPrimColorG, this->rPrimColorB, this->rPrimColorA); gDPSetEnvColor(POLY_XLU_DISP++, this->rEnvColorR, this->rEnvColorG, this->rEnvColorB, (u32)alpha);