ovl_Obj_Danpeilift decompiled and documented (#973)

* `ovl_Obj_Danpeilift` decompiled

* Rename functions

* Change arg1 to index

* Improve ObjDanpeilift_Move match

* Upcast macro
This commit is contained in:
Lucas 2022-08-09 20:11:29 -04:00 committed by GitHub
parent 0395b7bd4f
commit 1cbf26a5d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 184 additions and 26 deletions

3
spec
View File

@ -5021,8 +5021,7 @@ beginseg
name "ovl_Obj_Danpeilift" name "ovl_Obj_Danpeilift"
compress compress
include "build/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.o" 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/src/overlays/actors/ovl_Obj_Danpeilift/ovl_Obj_Danpeilift_reloc.o"
include "build/data/ovl_Obj_Danpeilift/ovl_Obj_Danpeilift.reloc.o"
endseg endseg
beginseg beginseg

View File

@ -15,7 +15,12 @@ void ObjDanpeilift_Destroy(Actor* thisx, PlayState* play);
void ObjDanpeilift_Update(Actor* thisx, PlayState* play); void ObjDanpeilift_Update(Actor* thisx, PlayState* play);
void ObjDanpeilift_Draw(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 = { const ActorInit Obj_Danpeilift_InitVars = {
ACTOR_OBJ_DANPEILIFT, ACTOR_OBJ_DANPEILIFT,
ACTORCAT_BG, ACTORCAT_BG,
@ -28,35 +33,171 @@ const ActorInit Obj_Danpeilift_InitVars = {
(ActorFunc)ObjDanpeilift_Draw, (ActorFunc)ObjDanpeilift_Draw,
}; };
// static InitChainEntry sInitChain[] = { static InitChainEntry sInitChain[] = {
static InitChainEntry D_80C1B540[] = {
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_CONTINUE),
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), 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; Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
extern UNK_TYPE D_06000BA0; 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);
}

View File

@ -2,16 +2,34 @@
#define Z_OBJ_DANPEILIFT_H #define Z_OBJ_DANPEILIFT_H
#include "global.h" #include "global.h"
#include "objects/object_obj_danpeilift/object_obj_danpeilift.h"
struct ObjDanpeilift; struct ObjDanpeilift;
typedef void (*ObjDanpeiliftActionFunc)(struct ObjDanpeilift*, PlayState*); 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 { typedef struct ObjDanpeilift {
/* 0x000 */ Actor actor; /* 0x000 */ DynaPolyActor dyna;
/* 0x144 */ char unk_144[0x18];
/* 0x15C */ ObjDanpeiliftActionFunc actionFunc; /* 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 } ObjDanpeilift; // size = 0x18C
extern const ActorInit Obj_Danpeilift_InitVars; extern const ActorInit Obj_Danpeilift_InitVars;

View File

@ -16912,13 +16912,13 @@
0x80C1A98C:("EnInvadepohDemo_Destroy",), 0x80C1A98C:("EnInvadepohDemo_Destroy",),
0x80C1A9C0:("EnInvadepohDemo_Update",), 0x80C1A9C0:("EnInvadepohDemo_Update",),
0x80C1A9E4:("EnInvadepohDemo_Draw",), 0x80C1A9E4:("EnInvadepohDemo_Draw",),
0x80C1ADC0:("func_80C1ADC0",), 0x80C1ADC0:("ObjDanpeilift_UpdatePosition",),
0x80C1ADFC:("ObjDanpeilift_Init",), 0x80C1ADFC:("ObjDanpeilift_Init",),
0x80C1AF50:("ObjDanpeilift_Destroy",), 0x80C1AF50:("ObjDanpeilift_Destroy",),
0x80C1AF84:("func_80C1AF84",), 0x80C1AF84:("ObjDanpeilift_DoNothing",),
0x80C1AF94:("func_80C1AF94",), 0x80C1AF94:("ObjDanpeilift_Move",),
0x80C1B210:("func_80C1B210",), 0x80C1B210:("ObjDanpeilift_Teleport",),
0x80C1B26C:("func_80C1B26C",), 0x80C1B26C:("ObjDanpeilift_Wait",),
0x80C1B2A4:("ObjDanpeilift_Update",), 0x80C1B2A4:("ObjDanpeilift_Update",),
0x80C1B4E4:("ObjDanpeilift_Draw",), 0x80C1B4E4:("ObjDanpeilift_Draw",),
0x80C1B640:("EnFall2_Init",), 0x80C1B640:("EnFall2_Init",),