From 20c999e579341d3a8196ce4e0a9766856c34edf4 Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Wed, 27 Mar 2024 18:47:47 -0400 Subject: [PATCH] Fixed some interpolation issues with Goht and Gyorg --- .../objects/object_boss03/object_boss03.h | 156 +++++ patches/specific_actor_transform_tagging.c | 570 +++++++++++++++++- patches/transform_ids.h | 3 + 3 files changed, 727 insertions(+), 2 deletions(-) create mode 100644 patches/dummy_headers/objects/object_boss03/object_boss03.h diff --git a/patches/dummy_headers/objects/object_boss03/object_boss03.h b/patches/dummy_headers/objects/object_boss03/object_boss03.h new file mode 100644 index 0000000..6338dd0 --- /dev/null +++ b/patches/dummy_headers/objects/object_boss03/object_boss03.h @@ -0,0 +1,156 @@ +// Required to include MM decomp headers without having built the repo + +#ifndef OBJECT_BOSS03_H +#define OBJECT_BOSS03_H 1 + +typedef enum GyorgLimb { + /* 0x00 */ GYORG_LIMB_NONE, + /* 0x01 */ GYORG_LIMB_ROOT, + /* 0x02 */ GYORG_LIMB_HEAD, + /* 0x03 */ GYORG_LIMB_BODY_ROOT, + /* 0x04 */ GYORG_LIMB_UPPER_TRUNK, + /* 0x05 */ GYORG_LIMB_LOWER_TRUNK, + /* 0x06 */ GYORG_LIMB_TAIL, + /* 0x07 */ GYORG_LIMB_RIGHT_FIN_ROOT, + /* 0x08 */ GYORG_LIMB_UPPER_RIGHT_FIN, + /* 0x09 */ GYORG_LIMB_LOWER_RIGHT_FIN, + /* 0x0A */ GYORG_LIMB_LEFT_FIN_ROOT, + /* 0x0B */ GYORG_LIMB_UPPER_LEFT_FIN, + /* 0x0C */ GYORG_LIMB_LOWER_LEFT_FIN, + /* 0x0D */ GYORG_LIMB_JAW_ROOT, + /* 0x0E */ GYORG_LIMB_JAW, + /* 0x0F */ GYORG_LIMB_MAX +} GyorgLimb; + +typedef enum GyorgSmallFishLimb { + /* 0x00 */ GYORG_SMALL_FISH_LIMB_NONE, + /* 0x01 */ GYORG_SMALL_FISH_LIMB_ROOT, + /* 0x02 */ GYORG_SMALL_FISH_LIMB_BODY_ROOT, + /* 0x03 */ GYORG_SMALL_FISH_LIMB_TRUNK_ROOT, + /* 0x04 */ GYORG_SMALL_FISH_LIMB_TAIL_FIN, + /* 0x05 */ GYORG_SMALL_FISH_LIMB_TRUNK, + /* 0x06 */ GYORG_SMALL_FISH_LIMB_LEFT_FIN, + /* 0x07 */ GYORG_SMALL_FISH_LIMB_DORSAL_FIN, + /* 0x08 */ GYORG_SMALL_FISH_LIMB_RIGHT_FIN, + /* 0x09 */ GYORG_SMALL_FISH_LIMB_HEAD, + /* 0x0A */ GYORG_SMALL_FISH_LIMB_MAX +} GyorgSmallFishLimb; + +extern s16 sGyorgIdleAnimFrameData[]; +extern JointIndex sGyorgIdleAnimJointIndices[]; +extern AnimationHeader gGyorgIdleAnim; +extern u64 gGyorgUnusedMajorasWrathWhipTex[]; +extern Vtx object_boss03Vtx_0001A0[]; +extern Gfx gGyorgUnusedMajorasWrathWhipDL1[]; +extern Gfx gGyorgUnusedMajorasWrathWhipDL2[]; +extern Gfx gGyorgUnusedMajorasWrathWhipDL3[]; +extern Vtx object_boss03Vtx_0002D8[]; +extern Gfx gGyorgHeadDL[]; +extern Gfx gGyorgJawDL[]; +extern Gfx gGyorgUpperLeftFinDL[]; +extern Gfx gGyorgLowerLeftFinDL[]; +extern Gfx gGyorgUpperRightFinDL[]; +extern Gfx gGyorgLowerRightFinDL[]; +extern Gfx gGyorgUpperTrunkDL[]; +extern Gfx gGyorgLowerTrunkDL[]; +extern Gfx gGyorgTailDL[]; +extern AnimatedMaterial gGyorgUnused5388TexAnim[]; +extern u64 gGyorgFinsSpikesAndJawTLUT[]; +extern u64 gGyorgSidesTLUT[]; +extern u64 gGyorgMouthAndSpikeBacksideTLUT[]; +extern u64 gGyorgBellyAndFinFleshTLUT[]; +extern u64 gGyorgEyeTex[]; +extern u64 gGyorgFinsSpikesAndJawTex[]; +extern u64 gGyorgSidesTex[]; +extern u64 gGyorgMouthAndSpikeBacksideTex[]; +extern u64 gGyorgBellyAndFinFleshTex[]; +extern u64 gGyorgHornsTeethAndClawsTex[]; +extern Vtx object_boss03Vtx_007E10[]; +extern Gfx gGyorgBubbleMaterialDL[]; +extern Gfx gGyorgBubbleModelDL[]; +extern u64 gGyorgTitleCardTex[]; +extern StandardLimb gGyorgRootLimb; +extern StandardLimb gGyorgHeadLimb; +extern StandardLimb gGyorgBodyRootLimb; +extern StandardLimb gGyorgUpperTrunkLimb; +extern StandardLimb gGyorgLowerTrunkLimb; +extern StandardLimb gGyorgTailLimb; +extern StandardLimb gGyorgRightFinRootLimb; +extern StandardLimb gGyorgUpperRightFinLimb; +extern StandardLimb gGyorgLowerRightFinLimb; +extern StandardLimb gGyorgLeftFinRootLimb; +extern StandardLimb gGyorgUpperLeftFinLimb; +extern StandardLimb gGyorgLowerLeftFinLimb; +extern StandardLimb gGyorgJawRootLimb; +extern StandardLimb gGyorgJawLimb; +extern void* gGyorgSkelLimbs[]; +extern FlexSkeletonHeader gGyorgSkel; +extern s16 sGyorgFloppingAnimFrameData[]; +extern JointIndex sGyorgFloppingAnimJointIndices[]; +extern AnimationHeader gGyorgFloppingAnim; +extern s16 sGyorgJumpingAnimFrameData[]; +extern JointIndex sGyorgJumpingAnimJointIndices[]; +extern AnimationHeader gGyorgJumpingAnim; +extern s16 sGyorgStunnedAnimFrameData[]; +extern JointIndex sGyorgStunnedAnimJointIndices[]; +extern AnimationHeader gGyorgStunnedAnim; +extern s16 sGyorgBackingUpAnimFrameData[]; +extern JointIndex sGyorgBackingUpAnimJointIndices[]; +extern AnimationHeader gGyorgBackingUpAnim; +extern s16 sGyorgFastSwimmingAnimFrameData[]; +extern JointIndex sGyorgFastSwimmingAnimJointIndices[]; +extern AnimationHeader gGyorgFastSwimmingAnim; +extern s16 sGyorgGentleSwimmingAnimFrameData[]; +extern JointIndex sGyorgGentleSwimmingAnimJointIndices[]; +extern AnimationHeader gGyorgGentleSwimmingAnim; +extern s16 sGyorgTailSweepAnimFrameData[]; +extern JointIndex sGyorgTailSweepAnimJointIndices[]; +extern AnimationHeader gGyorgTailSweepAnim; +extern s16 sGyorgCrawlingAnimFrameData[]; +extern JointIndex sGyorgCrawlingAnimJointIndices[]; +extern AnimationHeader gGyorgCrawlingAnim; +extern Vtx object_boss03Vtx_00A6E0[]; +extern Gfx gGyorgSeaweedPiece1DL[]; +extern Gfx gGyorgSeaweedPiece2DL[]; +extern Gfx gGyorgSeaweedPiece3DL[]; +extern Gfx gGyorgSeaweedPiece4DL[]; +extern Gfx gGyorgSeaweedPiece5DL[]; +extern Gfx gGyorgSeaweedTopDL[]; +extern u64 gGyorgSeaweedTopTLUT[]; +extern u64 gGyorgSeaweedTLUT[]; +extern u64 gGyorgSeaweedTopTex[]; +extern u64 gGyorgSeaweedTex[]; +extern AnimatedMaterial gGyorgUnusedBB00TexAnim[]; +extern Vtx object_boss03Vtx_00BB10[]; +extern Gfx gUnusedGyorgSmallFishHeadDL[]; +extern Gfx gUnusedGyorgSmallFishTrunkDL[]; +extern Gfx gUnusedGyorgSmallFishRightFinDL[]; +extern Gfx gUnusedGyorgSmallFishDorsalFinDL[]; +extern Gfx gUnusedGyorgSmallFishLeftFinDL[]; +extern Gfx gUnusedGyorgSmallFishTailFinDL[]; +extern u64 gUnusedGyorgSmallFishTLUT[]; +extern u64 gUnusedGyorgSmallFishTex[]; +extern Vtx object_boss03Vtx_00CA50[]; +extern Gfx gGyorgSmallFishHeadDL[]; +extern Gfx gGyorgSmallFishTrunkDL[]; +extern Gfx gGyorgSmallFishRightFinDL[]; +extern Gfx gGyorgSmallFishDorsalFinDL[]; +extern Gfx gGyorgSmallFishLeftFinDL[]; +extern Gfx gGyorgSmallFishTailFinDL[]; +extern u64 gGyorgSmallFishTLUT[]; +extern u64 gGyorgSmallFishTex[]; +extern StandardLimb gGyorgSmallFishRootLimb; +extern StandardLimb gGyorgSmallFishBodyRootLimb; +extern StandardLimb gGyorgSmallFishTrunkRootLimb; +extern StandardLimb gGyorgSmallFishTailFinLimb; +extern StandardLimb gGyorgSmallFishTrunkLimb; +extern StandardLimb gGyorgSmallFishLeftFinLimb; +extern StandardLimb gGyorgSmallFishDorsalFinLimb; +extern StandardLimb gGyorgSmallFishRightFinLimb; +extern StandardLimb gGyorgSmallFishHeadLimb; +extern void* gGyorgSmallFishSkelLimbs[]; +extern FlexSkeletonHeader gGyorgSmallFishSkel; +extern s16 sGyorgSmallFishSwimAnimFrameData[]; +extern JointIndex sGyorgSmallFishSwimAnimJointIndices[]; +extern AnimationHeader gGyorgSmallFishSwimAnim; +#endif diff --git a/patches/specific_actor_transform_tagging.c b/patches/specific_actor_transform_tagging.c index 90334cc..0c9fc8e 100644 --- a/patches/specific_actor_transform_tagging.c +++ b/patches/specific_actor_transform_tagging.c @@ -1,7 +1,10 @@ #include "patches.h" #include "transform_ids.h" #include "overlays/actors/ovl_En_Tanron2/z_en_tanron2.h" +#include "overlays/actors/ovl_Boss_03/z_boss_03.h" #include "overlays/actors/ovl_Boss_04/z_boss_04.h" +#include "overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h" +#include "overlays/actors/ovl_En_Water_Effect/z_en_water_effect.h" extern EnTanron2* D_80BB8458[82]; extern Boss04* D_80BB8450; @@ -12,6 +15,10 @@ extern Gfx gWartBubbleMaterialDL[]; extern Gfx gWartShadowMaterialDL[]; extern Gfx gEffWaterRippleDL[]; +// @recomp Tag gyorg's effects. +#define MAX_SPECIAL_EFFECTS 256 +u8 special_effect_reset_states[MAX_SPECIAL_EFFECTS]; + // @recomp Tag Wart's bubbles void EnTanron2_Draw(Actor* thisx, PlayState* play2) { PlayState* play = play2; @@ -54,8 +61,6 @@ void EnTanron2_Draw(Actor* thisx, PlayState* play2) { } } } - // @recomp Extract this actor's ID. - u32 actor_id = actor_transform_id(thisx); for (i = 0; i < ARRAY_COUNT(D_80BB8458); i++) { if (D_80BB8458_relocated[i] != NULL) { @@ -145,3 +150,564 @@ void EnTanron2_Draw(Actor* thisx, PlayState* play2) { CLOSE_DISPS(play->state.gfxCtx); } + +// @recomp Track this effect's reset state. +void Boss03_SpawnEffectWetSpot(PlayState* play, Vec3f* pos) { + s16 i; + GyorgEffect* eff = play->specialEffects; + + for (i = 0; i < GYORG_EFFECT_COUNT; i++) { + if ((eff->type == GYORG_EFFECT_NONE) || (eff->type == GYORG_EFFECT_BUBBLE)) { + eff->type = GYORG_EFFECT_WET_SPOT; + eff->pos = *pos; + eff->unk_34.x = 0.1f; + eff->unk_34.y = 0.4f; + eff->velocity = gZeroVec3f; + eff->accel = gZeroVec3f; + eff->alpha = 150; + eff->alphaDelta = Rand_ZeroFloat(4.0f) + 5.0f; + // @recomp Tag this effect as having been reset. + special_effect_reset_states[i] = true; + return; + } + + eff++; + } +} + +// @recomp Track this effect's reset state. +void Boss03_SpawnEffectDroplet(PlayState* play, Vec3f* pos) { + s16 i; + GyorgEffect* eff = play->specialEffects; + + for (i = 0; i < GYORG_EFFECT_COUNT; i++) { + if ((eff->type == GYORG_EFFECT_NONE) || (eff->type == GYORG_EFFECT_BUBBLE)) { + eff->type = GYORG_EFFECT_DROPLET; + eff->pos = *pos; + eff->velocity = gZeroVec3f; + eff->accel = gZeroVec3f; + eff->accel.y = -2.0f; + eff->unk_34.x = 0.1f; + eff->unk_34.y = 0.0f; + eff->unk_34.z = Rand_ZeroFloat(2 * M_PI); + eff->unk_02 = Rand_ZeroFloat(100.0f); + eff->velocity.x = Rand_CenteredFloat(25.0f); + eff->velocity.z = Rand_CenteredFloat(25.0f); + // @recomp Tag this effect as having been reset. + special_effect_reset_states[i] = true; + return; + } + + eff++; + } +} + +// @recomp Track this effect's reset state. +void Boss03_SpawnEffectSplash(PlayState* play, Vec3f* pos, Vec3f* velocity) { + Vec3f accel = { 0.0f, -1.0f, 0.0f }; + f32 temp_f2; + GyorgEffect* eff = play->specialEffects; + s16 i; + + for (i = 0; i < GYORG_EFFECT_COUNT; i++) { + if ((eff->type == GYORG_EFFECT_NONE) || (eff->type == GYORG_EFFECT_BUBBLE)) { + eff->type = GYORG_EFFECT_SPLASH; + eff->pos = *pos; + eff->velocity = *velocity; + eff->accel = accel; + temp_f2 = Rand_ZeroFloat(0.02f) + 0.02f; + eff->unk_34.y = temp_f2; + eff->unk_34.x = temp_f2; + eff->unk_34.z = Rand_ZeroFloat(2 * M_PI); + eff->unk_02 = Rand_ZeroFloat(100.0f); + // @recomp Tag this effect as having been reset. + special_effect_reset_states[i] = true; + return; + } + + eff++; + } +} + +// @recomp Track this effect's reset state. +void Boss03_SpawnEffectBubble(PlayState* play, Vec3f* pos) { + s16 i; + GyorgEffect* eff = play->specialEffects; + + for (i = 0; i < GYORG_EFFECT_COUNT; i++) { + if (eff->type == GYORG_EFFECT_NONE) { + eff->type = GYORG_EFFECT_BUBBLE; + eff->pos = *pos; + eff->velocity = gZeroVec3f; + eff->accel = gZeroVec3f; + eff->accel.y = 0.2f; + eff->unk_34.x = Rand_ZeroFloat(0.3f) + 0.2f; + eff->unk_02 = 0; + // @recomp Tag this effect as having been reset. + special_effect_reset_states[i] = true; + return; + } + + eff++; + } +} + +extern Gfx object_water_effect_DL_004260[]; +extern Gfx object_water_effect_DL_0042B0[]; +extern Gfx object_water_effect_DL_0042F8[]; +extern u8 gEffDust1Tex[]; + +void Boss03_SetObject(PlayState* play, s16 objectId); + +// @recomp Tag Gyorg's effects. +void Boss03_DrawEffects(PlayState* play) { + u8 flag = false; + s16 i; + GraphicsContext* gfxCtx = play->state.gfxCtx; + s32 pad; + GyorgEffect* eff = play->specialEffects; + GyorgEffect* effFirst = eff; + + OPEN_DISPS(gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + Gfx_SetupDL25_Opa(gfxCtx); + + for (i = 0; i < GYORG_EFFECT_COUNT; i++, eff++) { + if (eff->type == GYORG_EFFECT_BUBBLE) { + if (!flag) { + gSPDisplayList(POLY_OPA_DISP++, gGyorgBubbleMaterialDL); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 150, 150, 150, 0); + + flag = true; + } + + Matrix_Translate(eff->pos.x, eff->pos.y, eff->pos.z, MTXMODE_NEW); + Matrix_Scale(eff->unk_34.x, eff->unk_34.x, 1.0f, MTXMODE_APPLY); + Matrix_ReplaceRotation(&play->billboardMtxF); + + // @recomp Tag this effect and clear its reset state. + if (special_effect_reset_states[i]) { + gEXMatrixGroupDecomposed(POLY_OPA_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_ORDER_LINEAR); + } + else { + gEXMatrixGroupDecomposed(POLY_OPA_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR); + } + special_effect_reset_states[i] = false; + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gGyorgBubbleModelDL); + + // @recomp Pop the effect's matrix group. + gEXPopMatrixGroup(POLY_OPA_DISP++); + } + } + + eff = effFirst; + + Boss03_SetObject(play, OBJECT_WATER_EFFECT); + + flag = false; + + for (i = 0; i < GYORG_EFFECT_COUNT; i++, eff++) { + if ((eff->type == GYORG_EFFECT_DROPLET) || (eff->type == GYORG_EFFECT_SPLASH)) { + + if (!flag) { + POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_0); + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gEffDust1Tex)); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004260); + gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0); + + flag++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)eff->unk_40, (u8)((((void)0, eff->unk_40) + 55.0f)), 225, 150); + + Matrix_Translate(eff->pos.x, eff->pos.y, eff->pos.z, MTXMODE_NEW); + + if (eff->type == GYORG_EFFECT_DROPLET) { + Matrix_RotateYF(BINANG_TO_RAD(Camera_GetInputDirYaw(GET_ACTIVE_CAM(play))), MTXMODE_APPLY); + } else { // GYORG_EFFECT_SPLASH + Matrix_ReplaceRotation(&play->billboardMtxF); + } + + Matrix_Scale(eff->unk_34.x, eff->unk_34.y, 1.0f, MTXMODE_APPLY); + Matrix_RotateZF(eff->unk_34.z, MTXMODE_APPLY); + + // @recomp Tag this effect and clear its reset state. + if (special_effect_reset_states[i]) { + gEXMatrixGroupDecomposed(POLY_XLU_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_ORDER_LINEAR); + } + else { + gEXMatrixGroupDecomposed(POLY_XLU_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR); + } + special_effect_reset_states[i] = false; + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0042B0); + + // @recomp Pop the effect's matrix group. + gEXPopMatrixGroup(POLY_XLU_DISP++); + } + } + + eff = effFirst; + + flag = false; + + for (i = 0; i < GYORG_EFFECT_COUNT; i++, eff++) { + if (eff->type == GYORG_EFFECT_WET_SPOT) { + if (!flag) { + Gfx_SetupDL44_Xlu(gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gEffDust1Tex)); + gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004260); + + flag++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (s16)eff->unk_40, ((void)0, ((s16)eff->unk_40) + 55), 225, + eff->alpha); + + Matrix_Translate(eff->pos.x, eff->pos.y, eff->pos.z, MTXMODE_NEW); + + Matrix_Scale(eff->unk_34.x, 1.0f, eff->unk_34.x, MTXMODE_APPLY); + Matrix_RotateYF(eff->unk_34.z, MTXMODE_APPLY); + + // @recomp Tag this effect and clear its reset state. + if (special_effect_reset_states[i]) { + gEXMatrixGroupDecomposed(POLY_XLU_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_ORDER_LINEAR); + } + else { + gEXMatrixGroupDecomposed(POLY_XLU_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR); + } + special_effect_reset_states[i] = false; + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0042F8); + + // @recomp Pop the effect's matrix group. + gEXPopMatrixGroup(POLY_XLU_DISP++); + } + } + + Boss03_SetObject(play, OBJECT_BOSS03); + + CLOSE_DISPS(gfxCtx); +} + +// @recomp Tag Gyorg's water effects. +extern AnimatedMaterial object_water_effect_Matanimheader_000DE0[]; +extern AnimatedMaterial object_water_effect_Matanimheader_000E0C[]; +extern AnimatedMaterial object_water_effect_Matanimheader_000E40[]; +extern AnimatedMaterial object_water_effect_Matanimheader_000E58[]; +extern Gfx object_water_effect_DL_000730[]; +extern Gfx object_water_effect_DL_000420[]; +extern Gfx object_water_effect_DL_000A48[]; +extern Gfx object_water_effect_DL_000CD8[]; + +void func_80A5A6B8(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + EnWaterEffect* this = (EnWaterEffect*)thisx; + EnWaterEffectStruct* ptr = &this->unk_144[0]; + u8 phi_s4 = false; + s16 i; + + // @recomp Extract this actor's ID. + u32 actor_id = actor_transform_id(thisx); + + OPEN_DISPS(play->state.gfxCtx); + + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + + gDPSetEnvColor(POLY_XLU_DISP++, 165, 235, 255, 128); + + Matrix_Push(); + Matrix_Push(); + Matrix_Push(); + + if ((this->actor.params == ENWATEREFFECT_TYPE_GYORG_RIPPLES) || + (this->actor.params == ENWATEREFFECT_TYPE_GYORG_PRIMARY_SPRAY)) { + if (this->unk_E2C > 1.0f) { + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(object_water_effect_Matanimheader_000DE0)); + Matrix_Scale(this->unk_DC8[1].y, this->unk_DC8[1].z, this->unk_DC8[1].y, MTXMODE_APPLY); + + // @recomp Tag the transform. + gEXMatrixGroupDecomposed(POLY_XLU_DISP++, actor_id + 0, + G_EX_PUSH, G_MTX_MODELVIEW, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)this->unk_E2C); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_000420); + + // @recomp Pop the transform id. + gEXPopMatrixGroup(POLY_XLU_DISP++); + } + + Matrix_Pop(); + + if (this->unk_E30 > 1.0f) { + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(object_water_effect_Matanimheader_000E0C)); + Matrix_Scale(this->unk_DC8[2].y, this->unk_DC8[2].z, this->unk_DC8[2].y, MTXMODE_APPLY); + + // @recomp Tag the transform. + gEXMatrixGroupDecomposed(POLY_XLU_DISP++, actor_id + 1, + G_EX_PUSH, G_MTX_MODELVIEW, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)this->unk_E30); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_000730); + + // @recomp Pop the transform id. + gEXPopMatrixGroup(POLY_XLU_DISP++); + } + Matrix_Pop(); + } else { + Matrix_Pop(); + Matrix_Pop(); + } + + if ((this->unk_E34 > 1.0f) && (this->actor.params != ENWATEREFFECT_TYPE_GYORG_SHOCKWAVE)) { + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(object_water_effect_Matanimheader_000E40)); + Matrix_Scale(this->unk_DC8[3].y, this->unk_DC8[3].z, this->unk_DC8[3].y, MTXMODE_APPLY); + + // @recomp Tag the transform. + gEXMatrixGroupDecomposed(POLY_XLU_DISP++, actor_id + 2, + G_EX_PUSH, G_MTX_MODELVIEW, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)this->unk_E34); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_000A48); + + // @recomp Pop the transform id. + gEXPopMatrixGroup(POLY_XLU_DISP++); + } + + Matrix_Pop(); + + if ((this->actor.params == ENWATEREFFECT_TYPE_GYORG_RIPPLES) || + (this->actor.params == ENWATEREFFECT_TYPE_GYORG_SHOCKWAVE)) { + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(object_water_effect_Matanimheader_000E58)); + Matrix_Scale(this->unk_DC8[4].y, this->unk_DC8[4].z, this->unk_DC8[4].y, MTXMODE_APPLY); + + // @recomp Tag the transform. + gEXMatrixGroupDecomposed(POLY_XLU_DISP++, actor_id + 3, + G_EX_PUSH, G_MTX_MODELVIEW, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)this->unk_E38); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_000CD8); + + // @recomp Pop the transform id. + gEXPopMatrixGroup(POLY_XLU_DISP++); + } + + if (this->actor.params == ENWATEREFFECT_TYPE_GYORG_RIPPLES) { + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + + for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) { + if (ptr->unk_00 == 3) { + if (!phi_s4) { + Gfx_SetupDL44_Xlu(play->state.gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gEffDust1Tex)); + gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004260); + phi_s4++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)ptr->unk_38, (u8)(((void)0, ptr->unk_38) + 55.0f), 225, + ptr->unk_3C); + + Matrix_Translate(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW); + Matrix_Scale(ptr->unk_2C.x, 1.0f, ptr->unk_2C.x, MTXMODE_APPLY); + Matrix_RotateYF(ptr->unk_2C.z, MTXMODE_APPLY); + + // @recomp Tag the transform. + gEXMatrixGroupDecomposed(POLY_XLU_DISP++, actor_id + 4 + i, + G_EX_PUSH, G_MTX_MODELVIEW, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0042F8); + + // @recomp Pop the transform id. + gEXPopMatrixGroup(POLY_XLU_DISP++); + } + } + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +// @recomp Tag normal water effects. +void EnWaterEffect_Draw(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + GraphicsContext* gfxCtx = play->state.gfxCtx; + EnWaterEffect* this = (EnWaterEffect*)thisx; + s32 pad; + EnWaterEffectStruct* backupPtr = &this->unk_144[0]; + EnWaterEffectStruct* ptr = backupPtr; + u8 phi_s4 = false; + s16 i; + + OPEN_DISPS(gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + + // @recomp Extract this actor's ID. + u32 actor_id = actor_transform_id(thisx); + + for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) { + if ((ptr->unk_00 == 1) || (ptr->unk_00 == 2)) { + if (!phi_s4) { + POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_0); + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gEffDust1Tex)); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004260); + gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0); + phi_s4++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)ptr->unk_38, (u8)(((void)0, ptr->unk_38) + 55.0f), 225, 150); + + Matrix_Translate(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW); + + if (ptr->unk_00 == 1) { + Matrix_RotateYS(Camera_GetInputDirYaw(GET_ACTIVE_CAM(play)), MTXMODE_APPLY); + } else { + Matrix_ReplaceRotation(&play->billboardMtxF); + } + + Matrix_Scale(ptr->unk_2C.x, ptr->unk_2C.y, 1.0f, MTXMODE_APPLY); + Matrix_RotateZF(ptr->unk_2C.z, MTXMODE_APPLY); + + // @recomp Tag the transform. + gEXMatrixGroupDecomposed(POLY_XLU_DISP++, actor_id + i + 0 * (ARRAY_COUNT(this->unk_144) / 2), + G_EX_PUSH, G_MTX_MODELVIEW, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0042B0); + + // @recomp Pop the transform id. + gEXPopMatrixGroup(POLY_XLU_DISP++); + } + } + + phi_s4 = false; + ptr = backupPtr; + + for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) { + if (ptr->unk_00 == 3) { + if (!phi_s4) { + Gfx_SetupDL44_Xlu(gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gEffDust1Tex)); + gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004260); + phi_s4++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)ptr->unk_38, (u8)(((void)0, ptr->unk_38) + 55.0f), 225, + ptr->unk_3C); + + Matrix_Translate(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW); + Matrix_Scale(ptr->unk_2C.x, 1.0f, ptr->unk_2C.x, MTXMODE_APPLY); + Matrix_RotateYF(ptr->unk_2C.z, MTXMODE_APPLY); + + // @recomp Tag the transform. + gEXMatrixGroupDecomposed(POLY_XLU_DISP++, actor_id + i + 1 * (ARRAY_COUNT(this->unk_144) / 2), + G_EX_PUSH, G_MTX_MODELVIEW, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0042F8); + + // @recomp Pop the transform id. + gEXPopMatrixGroup(POLY_XLU_DISP++); + } + } + + CLOSE_DISPS(gfxCtx); +} + +extern Gfx gameplay_keep_DL_06AB30[]; +extern Gfx gGohtRockMaterialDL[]; +extern Gfx gGohtRockModelDL[]; +extern Gfx gGohtStalactiteMaterialDL[]; +extern Gfx gGohtStalactiteModelDL[]; + +// @recomp Tag Goht's rocks. +void func_80B0C398(BossHakugin* this, PlayState* play) { + BossHakuginEffect* effect; + s32 i; + + OPEN_DISPS(play->state.gfxCtx); + + gSPDisplayList(POLY_OPA_DISP++, gGohtRockMaterialDL); + for (i = 0; i < ARRAY_COUNT(this->unk_9F8); i++) { + effect = &this->unk_9F8[i]; + if ((effect->unk_18 >= 0) && (effect->unk_1A == 0)) { + Matrix_SetTranslateRotateYXZ(effect->unk_0.x, effect->unk_0.y, effect->unk_0.z, &effect->unk_1C); + Matrix_Scale(effect->unk_24, effect->unk_24, effect->unk_24, MTXMODE_APPLY); + + // @recomp Tag the transform. + gEXMatrixGroupDecomposed(POLY_OPA_DISP++, GOHT_ROCKS_TRANSFORM_ID_START + i + 0 * ARRAY_COUNT(this->unk_9F8), + G_EX_PUSH, G_MTX_MODELVIEW, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gGohtRockModelDL); + + // @recomp Pop the transform id. + gEXPopMatrixGroup(POLY_OPA_DISP++); + } + } + + gSPDisplayList(POLY_OPA_DISP++, gGohtStalactiteMaterialDL); + for (i = 0; i < ARRAY_COUNT(this->unk_9F8); i++) { + effect = &this->unk_9F8[i]; + if ((effect->unk_18 >= 0) && (effect->unk_1A == 1)) { + Matrix_SetTranslateRotateYXZ(effect->unk_0.x, effect->unk_0.y, effect->unk_0.z, &effect->unk_1C); + Matrix_Scale(effect->unk_24, effect->unk_24, effect->unk_24, MTXMODE_APPLY); + + // @recomp Tag the transform. + gEXMatrixGroupDecomposed(POLY_OPA_DISP++, GOHT_ROCKS_TRANSFORM_ID_START + i + 1 * ARRAY_COUNT(this->unk_9F8), + G_EX_PUSH, G_MTX_MODELVIEW, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gGohtStalactiteModelDL); + + // @recomp Pop the transform id. + gEXPopMatrixGroup(POLY_OPA_DISP++); + } + } + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/patches/transform_ids.h b/patches/transform_ids.h index f6ab6d3..2990615 100644 --- a/patches/transform_ids.h +++ b/patches/transform_ids.h @@ -16,6 +16,9 @@ #define PAUSE_CURSOR_TRANSFORM_ID_START 0x500U +#define GOHT_ROCKS_TRANSFORM_ID_START 0x600U // Count: 0x200 +#define SPECIAL_EFFECTS_TRANSFORM_ID_START 0x800U + #define STAR_TRANSFORM_ID_START 0x1000U #define EFFECT_TRANSFORM_ID_COUNT 0x800U