diff --git a/spec b/spec index adcd5feb0a..29b59edc7c 100644 --- a/spec +++ b/spec @@ -3041,8 +3041,7 @@ beginseg name "ovl_Obj_Purify" compress include "build/src/overlays/actors/ovl_Obj_Purify/z_obj_purify.o" - include "build/data/ovl_Obj_Purify/ovl_Obj_Purify.data.o" - include "build/data/ovl_Obj_Purify/ovl_Obj_Purify.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Purify/ovl_Obj_Purify_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Obj_Purify/z_obj_purify.c b/src/overlays/actors/ovl_Obj_Purify/z_obj_purify.c index b988df8898..6255b2cbe1 100644 --- a/src/overlays/actors/ovl_Obj_Purify/z_obj_purify.c +++ b/src/overlays/actors/ovl_Obj_Purify/z_obj_purify.c @@ -5,6 +5,8 @@ */ #include "z_obj_purify.h" +#include "objects/object_numa_obj/object_numa_obj.h" +#include "objects/object_dekucity_obj/object_dekucity_obj.h" #define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) @@ -14,7 +16,31 @@ void ObjPurify_Init(Actor* thisx, PlayState* play); void ObjPurify_Destroy(Actor* thisx, PlayState* play); void ObjPurify_Update(Actor* thisx, PlayState* play); -#if 0 +void func_80A84EC0(ObjPurify* this, PlayState* play); +void func_80A851C8(Actor* thisx, PlayState* play); +void func_80A85074(ObjPurify* this, PlayState* play); +void func_80A850B0(ObjPurify* this); +void func_80A850E8(ObjPurify* this, PlayState* play); +void func_80A85304(Actor* thisx, PlayState* play); +void func_80A84FB4(ObjPurify* this, PlayState* play); +void func_80A85010(ObjPurify* this, PlayState* play); +void ObjPurify_DoNothing(ObjPurify* this, PlayState* play); +void func_80A85048(ObjPurify* this); +void func_80A84FA0(ObjPurify* this); +void func_80A8515C(ObjPurify* this); +void func_80A84FEC(ObjPurify* this); +void func_80A84EAC(ObjPurify* this); + +typedef struct ObjPurifyInfo { + /* 0x00 */ s16 objectId; + /* 0x04 */ f32 scale; + /* 0x08 */ Gfx* opaDLists[2]; + /* 0x10 */ Gfx* xluDLists[2]; + /* 0x18 */ AnimatedMaterial* animMat[2]; + /* 0x20 */ CollisionHeader* colHeader; + /* 0x24 */ s32 isDekuCity; +} ObjPurifyInfo; // size = 0x28 + const ActorInit Obj_Purify_InitVars = { ACTOR_OBJ_PURIFY, ACTORCAT_BG, @@ -27,42 +53,248 @@ const ActorInit Obj_Purify_InitVars = { (ActorFunc)NULL, }; -#endif +ObjPurifyInfo sObjPurifyInfo[] = { + { + OBJECT_NUMA_OBJ, + 0.1f, + { NULL, NULL }, + { object_numa_obj_DL_0128E0, object_numa_obj_DL_012D90 }, + { object_numa_obj_Matanimheader_012CF8, object_numa_obj_Matanimheader_0131A8 }, + &object_numa_obj_Colheader_012818, + false, + }, + { + OBJECT_DEKUCITY_OBJ, + 1.0f, + { NULL, NULL }, + { object_dekucity_obj_DL_0004E0, object_dekucity_obj_DL_001030 }, + { object_dekucity_obj_Matanimheader_000E28, object_dekucity_obj_Matanimheader_001978 }, + &object_dekucity_obj_Colheader_0002AC, + true, + }, + { + OBJECT_DEKUCITY_OBJ, + 1.0f, + { object_dekucity_obj_DL_001ED8, object_dekucity_obj_DL_003998 }, + { object_dekucity_obj_DL_001D80, NULL }, + { object_dekucity_obj_Matanimheader_003820, NULL }, + NULL, + true, + }, + { + OBJECT_NUMA_OBJ, + 0.1f, + { NULL, NULL }, + { object_numa_obj_DL_012A60, object_numa_obj_DL_012F10 }, + { object_numa_obj_Matanimheader_012B58, object_numa_obj_Matanimheader_013008 }, + &object_numa_obj_Colheader_012818, + false, + }, + { + OBJECT_NUMA_OBJ, + 0.1f, + { NULL, NULL }, + { object_numa_obj_DL_012BF0, object_numa_obj_DL_0130A0 }, + { object_numa_obj_Matanimheader_012CE8, object_numa_obj_Matanimheader_013198 }, + &object_numa_obj_Colheader_012818, + false, + }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A84CD0.s") +void ObjPurify_SetSysMatrix(f32 yPos) { + Matrix_GetCurrent()->yw = yPos; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A84CF8.s") +s32 ObjPurify_IsPurified(ObjPurify* this) { + ObjPurifyInfo* info = &sObjPurifyInfo[OBJPURIFY_GET_INFO_INDEX(&this->dyna.actor)]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/ObjPurify_Init.s") + if (!info->isDekuCity) { + // woodfall temple wood flower unraveled + if (gSaveContext.save.weekEventReg[12] & 1) { + return true; + } + } + // woodfall temple purification cutscene watched + else { + if (gSaveContext.save.weekEventReg[20] & 2) { + return true; + } + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/ObjPurify_Destroy.s") +void ObjPurify_Init(Actor* thisx, PlayState* play) { + s32 pad; + ObjPurify* this = THIS; + ObjPurifyInfo* info = &sObjPurifyInfo[OBJPURIFY_GET_INFO_INDEX(&this->dyna.actor)]; + s32 sp20 = OBJPURIFY_GET_UNK_FLAG(thisx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A84EAC.s") + Actor_SetScale(&this->dyna.actor, info->scale); + if (sp20 == 1) { + DynaPolyActor_Init(&this->dyna, 0); + } + this->objIndex = Object_GetIndex(&play->objectCtx, info->objectId); + if (this->objIndex < 0) { + Actor_MarkForDeath(&this->dyna.actor); + } else if (sp20 == 0) { + func_80A84EAC(this); + } else if (ObjPurify_IsPurified(this)) { + Actor_MarkForDeath(&this->dyna.actor); + } else { + func_80A84EAC(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A84EC0.s") +void ObjPurify_Destroy(Actor* thisx, PlayState* play) { + ObjPurify* this = THIS; + if (OBJPURIFY_GET_UNK_FLAG(&this->dyna.actor) == 1) { + DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A84FA0.s") +void func_80A84EAC(ObjPurify* this) { + this->actionFunc = func_80A84EC0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A84FB4.s") +void func_80A84EC0(ObjPurify* this, PlayState* play) { + s32 pad; + s32 sp28; + s32 index; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A84FEC.s") + if (Object_IsLoaded(&play->objectCtx, this->objIndex)) { + sp28 = OBJPURIFY_GET_UNK_FLAG(&this->dyna.actor); + index = OBJPURIFY_GET_INFO_INDEX(&this->dyna.actor); + this->dyna.actor.objBankIndex = this->objIndex; + Actor_SetObjectDependency(play, &this->dyna.actor); + if (sp28 == 1) { + DynaPolyActor_LoadMesh(play, &this->dyna, sObjPurifyInfo[index].colHeader); + func_80A84FA0(this); + } else if (ObjPurify_IsPurified(this)) { + func_80A8515C(this); + } else { + func_80A84FEC(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A85010.s") +void func_80A84FA0(ObjPurify* this) { + this->actionFunc = func_80A84FB4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A85048.s") +void func_80A84FB4(ObjPurify* this, PlayState* play) { + if (ObjPurify_IsPurified(this)) { + Actor_MarkForDeath(&this->dyna.actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A85074.s") +void func_80A84FEC(ObjPurify* this) { + this->dyna.actor.draw = func_80A851C8; + this->gfxIndex = 0; + this->actionFunc = func_80A85010; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A850B0.s") +void func_80A85010(ObjPurify* this, PlayState* play) { + if (ObjPurify_IsPurified(this)) { + func_80A85048(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A850E8.s") +void func_80A85048(ObjPurify* this) { + this->dyna.actor.draw = func_80A851C8; + this->gfxIndex = 0; + this->actionFunc = func_80A85074; + this->timer = 30; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A8515C.s") +void func_80A85074(ObjPurify* this, PlayState* play) { + this->timer--; + if (this->timer <= 0) { + func_80A850B0(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A85194.s") +void func_80A850B0(ObjPurify* this) { + f32 yPos = this->dyna.actor.home.pos.y; + this->dyna.actor.draw = func_80A85304; + this->unk168[1] = yPos - 90.0f; + this->actionFunc = func_80A850E8; + this->unk168[0] = yPos; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/ObjPurify_Update.s") +void func_80A850E8(ObjPurify* this, PlayState* play) { + Math_StepToF(&this->unk168[0], this->dyna.actor.home.pos.y - 90.0f, 0.9f); + if (Math_StepToF(&this->unk168[1], this->dyna.actor.home.pos.y, 0.9f)) { + func_80A8515C(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A851C8.s") +void func_80A8515C(ObjPurify* this) { + this->dyna.actor.flags &= ~ACTOR_FLAG_10; + this->dyna.actor.draw = func_80A851C8; + this->gfxIndex = 1; + this->actionFunc = ObjPurify_DoNothing; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Purify/func_80A85304.s") +void ObjPurify_DoNothing(ObjPurify* this, PlayState* play) { +} + +void ObjPurify_Update(Actor* thisx, PlayState* play) { + ObjPurify* this = THIS; + + this->actionFunc(this, play); +} + +void func_80A851C8(Actor* thisx, PlayState* play) { + s32 pad; + ObjPurify* this = THIS; + ObjPurifyInfo* info = &sObjPurifyInfo[OBJPURIFY_GET_INFO_INDEX(&this->dyna.actor)]; + Gfx* opaDList = info->opaDLists[this->gfxIndex]; + Gfx* xluDList = info->xluDLists[this->gfxIndex]; + AnimatedMaterial* animMat = info->animMat[this->gfxIndex]; + + OPEN_DISPS(play->state.gfxCtx); + + if (animMat != NULL) { + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(animMat)); + } + if (opaDList != NULL) { + func_8012C28C(play->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, opaDList); + } + if (xluDList != NULL) { + func_8012C2DC(play->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, xluDList); + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +void func_80A85304(Actor* thisx, PlayState* play) { + s32 pad; + ObjPurify* this = THIS; + ObjPurifyInfo* info = &sObjPurifyInfo[OBJPURIFY_GET_INFO_INDEX(&this->dyna.actor)]; + s32 sp6C[2]; + s32 i; + s32 index; + + if (this->unk168[1] < this->unk168[0]) { + sp6C[0] = 1; + sp6C[1] = 0; + } else { + sp6C[0] = 0; + sp6C[1] = 1; + } + + OPEN_DISPS(play->state.gfxCtx); + func_8012C2DC(play->state.gfxCtx); + for (i = 0; i < ARRAY_COUNT(sp6C); i++) { + index = sp6C[i]; + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(info->animMat[index])); + ObjPurify_SetSysMatrix(this->unk168[index]); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, info->xluDLists[index]); + }; + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Purify/z_obj_purify.h b/src/overlays/actors/ovl_Obj_Purify/z_obj_purify.h index 6d16baa7b3..542938c807 100644 --- a/src/overlays/actors/ovl_Obj_Purify/z_obj_purify.h +++ b/src/overlays/actors/ovl_Obj_Purify/z_obj_purify.h @@ -8,12 +8,17 @@ struct ObjPurify; typedef void (*ObjPurifyActionFunc)(struct ObjPurify*, PlayState*); typedef struct ObjPurify { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x18]; + /* 0x000 */ DynaPolyActor dyna; /* 0x15C */ ObjPurifyActionFunc actionFunc; - /* 0x160 */ char unk_160[0x10]; + /* 0x160 */ s32 gfxIndex; + /* 0x164 */ s16 timer; + /* 0x166 */ s16 objIndex; + /* 0x168 */ f32 unk168[2]; } ObjPurify; // size = 0x170 extern const ActorInit Obj_Purify_InitVars; +#define OBJPURIFY_GET_INFO_INDEX(thisx) ((thisx)->params & 0xF) +#define OBJPURIFY_GET_UNK_FLAG(thisx) (((thisx)->params >> 0xC) & 1) + #endif // Z_OBJ_PURIFY_H diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index c0846f057a..fc4e3697a2 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -11197,8 +11197,8 @@ 0x80A83FBC:("func_80A83FBC",), 0x80A84088:("func_80A84088",), 0x80A84338:("func_80A84338",), - 0x80A84CD0:("func_80A84CD0",), - 0x80A84CF8:("func_80A84CF8",), + 0x80A84CD0:("ObjPurify_SetSysMatrix",), + 0x80A84CF8:("ObjPurify_IsPurified",), 0x80A84D68:("ObjPurify_Init",), 0x80A84E68:("ObjPurify_Destroy",), 0x80A84EAC:("func_80A84EAC",), @@ -11212,7 +11212,7 @@ 0x80A850B0:("func_80A850B0",), 0x80A850E8:("func_80A850E8",), 0x80A8515C:("func_80A8515C",), - 0x80A85194:("func_80A85194",), + 0x80A85194:("ObjPurify_DoNothing",), 0x80A851A4:("ObjPurify_Update",), 0x80A851C8:("func_80A851C8",), 0x80A85304:("func_80A85304",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index f04436e7c5..280ca73650 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -12328,7 +12328,7 @@ 0x80A846A0:("D_80A846A0","f32","",0x4), 0x80A849D0:("D_80A849D0","UNK_TYPE4","",0x4), 0x80A85460:("Obj_Purify_InitVars","UNK_TYPE1","",0x1), - 0x80A85480:("D_80A85480","UNK_TYPE1","",0x1), + 0x80A85480:("ObjPurifyInfoList","UNK_TYPE1","",0x1), 0x80A854A0:("D_80A854A0","UNK_TYPE1","",0x1), 0x80A88910:("D_80A88910","UNK_TYPE1","",0x1), 0x80A88918:("D_80A88918","UNK_TYPE1","",0x1),