From cf3eb3b2e19bb60ec9d93b04a57127585e8ac6df Mon Sep 17 00:00:00 2001 From: engineer124 <47598039+engineer124@users.noreply.github.com> Date: Sun, 23 May 2021 01:36:21 +1000 Subject: [PATCH] Ovl_En_Fg OK (#133) * En_Fg Frogs 9/18 decompiled * En_Fg Frogs One Non-Matching * documentation and cleanup * final matched function * code_script * whitespace * Fixed some mistakes, EnFg_UpdateDust no longer matches? * fixed nonmatching * Minor fixes and documentation * PR suggestions * Fixed genericHeader rename to common * Fix Warnings * PR Good Documentation Suggestions * update names * more pr suggestions Co-authored-by: Jared Collette Co-authored-by: engineer124 --- linker_scripts/code_script.txt | 4 +- linker_scripts/object_script.txt | 20 +- src/overlays/actors/ovl_En_Fg/z_en_fg.c | 446 ++++++++++++++++++++++-- src/overlays/actors/ovl_En_Fg/z_en_fg.h | 54 ++- tables/functions.txt | 10 +- 5 files changed, 503 insertions(+), 31 deletions(-) diff --git a/linker_scripts/code_script.txt b/linker_scripts/code_script.txt index ea5ba3c72d..03f8f83f97 100644 --- a/linker_scripts/code_script.txt +++ b/linker_scripts/code_script.txt @@ -4379,9 +4379,9 @@ SECTIONS ovl_En_Fg : AT(RomLocation) { build/src/overlays/actors/ovl_En_Fg/z_en_fg.o(.text) - build/asm/overlays/ovl_En_Fg_data.o(.data) + build/src/overlays/actors/ovl_En_Fg/z_en_fg.o(.data) build/src/overlays/actors/ovl_En_Fg/z_en_fg.o(.rodata) - build/asm/overlays/ovl_En_Fg_rodata.o(.rodata) + build/src/overlays/actors/ovl_En_Fg/z_en_fg_overlay.o(.ovl) } SegmentEnd = .; SegmentSize = SegmentEnd - SegmentStart; diff --git a/linker_scripts/object_script.txt b/linker_scripts/object_script.txt index 5e02b39d5e..73233ae5f9 100644 --- a/linker_scripts/object_script.txt +++ b/linker_scripts/object_script.txt @@ -1,3 +1,4 @@ +/* gameplay_keep */ D_040008D0 = 0x040008D0; D_04029CB0 = 0x04029CB0; D_04029CF0 = 0x04029CF0; @@ -25,6 +26,14 @@ D_04076BC0 = 0x04076BC0; D_04075A40 = 0x04075A40; D_04077480 = 0x04077480; D_04075B30 = 0x04075B30; +D_0408DBE0 = 0x0408DBE0; +D_0408DFE0 = 0x0408DFE0; +D_0408E3E0 = 0x0408E3E0; +D_0408E7E0 = 0x0408E7E0; +D_0408EBE0 = 0x0408EBE0; +D_0408EFE0 = 0x0408EFE0; +D_0408F3E0 = 0x0408F3E0; +D_0408F7E0 = 0x0408F7E0; /* gameplay_dangeon_keep */ D_05018090 = 0x05018090; @@ -246,6 +255,15 @@ D_06000958 = 0x06000958; /* z_en_jc_mato */ D_06000390 = 0x06000390; +/* z_en_fg */ +D_06001534 = 0x06001534; +D_060011C0 = 0x060011C0; +D_060007BC = 0x060007BC; +D_060059A0 = 0x060059A0; +D_0600B328 = 0x0600B328; +D_0600B338 = 0x0600B338; +D_0600B538 = 0x0600B538; + /* z_bg_ladder */ D_060000A0 = 0x060000A0; D_060001D8 = 0x060001D8; @@ -265,4 +283,4 @@ D_04089070 = 0x04089070; /* z_obj_moon_stone */ D_06001C60 = 0x06001C60; D_06000D78 = 0x06000D78; -D_06000C80 = 0x06000C80; \ No newline at end of file +D_06000C80 = 0x06000C80; diff --git a/src/overlays/actors/ovl_En_Fg/z_en_fg.c b/src/overlays/actors/ovl_En_Fg/z_en_fg.c index 9112339ed6..e458e43060 100644 --- a/src/overlays/actors/ovl_En_Fg/z_en_fg.c +++ b/src/overlays/actors/ovl_En_Fg/z_en_fg.c @@ -1,3 +1,9 @@ +/* + * File: z_en_fg.c + * Overlay: En_Fg + * Description: Likely beta frogs, a version where they were all enemies + */ + #include "z_en_fg.h" #define FLAGS 0x00004209 @@ -9,7 +15,29 @@ void EnFg_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnFg_Update(Actor* thisx, GlobalContext* globalCtx); void EnFg_Draw(Actor* thisx, GlobalContext* globalCtx); -/* +void EnFg_Jump(EnFg* this, GlobalContext* globalCtx); +void EnFg_DoNothing(EnFg* this, GlobalContext* globalCtx); +void EnFg_Knockback(EnFg* this, GlobalContext* globalCtx); +void EnFg_AddDust(EnFgEffectDust* dustEffect, Vec3f* worldPos); +void EnFg_UpdateDust(EnFgEffectDust* dustEffect); +void EnFg_DrawDust(GlobalContext* globalCtx, EnFgEffectDust* dustEffect); + +extern u64 D_0408DBE0[]; // gDust1Tex +extern u64 D_0408DFE0[]; // gDust2Tex +extern u64 D_0408E3E0[]; // gDust3Tex +extern u64 D_0408E7E0[]; // gDust4Tex +extern u64 D_0408EBE0[]; // gDust5Tex +extern u64 D_0408EFE0[]; // gDust6Tex +extern u64 D_0408F3E0[]; // gDust7Tex +extern u64 D_0408F7E0[]; // gDust8Tex +extern AnimationHeader D_06001534; +extern AnimationHeader D_060011C0; +extern AnimationHeader D_060007BC; +extern Gfx* D_060059A0[]; +extern Gfx* D_0600B328[]; +extern Gfx* D_0600B338[]; +extern FlexSkeletonHeader D_0600B538; + const ActorInit En_Fg_InitVars = { ACTOR_EN_FG, ACTORCAT_NPC, @@ -21,40 +49,418 @@ const ActorInit En_Fg_InitVars = { (ActorFunc)EnFg_Update, (ActorFunc)EnFg_Draw, }; -*/ -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2D280.asm") +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT0, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0x000010AA, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, + { 8, 10, 0, { 0, 0, 0 } }, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2D348.asm") +static CollisionCheckInfoInit2 sColChkInfoInit2 = { + 1, 0, 0, 0, MASS_IMMOVABLE, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2D3D4.asm") +static DamageTable sDamageTable = { + 0x00, 0x11, 0x00, 0x01, 0x00, 0xE1, 0x11, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2D400.asm") +static EnFgAnimation sAnimations[] = { + { &D_06001534, 1.0f, 0, -1, 0, 0 }, + { &D_06001534, 1.0f, 0, -1, 0, -4 }, + { &D_060011C0, 1.0f, 0, -1, 0, -4 }, + { &D_060007BC, 1.0f, 0, -1, 2, -4 }, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2D42C.asm") +s32 EnFg_UpdateAnimation(SkelAnime* skelAnime, s16 animIndex) { + s16 frameCount; + s32 ret; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2D4B8.asm") + ret = false; + if (animIndex >= 0 && animIndex < 4) { + ret = true; + frameCount = sAnimations[animIndex].frameCount; + if (frameCount < 0) { + frameCount = SkelAnime_GetFrameCount(&sAnimations[animIndex].animationSeg->common); + } + SkelAnime_ChangeAnim(skelAnime, sAnimations[animIndex].animationSeg, sAnimations[animIndex].playbackSpeed, + sAnimations[animIndex].frame, frameCount, sAnimations[animIndex].mode, + sAnimations[animIndex].transitionRate); + } + return ret; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2D778.asm") +void func_80A2D348(EnFg* this, GlobalContext* globalCtx) { + if (this->actor.colChkInfo.health != 0) { + this->collider.dim.pos.x = this->actor.world.pos.x; + this->collider.dim.pos.y = this->actor.world.pos.y; + this->collider.dim.pos.z = this->actor.world.pos.z; + CollisionCheck_SetAC(globalCtx, &globalCtx->colCheckCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colCheckCtx, &this->collider.base); + } +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2D9CC.asm") +void func_80A2D3D4(EnFg* this, GlobalContext* globalCtx) { + SkelAnime_FrameUpdateMatrix(&this->skelAnime); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2D9DC.asm") +u8 EnFg_UpdateHealth(EnFg* this) { + if (this->actor.colChkInfo.damage >= this->actor.colChkInfo.health) { + this->actor.colChkInfo.health = 0; + } else { + this->actor.colChkInfo.health -= this->actor.colChkInfo.damage; + } + return this->actor.colChkInfo.health; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/EnFg_Init.asm") +s32 EnFg_GetDamageEffect(EnFg* this) { + s32 ret = 0; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/EnFg_Destroy.asm") + if (this->collider.base.acFlags & 2) { + switch (this->actor.colChkInfo.damageEffect) { + case 1: + ret = FG_DMGEFFECT_DEKUSTICK; + break; + case 15: + ret = FG_DMGEFFECT_HOOKSHOT; + break; + case 14: + ret = FG_DMGEFFECT_ARROW; + break; + case 3: + ret = FG_DMGEFFECT_ICEARROW; + break; + default: + ret = FG_DMGEFFECT_EXPLOSION; + break; + } + this->collider.base.acFlags &= ~2; + EnFg_UpdateHealth(this); + } + return ret; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/EnFg_Update.asm") +void EnFg_Idle(EnFg* this, GlobalContext* globalCtx) { + Actor* ac; + s16 rotY; + s16 rotX; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2DCE0.asm") + switch (EnFg_GetDamageEffect(this)) { + case FG_DMGEFFECT_DEKUSTICK: + this->actor.flags &= ~1; + Audio_PlayActorSound2(this, 0x28E4); + this->skelAnime.animPlaybackSpeed = 0.0f; + this->actor.shape.shadowDraw = NULL; + this->actor.scale.x *= 1.5f; + this->actor.scale.z *= 1.5f; + this->actor.scale.y = 0.001f; + this->actor.world.pos.y = this->actor.floorHeight + 2.0f; + this->actionFunc = EnFg_DoNothing; + break; + case FG_DMGEFFECT_HOOKSHOT: + break; + case FG_DMGEFFECT_ARROW: + this->actor.flags &= ~1; + this->skelAnime.animPlaybackSpeed = 0.0f; + rotY = this->collider.base.ac->world.rot.y; + rotX = this->collider.base.ac->world.rot.x; + this->actor.scale.x = fabsf(0.01f * Math_CosS(rotY)); + this->actor.scale.y = fabsf(0.01f * Math_CosS(rotX)); + this->actor.scale.z = fabsf(0.01f * Math_SinS(rotY)); + this->actor.scale.x = CLAMP_MIN(this->actor.scale.x, 0.001f); + this->actor.scale.y = CLAMP_MIN(this->actor.scale.y, 0.001f); + this->actor.scale.z = CLAMP_MIN(this->actor.scale.z, 0.001f); + this->actionFunc = EnFg_DoNothing; + break; + case FG_DMGEFFECT_EXPLOSION: + this->actor.flags &= ~1; + Audio_PlayActorSound2(this, 0x28E3); + if(1) {} + this->actor.params = FG_BLACK; + this->skelAnime.animPlaybackSpeed = 0.0f; + ac = this->collider.base.ac; + this->actor.world.rot.y = Math_Vec3f_Yaw(&ac->world.pos, &this->actor.world.pos); + this->actor.shape.rot = this->actor.world.rot; + this->actor.velocity.y = 10.0f; + this->actor.speedXZ = 3.0f; + this->actor.gravity = -0.8f; + this->bounceCounter = 1; + this->timer = 0; + this->actionFunc = EnFg_Knockback; + break; + default: + if (DECR(this->timer) == 0) { + Audio_PlayActorSound2(this, 0x28B1); + EnFg_UpdateAnimation(&this->skelAnime, 3); + this->actor.velocity.y = 10.0f; + this->timer = Rand_S16Offset(30, 30); + this->actionFunc = EnFg_Jump; + } + } + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2DD34.asm") +void EnFg_Jump(EnFg* this, GlobalContext* globalCtx) { + Actor* ac; + s32 pad; + s16 rotY; + s16 rotX; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/EnFg_Draw.asm") + switch (EnFg_GetDamageEffect(this)) { + case FG_DMGEFFECT_ARROW: + this->actor.flags &= ~1; + this->skelAnime.animPlaybackSpeed = 0.0f; + ac = this->collider.base.ac; + rotY = ac->world.rot.y; + rotX = ac->world.rot.x; + this->actor.scale.x = fabsf(Math_CosS(rotY) * 0.01f); + this->actor.scale.y = fabsf(Math_CosS(rotX) * 0.01f); + this->actor.scale.z = fabsf(Math_SinS(rotY) * 0.01f); + this->actor.scale.x = CLAMP_MIN(this->actor.scale.x, 0.001f); + this->actor.scale.y = CLAMP_MIN(this->actor.scale.y, 0.001f); + this->actor.scale.z = CLAMP_MIN(this->actor.scale.z, 0.001f); + this->actionFunc = EnFg_DoNothing; + break; + case FG_DMGEFFECT_HOOKSHOT: + break; + case FG_DMGEFFECT_EXPLOSION: + this->actor.flags &= ~1; + Audio_PlayActorSound2(this, 0x28E3); + EnFg_UpdateAnimation(&this->skelAnime, 0); + this->actor.params = FG_BLACK; + this->skelAnime.animPlaybackSpeed = 0.0f; + ac = this->collider.base.ac; + this->actor.world.rot.y = Math_Vec3f_Yaw(&ac->world.pos, &this->actor.world.pos); + this->actor.shape.rot = this->actor.world.rot; + this->actor.velocity.y = 10.0f; + this->actor.speedXZ = 3.0f; + this->actor.gravity = -0.8f; + this->bounceCounter = 1; + this->timer = 0; + this->actionFunc = EnFg_Knockback; + break; + default: + if (func_801378B8(&this->skelAnime, 8.0f)) { + this->skelAnime.animCurrentFrame = 8.0f; + this->skelAnime.animPlaybackSpeed = 0.0f; + } -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2DFC4.asm") + if ((this->actor.velocity.y <= 0.0f) && (this->actor.bgCheckFlags & 1)) { + EnFg_UpdateAnimation(&this->skelAnime, 0); + this->actionFunc = EnFg_Idle; + this->actor.velocity.y = 0.0f; + } else { + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } + } +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2E0A0.asm") +void EnFg_DoNothing(EnFg* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Fg_0x80A2D280/func_80A2E268.asm") +void EnFg_Knockback(EnFg* this, GlobalContext* globalCtx) { + if ((this->actor.velocity.y <= 0.0f) && (this->actor.bgCheckFlags & 1)) { + this->bounceCounter++; + if (this->bounceCounter < 4) { + this->actor.shape.rot.x += 0x1000; + this->actor.velocity.y = 10.0f / this->bounceCounter; + } else { + this->actionFunc = EnFg_DoNothing; + } + } else { + if (this->actor.bgCheckFlags & 8) { + this->actor.world.rot.y = this->actor.wallYaw; + this->actor.shape.rot = this->actor.world.rot; + } + + if (DECR(this->timer) == 0) { + EnFg_AddDust(&this->dustEffect[0], &this->actor.world.pos); + } + this->actor.shape.rot.x += 0x1000; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } +} + +void EnFg_Init(Actor* thisx, GlobalContext* globalCtx) { + EnFg* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 10.0f); + SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_0600B538, NULL, this->limbDrawTbl, this->transitionDrawTbl, 24); + EnFg_UpdateAnimation(&this->skelAnime, 0); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit2); + this->actor.flags |= 0x4000; + Actor_SetScale(&this->actor, 0.01f); + this->actor.gravity = -1.6f; + this->actionFunc = EnFg_Idle; +} + +void EnFg_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnFg* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnFg_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFg* this = THIS; + s32 flag; + s32 flagSet; + + flag = this->actor.flags; + flagSet = ((flag & 0x2000) == 0x2000); + if (1) {} + if (!flagSet) { + flagSet = ((flag & 0x8000) == 0x8000); + if (1) {} + if (!flagSet) { + this->actionFunc(this, globalCtx); + func_800B78B8(globalCtx, &this->actor, BASE_REG(16, 0), BASE_REG(16, 1), 0.0f, 5); + } + } + + func_80A2D3D4(this, globalCtx); + EnFg_UpdateDust(&this->dustEffect[0]); + func_80A2D348(this, globalCtx); +} + +s32 EnFg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnFg* this = THIS; + + if ((limbIndex == 7) || (limbIndex == 8)) { + *dList = NULL; + } + + if (this->actor.colChkInfo.health == 0) { + if ((limbIndex == 5) || (limbIndex == 9)) { + *dList = NULL; + } + } + return 0; +} + +void EnFg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnFg* this = THIS; + s16 pad; + Vec3f vec1 = { 0.0f, 0.0f, 0.0f }; + + if ((limbIndex == 7) || (limbIndex == 8)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + Matrix_Push(); + SysMatrix_NormalizeXYZ(&globalCtx->unk187FC); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, *dList); + Matrix_Pop(); + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + if (limbIndex == 4) { + SysMatrix_MultiplyVector3fByState(&vec1, &this->actor.focus.pos); + } +} + +void EnFg_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnFg* this = THIS; + s32 pad; + Color_RGBA8 envColor[] = { + { 200, 170, 0, 255 }, { 0, 170, 200, 255 }, { 210, 120, 100, 255 }, + { 120, 130, 230, 255 }, { 190, 190, 190, 255 }, { 0, 0, 0, 255 }, + }; + + Matrix_Push(); + EnFg_DrawDust(globalCtx, &this->dustEffect[0]); + Matrix_Pop(); + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + gDPPipeSync(POLY_OPA_DISP++); + gDPSetEnvColor(POLY_OPA_DISP++, envColor[this->actor.params].r, envColor[this->actor.params].g, envColor[this->actor.params].b, envColor[this->actor.params].a); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(&D_060059A0)); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(&D_060059A0)); + SkelAnime_DrawSV(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount, + EnFg_OverrideLimbDraw, EnFg_PostLimbDraw, &this->actor); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFg_AddDust(EnFgEffectDust* dustEffect, Vec3f* worldPos) { + Vec3f vel = { 0.0f, 3.0f, 0.0f }; + Vec3f unk_20 = { 0.0f, 0.0f, 0.0f }; + s32 i; + + for (i = 0; i < 10; i++, dustEffect++) { + if (!dustEffect->type) { + dustEffect->type = true; + dustEffect->timer = 16; + dustEffect->pos = *worldPos; + dustEffect->velocity = vel; + dustEffect->unk_20 = unk_20; + dustEffect->xyScale = 0.4f; + break; + } + } +} + +void EnFg_UpdateDust(EnFgEffectDust* dustEffect) { + s32 i; + + for (i = 0; i < 10; i++, dustEffect++) { + if (dustEffect->type == true) { + if (DECR(dustEffect->timer) == 0) { + dustEffect->type = false; + } + dustEffect->pos.y += dustEffect->velocity.y; + } + } +} + +u64* sDustTex[] = { + D_0408F7E0, D_0408F3E0, D_0408EFE0, D_0408EBE0, D_0408E7E0, D_0408E3E0, D_0408DFE0, D_0408DBE0, +}; + +void EnFg_DrawDust(GlobalContext* globalCtx, EnFgEffectDust* dustEffect) { + s16 i; + s16 alpha; + s16 index; + s16 firstDone = false; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < 10; i++, dustEffect++) { + if (dustEffect->type) { + if (!firstDone) { + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0); + gSPDisplayList(POLY_XLU_DISP++, D_0600B328); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, 0); + firstDone = true; + } + + if (1) {} + alpha = (255.0f / 16.0f) * dustEffect->timer; + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, alpha); + gDPPipeSync(POLY_XLU_DISP++); + SysMatrix_InsertTranslation(dustEffect->pos.x, dustEffect->pos.y, dustEffect->pos.z, MTXMODE_NEW); + SysMatrix_NormalizeXYZ(&globalCtx->unk187FC); + Matrix_Scale(dustEffect->xyScale, dustEffect->xyScale, 1.0f, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + index = 0.5f * dustEffect->timer; + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(sDustTex[index])); + gSPDisplayList(POLY_XLU_DISP++, D_0600B338); + } + } + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Fg/z_en_fg.h b/src/overlays/actors/ovl_En_Fg/z_en_fg.h index b1ffaca057..f21bace332 100644 --- a/src/overlays/actors/ovl_En_Fg/z_en_fg.h +++ b/src/overlays/actors/ovl_En_Fg/z_en_fg.h @@ -5,11 +5,59 @@ struct EnFg; +typedef void (*EnFgActionFunc)(struct EnFg*, GlobalContext*); + +// Based on the envColor data. Related to params but mostly unused. +typedef enum { + /* 0x00 */ FG_YELLOW, + /* 0x01 */ FG_CYAN, + /* 0x02 */ FG_PINK, + /* 0x03 */ FG_BLUE, + /* 0x04 */ FG_WHITE, + /* 0x05 */ FG_BLACK, // All frogs are blackened when hit by an explosion +} FrogType; + +typedef enum { + /* 0x00 */ FG_DMGEFFECT_NONE, + /* 0x01 */ FG_DMGEFFECT_EXPLOSION, // Bomb or bombchu, not powderkeg + /* 0x02 */ FG_DMGEFFECT_DEKUSTICK, + /* 0x03 */ FG_DMGEFFECT_HOOKSHOT, + /* 0x04 */ FG_DMGEFFECT_ARROW, + /* 0x05 */ FG_DMGEFFECT_ICEARROW, +} FrogDamageEffect; + +// TODO: This is a common struct and may be moved to a more global header +// Typically the frame/transition data is f32, not s16. +typedef struct { + /* 0x00 */ AnimationHeader* animationSeg; + /* 0x04 */ f32 playbackSpeed; + /* 0x08 */ s16 frame; + /* 0x0A */ s16 frameCount; + /* 0x0C */ u8 mode; + /* 0x0E */ s16 transitionRate; +} EnFgAnimation; // size = 0x10 + +typedef struct { + /* 0x0000 */ u8 type; + /* 0x0001 */ u8 timer; + /* 0x0004 */ f32 xyScale; + /* 0x0008 */ UNK_TYPE1 unk_08[0xC]; + /* 0x0014 */ Vec3f pos; + /* 0x0020 */ Vec3f unk_20; // Likely acceleration, set to 0 but unused + /* 0x002C */ Vec3f velocity; + /* 0x0038 */ UNK_TYPE1 unk_38[0x4]; +} EnFgEffectDust; // size = 0x3C + typedef struct EnFg { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x410]; + /* 0x144 */ EnFgActionFunc actionFunc; + /* 0x148 */ SkelAnime skelAnime; + /* 0x18C */ ColliderCylinder collider; + /* 0x1D8 */ Vec3s limbDrawTbl[24]; + /* 0x268 */ Vec3s transitionDrawTbl[24]; + /* 0x2F8 */ s16 timer; + /* 0x2FA */ s16 bounceCounter; + /* 0x2FC */ EnFgEffectDust dustEffect[10]; } EnFg; // size = 0x554 -extern const ActorInit En_Fg_InitVars; - #endif // Z_EN_FG_H diff --git a/tables/functions.txt b/tables/functions.txt index f2e5f4a8ab..343821ebb4 100644 --- a/tables/functions.txt +++ b/tables/functions.txt @@ -10115,12 +10115,12 @@ 0x80A2DAF4:("EnFg_Init",), 0x80A2DBE8:("EnFg_Destroy",), 0x80A2DC14:("EnFg_Update",), - 0x80A2DCE0:("func_80A2DCE0",), - 0x80A2DD34:("func_80A2DD34",), + 0x80A2DCE0:("EnFg_OverrideLimbDraw",), + 0x80A2DD34:("EnFg_PostLimbDraw",), 0x80A2DE34:("EnFg_Draw",), - 0x80A2DFC4:("func_80A2DFC4",), - 0x80A2E0A0:("func_80A2E0A0",), - 0x80A2E268:("func_80A2E268",), + 0x80A2DFC4:("EnFg_AddDust",), + 0x80A2E0A0:("EnFg_UpdateDust",), + 0x80A2E268:("EnFg_DrawDust",), 0x80A2E7A0:("DmRavine_Init",), 0x80A2E828:("DmRavine_Destroy",), 0x80A2E838:("DmRavine_DoNothing",),