Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
firework_rocket.c
Go to the documentation of this file.
1#include "common.h"
2#include "effects_internal.h"
3
7void firework_rocket_appendGfx(void* effect);
8
9typedef struct FireworkRocketUnk {
10 /* 0x00 */ Vec3b* sparks;
11 /* 0x04 */ s32 num;
12} FireworkRocketUnk; // size = 0x8
13
14extern Gfx D_09000080_3E53D0[];
15extern Gfx D_09000158_3E54A8[];
16
19
21 { 36, 0, 93 }, { 54, -40, 74 }, { 67, 0, 74 }, { 82, -36, 45 }, { 89, 0, 45 },
22 { 60, -66, 45 }, { 21, -64, 74 }, { 28, -85, 45 }, { 10, -98, 15 }, { 49, -86, 15 },
23 { -90, -40, 15 }, { -87, -19, 45 }, { -99, 0, 15 }, { -72, -53, 45 }, { -87, 19, 45 },
24 { -90, 40, 15 }, { -66, 73, 15 }, { -72, 53, 45 }, { -45, 77, 45 }, { -31, 94, 15 },
25 { -9, 89, 45 }, { -72, 53, 45 }, { 11, -34, 93 }, { 0, 0, 100 }, { -54, -40, 74 },
26 { -72, -53, 45 }, { -45, -77, 45 }, { -90, -40, 15 }, { -66, -73, 15 }, { 11, -34, 93 },
27 { -21, -64, 74 }, { 21, -64, 74 }, { -9, -89, 45 }, { 28, -85, 45 }, { 10, 98, 15 },
28 { 80, -58, 15 }, { 97, -21, 15 }, { 49, -86, 15 }, { 10, -98, 15 }, { -31, -94, 15 },
29 { -66, -73, 15 }, { 49, 86, 15 }, { 80, 58, 15 }, { 97, 21, 15 }, { -29, -21, 93 },
30 { 0, 0, 100 }, { 11, 34, 93 }, { -29, 21, 93 }, { 21, 64, 74 }, { -21, 64, 74 },
31 { -54, 40, 74 }, { 28, 85, 45 }, { 67, 0, 74 }, { 89, 0, 45 }, { 36, 0, 93 },
32 { 0, 0, 100 }, { 11, 34, 93 }, { 54, 40, 74 }, { 21, 64, 74 }, { -54, 40, 74 },
33 { -72, 53, 45 }, { 0, 0, 100 }, { -29, -21, 93 }, { -67, 0, 74 }, { -54, -40, 74 },
34 { -29, 21, 93 }, { 0, 0, 100 }, { 60, -66, 45 }, { 82, -36, 45 }, { 89, 0, 45 },
35 { 28, -85, 45 }, { 28, -85, 45 }, { -9, -89, 45 }, { -45, -77, 45 }, { -72, -53, 45 },
36 { 60, 66, 45 }, { 28, 85, 45 }, { 82, 36, 45 }, { 28, 85, 45 }, { 89, 0, 45 },
37 { -9, 89, 45 }, { -45, 77, 45 }, { -72, 53, 45 }, { 49, 86, 15 }, { 10, 98, 15 },
38 { 82, 36, 45 }, { 97, -21, 15 }, { 97, 21, 15 }, { 60, 66, 45 }, { 28, 85, 45 },
39 { -87, 19, 45 }, { -66, 73, 15 }, { -90, 40, 15 }, { -87, -19, 45 }, { -72, -53, 45 },
40};
41
43 { -48, -15, 0 }, { -36, -26, 22 }, { -45, 0, 22 }, { -48, 15, 0 }, { -36, 26, 22 },
44 { -29, 40, 0 }, { -36, 26, 22 }, { -14, 43, 22 }, { 0, 50, 0 }, { 14, 43, 22 },
45 { 8, -25, 43 }, { 14, -43, 22 }, { 36, -26, 22 }, { 26, 0, 43 }, { 0, 0, 50 },
46 { 0, -50, 0 }, { 29, -40, 0 }, { 45, 0, 22 }, { 29, -40, 0 }, { 36, -26, 22 },
47 { 14, -43, 22 }, { 48, -15, 0 }, { 45, 0, 22 }, { 0, -50, 0 }, { 14, -43, 22 },
48 { -14, -43, 22 }, { -29, -40, 0 }, { -36, -26, 22 }, { 29, 40, 0 }, { 36, 26, 22 },
49 { 48, 15, 0 }, { 14, 43, 22 }, { 45, 0, 22 }, { 0, 0, 50 }, { 8, 25, 43 },
50 { -21, 15, 43 }, { 14, 43, 22 }, { 26, 0, 43 }, { 45, 0, 22 }, { 0, 0, 50 },
51 { 8, 25, 43 }, { -21, -15, 43 }, { 0, 0, 50 }, { -36, -26, 22 }, { 8, -25, 43 },
52 { 0, 0, 50 }, { -21, 15, 43 }, { -21, -15, 43 }, { -36, 26, 22 }, { -14, 43, 22 },
53 { -36, 26, 22 }, { 29, 40, 0 }, { 0, 50, 0 }, { 36, 26, 22 }, { 48, -15, 0 },
54 { 48, 15, 0 }, { 14, 43, 22 }, { -14, -43, 22 }, { -48, -15, 0 }, { -29, -40, 0 },
55 { 14, -43, 22 }, { -45, 0, 22 }, { -36, -26, 22 }, { -29, 40, 0 }, { -48, 15, 0 },
56 { 0, 0, 0 },
57};
58
60 { -9, 105, 0 }, { -17, 87, 0 }, { 17, 87, 0 }, { 9, 105, 0 }, { 0, 122, 0 },
61 { -26, 69, 0 }, { 26, 69, 0 }, { -35, 52, 0 }, { 35, 52, 0 }, { -54, 49, 0 },
62 { -70, -1, 0 }, { -56, -15, 0 }, { 0, -56, 0 }, { 56, -15, 0 }, { 70, -1, 0 },
63 { 54, 49, 0 }, { -60, -34, 0 }, { -17, -65, 0 }, { 17, -65, 0 }, { 60, -34, 0 },
64 { 85, 13, 0 }, { 74, 46, 0 }, { 99, 27, 0 }, { 93, 43, 0 }, { 12, 33, 0 },
65 { 12, 22, 0 }, { 24, 22, 0 }, { 24, 33, 0 }, { 12, 10, 0 }, { 24, 10, 0 },
66 { 24, 45, 0 }, { -24, 33, 0 }, { -24, 22, 0 }, { -24, 45, 0 }, { 113, 40, 0 },
67 { -63, -53, 0 }, { -66, -73, 0 }, { -74, 46, 0 }, { -93, 43, 0 }, { 35, -74, 0 },
68 { 52, -83, 0 }, { 12, 45, 0 }, { -12, 22, 0 }, { -12, 33, 0 }, { -24, 10, 0 },
69 { -12, 10, 0 }, { -12, 45, 0 }, { -52, -83, 0 }, { -35, -74, 0 }, { -70, -92, 0 },
70 { -85, 13, 0 }, { -99, 27, 0 }, { -113, 40, 0 }, { 63, -53, 0 }, { 66, -73, 0 },
71 { 70, -92, 0 },
72};
73
79
82
83EffectInstance* firework_rocket_main(s32 variation, f32 centerX, f32 centerY, f32 centerZ, f32 velX, f32 velY, f32 velZ, f32 radius, s32 duration) {
85 EffectInstance* effect;
87 s32 numParts = 1;
88 s32 i;
89
93 bp.unk_00 = 0;
94 bp.renderUI = NULL;
95 bp.effectID = EFFECT_FIREWORK_ROCKET;
96
97 effect = create_effect_instance(&bp);
98 effect->numParts = numParts;
99 data = effect->data.fireworkRocket = general_heap_malloc(numParts * sizeof(*data));
100 ASSERT(effect->data.fireworkRocket != NULL);
101
102 data->variation = variation;
103 data->lifeTime = 0;
104 if (duration <= 0) {
105 data->timeLeft = 1000;
106 } else {
107 data->timeLeft = duration + 32;
108 }
109 data->isExploded = FALSE;
110 data->minBlurAlpha = 255;
111 data->pos.x = centerX;
112 data->pos.y = centerY;
113 data->pos.z = centerZ;
114 data->radius = 0;
115 data->vel.x = velX;
116 data->vel.y = velY;
117 data->vel.z = velZ;
118 data->maxRadius = radius;
119 data->r = 255;
120 data->g = 255;
121 data->b = 100;
122 data->unk_34 = 255;
123 data->unk_38 = 100;
124 data->unk_3C = 150;
125 data->unk_40 = 255;
126
127 for (i = 0; i < ROCKET_BUF_SIZE; i++) {
128 data->rocketX[i] = data->pos.x;
129 data->rocketY[i] = data->pos.y - 1000.0f;
130 data->rocketZ[i] = data->pos.z;
131 data->rocketVelX[i] = 0;
132 data->rocketVelY[i] = 0;
133 data->rocketVelZ[i] = 0;
134 }
135
136 return effect;
137}
138
141
144 f32 factor;
145 s32 lifeTime;
146 s32 i;
147
148 if (effect->flags & FX_INSTANCE_FLAG_DISMISS) {
149 effect->flags &= ~FX_INSTANCE_FLAG_DISMISS;
150 data->timeLeft = 16;
151 }
152
153 if (data->timeLeft < 1000) {
154 data->timeLeft--;
155 }
156
157 data->lifeTime++;
158
159 if (data->timeLeft < 0) {
160 remove_effect(effect);
161 return;
162 }
163
164 lifeTime = data->lifeTime;
165
166 if (data->timeLeft < 32) {
167 data->minBlurAlpha = data->timeLeft * 8;
168 }
169
170 if (data->isExploded == TRUE) {
171 factor = 0.95f;
172 data->pos.x += data->vel.x;
173 data->pos.y += data->vel.y;
174 data->pos.z += data->vel.z;
175 data->vel.x *= factor;
176 data->vel.y *= factor;
177 data->vel.z *= factor;
178 data->radius += (data->maxRadius - data->radius) * 0.11;
179 data->vel.y -= 0.15;
180 return;
181 }
182
183 i = lifeTime & 3;
184 data->rocketX[i] = data->pos.x - data->vel.x * (32 - lifeTime);
185 data->rocketY[i] = data->pos.y - data->vel.y * (32 - lifeTime)
186 - (80.0f - sin_deg((s32)(lifeTime * 90) >> 5) * 80.0f);
187 data->rocketZ[i] = data->pos.z - data->vel.z * (32 - lifeTime);
188 data->rocketVelX[i] = (rand_int(10) - 5) * 0.1f;
189 data->rocketVelY[i] = (rand_int(10) - 5) * 0.1f;
190 data->rocketVelZ[i] = (rand_int(10) - 5) * 0.1f;
191
192 for (i = 0; i < ROCKET_BUF_SIZE; i++) {
193 data->rocketX[i] += data->rocketVelX[i];
194 data->rocketY[i] += data->rocketVelY[i];
195 data->rocketZ[i] += data->rocketVelZ[i];
196 data->rocketVelY[i] -= 0.15;
197 if (lifeTime >= 27) {
198 data->rocketY[i] = NPC_DISPOSE_POS_Y;
199 }
200 }
201
202 if (lifeTime >= 32) {
203 data->isExploded = TRUE;
204 data->lifeTime = 1;
205 }
206}
207
209 RenderTask renderTask;
210 RenderTask* retTask;
211
213 renderTask.appendGfxArg = effect;
214 renderTask.dist = 700;
216
217 retTask = queue_render_task(&renderTask);
219}
220
221void firework_rocket_appendGfx(void* effect) {
222 FireworkRocketFXData* data = ((EffectInstance*)effect)->data.fireworkRocket;
223 Camera* camera = &gCameras[gCurrentCameraID];
224 s32 minBlurAlpha = data->minBlurAlpha;
225 s32 variation = data->variation;
226 f32 mtx_0_0, mtx_0_1, mtx_0_2, mtx_0_3;
227 f32 mtx_1_0, mtx_1_1, mtx_1_2, mtx_1_3;
228 f32 mtx_2_0, mtx_2_1, mtx_2_2, mtx_2_3;
229 f32 mtx_3_0, mtx_3_1, mtx_3_2, mtx_3_3;
230 f32 sinTheta, cosTheta;
231 f32 centerX, centerY, centerZ;
232 f32 negYaw;
233 f32 x, y, z;
234 f32 outX, outY, outZ, outS;
235 f32 radius;
236 s32 isExploded;
237 s32 numSparks;
238 Vec3b* sparkDir;
239 s32 i;
240
241 negYaw = -camera->curYaw;
242 sinTheta = sin_deg(negYaw);
243 cosTheta = cos_deg(negYaw);
244 isExploded = data->isExploded;
246 // draw previous frame to create motion blur effect
250 }
251 if (firework_rocket_blur_alpha < minBlurAlpha) {
252 firework_rocket_blur_alpha = minBlurAlpha;
253 }
254
255 gDPPipeSync(gMainGfxPos++);
256 gSPSegment(gMainGfxPos++, 0x09, VIRTUAL_TO_PHYSICAL(((EffectInstance*)effect)->graphics->data));
257
258 mtx_0_0 = camera->mtxPerspective[0][0];
259 mtx_0_1 = camera->mtxPerspective[0][1];
260 mtx_0_2 = camera->mtxPerspective[0][2];
261 mtx_0_3 = camera->mtxPerspective[0][3];
262 mtx_1_0 = camera->mtxPerspective[1][0];
263 mtx_1_1 = camera->mtxPerspective[1][1];
264 mtx_1_2 = camera->mtxPerspective[1][2];
265 mtx_1_3 = camera->mtxPerspective[1][3];
266 mtx_2_0 = camera->mtxPerspective[2][0];
267 mtx_2_1 = camera->mtxPerspective[2][1];
268 mtx_2_2 = camera->mtxPerspective[2][2];
269 mtx_2_3 = camera->mtxPerspective[2][3];
270 mtx_3_0 = camera->mtxPerspective[3][0];
271 mtx_3_1 = camera->mtxPerspective[3][1];
272 mtx_3_2 = camera->mtxPerspective[3][2];
273 mtx_3_3 = camera->mtxPerspective[3][3];
274
275 gSPDisplayList(gMainGfxPos++, D_E010ACCC[variation]);
276 centerX = data->pos.x;
277 centerY = data->pos.y;
278 centerZ = data->pos.z;
279 radius = data->radius;
280 gDPSetPrimColor(gMainGfxPos++, 0, 0, data->r, data->g, data->b, minBlurAlpha);
281 gDPSetEnvColor(gMainGfxPos++, data->r, data->g, data->b, 0);
282
283 if (isExploded == TRUE) {
284 sparkDir = D_E010AF68[variation].sparks;
285 numSparks = D_E010AF68[variation].num;
286 } else {
287 sparkDir = NULL;
288 numSparks = 4;
289 }
290
291 for (i = 0; i < numSparks; i++, sparkDir++) {
292 if (isExploded == TRUE) {
293 // create blinking effect
294 if (rand_int(16) < 6) {
295 continue;
296 }
297 x = (sparkDir->x * cosTheta + sparkDir->z * sinTheta) * radius + centerX;
298 y = sparkDir->y * radius + centerY;
299 z = (-sparkDir->x * sinTheta + sparkDir->z * cosTheta) * radius + centerZ;
300 } else {
301 x = data->rocketX[i];
302 y = data->rocketY[i];
303 z = data->rocketZ[i];
304 }
305
306 // convert world coords to screen coords
307 outX = mtx_0_0 * x + mtx_1_0 * y + mtx_2_0 * z + mtx_3_0;
308 outY = mtx_0_1 * x + mtx_1_1 * y + mtx_2_1 * z + mtx_3_1;
309 outZ = mtx_0_2 * x + mtx_1_2 * y + mtx_2_2 * z + mtx_3_2;
310 outS = mtx_0_3 * x + mtx_1_3 * y + mtx_2_3 * z + mtx_3_3;
311
312 if (outS != 0.0f) {
313 outS = 1.0f / outS;
314 x = outX * outS;
315 y = -outY * outS;
316 z = outZ * outS;
317
318 if (z <= -1.0f || x <= -1.0f || x >= 1.0f || y <= -1.0f || y >= 1.0f) {
319 continue;
320 }
321 z = 4.0f; // required to match
322
323 x = (x + 1.0f) * camera->viewportW * 0.5;
324 x += camera->viewportStartX;
325 x *= 4.0f;
326
327 y = (y + 1.0f) * camera->viewportH * 0.5;
328 y += camera->viewportStartY;
329 y *= 4.0f;
330
331 gSPScisTextureRectangle(gMainGfxPos++,
332 x, y, x + 8.0f, y + 8.0f,
333 G_TX_RENDERTILE, 4 << 5, 4 << 5, 16 << 10, 16 << 10);
334 }
335 }
336}
337
#define general_heap_malloc
#define queue_render_task
#define sin_deg
#define remove_effect
#define rand_int
#define draw_prev_frame_buffer_at_screen_pos
#define cos_deg
#define create_effect_instance
#define ROCKET_BUF_SIZE
Definition effects.h:2129
struct FireworkRocketFXData * fireworkRocket
Definition effects.h:2583
EffectData data
Definition effects.h:2605
#define ASSERT(condition)
@ FX_INSTANCE_FLAG_DISMISS
Definition enums.h:3517
@ RENDER_TASK_FLAG_REFLECT_FLOOR
Definition enums.h:3318
@ RENDER_MODE_SURFACE_OPA
Definition enums.h:3264
Gfx D_09000080_3E53D0[]
FireworkRocketUnk D_E010AF68[]
EffectInstance * firework_rocket_main(s32 variation, f32 centerX, f32 centerY, f32 centerZ, f32 velX, f32 velY, f32 velZ, f32 radius, s32 duration)
void firework_rocket_init(EffectInstance *effect)
void firework_rocket_appendGfx(void *effect)
Vec3b D_E010ADF8[]
void firework_rocket_update(EffectInstance *effect)
s32 firework_rocket_blur_alpha
Vec3b D_E010AEC0[]
void firework_rocket_render(EffectInstance *effect)
Vec3b D_E010ACD8[]
Gfx D_09000158_3E54A8[]
s32 firework_rocket_frame_counter
Gfx * D_E010ACC0[]
Gfx * D_E010ACCC[]
#define SCREEN_WIDTH
Definition macros.h:105
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define NPC_DISPOSE_POS_Y
Definition macros.h:160
#define SCREEN_HEIGHT
Definition macros.h:106
#define VIRTUAL_TO_PHYSICAL(addr)
Definition macros.h:47
s16 viewportStartX
s16 viewportStartY
Matrix4f mtxPerspective
void(* renderUI)(EffectInstance *effectInst)
Definition effects.h:2655
void(* init)(EffectInstance *effectInst)
Definition effects.h:2652
void(* update)(EffectInstance *effectInst)
Definition effects.h:2653
void(* renderWorld)(EffectInstance *effectInst)
Definition effects.h:2654
void * appendGfxArg
void(* appendGfx)(void *)
GameStatus * gGameStatusPtr
Definition main_loop.c:32
Camera gCameras[4]
Definition cam_main.c:17
Gfx * gMainGfxPos
Definition cam_main.c:15
s32 gCurrentCameraID
Definition cam_math.c:4