diff --git a/config/SOUE01/rels/d_t_gekotagNP/splits.txt b/config/SOUE01/rels/d_t_gekotagNP/splits.txt index 37e901f5..7bae4b0f 100644 --- a/config/SOUE01/rels/d_t_gekotagNP/splits.txt +++ b/config/SOUE01/rels/d_t_gekotagNP/splits.txt @@ -17,3 +17,6 @@ REL/global_destructor_chain.c: REL/d/t/d_t_gekotag.cpp: .text start:0x000000F0 end:0x00000D08 .ctors start:0x00000000 end:0x00000004 + .rodata start:0x00000000 end:0x00000014 + .data start:0x00000000 end:0x00000210 + .bss start:0x00000008 end:0x00000048 diff --git a/config/SOUE01/rels/d_t_gekotagNP/symbols.txt b/config/SOUE01/rels/d_t_gekotagNP/symbols.txt index f5130510..5eb85e03 100644 --- a/config/SOUE01/rels/d_t_gekotagNP/symbols.txt +++ b/config/SOUE01/rels/d_t_gekotagNP/symbols.txt @@ -4,25 +4,25 @@ _unresolved = .text:0x00000060; // type:function size:0x4 scope:global __register_global_object = .text:0x00000070; // type:function size:0x1C scope:global __destroy_global_chain = .text:0x00000090; // type:function size:0x54 scope:global dTgGekoTag_classInit__Fv = .text:0x000000F0; // type:function size:0xCC -__dt__10dTgGekoTagFv = .text:0x000001C0; // type:function size:0x58 +__dt__5dTg_cFv = .text:0x000001C0; // type:function size:0x58 __dt__23sFState_c<10dTgGekoTag>Fv = .text:0x00000220; // type:function size:0x58 __dt__26sFStateFct_c<10dTgGekoTag>Fv = .text:0x00000280; // type:function size:0x6C __dt__79sStateMgr_c<10dTgGekoTag,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x000002F0; // type:function size:0xA0 __dt__49sFStateMgr_c<10dTgGekoTag,20sStateMethodUsr_FI_c>Fv = .text:0x00000390; // type:function size:0xA4 -fn_188_440 = .text:0x00000440; // type:function size:0x14 -fn_188_460 = .text:0x00000460; // type:function size:0x58 -fn_188_4C0 = .text:0x000004C0; // type:function size:0x130 +__ct__22dAcRef_c<10dAcEgeko_c>Fv = .text:0x00000440; // type:function size:0x14 +__dt__22dAcRef_c<10dAcEgeko_c>Fv = .text:0x00000460; // type:function size:0x58 +create__10dTgGekoTagFv = .text:0x000004C0; // type:function size:0x130 changeState__79sStateMgr_c<10dTgGekoTag,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x000005F0; // type:function size:0x10 -fn_188_600 = .text:0x00000600; // type:function size:0x8 -fn_188_610 = .text:0x00000610; // type:function size:0x30 +doDelete__10dTgGekoTagFv = .text:0x00000600; // type:function size:0x8 +actorExecute__10dTgGekoTagFv = .text:0x00000610; // type:function size:0x30 executeState__79sStateMgr_c<10dTgGekoTag,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x00000640; // type:function size:0x10 -fn_188_650 = .text:0x00000650; // type:function size:0x8 +draw__10dTgGekoTagFv = .text:0x00000650; // type:function size:0x8 initializeState_Wait__10dTgGekoTagFv = .text:0x00000660; // type:function size:0x4 executeState_Wait__10dTgGekoTagFv = .text:0x00000670; // type:function size:0x4 finalizeState_Wait__10dTgGekoTagFv = .text:0x00000680; // type:function size:0x4 -fn_188_690 = .text:0x00000690; // type:function size:0x1A8 -fn_188_840 = .text:0x00000840; // type:function size:0x1C -fn_188_860 = .text:0x00000860; // type:function size:0xE0 +doExecute__10dTgGekoTagFv = .text:0x00000690; // type:function size:0x1A8 +calcTimer__2cMFPUs_Us = .text:0x00000840; // type:function size:0x1C +__dt__10dTgGekoTagFv = .text:0x00000860; // type:function size:0xE0 getStateID__79sStateMgr_c<10dTgGekoTag,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x00000940; // type:function size:0x10 build__26sFStateFct_c<10dTgGekoTag>FRC12sStateIDIf_c = .text:0x00000950; // type:function size:0x60 dispose__26sFStateFct_c<10dTgGekoTag>FRP10sStateIf_c = .text:0x000009B0; // type:function size:0xC @@ -44,18 +44,18 @@ isSameName__25sFStateID_c<10dTgGekoTag>CFPCc = .text:0x00000C80; // type:functio _ctors = .ctors:0x00000000; // type:label scope:global _dtors = .dtors:0x00000000; // type:label scope:global __destroy_global_chain_reference = .dtors:0x00000000; // type:object size:0x4 scope:global -lbl_188_rodata_0 = .rodata:0x00000000; // type:object size:0x4 data:float -lbl_188_rodata_4 = .rodata:0x00000004; // type:object size:0x4 data:float -lbl_188_rodata_8 = .rodata:0x00000008; // type:object size:0x8 data:double -lbl_188_rodata_10 = .rodata:0x00000010; // type:object size:0x4 data:float -lbl_188_data_0 = .data:0x00000000; // type:object size:0x10 data:4byte +lbl_188_rodata_0 = .rodata:0x00000000; // type:object size:0x4 scope:local data:float +lbl_188_rodata_4 = .rodata:0x00000004; // type:object size:0x4 scope:local data:float +lbl_188_rodata_8 = .rodata:0x00000008; // type:object size:0x8 scope:local data:double +lbl_188_rodata_10 = .rodata:0x00000010; // type:object size:0x4 scope:local data:float +lbl_188_data_0 = .data:0x00000000; // type:object size:0x10 scope:local data:4byte g_profile_GEKO_TAG = .data:0x00000010; // type:object size:0x10 -lbl_188_data_20 = .data:0x00000020; // type:object size:0x78 -lbl_188_data_98 = .data:0x00000098; // type:object size:0x30 -lbl_188_data_C8 = .data:0x000000C8; // type:object size:0x30 -lbl_188_data_F8 = .data:0x000000F8; // type:object size:0x18 -lbl_188_data_110 = .data:0x00000110; // type:object size:0xCC -lbl_188_data_1DC = .data:0x000001DC; // type:object size:0x34 +__vt__10dTgGekoTag = .data:0x00000020; // type:object size:0x74 +__vt__49sFStateMgr_c<10dTgGekoTag,20sStateMethodUsr_FI_c> = .data:0x00000098; // type:object size:0x30 +__vt__79sStateMgr_c<10dTgGekoTag,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x000000C8; // type:object size:0x30 +__vt__26sFStateFct_c<10dTgGekoTag> = .data:0x000000F8; // type:object size:0x14 +__vt__23sFState_c<10dTgGekoTag> = .data:0x00000110; // type:object size:0x18 +__vt__25sFStateID_c<10dTgGekoTag> = .data:0x000001DC; // type:object size:0x34 __global_destructor_chain = .bss:0x00000000; // type:object size:0x4 scope:global -lbl_188_bss_8 = .bss:0x00000008; // type:object size:0x10 -lbl_188_bss_18 = .bss:0x00000018; // type:object size:0x30 data:4byte +lbl_188_bss_8 = .bss:0x00000008; // type:object size:0x10 scope:local +StateID_Wait__10dTgGekoTag = .bss:0x00000018; // type:object size:0x30 data:4byte diff --git a/include/d/t/d_t_gekotag.h b/include/d/t/d_t_gekotag.h index 2cb4c1cf..97bbab84 100644 --- a/include/d/t/d_t_gekotag.h +++ b/include/d/t/d_t_gekotag.h @@ -2,18 +2,56 @@ #define D_T_GEKOTAG_H #include "d/a/d_a_base.h" +#include "d/a/e/d_a_e_geko.h" +#include "d/t/d_tg.h" #include "s/s_State.hpp" #include "s/s_StateMgr.hpp" -class dTgGekoTag : public dAcBase_c { +class dTgGekoTag : public dTg_c { public: dTgGekoTag() : mStateMgr(*this, sStateID::null) {} virtual ~dTgGekoTag() {} + virtual int create() override; + virtual int doDelete() override; + virtual int actorExecute() override; + virtual int draw() override; + STATE_FUNC_DECLARE(dTgGekoTag, Wait); private: - /* 0x??? */ STATE_MGR_DECLARE(dTgGekoTag); + void doExecute(); + + s32 getNumGeko() const { + return (params >> 16) & 0xF; + } + + s32 getNoSpawnRadiusParm() const { + return params & 0xFF; + } + + u8 getGekoParam() const { + return (params >> 20) & 0x3; + } + + u8 getParm3() const { + return (params >> 22) & 0xFF; + } + + f32 getNoSpawnRadius() const { + return getNoSpawnRadiusParm() != 0xFF ? getNoSpawnRadiusParm() * 100.0f : 100.0f; + } + + /* 0x0FC */ STATE_MGR_DECLARE(dTgGekoTag); + /* 0x138 */ dAcRef_c mRefs[15]; + /* 0x1EC */ u8 field_0x1EC[0x1F0 - 0x1EC]; + /* 0x1F0 */ f32 mNoSpawnRadius; + /* 0x1F4 */ s32 mNumGeko; + /* 0x1F8 */ u16 mTimer1; + /* 0x1FA */ u16 mTimer2; + /* 0x1FC */ u8 mGekoParam; + // seemingly unused + /* 0x1FD */ u8 field_0x1FD; }; #endif diff --git a/src/REL/d/t/d_t_gekotag.cpp b/src/REL/d/t/d_t_gekotag.cpp index fcaefbe0..32df5084 100644 --- a/src/REL/d/t/d_t_gekotag.cpp +++ b/src/REL/d/t/d_t_gekotag.cpp @@ -1,9 +1,100 @@ #include "d/t/d_t_gekotag.h" +#include "c/c_math.h" +#include "common.h" +#include "d/a/d_a_player.h" +#include "d/a/e/d_a_e_geko.h" +#include "d/a/obj/d_a_obj_base.h" +#include "f/f_base.h" +#include "f/f_profile_name.h" +#include "m/m_angle.h" + +#pragma explicit_zero_data on +static u32 initialRotX = 0; +static u32 initialRotY = 0; +static u32 initialRotZ = 0; +#pragma explicit_zero_data off + SPECIAL_ACTOR_PROFILE(GEKO_TAG, dTgGekoTag, fProfile::GEKO_TAG, 0xEE, 0, 0); STATE_DEFINE(dTgGekoTag, Wait); +int dTgGekoTag::create() { + mNumGeko = getNumGeko() != 0xF ? getNumGeko() : 1; + + for (int i = 0; i < mNumGeko; i++) { + mRefs[i].unlink(); + } + + // Regswaps + mNoSpawnRadius = getNoSpawnRadius(); + if (!mNoSpawnRadius) { + mNoSpawnRadius = 100.0f; + } + + mGekoParam = getGekoParam() != 3 ? getGekoParam() : 0; + field_0x1FD = getParm3(); + + mStateMgr.changeState(StateID_Wait); + + return SUCCEEDED; +} + +int dTgGekoTag::doDelete() { + return SUCCEEDED; +} + +int dTgGekoTag::actorExecute() { + mStateMgr.executeState(); + return SUCCEEDED; +} + +int dTgGekoTag::draw() { + return SUCCEEDED; +} + void dTgGekoTag::initializeState_Wait() {} -void dTgGekoTag::executeState_Wait() {} +void dTgGekoTag::executeState_Wait() { + doExecute(); +} void dTgGekoTag::finalizeState_Wait() {} + +void dTgGekoTag::doExecute() { + cM::calcTimer(&mTimer2); + if (cM::calcTimer(&mTimer1) != 0) { + return; + } + + if (dAcPy_c::LINK->getSquareDistanceTo(position) < mNoSpawnRadius * mNoSpawnRadius) { + return; + } + field_0x1FD = 0xFF; + + u32 gekoParmTmp = (params & 0xFF) | 0x3FC00000; + gekoParmTmp = (gekoParmTmp & 0xFFFF00FF) | (params & 0xFF00); + u32 gekoParm = gekoParmTmp | ((mGekoParam != 0 ? 3 : 1) << 16); + + mAng3_c gekoRot = mAng3_c(initialRotX, initialRotY, initialRotZ); + gekoRot.y = cM::rndF(65535.0f); + int numFullGekoRefs = 0; + for (int i = 0; i < mNumGeko; i++) { + if (mRefs[i].get() == nullptr) { + if (mTimer2 == 0) { + dAcObjBase_c *b = + dAcObjBase_c::create(fProfile::E_GEKO, roomid, gekoParm, &position, &gekoRot, nullptr, 0xFFFFFFFF); + + if (b != nullptr) { + mRefs[i].link(static_cast(b)); + mTimer1 = 20; + return; + } + } + } else { + numFullGekoRefs++; + } + } + + if (numFullGekoRefs == mNumGeko) { + mTimer2 = 0x96; + } +}