summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2025-05-02 23:56:58 +0200
committerrobojumper <robojumper@gmail.com>2025-05-03 08:48:10 +0200
commit207c3706b4e9896b4b625e6686a3a15b51ff5b00 (patch)
treedddc14e168f152cce88beac5294ae41312773ddf
parent594bc67d676e944980054b104368e02617428a85 (diff)
d_particle OK
-rw-r--r--config/SOUE01/splits.txt3
-rw-r--r--config/SOUE01/symbols.txt47
-rw-r--r--configure.py2
-rw-r--r--include/JSystem/JParticle/JPADynamicsBlock.h6
-rw-r--r--include/JSystem/JParticle/JPAEmitter.h14
-rw-r--r--include/d/d_stage_mgr.h5
-rw-r--r--include/egg/gfx/eggCpuTexture.h14
-rw-r--r--include/toBeSorted/d_particle.h96
-rw-r--r--src/toBeSorted/d_particle.cpp169
9 files changed, 322 insertions, 34 deletions
diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt
index 68ce0d6f..75a194e2 100644
--- a/config/SOUE01/splits.txt
+++ b/config/SOUE01/splits.txt
@@ -454,6 +454,9 @@ toBeSorted/special_item_drop_mgr.cpp:
toBeSorted/d_particle.cpp:
.text start:0x800C82B0 end:0x800C8948 align:16
+ .data start:0x80511C60 end:0x80511C80
+ .sdata start:0x80572310 end:0x80572318
+ .sbss start:0x80575440 end:0x80575448
d/lyt/meter/d_lyt_meter.cpp:
.text start:0x800C8950 end:0x800DF8A8 align:16
diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt
index 2890520f..d60aa2a7 100644
--- a/config/SOUE01/symbols.txt
+++ b/config/SOUE01/symbols.txt
@@ -4423,24 +4423,24 @@ giveSpecialDropItem__18SpecialItemDropMgrFiiP7mVec3_ci4mAngl = .text:0x800C7D40;
spawnSpecialDropItem__18SpecialItemDropMgrFiiP7mVec3_ci4mAng = .text:0x800C7EF0; // type:function size:0x2D8
rndRange<4mAng>__2cMF4mAng4mAng_4mAng = .text:0x800C81D0; // type:function size:0x98
__dt__18SpecialItemDropMgrFv = .text:0x800C8270; // type:function size:0x40
-isShortNegative = .text:0x800C82B0; // type:function size:0x18
-0x3FFFMask = .text:0x800C82D0; // type:function size:0x18
-Particle__init = .text:0x800C82F0; // type:function size:0xB0
-fn_800C83A0 = .text:0x800C83A0; // type:function size:0x68
-fn_800C8410 = .text:0x800C8410; // type:function size:0xE4
-fn_800C8500 = .text:0x800C8500; // type:function size:0xCC
-fn_800C85D0 = .text:0x800C85D0; // type:function size:0x6C
-fn_800C8640 = .text:0x800C8640; // type:function size:0x50
-dParticle__GetResUserWork = .text:0x800C8690; // type:function size:0x74
-fn_800C8710 = .text:0x800C8710; // type:function size:0x78
-fn_800C8790 = .text:0x800C8790; // type:function size:0x8
-fn_800C87A0 = .text:0x800C87A0; // type:function size:0x8
-fn_800C87B0 = .text:0x800C87B0; // type:function size:0x8
-fn_800C87C0 = .text:0x800C87C0; // type:function size:0xE0
-fn_800C88A0 = .text:0x800C88A0; // type:function size:0x8
-fn_800C88B0 = .text:0x800C88B0; // type:function size:0x8
-fn_800C88C0 = .text:0x800C88C0; // type:function size:0x10
-fn_800C88D0 = .text:0x800C88D0; // type:function size:0x78
+extractResMgrIdx__FUs = .text:0x800C82B0; // type:function size:0x18
+extractResUserIdx__FUs = .text:0x800C82D0; // type:function size:0x18
+init__Q29dParticle5res_cFPCvPCvPQ23EGG4Heap = .text:0x800C82F0; // type:function size:0xB0
+dispose__Q29dParticle5res_cFv = .text:0x800C83A0; // type:function size:0x68
+set__Q29dParticle5tex_cFPQ23EGG10CpuTexture = .text:0x800C8410; // type:function size:0xE4
+__ct__Q29dParticle5mgr_cFPQ23EGG4HeapUlUlUc = .text:0x800C8500; // type:function size:0xCC
+createResource__Q29dParticle5mgr_cFPQ23EGG4HeaplPvPv = .text:0x800C85D0; // type:function size:0x6C
+disposeResource__Q29dParticle5mgr_cFl = .text:0x800C8640; // type:function size:0x50
+getResUserWork__Q29dParticle5mgr_cCFUs = .text:0x800C8690; // type:function size:0x74
+getJpnData__Q29dParticle5mgr_cCFUs = .text:0x800C8710; // type:function size:0x78
+doCustomSkywardSwordThing__Q29dParticle5mgr_cFUcff = .text:0x800C8790; // type:function size:0x8
+calc__Q29dParticle5mgr_cFUc = .text:0x800C87A0; // type:function size:0x8
+draw__Q29dParticle5mgr_cFPC11JPADrawInfoUc = .text:0x800C87B0; // type:function size:0x8
+createEmitter__Q29dParticle5mgr_cFUsUcRC7mVec3_cPC7mAng3_cPC7mVec3_c = .text:0x800C87C0; // type:function size:0xE0
+forceDeleteAllEmitter__Q29dParticle5mgr_cFv = .text:0x800C88A0; // type:function size:0x8
+forceDeleteEmitter__Q29dParticle5mgr_cFP14JPABaseEmitter = .text:0x800C88B0; // type:function size:0x8
+getResourceManager__Q29dParticle5mgr_cFl = .text:0x800C88C0; // type:function size:0x10
+create__Q29dParticle5mgr_cFPQ23EGG4HeapUlUlUc = .text:0x800C88D0; // type:function size:0x78
initializeState_Wait__18dLytMeter1Button_cFv = .text:0x800C8950; // type:function size:0x4
executeState_Wait__18dLytMeter1Button_cFv = .text:0x800C8960; // type:function size:0x34
changeState__87sStateMgr_c<18dLytMeter1Button_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x800C89A0; // type:function size:0x10
@@ -31054,8 +31054,8 @@ lbl_80511C10 = .data:0x80511C10; // type:object size:0x10
lbl_80511C20 = .data:0x80511C20; // type:object size:0x10
Timekeeper__vtable = .data:0x80511C30; // type:object size:0x20
__vt__18SpecialItemDropMgr = .data:0x80511C50; // type:object size:0xC
-lbl_80511C60 = .data:0x80511C60; // type:object size:0x14
-lbl_80511C74 = .data:0x80511C74; // type:object size:0xC
+lbl_80511C60 = .data:0x80511C60; // type:object size:0x11 data:string
+__vt__Q29dParticle5tex_c = .data:0x80511C74; // type:object size:0xC
lbl_80511C80 = .data:0x80511C80; // type:object size:0x1A data:string
lbl_80511C9C = .data:0x80511C9C; // type:object size:0xB data:string
lbl_80511CA8 = .data:0x80511CA8; // type:object size:0x19 data:string
@@ -38110,7 +38110,7 @@ lbl_805722F4 = .sdata:0x805722F4; // type:object size:0x4 data:4byte
lbl_805722F8 = .sdata:0x805722F8; // type:object size:0x8
lbl_80572300 = .sdata:0x80572300; // type:object size:0x8 data:4byte
lbl_80572308 = .sdata:0x80572308; // type:object size:0x8 data:4byte
-lbl_80572310 = .sdata:0x80572310; // type:object size:0x8
+lbl_80572310 = .sdata:0x80572310; // type:object size:0x6 data:string
lbl_80572318 = .sdata:0x80572318; // type:object size:0x4 data:4byte
lbl_8057231C = .sdata:0x8057231C; // type:object size:0x4 data:4byte
lbl_80572320 = .sdata:0x80572320; // type:object size:0x4 data:4byte
@@ -40092,7 +40092,7 @@ lbl_80575420 = .sbss:0x80575420; // type:object size:0x8 data:byte
lbl_80575428 = .sbss:0x80575428; // type:object size:0x8 data:byte
lbl_80575430 = .sbss:0x80575430; // type:object size:0x8 data:4byte
sInstance__18SpecialItemDropMgr = .sbss:0x80575438; // type:object size:0x4 data:4byte
-FOR_LOADED_PARTICLES = .sbss:0x80575440; // type:object size:0x8 data:4byte
+sInstance__Q29dParticle5mgr_c = .sbss:0x80575440; // type:object size:0x4 data:4byte
sInstance__11dLytMeter_c = .sbss:0x80575448; // type:object size:0x8 data:4byte
sInstance__24dLytMeterConfiguration_c = .sbss:0x80575450; // type:object size:0x8 data:4byte
sInstance__20LytMeterTimerPart1_c = .sbss:0x80575458; // type:object size:0x4 data:4byte
@@ -43742,7 +43742,8 @@ lbl_8057A398 = .sdata2:0x8057A398; // type:object size:0x4 data:float
lbl_8057A39C = .sdata2:0x8057A39C; // type:object size:0x4 data:float
lbl_8057A3A0 = .sdata2:0x8057A3A0; // type:object size:0x4 data:float
lbl_8057A3A4 = .sdata2:0x8057A3A4; // type:object size:0x4 data:float
-lbl_8057A3A8 = .sdata2:0x8057A3A8; // type:object size:0xA
+lbl_8057A3A8 = .sdata2:0x8057A3A8; // type:object size:0x8 data:float
+PARTICLE_RESOURCE_ID_MAPPING_0_ = .sdata2:0x8057A3B0; // type:object size:0x2 data:2byte
PARTICLE_RESOURCE_ID_MAPPING_1_ = .sdata2:0x8057A3B2; // type:object size:0x2 data:2byte
PARTICLE_RESOURCE_ID_MAPPING_2_ = .sdata2:0x8057A3B4; // type:object size:0x2 data:2byte
PARTICLE_RESOURCE_ID_MAPPING_3_ = .sdata2:0x8057A3B6; // type:object size:0x2 data:2byte
diff --git a/configure.py b/configure.py
index 5c2384a2..5db0be0c 100644
--- a/configure.py
+++ b/configure.py
@@ -468,7 +468,7 @@ config.libs = [
Object(NonMatching, "toBeSorted/unk_bird_stuff.cpp"),
Object(NonMatching, "toBeSorted/timekeeper.cpp"),
Object(NonMatching, "toBeSorted/special_item_drop_mgr.cpp"),
- Object(NonMatching, "toBeSorted/d_particle.cpp"),
+ Object(Matching, "toBeSorted/d_particle.cpp"),
Object(Matching, "d/lyt/meter/d_lyt_meter.cpp"),
Object(NonMatching, "d/lyt/meter/d_lyt_meter_unk.cpp"),
Object(Matching, "d/lyt/meter/d_lyt_meter_a_btn.cpp"),
diff --git a/include/JSystem/JParticle/JPADynamicsBlock.h b/include/JSystem/JParticle/JPADynamicsBlock.h
index f1811246..73a7a6f6 100644
--- a/include/JSystem/JParticle/JPADynamicsBlock.h
+++ b/include/JSystem/JParticle/JPADynamicsBlock.h
@@ -3,8 +3,8 @@
#include "common.h"
-#include "JSystem/JGeometry.h"
#include "egg/math/eggVector.h"
+#include "m/m_angle.h"
class JPAEmitterWorkData;
@@ -36,7 +36,7 @@ struct JPADynamicsBlockData {
/* 0x5C */ f32 mVolumeMinRad;
/* 0x60 */ f32 mAirResist;
/* 0x64 */ f32 mMoment;
- /* 0x68 */ JGeometry::TVec3<s16> mEmitterRot;
+ /* 0x68 */ mAng3_c mEmitterRot;
/* 0x6E */ s16 mMaxFrame;
/* 0x70 */ s16 mStartFrame;
/* 0x72 */ s16 mLifeTime;
@@ -83,7 +83,7 @@ public:
void getEmitterDir(EGG::Vector3f* vec) const {
vec->set(mpData->mEmitterDir.x, mpData->mEmitterDir.y, mpData->mEmitterDir.z);
}
- void getEmitterRot(JGeometry::TVec3<s16>* vec) const {
+ void getEmitterRot(mAng3_c* vec) const {
vec->set(mpData->mEmitterRot.x, mpData->mEmitterRot.y, mpData->mEmitterRot.z);
}
s16 getMaxFrame() { return mpData->mMaxFrame; }
diff --git a/include/JSystem/JParticle/JPAEmitter.h b/include/JSystem/JParticle/JPAEmitter.h
index d8900bff..6e49752f 100644
--- a/include/JSystem/JParticle/JPAEmitter.h
+++ b/include/JSystem/JParticle/JPAEmitter.h
@@ -9,6 +9,8 @@
#include "JSystem/JParticle/JPAMath.h"
#include "JSystem/JParticle/JPADynamicsBlock.h"
#include "JSystem/JSupport/JSUList.h"
+#include "egg/math/eggVector.h"
+#include "m/m_angle.h"
class JPAResourceManager;
class JPABaseEmitter;
@@ -47,8 +49,8 @@ struct JPAEmitterWorkData {
/* 0x120 */ EGG::Vector3f mGlobalEmtrDir;
/* 0x12C */ EGG::Vector3f mPublicScale;
/* 0x138 */ EGG::Vector3f mGlobalPos;
- /* 0x144 */ JGeometry::TVec2<f32> mGlobalPtclScl;
- /* 0x14C */ JGeometry::TVec2<f32> mPivot;
+ /* 0x144 */ EGG::Vector2f mGlobalPtclScl;
+ /* 0x14C */ EGG::Vector2f mPivot;
/* 0x154 */ Mtx mYBBCamMtx;
/* 0x184 */ Mtx mPosCamMtx;
/* 0x1B4 */ Mtx mPrjMtx;
@@ -136,7 +138,7 @@ public:
void setGlobalTranslation(f32 x, f32 y, f32 z) { mGlobalTrs.set(x, y, z); }
void setGlobalTranslation(const EGG::Vector3f& trs) { mGlobalTrs.set(trs); }
void getLocalTranslation(EGG::Vector3f& vec) { vec.set(mLocalTrs); }
- void setGlobalRotation(const JGeometry::TVec3<s16>& rot) {
+ void setGlobalRotation(const mAng3_c& rot) {
JPAGetXYZRotateMtx(rot.x, rot.y, rot.z, mGlobalRot);
}
void getGlobalTranslation(EGG::Vector3f* out) const { out->set(mGlobalTrs); }
@@ -152,7 +154,7 @@ public:
void setAwayFromAxisSpeed(f32 i_speed) { mAwayFromAxisSpeed = i_speed; }
void setSpread(f32 i_spread) { mSpread = i_spread; }
void setLocalTranslation(const EGG::Vector3f& i_trans) { mLocalTrs.set(i_trans); }
- void setLocalRotation(const JGeometry::TVec3<s16>& i_rot) { mLocalRot.set(i_rot.x * 0.005493248f, i_rot.y * 0.005493248f, i_rot.z * 0.005493248f); }
+ void setLocalRotation(const mAng3_c& i_rot) { mLocalRot.set(i_rot.x * 0.005493248f, i_rot.y * 0.005493248f, i_rot.z * 0.005493248f); }
void setRateStep(u8 i_step) { mRateStep = i_step; }
void setGlobalParticleHeightScale(f32 height) {
@@ -232,7 +234,7 @@ public:
/* 0x40 */ f32 mSpread;
/* 0x44 */ f32 mRndmDirSpeed;
/* 0x48 */ f32 mAirResist;
- /* 0x4C */ JGeometry::TVec3<s16> mLocalRot;
+ /* 0x4C */ mAng3_c mLocalRot;
/* 0x52 */ s16 mLifeTime;
/* 0x54 */ u16 mVolumeSize;
/* 0x56 */ u8 mRateStep;
@@ -240,7 +242,7 @@ public:
/* 0x68 */ Mtx mGlobalRot;
/* 0x98 */ EGG::Vector3f mGlobalScl;
/* 0xA4 */ EGG::Vector3f mGlobalTrs;
- /* 0xB0 */ JGeometry::TVec2<f32> mGlobalPScl;
+ /* 0xB0 */ EGG::Vector2f mGlobalPScl;
/* 0xB8 */ GXColor mGlobalPrmClr;
/* 0xBC */ GXColor mGlobalEnvClr;
/* 0xC0 */ s32 mpUserWork;
diff --git a/include/d/d_stage_mgr.h b/include/d/d_stage_mgr.h
index cc7d16a3..c239a98d 100644
--- a/include/d/d_stage_mgr.h
+++ b/include/d/d_stage_mgr.h
@@ -18,6 +18,7 @@
#include "toBeSorted/arc_managers/oarc_manager.h"
#include "toBeSorted/attention.h"
#include "toBeSorted/d_d3d.h"
+#include "toBeSorted/d_particle.h"
#include "toBeSorted/time_area_mgr.h"
class RelObjCtrl {
@@ -161,9 +162,11 @@ private:
/* 0x0580 */ LayoutArcControl mLayoutArcCtrl2;
/* 0x058C */ dBgS mBg;
// ...
- u8 _0x00001[0x7D0];
+ u8 _0x00001[0x778];
/* 0x3E40 */ dCcS mCc;
// ...
+ /* 0x7814 */ dParticle::tex_c mParticleTex[2];
+ // ...
/* 0x7930 */ dFader_c mFader;
/* 0x7954 */ u16 mPcamCount;
diff --git a/include/egg/gfx/eggCpuTexture.h b/include/egg/gfx/eggCpuTexture.h
index a3e4db22..d5300b41 100644
--- a/include/egg/gfx/eggCpuTexture.h
+++ b/include/egg/gfx/eggCpuTexture.h
@@ -90,6 +90,13 @@ public:
mWrapT = wrap;
}
+ GXTexWrapMode getWrapS() const {
+ return (GXTexWrapMode)mWrapS;
+ }
+ GXTexWrapMode getWrapT() const {
+ return (GXTexWrapMode)mWrapT;
+ }
+
void setWrap(GXTexWrapMode wrapS, GXTexWrapMode wrapT) {
mWrapS = wrapS;
mWrapT = wrapT;
@@ -107,6 +114,13 @@ public:
mMagFilt = filt;
}
+ GXTexFilter getMinFilt() const {
+ return (GXTexFilter)mMinFilt;
+ }
+ GXTexFilter getMagFilt() const {
+ return (GXTexFilter)mMagFilt;
+ }
+
ResTIMG *getHeader() const {
return (ResTIMG *)((u8 *)dataPtr - sizeof(ResTIMG));
}
diff --git a/include/toBeSorted/d_particle.h b/include/toBeSorted/d_particle.h
new file mode 100644
index 00000000..ef81921b
--- /dev/null
+++ b/include/toBeSorted/d_particle.h
@@ -0,0 +1,96 @@
+#ifndef D_PARTICLE_H
+#define D_PARTICLE_H
+
+#include "JSystem/JParticle/JPADrawInfo.h"
+#include "JSystem/JParticle/JPAEmitter.h"
+#include "JSystem/JParticle/JPAResourceManager.h"
+#include "common.h"
+#include "m/m_angle.h"
+#include "m/m_vec.h"
+
+#define D_PARTICLE_RES_COMMON 0
+#define D_PARTICLE_RES_PARTICLE 1
+
+#define D_PARTICLE_NUM_RES 2
+
+namespace dParticle {
+
+struct JPN {
+ u16 numJpn;
+ u16 mData[1];
+};
+
+class res_c {
+public:
+ res_c() {
+ mpHeap = nullptr;
+ mpResourceManager = nullptr;
+ mpJpnData = nullptr;
+ }
+
+ JPAResourceManager *init(const void *jpc, const void *jpn, EGG::Heap *heap);
+ void dispose();
+
+ JPAResourceManager *getResourceManager() {
+ return mpResourceManager;
+ }
+
+ const JPN *getJpn() const {
+ return mpJpnData;
+ }
+
+private:
+ /* 0x00 */ EGG::FrmHeap *mpHeap;
+ /* 0x04 */ JPAResourceManager *mpResourceManager;
+ /* 0x08 */ const JPN *mpJpnData;
+};
+
+// Made up name
+class tex_c {
+public:
+ tex_c() {
+ field_0x04 = 0;
+ field_0x08 = 0;
+ }
+ virtual void set(EGG::CpuTexture *tex);
+
+private:
+ /* 0x04 */ UNKWORD field_0x04;
+ /* 0x08 */ UNKWORD field_0x08;
+ /* 0x0C */ EGG::ResTIMG mImg;
+};
+
+// Made up name
+class mgr_c {
+public:
+ mgr_c(EGG::Heap *heap, u32 ptclMax, u32 emtrMax, u8 grpMax);
+
+ static mgr_c *GetInstance() {
+ return sInstance;
+ }
+
+ static mgr_c *create(EGG::Heap *heap, u32 ptclMax, u32 emtrMax, u8 grpMax);
+
+ void createResource(EGG::Heap *heap, s32 mgrIndex, void *jpc, void *jpn);
+ void disposeResource(s32 mgrIndex);
+ s32 getResUserWork(u16 handle) const;
+ u16 getJpnData(u16 handle) const;
+ // Invokes the JParticle 11 extension
+ void doCustomSkywardSwordThing(u8 groupId, f32 x, f32 y);
+ void calc(u8 groupId);
+ void draw(const JPADrawInfo *drawInfo, u8 groupId);
+ JPABaseEmitter *
+ createEmitter(u16 particleResId, u8 groupId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale);
+ void forceDeleteAllEmitter();
+ void forceDeleteEmitter(JPABaseEmitter *emitter);
+ JPAResourceManager *getResourceManager(s32 idx);
+
+private:
+ static mgr_c *sInstance;
+ /* 0x00 */ JPAEmitterManager *mpEmitterMgr;
+ /* 0x04 */ res_c mRes[D_PARTICLE_NUM_RES];
+};
+
+} // namespace dParticle
+
+#endif
diff --git a/src/toBeSorted/d_particle.cpp b/src/toBeSorted/d_particle.cpp
new file mode 100644
index 00000000..e05695af
--- /dev/null
+++ b/src/toBeSorted/d_particle.cpp
@@ -0,0 +1,169 @@
+#include "toBeSorted/d_particle.h"
+
+#include "JSystem/JParticle/JPAEmitter.h"
+#include "JSystem/JParticle/JPAEmitterManager.h"
+#include "JSystem/JParticle/JPAResourceManager.h"
+#include "common.h"
+#include "egg/core/eggHeap.h"
+#include "egg/egg_types.h"
+#include "egg/gfx/eggCpuTexture.h"
+#include "egg/gfx/eggTexture.h"
+#include "m/m_angle.h"
+#include "m/m_heap.h"
+#include "m/m_vec.h"
+
+extern "C" const u16 lbl_8057AB72;
+extern "C" const u16 lbl_8057AB74;
+
+static u32 extractResMgrIdx(u16 particleResId) {
+ return (particleResId & lbl_8057AB72) != 0 ? 1 : 0;
+}
+
+static u16 extractResUserIdx(u16 particleResId) {
+ return (particleResId & ~(lbl_8057AB72 | lbl_8057AB74));
+}
+
+namespace dParticle {
+
+JPAResourceManager *res_c::init(const void *jpc, const void *jpn, EGG::Heap *heap) {
+ mpHeap = mHeap::createFrmHeap(-1, heap, "dParticle::res_c", 0x20, 0);
+ if (mpHeap == nullptr) {
+ return nullptr;
+ }
+ mpResourceManager = new (mpHeap, 4) JPAResourceManager(jpc, mpHeap);
+ if (mpResourceManager != nullptr) {
+ mpJpnData = static_cast<const JPN *>(jpn);
+ }
+ mHeap::adjustFrmHeap(mpHeap);
+ return mpResourceManager;
+}
+
+void res_c::dispose() {
+ if (mpHeap != nullptr) {
+ if (mpResourceManager != nullptr) {
+ mpResourceManager = nullptr;
+ mpJpnData = nullptr;
+ }
+ mpHeap->destroy();
+ mpHeap = nullptr;
+ }
+}
+
+void tex_c::set(EGG::CpuTexture *tex) {
+ mImg.format = tex->getFormat();
+ mImg.alphaEnabled = true;
+ mImg.width = tex->getWidth();
+ mImg.height = tex->getHeight();
+ mImg.wrapS = tex->getWrapS();
+ mImg.wrapT = tex->getWrapT();
+ mImg.indexTexture = 0;
+ mImg.colorFormat = GX_TL_IA8;
+ mImg.numColors = 0;
+ mImg.paletteOffset = 0;
+ mImg.mipmapEnabled = 0;
+ mImg.doEdgeLOD = 0;
+ mImg.biasClamp = 0;
+ mImg.maxAnisotropy = 0;
+ mImg.minFilter = tex->getMinFilt();
+ mImg.magFilter = tex->getMagFilt();
+ mImg.minLOD = 0;
+ mImg.maxLOD = 0;
+ mImg.mipmapCount = 1;
+ mImg.LODBias = 0;
+ mImg.imageOffset = (u32)tex->getBuffer() - (u32)&mImg;
+
+ for (int i = 0; i < D_PARTICLE_NUM_RES; i++) {
+ JPAResourceManager *mgr = dParticle::mgr_c::GetInstance()->getResourceManager(i);
+ if (mgr != nullptr) {
+ mgr->swapTexture(&mImg, "dummy");
+ }
+ }
+}
+
+mgr_c *mgr_c::sInstance;
+
+mgr_c::mgr_c(EGG::Heap *heap, u32 ptclMax, u32 emtrMax, u8 grpMax) : mpEmitterMgr(nullptr) {
+ sInstance = this;
+ mpEmitterMgr = new (heap, 4) JPAEmitterManager(ptclMax, emtrMax, heap, grpMax, D_PARTICLE_NUM_RES);
+}
+
+void mgr_c::createResource(EGG::Heap *heap, s32 mgrIndex, void *jpc, void *jpn) {
+ JPAResourceManager *mgr = mRes[mgrIndex].init(jpc, jpn, heap);
+ if (mgr != nullptr) {
+ mpEmitterMgr->entryResourceManager(mgr, mgrIndex);
+ }
+}
+
+void mgr_c::disposeResource(s32 mgrIndex) {
+ res_c &res = mRes[mgrIndex];
+ if (res.getResourceManager() != nullptr) {
+ mpEmitterMgr->clearResourceManager(mgrIndex);
+ }
+ res.dispose();
+}
+
+s32 mgr_c::getResUserWork(u16 particleResId) const {
+ u8 idx = extractResMgrIdx(particleResId);
+ JPAResourceManager *mgr = mpEmitterMgr->getResourceManager(idx);
+ if (mgr == nullptr) {
+ return -1;
+ }
+ return mgr->getResUserWork(extractResUserIdx(particleResId));
+}
+
+u16 mgr_c::getJpnData(u16 particleResId) const {
+ const JPN *jpn = mRes[extractResMgrIdx(particleResId)].getJpn();
+ u16 idx = extractResUserIdx(particleResId);
+ if (idx >= jpn->numJpn) {
+ return 0xFFFF;
+ } else {
+ return jpn->mData[idx];
+ }
+}
+
+void mgr_c::doCustomSkywardSwordThing(u8 groupId, f32 x, f32 y) {
+ mpEmitterMgr->fn_80320E20(groupId, x, y);
+}
+
+void mgr_c::calc(u8 groupId) {
+ mpEmitterMgr->calc(groupId);
+}
+
+void mgr_c::draw(const JPADrawInfo *drawInfo, u8 groupId) {
+ mpEmitterMgr->draw(drawInfo, groupId);
+}
+
+JPABaseEmitter *
+mgr_c::createEmitter(u16 particleResId, u8 groupId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale) {
+ u32 resMgrId = extractResMgrIdx(particleResId);
+ u16 resId = extractResUserIdx(particleResId);
+ JPABaseEmitter *emitter = mpEmitterMgr->createSimpleEmitterID(pos, resId, groupId, resMgrId, nullptr, nullptr);
+ if (emitter == nullptr) {
+ return nullptr;
+ }
+ if (rot != nullptr) {
+ emitter->setGlobalRotation(*rot);
+ }
+ if (scale != nullptr) {
+ emitter->setGlobalScale(*scale);
+ }
+ return emitter;
+}
+
+void mgr_c::forceDeleteAllEmitter() {
+ mpEmitterMgr->forceDeleteAllEmitter();
+}
+
+void mgr_c::forceDeleteEmitter(JPABaseEmitter *emitter) {
+ mpEmitterMgr->forceDeleteEmitter(emitter);
+}
+
+JPAResourceManager *mgr_c::getResourceManager(s32 idx) {
+ return mRes[idx].getResourceManager();
+}
+
+mgr_c *mgr_c::create(EGG::Heap *heap, u32 ptclMax, u32 emtrMax, u8 grpMax) {
+ return new (heap, 4) mgr_c(heap, ptclMax, emtrMax, grpMax);
+}
+
+} // namespace dParticle