diff --git a/linker_scripts/code_script.txt b/linker_scripts/code_script.txt index 61a0dfad3d..c7e7dadec6 100644 --- a/linker_scripts/code_script.txt +++ b/linker_scripts/code_script.txt @@ -8217,9 +8217,9 @@ SECTIONS ovl_Bg_Iknv_Obj : AT(RomLocation) { build/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.o(.text) - build/asm/overlays/ovl_Bg_Iknv_Obj_data.o(.data) + build/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.o(.data) build/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.o(.rodata) - build/asm/overlays/ovl_Bg_Iknv_Obj_rodata.o(.rodata) + build/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj_overlay.o(.ovl) } SegmentEnd = .; SegmentSize = SegmentEnd - SegmentStart; diff --git a/linker_scripts/object_script.txt b/linker_scripts/object_script.txt index 4c72dfd7e0..115167394d 100644 --- a/linker_scripts/object_script.txt +++ b/linker_scripts/object_script.txt @@ -228,6 +228,13 @@ D_06000C20 = 0x6000C20; D_06000420 = 0x6000420; D_06001420 = 0x6001420; +/* z_bg_iknv_obj */ +D_060119D4 = 0x060119D4; +D_06012CA4 = 0x06012CA4; +D_06011880 = 0x06011880; +D_060129C8 = 0x060129C8; +D_06013058 = 0x06013058; + /* z_obj_kepn_koya */ D_0600805C = 0x0600805C; D_06003478 = 0x06003478; diff --git a/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.c b/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.c index bfeb63fdb8..4b129e8e36 100644 --- a/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.c +++ b/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.c @@ -9,7 +9,17 @@ void BgIknvObj_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgIknvObj_Update(Actor* thisx, GlobalContext* globalCtx); void BgIknvObj_Draw(Actor* thisx, GlobalContext* globalCtx); -/* +void BgIknvObj_DoNothing(BgIknvObj* this, GlobalContext* globalCtx); +void BgIknvObj_UpdateWaterwheel(BgIknvObj* this, GlobalContext* globalCtx); +void BgIknvObj_UpdateRaisedDoor(BgIknvObj* this, GlobalContext* globalCtx); +void BgIknvObj_UpdateSakonDoor(BgIknvObj* this, GlobalContext* globalCtx); + +extern CollisionHeader D_060119D4; +extern CollisionHeader D_06012CA4; +extern Gfx D_06011880[]; +extern Gfx D_060129C8[]; +extern Gfx D_06013058[]; + const ActorInit Bg_Iknv_Obj_InitVars = { ACTOR_BG_IKNV_OBJ, ACTORCAT_BG, @@ -21,32 +31,187 @@ const ActorInit Bg_Iknv_Obj_InitVars = { (ActorFunc)BgIknvObj_Update, (ActorFunc)BgIknvObj_Draw, }; -*/ -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/BgIknvObj_Init.asm") +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_ENEMY, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { 40, 40, 0, { 0, 0, 0 } }, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/BgIknvObj_Destroy.asm") +void BgIknvObj_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgIknvObj* this = THIS; + CollisionHeader* colHeader = NULL; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/func_80BD7CEC.asm") + Actor_SetScale(&this->dyna.actor, 0.1f); + this->actionFunc = BgIknvObj_DoNothing; + switch (IKNV_OBJ_TYPE(this)) { + case IKNV_OBJ_WATERWHEEL: + this->displayListPtr = D_06013058; + this->actionFunc = BgIknvObj_UpdateWaterwheel; + this->dyna.actor.flags |= 0x100000; + this->dyna.actor.flags |= 0x10; + break; + case IKNV_OBJ_RAISED_DOOR: + this->displayListPtr = D_06011880; + BcCheck3_BgActorInit(&this->dyna, 0); + BgCheck_RelocateMeshHeader(&D_060119D4, &colHeader); + this->dyna.bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, &this->dyna, colHeader); + this->actionFunc = BgIknvObj_UpdateRaisedDoor; + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + 120.0f; + break; + case IKNV_OBJ_SAKON_DOOR: + this->displayListPtr = D_060129C8; + this->actionFunc = BgIknvObj_UpdateSakonDoor; + BcCheck3_BgActorInit(&this->dyna, 0); + BgCheck_RelocateMeshHeader(&D_06012CA4, &colHeader); + this->dyna.bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, &this->dyna, colHeader); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + this->dyna.actor.colChkInfo.mass = MASS_IMMOVABLE; + gSaveContext.weekEventReg[51] &= (u8)~0x10; + Actor_SetHeight(&this->dyna.actor, IREG(88)); + break; + default: + Actor_MarkForDeath(&this->dyna.actor); + } +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/BgIknvObj_UpdateType0.asm") +void BgIknvObj_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgIknvObj* this = THIS; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/func_80BD7E0C.asm") + if (IKNV_OBJ_TYPE(this) != IKNV_OBJ_RAISED_DOOR) { + if (IKNV_OBJ_TYPE(this) == IKNV_OBJ_SAKON_DOOR) { + Collider_DestroyCylinder(globalCtx, &this->collider); + gSaveContext.weekEventReg[51] &= (u8)~0x10; + } else { + return; + } + } + BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/func_80BD7ED8.asm") +s32 func_80BD7CEC(BgIknvObj* this) { + if (this->dyna.actor.cutscene == -1) { + return true; + } -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/func_80BD7F4C.asm") + if (ActorCutscene_GetCurrentIndex() == this->dyna.actor.cutscene) { + return true; + } -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/func_80BD7FDC.asm") + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + return true; + } -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/func_80BD8040.asm") + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + return false; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/BgIknvObj_UpdateType2.asm") +void BgIknvObj_UpdateWaterwheel(BgIknvObj* this, GlobalContext* globalCtx) { + if (gSaveContext.weekEventReg[14] & 4) { + this->dyna.actor.shape.rot.z -= 0x64; + func_800B9098(&this->dyna.actor); + func_800B9010(&this->dyna.actor, NA_SE_EV_WOOD_WATER_WHEEL - SFX_FLAG); + } -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/BgIknvObj_UpdateType1.asm") + if ((globalCtx->csCtx.state != 0) && (gSaveContext.sceneSetupIndex == 1) && (globalCtx->csCtx.unk12 == 4) && + (globalCtx->csCtx.frames == 0x5D7)) { + func_8019F128(NA_SE_EV_DOOR_UNLOCK); + } +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/BgIknvObj_UpdateDefault.asm") +s32 func_80BD7E0C(BgIknvObj* this, s16 targetRotation, GlobalContext* globalCtx) { + this->dyna.actor.shape.yOffset = 0.0f; + CollisionCheck_SetOC(globalCtx, &globalCtx->colCheckCtx, &this->collider.base); + if (targetRotation != this->dyna.actor.shape.rot.y) { + Math_SmoothStepToS(&this->dyna.actor.shape.rot.y, targetRotation, 2, 100, 100); + this->dyna.actor.world.rot.y = this->dyna.actor.shape.rot.y; + if ((globalCtx->gameplayFrames % 2) != 0) { + this->dyna.actor.shape.yOffset = 5.0f; + } + func_800B9010(&this->dyna.actor, NA_SE_EV_STONEDOOR_OPEN_S - SFX_FLAG); + return false; + } + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONEDOOR_STOP); + return true; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/BgIknvObj_Update.asm") +void func_80BD7ED8(BgIknvObj* this, GlobalContext* globalCtx) { + if (func_80BD7E0C(this, this->dyna.actor.home.rot.y, globalCtx)) { + this->actionFunc = BgIknvObj_UpdateSakonDoor; + gSaveContext.weekEventReg[51] &= (u8)~0x10; + } + CollisionCheck_SetOC(globalCtx, &globalCtx->colCheckCtx, &this->collider.base); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Iknv_Obj_0x80BD7AB0/BgIknvObj_Draw.asm") +void func_80BD7F4C(BgIknvObj* this, GlobalContext* globalCtx) { + if (gSaveContext.time > 0xD000) { + this->actionFunc = func_80BD7ED8; + } + if ((this->dyna.actor.home.rot.x == 1) && !(gSaveContext.weekEventReg[58] & 0x80)) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + this->dyna.actor.home.rot.x = 0; + } + CollisionCheck_SetOC(globalCtx, &globalCtx->colCheckCtx, &this->collider.base); +} + +void func_80BD7FDC(BgIknvObj* this, GlobalContext* globalCtx) { + if (func_80BD7E0C(this, this->dyna.actor.home.rot.y + 0x4000, globalCtx)) { + this->actionFunc = func_80BD7F4C; + gSaveContext.weekEventReg[51] |= 0x10; + this->dyna.actor.home.rot.x = 1; + } +} + +void func_80BD8040(BgIknvObj* this, GlobalContext* globalCtx) { + if (func_80BD7CEC(this)) { + this->actionFunc = func_80BD7FDC; + } + CollisionCheck_SetOC(globalCtx, &globalCtx->colCheckCtx, &this->collider.base); +} + +void BgIknvObj_UpdateSakonDoor(BgIknvObj* this, GlobalContext* globalCtx) { + if (gSaveContext.weekEventReg[58] & 0x80) { + this->actionFunc = func_80BD8040; + gSaveContext.weekEventReg[89] |= 0x80; + } + CollisionCheck_SetOC(globalCtx, &globalCtx->colCheckCtx, &this->collider.base); +} + +void BgIknvObj_UpdateRaisedDoor(BgIknvObj* this, GlobalContext* globalCtx) { +} + +void BgIknvObj_DoNothing(BgIknvObj* this, GlobalContext* globalCtx) { +} + +void BgIknvObj_Update(Actor* thisx, GlobalContext* globalCtx) { + BgIknvObj* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void BgIknvObj_Draw(Actor* thisx, GlobalContext* globalCtx) { + BgIknvObj* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C28C(globalCtx->state.gfxCtx); + gSPDisplayList(POLY_OPA_DISP++, this->displayListPtr); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.h b/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.h index e71a24f8a0..fd62059d36 100644 --- a/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.h +++ b/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.h @@ -5,11 +5,23 @@ struct BgIknvObj; +typedef void (*BgIknvObjActionFunc)(struct BgIknvObj*, GlobalContext*); + +#define IKNV_OBJ_TYPE(x) (x->dyna.actor.params & 0xF) + typedef struct BgIknvObj { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x6C]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ ColliderCylinder collider; + /* 0x1A8 */ Gfx* displayListPtr; + /* 0x1AC */ BgIknvObjActionFunc actionFunc; } BgIknvObj; // size = 0x1B0 +typedef enum { + /* 0 */ IKNV_OBJ_WATERWHEEL, + /* 1 */ IKNV_OBJ_RAISED_DOOR, // defunct door covering entrance to Stone Tower + /* 2 */ IKNV_OBJ_SAKON_DOOR, // door to Sakon's Hideout +} BgIknvObjType; + extern const ActorInit Bg_Iknv_Obj_InitVars; #endif // Z_BG_IKNV_OBJ_H diff --git a/tables/functions.txt b/tables/functions.txt index c20d46b6d0..62897e70ac 100644 --- a/tables/functions.txt +++ b/tables/functions.txt @@ -15885,15 +15885,15 @@ 0x80BD7AB0:("BgIknvObj_Init",), 0x80BD7C7C:("BgIknvObj_Destroy",), 0x80BD7CEC:("func_80BD7CEC",), - 0x80BD7D6C:("BgIknvObj_UpdateType0",), + 0x80BD7D6C:("BgIknvObj_UpdateWaterwheel",), 0x80BD7E0C:("func_80BD7E0C",), 0x80BD7ED8:("func_80BD7ED8",), 0x80BD7F4C:("func_80BD7F4C",), 0x80BD7FDC:("func_80BD7FDC",), 0x80BD8040:("func_80BD8040",), - 0x80BD8098:("BgIknvObj_UpdateType2",), - 0x80BD80FC:("BgIknvObj_UpdateType1",), - 0x80BD810C:("BgIknvObj_UpdateDefault",), + 0x80BD8098:("BgIknvObj_UpdateSakonDoor",), + 0x80BD80FC:("BgIknvObj_UpdateRaisedDoor",), + 0x80BD810C:("BgIknvObj_DoNothing",), 0x80BD811C:("BgIknvObj_Update",), 0x80BD8140:("BgIknvObj_Draw",), 0x80BD82B0:("EnPamera_Init",),