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
__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__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:
- /* 0x??? */ STATE_MGR_DECLARE(dAcOMushRoom_c);
+ const char *getResFileName();
+ const char *getResMdlName();
+ const char *getDataBinName();
+
+private:
+ /* 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 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
+static inline T extract_data(void *base, size_t offset) {
+ return *reinterpret_cast(reinterpret_cast(base) + offset);
+}
+template
+static inline T *offset_ptr(void *base, size_t offset) {
+ return reinterpret_cast(reinterpret_cast(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(dat, 0x08);
+ int posArrOffset = extract_data(dat, 0x0C);
+ int nrmArrOffset = extract_data(dat, 0x10);
+ int posIdxArrOffset = extract_data(dat, 0x14);
+ int nrmIdxArrOffset = extract_data(dat, 0x18);
+
+ mData_IdxMax = extract_data(dat, 4);
+ mData_VecNum = numIdx / 3;
+ mData_pPosArr = offset_ptr(dat, posArrOffset);
+ mData_pNrmArr = offset_ptr(dat, nrmArrOffset);
+ mData_pPosIdxArr = offset_ptr(dat, posIdxArrOffset);
+ mData_pNrmIdxArr = offset_ptr(dat, nrmIdxArrOffset);
+ EGG::ResTIMG *pImg = reinterpret_cast(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(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(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(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(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;
}