mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-08-12 12:18:32 -04:00
Constant-size texture scroll display lists via G_SETTILESIZE_LERP (#6902)
Rewrite Gfx_TexScrollEx / Gfx_TwoTexScrollEx / Gfx_TwoTexScrollEnvColorEx to emit one command per tile instead of one baked tile size per interpolated frame, so texture DL memory no longer scales with InterpolationFPS
This commit is contained in:
+1
-1
Submodule libultraship updated: 2bfbde3a72...c57da1b4af
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -1793,6 +1793,7 @@ void RunCommands(Gfx* Commands, int time, int step, int denom, int count) {
|
||||
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++;
|
||||
}
|
||||
@@ -2530,8 +2531,3 @@ bool SoH_HandleConfigDrop(char* filePath) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Number of interpolated frames
|
||||
extern "C" uint32_t Ship_GetInterpolationFrameCount() {
|
||||
return static_cast<uint32_t>(ceil((float)OTRGlobals::Instance->GetInterpolationFPS() / 20.0f));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+30
-89
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user