From af165cb21cbfba04247f416114612fae1e600d11 Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Sun, 5 May 2024 19:09:11 -0400 Subject: [PATCH] Various transform tagging --- patches/effect_transform_tagging.c | 72 ++++++++ patches/fixes.c | 32 ++++ patches/song_transform_tagging.c | 9 + patches/specific_actor_transform_tagging.c | 169 +++++++++++++++++ patches/terrain_transform_tagging.c | 200 +++++++++++++++++++++ patches/transform_ids.h | 3 + 6 files changed, 485 insertions(+) diff --git a/patches/effect_transform_tagging.c b/patches/effect_transform_tagging.c index bd7ffd7..3f6ba7c 100644 --- a/patches/effect_transform_tagging.c +++ b/patches/effect_transform_tagging.c @@ -751,3 +751,75 @@ void EnClearTag_DrawEffects(Actor* thisx, PlayState* play) { CLOSE_DISPS(play->state.gfxCtx); } + +// @recomp Patched to tag the two custom lens flares (used by the Igos du Ikana curtains). +void Environment_DrawCustomLensFlare(PlayState* play) { + Vec3f pos; + + // @recomp Set up the graphics context. + OPEN_DISPS(play->state.gfxCtx); + + if (gCustomLensFlare1On) { + pos.x = gCustomLensFlare1Pos.x; + pos.y = gCustomLensFlare1Pos.y; + pos.z = gCustomLensFlare1Pos.z; + // @recomp Tag the entire lens flare effect, using order linear. Skip interpolation when the camera is skipped. + if (camera_was_skipped()) { + gEXMatrixGroupDecomposedSkipAll(POLY_XLU_DISP++, CUSTOM_LENS_FLARE_TRANSFORM_ID_START + 0, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE); + } + else { + gEXMatrixGroupDecomposedNormal(POLY_XLU_DISP++, CUSTOM_LENS_FLARE_TRANSFORM_ID_START + 0, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE); + } + Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, pos, D_801F4E44, D_801F4E48, + D_801F4E4C, false); + // @recomp Pop the matrix group. + gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW); + } + + if (gCustomLensFlare2On) { + pos.x = gCustomLensFlare2Pos.x; + pos.y = gCustomLensFlare2Pos.y; + pos.z = gCustomLensFlare2Pos.z; + // @recomp Tag the entire lens flare effect, using order linear. Skip interpolation when the camera is skipped. + if (camera_was_skipped()) { + gEXMatrixGroupDecomposedSkipAll(POLY_XLU_DISP++, CUSTOM_LENS_FLARE_TRANSFORM_ID_START + 1, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE); + } + else { + gEXMatrixGroupDecomposedNormal(POLY_XLU_DISP++, CUSTOM_LENS_FLARE_TRANSFORM_ID_START + 1, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE); + } + Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, pos, D_801F4E5C, D_801F4E60, + D_801F4E64, false); + // @recomp Pop the matrix group. + gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW); + } + + // @recomp Close the graphics context. + CLOSE_DISPS(); +} + +// @recomp Patched to tag the sun lens flare. +void Environment_DrawSunLensFlare(PlayState* play, EnvironmentContext* envCtx, View* view, GraphicsContext* gfxCtx, + Vec3f vec) { + if ((play->envCtx.precipitation[PRECIP_RAIN_CUR] == 0) && + !(GET_ACTIVE_CAM(play)->stateFlags & CAM_STATE_UNDERWATER) && (play->skyboxId == SKYBOX_NORMAL_SKY)) { + f32 v0 = Math_CosS(CURRENT_TIME - CLOCK_TIME(12, 0)); + + // @recomp Set up the graphics context. + OPEN_DISPS(play->state.gfxCtx); + + // @recomp Tag the entire lens flare effect, using order linear. Skip interpolation when the camera is skipped. + if (camera_was_skipped()) { + gEXMatrixGroupDecomposedSkipAll(POLY_XLU_DISP++, SUN_LENS_FLARE_TRANSFORM_ID, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE); + } + else { + gEXMatrixGroupDecomposedNormal(POLY_XLU_DISP++, SUN_LENS_FLARE_TRANSFORM_ID, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE); + } + Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, vec, 370.0f, v0 * 120.0f, 0x190, + true); + // @recomp Pop the matrix group. + gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW); + + // @recomp Close the graphics context. + CLOSE_DISPS(); + } +} diff --git a/patches/fixes.c b/patches/fixes.c index 1341c2c..aae4bba 100644 --- a/patches/fixes.c +++ b/patches/fixes.c @@ -1,6 +1,7 @@ #include "patches.h" #include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h" #include "overlays/actors/ovl_En_Fall/z_en_fall.h" +#include "overlays/actors/ovl_Demo_Effect/z_demo_effect.h" #define PAGE_BG_WIDTH (PAGE_BG_COLS * PAGE_BG_QUAD_WIDTH) #define PAGE_BG_HEIGHT (PAGE_BG_ROWS * PAGE_BG_QUAD_HEIGHT) @@ -298,3 +299,34 @@ void Cutscene_UpdateScripted(PlayState* play, CutsceneContext* csCtx) { } } } + +// @recomp Fix a texture scroll using an incorrect tile size, which resulted in the scroll jumping during the animation. +s32 DemoEffect_OverrideLimbDrawTimewarp(PlayState* play, SkelCurve* skelCurve, s32 limbIndex, Actor* thisx) { + s32 pad; + DemoEffect* this = (DemoEffect*)thisx; + u32 frames = play->gameplayFrames; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 170, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, this->envXluColor[0], this->envXluColor[1], this->envXluColor[2], 255); + + // @recomp Fix the tile size to be 64x64 for both tiles to match the actual texture size. + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(play->state.gfxCtx, + 0, (frames * 6) % 256, 255 - ((frames * 16) % 256), 0x40, 0x40, + 1, (frames * 4) % 256, 255 - ((frames * 12) % 256), 0x40, 0x40)); + + CLOSE_DISPS(play->state.gfxCtx); + + if (limbIndex == 0) { + s16* transform = skelCurve->jointTable[0]; + + transform[2] = transform[0] = 1024; + transform[1] = 1024; + } + + return true; +} diff --git a/patches/song_transform_tagging.c b/patches/song_transform_tagging.c index 619d57b..9c9bb8c 100644 --- a/patches/song_transform_tagging.c +++ b/patches/song_transform_tagging.c @@ -64,8 +64,17 @@ void EnTest7_Draw(Actor* thisx, PlayState* play) { EnTest7_DrawFeathers(play, this->feathers); if (this->flags & OWL_WARP_FLAGS_DRAW_LENS_FLARE) { + // @recomp Tag the entire lens flare effect, using order linear. Skip interpolation when the camera is skipped. + if (camera_was_skipped()) { + gEXMatrixGroupDecomposedSkipAll(POLY_XLU_DISP++, SOARING_LENS_FLARE_TRANSFORM_ID, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE); + } + else { + gEXMatrixGroupDecomposedNormal(POLY_XLU_DISP++, SOARING_LENS_FLARE_TRANSFORM_ID, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE); + } Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, this->actor.world.pos, 70.0f, 5.0f, 0, false); + // @recomp Pop the lens flare matrix group. + gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW); } CLOSE_DISPS(play->state.gfxCtx); diff --git a/patches/specific_actor_transform_tagging.c b/patches/specific_actor_transform_tagging.c index 3ce4d78..3c4341a 100644 --- a/patches/specific_actor_transform_tagging.c +++ b/patches/specific_actor_transform_tagging.c @@ -10,6 +10,11 @@ #include "overlays/actors/ovl_Obj_Entotu/z_obj_entotu.h" #include "overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.h" #include "overlays/actors/ovl_En_Twig/z_en_twig.h" +#include "overlays/actors/ovl_En_Honotrap/z_en_honotrap.h" + +// Decomp renames, TODO update decomp and remove these +#define EnHonotrap_FlameGroup func_8092F878 +#define EnHonotrap_DrawFlameGroup func_80930190 extern EnTanron2* D_80BB8458[82]; extern Boss04* D_80BB8450; @@ -1109,3 +1114,167 @@ void EnTwig_Draw(Actor* thisx, PlayState* play) { break; } } + +extern Gfx gEffFire1DL[]; + +#define HONOTRAP_EXTRA_BYTE_1(flameGroup) (&(flameGroup)->flameList[0].isDrawn)[1] +#define HONOTRAP_EXTRA_BYTE_2(flameGroup) (&(flameGroup)->flameList[1].isDrawn)[1] + +void EnHonotrap_FlameGroup(EnHonotrap* this, PlayState* play) { + s32 i; + EnHonotrapFlameGroup* flameGroup = &this->flameGroup; + f32 var_fs0; + f32 temp_fs0; + f32 temp_fs1; + f32 sp88; + f32 sp84; + f32 sp80; + s32 flameScrollDisplacement; + s32 sp78 = false; + f32 var_fs0_2; + Vec3f sp68; + EnHonotrapFlameElement* flameElem; + + sp80 = fabsf(Math_CosS(Camera_GetCamDirPitch(GET_ACTIVE_CAM(play)))); + flameScrollDisplacement = (s32)(sp80 * -10.5f) - 10; + Math_StepToF(&flameGroup->unk0, 1.0f, 0.05f); + if (this->timer <= 40) { + sp78 = Math_StepToF(&flameGroup->unk4, 1.0f, 0.05f); + } else if (this->actor.parent == NULL) { + this->timer = 40; + } + for (i = 0; i < ARRAY_COUNT(flameGroup->flameList); i++) { + flameGroup->flameList[i].isDrawn = false; + } + + sp88 = Math_SinS(this->actor.shape.rot.y) * 120.0f; + sp84 = Math_CosS(this->actor.shape.rot.y) * 120.0f; + + flameGroup->unk8 += 0.050f * (1.0f - flameGroup->unk4); + + if (flameGroup->unk8 > 1.0f / 6) { + flameGroup->unk8 -= 1.0f / 6; + // @recomp Indicate that a cycle of the flame group has occurred. + HONOTRAP_EXTRA_BYTE_1(flameGroup) = true; + HONOTRAP_EXTRA_BYTE_2(flameGroup)++; + if (HONOTRAP_EXTRA_BYTE_2(flameGroup) == ARRAY_COUNT(flameGroup->flameList)) { + HONOTRAP_EXTRA_BYTE_2(flameGroup) = 0; + } + } + else { + HONOTRAP_EXTRA_BYTE_1(flameGroup) = false; + } + var_fs0 = flameGroup->unk4 + flameGroup->unk8; + + for (i = 0; i < ARRAY_COUNT(flameGroup->flameList) && (var_fs0 <= flameGroup->unk0); i++) { + flameElem = &flameGroup->flameList[i]; + flameElem->isDrawn = true; + + flameElem->pos.x = (sp88 * var_fs0) + this->actor.world.pos.x; + flameElem->pos.y = this->actor.world.pos.y; + flameElem->pos.z = (sp84 * var_fs0) + this->actor.world.pos.z; + + flameElem->unkC = Math_SinS(TRUNCF_BINANG(var_fs0 * 25486.223f)) * 1.6f; + if (flameElem->unkC > 1.0f) { + flameElem->unkC = 1.0f; + } else if (flameElem->unkC < 0.0f) { + flameElem->unkC = 0.0f; + } + + var_fs0 += 1.0f / 6; + flameElem->unkC *= (0.006f * (((1.0f - flameGroup->unk4) * 0.8f) + 0.2f)); + flameElem->flameScroll += flameScrollDisplacement; + flameElem->flameScroll %= 0x200U; + } + + if (sp78 || (this->timer <= 0)) { + Actor_Kill(&this->actor); + return; + } + temp_fs0 = flameGroup->unk0 * 120.0f; + temp_fs1 = flameGroup->unk4 * 120.0f; + Actor_OffsetOfPointInActorCoords(&this->actor, &sp68, &GET_PLAYER(play)->actor.world.pos); + + if (sp68.z < temp_fs1) { + sp68.z = temp_fs1; + } else if (temp_fs0 < sp68.z) { + sp68.z = temp_fs0; + } + + var_fs0_2 = Math_SinS(TRUNCF_BINANG(sp68.z * 212.3852f)) * 1.6f; + if (var_fs0_2 > 1.0f) { + var_fs0_2 = 1.0f; + } + sp80 *= ((1.0f - flameGroup->unk4) * 0.8f) + 0.2f; + if (sp80 > 0.2f) { + this->collider.cyl.dim.pos.x = + TRUNCF_BINANG((Math_SinS(this->actor.shape.rot.y) * sp68.z) + this->actor.world.pos.x); + this->collider.cyl.dim.pos.y = TRUNCF_BINANG(this->actor.world.pos.y - (24.0f * var_fs0_2)); + this->collider.cyl.dim.pos.z = + TRUNCF_BINANG((Math_CosS(this->actor.shape.rot.y) * sp68.z) + this->actor.world.pos.z); + this->collider.cyl.dim.radius = TRUNCF_BINANG(15.0f * var_fs0_2); + this->collider.cyl.dim.height = TRUNCF_BINANG(37.5f * var_fs0_2); + CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.tris.base); + CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.tris.base); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.tris.base); + } +} + + +// @recomp Patched to tag the flames that come out of fire eyes. +void EnHonotrap_DrawFlameGroup(Actor* thisx, PlayState* play) { + s32 pad; + EnHonotrap* this = (EnHonotrap*)thisx; + EnHonotrapFlameElement* flameElem; + EnHonotrapFlameGroup* flameGroup = &this->flameGroup; + s32 i; + s32 pad2; + Vec3s camDir; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 200, 0, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0); + camDir = Camera_GetCamDir(GET_ACTIVE_CAM(play)); + camDir.y += 0x8000; + + // @recomp Get the transform ID for this actor. + u32 base_transform_id = actor_transform_id(thisx); + + for (i = 0; i < ARRAY_COUNT(flameGroup->flameList); i++) { + flameElem = &flameGroup->flameList[i]; + if (flameElem->isDrawn) { + + // @recomp Tag the current flame. + s32 transform_id_offset = i - HONOTRAP_EXTRA_BYTE_2(flameGroup); + if (transform_id_offset < 0) { + transform_id_offset += ARRAY_COUNT(flameGroup->flameList); + } + u32 transform_id = base_transform_id + transform_id_offset; + + // @recomp Use the texscroll for the flame index based on the calculated transform offset to make it consistent in movement. + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, flameGroup->flameList[transform_id_offset].flameScroll, 32, 128)); + Matrix_SetTranslateRotateYXZ(flameElem->pos.x, flameElem->pos.y - (4000.0f * flameElem->unkC), + flameElem->pos.z, &camDir); + Matrix_Scale(((fabsf(Math_SinS((s16)(camDir.y - thisx->shape.rot.y) >> 1)) * 0.2f) + 1.7f) * + flameElem->unkC, + flameElem->unkC, 1.0f, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + // @recomp Skip if a cycle occurred and this is the first flame. + if (i == 0 && HONOTRAP_EXTRA_BYTE_1(flameGroup)) { + gEXMatrixGroupDecomposedSkipAll(POLY_XLU_DISP++, transform_id, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE); + } + else { + gEXMatrixGroupDecomposedNormal(POLY_XLU_DISP++, transform_id, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE); + } + gSPDisplayList(POLY_XLU_DISP++, gEffFire1DL); + // @recomp Pop the matrix group. + gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW); + } + } + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/patches/terrain_transform_tagging.c b/patches/terrain_transform_tagging.c index 2b392c7..3de96a4 100644 --- a/patches/terrain_transform_tagging.c +++ b/patches/terrain_transform_tagging.c @@ -1,6 +1,7 @@ #include "patches.h" #include "transform_ids.h" #include "overlays/actors/ovl_Dm_Opstage/z_dm_opstage.h" +#include "overlays/actors/ovl_Dm_Char01/z_dm_char01.h" static Vec3f sZeroVec = { 0.0f, 0.0f, 0.0f }; @@ -97,3 +98,202 @@ void DmOpstage_Draw(Actor* thisx, PlayState* play) { break; } } + +extern AnimatedMaterial gWoodfallSceneryPoisonWaterTexAnim[]; +extern AnimatedMaterial gWoodfallSceneryPurifiedWaterTexAnim[]; +extern AnimatedMaterial gWoodfallSceneryDynamicPoisonWaterTexAnim[]; +extern AnimatedMaterial gWoodfallSceneryPoisonWallsTexAnim[]; +extern AnimatedMaterial gWoodfallSceneryPurifiedWallsTexAnim[]; +extern AnimatedMaterial gWoodfallSceneryTempleTexAnim[]; +extern AnimatedMaterial gWoodfallSceneryWaterFlowingOverTempleTexAnim[]; +extern Gfx gWoodfallSceneryPoisonWaterDL[]; +extern Gfx gWoodfallSceneryFloorDL[]; +extern Gfx gWoodfallSceneryPurifiedWaterDL[]; +extern Gfx gWoodfallSceneryPurifiedWallsDL[]; +extern Gfx gWoodfallSceneryDynamicPoisonWaterDL[]; +extern Gfx gWoodfallSceneryPoisonWallsDL[]; +extern Gfx gWoodfallSceneryTempleDL[]; +extern Gfx gWoodfallSceneryWaterFlowingOverTempleDL[]; +extern Gfx gWoodfallSceneryTempleEntrancesDL[]; +extern Gfx gWoodfallSceneryTempleRampAndPlatformDL[]; +extern Vtx gWoodfallSceneryDynamicPoisonWaterVtx[]; + +extern s16 D_80AAAE20; +extern s16 D_80AAAE22; +extern s16 D_80AAAE24; + +// @recomp Patched to enable vertex interpolation for the dynamic water as Woodfall temple rises from below the water. +void DmChar01_Draw(Actor* thisx, PlayState* play) { + static f32 D_80AAAAB8 = 0.0f; + static f32 D_80AAAABC = 0.0f; + static s16 D_80AAAAC0 = 0; + static s16 D_80AAAAC4 = 0; + static s16 D_80AAAAC8 = 0; + static s16 D_80AAAACC = 0; + DmChar01* this = (DmChar01*)thisx; + f32 temp_f12; + f32 spBC; + s32 i; + u8 spB7 = false; + + switch (DMCHAR01_GET(thisx)) { + case DMCHAR01_0: + switch (this->unk_34C) { + case 0: + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryPoisonWaterTexAnim)); + Gfx_DrawDListOpa(play, gWoodfallSceneryPoisonWaterDL); + break; + + case 1: + if (gSaveContext.sceneLayer == 1) { + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryPurifiedWaterTexAnim)); + Gfx_DrawDListOpa(play, gWoodfallSceneryFloorDL); + Gfx_DrawDListXlu(play, gWoodfallSceneryPurifiedWaterDL); + Matrix_Translate(0.0f, 10.0f, 0.0f, MTXMODE_APPLY); + } + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryDynamicPoisonWaterTexAnim)); + + OPEN_DISPS(play->state.gfxCtx); + + if ((u8)this->unk_348 == 255) { + Gfx_SetupDL25_Opa(play->state.gfxCtx); + + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2); + gDPPipeSync(POLY_OPA_DISP++); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x96, 255, 255, 255, 255); + // @recomp Manual relocation, TODO remove when automated. + gSPSegment(POLY_OPA_DISP++, 0x0B, actor_relocate(thisx, gWoodfallSceneryDynamicPoisonWaterVtx)); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // @recomp Tag the matrix to enable vertex interpolation. + gEXMatrixGroupDecomposedVerts(POLY_OPA_DISP++, actor_transform_id(thisx), G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE); + gSPDisplayList(POLY_OPA_DISP++, gWoodfallSceneryDynamicPoisonWaterDL); + // @recomp Tag the matrix to enable vertex interpolation. + gEXPopMatrixGroup(POLY_OPA_DISP++, G_MTX_MODELVIEW); + } else { + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, (u8)this->unk_348); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x96, 255, 255, 255, (u8)this->unk_348); + // @recomp Manual relocation, TODO remove when automated. + gSPSegment(POLY_XLU_DISP++, 0x0B, actor_relocate(thisx, gWoodfallSceneryDynamicPoisonWaterVtx)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // @recomp Tag the matrix to enable vertex interpolation. + gEXMatrixGroupDecomposedVerts(POLY_XLU_DISP++, actor_transform_id(thisx), G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE); + gSPDisplayList(POLY_XLU_DISP++, gWoodfallSceneryDynamicPoisonWaterDL); + // @recomp Tag the matrix to enable vertex interpolation. + gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW); + } + + CLOSE_DISPS(play->state.gfxCtx); + break; + + case 2: + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryPurifiedWaterTexAnim)); + Gfx_DrawDListOpa(play, gWoodfallSceneryFloorDL); + Gfx_DrawDListXlu(play, gWoodfallSceneryPurifiedWaterDL); + break; + } + break; + + case DMCHAR01_1: + switch (this->unk_34C) { + case 0: + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryPoisonWallsTexAnim)); + Gfx_DrawDListOpa(play, gWoodfallSceneryPoisonWallsDL); + break; + + case 1: + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryPurifiedWallsTexAnim)); + Gfx_DrawDListOpa(play, gWoodfallSceneryPurifiedWallsDL); + break; + } + break; + + case DMCHAR01_2: + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryTempleTexAnim)); + Gfx_DrawDListOpa(play, gWoodfallSceneryTempleDL); + + if ((this->unk_34C != 0) && ((u8)this->unk_348 != 0)) { + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryWaterFlowingOverTempleTexAnim)); + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, (u8)this->unk_348); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, (u8)this->unk_348); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gWoodfallSceneryWaterFlowingOverTempleDL); + + CLOSE_DISPS(play->state.gfxCtx); + } + + // @recomp Manual relocations, TODO remove when automated. + s16 D_80AAAE20_val = *(s16*)actor_relocate(thisx, &D_80AAAE20); + s16 D_80AAAE22_val = *(s16*)actor_relocate(thisx, &D_80AAAE22); + s16 D_80AAAE24_val = *(s16*)actor_relocate(thisx, &D_80AAAE24); + + if (D_80AAAE24_val != 0) { + if ((D_80AAAE22_val > -1800) && (D_80AAAE22_val < 3000)) { + temp_f12 = D_80AAAE22_val - 640.0f; + if ((D_80AAAE20_val == 380) && (D_80AAAE22_val > 640)) { + D_80AAAAC0 = 2; + D_80AAAAC4 = 0; + D_80AAAAC8 = 900; + D_80AAAACC = 700; + spB7 = true; + if (D_80AAAE22_val < 1350) { + f32 temp_f0 = temp_f12 / 2000.0f; + + D_80AAAAB8 = 420.0f - (420.0f * temp_f0); + D_80AAAABC = (200.0f * temp_f0) + 200.0f; + } else { + f32 temp_f0 = temp_f12 / 2000.0f; + + D_80AAAAB8 = 420.0f - (420.0f * temp_f0); + D_80AAAABC = 400.0f; + } + } + } + + if (spB7) { + for (i = 0; i < D_80AAAAC0 * 2; i++) { + Vec3f sp44; + f32 phi_f2 = D_80AAAABC; + s16 temp; + + spBC = Rand_ZeroOne() * D_80AAAAC8; + if ((play->state.frames % 2) != 0) { + sp44.x = (Rand_ZeroOne() - 0.5f) * (2.0f * phi_f2); + sp44.y = D_80AAAAB8; + sp44.z = (Rand_ZeroOne() * D_80AAAAC4) + phi_f2; + temp = (s16)spBC + D_80AAAACC; + EffectSsGSplash_Spawn(play, &sp44, NULL, NULL, 0, temp); + } else { + sp44.x = -phi_f2 - (Rand_ZeroOne() * D_80AAAAC4); + sp44.y = D_80AAAAB8; + sp44.z = (Rand_ZeroOne() - 0.5f) * (2.0f * phi_f2); + temp = (s16)spBC + D_80AAAACC; + EffectSsGSplash_Spawn(play, &sp44, NULL, NULL, 0, temp); + } + } + } + } + + Gfx_DrawDListXlu(play, gWoodfallSceneryTempleEntrancesDL); + break; + + case DMCHAR01_3: + if (thisx->world.pos.y > -120.0f) { + Gfx_DrawDListOpa(play, gWoodfallSceneryTempleRampAndPlatformDL); + } + break; + } +} diff --git a/patches/transform_ids.h b/patches/transform_ids.h index 4688b57..0562b73 100644 --- a/patches/transform_ids.h +++ b/patches/transform_ids.h @@ -17,10 +17,13 @@ #define SOARING_WINGS_TRANSFORM_ID 0x300U #define SOARING_CAPSULE_TRANSFORM_ID 0x301U +#define SOARING_LENS_FLARE_TRANSFORM_ID 0x302U #define BOWSTRING_TRANSFORM_ID 0x400U #define HOOKSHOT_RETICLE_TRANSFORM_ID 0x401U +#define CUSTOM_LENS_FLARE_TRANSFORM_ID_START 0x500 // Count: 2 +#define SUN_LENS_FLARE_TRANSFORM_ID 0x502 // Count: 1 #define GOHT_ROCKS_TRANSFORM_ID_START 0x600U // Count: 0x200 #define SPECIAL_EFFECTS_TRANSFORM_ID_START 0x800U