From 340462ea446bb6ddca78dad60b5997135e5dbfc8 Mon Sep 17 00:00:00 2001 From: tom-overton Date: Mon, 8 Nov 2021 01:43:35 -0800 Subject: [PATCH] Finish documentation --- .../actors/ovl_Obj_Tokeidai/z_obj_tokeidai.c | 443 ++++++++++-------- .../actors/ovl_Obj_Tokeidai/z_obj_tokeidai.h | 21 +- tools/disasm/functions.txt | 62 +-- 3 files changed, 289 insertions(+), 237 deletions(-) diff --git a/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.c b/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.c index b4c197ba19..48549c8ba1 100644 --- a/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.c +++ b/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.c @@ -1,7 +1,7 @@ /* * File: z_obj_tokeidai.c * Overlay: ovl_Obj_Tokeidai - * Description: Clock Face + * Description: Components of the Clock Tower (gears, clock face, counterweight, etc). Also used for wall clocks. */ #include "z_obj_tokeidai.h" @@ -15,42 +15,45 @@ void ObjTokeidai_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjTokeidai_Update(Actor* thisx, GlobalContext* globalCtx); void ObjTokeidai_Draw(Actor* thisx, GlobalContext* globalCtx); -void ObjTokeidai_CollapseGear(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_TransformedGearIdle(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_TransformedClockFaceFall(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_TransformedClockFaceSlideOff(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_TransformedClockIdle(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_CollapseTop(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_TransformedTopIdle(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_CollapseWalls(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_WallsIdle(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_TowerTransformationFinish(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_TowerTransformationWait(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_TowerTopFall(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_TowerRaiseFinished(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_RaiseTower(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_TowerTransformationStart(ObjTokeidai* this, GlobalContext* globalCtx); void ObjTokeidai_DoNothing(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_StaircaseIntoTowerIdle(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_TowerClockIdle(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_SmallClockIdle(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_TowerGearIdle(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_TowerTopIdle(ObjTokeidai* this, GlobalContext* globalCtx); -void ObjTokeidai_SetupTowerTransformationStart(ObjTokeidai* this); -void ObjTokeidai_DrawClock(Actor* thisx, GlobalContext* globalCtx); -void ObjTokeidai_DrawTowerTop(Actor* thisx, GlobalContext* globalCtx); -void ObjTokeidai_DrawTowerGear(Actor* thisx, GlobalContext* globalCtx); +void ObjTokeidai_TowerClock_TransformedIdle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_TowerGear_TransformedIdle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_Counterweight_TransformedIdle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_TowerClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_WallClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_TowerGear_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_Counterweight_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_Walls_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_StaircaseIntoTower_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_SetupTowerTransformation(ObjTokeidai* this); +void ObjTokeidai_Clock_Draw(Actor* thisx, GlobalContext* globalCtx); +void ObjTokeidai_Counterweight_Draw(Actor* thisx, GlobalContext* globalCtx); +void ObjTokeidai_TowerGear_Draw(Actor* thisx, GlobalContext* globalCtx); -// Silly overload defines that I'm not sure I should even be doing -#define settleTimer clockFaceAdditionalRotation -#define transformationRotationalVelocity clockFaceAdditionalRotation -#define transformationWaitTimer clockFaceAdditionalRotation -#define slidingClockFaceAngle clockFaceAdditionalRotation -#define settleAmount clockFaceRotationTimer -#define transformationRotationalAcceleration clockFaceRotationTimer -#define aerialClockFaceSpeed clockFaceRotationTimer -#define clockFaceRotationalVelocity sunMoonDiskAdditionalRotation -#define lightIntensity clockHour +// Used for regular clock functions +#define clockFaceRotationalVelocity actionVar1 +#define clockFaceRotationTimer actionVar2 +#define sunMoonDiskRotationalVelocity actionVar3 +#define clockHour actionVar4 + +// Used for regular counterweight functions +#define spotlightIntensity actionVar4 + +// Used in ObjTokeidai_TowerTransformation_FinishRaise +#define settleTimer actionVar1 +#define settleAmount actionVar2 + +// Used in ObjTokeidai_TowerTransformation_DropCounterweight +#define transformationRotationalVelocity actionVar1 +#define transformationRotationalAcceleration actionVar2 + +// Used in ObjTokeidai_TowerTransformation_Wait +#define transformationWaitTimer actionVar1 + +// Used in ObjTokeidai_TowerClock_SlideOff and ObjTokeidai_TowerClock_Fall +#define slidingClockFaceAngle actionVar1 +#define aerialClockFaceSpeed actionVar2 +#define fallingClockFaceRotationalVelocity actionVar3 const ActorInit Obj_Tokeidai_InitVars = { ACTOR_OBJ_TOKEIDAI, @@ -72,19 +75,25 @@ static InitChainEntry D_80AB49E0[] = { ICHAIN_F32(uncullZoneForward, 1100, ICHAIN_STOP), }; -extern Gfx D_06009A08[]; // central part of the tower -extern Gfx D_0600B0C0[]; // light beam -extern Gfx D_0600B208[]; // thing at the top of the tower -extern Gfx D_0600BA78[]; // gear on the side of the tower +extern Gfx D_06009A08[]; // the tower's four walls, used in Termina Field +extern Gfx D_0600B0C0[]; // spotlight emitted from the counterweight at night +extern Gfx D_0600B208[]; // the tower's counterweight +extern Gfx D_0600BA78[]; // rotating gear on the side of the tower extern Gfx D_0600BEE8[]; // clock center and "hand" -extern Gfx D_0600C368[]; // sun and moon circle +extern Gfx D_0600C368[]; // sun and moon disk extern Gfx D_0600CF28[]; // outer ring of the clock face -extern Gfx D_0600D388[]; // tower base? +extern Gfx D_0600D388[]; // unused tower wall extern Gfx D_0600D8E0[]; // empty dlist extern Gfx D_0600D8E8[]; // spiral staircase to tower interior extern Gfx D_0600E818[]; // clock tower clock face -extern Gfx D_0600F518[]; // small and very small clock face +extern Gfx D_0600F518[]; // wall clock clock face +/** + * Returns the angle necessary to show the correct side of + * the sun and moon disk based on the time of day. The actual + * angle can differ from the target angle if the disk is in + * the middle of rotating. + */ s32 ObjTokeidai_GetTargetSunMoonDiskRotation() { if (gSaveContext.isNight) { return 0x8000; @@ -98,49 +107,51 @@ void ObjTokeidai_SetupClockOrGear(ObjTokeidai* this) { currentMinute = OBJ_TOKEIDAI_GET_CURRENT_MINUTE(this); this->clockMinute = currentMinute; this->outerRingOrGearRotation = OBJ_TOKEIDAI_GET_OUTER_RING_OR_GEAR_ROTATION(currentMinute); - this->outerRingOrGearAdditionalRotation = 0x3C; + this->outerRingOrGearRotationalVelocity = 0x3C; this->outerRingOrGearRotationTimer = 0; } -void ObjTokeidai_InitClock(ObjTokeidai* this) { +void ObjTokeidai_Clock_Init(ObjTokeidai* this) { s32 currentHour; ObjTokeidai_SetupClockOrGear(this); currentHour = OBJ_TOKEIDAI_GET_CURRENT_HOUR(this); this->clockHour = currentHour; this->clockFaceRotation = OBJ_TOKEIDAI_GET_CLOCK_FACE_ROTATION(currentHour); - this->clockFaceAdditionalRotation = 0; + this->clockFaceRotationalVelocity = 0; this->clockFaceRotationTimer = 0; - this->sunMoonDiskAdditionalRotation = 0; + this->sunMoonDiskRotationalVelocity = 0; this->sunMoonDiskRotation = ObjTokeidai_GetTargetSunMoonDiskRotation(); } -void ObjTokeidai_InitTowerGear(ObjTokeidai* this, GlobalContext* globalCtx) { - this->actor.draw = ObjTokeidai_DrawTowerGear; +void ObjTokeidai_TowerGear_Init(ObjTokeidai* this, GlobalContext* globalCtx) { + this->actor.draw = ObjTokeidai_TowerGear_Draw; this->opaDList = D_0600BA78; ObjTokeidai_SetupClockOrGear(this); + if ((globalCtx->sceneNum == SCENE_CLOCKTOWER && gSaveContext.sceneSetupIndex == 2 && globalCtx->csCtx.unk_12 == 0) || (globalCtx->sceneNum == SCENE_00KEIKOKU && gSaveContext.sceneSetupIndex == 2 && globalCtx->csCtx.unk_12 == 0)) { - ObjTokeidai_SetupTowerTransformationStart(this); - } else if ((gSaveContext.day % 5 == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || gSaveContext.day % 5 >= 4) { - this->actionFunc = ObjTokeidai_TransformedGearIdle; + ObjTokeidai_SetupTowerTransformation(this); + } else if (OBJ_TOKEIDAI_IS_TRANSFORMED()) { + this->actionFunc = ObjTokeidai_TowerGear_TransformedIdle; this->actor.world.pos.y += this->actor.scale.y * 1900.0f; this->actor.shape.yOffset = 1500.0f; gSaveContext.weekEventReg[8] |= 0x40; } else { - this->actionFunc = ObjTokeidai_TowerGearIdle; + this->actionFunc = ObjTokeidai_TowerGear_Idle; } } -void ObjTokeidai_InitTowerClock(ObjTokeidai* this, GlobalContext* globalCtx) { - this->actor.draw = ObjTokeidai_DrawClock; - ObjTokeidai_InitClock(this); +void ObjTokeidai_TowerClock_Init(ObjTokeidai* this, GlobalContext* globalCtx) { + this->actor.draw = ObjTokeidai_Clock_Draw; + ObjTokeidai_Clock_Init(this); + if ((globalCtx->sceneNum == SCENE_CLOCKTOWER && gSaveContext.sceneSetupIndex == 2 && globalCtx->csCtx.unk_12 == 0) || (globalCtx->sceneNum == SCENE_00KEIKOKU && gSaveContext.sceneSetupIndex == 2 && globalCtx->csCtx.unk_12 == 0)) { - ObjTokeidai_SetupTowerTransformationStart(this); - } else if ((gSaveContext.day % 5 == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || gSaveContext.day % 5 >= 4) { + ObjTokeidai_SetupTowerTransformation(this); + } else if (OBJ_TOKEIDAI_IS_TRANSFORMED()) { this->actor.world.pos.y += (this->actor.scale.y * 5191.0f) - 50.0f; this->actor.world.pos.x += Math_SinS(this->actor.world.rot.y) * this->actor.scale.z * 1791.0f; this->actor.world.pos.z += -Math_CosS(this->actor.world.rot.y) * this->actor.scale.z * 1791.0f; @@ -149,52 +160,54 @@ void ObjTokeidai_InitTowerClock(ObjTokeidai* this, GlobalContext* globalCtx) { this->actor.home.pos = this->actor.world.pos; this->actor.home.pos.y -= 1178.0f; this->actor.home.pos.z += 13.0f; - this->actionFunc = ObjTokeidai_TransformedClockIdle; + this->actionFunc = ObjTokeidai_TowerClock_TransformedIdle; } else { - this->actionFunc = ObjTokeidai_TowerClockIdle; + this->actionFunc = ObjTokeidai_TowerClock_Idle; } } -void ObjTokeidai_InitTowerTop(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_Counterweight_Init(ObjTokeidai* this, GlobalContext* globalCtx) { s32 type; - this->actor.draw = ObjTokeidai_DrawTowerTop; + this->actor.draw = ObjTokeidai_Counterweight_Draw; this->opaDList = D_0600B208; this->xluDList = D_0600B0C0; if (gSaveContext.isNight) { - this->lightIntensity = 100; + this->spotlightIntensity = 100; } else { - this->lightIntensity = 0; + this->spotlightIntensity = 0; } + if ((globalCtx->sceneNum == SCENE_CLOCKTOWER && gSaveContext.sceneSetupIndex == 2 && globalCtx->csCtx.unk_12 == 0) || (globalCtx->sceneNum == SCENE_00KEIKOKU && gSaveContext.sceneSetupIndex == 2 && globalCtx->csCtx.unk_12 == 0)) { - this->lightIntensity = 0; - ObjTokeidai_SetupTowerTransformationStart(this); + this->spotlightIntensity = 0; + ObjTokeidai_SetupTowerTransformation(this); if (this->actor.child == NULL) { type = OBJ_TOKEIDAI_TYPE(&this->actor); - if (type == OBJ_TOKEIDAI_TYPE_TOWER_TOP_CLOCK_TOWN || type == OBJ_TOKEIDAI_TYPE_TOWER_TOP_TERMINA_FIELD) { + if (type == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_CLOCK_TOWN || + type == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD) { this->actor.child = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_HANABI, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0); } } if (this->actor.child != NULL) { - if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_TOWER_TOP_TERMINA_FIELD) { + if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD) { this->actor.child->home.rot.x = 0x384; } else { this->actor.child->home.rot.x = 0x12C; } } - } else if ((gSaveContext.day % 5 == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || gSaveContext.day % 5 >= 4) { - this->lightIntensity = 0; + } else if (OBJ_TOKEIDAI_IS_TRANSFORMED()) { + this->spotlightIntensity = 0; this->actor.world.pos.y += this->actor.scale.y * -2160.0f; this->actor.world.pos.x += Math_SinS(this->actor.world.rot.y) * this->actor.scale.z * 5400.0f; this->actor.world.pos.z += -Math_CosS(this->actor.world.rot.y) * this->actor.scale.z * 5400.0f; this->actor.shape.rot.x = -0x4000; - this->actionFunc = ObjTokeidai_TransformedTopIdle; + this->actionFunc = ObjTokeidai_Counterweight_TransformedIdle; } else { - this->actionFunc = ObjTokeidai_TowerTopIdle; + this->actionFunc = ObjTokeidai_Counterweight_Idle; } } @@ -210,13 +223,14 @@ void ObjTokeidai_Init(Actor* thisx, GlobalContext* globalCtx) { this->clockFaceZTranslation = 0; this->currentTime = gSaveContext.time; this->actor.home.rot.x = 0; + switch (OBJ_TOKEIDAI_TYPE(&this->actor)) { case OBJ_TOKEIDAI_TYPE_TOWER_GEAR_TERMINA_FIELD: Actor_SetScale(&this->actor, 0.15f); - ObjTokeidai_InitTowerGear(this, globalCtx); + ObjTokeidai_TowerGear_Init(this, globalCtx); break; case OBJ_TOKEIDAI_TYPE_TOWER_GEAR_CLOCK_TOWN: - ObjTokeidai_InitTowerGear(this, globalCtx); + ObjTokeidai_TowerGear_Init(this, globalCtx); break; case OBJ_TOKEIDAI_TYPE_UNUSED_WALL: this->opaDList = D_0600D388; @@ -224,38 +238,38 @@ void ObjTokeidai_Init(Actor* thisx, GlobalContext* globalCtx) { case OBJ_TOKEIDAI_TYPE_TOWER_WALLS_TERMINA_FIELD: Actor_SetScale(&this->actor, 1.0f); this->opaDList = D_06009A08; - this->actionFunc = ObjTokeidai_WallsIdle; + this->actionFunc = ObjTokeidai_Walls_Idle; break; case OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD: Actor_SetScale(&this->actor, 0.15f); - ObjTokeidai_InitTowerClock(this, globalCtx); + ObjTokeidai_TowerClock_Init(this, globalCtx); break; case OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_CLOCK_TOWN: - ObjTokeidai_InitTowerClock(this, globalCtx); + ObjTokeidai_TowerClock_Init(this, globalCtx); break; - case OBJ_TOKEIDAI_TYPE_SMALL_CLOCK: + case OBJ_TOKEIDAI_TYPE_WALL_CLOCK: Actor_SetScale(&this->actor, 0.02f); - this->actor.draw = ObjTokeidai_DrawClock; - ObjTokeidai_InitClock(this); - this->actionFunc = ObjTokeidai_SmallClockIdle; + this->actor.draw = ObjTokeidai_Clock_Draw; + ObjTokeidai_Clock_Init(this); + this->actionFunc = ObjTokeidai_WallClock_Idle; break; - case OBJ_TOKEIDAI_TYPE_VERY_SMALL_CLOCK: + case OBJ_TOKEIDAI_TYPE_SMALL_WALL_CLOCK: Actor_SetScale(&this->actor, 0.01f); - this->actor.draw = ObjTokeidai_DrawClock; - ObjTokeidai_InitClock(this); - this->actionFunc = ObjTokeidai_SmallClockIdle; + this->actor.draw = ObjTokeidai_Clock_Draw; + ObjTokeidai_Clock_Init(this); + this->actionFunc = ObjTokeidai_WallClock_Idle; break; - case OBJ_TOKEIDAI_TYPE_TOWER_TOP_TERMINA_FIELD: + case OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD: Actor_SetScale(&this->actor, 0.15f); - ObjTokeidai_InitTowerTop(this, globalCtx); + ObjTokeidai_Counterweight_Init(this, globalCtx); break; - case OBJ_TOKEIDAI_TYPE_TOWER_TOP_CLOCK_TOWN: - ObjTokeidai_InitTowerTop(this, globalCtx); + case OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_CLOCK_TOWN: + ObjTokeidai_Counterweight_Init(this, globalCtx); break; case OBJ_TOKEIDAI_TYPE_STAIRCASE_INTO_TOWER: this->opaDList = D_0600D8E8; this->xluDList = D_0600D8E0; - this->actionFunc = ObjTokeidai_StaircaseIntoTowerIdle; + this->actionFunc = ObjTokeidai_StaircaseIntoTower_Idle; break; } } @@ -263,7 +277,7 @@ void ObjTokeidai_Init(Actor* thisx, GlobalContext* globalCtx) { void ObjTokeidai_Destroy(Actor* thisx, GlobalContext* globalCtx) { } -void ObjTokeidai_HandleMinute(ObjTokeidai* this, s32 playSound) { +void ObjTokeidai_RotateOnMinuteChange(ObjTokeidai* this, s32 playSound) { s32 currentMinute; currentMinute = OBJ_TOKEIDAI_GET_CURRENT_MINUTE(this); @@ -271,10 +285,15 @@ void ObjTokeidai_HandleMinute(ObjTokeidai* this, s32 playSound) { if (this->outerRingOrGearRotationTimer == 8 && playSound) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_SECOND_HAND); } + if (this->outerRingOrGearRotationTimer >= 9) { - this->outerRingOrGearAdditionalRotation += 0x3C; - this->outerRingOrGearRotation += this->outerRingOrGearAdditionalRotation; + // This actually performs the rotation to the next minute + // for the outer ring or gear. + this->outerRingOrGearRotationalVelocity += 0x3C; + this->outerRingOrGearRotation += this->outerRingOrGearRotationalVelocity; } else { + // This makes the outer ring or gear wiggle in place for a bit + // before rotating to the next position. if ((this->outerRingOrGearRotationTimer & 3) == 0) { this->outerRingOrGearRotation += 0x5A; } @@ -282,19 +301,20 @@ void ObjTokeidai_HandleMinute(ObjTokeidai* this, s32 playSound) { this->outerRingOrGearRotation -= 0x5A; } } + this->outerRingOrGearRotationTimer++; if ((currentMinute == 15 && this->outerRingOrGearRotation < 0) || (currentMinute != 15 && this->outerRingOrGearRotation > OBJ_TOKEIDAI_GET_OUTER_RING_OR_GEAR_ROTATION(currentMinute))) { this->outerRingOrGearRotation = OBJ_TOKEIDAI_GET_OUTER_RING_OR_GEAR_ROTATION(currentMinute); this->clockMinute = currentMinute; - this->outerRingOrGearAdditionalRotation = 0x5A; + this->outerRingOrGearRotationalVelocity = 0x5A; this->outerRingOrGearRotationTimer = 0; } } } -void ObjTokeidai_CollapseGear(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_TowerGear_Collapse(ObjTokeidai* this, GlobalContext* globalCtx) { if ((this->actor.bgCheckFlags & 1) || this->actor.world.pos.y < 0.0f) { this->actionFunc = ObjTokeidai_DoNothing; return; @@ -305,22 +325,25 @@ void ObjTokeidai_CollapseGear(ObjTokeidai* this, GlobalContext* globalCtx) { Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); } -void ObjTokeidai_TransformedGearIdle(ObjTokeidai* this, GlobalContext* globalCtx) { - if (func_800EE29C(globalCtx, 0x84) != 0) { - if (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 2) { - this->actionFunc = ObjTokeidai_CollapseGear; - this->actor.speedXZ = this->actor.scale.y * 5.0f; - this->actor.velocity.y = 0.0f; - this->actor.minVelocityY = this->actor.scale.y * -50.0f; - this->actor.gravity = this->actor.scale.y * -5.0f; - } +void ObjTokeidai_TowerGear_TransformedIdle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (func_800EE29C(globalCtx, 0x84) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 2) { + this->actionFunc = ObjTokeidai_TowerGear_Collapse; + this->actor.speedXZ = this->actor.scale.y * 5.0f; + this->actor.velocity.y = 0.0f; + this->actor.minVelocityY = this->actor.scale.y * -50.0f; + this->actor.gravity = this->actor.scale.y * -5.0f; } } -void ObjTokeidai_TransformedClockFaceFall(ObjTokeidai* this, GlobalContext* globalCtx) { - this->actor.shape.rot.x += this->clockFaceRotationalVelocity; - if (this->clockFaceRotationalVelocity >= 0xA1) { - this->clockFaceRotationalVelocity -= 5; +/** + * This doesn't seem to be used in the final game. This, used in conjunction + * with the following function, would make the tower's clock slide off the + * tower and spin through the air. + */ +void ObjTokeidai_TowerClock_Fall(ObjTokeidai* this, GlobalContext* globalCtx) { + this->actor.shape.rot.x += this->fallingClockFaceRotationalVelocity; + if (this->fallingClockFaceRotationalVelocity >= 0xA1) { + this->fallingClockFaceRotationalVelocity -= 5; } this->actor.world.pos.z += 4.0f; Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); @@ -329,7 +352,11 @@ void ObjTokeidai_TransformedClockFaceFall(ObjTokeidai* this, GlobalContext* glob } } -void ObjTokeidai_TransformedClockFaceSlideOff(ObjTokeidai* this, GlobalContext* globalCtx) { +/** + * This doesn't seem to be used in the final game. Presumably, this would make the + * tower's clock slide off as the moon crashes into it. + */ +void ObjTokeidai_TowerClock_SlideOff(ObjTokeidai* this, GlobalContext* globalCtx) { f32 cos; f32 sin; Actor* thisx = &this->actor; @@ -340,18 +367,19 @@ void ObjTokeidai_TransformedClockFaceSlideOff(ObjTokeidai* this, GlobalContext* if (this->slidingClockFaceAngle >= 0x801) { this->aerialClockFaceSpeed += 4; } + if (this->aerialClockFaceSpeed < 0x80) { thisx->shape.rot.x = this->slidingClockFaceAngle - 0x4000; - this->clockFaceRotationalVelocity = 0x28; + this->fallingClockFaceRotationalVelocity = 0x28; } else { if (thisx->shape.rot.x < -0x1000) { - thisx->shape.rot.x += this->clockFaceRotationalVelocity; - if (this->clockFaceRotationalVelocity < 0x1E0) { - this->clockFaceRotationalVelocity += 0xA; + thisx->shape.rot.x += this->fallingClockFaceRotationalVelocity; + if (this->fallingClockFaceRotationalVelocity < 0x1E0) { + this->fallingClockFaceRotationalVelocity += 0xA; } } else { - thisx->shape.rot.x += this->clockFaceRotationalVelocity; - this->actionFunc = ObjTokeidai_TransformedClockFaceFall; + thisx->shape.rot.x += this->fallingClockFaceRotationalVelocity; + this->actionFunc = ObjTokeidai_TowerClock_Fall; thisx->minVelocityY = -7.5f; thisx->gravity = -0.75f; thisx->velocity.y = -2.0f; @@ -364,15 +392,15 @@ void ObjTokeidai_TransformedClockFaceSlideOff(ObjTokeidai* this, GlobalContext* thisx->world.pos.z = (1178.0f * sin) + (this->aerialClockFaceSpeed * cos) + thisx->home.pos.z; } -void ObjTokeidai_TransformedClockIdle(ObjTokeidai* this, GlobalContext* globalCtx) { - if (func_800EE29C(globalCtx, 0x84) != 0 && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 1) { - this->actionFunc = ObjTokeidai_TransformedClockFaceSlideOff; +void ObjTokeidai_TowerClock_TransformedIdle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (func_800EE29C(globalCtx, 0x84) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 1) { + this->actionFunc = ObjTokeidai_TowerClock_SlideOff; this->slidingClockFaceAngle = 0; this->aerialClockFaceSpeed = -0xD; } } -void ObjTokeidai_CollapseTop(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_Counterweight_Collapse(ObjTokeidai* this, GlobalContext* globalCtx) { if (this->actor.world.pos.y < 0.0f) { this->actionFunc = ObjTokeidai_DoNothing; return; @@ -381,31 +409,33 @@ void ObjTokeidai_CollapseTop(ObjTokeidai* this, GlobalContext* globalCtx) { Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); } -void ObjTokeidai_TransformedTopIdle(ObjTokeidai* this, GlobalContext* globalCtx) { - if (func_800EE29C(globalCtx, 0x84) != 0) { - if (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 3) { - this->actionFunc = ObjTokeidai_CollapseTop; - this->xRotation = 0; - this->actor.velocity.y = 0.0f; - this->actor.minVelocityY = this->actor.scale.y * -50.0f; - this->actor.gravity = this->actor.scale.y * -5.0f; - } +void ObjTokeidai_Counterweight_TransformedIdle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (func_800EE29C(globalCtx, 0x84) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 3) { + this->actionFunc = ObjTokeidai_Counterweight_Collapse; + this->xRotation = 0; + this->actor.velocity.y = 0.0f; + this->actor.minVelocityY = this->actor.scale.y * -50.0f; + this->actor.gravity = this->actor.scale.y * -5.0f; } } -void ObjTokeidai_CollapseWalls(ObjTokeidai* this, GlobalContext* globalCtx) { +/** + * This doesn't seem to be used in the final game. Presumably, this would make the walls of + * the clock tower appear to buckle as the moon crashes into it. + */ +void ObjTokeidai_Walls_Collapse(ObjTokeidai* this, GlobalContext* globalCtx) { if (this->actor.shape.rot.x < 0x4000) { this->actor.shape.rot.x += +0x28; } } -void ObjTokeidai_WallsIdle(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_Walls_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { if (func_800EE29C(globalCtx, 0x84) != 0 && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 1) { - this->actionFunc = ObjTokeidai_CollapseWalls; + this->actionFunc = ObjTokeidai_Walls_Collapse; } } -void ObjTokeidai_TowerTransformationEndCutscene(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_TowerTransformation_EndCutscene(ObjTokeidai* this, GlobalContext* globalCtx) { if (func_800EE29C(globalCtx, 0x84) != 0 && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 5) { gSaveContext.weekEventReg[8] |= 0x40; if ((globalCtx->sceneNum == SCENE_CLOCKTOWER && gSaveContext.sceneSetupIndex == 2 && @@ -429,16 +459,18 @@ void ObjTokeidai_TowerTransformationEndCutscene(ObjTokeidai* this, GlobalContext } } -void ObjTokeidai_TowerTransformationFinish(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_TowerTransformation_FinishTransformation(ObjTokeidai* this, GlobalContext* globalCtx) { s32 type; if (this->clockFaceZTranslation >= -0x13F) { + // Recess the clock face before ending the cutscene, since the Termina + // Field version of the cutscene looks right at it. this->clockFaceZTranslation -= 0xA; } else { type = OBJ_TOKEIDAI_TYPE(&this->actor); if ((type == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_CLOCK_TOWN) || (type == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD)) { - ObjTokeidai_TowerTransformationEndCutscene(this, globalCtx); + ObjTokeidai_TowerTransformation_EndCutscene(this, globalCtx); } else { this->actionFunc = ObjTokeidai_DoNothing; if (this->actor.child != NULL) { @@ -448,24 +480,25 @@ void ObjTokeidai_TowerTransformationFinish(ObjTokeidai* this, GlobalContext* glo } } -void ObjTokeidai_TowerTransformationWait(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_TowerTransformation_Wait(ObjTokeidai* this, GlobalContext* globalCtx) { if (this->transformationWaitTimer > 0) { this->transformationWaitTimer--; } else { - this->actionFunc = ObjTokeidai_TowerTransformationFinish; + this->actionFunc = ObjTokeidai_TowerTransformation_FinishTransformation; this->transformationWaitTimer = 0; } } -void ObjTokeidai_TowerTopFall(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_TowerTransformation_DropCounterweight(ObjTokeidai* this, GlobalContext* globalCtx) { this->xRotation += this->transformationRotationalVelocity; if (this->xRotation < 0x4000) { this->transformationRotationalVelocity += this->transformationRotationalAcceleration; return; } + this->transformationRotationalAcceleration = 0x14; this->xRotation = 0x4000; - switch (this->reboundCount) { + switch (this->boundCount) { case 0: Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_BOUND_0); break; @@ -476,22 +509,31 @@ void ObjTokeidai_TowerTopFall(ObjTokeidai* this, GlobalContext* globalCtx) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_BOUND_2); break; } - this->reboundCount += 1; + this->boundCount++; + if (this->transformationRotationalVelocity >= 0x191) { + // This condition is met for the first bound, causing the counterweight + // to rebound upwards quickly. this->transformationRotationalVelocity = -0xC8; } else if (this->transformationRotationalVelocity >= 0x33) { + // This condition is met for the second bound, causing the counterweight + // to rebound upwards slowly. this->transformationRotationalVelocity = -(this->transformationRotationalVelocity >> 1); } else { - this->actionFunc = ObjTokeidai_TowerTransformationWait; - this->transformationWaitTimer = 0xA; + // This condition is met for the third bound, causing the counterweight + // to stop moving. + this->actionFunc = ObjTokeidai_TowerTransformation_Wait; + this->transformationWaitTimer = 10; } } -void ObjTokeidai_TowerRaiseFinished(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_TowerTransformation_FinishRaise(ObjTokeidai* this, GlobalContext* globalCtx) { s32 type; if (this->settleTimer > 0) { - if ((this->settleTimer & 1) != 0) { + // Jiggle the parts of the tower up and down to give it the appearance + // of "settling" into place. + if (this->settleTimer & 1) { this->yTranslation = this->settleAmount + 3400; } else { this->yTranslation = 3400 - this->settleAmount; @@ -507,14 +549,14 @@ void ObjTokeidai_TowerRaiseFinished(ObjTokeidai* this, GlobalContext* globalCtx) Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_FALL); } this->yTranslation = 3400; - this->actionFunc = ObjTokeidai_TowerTopFall; + this->actionFunc = ObjTokeidai_TowerTransformation_DropCounterweight; this->transformationRotationalVelocity = 0; this->transformationRotationalAcceleration = 0xA; - this->reboundCount = 0; + this->boundCount = 0; } } -void ObjTokeidai_RaiseTower(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_TowerTransformation_RaiseTower(ObjTokeidai* this, GlobalContext* globalCtx) { s32 type; if (this->yTranslation < 3400) { @@ -531,23 +573,22 @@ void ObjTokeidai_RaiseTower(ObjTokeidai* this, GlobalContext* globalCtx) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_STOP); } this->yTranslation = 3400; - this->actionFunc = ObjTokeidai_TowerRaiseFinished; + this->actionFunc = ObjTokeidai_TowerTransformation_FinishRaise; this->settleTimer = 10; this->settleAmount = 20; } } -void ObjTokeidai_TowerTransformationStart(ObjTokeidai* this, GlobalContext* globalCtx) { - if ((func_800EE29C(globalCtx, 0x84) != 0 && - globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 4) || - ((gSaveContext.weekEventReg[8] & 0x40) != 0)) { - this->actionFunc = ObjTokeidai_RaiseTower; +void ObjTokeidai_TowerTransformation_Start(ObjTokeidai* this, GlobalContext* globalCtx) { + if ((func_800EE29C(globalCtx, 0x84) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 4) || + (gSaveContext.weekEventReg[8] & 0x40)) { + this->actionFunc = ObjTokeidai_TowerTransformation_RaiseTower; } } -void ObjTokeidai_SetupTowerTransformationStart(ObjTokeidai* this) { - this->actionFunc = ObjTokeidai_TowerTransformationStart; - this->clockFaceAdditionalRotation = 0; +void ObjTokeidai_SetupTowerTransformation(ObjTokeidai* this) { + this->actionFunc = ObjTokeidai_TowerTransformation_Start; + this->clockFaceRotationalVelocity = 0; this->clockFaceRotationTimer = 0; this->yTranslation = 0; this->xRotation = 0; @@ -557,9 +598,8 @@ void ObjTokeidai_SetupTowerTransformationStart(ObjTokeidai* this) { void ObjTokeidai_DoNothing(ObjTokeidai* this, GlobalContext* globalCtx) { } -void ObjTokeidai_StaircaseIntoTowerIdle(ObjTokeidai* this, GlobalContext* globalCtx) { - if ((gSaveContext.day % 5 == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || (gSaveContext.day % 5 >= 4) || - ((gSaveContext.weekEventReg[8] & 0x40) != 0)) { +void ObjTokeidai_StaircaseIntoTower_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (OBJ_TOKEIDAI_IS_TRANSFORMED() || (gSaveContext.weekEventReg[8] & 0x40)) { this->actor.draw = ObjTokeidai_Draw; } else { this->actor.draw = NULL; @@ -571,21 +611,25 @@ s32 ObjTokeidai_IsPostFirstCycleFinalHours(ObjTokeidai* this, GlobalContext* glo return false; } if (gSaveContext.day % 5 == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) { - ObjTokeidai_SetupTowerTransformationStart(this); + ObjTokeidai_SetupTowerTransformation(this); return true; } return false; } -void ObjTokeidai_HandleHour(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_RotateOnHourChange(ObjTokeidai* this, GlobalContext* globalCtx) { s32 currentHour; currentHour = OBJ_TOKEIDAI_GET_CURRENT_HOUR(this); if (currentHour != this->clockHour) { if (this->clockFaceRotationTimer >= 13) { - this->clockFaceAdditionalRotation += 0xA; - this->clockFaceRotation += this->clockFaceAdditionalRotation; + // This actually performs the rotation to the next hour + // for the clock face. + this->clockFaceRotationalVelocity += 0xA; + this->clockFaceRotation += this->clockFaceRotationalVelocity; } else { + // This makes the clock face wiggle in place for a bit + // before rotating to the next position. if ((this->clockFaceRotationTimer & 3) == 0) { this->clockFaceRotation += 0x3C; } @@ -593,46 +637,51 @@ void ObjTokeidai_HandleHour(ObjTokeidai* this, GlobalContext* globalCtx) { this->clockFaceRotation -= 0x3C; } } + this->clockFaceRotationTimer++; if ((currentHour == 12 && this->clockFaceRotation < 0) || (currentHour != 12 && this->clockFaceRotation > OBJ_TOKEIDAI_GET_CLOCK_FACE_ROTATION(currentHour))) { this->clockFaceRotation = OBJ_TOKEIDAI_GET_CLOCK_FACE_ROTATION(currentHour); this->clockHour = currentHour; - this->clockFaceAdditionalRotation = 0; + this->clockFaceRotationalVelocity = 0; this->clockFaceRotationTimer = 0; } } + + // If the sun and moon disk doesn't have the target rotation (e.g., the time of day + // just changed), rotate it until it matches the target. if (this->sunMoonDiskRotation != ObjTokeidai_GetTargetSunMoonDiskRotation()) { if (this->clockHour == 6) { - this->sunMoonDiskAdditionalRotation += 0x222; - this->sunMoonDiskRotation += this->sunMoonDiskAdditionalRotation; + this->sunMoonDiskRotationalVelocity += 0x222; + this->sunMoonDiskRotation += this->sunMoonDiskRotationalVelocity; if (this->sunMoonDiskRotation >= 0x10001) { this->sunMoonDiskRotation = ObjTokeidai_GetTargetSunMoonDiskRotation(); - this->sunMoonDiskAdditionalRotation = 0; + this->sunMoonDiskRotationalVelocity = 0; } } if (this->clockHour == 18) { - this->sunMoonDiskAdditionalRotation += 0x222; - this->sunMoonDiskRotation += this->sunMoonDiskAdditionalRotation; + this->sunMoonDiskRotationalVelocity += 0x222; + this->sunMoonDiskRotation += this->sunMoonDiskRotationalVelocity; if (this->sunMoonDiskRotation >= 0x8001) { this->sunMoonDiskRotation = ObjTokeidai_GetTargetSunMoonDiskRotation(); - this->sunMoonDiskAdditionalRotation = 0; + this->sunMoonDiskRotationalVelocity = 0; } } } } -void ObjTokeidai_TowerClockIdle(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_TowerClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { if (gSaveContext.day % 5 == 3 && this->clockHour < 6 && gSaveContext.time < CLOCK_TIME(6, 0)) { - this->actor.draw = ObjTokeidai_DrawClock; - ObjTokeidai_SetupTowerTransformationStart(this); + this->actor.draw = ObjTokeidai_Clock_Draw; + ObjTokeidai_SetupTowerTransformation(this); gSaveContext.weekEventReg[8] |= 0x40; return; } + if (globalCtx->csCtx.state != 0) { this->actor.home.rot.x = 1; this->currentTime += 3; - this->actor.draw = ObjTokeidai_DrawClock; + this->actor.draw = ObjTokeidai_Clock_Draw; } else { if ((globalCtx->actorCtx.unk5 & 2) == 0 && OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD && @@ -641,30 +690,31 @@ void ObjTokeidai_TowerClockIdle(ObjTokeidai* this, GlobalContext* globalCtx) { } this->currentTime = gSaveContext.time; if (this->actor.home.rot.x != 0) { - ObjTokeidai_InitClock(this); + ObjTokeidai_Clock_Init(this); this->actor.home.rot.x = 0; } } + if (gSaveContext.day % 5 != 3 || gSaveContext.time >= CLOCK_TIME(6, 0)) { - ObjTokeidai_HandleMinute(this, true); + ObjTokeidai_RotateOnMinuteChange(this, true); } - ObjTokeidai_HandleHour(this, globalCtx); + ObjTokeidai_RotateOnHourChange(this, globalCtx); } -void ObjTokeidai_SmallClockIdle(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_WallClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { this->currentTime = gSaveContext.time; - ObjTokeidai_HandleMinute(this, true); - ObjTokeidai_HandleHour(this, globalCtx); + ObjTokeidai_RotateOnMinuteChange(this, true); + ObjTokeidai_RotateOnHourChange(this, globalCtx); } -void ObjTokeidai_TowerGearIdle(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_TowerGear_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { if (ObjTokeidai_IsPostFirstCycleFinalHours(this, globalCtx)) { - this->actor.draw = ObjTokeidai_DrawTowerGear; + this->actor.draw = ObjTokeidai_TowerGear_Draw; } else { if (globalCtx->csCtx.state != 0) { this->actor.home.rot.x = 1; this->currentTime += 3; - this->actor.draw = ObjTokeidai_DrawTowerGear; + this->actor.draw = ObjTokeidai_TowerGear_Draw; } else { if ((globalCtx->actorCtx.unk5 & 2) == 0 && OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_TOWER_GEAR_TERMINA_FIELD && @@ -677,25 +727,26 @@ void ObjTokeidai_TowerGearIdle(ObjTokeidai* this, GlobalContext* globalCtx) { this->actor.home.rot.x = 0; } } - ObjTokeidai_HandleMinute(this, false); + ObjTokeidai_RotateOnMinuteChange(this, false); } } -void ObjTokeidai_TowerTopIdle(ObjTokeidai* this, GlobalContext* globalCtx) { +void ObjTokeidai_Counterweight_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { s32 type; if (ObjTokeidai_IsPostFirstCycleFinalHours(this, globalCtx)) { - this->lightIntensity = 0; + this->spotlightIntensity = 0; if ((this->actor.child == NULL)) { type = OBJ_TOKEIDAI_TYPE(&this->actor); - if (type == OBJ_TOKEIDAI_TYPE_TOWER_TOP_CLOCK_TOWN || type == OBJ_TOKEIDAI_TYPE_TOWER_TOP_TERMINA_FIELD) { + if (type == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_CLOCK_TOWN || + type == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD) { this->actor.child = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_HANABI, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0); } } if (this->actor.child != NULL) { - if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_TOWER_TOP_TERMINA_FIELD) { + if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD) { this->actor.child->home.rot.x = 0x384; } else { this->actor.child->home.rot.x = 0x12C; @@ -704,11 +755,11 @@ void ObjTokeidai_TowerTopIdle(ObjTokeidai* this, GlobalContext* globalCtx) { } else { this->actor.shape.rot.y -= 0x40; if (gSaveContext.isNight != 0) { - if (this->lightIntensity < 100) { - this->lightIntensity += +4; + if (this->spotlightIntensity < 100) { + this->spotlightIntensity += +4; } - } else if (this->lightIntensity > 0) { - this->lightIntensity -= 4; + } else if (this->spotlightIntensity > 0) { + this->spotlightIntensity -= 4; } } } @@ -737,7 +788,7 @@ void ObjTokeidai_Draw(Actor* thisx, GlobalContext* globalCtx) { CLOSE_DISPS(globalCtx->state.gfxCtx); } -void ObjTokeidai_DrawClock(Actor* thisx, GlobalContext* globalCtx) { +void ObjTokeidai_Clock_Draw(Actor* thisx, GlobalContext* globalCtx) { ObjTokeidai* this = THIS; OPEN_DISPS(globalCtx->state.gfxCtx); @@ -757,8 +808,8 @@ void ObjTokeidai_DrawClock(Actor* thisx, GlobalContext* globalCtx) { gSPDisplayList(POLY_OPA_DISP++, D_0600BEE8); Matrix_InsertZRotation_s(-this->clockFaceRotation * 2, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_SMALL_CLOCK || - OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_VERY_SMALL_CLOCK) { + if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_WALL_CLOCK || + OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_SMALL_WALL_CLOCK) { gSPDisplayList(POLY_OPA_DISP++, D_0600F518); } else { gSPDisplayList(POLY_OPA_DISP++, D_0600E818); @@ -771,7 +822,7 @@ void ObjTokeidai_DrawClock(Actor* thisx, GlobalContext* globalCtx) { CLOSE_DISPS(globalCtx->state.gfxCtx); } -void ObjTokeidai_DrawTowerTop(Actor* thisx, GlobalContext* globalCtx) { +void ObjTokeidai_Counterweight_Draw(Actor* thisx, GlobalContext* globalCtx) { s32 pad; u32 gameplayFrames = globalCtx->gameplayFrames; ObjTokeidai* this = THIS; @@ -792,13 +843,13 @@ void ObjTokeidai_DrawTowerTop(Actor* thisx, GlobalContext* globalCtx) { gSPDisplayList(POLY_OPA_DISP++, this->opaDList); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); func_8012C2DC(globalCtx->state.gfxCtx); - gDPSetPrimColor(POLY_XLU_DISP++, 0, 255, 255, 235, 180, (s32)(this->lightIntensity * 2.55f)); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 255, 255, 235, 180, (s32)(this->spotlightIntensity * 2.55f)); gSPDisplayList(POLY_XLU_DISP++, this->xluDList); CLOSE_DISPS(globalCtx->state.gfxCtx); } -void ObjTokeidai_DrawTowerGear(Actor* thisx, GlobalContext* globalCtx) { +void ObjTokeidai_TowerGear_Draw(Actor* thisx, GlobalContext* globalCtx) { ObjTokeidai* this = THIS; OPEN_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.h b/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.h index bec2c4541a..f91eca531a 100644 --- a/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.h +++ b/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.h @@ -8,18 +8,19 @@ #define OBJ_TOKEIDAI_GET_CURRENT_MINUTE(this) ((s32)(this->currentTime * (360 * 2.0f / 0x10000)) % 30) #define OBJ_TOKEIDAI_GET_CLOCK_FACE_ROTATION(currentHour) ((s16)(currentHour * (0x10000 / 24.0f))) #define OBJ_TOKEIDAI_GET_OUTER_RING_OR_GEAR_ROTATION(currentMinute) ((s16)(currentMinute * (0x10000 * 12.0f / 360))) +#define OBJ_TOKEIDAI_IS_TRANSFORMED() ((gSaveContext.day % 5 == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || gSaveContext.day % 5 >= 4) typedef enum { /* 0 */ OBJ_TOKEIDAI_TYPE_TOWER_GEAR_CLOCK_TOWN, /* 1 */ OBJ_TOKEIDAI_TYPE_UNUSED_WALL, /* 2 */ OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_CLOCK_TOWN, - /* 3 */ OBJ_TOKEIDAI_TYPE_TOWER_TOP_CLOCK_TOWN, + /* 3 */ OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_CLOCK_TOWN, /* 4 */ OBJ_TOKEIDAI_TYPE_TOWER_GEAR_TERMINA_FIELD, /* 5 */ OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD, - /* 6 */ OBJ_TOKEIDAI_TYPE_TOWER_TOP_TERMINA_FIELD, + /* 6 */ OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD, /* 8 */ OBJ_TOKEIDAI_TYPE_TOWER_WALLS_TERMINA_FIELD = 8, - /* 9 */ OBJ_TOKEIDAI_TYPE_SMALL_CLOCK, - /* 10 */ OBJ_TOKEIDAI_TYPE_VERY_SMALL_CLOCK, + /* 9 */ OBJ_TOKEIDAI_TYPE_WALL_CLOCK, + /* 10 */ OBJ_TOKEIDAI_TYPE_SMALL_WALL_CLOCK, /* 11 */ OBJ_TOKEIDAI_TYPE_STAIRCASE_INTO_TOWER, } ObjTokeidaiType; @@ -32,19 +33,19 @@ typedef struct ObjTokeidai { /* 0x144 */ Gfx* opaDList; /* 0x148 */ Gfx* xluDList; /* 0x14C */ s16 outerRingOrGearRotation; - /* 0x14E */ s16 outerRingOrGearAdditionalRotation; + /* 0x14E */ s16 outerRingOrGearRotationalVelocity; /* 0x150 */ s16 outerRingOrGearRotationTimer; /* 0x152 */ s16 clockFaceRotation; - /* 0x154 */ s16 clockFaceAdditionalRotation; // overloaded in transformation seqeuence - /* 0x156 */ s16 clockFaceRotationTimer; // overloaded in transformation seqeuence + /* 0x154 */ s16 actionVar1; + /* 0x156 */ s16 actionVar2; /* 0x158 */ s32 sunMoonDiskRotation; - /* 0x15C */ s16 sunMoonDiskAdditionalRotation; // overloaded to also be something weird with the clock + /* 0x15C */ s16 actionVar3; /* 0x15E */ s16 yTranslation; /* 0x160 */ s16 xRotation; /* 0x162 */ s16 clockFaceZTranslation; // amount the clock face recesses inwards once it transforms - /* 0x164 */ s16 reboundCount; + /* 0x164 */ s16 boundCount; /* 0x168 */ s32 clockMinute; // only 30 minutes in an hour - /* 0x16C */ s32 clockHour; // overloaded to also be the light beam intensity + /* 0x16C */ s32 actionVar4; /* 0x170 */ u16 currentTime; /* 0x174 */ ObjTokeidaiActionFunc actionFunc; } ObjTokeidai; // size = 0x178 diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 96866026e3..7bc9d297ef 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -11669,43 +11669,43 @@ 0x80AB261C:("DmChar09_Draw",), 0x80AB2790:("ObjTokeidai_GetTargetSunMoonDiskRotation",), 0x80AB27B4:("ObjTokeidai_SetupClockOrGear",), - 0x80AB2834:("ObjTokeidai_InitClock",), - 0x80AB28C8:("ObjTokeidai_InitTowerGear",), - 0x80AB29F8:("ObjTokeidai_InitTowerClock",), - 0x80AB2BBC:("ObjTokeidai_InitTowerTop",), + 0x80AB2834:("ObjTokeidai_Clock_Init",), + 0x80AB28C8:("ObjTokeidai_TowerGear_Init",), + 0x80AB29F8:("ObjTokeidai_TowerClock_Init",), + 0x80AB2BBC:("ObjTokeidai_Counterweight_Init",), 0x80AB2DEC:("ObjTokeidai_Init",), 0x80AB3000:("ObjTokeidai_Destroy",), - 0x80AB3010:("ObjTokeidai_HandleMinute",), - 0x80AB319C:("ObjTokeidai_CollapseGear",), - 0x80AB3240:("ObjTokeidai_TransformedGearIdle",), - 0x80AB32F0:("ObjTokeidai_TransformedClockFaceFall",), - 0x80AB3370:("ObjTokeidai_TransformedClockFaceSlideOff",), - 0x80AB34CC:("ObjTokeidai_TransformedClockIdle",), - 0x80AB3544:("ObjTokeidai_CollapseTop",), - 0x80AB3598:("ObjTokeidai_TransformedTopIdle",), - 0x80AB363C:("ObjTokeidai_CollapseWalls",), - 0x80AB365C:("ObjTokeidai_WallsIdle",), - 0x80AB36C4:("ObjTokeidai_TowerTransformationEndCutscene",), - 0x80AB3808:("ObjTokeidai_TowerTransformationFinish",), - 0x80AB3880:("ObjTokeidai_TowerTransformationWait",), - 0x80AB38B0:("ObjTokeidai_TowerTopFall",), - 0x80AB39BC:("ObjTokeidai_TowerRaiseFinished",), - 0x80AB3A7C:("ObjTokeidai_RaiseTower",), - 0x80AB3B34:("ObjTokeidai_TowerTransformationStart",), - 0x80AB3BB0:("ObjTokeidai_SetupTowerTransformationStart",), + 0x80AB3010:("ObjTokeidai_RotateOnMinuteChange",), + 0x80AB319C:("ObjTokeidai_TowerGear_Collapse",), + 0x80AB3240:("ObjTokeidai_TowerGear_TransformedIdle",), + 0x80AB32F0:("ObjTokeidai_TowerClock_Fall",), + 0x80AB3370:("ObjTokeidai_TowerClock_SlideOff",), + 0x80AB34CC:("ObjTokeidai_TowerClock_TransformedIdle",), + 0x80AB3544:("ObjTokeidai_Counterweight_Collapse",), + 0x80AB3598:("ObjTokeidai_Counterweight_TransformedIdle",), + 0x80AB363C:("ObjTokeidai_Walls_Collapse",), + 0x80AB365C:("ObjTokeidai_Walls_Idle",), + 0x80AB36C4:("ObjTokeidai_TowerTransformation_EndCutscene",), + 0x80AB3808:("ObjTokeidai_TowerTransformation_FinishTransformation",), + 0x80AB3880:("ObjTokeidai_TowerTransformation_Wait",), + 0x80AB38B0:("ObjTokeidai_TowerTransformation_DropCounterweight",), + 0x80AB39BC:("ObjTokeidai_TowerTransformation_FinishRaise",), + 0x80AB3A7C:("ObjTokeidai_TowerTransformation_RaiseTower",), + 0x80AB3B34:("ObjTokeidai_TowerTransformation_Start",), + 0x80AB3BB0:("ObjTokeidai_SetupTowerTransformation",), 0x80AB3BD8:("ObjTokeidai_DoNothing",), - 0x80AB3BE8:("ObjTokeidai_StaircaseIntoTowerIdle",), + 0x80AB3BE8:("ObjTokeidai_StaircaseIntoTower_Idle",), 0x80AB3C50:("ObjTokeidai_IsPostFirstCycleFinalHours",), - 0x80AB3CCC:("ObjTokeidai_HandleHour",), - 0x80AB3ED0:("ObjTokeidai_TowerClockIdle",), - 0x80AB4040:("ObjTokeidai_SmallClockIdle",), - 0x80AB4080:("ObjTokeidai_TowerGearIdle",), - 0x80AB4160:("ObjTokeidai_TowerTopIdle",), + 0x80AB3CCC:("ObjTokeidai_RotateOnHourChange",), + 0x80AB3ED0:("ObjTokeidai_TowerClock_Idle",), + 0x80AB4040:("ObjTokeidai_WallClock_Idle",), + 0x80AB4080:("ObjTokeidai_TowerGear_Idle",), + 0x80AB4160:("ObjTokeidai_Counterweight_Idle",), 0x80AB4278:("ObjTokeidai_Update",), 0x80AB429C:("ObjTokeidai_Draw",), - 0x80AB4394:("ObjTokeidai_DrawClock",), - 0x80AB4664:("ObjTokeidai_DrawTowerTop",), - 0x80AB4894:("ObjTokeidai_DrawTowerGear",), + 0x80AB4394:("ObjTokeidai_Clock_Draw",), + 0x80AB4664:("ObjTokeidai_Counterweight_Draw",), + 0x80AB4894:("ObjTokeidai_TowerGear_Draw",), 0x80AB4D10:("func_80AB4D10",), 0x80AB4E34:("func_80AB4E34",), 0x80AB4E58:("func_80AB4E58",),