ovl obj raillift OK and Mostly Documented (#201)

* First pass: matched everything with data

* Better matching of data and ObjRaillift_Init

* Documented

* Added clarifying comment

* Change 0 and 1 to false and true for isColorful

* PR Comments

* PR name suggestions

Co-authored-by: Derek Hensley <d.hensley@tempered.io>
This commit is contained in:
Derek Hensley 2021-07-14 21:06:37 -07:00 committed by GitHub
parent 1d350f1bad
commit 0b6aa837d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 308 additions and 32 deletions

View File

@ -4207,9 +4207,9 @@ SECTIONS
ovl_Obj_Raillift : AT(RomLocation) ovl_Obj_Raillift : AT(RomLocation)
{ {
build/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.o(.text) build/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.o(.text)
build/asm/overlays/ovl_Obj_Raillift_data.o(.data) build/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.o(.data)
build/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.o(.rodata) build/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.o(.rodata)
build/asm/overlays/ovl_Obj_Raillift_rodata.o(.rodata) build/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift_overlay.o(.ovl)
} }
SegmentEnd = .; SegmentEnd = .;
SegmentSize = SegmentEnd - SegmentStart; SegmentSize = SegmentEnd - SegmentStart;

View File

@ -573,6 +573,13 @@ D_06001C60 = 0x06001C60;
D_06000D78 = 0x06000D78; D_06000D78 = 0x06000D78;
D_06000C80 = 0x06000C80; D_06000C80 = 0x06000C80;
/* z_obj_raillift */
D_06004FF8 = 0x06004FF8;
D_060048D0 = 0x060048D0;
D_06004BF0 = 0x06004BF0;
D_060071B8 = 0x060071B8;
D_06000208 = 0x06000208;
/* z_obj_tokei_step */ /* z_obj_tokei_step */
D_06000088 = 0x06000088; D_06000088 = 0x06000088;
D_06000968 = 0x06000968; D_06000968 = 0x06000968;

View File

@ -1,3 +1,9 @@
/*
* File: z_obj_raillift.c
* Overlay: Obj_Raillift
* Description: Moving Deku Flower Platform and OOT Water Temple Waterfall Platform
*/
#include "z_obj_raillift.h" #include "z_obj_raillift.h"
#define FLAGS 0x00000010 #define FLAGS 0x00000010
@ -9,7 +15,23 @@ void ObjRaillift_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjRaillift_Update(Actor* thisx, GlobalContext* globalCtx); void ObjRaillift_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjRaillift_Draw(Actor* thisx, GlobalContext* globalCtx); void ObjRaillift_Draw(Actor* thisx, GlobalContext* globalCtx);
/* void ObjRaillift_DrawDekuFlowerPlatformColorful(Actor* thisx, GlobalContext* globalCtx);
void ObjRaillift_DrawDekuFlowerPlatform(Actor* thisx, GlobalContext* globalCtx);
void ObjRaillift_DoNothing(ObjRaillift* this, GlobalContext* globalCtx);
void ObjRaillift_Idle(ObjRaillift* this, GlobalContext* globalCtx);
void ObjRaillift_UpdatePosition(ObjRaillift* this, s32 arg1);
void ObjRaillift_StartCutscene(ObjRaillift* this, GlobalContext* globalCtx);
void ObjRaillift_Teleport(ObjRaillift* this, GlobalContext* globalCtx);
void ObjRaillift_Wait(ObjRaillift* this, GlobalContext* globalCtx);
void ObjRaillift_Move(ObjRaillift* this, GlobalContext* globalCtx);
extern CollisionHeader D_06004FF8;
extern CollisionHeader D_060048D0;
extern Gfx D_06004BF0[];
extern Gfx D_06000208[];
extern Gfx D_060071B8[];
const ActorInit Obj_Raillift_InitVars = { const ActorInit Obj_Raillift_InitVars = {
ACTOR_OBJ_RAILLIFT, ACTOR_OBJ_RAILLIFT,
ACTORCAT_BG, ACTORCAT_BG,
@ -21,30 +43,249 @@ const ActorInit Obj_Raillift_InitVars = {
(ActorFunc)ObjRaillift_Update, (ActorFunc)ObjRaillift_Update,
(ActorFunc)ObjRaillift_Draw, (ActorFunc)ObjRaillift_Draw,
}; };
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),
};
static CollisionHeader* sColHeaders[] = { &D_06004FF8, &D_060048D0 };
void ObjRaillift_UpdatePosition(ObjRaillift* this, s32 idx) {
Math_Vec3s_ToVec3f(&this->dyna.actor.world.pos, &this->points[idx]);
}
void ObjRaillift_Init(Actor* thisx, GlobalContext* globalCtx) {
ObjRaillift* this = THIS;
s32 pad;
Path* path;
s32 type = OBJRAILLIFT_GET_TYPE(thisx);
s32 isColorful = false;
Actor_ProcessInitChain(thisx, sInitChain);
thisx->shape.rot.x = 0;
thisx->world.rot.x = 0;
thisx->shape.rot.z = 0;
thisx->world.rot.z = 0;
BcCheck3_BgActorInit(&this->dyna, 1);
BgCheck3_LoadMesh(globalCtx, &this->dyna, sColHeaders[type]);
this->speed = OBJRAILLIFT_GET_SPEED(thisx);
if (this->speed < 0.0f) {
this->speed = -this->speed;
isColorful = true;
}
if (type == DEKU_FLOWER_PLATFORM) {
Actor_SpawnWithParent(&globalCtx->actorCtx, thisx, globalCtx, ACTOR_OBJ_ETCETERA, thisx->world.pos.x,
thisx->world.pos.y, thisx->world.pos.z, thisx->shape.rot.x, thisx->shape.rot.y,
thisx->shape.rot.z, 0);
if (isColorful) {
thisx->draw = ObjRaillift_DrawDekuFlowerPlatformColorful;
} else {
thisx->draw = ObjRaillift_DrawDekuFlowerPlatform;
}
}
if (this->speed < 0.01f) {
this->actionFunc = ObjRaillift_DoNothing;
} else {
path = &globalCtx->setupPathList[OBJRAILLIFT_GET_PATH(thisx)];
this->curPoint = OBJRAILLIFT_GET_STARTING_POINT(thisx);
this->endPoint = path->count - 1;
this->direction = 1;
this->points = (Vec3s*)Lib_SegmentedToVirtual(path->points);
ObjRaillift_UpdatePosition(this, this->curPoint);
if (OBJRAILLIFT_HAS_FLAG(thisx) && !Flags_GetSwitch(globalCtx, OBJRAILLIFT_GET_FLAG(thisx))) {
this->actionFunc = ObjRaillift_Idle;
} else {
this->actionFunc = ObjRaillift_Move;
}
}
}
void ObjRaillift_Destroy(Actor* thisx, GlobalContext* globalCtx) {
ObjRaillift* this = THIS;
BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
}
void ObjRaillift_DoNothing(ObjRaillift* this, GlobalContext* globalCtx) {
}
void ObjRaillift_Move(ObjRaillift* this, GlobalContext* globalCtx) {
s32 isTeleporting;
Vec3f nextPoint;
f32 speed;
f32 target;
f32 step;
s32 isPosUpdated;
Vec3s* initialPoint;
Vec3s* endPoint;
s32 pad;
if (OBJRAILLIFT_HAS_FLAG(&this->dyna.actor)) {
if (!Flags_GetSwitch(globalCtx, OBJRAILLIFT_GET_FLAG(&this->dyna.actor))) {
this->actionFunc = ObjRaillift_Idle;
return;
}
if (OBJRAILLIFT_GET_TYPE(&this->dyna.actor) == DEKU_FLOWER_PLATFORM) {
func_800B9010(&this->dyna.actor, NA_SE_EV_PLATE_LIFT_LEVEL - SFX_FLAG);
}
}
Math_Vec3s_ToVec3f(&nextPoint, &(&this->points[this->curPoint])[this->direction]);
Math_Vec3f_Diff(&nextPoint, &this->dyna.actor.world.pos, &this->dyna.actor.velocity);
speed = Math3D_Vec3fMagnitude(&this->dyna.actor.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(&this->dyna.actor.speedXZ, target, step);
if ((this->dyna.actor.speedXZ + 0.05f) < speed) {
Math_Vec3f_Scale(&this->dyna.actor.velocity, this->dyna.actor.speedXZ / speed);
this->dyna.actor.world.pos.x += this->dyna.actor.velocity.x;
this->dyna.actor.world.pos.y += this->dyna.actor.velocity.y;
this->dyna.actor.world.pos.z += this->dyna.actor.velocity.z;
} else {
this->curPoint += this->direction;
if (1) {}
this->dyna.actor.speedXZ *= 0.4f;
isTeleporting = OBJRAILLIFT_SHOULD_TELEPORT(&this->dyna.actor);
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 = ObjRaillift_Wait;
} else {
endPoint = &this->points[this->endPoint];
this->curPoint = this->direction > 0 ? 0 : this->endPoint;
initialPoint = &this->points[0];
if ((initialPoint->x != endPoint->x) || (initialPoint->y != endPoint->y) || (initialPoint->z != endPoint->z)) {
this->actionFunc = ObjRaillift_Teleport;
func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
isPosUpdated = false;
}
}
}
if (isPosUpdated) {
ObjRaillift_UpdatePosition(this, this->curPoint);
}
}
}
/*
Will teleport to what ever curpoint is set to
*/ */
void ObjRaillift_Teleport(ObjRaillift* this, GlobalContext* globalCtx) {
if (!func_800CAF70(&this->dyna)) {
ObjRaillift_UpdatePosition(this, this->curPoint);
func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
this->actionFunc = ObjRaillift_Move;
}
}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Raillift_0x80A19910/func_80A19910.asm") void ObjRaillift_Wait(ObjRaillift* this, GlobalContext* globalCtx) {
this->waitTimer--;
if (this->waitTimer <= 0) {
this->actionFunc = ObjRaillift_Move;
this->dyna.actor.speedXZ = 0.0f;
}
}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Raillift_0x80A19910/ObjRaillift_Init.asm") void ObjRaillift_Idle(ObjRaillift* this, GlobalContext* globalCtx) {
if (Flags_GetSwitch(globalCtx, OBJRAILLIFT_GET_FLAG(&this->dyna.actor))) {
this->dyna.actor.speedXZ = 0.0f;
ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene);
this->actionFunc = ObjRaillift_StartCutscene;
}
}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Raillift_0x80A19910/ObjRaillift_Destroy.asm") void ObjRaillift_StartCutscene(ObjRaillift* this, GlobalContext* globalCtx) {
if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) {
ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor);
this->cutsceneTimer = 50;
this->actionFunc = ObjRaillift_Move;
} else {
ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene);
}
}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Raillift_0x80A19910/func_80A19B98.asm") void ObjRaillift_Update(Actor* thisx, GlobalContext* globalCtx) {
ObjRaillift* this = THIS;
f32 target;
f32 step;
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Raillift_0x80A19910/func_80A19BA8.asm") this->actionFunc(this, globalCtx);
Actor_SetHeight(&this->dyna.actor, 10.0f);
if (this->cutsceneTimer > 0) {
this->cutsceneTimer--;
if (this->cutsceneTimer == 0) {
ActorCutscene_Stop(this->dyna.actor.cutscene);
}
}
if (OBJRAILLIFT_SHOULD_REACT_TO_WEIGHT(thisx)) {
this->isWeightOnPrev = this->isWeightOn;
if (func_800CAF70(&this->dyna)) {
this->isWeightOn = true;
} else {
this->isWeightOn = false;
}
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;
dummy:;
}
if (OBJRAILLIFT_GET_TYPE(thisx) == DEKU_FLOWER_PLATFORM && 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;
}
}
}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Raillift_0x80A19910/func_80A19E84.asm") void ObjRaillift_Draw(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Raillift_0x80A19910/func_80A19EE0.asm") OPEN_DISPS(globalCtx->state.gfxCtx);
func_8012C28C(globalCtx->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08,
Gfx_TwoTexScrollEnvColor(globalCtx->state.gfxCtx, 0, globalCtx->gameplayFrames, 0, 32, 32, 1, 0, 0,
32, 32, 0, 0, 0, 160));
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, D_06004BF0);
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Raillift_0x80A19910/func_80A19F18.asm") /*
The non-colorful platforms are the ones found in Woodfall Temple
*/
void ObjRaillift_DrawDekuFlowerPlatform(Actor* thisx, GlobalContext* globalCtx) {
func_800BDFC0(globalCtx, D_06000208);
}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Raillift_0x80A19910/func_80A19F78.asm") /*
The colorful platforms are the ones found in Deku Palace
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Raillift_0x80A19910/ObjRaillift_Update.asm") */
void ObjRaillift_DrawDekuFlowerPlatformColorful(Actor* thisx, GlobalContext* globalCtx) {
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Raillift_0x80A19910/ObjRaillift_Draw.asm") func_800BDFC0(globalCtx, D_060071B8);
}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Raillift_0x80A19910/func_80A1A330.asm")
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Raillift_0x80A19910/func_80A1A360.asm")

