From 1cbf26a5d16a7207948dc00a17243710fc3d28a6 Mon Sep 17 00:00:00 2001 From: Lucas <60241136+ordlucas@users.noreply.github.com> Date: Tue, 9 Aug 2022 20:11:29 -0400 Subject: [PATCH] ovl_Obj_Danpeilift decompiled and documented (#973) * `ovl_Obj_Danpeilift` decompiled * Rename functions * Change arg1 to index * Improve ObjDanpeilift_Move match * Upcast macro --- spec | 3 +- .../ovl_Obj_Danpeilift/z_obj_danpeilift.c | 173 ++++++++++++++++-- .../ovl_Obj_Danpeilift/z_obj_danpeilift.h | 24 ++- tools/disasm/functions.txt | 10 +- 4 files changed, 184 insertions(+), 26 deletions(-) diff --git a/spec b/spec index 56aa7c21d8..4a1ecfc758 100644 --- a/spec +++ b/spec @@ -5021,8 +5021,7 @@ beginseg name "ovl_Obj_Danpeilift" compress include "build/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.o" - include "build/data/ovl_Obj_Danpeilift/ovl_Obj_Danpeilift.data.o" - include "build/data/ovl_Obj_Danpeilift/ovl_Obj_Danpeilift.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Danpeilift/ovl_Obj_Danpeilift_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.c b/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.c index fb395f8d05..be3f365e36 100644 --- a/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.c +++ b/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.c @@ -15,7 +15,12 @@ void ObjDanpeilift_Destroy(Actor* thisx, PlayState* play); void ObjDanpeilift_Update(Actor* thisx, PlayState* play); void ObjDanpeilift_Draw(Actor* thisx, PlayState* play); -#if 0 +void ObjDanpeilift_UpdatePosition(ObjDanpeilift* this, s32 index); +void ObjDanpeilift_DoNothing(ObjDanpeilift* this, PlayState* play); +void ObjDanpeilift_Move(ObjDanpeilift* this, PlayState* play); +void ObjDanpeilift_Teleport(ObjDanpeilift* this, PlayState* play); +void ObjDanpeilift_Wait(ObjDanpeilift* this, PlayState* play); + const ActorInit Obj_Danpeilift_InitVars = { ACTOR_OBJ_DANPEILIFT, ACTORCAT_BG, @@ -28,35 +33,171 @@ const ActorInit Obj_Danpeilift_InitVars = { (ActorFunc)ObjDanpeilift_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C1B540[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void ObjDanpeilift_UpdatePosition(ObjDanpeilift* this, s32 index) { + Math_Vec3s_ToVec3f(&this->dyna.actor.world.pos, &this->points[index]); +} -extern InitChainEntry D_80C1B540[]; +void ObjDanpeilift_Init(Actor* thisx, PlayState* play) { + Path* path; + ObjDanpeiliftActionFunc tempActionFunc; + ObjDanpeilift* this = THIS; -extern UNK_TYPE D_06000180; -extern UNK_TYPE D_06000BA0; + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + this->dyna.actor.shape.rot.x = 0; + this->dyna.actor.world.rot.x = 0; + this->dyna.actor.shape.rot.z = 0; + this->dyna.actor.world.rot.z = 0; + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(play, &this->dyna, &object_obj_danpeilift_Colheader_000BA0); + if (this->dyna.bgId == BG_ACTOR_MAX) { + Actor_MarkForDeath(&this->dyna.actor); + } else { + this->speed = OBJDANPEILIFT_GET_SPEED(thisx); + if (this->speed < 0.0f) { + this->speed = -this->speed; + } + if (this->speed < 0.01f) { + this->actionFunc = ObjDanpeilift_DoNothing; + } else { + path = &play->setupPathList[OBJDANPEILIFT_GET_PATH(thisx)]; + this->curPoint = OBJDANPEILIFT_GET_STARTING_POINT(thisx); + this->endPoint = path->count - 1; + this->direction = 1; + this->points = Lib_SegmentedToVirtual(path->points); + ObjDanpeilift_UpdatePosition(this, this->curPoint); + this->actionFunc = ObjDanpeilift_Move; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/func_80C1ADC0.s") +void ObjDanpeilift_Destroy(Actor* thisx, PlayState* play) { + ObjDanpeilift* this = THIS; + DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/ObjDanpeilift_Init.s") +void ObjDanpeilift_DoNothing(ObjDanpeilift* this, PlayState* play) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/ObjDanpeilift_Destroy.s") +void ObjDanpeilift_Move(ObjDanpeilift* this, PlayState* play) { + Actor* thisx = &this->dyna.actor; + Vec3f nextPoint; + f32 speed; + f32 target; + f32 step; + s32 isTeleporting; + s32 isPosUpdated; + Vec3s* endPoint; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/func_80C1AF84.s") + Math_Vec3s_ToVec3f(&nextPoint, this->points + this->curPoint + this->direction); + Math_Vec3f_Diff(&nextPoint, &thisx->world.pos, &thisx->velocity); + speed = Math3D_Vec3fMagnitude(&thisx->velocity); + if ((speed < (this->speed * 8.0f)) && (this->speed > 2.0f)) { + target = ((this->speed - 2.0f) * 0.1f) + 2.0f; + step = this->speed * 0.03f; + } else { + target = this->speed; + step = this->speed * 0.16f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/func_80C1AF94.s") + Math_StepToF(&thisx->speedXZ, target, step); + if ((thisx->speedXZ + 0.05f) < speed) { + Math_Vec3f_Scale(&thisx->velocity, thisx->speedXZ / speed); + thisx->world.pos.x += thisx->velocity.x; + thisx->world.pos.y += thisx->velocity.y; + thisx->world.pos.z += thisx->velocity.z; + } else { + this->curPoint += this->direction; + thisx->speedXZ *= 0.4f; + isTeleporting = OBJDANPEILIFT_SHOULD_TELEPORT(thisx); + isPosUpdated = true; + if (((this->curPoint >= this->endPoint) && (this->direction > 0)) || + ((this->curPoint <= 0) && (this->direction < 0))) { + if (!isTeleporting) { + this->direction = -this->direction; + this->waitTimer = 10; + this->actionFunc = ObjDanpeilift_Wait; + } else { + endPoint = &this->points[this->endPoint]; + this->curPoint = this->direction > 0 ? 0 : this->endPoint; + if ((this->points[0].x != endPoint->x) || (this->points[0].y != endPoint->y) || + (this->points[0].z != endPoint->z)) { + this->actionFunc = ObjDanpeilift_Teleport; + func_800C62BC(play, &play->colCtx.dyna, this->dyna.bgId); + isPosUpdated = false; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/func_80C1B210.s") + if (isPosUpdated) { + ObjDanpeilift_UpdatePosition(this, this->curPoint); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/func_80C1B26C.s") +void ObjDanpeilift_Teleport(ObjDanpeilift* this, PlayState* play) { + if (!DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + ObjDanpeilift_UpdatePosition(this, this->curPoint); + func_800C6314(play, &play->colCtx.dyna, this->dyna.bgId); + this->actionFunc = ObjDanpeilift_Move; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/ObjDanpeilift_Update.s") +void ObjDanpeilift_Wait(ObjDanpeilift* this, PlayState* play) { + this->waitTimer--; + if (this->waitTimer <= 0) { + this->actionFunc = ObjDanpeilift_Move; + this->dyna.actor.speedXZ = 0.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/ObjDanpeilift_Draw.s") +void ObjDanpeilift_Update(Actor* thisx, PlayState* play) { + f32 step; + ObjDanpeilift* this = THIS; + + this->actionFunc(this, play); + Actor_SetFocus(&this->dyna.actor, 10.0f); + if (this->cutsceneTimer > 0) { + this->cutsceneTimer--; + if (this->cutsceneTimer == 0) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + } + } + if (OBJDANPEILIFT_SHOULD_REACT_TO_WEIGHT(thisx)) { + f32 target; + + this->isWeightOnPrev = this->isWeightOn; + this->isWeightOn = DynaPolyActor_IsInRidingMovingState(&this->dyna) ? 1 : 0; + if ((this->isWeightOn != this->isWeightOnPrev) && (this->maxHeight < 1.0f)) { + this->cycle = -0x8000; + this->maxHeight = 6.0f; + } + this->cycle += 0xCE4; + Math_StepToF(&this->maxHeight, 0.0f, 0.12f); + step = this->isWeightOn ? Math_CosS(fabsf(this->cycleSpeed) * 2048.0f) + 0.02f + : Math_SinS(fabsf(this->cycleSpeed) * 2048.0f) + 0.02f; + target = this->isWeightOn ? -8.0f : 0.0f; + Math_StepToF(&this->cycleSpeed, target, step); + this->dyna.actor.shape.yOffset = ((Math_SinS(this->cycle) * this->maxHeight) + this->cycleSpeed) * 10.0f; + } + if ((OBJDANPEILIFT_GET_TYPE(thisx) == 1) && (this->dyna.actor.child != NULL)) { + if (this->dyna.actor.child->update == NULL) { + this->dyna.actor.child = NULL; + } else { + this->dyna.actor.child->world.pos.x = this->dyna.actor.world.pos.x; + this->dyna.actor.child->world.pos.y = + this->dyna.actor.world.pos.y + (this->dyna.actor.shape.yOffset * this->dyna.actor.scale.y); + this->dyna.actor.child->world.pos.z = this->dyna.actor.world.pos.z; + } + } +} + +void ObjDanpeilift_Draw(Actor* thisx, PlayState* play) { + Gfx_DrawDListOpa(play, object_obj_danpeilift_DL_000180); +} diff --git a/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.h b/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.h index 8b915a184c..31f6b90c4d 100644 --- a/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.h +++ b/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.h @@ -2,16 +2,34 @@ #define Z_OBJ_DANPEILIFT_H #include "global.h" +#include "objects/object_obj_danpeilift/object_obj_danpeilift.h" struct ObjDanpeilift; typedef void (*ObjDanpeiliftActionFunc)(struct ObjDanpeilift*, PlayState*); +#define OBJDANPEILIFT_GET_TYPE(thisx) (((thisx)->params >> 0xF) & 1) +#define OBJDANPEILIFT_GET_STARTING_POINT(thisx) (((thisx)->params >> 7) & 0x1F) +#define OBJDANPEILIFT_GET_PATH(thisx) ((thisx)->params & 0x7F) +#define OBJDANPEILIFT_SHOULD_TELEPORT(thisx) (((thisx)->params >> 0xC) & 1) +#define OBJDANPEILIFT_GET_SPEED(thisx) ((thisx)->home.rot.z * 0.1f) +#define OBJDANPEILIFT_SHOULD_REACT_TO_WEIGHT(thisx) (((thisx)->params >> 0xE) & 1) + typedef struct ObjDanpeilift { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x18]; + /* 0x000 */ DynaPolyActor dyna; /* 0x15C */ ObjDanpeiliftActionFunc actionFunc; - /* 0x160 */ char unk_160[0x2C]; + /* 0x160 */ f32 speed; + /* 0x164 */ s32 endPoint; + /* 0x168 */ s32 curPoint; + /* 0x16C */ s32 direction; + /* 0x170 */ Vec3s* points; + /* 0x174 */ s32 isWeightOn; + /* 0x178 */ s32 isWeightOnPrev; + /* 0x17C */ f32 cycleSpeed; + /* 0x180 */ f32 maxHeight; + /* 0x184 */ s16 cycle; + /* 0x186 */ s16 waitTimer; + /* 0x188 */ s16 cutsceneTimer; } ObjDanpeilift; // size = 0x18C extern const ActorInit Obj_Danpeilift_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 54c70c1cd0..a5c3526f0a 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -16912,13 +16912,13 @@ 0x80C1A98C:("EnInvadepohDemo_Destroy",), 0x80C1A9C0:("EnInvadepohDemo_Update",), 0x80C1A9E4:("EnInvadepohDemo_Draw",), - 0x80C1ADC0:("func_80C1ADC0",), + 0x80C1ADC0:("ObjDanpeilift_UpdatePosition",), 0x80C1ADFC:("ObjDanpeilift_Init",), 0x80C1AF50:("ObjDanpeilift_Destroy",), - 0x80C1AF84:("func_80C1AF84",), - 0x80C1AF94:("func_80C1AF94",), - 0x80C1B210:("func_80C1B210",), - 0x80C1B26C:("func_80C1B26C",), + 0x80C1AF84:("ObjDanpeilift_DoNothing",), + 0x80C1AF94:("ObjDanpeilift_Move",), + 0x80C1B210:("ObjDanpeilift_Teleport",), + 0x80C1B26C:("ObjDanpeilift_Wait",), 0x80C1B2A4:("ObjDanpeilift_Update",), 0x80C1B4E4:("ObjDanpeilift_Draw",), 0x80C1B640:("EnFall2_Init",),