summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLucas <60241136+ordlucas@users.noreply.github.com>2022-08-09 20:11:29 -0400
committerGitHub <noreply@github.com>2022-08-09 20:11:29 -0400
commit1cbf26a5d16a7207948dc00a17243710fc3d28a6 (patch)
tree3469e15354b6798ffddd5417beb818d3770304d6 /src
parent0395b7bd4f1fc741b9647b5d28b725580c049962 (diff)
ovl_Obj_Danpeilift decompiled and documented (#973)
* `ovl_Obj_Danpeilift` decompiled * Rename functions * Change arg1 to index * Improve ObjDanpeilift_Move match * Upcast macro
Diffstat (limited to 'src')
-rw-r--r--src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.c195
-rw-r--r--src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.h24
2 files changed, 189 insertions, 30 deletions
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 fb395f8d0..be3f365e3 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
-
-extern InitChainEntry D_80C1B540[];
-
-extern UNK_TYPE D_06000180;
-extern UNK_TYPE D_06000BA0;
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/func_80C1ADC0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/ObjDanpeilift_Init.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/ObjDanpeilift_Destroy.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/func_80C1AF84.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/func_80C1AF94.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/func_80C1B210.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/func_80C1B26C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/ObjDanpeilift_Update.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Danpeilift/ObjDanpeilift_Draw.s")
+void ObjDanpeilift_UpdatePosition(ObjDanpeilift* this, s32 index) {
+ Math_Vec3s_ToVec3f(&this->dyna.actor.world.pos, &this->points[index]);
+}
+
+void ObjDanpeilift_Init(Actor* thisx, PlayState* play) {
+ Path* path;
+ ObjDanpeiliftActionFunc tempActionFunc;
+ ObjDanpeilift* this = THIS;
+
+ 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;
+ }
+ }
+}
+
+void ObjDanpeilift_Destroy(Actor* thisx, PlayState* play) {
+ ObjDanpeilift* this = THIS;
+ DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
+}
+
+void ObjDanpeilift_DoNothing(ObjDanpeilift* this, PlayState* play) {
+}
+
+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;
+
+ 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;
+ }
+
+ 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;
+ }
+ }
+ }
+
+ if (isPosUpdated) {
+ ObjDanpeilift_UpdatePosition(this, this->curPoint);
+ }
+ }
+}
+
+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;
+ }
+}
+
+void ObjDanpeilift_Wait(ObjDanpeilift* this, PlayState* play) {
+ this->waitTimer--;
+ if (this->waitTimer <= 0) {
+ this->actionFunc = ObjDanpeilift_Move;
+ this->dyna.actor.speedXZ = 0.0f;
+ }
+}
+
+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 8b915a184..31f6b90c4 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;