NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
ef_particle.h
1#ifndef NW4R_EF_PARTICLE_H
2#define NW4R_EF_PARTICLE_H
3#include <nw4r/types_nw4r.h>
4
5#include <nw4r/ef/ef_particlemanager.h>
6#include <nw4r/ef/ef_referencedobject.h>
7#include <nw4r/ef/ef_res_emitter.h>
8#include <nw4r/ef/ef_types.h>
9
10#include <nw4r/math.h>
11
12#include <revolution/GX.h>
13
14namespace nw4r {
15namespace ef {
16
17// Forward declarations
19struct TextureData;
20
22 GXColor mColor[COLOR_LAYER_MAX][COLOR_IDX_MAX]; // at 0x0
23 math::VEC2 size; // at 0x10
24 math::VEC2 scale; // at 0x18
25 math::VEC3 rotate; // at 0x20
26 math::VEC2 textureScale[TEX_LAYER_MAX]; // at 0x2C
27 f32 textureRotate[TEX_LAYER_MAX]; // at 0x44
28 math::VEC2 textureTranslate[TEX_LAYER_MAX]; // at 0x50
29 TextureData* mTexture[TEX_LAYER_MAX]; // at 0x68
30 u16 textureWrap; // at 0x74
31 u8 textureReverse; // at 0x76
32 u8 mACmpRef0; // at 0x77
33 u8 mACmpRef1; // at 0x78
34 u8 rotateOffsetRandom[AXIS_MAX]; // at 0x79
35 f32 rotateOffset[AXIS_MAX]; // at 0x7C
36 u8 textureNames[1]; // at 0x88
37};
38
40public:
41 GXColor mColor[COLOR_LAYER_MAX][COLOR_IDX_MAX]; // at 0x0
42 math::VEC2 mSize; // at 0x10
43 math::VEC2 mScale; // at 0x18
44 math::VEC3 mRotate; // at 0x20
45 math::VEC2 mTextureScale[TEX_LAYER_MAX]; // at 0x2C
46 f32 mTextureRotate[TEX_LAYER_MAX]; // at 0x44
47 math::VEC2 mTextureTranslate[TEX_LAYER_MAX]; // at 0x50
48 TextureData* mTexture[TEX_LAYER_MAX]; // at 0x68
49 u16 mTextureWrap; // at 0x74
50 u8 mTextureReverse; // at 0x76
51 u8 mACmpRef0; // at 0x77
52 u8 mACmpRef1; // at 0x78
53 s8 mAlphaFlickRnd; // at 0x79
54 u8 mRotateOffset[AXIS_MAX]; // at 0x7A
55 u8 mCollisionStatus; // at 0x7D
56 math::VEC3 mVelocity; // at 0x80
57 math::VEC3 mPosition; // at 0x8C
58 math::VEC3 mPrevPosition; // at 0x98
59 f32 mMomentum; // at 0xA4
60
61public:
62 void Initialize(ParticleParameterDesc* pDesc, ParticleManager* pManager);
63};
64
65class Particle : public ReferencedObject {
66 friend class ParticleManager;
67
68public:
69 ParticleParameter mParameter; // at 0x20
70 ParticleManager* mParticleManager; // at 0xC8
71 math::VEC3 mPrevAxis; // at 0xCC
72 EvaluateStatus mEvalStatus; // at 0xD8
73 u16 mTick; // at 0xDC
74 u16 mRandSeed; // at 0xDE
75 u16 mLife; // at 0xE0
76 u16 mCalcRemain; // at 0xE2
77
78public:
79 Particle();
80 ~Particle();
81
82 virtual void SendClosing(); // at 0x8
83 virtual void DestroyFunc(); // at 0xC
84 virtual bool Initialize(u16 life, math::VEC3 pos, math::VEC3 vel,
85 ParticleManager* pManager,
86 const math::MTX34* pSpace, float momentum,
87 const EmitterInheritSetting* pSetting,
88 Particle* pReferencePtcl); // at 0x10
89
90 void Draw_GetColor(int layer, GXColor* pColorPri, GXColor* pColorSec);
91
92 void GetColor(int layer, int index, GXColor* pColor) {
93 pColor->r = mParameter.mColor[layer][index].r;
94 pColor->g = mParameter.mColor[layer][index].g;
95 pColor->b = mParameter.mColor[layer][index].b;
96 pColor->a = mParameter.mColor[layer][index].a;
97 }
98
99 f32 Draw_GetSizeX() {
100 f32 sx = mParameter.mSize.x * mParameter.mScale.x;
101 return mParticleManager->Draw_ModifyScaleX(this, sx);
102 }
103 f32 Draw_GetSizeY() {
104 f32 sy;
105
106 switch (mParticleManager->mResource->GetEmitterDrawSetting()->mFlags &
107 (EmitterDrawSetting::FLAG_XY_SAME_SIZE |
108 EmitterDrawSetting::FLAG_XY_SAME_SCALE)) {
109
110 case EmitterDrawSetting::FLAG_XY_SAME_SCALE: {
111 sy = mParameter.mSize.y * mParameter.mScale.x;
112 break;
113 }
114
115 case EmitterDrawSetting::FLAG_XY_SAME_SIZE: {
116 sy = mParameter.mSize.x * mParameter.mScale.y;
117 break;
118 }
119
120 case (EmitterDrawSetting::FLAG_XY_SAME_SIZE |
121 EmitterDrawSetting::FLAG_XY_SAME_SCALE): {
122 sy = mParameter.mSize.x * mParameter.mScale.x;
123 break;
124 }
125
126 default: {
127 sy = mParameter.mSize.y * mParameter.mScale.y;
128 break;
129 }
130 }
131
132 return mParticleManager->Draw_ModifyScaleY(this, sy);
133 }
134
135 void Draw_GetRotate(math::VEC3* pRot) {
136 *pRot = mParameter.mRotate;
137
138 if (mParameter.mRotateOffset[AXIS_X] > 0) {
139 pRot->x += NW4R_MATH_FIDX_TO_RAD(mParameter.mRotateOffset[AXIS_X]);
140 }
141
142 if (mParameter.mRotateOffset[AXIS_Y] > 0) {
143 pRot->y += NW4R_MATH_FIDX_TO_RAD(mParameter.mRotateOffset[AXIS_Y]);
144 }
145
146 if (mParameter.mRotateOffset[AXIS_Z] > 0) {
147 pRot->z += NW4R_MATH_FIDX_TO_RAD(mParameter.mRotateOffset[AXIS_Z]);
148 }
149
150 mParticleManager->Draw_ModifyRotate(this, pRot);
151 }
152
153 int Draw_GetTextureScaleS(int layer) const {
154 int scale = 1;
155
156 if (GetTextureWrapS(layer) == GX_MIRROR) {
157 scale = 2;
158 }
159
160 u8 reverse =
161 (mParameter.mTextureReverse >> (layer * NUM_OF_TEX_REVERSE) &
162 TEX_REVERSE_ST);
163
164 if (static_cast<ulong>(reverse) == TEX_REVERSE_S ||
165 static_cast<ulong>(reverse) == TEX_REVERSE_ST) {
166 scale -= scale * 2;
167 }
168
169 return scale;
170 }
171 int Draw_GetTextureScaleT(int layer) const {
172 int scale = 1;
173
174 if (GetTextureWrapT(layer) == GX_MIRROR) {
175 scale = 2;
176 }
177
178 u8 reverse =
179 (mParameter.mTextureReverse >> (layer * NUM_OF_TEX_REVERSE) &
180 TEX_REVERSE_ST);
181
182 if (static_cast<ulong>(reverse) == TEX_REVERSE_T ||
183 static_cast<ulong>(reverse) == TEX_REVERSE_ST) {
184 scale -= scale * 2;
185 }
186
187 return scale;
188 }
189
190 int Draw_GetTextureTransS(int layer) const {
191 int trans = 0;
192
193 u8 reverse =
194 (mParameter.mTextureReverse >> (layer * NUM_OF_TEX_REVERSE) &
195 TEX_REVERSE_ST);
196
197 if (static_cast<ulong>(reverse) == TEX_REVERSE_S ||
198 static_cast<ulong>(reverse) == TEX_REVERSE_ST) {
199 trans = 1;
200 }
201
202 if (GetTextureWrapS(layer) == GX_MIRROR) {
203 trans *= 2;
204 }
205
206 return trans;
207 }
208 int Draw_GetTextureTransT(int layer) const {
209 int trans = 0;
210
211 u8 reverse =
212 (mParameter.mTextureReverse >> (layer * NUM_OF_TEX_REVERSE) &
213 TEX_REVERSE_ST);
214
215 if (static_cast<ulong>(reverse) == TEX_REVERSE_T ||
216 static_cast<ulong>(reverse) == TEX_REVERSE_ST) {
217 trans = 1;
218 }
219
220 if (GetTextureWrapT(layer) == GX_MIRROR) {
221 trans *= 2;
222 }
223
224 return trans;
225 }
226
227 GXTexWrapMode GetTextureWrapS(int layer) const {
228 // clang-format off
229 return static_cast<GXTexWrapMode>(mParameter.mTextureWrap >>
230 (layer * NUM_OF_TEX_WRAP_ST + 0) & TEX_WRAP_MASK);
231 // clang-format on
232 }
233 GXTexWrapMode GetTextureWrapT(int layer) const {
234 // clang-format off
235 return static_cast<GXTexWrapMode>(mParameter.mTextureWrap >>
236 (layer * NUM_OF_TEX_WRAP_ST + NUM_OF_TEX_WRAP_S) & TEX_WRAP_MASK);
237 // clang-format on
238 }
239
240 math::VEC3& GetMoveDir(math::VEC3* pDir) {
241 *pDir = mParameter.mPosition - mParameter.mPrevPosition;
242 return *pDir;
243 }
244
245 math::VEC3& AddPosition(const math::VEC3* pDelta) {
246 mParameter.mPosition.x += pDelta->x * mParameter.mMomentum;
247 mParameter.mPosition.y += pDelta->y * mParameter.mMomentum;
248 mParameter.mPosition.z += pDelta->z * mParameter.mMomentum;
249 return mParameter.mPosition;
250 }
251
252private:
253 enum TextureReverseFlag {
254 TEX_REVERSE_S = (1 << 0),
255 TEX_REVERSE_T = (1 << 1),
256 TEX_REVERSE_ST = TEX_REVERSE_S | TEX_REVERSE_T,
257
258 // 1 bit for each S/T
259 NUM_OF_TEX_REVERSE = 2
260 };
261
262 enum TextureWrapFlag {
263 TEX_WRAP_MASK = (1 << 0) | (1 << 1),
264
265 // 2 bits for each S/T
266 NUM_OF_TEX_WRAP_S = 2,
267 NUM_OF_TEX_WRAP_T = 2,
268
269 NUM_OF_TEX_WRAP_ST = 4
270 };
271};
272
273} // namespace ef
274} // namespace nw4r
275
276#endif