diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index f826aa09..804eaef8 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -642,6 +642,7 @@ d/a/obj/d_a_obj_tbox.cpp: .ctors start:0x804DB83C end:0x804DB840 .rodata start:0x804ED3B0 end:0x804EE548 .data start:0x80535270 end:0x80535A18 + .sdata2 start:0x8057C238 end:0x8057C3F0 .bss start:0x805B4FA8 end:0x805B5458 d/a/obj/d_a_obj_time_area.cpp: diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 8e658e75..ddda8137 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -14251,7 +14251,7 @@ __dt__24sFStateFct_c<9dAcTbox_c>Fv = .text:0x80268B40; // type:function size:0x6 __dt__77sStateMgr_c<9dAcTbox_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80268BB0; // type:function size:0xA0 __dt__47sFStateMgr_c<9dAcTbox_c,20sStateMethodUsr_FI_c>Fv = .text:0x80268C50; // type:function size:0xA4 __dt__9dAcTbox_cFv = .text:0x80268D00; // type:function size:0x250 -AcTbox__initModels = .text:0x80268F50; // type:function size:0x54C +createHeap__9dAcTbox_cFv = .text:0x80268F50; // type:function size:0x54C AcTbox__init = .text:0x802694A0; // type:function size:0xA00 AcTbox__destroy = .text:0x80269EA0; // type:function size:0xB4 AcTbox__update = .text:0x80269F60; // type:function size:0x690 @@ -49009,12 +49009,20 @@ StateID_CatchDemo__13dAcObjFairy_c = .bss:0x805B4F68; // type:object size:0x30 d lbl_805B4FA8 = .bss:0x805B4FA8; // type:object size:0x30 data:float lbl_805B4FD8 = .bss:0x805B4FD8; // type:object size:0xC data:float lbl_805B4FE4 = .bss:0x805B4FE4; // type:object size:0xC data:float -lbl_805B4FF0 = .bss:0x805B4FF0; // type:object size:0xE8 data:float -AcTbox__STATE_WAIT_OPEN = .bss:0x805B50D8; // type:object size:0x80 data:4byte -AcTbox__STATE_GODDESS_WAIT_ON = .bss:0x805B5158; // type:object size:0x80 data:4byte -AcTbox__STATE_LOAD_ARCHIVE = .bss:0x805B51D8; // type:object size:0x40 data:4byte -AcTbox__STATE_OPEN = .bss:0x805B5218; // type:object size:0x40 data:4byte -AcTbox__StateID_PresentItem = .bss:0x805B5258; // type:object size:0xF0 data:4byte +lbl_805B4FF0 = .bss:0x805B4FF0; // type:object size:0x18 data:float +StateID_DugOut__9dAcTbox_c = .bss:0x805B5018; // type:object size:0x30 data:4byte +StateID_WaitAppear__9dAcTbox_c = .bss:0x805B5058; // type:object size:0x30 data:4byte +StateID_DemoAppear__9dAcTbox_c = .bss:0x805B5098; // type:object size:0x30 data:4byte +StateID_WaitOpen__9dAcTbox_c = .bss:0x805B50D8; // type:object size:0x30 data:4byte +StateID_GoddessWaitOff__9dAcTbox_c = .bss:0x805B5118; // type:object size:0x30 data:4byte +StateID_GoddessWaitOn__9dAcTbox_c = .bss:0x805B5158; // type:object size:0x30 data:4byte +StateID_DeleteArchive__9dAcTbox_c = .bss:0x805B5198; // type:object size:0x30 data:4byte +StateID_LoadArchive__9dAcTbox_c = .bss:0x805B51D8; // type:object size:0x30 data:4byte +StateID_Open__9dAcTbox_c = .bss:0x805B5218; // type:object size:0x30 data:4byte +StateID_PresentItem__9dAcTbox_c = .bss:0x805B5258; // type:object size:0x30 data:4byte +StateID_Close__9dAcTbox_c = .bss:0x805B5298; // type:object size:0x30 data:4byte +StateID_Wait__9dAcTbox_c = .bss:0x805B52D8; // type:object size:0x30 data:4byte +StateID_GoddessWait__9dAcTbox_c = .bss:0x805B5318; // type:object size:0x30 data:4byte lbl_805B5348 = .bss:0x805B5348; // type:object size:0xA0 lbl_805B53E8 = .bss:0x805B53E8; // type:object size:0x40 data:4byte lbl_805B5428 = .bss:0x805B5428; // type:object size:0x30 data:float diff --git a/include/d/a/obj/d_a_obj_tbox.h b/include/d/a/obj/d_a_obj_tbox.h index f8e9dd10..355ed2e0 100644 --- a/include/d/a/obj/d_a_obj_tbox.h +++ b/include/d/a/obj/d_a_obj_tbox.h @@ -13,23 +13,30 @@ #include "m/m3d/m_anmtexpat.h" #include "m/m3d/m_anmtexsrt.h" #include "m/m3d/m_smdl.h" +#include "m/m_vec.h" #include "s/s_State.hpp" #include "toBeSorted/actor_event.h" #include "toBeSorted/dowsing_target.h" #include "toBeSorted/stage_render_stuff.h" +// Somewhere in d_cc class dAcTboxCcD : public dCcD_Unk { public: - dAcTboxCcD() : mpList(nullptr), field_0x210(nullptr) {} + dAcTboxCcD() : mpList(nullptr), field_0x210(this) {} virtual ~dAcTboxCcD() { if (mpList != nullptr) { mpList->remove(&mNode); mpList = nullptr; } } - cListNd_c mNode; - void *field_0x210; - cListMg_c *mpList; + /* 0x00 */ cListNd_c mNode; + /* 0x08 */ dCcD_Unk *field_0x210; + /* 0x0C */ cListMg_c *mpList; +}; + +struct TboxAndMoreUnkCC { + cListMg_c mList; + virtual ~TboxAndMoreUnkCC(); }; class dAcTbox_c : public dAcObjBase_c { @@ -37,6 +44,8 @@ public: dAcTbox_c(); virtual ~dAcTbox_c(); + virtual bool createHeap() override; + STATE_FUNC_DECLARE(dAcTbox_c, DugOut); STATE_FUNC_DECLARE(dAcTbox_c, WaitAppear); STATE_FUNC_DECLARE(dAcTbox_c, DemoAppear); @@ -52,30 +61,47 @@ public: STATE_FUNC_DECLARE(dAcTbox_c, GoddessWait); private: + bool initBgW(dBgW &bg, const char *arcName, const char *ccName); + bool isNotSmall() const; + void fn_8026B380(mVec3_c &outResult) const; + const mVec3_c &fn_8026B3C0() const; + /* 0x0330 */ m3d::mdlAnmChr mMdl1; - /* 0x0398 */ m3d::smdl_c mMdl2; + /* 0x0398 */ m3d::smdl_c mOpenFxMdl; /* 0x03B4 */ m3d::anmMatClr_c mAnmMatClr1; /* 0x03E0 */ m3d::anmMatClr_c mAnmMatClr2; /* 0x040C */ m3d::anmChr_c mAnmChr; /* 0x0444 */ m3d::anmTexSrt_c mAnmTexSrt1; - /* 0x0470 */ m3d::anmTexSrt_c mAnmTexSrt2; - /* 0x049C */ m3d::anmTexPat_c mAnmTextPat; + /* 0x0470 */ m3d::anmTexSrt_c mAnmGoddessTexSrt; + /* 0x049C */ m3d::anmTexPat_c mAnmGoddessPat; /* 0x04C8 */ dScnCallback_c mScnCallback; /* 0x04D4 */ dShadowCircle_c mShadowCircle; - u8 f1[0x1C]; + + // Could be part of an aggregate structure + s32 field_0x4DC; + s32 field_0x4E0; + s32 field_0x4E4; + s32 field_0x4E8; + s32 field_0x4EC; + s32 field_0x4F0; + s32 field_0x4F4; + /* 0x04F8 */ dBgW mBgWs[2]; /* 0x0918 */ dAcTboxCcD mCcD1; /* 0x0B30 */ dAcTboxCcD mCcD2; - u8 f2[0xC]; + /* 0x0D48 */ TboxAndMoreUnkCC field_0x0D48; /* 0x0D54 */ dCcD_Unk mCcD3; /* 0x0F5C */ dCcD_Cyl mCcD4; /* 0x10AC */ STATE_MGR_DECLARE(dAcTbox_c); /* 0x10E8 */ fLiNdBa_c mTboxListNode; /* 0x10F4 */ ActorEventRelated mEvent; - dAcRef_c mItemRef; + /* 0x1144 */ dAcRef_c mItemRef; /* 0x1150 */ DowsingTarget mDowsingTarget1; /* 0x1170 */ DowsingTarget mDowsingTarget2; + /* 0x1204 */ bool mHasBeenOpened; + /* 0x1209 */ u8 mVariant; + static fLiMgBa_c sTboxActorList; }; diff --git a/src/d/a/obj/d_a_obj_tbox.cpp b/src/d/a/obj/d_a_obj_tbox.cpp index 52f092b9..8b38c261 100644 --- a/src/d/a/obj/d_a_obj_tbox.cpp +++ b/src/d/a/obj/d_a_obj_tbox.cpp @@ -1,14 +1,20 @@ #include "d/a/obj/d_a_obj_tbox.h" + +#include "common.h" +#include "d/flag/storyflag_manager.h" +#include "m/m_mtx.h" #include "m/m_vec.h" +#include "nw4r/g3d/g3d_resanmchr.h" +#include "nw4r/g3d/g3d_resanmtexpat.h" +#include "nw4r/g3d/g3d_resanmtexsrt.h" +#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/g3d_resmdl.h" #include "toBeSorted/dowsing_target.h" SPECIAL_ACTOR_PROFILE(TBOX, dAcTbox_c, fProfile::TBOX, 0x018D, 0, 6); extern "C" mVec3_c vecs[] = { - mVec3_c(0.0f, 54.0f, 0.0f), - mVec3_c(0.0f, 34.0f, 0.0f), - mVec3_c(0.0f, 66.5f, 0.0f), - mVec3_c(0.0f, 49.0f, 0.0f) + mVec3_c(0.0f, 54.0f, 0.0f), mVec3_c(0.0f, 34.0f, 0.0f), mVec3_c(0.0f, 66.5f, 0.0f), mVec3_c(0.0f, 49.0f, 0.0f) }; extern "C" mVec3_c v1 = mVec3_c(0.0f, 0.0f, -2.0f); @@ -32,14 +38,191 @@ STATE_DEFINE(dAcTbox_c, GoddessWait); fLiMgBa_c dAcTbox_c::sTboxActorList; -dAcTbox_c::dAcTbox_c() : mStateMgr(*this, sStateID::null), mScnCallback(this), mEvent(*this, nullptr), mTboxListNode(this), mDowsingTarget1(this, DowsingTarget::SLOT_NONE), mDowsingTarget2(this, DowsingTarget::SLOT_NONE) { +static char *const sArcNames[] = { + "TBoxNormalT", + "TBoxSmallT", + "TBoxBossT", + "GoddessTBox", +}; + +static const char *const sOpenArcName = "FX_TBoxOpen"; +static const char *const sOpenMdlName = "FX_TBoxOpen"; +static const char *const sOpenAnmChrName = "FX_TBoxOpen"; +static const char *const sOpenAnmTexSrtName = "FX_TBoxOpen"; +static const char *const sOpenAnmClrName = "FX_TBoxOpen"; + +static const char *const sAppearAnmName = "TBoxNormalT_appear"; + +extern "C" char *const sOpenEventNames[] = { + "TreasureBoxOpen", + "TreasureBoxOpenSmall", + "TreasureBoxOpenBoss", + "TreasureBoxOpen", +}; + +static char *const sMdlNames[] = { + "TBoxNormalT", + "TBoxSmallT", + "TBoxBossT", + "GoddessTBox", +}; + +static char *const sAnmNames[] = { + "TBoxNormalT", + "TBoxSmallT", + "TBoxBossT", + "TBoxNormalT", +}; + +static char *const sCloseCcNames[] = { + "TBoxNormalTClose", + "TBoxSmallTClose", + "TBoxBossTClose", + "GoddessTBoxClose", +}; + +static char *const sOpenCcNames[] = { + "TBoxNormalTOpen", + "TBoxSmallTOpen", + "TBoxBossTOpen", + "GoddessTBoxOpen", +}; + +dAcTbox_c::dAcTbox_c() + : mStateMgr(*this, sStateID::null), mScnCallback(this), mEvent(*this, nullptr), mTboxListNode(this), + mDowsingTarget1(this, DowsingTarget::SLOT_NONE), mDowsingTarget2(this, DowsingTarget::SLOT_NONE), + field_0x4E8(-1) { sTboxActorList.append(&mTboxListNode); unkByteTargetFiRelated = 2; } + dAcTbox_c::~dAcTbox_c() { sTboxActorList.remove(&mTboxListNode); } +bool dAcTbox_c::createHeap() { + void *data = getOarcResFile(sArcNames[mVariant]); + if (data == nullptr) { + return false; + } + if (!mMdl1.create(data, data, sMdlNames[mVariant], sAnmNames[mVariant], &heap_allocator, 0x32F, 1, nullptr)) { + return false; + } + mMdl1.getModel().setLocalMtx(mWorldMtx); + mScnCallback.attach(mMdl1.getModel()); + if (!initBgW(mBgWs[0], sArcNames[mVariant], sCloseCcNames[mVariant])) { + return false; + } + if (!initBgW(mBgWs[1], sArcNames[mVariant], sOpenCcNames[mVariant])) { + return false; + } + + if (mVariant == 3) { + if (data == nullptr) { + return false; + } + nw4r::g3d::ResFile res = data; + nw4r::g3d::ResMdl mdl = mMdl1.getModel().getResMdl(); + if (!mdl.IsValid()) { + return false; + } + nw4r::g3d::ResAnmTexPat anmTexPat = res.GetResAnmTexPat("GoddessTBox"); + if (!anmTexPat.mAnmTexPat.IsValid()) { + return false; + } + if (!mAnmGoddessPat.create(mdl, anmTexPat, &heap_allocator, nullptr, 1)) { + return false; + } + mMdl1.getModel().setAnm(mAnmGoddessPat); + u16 goddessTBoxActive = getParams2Lower(); + if (StoryflagManager::sInstance->getCounterOrFlag(goddessTBoxActive) && !mHasBeenOpened) { + nw4r::g3d::ResAnmTexSrt anmTexSrt = res.GetResAnmTexSrt("GoddessTBox"); + if (!anmTexSrt.mAnmTexSrt.IsValid()) { + return false; + } + if (!mAnmGoddessTexSrt.create(mdl, anmTexSrt, &heap_allocator, nullptr, 1)) { + return false; + } + mMdl1.getModel().setAnm(mAnmGoddessTexSrt); + } + } else if (mVariant == 0) { + if (data == nullptr) { + return false; + } + nw4r::g3d::ResFile res = data; + nw4r::g3d::ResAnmClr anmClr = res.GetResAnmClr("TBoxNormalTAppear"); + if (!anmClr.mAnmClr.IsValid()) { + return false; + } + nw4r::g3d::ResMdl mdl = mMdl1.getModel().getResMdl(); + if (!mdl.IsValid()) { + return false; + } + if (!mAnmMatClr1.create(mdl, anmClr, &heap_allocator, nullptr, 1)) { + return false; + } + mAnmMatClr1.setRate(1.0f, 0); + mMdl1.getModel().setAnm(mAnmMatClr1); + } + + if (isNotSmall()) { + void *fxData = getOarcResFile(sOpenArcName); + if (fxData == nullptr) { + return false; + } + nw4r::g3d::ResFile fxRes = fxData; + if (!fxRes.mFile.IsValid()) { + return false; + } + + nw4r::g3d::ResMdl openMdl = fxRes.GetResMdl(sOpenMdlName); + if (!openMdl.IsValid()) { + return false; + } + if (!mOpenFxMdl.create(openMdl, &heap_allocator, 0x120)) { + return false; + } + mOpenFxMdl.setPriorityDraw(0x7F, 0x86); + + nw4r::g3d::ResAnmChr openAnm = fxRes.GetResAnmChr(sOpenAnmChrName); + if (!openAnm.mAnmChr.IsValid()) { + return false; + } + if (!mAnmChr.create(openMdl, openAnm, &heap_allocator, nullptr)) { + return false; + } + mOpenFxMdl.setAnm(mAnmChr); + + nw4r::g3d::ResAnmTexSrt anmTexSrt = fxRes.GetResAnmTexSrt(sOpenAnmTexSrtName); + if (!anmTexSrt.mAnmTexSrt.IsValid()) { + return false; + } + if (!mAnmTexSrt1.create(openMdl, anmTexSrt, &heap_allocator, nullptr, 1)) { + return false; + } + mOpenFxMdl.setAnm(mAnmTexSrt1); + + nw4r::g3d::ResAnmClr anmClr = fxRes.GetResAnmClr(sOpenAnmClrName); + if (!anmClr.mAnmClr.IsValid()) { + return false; + } + if (!mAnmMatClr2.create(openMdl, anmClr, &heap_allocator, nullptr, 1)) { + return false; + } + mOpenFxMdl.setAnm(mAnmMatClr2); + mVec3_c fxPos; + fn_8026B380(fxPos); + mMtx_c fxTransform; + fxTransform.transS(fxPos); + // TODO address calculations here + fxTransform.ZXYrotM(rotation.x, rotation.y, rotation.y); + mOpenFxMdl.setLocalMtx(mWorldMtx); + mOpenFxMdl.setScale(fn_8026B3C0()); + } + + return true; +} + void dAcTbox_c::initializeState_DugOut() {} void dAcTbox_c::executeState_DugOut() {} void dAcTbox_c::finalizeState_DugOut() {} @@ -79,3 +262,7 @@ void dAcTbox_c::finalizeState_Wait() {} void dAcTbox_c::initializeState_GoddessWait() {} void dAcTbox_c::executeState_GoddessWait() {} void dAcTbox_c::finalizeState_GoddessWait() {} + +bool dAcTbox_c::isNotSmall() const { + return mVariant != 1; +}