View File

@ -5,9 +5,37 @@
struct ObjRaillift; struct ObjRaillift;
typedef void (*ObjRailliftActionFunc)(struct ObjRaillift*, GlobalContext*);
#define OBJRAILLIFT_GET_TYPE(thisx) (((thisx)->params >> 0xF) & 1)
#define OBJRAILLIFT_HAS_FLAG(thisx) (((thisx)->params >> 0xD) & 1)
#define OBJRAILLIFT_GET_FLAG(thisx) ((thisx)->home.rot.x & 0x7F)
#define OBJRAILLIFT_GET_PATH(thisx) ((thisx)->params & 0x7F)
#define OBJRAILLIFT_GET_STARTING_POINT(thisx) (((thisx)->params >> 7) & 0x1F)
#define OBJRAILLIFT_GET_SPEED(thisx) ((thisx)->home.rot.z * 0.1f)
#define OBJRAILLIFT_SHOULD_TELEPORT(thisx) (((thisx)->params >> 0xC) & 1)
#define OBJRAILLIFT_SHOULD_REACT_TO_WEIGHT(thisx) (((thisx)->params >> 0xE) & 1)
typedef enum {
/* 0 */ OOT_WATER_TEMPLE_WATERFALL_PLATFORM,
/* 1 */ DEKU_FLOWER_PLATFORM
} OBJRAILLIFT_TYPE;
typedef struct ObjRaillift { typedef struct ObjRaillift {
/* 0x000 */ Actor actor; /* 0x000 */ DynaPolyActor dyna;
/* 0x144 */ char unk_144[0x48]; /* 0x15C */ ObjRailliftActionFunc actionFunc;
/* 0x160 */ f32 speed;
/* 0x164 */ s32 endPoint;
/* 0x168 */ s32 curPoint;
/* 0x16C */ s32 direction; // +1 for forward, -1 for backward
/* 0x170 */ Vec3s* points;
/* 0x174 */ s32 isWeightOn;
/* 0x178 */ s32 isWeightOnPrev;
/* 0x17C */ f32 cycleSpeed;
/* 0x180 */ f32 maxHeight;
/* 0x184 */ s16 cycle;
/* 0x186 */ s16 waitTimer;
/* 0x188 */ s16 cutsceneTimer;
} ObjRaillift; // size = 0x18C } ObjRaillift; // size = 0x18C
extern const ActorInit Obj_Raillift_InitVars; extern const ActorInit Obj_Raillift_InitVars;

View File

@ -9787,19 +9787,19 @@
0x80A18DA0:("func_80A18DA0",), 0x80A18DA0:("func_80A18DA0",),
0x80A19740:("ObjFunen_Init",), 0x80A19740:("ObjFunen_Init",),
0x80A19778:("ObjFunen_Draw",), 0x80A19778:("ObjFunen_Draw",),
0x80A19910:("func_80A19910",), 0x80A19910:("ObjRaillift_UpdatePosition",),
0x80A1994C:("ObjRaillift_Init",), 0x80A1994C:("ObjRaillift_Init",),
0x80A19B64:("ObjRaillift_Destroy",), 0x80A19B64:("ObjRaillift_Destroy",),
0x80A19B98:("func_80A19B98",), 0x80A19B98:("ObjRaillift_DoNothing",),
0x80A19BA8:("func_80A19BA8",), 0x80A19BA8:("ObjRaillift_Move",),
0x80A19E84:("func_80A19E84",), 0x80A19E84:("ObjRaillift_Teleport",),
0x80A19EE0:("func_80A19EE0",), 0x80A19EE0:("ObjRaillift_Wait",),
0x80A19F18:("func_80A19F18",), 0x80A19F18:("ObjRaillift_Idle",),
0x80A19F78:("func_80A19F78",), 0x80A19F78:("ObjRaillift_StartCutscene",),
0x80A19FE0:("ObjRaillift_Update",), 0x80A19FE0:("ObjRaillift_Update",),
0x80A1A220:("ObjRaillift_Draw",), 0x80A1A220:("ObjRaillift_Draw",),
0x80A1A330:("func_80A1A330",), 0x80A1A330:("ObjRaillift_DrawDekuFlowerPlatform",),
0x80A1A360:("func_80A1A360",), 0x80A1A360:("ObjRaillift_DrawDekuFlowerPlatformColorful",),
0x80A1A500:("func_80A1A500",), 0x80A1A500:("func_80A1A500",),
0x80A1A56C:("func_80A1A56C",), 0x80A1A56C:("func_80A1A56C",),
0x80A1A750:("func_80A1A750",), 0x80A1A750:("func_80A1A750",),

View File

@ -11912,7 +11912,7 @@
0x80A1990C:("objFunenOverlayInfoOffset","u32","",0x4), 0x80A1990C:("objFunenOverlayInfoOffset","u32","",0x4),
0x80A1A390:("Obj_Raillift_InitVars","UNK_TYPE1","",0x1), 0x80A1A390:("Obj_Raillift_InitVars","UNK_TYPE1","",0x1),
0x80A1A3B0:("D_80A1A3B0","UNK_TYPE1","",0x1), 0x80A1A3B0:("D_80A1A3B0","UNK_TYPE1","",0x1),
0x80A1A3C0:("D_80A1A3C0","UNK_TYPE1","",0x1), 0x80A1A3C0:("sColHeaders","UNK_TYPE1","",0x1),
0x80A1A3C4:("D_80A1A3C4","UNK_TYPE1","",0x1), 0x80A1A3C4:("D_80A1A3C4","UNK_TYPE1","",0x1),
0x80A1A3D0:("D_80A1A3D0","f32","",0x4), 0x80A1A3D0:("D_80A1A3D0","f32","",0x4),
0x80A1A3D4:("D_80A1A3D4","f32","",0x4), 0x80A1A3D4:("D_80A1A3D4","f32","",0x4),