From c5f120b6f833528c5a1b0bc61bcb823a5164b597 Mon Sep 17 00:00:00 2001 From: KiritoDev <36680385+KiritoDv@users.noreply.github.com> Date: Mon, 2 May 2022 17:26:32 -0500 Subject: [PATCH] Fixed Lens of truth and sandstorm to be widescreen (#254) --- .../Lib/Fast3D/U64/PR/ultra64/gbi.h | 14 +++++++ soh/soh/OTRGlobals.cpp | 7 ++++ soh/soh/OTRGlobals.h | 1 + soh/src/code/z_actor.c | 22 +++++++---- soh/src/code/z_fbdemo_circle.c | 2 - soh/src/code/z_kankyo.c | 38 ++++++++++++++++--- soh/src/code/z_room.c | 19 ++++++---- 7 files changed, 80 insertions(+), 23 deletions(-) diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gbi.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gbi.h index 8af624e8f..dedc97939 100644 --- a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gbi.h +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gbi.h @@ -4575,6 +4575,20 @@ _DW({ \ _g2->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \ } +# define gsSPWideTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \ +{{ \ + (_SHIFTL(G_TEXRECT_WIDE, 24, 8) | _SHIFTL((xh), 0, 24)), \ + _SHIFTL((yh), 0, 24), \ +}}, \ +{{ \ + (_SHIFTL((tile), 24, 3) | _SHIFTL((xl), 0, 24)), \ + _SHIFTL((yl), 0, 24), \ +}}, \ +{{ \ + _SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16), \ + _SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16) \ +}} + /* like gSPTextureRectangle but accepts negative position arguments */ #define gSPScisTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \ _DW({ \ diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index d2bc941cf..aad82be29 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -289,6 +289,13 @@ extern "C" Gfx* ResourceMgr_LoadGfxByName(const char* path) return (Gfx*)&res->instructions[0]; } +extern "C" Gfx* ResourceMgr_PatchGfxByName(const char* path, int size) { + auto res = std::static_pointer_cast( + OTRGlobals::Instance->context->GetResourceManager()->LoadResource(path)); + res->instructions.resize(res->instructions.size() + size); + return (Gfx*)&res->instructions[0]; +} + extern "C" char* ResourceMgr_LoadArrayByName(const char* path) { auto res = std::static_pointer_cast(OTRGlobals::Instance->context->GetResourceManager()->LoadResource(path)); diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 7ce08649a..339613b25 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -38,6 +38,7 @@ char* ResourceMgr_LoadPlayerAnimByName(const char* animPath); char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc); Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc); Gfx* ResourceMgr_LoadGfxByName(const char* path); +Gfx* ResourceMgr_PatchGfxByName(const char* path, int size); Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc); Vtx* ResourceMgr_LoadVtxByName(const char* path); CollisionHeader* ResourceMgr_LoadColByName(const char* path); diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index bb55009bb..9d9a34c96 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -957,7 +957,7 @@ void TitleCard_InitPlaceName(GlobalContext* globalCtx, TitleCardContext* titleCt default: titleCtx->texture = NULL; return; - + } char newName[512]; @@ -1122,7 +1122,7 @@ void Actor_Init(Actor* actor, GlobalContext* globalCtx) { CollisionCheck_InitInfo(&actor->colChkInfo); actor->floorBgId = BGCHECK_SCENE; ActorShape_Init(&actor->shape, 0.0f, NULL, 0.0f); - //if (Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex)) + //if (Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex)) { //Actor_SetObjectDependency(globalCtx, actor); actor->init(actor, globalCtx); @@ -2358,7 +2358,7 @@ void Actor_UpdateAll(GlobalContext* globalCtx, ActorContext* actorCtx) { actor->sfx = 0; if (actor->init != NULL) { - if (Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex)) + if (Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex)) { Actor_SetObjectDependency(globalCtx, actor); actor->init(actor, globalCtx); @@ -2547,10 +2547,16 @@ void func_80030FA8(GraphicsContext* gfxCtx) { gDPLoadTextureBlock(POLY_XLU_DISP++, gLensOfTruthMaskTex, G_IM_FMT_I, G_IM_SIZ_8b, 64, 64, 0, G_TX_MIRROR | G_TX_CLAMP, G_TX_MIRROR | G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD); - gDPSetTileSize(POLY_XLU_DISP++, G_TX_RENDERTILE, 384, 224, 892, 732); - gSPTextureRectangle(POLY_XLU_DISP++, 0, 0, 1280, 960, G_TX_RENDERTILE, 2240, 1600, 576, 597); - gDPPipeSync(POLY_XLU_DISP++); + s32 x = OTRGetRectDimensionFromLeftEdge(0) << 2; + s32 w = OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH) << 2; + float ratio = OTRGetAspectRatio(); + + gDPSetTileSize(POLY_XLU_DISP++, G_TX_RENDERTILE, 384, 224, 892, 732); + // TODO: Do correct math to fix it + gSPWideTextureRectangle(POLY_XLU_DISP++, x, 0, x + abs(x), 960, G_TX_RENDERTILE, 0, 0, 0, 0); + gSPWideTextureRectangle(POLY_XLU_DISP++, 0, 0, w, 960, G_TX_RENDERTILE, 2240, 1600, 576, 597); + gDPPipeSync(POLY_XLU_DISP++); CLOSE_DISPS(gfxCtx, "../z_actor.c", 6183); } @@ -2894,7 +2900,7 @@ void Actor_FreeOverlay(ActorOverlay* actorOverlay) { osSyncPrintf(VT_FGCOL(CYAN)); if (actorOverlay->numLoaded == 0) { - + if (actorOverlay->initInfo->reset != NULL) { actorOverlay->initInfo->reset(); } @@ -3020,7 +3026,7 @@ Actor* Actor_Spawn(ActorContext* actorCtx, GlobalContext* globalCtx, s16 actorId if (objBankIndex < 0 && !gMapLoading) objBankIndex = 0; - + if ((objBankIndex < 0) || ((actorInit->category == ACTORCAT_ENEMY) && Flags_GetClear(globalCtx, globalCtx->roomCtx.curRoom.num))) { // "No data bank!! (profilep->bank=%d)" diff --git a/soh/src/code/z_fbdemo_circle.c b/soh/src/code/z_fbdemo_circle.c index b19948737..a6a46a0e4 100644 --- a/soh/src/code/z_fbdemo_circle.c +++ b/soh/src/code/z_fbdemo_circle.c @@ -145,8 +145,6 @@ void TransitionCircle_Draw(void* thisx, Gfx** gfxP) { modelView = this->modelView[this->frame]; - this->color.rgba = 0xFFFFFFFF; - this->frame ^= 1; gDPPipeSync(gfx++); texScroll = Gfx_BranchTexScroll(&gfx, this->texX, this->texY, 0x10, 0x40); diff --git a/soh/src/code/z_kankyo.c b/soh/src/code/z_kankyo.c index f3ac083ab..9f7518374 100644 --- a/soh/src/code/z_kankyo.c +++ b/soh/src/code/z_kankyo.c @@ -743,7 +743,7 @@ void Environment_UpdateSkybox(GlobalContext* globalCtx, u8 skyboxId, Environment if (envCtx->skyboxDmaState == SKYBOX_DMA_FILE2_DONE) { envCtx->skyboxDmaState = SKYBOX_DMA_PAL2_START; - if ((newSkybox2Index & 1) ^ ((newSkybox2Index & 4) >> 2)) + if ((newSkybox2Index & 1) ^ ((newSkybox2Index & 4) >> 2)) { SkyboxTableEntry entryA = sSkyboxTable[newSkybox2Index]; LoadSkyboxPalette(skyboxCtx, 0, entryA.palettes[0], 16, 8); @@ -753,7 +753,7 @@ void Environment_UpdateSkybox(GlobalContext* globalCtx, u8 skyboxId, Environment DmaMgr_SendRequest2(&envCtx->dmaRequest, (uintptr_t)skyboxCtx->palettes, gSkyboxFiles[newSkybox2Index].palette.vromStart, size, 0, &envCtx->loadQueue, NULL, "../z_kankyo.c", 1342);*/ - } else + } else { SkyboxTableEntry entryA = sSkyboxTable[newSkybox2Index]; LoadSkyboxPalette(skyboxCtx, 1, entryA.palettes[0], 16, 8); @@ -769,12 +769,12 @@ void Environment_UpdateSkybox(GlobalContext* globalCtx, u8 skyboxId, Environment } if ((envCtx->skyboxDmaState == SKYBOX_DMA_FILE1_START) || (envCtx->skyboxDmaState == SKYBOX_DMA_FILE2_START)) { - //if (osRecvMesg(&envCtx->loadQueue, 0, OS_MESG_NOBLOCK) == 0) + //if (osRecvMesg(&envCtx->loadQueue, 0, OS_MESG_NOBLOCK) == 0) { envCtx->skyboxDmaState++; } } else if (envCtx->skyboxDmaState >= SKYBOX_DMA_FILE1_DONE) { - //if (osRecvMesg(&envCtx->loadQueue, 0, OS_MESG_NOBLOCK) == 0) + //if (osRecvMesg(&envCtx->loadQueue, 0, OS_MESG_NOBLOCK) == 0) { envCtx->skyboxDmaState = SKYBOX_DMA_INACTIVE; } @@ -2275,6 +2275,29 @@ Color_RGB8 sSandstormEnvColors[] = { { 50, 40, 0 }, }; +Gfx* gFieldSandstormDL_Custom = NULL; + +void Environment_PatchSandstorm(GlobalContext* globalCtx) { + if (gFieldSandstormDL_Custom) return; + + gFieldSandstormDL_Custom = ResourceMgr_PatchGfxByName(gFieldSandstormDL, -3); + + const Gfx gFSPatchDL[2] = { gsSPEndDisplayList() }; + bool patched = false; + Gfx* cmd = gFieldSandstormDL_Custom; + int id = 0; + + while (!patched) { + const uint32_t opcode = cmd->words.w0 >> 24; + if (opcode == G_TEXRECT) { + gFieldSandstormDL_Custom[id] = gFSPatchDL[0]; + patched = true; + } + ++cmd; + id++; + } +} + void Environment_DrawSandstorm(GlobalContext* globalCtx, u8 sandstormState) { s32 primA1; s32 envA1; @@ -2288,6 +2311,8 @@ void Environment_DrawSandstorm(GlobalContext* globalCtx, u8 sandstormState) { u16 sp94; u16 sp92; + Environment_PatchSandstorm(globalCtx); + switch (sandstormState) { case 3: if ((globalCtx->sceneNum == SCENE_SPOT13) && (globalCtx->roomCtx.curRoom.num == 0)) { @@ -2394,8 +2419,11 @@ void Environment_DrawSandstorm(GlobalContext* globalCtx, u8 sandstormState) { Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (u32)sp96 % 0x1000, 0, 0x200, 0x20, 1, (u32)sp94 % 0x1000, 0xFFF - ((u32)sp92 % 0x1000), 0x100, 0x40)); gDPSetTextureLUT(POLY_XLU_DISP++, G_TT_NONE); - gSPDisplayList(POLY_XLU_DISP++, gFieldSandstormDL); + gSPDisplayList(POLY_XLU_DISP++, gFieldSandstormDL_Custom); + gSPWideTextureRectangle(POLY_XLU_DISP++, OTRGetRectDimensionFromLeftEdge(0) << 2, 0, + OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH) << 2, 0x03C0, G_TX_RENDERTILE, 0, 0, 0x008C, + -0x008C); CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_kankyo.c", 4068); D_8015FDB0 += (s32)sp98; diff --git a/soh/src/code/z_room.c b/soh/src/code/z_room.c index 93aab731f..5212799a6 100644 --- a/soh/src/code/z_room.c +++ b/soh/src/code/z_room.c @@ -126,7 +126,7 @@ void func_80095D04(GlobalContext* globalCtx, Room* room, u32 flags) { sp90.y = polygonDlist->pos.y; sp90.z = polygonDlist->pos.z; SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &sp90, &sp84, &sp80); - if (-(f32)polygonDlist->unk_06 < sp84.z) + if (-(f32)polygonDlist->unk_06 < sp84.z) { temp_f2 = sp84.z - polygonDlist->unk_06; if (temp_f2 < globalCtx->lightCtx.fogFar) { @@ -171,7 +171,7 @@ void func_80095D04(GlobalContext* globalCtx, Room* room, u32 flags) { Gfx* temp2; polygonDlist = spB4->unk_00; - if (iREG(86) != 0) + if (iREG(86) != 0) { temp = sp78; for (phi_v1 = 0; phi_v1 < polygon2->num; phi_v1++, temp++) { @@ -180,7 +180,7 @@ void func_80095D04(GlobalContext* globalCtx, Room* room, u32 flags) { } } - if (((iREG(86) == 1) && (iREG(89) >= sp9C)) || ((iREG(86) == 2) && (iREG(89) == sp9C))) + if (((iREG(86) == 1) && (iREG(89) >= sp9C)) || ((iREG(86) == 2) && (iREG(89) == sp9C))) { if (flags & 1) { temp2 = polygonDlist->opa; @@ -224,7 +224,7 @@ void func_80095D04(GlobalContext* globalCtx, Room* room, u32 flags) { s32 func_80096238(void* data) { OSTime time; - if (*(u32*)data == JPEG_MARKER) + if (*(u32*)data == JPEG_MARKER) { char* decodedJpeg = ResourceMgr_LoadJPEG(data, 320 * 240 * 2); //char* decodedJpeg = ResourceMgr_LoadJPEG(data, 480 * 240 * 2); @@ -235,8 +235,8 @@ s32 func_80096238(void* data) { osSyncPrintf("ワークバッファアドレス(Zバッファ)%08x\n", gZBuffer); time = osGetTime(); - - //if (!Jpeg_Decode(data, gZBuffer, gGfxSPTaskOutputBuffer, sizeof(gGfxSPTaskOutputBuffer))) + + //if (!Jpeg_Decode(data, gZBuffer, gGfxSPTaskOutputBuffer, sizeof(gGfxSPTaskOutputBuffer))) if (1) { memcpy(data, decodedJpeg, 320 * 240 * 2); @@ -294,14 +294,17 @@ void func_8009638C(Gfx** displayList, void* source, void* tlut, u16 width, u16 h bg->b.frameW = width * 4; bg->b.frameH = height * 4; guS2DInitBg(bg); - - gDPSetOtherMode(displayListHead++, mode0 | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_COPY | G_PM_NPRIMITIVE, + + gDPSetOtherMode(displayListHead++, mode0 | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_FILL | G_PM_NPRIMITIVE, G_AC_THRESHOLD | G_ZS_PIXEL | G_RM_NOOP | G_RM_NOOP2); gDPSetFillColor(displayListHead++, GPACK_RGBA5551(0, 0, 0, 1) << 16 | GPACK_RGBA5551(0, 0, 0, 1)); gDPFillWideRectangle(displayListHead++, OTRGetRectDimensionFromLeftEdge(0), 0, OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH), SCREEN_HEIGHT); + gDPSetOtherMode(displayListHead++, mode0 | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_COPY | G_PM_NPRIMITIVE, + G_AC_THRESHOLD | G_ZS_PIXEL | G_RM_NOOP | G_RM_NOOP2); + gDPLoadMultiTile(displayListHead++, bg->b.imagePtr, 0, G_TX_RENDERTILE, G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, 0, 0, 0, 0 + 31, 0 + 31, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD,