diff options
| author | Elijah Thomas <42302100+elijah-thomas774@users.noreply.github.com> | 2026-10-02 20:32:12 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-10-02 20:32:12 -0400 |
| commit | 98aba2c59b9bcd261d98cd8843bc40ae0b2d6877 (patch) | |
| tree | ab75b4ec8add5790a870a9a60d158519c10e434e | |
| parent | aec7b6f81ab79b07cd94a7754b592bc22c231041 (diff) | |
| parent | de0fcc21dd700bf25e417147820388d194a59b33 (diff) | |
Merge pull request #345 from elijah-thomas774/d_a_obj_mushroom
d_a_obj_mushroom
| -rw-r--r-- | config/SOUE01/rels/d_a_obj_mushroomNP/symbols.txt | 107 | ||||
| -rw-r--r-- | config/SOUE01/symbols.txt | 6 | ||||
| -rw-r--r-- | include/d/a/obj/d_a_obj_mushroom.h | 222 | ||||
| -rw-r--r-- | include/d/col/c/c_cc_d.h | 4 | ||||
| -rw-r--r-- | include/d/col/c/c_m3d.h | 2 | ||||
| -rw-r--r-- | include/egg/gfx/eggCamera.h | 5 | ||||
| -rw-r--r-- | include/toBeSorted/d_unk_mdl_stuff_2.h | 36 | ||||
| -rw-r--r-- | src/REL/d/a/obj/d_a_obj_mushroom.cpp | 1161 | ||||
| -rw-r--r-- | src/d/col/c/c_m3d.cpp | 6 |
9 files changed, 1481 insertions, 68 deletions
diff --git a/config/SOUE01/rels/d_a_obj_mushroomNP/symbols.txt b/config/SOUE01/rels/d_a_obj_mushroomNP/symbols.txt index 96105eb5..f34691bd 100644 --- a/config/SOUE01/rels/d_a_obj_mushroomNP/symbols.txt +++ b/config/SOUE01/rels/d_a_obj_mushroomNP/symbols.txt @@ -3,63 +3,63 @@ _epilog = .text:0x00000030; // type:function size:0x2C scope:global _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 -fn_328_F0 = .text:0x000000F0; // type:function size:0x40 +__dt__7mVec3_cFv = .text:0x000000F0; // type:function size:0x40 dAcOMushRoom_c_classInit__Fv = .text:0x00000130; // type:function size:0x1C0 -fn_328_2F0 = .text:0x000002F0; // type:function size:0x18 -fn_328_310 = .text:0x00000310; // type:function size:0x80 -fn_328_390 = .text:0x00000390; // type:function size:0x78 -fn_328_410 = .text:0x00000410; // type:function size:0x58 +__ct__Q26dLOD_c5mdl_cFv = .text:0x000002F0; // type:function size:0x18 +__dt__Q26dLOD_c5mdl_cFv = .text:0x00000310; // type:function size:0x80 +__dt__9dMdlLOD_cFv = .text:0x00000390; // type:function size:0x78 +__dt__15dShadowCircle_cFv = .text:0x00000410; // type:function size:0x58 __dt__27sFState_c<14dAcOMushRoom_c>Fv = .text:0x00000470; // type:function size:0x58 __dt__30sFStateFct_c<14dAcOMushRoom_c>Fv = .text:0x000004D0; // type:function size:0x6C __dt__83sStateMgr_c<14dAcOMushRoom_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x00000540; // type:function size:0xA0 __dt__53sFStateMgr_c<14dAcOMushRoom_c,20sStateMethodUsr_FI_c>Fv = .text:0x000005E0; // type:function size:0xA4 -fn_328_690 = .text:0x00000690; // type:function size:0x4 -fn_328_6A0 = .text:0x000006A0; // type:function size:0x5C -fn_328_700 = .text:0x00000700; // type:function size:0x7C -fn_328_780 = .text:0x00000780; // type:function size:0x64 -fn_328_7F0 = .text:0x000007F0; // type:function size:0x40 -fn_328_830 = .text:0x00000830; // type:function size:0x1C4 -AcOMushRoom__initModels = .text:0x00000A00; // type:function size:0x194 -AcOMushRoom__init = .text:0x00000BA0; // type:function size:0x424 +__ct__7mVec3_cFv = .text:0x00000690; // type:function size:0x4 +__ct__Q214dAcOMushRoom_c6proc_cFv = .text:0x000006A0; // type:function size:0x5C +__dt__Q214dAcOMushRoom_c6proc_cFv = .text:0x00000700; // type:function size:0x7C +__dt__Q214dAcOMushRoom_c8camera_cFv = .text:0x00000780; // type:function size:0x64 +__dt__Q23EGG11OrthoCameraFv = .text:0x000007F0; // type:function size:0x40 +fn_328_830__FScSc = .text:0x00000830; // type:function size:0x1C4 +createHeap__14dAcOMushRoom_cFv = .text:0x00000A00; // type:function size:0x194 +create__14dAcOMushRoom_cFv = .text:0x00000BA0; // type:function size:0x424 changeState__83sStateMgr_c<14dAcOMushRoom_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x00000FD0; // type:function size:0x10 -fn_328_FE0 = .text:0x00000FE0; // type:function size:0xFC -AcOMushRoom__update = .text:0x000010E0; // type:function size:0x1CC +doDelete__14dAcOMushRoom_cFv = .text:0x00000FE0; // type:function size:0xFC +actorExecute__14dAcOMushRoom_cFv = .text:0x000010E0; // type:function size:0x1CC executeState__83sStateMgr_c<14dAcOMushRoom_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x000012B0; // type:function size:0x10 -AcOMushRoom__draw = .text:0x000012C0; // type:function size:0x2C0 +draw__14dAcOMushRoom_cFv = .text:0x000012C0; // type:function size:0x2C0 initializeState_Wait__14dAcOMushRoom_cFv = .text:0x00001580; // type:function size:0x50 executeState_Wait__14dAcOMushRoom_cFv = .text:0x000015D0; // type:function size:0xD68 -fn_328_2340 = .text:0x00002340; // type:function size:0x1C +calcTimer<Ul>__4sLibFPUl_Ul = .text:0x00002340; // type:function size:0x1C finalizeState_Wait__14dAcOMushRoom_cFv = .text:0x00002360; // type:function size:0x4 initializeState_Init__14dAcOMushRoom_cFv = .text:0x00002370; // type:function size:0x4 executeState_Init__14dAcOMushRoom_cFv = .text:0x00002380; // type:function size:0x18 finalizeState_Init__14dAcOMushRoom_cFv = .text:0x000023A0; // type:function size:0x4 -fn_328_23B0 = .text:0x000023B0; // type:function size:0xB8 -fn_328_2470 = .text:0x00002470; // type:function size:0xBC -fn_328_2530 = .text:0x00002530; // type:function size:0x34 -fn_328_2570 = .text:0x00002570; // type:function size:0x34 -fn_328_25B0 = .text:0x000025B0; // type:function size:0xC4 -AcOMushRoom__getArcName = .text:0x00002680; // type:function size:0xB0 -AcOMushRoom__getArcName2 = .text:0x00002730; // type:function size:0x4 -AcOMushRoom__getBtiName = .text:0x00002740; // type:function size:0xF8 -fn_328_2840 = .text:0x00002840; // type:function size:0x208 -fn_328_2A50 = .text:0x00002A50; // type:function size:0x224 -fn_328_2C80 = .text:0x00002C80; // type:function size:0x76C -fn_328_33F0 = .text:0x000033F0; // type:function size:0x88 -fn_328_3480 = .text:0x00003480; // type:function size:0x30C -fn_328_3790 = .text:0x00003790; // type:function size:0x230 -fn_328_39C0 = .text:0x000039C0; // type:function size:0x72C -fn_328_40F0 = .text:0x000040F0; // type:function size:0xE8 -fn_328_41E0 = .text:0x000041E0; // type:function size:0x38 -fn_328_4220 = .text:0x00004220; // type:function size:0xC -fn_328_4230 = .text:0x00004230; // type:function size:0x4EC -fn_328_4720 = .text:0x00004720; // type:function size:0xB0 -fn_328_47D0 = .text:0x000047D0; // type:function size:0x350 -fn_328_4B20 = .text:0x00004B20; // type:function size:0x108 -fn_328_4C30 = .text:0x00004C30; // type:function size:0x19C -fn_328_4DD0 = .text:0x00004DD0; // type:function size:0xCC -fn_328_4EA0 = .text:0x00004EA0; // type:function size:0x4C -fn_328_4EF0 = .text:0x00004EF0; // type:function size:0xC0 -fn_328_4FB0 = .text:0x00004FB0; // type:function size:0x84 +getUnscaledRadiusX__14dAcOMushRoom_cFv = .text:0x000023B0; // type:function size:0xB8 +getUnscaledRadiusY__14dAcOMushRoom_cFv = .text:0x00002470; // type:function size:0xBC +getRadiusX__14dAcOMushRoom_cFv = .text:0x00002530; // type:function size:0x34 +getShadowOffsetY__14dAcOMushRoom_cFv = .text:0x00002570; // type:function size:0x34 +getRadiusZ__14dAcOMushRoom_cFv = .text:0x000025B0; // type:function size:0xC4 +getResFileName__14dAcOMushRoom_cFv = .text:0x00002680; // type:function size:0xB0 +getResMdlName__14dAcOMushRoom_cFv = .text:0x00002730; // type:function size:0x4 +getDataBinName__14dAcOMushRoom_cFv = .text:0x00002740; // type:function size:0xF8 +initCc__14dAcOMushRoom_cFv = .text:0x00002840; // type:function size:0x208 +setCc__14dAcOMushRoom_cFv = .text:0x00002A50; // type:function size:0x224 +startCloudEmitter__14dAcOMushRoom_cFv = .text:0x00002C80; // type:function size:0x76C +rndRange<i>__2cMFii_i = .text:0x000033F0; // type:function size:0x88 +startGlitterEmitter__14dAcOMushRoom_cFv = .text:0x00003480; // type:function size:0x30C +fn_328_3970__14dAcOMushRoom_cFv = .text:0x00003790; // type:function size:0x230 +fn_328_39C0__14dAcOMushRoom_cFv = .text:0x000039C0; // type:function size:0x72C +create__Q214dAcOMushRoom_c6proc_cFPQ23EGG7ResTIMGUlP12mAllocator_clP7mVec3_cP7mVec3_cPUsPUs = .text:0x000040F0; // type:function size:0xE8 +entryIdx__Q214dAcOMushRoom_c6proc_cFUs = .text:0x000041E0; // type:function size:0x38 +clearIdx__Q214dAcOMushRoom_c6proc_cFv = .text:0x00004220; // type:function size:0xC +drawOpa__Q214dAcOMushRoom_c6proc_cFv = .text:0x00004230; // type:function size:0x4EC +draw__Q214dAcOMushRoom_c6proc_cFv = .text:0x00004720; // type:function size:0xB0 +updateCameras__14dAcOMushRoom_cFv = .text:0x000047D0; // type:function size:0x350 +fn_328_4B20__14dAcOMushRoom_cFRC6mMtx_cRC7mVec3_cff = .text:0x00004B20; // type:function size:0x108 +fn_328_4C30__14dAcOMushRoom_cFRCfRCsP8cCcD_ObjRCfRCf = .text:0x00004C30; // type:function size:0x19C +setLighting__14dAcOMushRoom_cFv = .text:0x00004DD0; // type:function size:0xCC +cutLighting__14dAcOMushRoom_cFv = .text:0x00004EA0; // type:function size:0x4C +fn_328_4EF0__14dAcOMushRoom_cFv = .text:0x00004EF0; // type:function size:0xC0 +checkUnderWater__14dAcOMushRoom_cFv = .text:0x00004FB0; // type:function size:0x84 __dt__14dAcOMushRoom_cFv = .text:0x00005040; // type:function size:0x198 getStateID__83sStateMgr_c<14dAcOMushRoom_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x000051E0; // type:function size:0x10 build__30sFStateFct_c<14dAcOMushRoom_c>FRC12sStateIDIf_c = .text:0x000051F0; // type:function size:0x60 @@ -78,7 +78,7 @@ executeState__29sFStateID_c<14dAcOMushRoom_c>CFR14dAcOMushRoom_c = .text:0x00005 initializeState__29sFStateID_c<14dAcOMushRoom_c>CFR14dAcOMushRoom_c = .text:0x00005380; // type:function size:0x30 __sinit_\d_a_obj_mushroom_cpp = .text:0x000053B0; // type:function size:0x26C scope:local __dt__29sFStateID_c<14dAcOMushRoom_c>Fv = .text:0x00005620; // type:function size:0x58 -fn_328_5680 = .text:0x00005680; // type:function size:0x68 +__ct__Q214dAcOMushRoom_c8camera_cFv = .text:0x00005680; // type:function size:0x68 isSameName__29sFStateID_c<14dAcOMushRoom_c>CFPCc = .text:0x000056F0; // type:function size:0x88 _ctors = .ctors:0x00000000; // type:label scope:global _dtors = .dtors:0x00000000; // type:label scope:global @@ -102,14 +102,15 @@ lbl_328_data_40 = .data:0x00000040; // type:object size:0x30 lbl_328_data_70 = .data:0x00000070; // type:object size:0x58 lbl_328_data_C8 = .data:0x000000C8; // type:object size:0x98 lbl_328_data_160 = .data:0x00000160; // type:object size:0xA data:string -lbl_328_data_170 = .data:0x00000170; // type:object size:0x80 -lbl_328_data_1F0 = .data:0x000001F0; // type:object size:0x30 -lbl_328_data_220 = .data:0x00000220; // type:object size:0x30 -lbl_328_data_250 = .data:0x00000250; // type:object size:0x18 -lbl_328_data_268 = .data:0x00000268; // type:object size:0x18 -lbl_328_data_280 = .data:0x00000280; // type:object size:0x2C data:4byte -lbl_328_data_2AC = .data:0x000002AC; // type:object size:0x2C -lbl_328_data_2D8 = .data:0x000002D8; // type:object size:0x94 +__vt__14dAcOMushRoom_c = .data:0x00000170; // type:object size:0x7C +__vt__53sFStateMgr_c<14dAcOMushRoom_c,20sStateMethodUsr_FI_c> = .data:0x000001F0; // type:object size:0x30 +__vt__83sStateMgr_c<14dAcOMushRoom_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x00000220; // type:object size:0x30 +__vt__30sFStateFct_c<14dAcOMushRoom_c> = .data:0x00000250; // type:object size:0x18 +__vt__27sFState_c<14dAcOMushRoom_c> = .data:0x00000268; // type:object size:0x18 +__vt__Q214dAcOMushRoom_c6proc_c = .data:0x00000280; // type:object size:0x2C data:4byte +__vt__9dMdlLOD_c = .data:0x000002AC; // type:object size:0x2C +__vt__15dShadowCircle_c = .data:0x000002D8; // type:object size:0xC +lbl_328_data_2E4 = .data:0x000002E4; // type:object size:0x88 lbl_328_data_36C = .data:0x0000036C; // type:object size:0x34 __global_destructor_chain = .bss:0x00000000; // type:object size:0x4 scope:global lbl_328_bss_8 = .bss:0x00000008; // type:object size:0x70 data:4byte diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 3fefff01..303631b6 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -724,11 +724,11 @@ ExecCallback_CALC_MAT__Q34nw4r3g3d15IScnObjCallbackFQ44nw4r3g3d6ScnObj6TimingPQ3 fn_8001F700 = .text:0x8001F700; // type:function size:0xA8 fn_8001F7B0 = .text:0x8001F7B0; // type:function size:0x64 sprintf__15SizedString<32>FPCce = .text:0x8001F820; // type:function size:0xD0 -fn_8001F8F0 = .text:0x8001F8F0; // type:function size:0x14 -fn_8001F910 = .text:0x8001F910; // type:function size:0xD4 +setLODDistance__6dLOD_cFlf = .text:0x8001F8F0; // type:function size:0x14 +getMdl__6dLOD_cFRQ23m3d6smdl_c = .text:0x8001F910; // type:function size:0xD4 fn_8001F9F0 = .text:0x8001F9F0; // type:function size:0xB4 fn_8001FAB0 = .text:0x8001FAB0; // type:function size:0x140 -fn_8001FBF0 = .text:0x8001FBF0; // type:function size:0xA4 +create__9dMdlLOD_cFPvPCcP16mHeapAllocator_cUl = .text:0x8001FBF0; // type:function size:0xA4 fn_8001FCA0 = .text:0x8001FCA0; // type:function size:0x60 fn_8001FD00 = .text:0x8001FD00; // type:function size:0x64 fn_8001FD70 = .text:0x8001FD70; // type:function size:0xA8 diff --git a/include/d/a/obj/d_a_obj_mushroom.h b/include/d/a/obj/d_a_obj_mushroom.h index be711fa7..8247b68b 100644 --- a/include/d/a/obj/d_a_obj_mushroom.h +++ b/include/d/a/obj/d_a_obj_mushroom.h @@ -1,19 +1,237 @@ #ifndef D_A_OBJ_MUSHROOM_H #define D_A_OBJ_MUSHROOM_H +#include "common.h" #include "d/a/obj/d_a_obj_base.h" +#include "d/col/c/c_cc_d.h" +#include "d/col/cc/d_cc_d.h" +#include "d/d_light_env.h" +#include "d/d_shadow.h" +#include "egg/egg_types.h" +#include "egg/gfx/eggCamera.h" +#include "m/m3d/m_proc.h" +#include "m/m_allocator.h" +#include "m/m_angle.h" +#include "m/m_mtx.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" +#include "toBeSorted/d_emitter.h" +#include "toBeSorted/d_unk_mdl_stuff_2.h" class dAcOMushRoom_c : public dAcObjBase_c { public: - dAcOMushRoom_c() : mStateMgr(*this) {} + class proc_c : public m3d::proc_c { + public: + proc_c() : mpImg(nullptr), mpIdxArr(nullptr), field_0x20(0), mIdxNum(0), mIdxMax(0) {} + virtual ~proc_c() { + remove(); + } + virtual void drawOpa() override; + void draw(); + + bool create( + EGG::ResTIMG *pImg, u32 drawOpa, mAllocator_c *pAllocator, s32 idxNum, mVec3_c *pVtx, mVec3_c *pNrm, + u16 *pVtxIdx, u16 *pNrmIdx + ); + bool entryIdx(u16 idx); + void clearIdx(); + + /* 0x18 */ EGG::ResTIMG *mpImg; + /* 0x1C */ u16 *mpIdxArr; + /* 0x20 */ u32 field_0x20; + /* 0x24 */ s32 mIdxNum; + /* 0x28 */ s32 mIdxMax; + /* 0x2C */ u32 mCameraIdx; + /* 0x30 */ u32 mCameraSubIdx; + /* 0x34 */ u8 mTev0Alpha; + /* 0x38 */ mVec3_c *mpVtxArr; + /* 0x3C */ mVec3_c *mpNrmArr; + /* 0x40 */ u16 *mpVtxIdxArr; + /* 0x44 */ u16 *mpNrmIdxArr; + }; + + class camera_c { + public: + camera_c() : field_0x1B6(0) { + for (int i = 0; i < 3; ++i) { + mAlpha[i] = 0; + field_0x1B3[i] = 0; + } + } + ~camera_c(); + + /* 0x000 */ EGG::OrthoCamera mCam[3]; + /* 0x1B0 */ u8 mAlpha[3]; + /* 0x1B3 */ u8 field_0x1B3[3]; + /* 0x1B6 */ u8 field_0x1B6; + }; + static camera_c sCameras[8]; + + dAcOMushRoom_c() : mStateMgr(*this), mEmitter(this) {} virtual ~dAcOMushRoom_c() {} + virtual int create() override; + virtual int doDelete() override; + virtual int draw() override; + virtual bool createHeap() override; + virtual int actorExecute() override; + STATE_FUNC_DECLARE(dAcOMushRoom_c, Wait); STATE_FUNC_DECLARE(dAcOMushRoom_c, Init); + STATE_MGR_DEFINE_UTIL_ISSTATE(dAcOMushRoom_c); + STATE_MGR_DEFINE_UTIL_EXECUTESTATE(dAcOMushRoom_c); + STATE_MGR_DEFINE_UTIL_CHANGESTATE(dAcOMushRoom_c); + + f32 getUnscaledRadiusX(); + f32 getUnscaledRadiusY(); + f32 getRadiusX(); + f32 getShadowOffsetY(); + f32 getRadiusZ(); + + void initCc(); + void setCc(); + void startCloudEmitter(); + void startGlitterEmitter(); + void fn_328_3970(); + bool fn_328_39C0(); + void updateCameras(); + bool fn_328_4B20(const mMtx_c &m, const mVec3_c &v, f32 zHi, f32 zLo); + bool fn_328_4C30(const f32 &radius, const s16 &angle, cCcD_Obj *ccObj, const f32 &yHi, const f32 &yLo); + void setLighting(); + void cutLighting(); + void fn_328_4EF0(); + bool checkUnderWater(); + + enum SpawnedActorSubtype_e { + SPAWN_Param = 0, + SPAWN_MushroomA, + SPAWN_MushroomB, + SPAWN_MushroomC, + SPAWN_MushroomD, + }; + // The Actual Type + enum Type_e { + TYPE_MushroomA, + TYPE_MushroomB, + TYPE_MushroomC, + TYPE_MushroomD, + TYPE_Max + }; + s32 getType() { + s32 type; + if (mActorSubtype == SPAWN_Param) { // Spawned as "Mushroom" + switch ((s32)getFromParams(0, 0xF)) { + case TYPE_MushroomA: type = TYPE_MushroomA; break; + case TYPE_MushroomB: type = TYPE_MushroomB; break; + case TYPE_MushroomC: type = TYPE_MushroomC; break; + case TYPE_MushroomD: type = TYPE_MushroomD; break; + default: type = TYPE_MushroomA; break; + } + } else { // Spawned as "MushroomA", "MushroomB", "MushroomC", "MushroomD" + switch (mActorSubtype) { + case SPAWN_MushroomA: type = TYPE_MushroomA; break; + case SPAWN_MushroomB: type = TYPE_MushroomB; break; + case SPAWN_MushroomC: type = TYPE_MushroomC; break; + case SPAWN_MushroomD: type = TYPE_MushroomD; break; + default: type = TYPE_MushroomA; break; + } + } + return type; + } + + bool isNotParamBit30() { + return mActorSubtype == SPAWN_Param && (s32)getFromParams(30, 0x1) == 0; + } + + bool checkGlittering() { + return getFromParams(31, 1) == 1 && field_0x892; + } + + dCcD_Sph &getMainCc() { + return mSph0; + } + s32 getSporeParams1() const { + return field_0x892 != 0 ? 1 : 0; + } + + int findCameraIdx() { + for (int i = 0; i < 8; ++i) { + bool found; + if (sCameras[i].field_0x1B6 == 0) { + sCameras[i].field_0x1B6 = 1; + found = true; + } else { + found = false; + } + if (found) { + return i; + } + } + return -1; + } + + void clearField_0x854() { + if (mSph0.ChkTgHit() && mSph0.ChkTgAtHitType(AT_TYPE_BELLOWS)) { + return; + } + + if (!mSph0.ChkTgHit()) { + return; + } + field_0x854 = 0; + } + +private: + const char *getResFileName(); + const char *getResMdlName(); + const char *getDataBinName(); + private: - /* 0x??? */ STATE_MGR_DECLARE(dAcOMushRoom_c); + /* 0x330 */ nw4r::g3d::ResFile mRes; + /* 0x334 */ dMdlLOD_c mMdl; + /* 0x360 */ dShadowCircle_c mShadow; + /* 0x368 */ dCcD_Sph mSph0; + /* 0x4B8 */ dCcD_Cyl mCyl; + /* 0x608 */ dCcD_Sph mSph1; + /* 0x758 */ STATE_MGR_DECLARE(dAcOMushRoom_c); + /* 0x794 */ mAng3_c field_0x794; + /* 0x79C */ u32 field_0x79C; + /* 0x7A0 */ u8 field_0x7A0; + /* 0x7A1 */ u8 field_0x7A1; + /* 0x7A4 */ mVec3_c field_0x7A4; + /* 0x7B0 */ mVec3_c field_0x7B0; + /* 0x7BC */ f32 field_0x7BC; + /* 0x7C0 */ s32 field_0x7C0; + /* 0x7C4 */ mVec3_c field_0x7C4[3]; + /* 0x7E8 */ mVec3_c field_0x7E8[3]; + /* 0x80C */ mVec3_c field_0x80C[3]; + /* 0x830 */ int mProcAlpha[3]; + /* 0x83C */ u8 field_0x83C[3]; + /* 0x83F */ u8 field_0x83F[3]; + /* 0x844 */ mVec3_c field_0x844; + /* 0x850 */ s32 mCameraIdx; + /* 0x854 */ s32 field_0x854; + /* 0x858 */ LIGHT_INFLUENCE mLightInfluence; + /* 0x874 */ SHADOW_INFLUENCE mShadowInfluence; + /* 0x888 */ s32 field_0x888; + /* 0x88C */ s32 field_0x88C; + /* 0x890 */ u8 field_0x890; + /* 0x891 */ u8 field_0x891; + /* 0x892 */ u8 field_0x892; + /* 0x894 */ dAcObjRef_c mRef; + /* 0x8A0 */ dEmitter_c mEmitter; + + /* 0x8D4 */ proc_c mProc[3]; + + // Mushroom Bin Data info + /* 0x9AC */ s32 mData_VecNum; + /* 0x9B0 */ s32 mData_IdxMax; + /* 0x9B4 */ mVec3_c *mData_pPosArr; + /* 0x9B8 */ mVec3_c *mData_pNrmArr; + /* 0x9BC */ u16 *mData_pPosIdxArr; + /* 0x9C0 */ u16 *mData_pNrmIdxArr; }; #endif diff --git a/include/d/col/c/c_cc_d.h b/include/d/col/c/c_cc_d.h index 6c701aeb..1050ce14 100644 --- a/include/d/col/c/c_cc_d.h +++ b/include/d/col/c/c_cc_d.h @@ -332,6 +332,7 @@ struct cCcD_SrcGObjTg { }; enum dCcD_ObjAtType { + AT_TYPE_NONE = 0, /* 0x 0000 0001 */ AT_TYPE_0x1 = (1 << 0), /* 0x 0000 0002 */ AT_TYPE_SWORD = (1 << 1), /* 0x 0000 0004 */ AT_TYPE_0x4 = (1 << 2), @@ -399,7 +400,8 @@ enum cCcD_CutDir { CUT_DIR_STAB = (1 << 8), // 0x0100 CUT_DIR_ALL = - (CUT_DIR_U | CUT_DIR_LU | CUT_DIR_L | CUT_DIR_LD | CUT_DIR_D | CUT_DIR_RD | CUT_DIR_R | CUT_DIR_RU | CUT_DIR_STAB) + (CUT_DIR_U | CUT_DIR_LU | CUT_DIR_L | CUT_DIR_LD | CUT_DIR_D | CUT_DIR_RD | CUT_DIR_R | CUT_DIR_RU | + CUT_DIR_STAB) }; struct cCcD_SrcGObjAt { /* 0x00 */ u32 mType; diff --git a/include/d/col/c/c_m3d.h b/include/d/col/c/c_m3d.h index dfbd8ab7..3fdf0807 100644 --- a/include/d/col/c/c_m3d.h +++ b/include/d/col/c/c_m3d.h @@ -55,7 +55,7 @@ bool cM3d_Cross_LinTri( bool cM3d_Cross_LinTri_Easy(const cM3dGTri *, const nw4r::math::VEC3 *); bool cM3d_Cross_SphPnt(const cM3dGSph &, const nw4r::math::VEC3 *); bool cM3d_Cross_LinSph(const cM3dGLin &, const cM3dGSph &, nw4r::math::VEC3 *); -bool cM3d_Cross_LinSph_CrossPos(const cM3dGSph &, const cM3dGLin &, nw4r::math::VEC3 *, nw4r::math::VEC3 *); +BOOL cM3d_Cross_LinSph_CrossPos(const cM3dGSph &, const cM3dGLin &, nw4r::math::VEC3 *, nw4r::math::VEC3 *); bool cM3d_Cross_CylSph(const cM3dGCyl &, const cM3dGSph &, f32 *); bool cM3d_Cross_CylSph(const cM3dGCyl &, const cM3dGSph &, nw4r::math::VEC3 *, f32 *); bool cM3d_Cross_SphSph(const cM3dGSph &, const cM3dGSph &, f32 *); diff --git a/include/egg/gfx/eggCamera.h b/include/egg/gfx/eggCamera.h index 67c3853d..6f9631d0 100644 --- a/include/egg/gfx/eggCamera.h +++ b/include/egg/gfx/eggCamera.h @@ -35,8 +35,8 @@ protected: class LookAtCamera : public BaseCamera { public: LookAtCamera() : mPos(0.0f, 10.0f, 0.0f), mAt(0.0f, 0.0f, 0.0f), mUp(0.0f, 1.0f, 0.0f) {} - - LookAtCamera& operator=(const LookAtCamera &other) { + + LookAtCamera &operator=(const LookAtCamera &other) { mViewMtx.copyFrom(other.mViewMtx); mOtherMtx.copyFrom(other.mOtherMtx); mPos = other.mPos; @@ -79,6 +79,7 @@ public: class OrthoCamera : public LookAtCamera { public: OrthoCamera(); + ~OrthoCamera() {} virtual void doUpdateMatrix() override; diff --git a/include/toBeSorted/d_unk_mdl_stuff_2.h b/include/toBeSorted/d_unk_mdl_stuff_2.h index 0815c998..87c6edf8 100644 --- a/include/toBeSorted/d_unk_mdl_stuff_2.h +++ b/include/toBeSorted/d_unk_mdl_stuff_2.h @@ -3,13 +3,14 @@ #include "common.h" #include "m/m3d/m_proc.h" +#include "m/m3d/m_smdl.h" #include "m/m_allocator.h" #include "m/m_mtx.h" #include "m/m_vec.h" -#include "nw4r/g3d/res/g3d_resfile.h" #include "nw4r/g3d/res/g3d_resmat.h" #include "nw4r/g3d/res/g3d_resmdl.h" #include "nw4r/g3d/res/g3d_resshp.h" +#include "toBeSorted/raii_ptr.h" /** a process for drawing shapes directly */ class dShpProcBase_c : public m3d::proc_c { @@ -74,4 +75,37 @@ protected: /* 0x30 */ mMtx_c *mpTransforms; }; +class dLOD_c { +public: + class mdl_c { + public: + mdl_c() : mLODDistance(0.0f) {} + + RaiiPtr<m3d::smdl_c> mMdl; + f32 mLODDistance; + }; + + void setLODDistance(s32 idx, f32 dist); + m3d::smdl_c *getMdl(m3d::smdl_c &parent); + + // 0 - _M (Medium Detail ?) + // 1 - _L (Low Detail ?) + mdl_c mMdls[2]; +}; + +class dMdlLOD_c : public m3d::smdl_c { +public: + dMdlLOD_c() {} + virtual ~dMdlLOD_c() {} + + bool create(void *res, const char *mdlName, mHeapAllocator_c *alloc, u32 bufferOption); + m3d::smdl_c *getMdl() { + return mLod.getMdl(*this); + } + void setLODDistance(s32 idx, f32 dist) { + mLod.setLODDistance(idx, dist); + } + dLOD_c mLod; +}; + #endif diff --git a/src/REL/d/a/obj/d_a_obj_mushroom.cpp b/src/REL/d/a/obj/d_a_obj_mushroom.cpp index f5900665..01ff5ba3 100644 --- a/src/REL/d/a/obj/d_a_obj_mushroom.cpp +++ b/src/REL/d/a/obj/d_a_obj_mushroom.cpp @@ -1,13 +1,1168 @@ #include "d/a/obj/d_a_obj_mushroom.h" +#include "c/c_math.h" +#include "common.h" +#include "d/a/d_a_base.h" +#include "d/a/d_a_player.h" +#include "d/a/obj/d_a_obj_base.h" +#include "d/col/bg/d_bg_s_wtr_chk.h" +#include "d/col/c/c_cc_d.h" +#include "d/col/c/c_m3d.h" +#include "d/col/c/c_m3d_g_lin.h" +#include "d/col/c/c_m3d_g_sph.h" +#include "d/col/cc/d_cc_d.h" +#include "d/col/cc/d_cc_s.h" +#include "d/d_gfx.h" +#include "d/d_light_env.h" +#include "d/d_sc_game.h" +#include "d/snd/d_snd_wzsound.h" +#include "egg/gfx/eggCamera.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggLightManager.h" +#include "egg/gfx/eggLightTexture.h" +#include "egg/gfx/eggLightTextureMgr.h" +#include "egg/gfx/eggTexture.h" +#include "f/f_base.h" +#include "f/f_profile_name.h" +#include "m/m3d/m3d.h" +#include "m/m_color.h" +#include "m/m_mtx.h" +#include "m/m_sphere.h" +#include "m/m_vec.h" +#include "nw4r/g3d/g3d_camera.h" +#include "nw4r/g3d/g3d_dcc.h" +#include "nw4r/g3d/g3d_scnobj.h" +#include "nw4r/g3d/g3d_state.h" +#include "nw4r/g3d/res/g3d_resanmtexsrt.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXGeometry.h" +#include "rvl/GX/GXLight.h" +#include "rvl/GX/GXTev.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/GX/GXVert.h" +#include "rvl/MTX/mtx.h" +#include "s/s_Math.h" +#include "toBeSorted/d_emitter.h" + +class dAcOMushRoom_HIO_c { +public: + f32 field_0x00; + f32 field_0x04; + f32 field_0x08; + s32 field_0x0C; + u16 field_0x10; + f32 field_0x14; + f32 field_0x18; + f32 field_0x1C; + f32 field_0x20; + f32 field_0x24; + f32 field_0x28; + f32 mLightScaleS; + f32 mLightScaleT; + f32 mLightTransS; + f32 mLightTransT; + f32 field_0x3C; + f32 field_0x40; + f32 field_0x44; + f32 field_0x48; + u16 field_0x4C; + f32 field_0x50; + f32 field_0x54; + u16 field_0x58; + u16 field_0x5A; + u16 field_0x5C; + u16 field_0x5E; + u16 field_0x60; + u16 field_0x62; + u16 field_0x64; + u16 field_0x66; + + static const dAcOMushRoom_HIO_c sInstance; +}; + +const dAcOMushRoom_HIO_c dAcOMushRoom_HIO_c::sInstance = { + 0.0f, 4500.0f, 0.0f, 10, 30, 200.0f, 100.0f, 100.0f, 100.0f, 200.0f, 100.0f, 1.25f, 0.5f, 0.5f, 0.5f, + 0.0f, 0.0f, 0.0f, 0.1f, 30, 6.5f, 300.0f, 180, 230, 255, 200, 12, 79, 56, 255, +}; + +static const Vec sRadius[4] = { + {105.0f, 90.0f, 210.0f}, + {105.0f, 90.0f, 205.0f}, + {105.0f, 135.0f, 312.0f}, + {105.0f, 135.0f, 312.0f}, +}; + +extern const f32 unused_ = 0.3f; // TODO - maybe still part of HIO + SPECIAL_ACTOR_PROFILE(OBJ_MUSHROOM, dAcOMushRoom_c, fProfile::OBJ_MUSHROOM, 0x141, 0, 7); +static dCcD_SrcSph sSrcSph = { + /* mObjInf */ + {/* mObjAt */ {AT_TYPE_NONE, 0, {0, 0, 0}, 0, 0, 0, 0, CUT_DIR_NONE, 0}, + /* mObjTg */ {~AT_TYPE_COMMON0, 0x1000111, {0, 5, 0x407}, 0, CUT_DIR_NONE}, + /* mObjCo */ {0xE9}}, + /* mSphInf */ + {110.f} +}; +static dCcD_SrcCyl sSrcCyl = { + /* mObjInf */ + {/* mObjAt */ {AT_TYPE_NONE, 0, {0, 0, 0}, 0, 0, 0, 0, CUT_DIR_NONE, 0}, + /* mObjTg */ {~AT_TYPE_COMMON0, 0x1000110, {0, 5, 0x407}, 0, CUT_DIR_NONE}, + /* mObjCo */ {0xE9}}, + /* mSphInf */ + {135.0f, 30.0f} +}; + +static mVec3_c sBboxMin[4] = { + mVec3_c(-150.0, -30.0, -150.0), + mVec3_c(-100.0, -30.0, -100.0), + mVec3_c(-100.0, -30.0, -100.0), + mVec3_c(-100.0, -30.0, -100.0), +}; +static mVec3_c sBboxMax[4] = { + mVec3_c(150.0, 250.0, 150.0), + mVec3_c(100.0, 250.0, 100.0), + mVec3_c(100.0, 350.0, 100.0), + mVec3_c(100.0, 250.0, 100.0), +}; + STATE_DEFINE(dAcOMushRoom_c, Wait); STATE_DEFINE(dAcOMushRoom_c, Init); -void dAcOMushRoom_c::initializeState_Wait() {} -void dAcOMushRoom_c::executeState_Wait() {} +dAcOMushRoom_c::camera_c dAcOMushRoom_c::sCameras[8]; + +dAcOMushRoom_c::camera_c::~camera_c() {} + +static mMtx_c fn_328_830(s8 camIdx, s8 camSubIdx) { + nw4r::g3d::Camera cam = m3d::getCamera(10); + cam.SetOrtho( + dGfx_c::getCurrentScreenTopF(), dGfx_c::getCurrentScreenBottomF(), dGfx_c::getCurrentScreenLeftF(), + dGfx_c::getCurrentScreenRightF(), 0.1f, 1000.0f + ); + + dAcOMushRoom_c::camera_c &sCam = dAcOMushRoom_c::sCameras[camIdx]; + const dAcOMushRoom_HIO_c &sHIO = dAcOMushRoom_HIO_c::sInstance; + + f32 lightScaleS, lightScaleT, lightTransS, lightTransT; + if (sCam.mAlpha[camSubIdx] == 0) { + lightScaleS = lightScaleT = lightTransS = lightTransT = 0.0f; + } else { + if (sCam.field_0x1B3[camSubIdx] == 1) { + lightScaleS = 3.0f; + } else { + lightScaleS = sHIO.mLightScaleS; + } + lightScaleT = sHIO.mLightScaleT; + lightTransS = sHIO.mLightTransS; + lightTransT = sHIO.mLightTransT; + + lightScaleT += 1.5f * (255.0f - sCam.mAlpha[camSubIdx]) / 255.0f; + } + + cam.SetTexMtxParam(lightScaleS, -lightScaleT, lightTransS, lightTransT); + sCam.mCam[camSubIdx].setG3DCamera(cam); + mMtx_c projMtx, camMtx; + cam.GetProjectionTexMtx(projMtx); + cam.GetCameraMtx(camMtx); + + projMtx.concat(camMtx); + + mMtx_c ret = projMtx; + return ret; +} + +template <typename T> +static inline T extract_data(void *base, size_t offset) { + return *reinterpret_cast<T *>(reinterpret_cast<u8 *>(base) + offset); +} +template <typename T> +static inline T *offset_ptr(void *base, size_t offset) { + return reinterpret_cast<T *>(reinterpret_cast<u8 *>(base) + offset); +} + +bool dAcOMushRoom_c::createHeap() { + const char *resName = getResFileName(); + const char *mdlName = getResMdlName(); + + bool result = mMdl.create(getOarcResFile(resName), mdlName, &mAllocator, 0x120); + if (!result) { + return false; + } + + mMdl.setLODDistance(0, 0.0f); + mMdl.setLODDistance(1, 4500.0f); + + void *dat = getOarcFile(resName, getDataBinName()); + + u16 numIdx = extract_data<u16>(dat, 0x08); + int posArrOffset = extract_data<u32>(dat, 0x0C); + int nrmArrOffset = extract_data<u32>(dat, 0x10); + int posIdxArrOffset = extract_data<u32>(dat, 0x14); + int nrmIdxArrOffset = extract_data<u32>(dat, 0x18); + + mData_IdxMax = extract_data<u16>(dat, 4); + mData_VecNum = numIdx / 3; + mData_pPosArr = offset_ptr<mVec3_c>(dat, posArrOffset); + mData_pNrmArr = offset_ptr<mVec3_c>(dat, nrmArrOffset); + mData_pPosIdxArr = offset_ptr<u16>(dat, posIdxArrOffset); + mData_pNrmIdxArr = offset_ptr<u16>(dat, nrmIdxArrOffset); + EGG::ResTIMG *pImg = reinterpret_cast<EGG::ResTIMG *>(getOarcFile(resName, "tex/MushroomACut0.bti")); + for (int i = 0; i < 3; ++i) { + if (!mProc[i].create( + pImg, 0x25, &mAllocator, mData_VecNum / 2 + 3, mData_pPosArr, mData_pNrmArr, mData_pPosIdxArr, + mData_pNrmIdxArr + )) { + return false; + } + } + mMdl.setPriorityDraw(0x1C, 9); + + return result; +} + +int dAcOMushRoom_c::create() { + if ((getFromParams(31, 0x1) == 1 && mActorSubtype == SPAWN_Param)) { + if (cM::rndF(1.0f) <= 0.3f) { + field_0x892 = true; + } + } + + CREATE_ALLOCATOR_SIZE(dAcOMushRoom_c, 0x2000); + initCc(); + mAcceleration = 0.0f; + mMaxSpeed = 0.0f; + changeState(StateID_Init); + mBoundingBox.Set(sBboxMin[getType()], sBboxMax[getType()]); + field_0x7BC = 0.0f; + + mCameraIdx = -1; + if (getType() == TYPE_MushroomD) { + setLighting(); + } + + if (dScGame_c::isCurrentStage("F103") || dScGame_c::isCurrentStage("F103_1") || + dScGame_c::isCurrentStage("t_tkm24")) { + if ((s32)getFromParams(4, 0xF) == 0xF) { + field_0x891 = true; + } else { + field_0x891 = false; + } + } else if (dScGame_c::isCurrentStage("F100_1")) { + if (mPosition.y < -300.0f) { + field_0x891 = true; + } else { + field_0x891 = false; + } + } else { + if ((s32)getFromParams(4, 0xF) == 0xF) { + field_0x891 = false; + } else { + field_0x891 = true; + } + } + + if (isNotParamBit30()) { + unsetActorProperty(AC_PROP_0x1); + } + + return SUCCEEDED; +} + +int dAcOMushRoom_c::doDelete() { + if (mCameraIdx >= 0) { + sCameras[mCameraIdx].field_0x1B6 = false; + mCameraIdx = -1; + } + + if (getType() == TYPE_MushroomD) { + cutLighting(); + } + + return SUCCEEDED; +} + +int dAcOMushRoom_c::actorExecute() { + if (checkGlittering()) { + startGlitterEmitter(); + } + + executeState(); + + mWorldMtx.transS(mPosition); + mWorldMtx.ZXYrotM(mRotation); + mWorldMtx.YrotM(field_0x794.y); + mWorldMtx.XrotM(field_0x794.x); + mWorldMtx.YrotM(-field_0x794.y); + mMdl.setScale(mScale.x + field_0x7BC, mScale.y + field_0x7BC, mScale.z + field_0x7BC); + mMdl.setLocalMtx(mWorldMtx); + mMdl.calc(false); + + setCc(); + fn_328_3970(); + if (getType() == TYPE_MushroomD) { + fn_328_4EF0(); + } + + return SUCCEEDED; +} + +int dAcOMushRoom_c::draw() { + drawModelType1(mMdl.getMdl()); + mSphere_c sph(mVec3_c(0.0f, getShadowOffsetY(), 0.0f), getRadiusX() * 2.0f); + if (getType() == TYPE_MushroomD) { + drawShadow(mShadow, nullptr, mWorldMtx, &sph, -1, 0xC8, 0xB4, 0xE6, 0xFF, 0.0f); + } else { + drawShadow(mShadow, nullptr, mWorldMtx, &sph, -1, -1, -1, -1, -1, 0.0f); + } + + if (mCameraIdx >= 0) { + updateCameras(); + for (int i = 0; i < 3; ++i) { + if (mProcAlpha[i] != 0) { + mMtx_c m = mWorldMtx; + m.scaleM(mScale.x + field_0x7BC, mScale.y + field_0x7BC, mScale.z + field_0x7BC); + mProc[i].setLocalMtx(m); + mProc[i].entry(); + } + } + } + + return SUCCEEDED; +} + +void dAcOMushRoom_c::initializeState_Wait() { + field_0x7A4 = mVec3_c::Zero; + field_0x7B0 = mPosition; + field_0x7B0.y += 200.0f; + field_0x7C0 = 500; +} +void dAcOMushRoom_c::executeState_Wait() { + static mAng angle = 0xAAB; + + const dAcPy_c *pPlayer = dAcPy_c::GetLink(); + dCcD_Sph &cc = getMainCc(); + + if (cc.ChkTgHit()) { + if (cc.ChkTgAtHitType(AT_TYPE_BOMB)) { + dAcObjBase_c *pObj = cc.GetTgActor(); + if (pObj != nullptr) { + mVec3_c mod = mVec3_c::Ez * 10.0f; + mod.rotY((mPosition - pObj->mPosition).atan2sX_Z()); + field_0x7A4.x += mod.x; + field_0x7A4.z += mod.z; + field_0x7C0 = 0; + field_0x79C = 30; + startSoundWithFloatParam(SE_Kinoko_SHAKE, mScale.x); + } + } else if (cc.ChkTgAtHitType(AT_TYPE_WHIP) || cc.ChkTgAtHitType(AT_TYPE_CLAWSHOT) || + cc.ChkTgAtHitType(AT_TYPE_0x40) || cc.ChkTgAtHitType(AT_TYPE_ARROW)) { + mAng hitAng = (mPosition - const_cast<const dCcD_Sph &>(cc).GetTgHitPos()).atan2sX_Z(); + mVec3_c mod = mVec3_c::Ez * (field_0x7A4.mag() + 1.5f); + if (cc.ChkTgAtHitType(AT_TYPE_CLAWSHOT)) { + mod *= 1.5f; + } + mod.rotY(hitAng); + field_0x7A4.x = mod.x; + field_0x7A4.z = mod.z; + startSoundWithFloatParam(SE_Kinoko_SHAKE, mScale.x); + } else if (cc.ChkTgAtHitType(AT_TYPE_BELLOWS)) { + if (field_0x854 % 20 == 0) { + mAng hitAng = (mPosition - const_cast<const dCcD_Sph &>(cc).GetTgHitPos()).atan2sX_Z(); + mVec3_c mod = mVec3_c::Ez * (field_0x7A4.mag() + 3.5f); + mod.rotY(hitAng); + field_0x7A4.x += mod.x; + field_0x7A4.z += mod.z; + } + field_0x854++; + } else if (cc.ChkTgAtHitType(AT_TYPE_SWORD) || cc.ChkTgAtHitType(AT_TYPE_0x800000)) { + if (dAcPy_c::GetLink() != nullptr) { + mAng hitAng = (mPosition - dAcPy_c::GetLink()->mPosition).atan2sX_Z(); + + switch (cc.GetTgAtCutDir()) { + case CUT_DIR_LU: + case CUT_DIR_L: + case CUT_DIR_LD: hitAng = hitAng + -0x4000; break; + case CUT_DIR_RD: + case CUT_DIR_R: + case CUT_DIR_RU: hitAng = hitAng + 0x4000; break; + } + mVec3_c mod = mVec3_c::Ez * (field_0x7A4.mag() + 3.0f); + mod.rotY(hitAng); + field_0x7A4.x = mod.x; + field_0x7A4.z = mod.z; + field_0x7C0 = 0; + field_0x79C = 40; + startSoundWithFloatParam(SE_Kinoko_SHAKE, mScale.x); + fn_328_39C0(); + } + } else if (cc.ChkTgAtHitType(AT_TYPE_BUBBLE)) { + if (pPlayer != nullptr) { + mVec3_c mod = mVec3_c::Ez * 3.0f; + mod.rotY(pPlayer->mRotation.y); + field_0x7A4.x += mod.x; + field_0x7A4.z += mod.z; + field_0x7C0 = 0; + field_0x79C = 30; + startSoundWithFloatParam(SE_Kinoko_SHAKE, mScale.x); + } + } + } else if (pPlayer != nullptr && pPlayer->checkFlags0x350(0x2000) || pPlayer->checkFlags0x350(0x40)) { + if (field_0x7A0 != 0) { + mVec3_c mod = mVec3_c::Ez * 10.0f; + mod.rotY(pPlayer->mRotation.y); + field_0x7A4.x += mod.x; + field_0x7A4.z += mod.z; + field_0x7C0 = 0; + field_0x79C = 30; + startSoundWithFloatParam(SE_Kinoko_SHAKE, mScale.x); + mVec3_c bubbleSpawnPos(mPosition.x, mPosition.y + getRadiusZ() + 30.0f, mPosition.z); + itemDroppingAndGivingRelated(&bubbleSpawnPos, 3); + if (pPlayer->checkFlags0x350(0x40) && field_0x891) { + dAcObjBase_c::create(fProfile::OBJ_BUBBLE, mRoomID, 4, &bubbleSpawnPos, nullptr, nullptr, 0xFFFFFFFF); + dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_727_, bubbleSpawnPos, nullptr, nullptr, nullptr, nullptr, 0, 0 + ); + } + } else { + mVec3_c mod = mVec3_c::Ez * 3.0f; + mod.rotY((mPosition - pPlayer->mPosition).atan2sX_Z()); + field_0x7A4.x += mod.x; + field_0x7A4.z += mod.z; + } + } + + if (cc.ChkTgHit() && !cc.ChkTgAtHitType(AT_TYPE_BELLOWS) || !cc.ChkTgHit()) { + field_0x854 = 0; + } + if (field_0x891 == 0) { + if ((cc.ChkTgHit() && (cc.ChkTgAtHitType(AT_TYPE_BOMB) || cc.ChkTgAtHitType(AT_TYPE_SWORD) || + cc.ChkTgAtHitType(AT_TYPE_0x800000))) || + (pPlayer != nullptr && pPlayer->checkFlags0x350(0x2000) && field_0x7A0 != 0)) { + if (!checkUnderWater()) { + u32 p1 = getSporeParams1(); + static mVec3_c sOffsets[] = { + mVec3_c(0.0f, 70.0f, 0.0f), + mVec3_c(0.0f, 80.0f, 0.0f), + mVec3_c(0.0f, 120.0f, 0.0f), + mVec3_c(0.0f, 120.0f, 0.0f), + }; + s32 type = getType(); + mVec3_c pos = mPosition + sOffsets[type] * mScale.y; + + if (dAcObjBase_c::create(this, fProfile::OBJ_SPORE, p1, &pos, nullptr, nullptr, 0, 0x3F)) { + field_0x892 = false; + } + startCloudEmitter(); + } + } + } + + mVec3_c v0 = (mPosition - field_0x7B0) * 0.05f; + v0.y = 0.0f; + field_0x7A4 += v0; + if (sLib::calcTimer(&field_0x79C) == 0) { + field_0x7A4.x *= 0.93f; + field_0x7A4.z *= 0.93f; + } + if (field_0x7A4.absXZ() > 10.0f) { + field_0x7A4.normalizeRS(); + field_0x7A4 *= 10.0f; + } + field_0x7B0 += field_0x7A4; + mVec3_c diff = field_0x7B0 - mPosition; + field_0x794.x = cM::atan2s(diff.absXZ(), diff.y); + field_0x794.y = diff.atan2sX_Z(); + if (field_0x794.x > angle) { + field_0x794.x = angle; + } + if (field_0x794.x < -(angle.mVal)) { + field_0x794.x = -angle; + } + + // TODO: Figure out the const of the cc stuff + // The loading of the values here is off + static const s16 s0 = {0x2000}; + field_0x7A0 = fn_8002eff0(mScale.x * 150.0f, s0, (cCcD_Obj *)(&cc), mScale.x * 55.0f, mScale.x * -75.0f); + if (field_0x7A0 == 0) { + static const s16 s1 = {0x4000}; + field_0x7A0 = fn_328_4C30(mScale.x * 250.0f, s0, (cCcD_Obj *)(&cc), mScale.x * 200.0f, 0.0f); + } + + if (field_0x7C0 < 1000) { + field_0x7C0++; + } + + f32 f = (30 - field_0x7C0) / 30.0f; + if (f < 0.0f) { + f = 0.0f; + } + field_0x7BC = 0.1f * mAng(field_0x7C0 * 0x1000).cos() * f; + + if (cM::isZero(field_0x7BC)) { + field_0x7A1 = false; + } else { + field_0x7A1 = true; + } + + if (field_0x7A4.absXZ() > 6.5f) { + mVec3_c pos(mPosition.x, mPosition.y + getRadiusZ() + 30.0f, mPosition.z); + itemDroppingAndGivingRelated(&pos, 3); + } +} void dAcOMushRoom_c::finalizeState_Wait() {} + void dAcOMushRoom_c::initializeState_Init() {} -void dAcOMushRoom_c::executeState_Init() {} +void dAcOMushRoom_c::executeState_Init() { + changeState(StateID_Wait); +} void dAcOMushRoom_c::finalizeState_Init() {} + +f32 dAcOMushRoom_c::getUnscaledRadiusX() { + return sRadius[getType()].x; +} + +f32 dAcOMushRoom_c::getUnscaledRadiusY() { + return sRadius[getType()].y; +} + +f32 dAcOMushRoom_c::getRadiusX() { + return getUnscaledRadiusX() * mScale.x; +} + +f32 dAcOMushRoom_c::getShadowOffsetY() { + return getUnscaledRadiusY() * mScale.x; +} + +f32 dAcOMushRoom_c::getRadiusZ() { + return sRadius[getType()].z * mScale.y; +} + +const char *dAcOMushRoom_c::getResFileName() { + if (mActorSubtype == SPAWN_Param) { + switch ((s32)getFromParams(0, 0xF)) { + case TYPE_MushroomA: return "MushroomA"; + case TYPE_MushroomB: return "MushroomB"; + case TYPE_MushroomC: return "MushroomC"; + case TYPE_MushroomD: return "MushroomD"; + } + return "MushroomA"; + } + switch (mActorSubtype) { + case SPAWN_MushroomA: return "MushroomA"; + case SPAWN_MushroomB: return "MushroomB"; + case SPAWN_MushroomC: return "MushroomC"; + case SPAWN_MushroomD: return "MushroomD"; + } + return nullptr; +} + +const char *dAcOMushRoom_c::getResMdlName() { + return getResFileName(); +} + +const char *dAcOMushRoom_c::getDataBinName() { + switch (getType()) { + case TYPE_MushroomA: return "dat/MushroomA.bin"; + case TYPE_MushroomB: return "dat/MushroomB.bin"; + case TYPE_MushroomC: return "dat/MushroomC.bin"; + case TYPE_MushroomD: return "dat/MushroomD.bin"; + } + return nullptr; +} + +void dAcOMushRoom_c::initCc() { + mStts.SetRank(12); + mSph0.Set(sSrcSph); + mSph0.SetStts(mStts); + mCyl.Set(sSrcCyl); + mCyl.SetStts(mStts); + mSph1.Set(sSrcSph); + mSph1.SetStts(mStts); + + mSph0.SetR(getRadiusX()); + switch (getType()) { + case TYPE_MushroomA: { + mCyl.SetR(mScale.x * 135.0f); + mCyl.SetH(mScale.x * 30.0f); + mSph1.SetR(0.0f); + mSph0.SetR(getRadiusX() + 20.0f); + } break; + case TYPE_MushroomB: + case TYPE_MushroomD: { + mCyl.SetR(0.0f); + mCyl.SetH(0.0f); + mSph1.SetR(0.0f); + } break; + case TYPE_MushroomC: { + mCyl.SetR(0.0f); + mCyl.SetH(0.0f); + mSph1.SetR(mScale.x * 60.0f); + } break; + } +} + +void dAcOMushRoom_c::setCc() { + s32 type = getType(); + mVec3_c center = mVec3_c::Ey * getRadiusX(); + mWorldMtx.multVec(center, center); + field_0x844 = center; + mSph0.SetC(center); + dCcS::GetInstance()->Set(&mSph0); + if (type == TYPE_MushroomB) { + mVec3_c cylC(center.x, center.y - mScale.x * 30.0f, center.z); + mCyl.SetC(cylC); + dCcS::GetInstance()->Set(&mCyl); + } else if (type == TYPE_MushroomC) { + mVec3_c sphC = mVec3_c::Ey * getRadiusX() * 1.8f; + mWorldMtx.multVec(sphC, sphC); + mSph1.SetC(sphC); + dCcS::GetInstance()->Set(&mSph1); + } +} + +void dAcOMushRoom_c::startCloudEmitter() { + static mVec3_c sOffsets[] = { + mVec3_c(0.0f, 70.0f, 0.0f), // TYPE_MushroomA + mVec3_c(0.0f, 80.0f, 0.0f), // TYPE_MushroomB + mVec3_c(0.0f, 120.0f, 0.0f), // TYPE_MushroomC + mVec3_c(0.0f, 120.0f, 0.0f), // TYPE_MushroomD + }; + mVec3_c offset = sOffsets[getType()] * mScale.y; + + mMtx_c emitterLocation; + emitterLocation.transS(mPosition); + emitterLocation.ZXYrotM(mRotation); + emitterLocation.multVec(offset, offset); + emitterLocation.transS(offset); + emitterLocation.ZYXrotM(mRotation); + emitterLocation.YrotM(cM::rndRange(-0x7FFF, 0x7FFF)); + emitterLocation.scaleM(mScale); + // 737 -> Blue Spores + // 468 -> Yellow Dust + // 467 -> Rainbow Dust + if (field_0x892) { + dEmitterBase_c *pEmmitter = + dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_467_, emitterLocation, nullptr, nullptr, 0, 0); + if (pEmmitter != nullptr) { + s32 volumeSize = 60; + if (getType() == TYPE_MushroomA) { + volumeSize = 100; + } else if (getType() == TYPE_MushroomB) { + volumeSize = 90; + } else if (getType() == TYPE_MushroomC) { + volumeSize = 80; + } + pEmmitter->setVolumeSize(volumeSize); + } + } else if (getType() == TYPE_MushroomD) { + dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_737_, emitterLocation, nullptr, nullptr, 0, 0); + } else { + dEmitterBase_c *pEmmitter = + dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_468_, emitterLocation, nullptr, nullptr, 0, 0); + if (pEmmitter != nullptr) { + s32 volumeSize = 60; + if (getType() == TYPE_MushroomA) { + volumeSize = 100; + } else if (getType() == TYPE_MushroomB) { + volumeSize = 90; + } else if (getType() == TYPE_MushroomC) { + volumeSize = 80; + } + pEmmitter->setVolumeSize(volumeSize); + } + } +} + +void dAcOMushRoom_c::startGlitterEmitter() { + static mVec3_c sOffsets[] = { + mVec3_c(0.0f, 100.0f, 0.0f), + mVec3_c(0.0f, 110.0f, 0.0f), + mVec3_c(0.0f, 180.0f, 0.0f), + mVec3_c(0.0f, 180.0f, 0.0f), + }; + + mVec3_c offset = sOffsets[getType()] * mScale.y; + + mMtx_c emitterLocation; + emitterLocation.transS(mPosition); + emitterLocation.ZXYrotM(mRotation); + emitterLocation.multVec(offset, offset); + emitterLocation.transS(offset); + emitterLocation.ZYXrotM(mRotation); + emitterLocation.YrotM(cM::rndRange(-0x7FFF, 0x7FFF)); + emitterLocation.scaleM(mScale); + if (mEmitter.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_466_, emitterLocation, nullptr, nullptr)) { + s32 volumeSize; + switch (getType()) { + case TYPE_MushroomA: + case TYPE_MushroomB: volumeSize = 120; break; + case TYPE_MushroomC: volumeSize = 108; break; + default: volumeSize = 100; break; + } + + mEmitter.setVolumeSize(volumeSize); + } +} + +void dAcOMushRoom_c::fn_328_3970() { + if (mCameraIdx < 0) { + return; + } + + bool bVisible = false; + for (int i = 0; i < 3; ++i) { + if (field_0x83F[i] != 0) { + field_0x83F[i]--; + bVisible = true; + } else { + if (mProcAlpha[i] == 0xFF) { + cM3dGSph sph; + cM3dGLin lin; + mVec3_c out0, out1; + mVec3_c start, end; + sph.Set(&field_0x844, getRadiusX()); + start = field_0x7C4[i]; + end = field_0x7E8[i]; + if (field_0x83C[i] == 1) { + start.y += 100.0f; + end.y += (mScale.x + field_0x7BC) * 100.0f; + } else { + start.y += 200.0f; + end.y += (mScale.x + field_0x7BC) * 100.0f; + } + lin.Set(start, end); + if (cM3d_Cross_LinSph_CrossPos(sph, lin, out0, out1) > 0) { + mVec3_c src; + src.set(out1); + getSoundSource()->startSoundAtPosition2(SE_Kinoko_CURE, src); + } + } + sLib::chase(&mProcAlpha[i], 0, 12); + if (mProcAlpha[i] != 0) { + bVisible = true; + } + } + } + + if (!bVisible) { + sCameras[mCameraIdx].field_0x1B6 = 0; + mCameraIdx = -1; + } +} + +bool dAcOMushRoom_c::fn_328_39C0() { + if (mCameraIdx < 0) { + mCameraIdx = findCameraIdx(); + } + if (mCameraIdx < 0) { + return false; + } + + int idx = -1; + int alpha = 0xFF; + for (int i = 0; i < 3; ++i) { + if (mProcAlpha[i] == 0) { + idx = i; + break; + } + if (alpha >= mProcAlpha[i]) { + alpha = mProcAlpha[i]; + idx = i; + } + } + if (idx < 0) { + return false; + } + + mProcAlpha[idx] = 0xFF; + field_0x83F[idx] = 10; + + const dCcD_Sph &cc = getMainCc(); + field_0x7C4[idx] = dAcPy_c::GetLink()->mPosition; + field_0x7E8[idx] = mPosition; + + mAng rot; + s32 cutDir = cc.GetTgAtCutDir(); + if (cc.ChkTgAtHitType(AT_TYPE_0x800000)) { + switch (cutDir) { + case CUT_DIR_U: + case CUT_DIR_D: + case CUT_DIR_STAB: rot = 0x4000; break; + + case CUT_DIR_L: + case CUT_DIR_R: rot = 0; break; + + case CUT_DIR_LU: + case CUT_DIR_RD: rot = -0x2000; break; + + case CUT_DIR_LD: + case CUT_DIR_RU: rot = 0x2000; break; + + default: rot = 0; break; + } + + field_0x7E8[idx].x = cc.GetTgHitPos().x; + field_0x7E8[idx].z = cc.GetTgHitPos().z; + } else { + rot = dAcPy_c::GetLink()->vt_0x258() + 0x4000; + } + + if (cutDir == CUT_DIR_STAB) { + field_0x83C[idx] = 1; + } else { + field_0x83C[idx] = 0; + } + sCameras[mCameraIdx].field_0x1B3[idx] = field_0x83C[idx]; + + if (mRotation.x != 0 || mRotation.z != 0) { + mMtx_c m; + mVec3_c v; + m.ZXYrotS(mRotation); + m.multVecSR(mVec3_c::Ey, v); + C_MTXLookAt(m, field_0x7C4[idx], mVec3_c::Ey, field_0x7E8[idx]); + m.multVecSR(v, v); + s16 a = (0x4000 - cM::atan2s(v.y, v.x)); + rot += a; + } + + if (rot > 0x4000) { + rot = -(0x7FFF - rot); + } + if (rot < -0x4000) { + rot = rot + 0x7FFF; + } + mVec3_c v0 = field_0x7E8[idx] - field_0x7C4[idx]; + mVec3_c v1 = mVec3_c::Ez; + v1.rotY(v0.atan2sX_Z()); + mMtx_c m; + m.setAxisRotation(v1, -rot.radian_c()); + m.multVec(mVec3_c::Ey, field_0x80C[idx]); + sCameras[mCameraIdx].mAlpha[idx] = 0xFF; + + proc_c &proc = mProc[idx]; + proc.clearIdx(); + mProc[idx].mCameraIdx = mCameraIdx; + + proc.mCameraSubIdx = idx; + updateCameras(); + camera_c &cam = sCameras[mCameraIdx]; + + mMtx_c view = static_cast<mMtx_c &>(cam.mCam[idx].getViewMatrix()); + mVec3_c pos = cam.mCam[idx].mPos; + mVec3_c at = cam.mCam[idx].mAt; + view.multVec(pos, pos); + view.multVec(at, at); + + mMtx_c m1 = view; + m1.concat(mWorldMtx); + + bool vals[200]; + for (int i = 0; i < mData_IdxMax; ++i) { + mVec3_c posArr = mData_pPosArr[i]; + vals[i] = fn_328_4B20(m1, posArr, pos.z, at.z); + } + for (int i = 0; i < mData_VecNum; i++) { + u16 a = mData_pPosIdxArr[3 * i + 0]; + u16 b = mData_pPosIdxArr[3 * i + 1]; + u16 c = mData_pPosIdxArr[3 * i + 2]; + if (vals[a] || vals[b] || vals[c]) { + if (!mProc[idx].entryIdx(3 * i)) { + break; + } + } + } + return true; +} + +bool dAcOMushRoom_c::proc_c::create( + EGG::ResTIMG *pImg, u32 drawOpa, mAllocator_c *pAllocator, s32 idxNum, mVec3_c *pVtx, mVec3_c *pNrm, u16 *pVtxIdx, + u16 *pNrmIdx +) { + if (!m3d::proc_c::create(pAllocator, nullptr)) { + return false; + } + + mpIdxArr = new (pAllocator->getHeap()) u16[idxNum]; + if (mpIdxArr == nullptr) { + remove(); + return false; + } + + mpVtxArr = pVtx; + mpNrmArr = pNrm; + mpVtxIdxArr = pVtxIdx; + mpNrmIdxArr = pNrmIdx; + mIdxNum = 0; + mIdxMax = idxNum; + mpImg = pImg; + setPriorityDraw(drawOpa, 0); + setOption(nw4r::g3d::ScnObj::OPTION_DISABLE_DRAW_XLU, true); + return true; +} + +bool dAcOMushRoom_c::proc_c::entryIdx(u16 idx) { + if (mIdxNum > mIdxMax) { + return false; + } + + mpIdxArr[mIdxNum] = idx; + mIdxNum++; + return true; +} + +void dAcOMushRoom_c::proc_c::clearIdx() { + mIdxNum = 0; +} + +void dAcOMushRoom_c::proc_c::drawOpa() { + EGG::LightManager *pLightMgr = m3d::getLightMgr(0); + EGG::LightTexture *pLightTexture = pLightMgr->GetTextureMgr()->getTextureByName("LmBGMulti"); + pLightTexture->load(GX_TEXMAP1); + EGG::DrawGX::LoadTexture(mpImg, GX_TEXMAP0); + + u32 pDiffColorMask; + u32 pDiffAlphaMask; + u32 pSpecColorMask; + u32 pSpecAlphaMask; + GXColor pColor; + pLightMgr->LoadLightSet(1, &pDiffColorMask, &pDiffAlphaMask, &pSpecColorMask, &pSpecAlphaMask, &pColor); + m3d::getFogMgr(0); + nw4r::g3d::G3DState::LoadFog(0); + GXSetTevColor(GX_TEVREG0, (GXColor){0, 0, 0, mTev0Alpha}); + + m3d::resetMaterial(); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0, GX_TRUE, GX_SRC_REG, GX_SRC_REG, (GXLightID)pDiffColorMask, GX_DF_CLAMP, GX_AF_SPOT); + GXSetChanCtrl(GX_ALPHA0, GX_FALSE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetChanAmbColor(GX_COLOR0, pColor); + GXSetChanMatColor(GX_COLOR0, mColor(0xFFFFFFFF)); + GXSetNumTexGens(2); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_POS, GX_TEXMTX0, GX_FALSE, GX_DUALMTX0); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX3x4, GX_TG_NRM, GX_TEXMTX1, GX_TRUE, GX_DUALMTX1); + GXSetNumTevStages(2); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_A0, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetZCompLoc(GX_TRUE); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); + GXSetZMode(true, GX_LEQUAL, false); + GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); + GXSetCullMode(GX_CULL_BACK); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX16); + GXSetVtxDesc(GX_VA_NRM, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_POS_XY, GX_F32, 0); + + GXSetArray(GX_VA_POS, mpVtxArr, sizeof(*mpVtxArr)); + GXSetArray(GX_VA_NRM, mpNrmArr, sizeof(*mpNrmArr)); + + mMtx_c view; + getViewMtx(view); + GXLoadPosMtxImm(view, GX_PNMTX0); + GXSetCurrentMtx(GX_PNMTX0); + view.inverseTransposeTo(view); + GXLoadNrmMtxImm(view, GX_PNMTX0); + + mMtx_c tex; + nw4r::g3d::Camera cam = m3d::getCurrentCamera(); + cam.GetEnvironmentTexMtx(tex); + GXLoadTexMtxImm(view, GX_TEXMTX1, GX_MTX3x4); + GXLoadTexMtxImm(tex, GX_DUALMTX1, GX_MTX3x4); + mMtx_c m = fn_328_830(mCameraIdx, mCameraSubIdx); + mMtx_c ident; + MTXIdentity(ident); + ident.concat(m); + + mMtx_c texMtx; + + nw4r::g3d::TexSrt srt; + srt.Su = 2.0f; + srt.Sv = 20.0f; + srt.R = 0.0f; + srt.Tu = 0.0f; + srt.Tv = 0.0f; + + nw4r::g3d::CalcTexMtx( + texMtx, true, srt, + nw4r::g3d::TexSrt::Flag( + nw4r::g3d::TexSrt::FLAG_ANM_EXISTS | nw4r::g3d::TexSrt::FLAG_ROT_ZERO | nw4r::g3d::TexSrt::FLAG_TRANS_ZERO + ), + nw4r::g3d::TexSrt::TEXMATRIXMODE_3DSMAX + ); + f32 xz = texMtx.m[0][2]; + texMtx.m[0][2] = texMtx.m[0][3]; + texMtx.m[0][3] = xz; + f32 yz = texMtx.m[1][2]; + texMtx.m[1][2] = texMtx.m[1][3]; + texMtx.m[1][3] = yz; + texMtx.concat(ident); + view = *reinterpret_cast<const mMtx_c *>(getLocalMtx()); + GXLoadTexMtxImm(view, GX_TEXMTX0, GX_MTX3x4); + GXLoadTexMtxImm(texMtx, GX_DUALMTX0, GX_MTX3x4); + draw(); +} + +void dAcOMushRoom_c::proc_c::draw() { + GXBegin(GX_TRIANGLES, GX_VTXFMT0, mIdxNum * 3); + for (int i = 0; i < mIdxNum; ++i) { + u16 *pVtxIdx = mpVtxIdxArr + mpIdxArr[i]; + u16 *pNrmIdx = mpNrmIdxArr + mpIdxArr[i]; + + u16 vx = *pVtxIdx++; + u16 vy = *pVtxIdx++; + u16 vz = *pVtxIdx++; + u16 nx = *pNrmIdx++; + u16 ny = *pNrmIdx++; + u16 nz = *pNrmIdx++; + + GXPosition1x16(vx); + GXNormal1x16(nx); + GXPosition1x16(vy); + GXNormal1x16(ny); + GXPosition1x16(vz); + GXNormal1x16(nz); + } + GXEnd(); +} + +void dAcOMushRoom_c::updateCameras() { + mMtx_c m0 = mWorldMtx; + mMtx_c m1; + m1.ZXYrotS(mRotation); + m1.inverse(); + m0.concat(m1); + for (int i = 0; i < 3; ++i) { + camera_c *mushCam = sCameras + mCameraIdx; + mProc[i].mTev0Alpha = mProcAlpha[i]; + mushCam->mAlpha[i] = mProcAlpha[i]; + if (mProcAlpha[i] == 0) { + mushCam->mCam[i].mPos = mVec3_c::Ez; + mushCam->mCam[i].mAt = mVec3_c::Zero; + mushCam->mCam[i].mUp = mVec3_c::Ey; + mushCam->mCam[i].EGG::LookAtCamera::doUpdateMatrix(); + } else { + mVec3_c pos = field_0x7C4[i]; + mVec3_c at = field_0x7E8[i]; + mVec3_c up = field_0x80C[i]; + + pos -= mPosition; + at -= mPosition; + if (field_0x83C[i] == 1) { + pos.y += 100.0f; + at.y += (mScale.x + field_0x7BC) * 100.0f; + } else { + pos.y += 200.0f; + at.y += (mScale.x + field_0x7BC) * 100.0f; + } + m0.multVecSR(pos); + m0.multVecSR(up); + m0.multVecSR(at); + pos += mPosition; + at += mPosition; + + mushCam->mCam[i].mPos = pos; + mushCam->mCam[i].mAt = at; + mushCam->mCam[i].mUp = up; + mushCam->mCam[i].EGG::LookAtCamera::doUpdateMatrix(); + } + } +} +bool dAcOMushRoom_c::fn_328_4B20(const mMtx_c &m, const mVec3_c &vIn, f32 zHi, f32 zLo) { + f32 tempx = 200.0f; + f32 x = tempx * 0.5f; + + f32 tempy = 100.0f; + f32 y = tempy * 0.5f; + + mVec3_c v; + m.multVec(vIn, v); + if (v.x > x) { + return false; + } + if (v.x < -x) { + return false; + } + if (v.y > y) { + return false; + } + if (v.y < -y) { + return false; + } + if (v.z > zHi) { + return false; + } + if (v.z < zLo) { + return false; + } + return true; +} + +// NONMATCHING - I dont feel like dealing with this one lol +bool dAcOMushRoom_c::fn_328_4C30(const f32 &radius, const s16 &angle, cCcD_Obj *ccObj, const f32 &yHi, const f32 &yLo) { + if (ccObj != nullptr && ccObj->ChkTgHit() && ccObj->ChkTgAtHitType(AT_TYPE_BUBBLE)) { + dAcPy_c *pPlayer = dAcPy_c::GetLinkM(); + f32 yDiff = pPlayer->mPosition.y - mPosition.y; + f32 rad = radius + 40.f; + + if ((yLo < yDiff && yDiff < yHi) && mPosition.squareDistanceToXZ(pPlayer->mPosition) < rad * rad && + labs(mAng::fromVec(mPosition - pPlayer->mPosition) - pPlayer->mAngle.y) < angle) { + pPlayer->onFlags_0x360(1); + return true; + } + } + + return false; +} +void dAcOMushRoom_c::setLighting() { + mLightInfluence.mPos = mPositionCopy3; + mLightInfluence.mClr.Set(0xC, 0x4F, 0x38, 0xFF); + mLightInfluence.mScale = 0.0f; + mLightInfluence.field_0x18 = 0; + dLightEnv_c::GetPInstance()->plight_set(&mLightInfluence); + + mShadowInfluence.mPos = mPositionCopy3; + mShadowInfluence.mPos.y += 250.0f; + mShadowInfluence.mRadius = 400.0f; + dLightEnv_c::GetPInstance()->shadow_set(&mShadowInfluence); +} + +void dAcOMushRoom_c::cutLighting() { + dLightEnv_c::GetPInstance()->plight_cut(&mLightInfluence); + dLightEnv_c::GetPInstance()->shadow_cut(&mShadowInfluence); +} + +void dAcOMushRoom_c::fn_328_4EF0() { + if (field_0x888 > 0) { + field_0x888--; + mLightInfluence.mScale = 0.0f; + } else { + if (field_0x890 != 0) { + if (field_0x88C > 0) { + field_0x88C--; + } + if (field_0x88C == 0) { + field_0x890--; + field_0x888 = 2 + cM::rndInt(10); + } + } + mLightInfluence.mScale = mScale.x * 300.0f; + mLightInfluence.mPos = mPosition; + } +} + +bool dAcOMushRoom_c::checkUnderWater() { + if (!dBgS_WtrChk::CheckPos(&mPosition, true, 200.0f, 0.0f) || + mPosition.y + mScale.y * 100.0f > dBgS_WtrChk::GetWaterHeight()) { + return false; + } + return true; +} diff --git a/src/d/col/c/c_m3d.cpp b/src/d/col/c/c_m3d.cpp index 4ac33b5a..27d79d52 100644 --- a/src/d/col/c/c_m3d.cpp +++ b/src/d/col/c/c_m3d.cpp @@ -12,9 +12,11 @@ #include "egg/math/eggMath.h" #include "m/m_vec.h" #include "nw4r/math/math_types.h" -#include "rvl/MTX.h" // IWYU pragma: export #include "rvl/MTX/vec.h" +#include "rvl/MTX.h" // IWYU pragma: export + + using namespace nw4r::math; using namespace EGG; @@ -141,7 +143,7 @@ bool cM3d_Cross_LinSph(const cM3dGLin *, const cM3dGSph *, VEC3 *) { // TODO - returns false to satisfy warning return false; } -bool cM3d_Cross_LinSph_CrossPos(const cM3dGSph &, const cM3dGLin &, VEC3 *, VEC3 *) { +BOOL cM3d_Cross_LinSph_CrossPos(const cM3dGSph &, const cM3dGLin &, VEC3 *, VEC3 *) { // TODO - returns false to satisfy warning return false; } |
