Alchemy
Loading...
Searching...
No Matches

djinn_attacks.c

Go to the documentation of this file.
1/// @file
2/// The Mercury, Jupiter, Venus and Mars Djinn attacks.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7/// Copies a w x h byte picture into an h x w one turned 90 degrees
8/// clockwise: the top row of src becomes the right column of dst.
9///
10/// Called twice by BattleFx_RunMercury, to lay its blue flames on their side.
11/// Writes only dst.
12void Graphics_TransposeCopy(const u8 *src, u8 *dst, s32 w, s32 h) {
13 s32 y;
14 s32 x;
15 s32 column;
16 s32 offset;
17 u8 *to;
18 const u8 *from;
19
20 y = 0;
21 if (h != 0) {
22 offset = 0;
23 column = h;
24 do {
25 x = 0;
26 if (w != 0) {
27 to = (u8 *)(column + (u32)dst - 1);
28 from = (const u8 *)(offset + (u32)src);
29 do {
30 x++;
31 *to = *from;
32 from++;
33 to += h;
34 } while (x != w);
35 }
36 y++;
37 offset += w;
38 column--;
39 } while (y != h);
40 }
41}
42
43// The Djinn attacks. The folder README describes them under "Effect
44// families".
45
46#define MERCURY_FRAMES 96
47/// The blue flame sheet holds a 17x104 flame, then a 34x65 one; Mercury
48/// turns both on their side after its Djinni, Venus draws the second.
49#define DJINN_ATTACKS_FLAME2_CELLS (17 * 104)
50/// The first flame turned, 104x17, after the 20x34 Djinni; never drawn.
51#define MERCURY_TALL_FLAME_CELLS 0x2a8
52#define MERCURY_FLAME_CELLS 0x990 ///< 65x34
53#define MERCURY_FLAMES 5 ///< flames thrown
54/// The mote slots Mercury walks: room for more than MERCURY_FLAMES *
55/// DJINN_ATTACKS_MOTES_PER_FLAME.
56#define MERCURY_MOTE_SLOTS 256
57// The Djinn attacks share these: each flame, ball or column that lands
58// throws its motes into its own DJINN_ATTACKS_MOTES_PER_FLAME slots of
59// PARTICLES (Venus's columns fill 16 of them), and the motes move through all
60// DJINN_ATTACKS_MOTE_SLOTS. A mote's variant is its life left, -1 when free;
61// at life 0 it still draws once before its slot is freed.
62#define DJINN_ATTACKS_MOTES_PER_FLAME 32 ///< slots for each flame's motes
63#define DJINN_ATTACKS_MOTE_SLOTS 512
64
65/// Mercury Djinni flames: the small Mercury Djinni spirals around (96, 60) and
66/// fires five blue flames to the left; each flame shatters into 32 motes after
67/// 5 frames, hitting every target.
68///
69/// Abilities: Mercury (kind 251).
70///
71/// work->particles 0 to 4 hold the flames, variant -1 until launched and then
72/// counting the frames since; Ram_MapCellBuffer takes the blue flame sheet
73/// before it is turned. Sets work->shakeFrames as each flame shatters, and
74/// ends with the transfer callback removed, the blitters freed and the canvas
75/// layer closed.
76///
77/// effect: the targets.
79 void **slots;
80 void **cursor;
81 struct BattleEffectWork *work;
82 void *canvas;
83 s32 frame;
84 u8 *sheet;
85 BlitterPair blit;
86 DrawRectangle *draw;
87 struct EffectStep *flame;
88 struct EffectStep *mote;
89 u8 *cells;
90 s32 i;
91 s32 j;
92
93 EFFECT_GET_SLOTS(slots, cursor, work, canvas);
94 sheet = EFFECT_SLOT(slots, HEAP_SLOT_BATTLE_SHEET);
95 work->effect = effect;
97 draw = blit;
99
100 // The flame pictures are the blue flame sheet turned on its side.
101 cells = Ram_MapCellBuffer;
104 work->sheet, 1, 0);
106 Graphics_TransposeCopy(cells, work->sheet + MERCURY_TALL_FLAME_CELLS, 17,
107 104);
109 work->sheet + MERCURY_FLAME_CELLS, 34, 65);
110 // Each transfer keeps three quarters of every level, for trails.
112 EFFECT_FREE_PARTICLES(i, work->particles, 8);
115 frame = 0;
116 do {
117 if (frame == 56)
119
120 // Flames move 12 pixels left a frame and shatter on their 5th frame;
121 // a shattered flame is still drawn, flying on off the canvas.
122 for (i = 0; i != MERCURY_FLAMES; i++) {
123 flame = &work->particles[i];
124 if (flame->variant != -1) {
125 blit[0](canvas, work->sheet + MERCURY_FLAME_CELLS, flame->x - 16,
126 flame->y - 17, 65, 34);
127 flame->x -= 12;
128 flame->variant++;
129 if (flame->variant == 5) {
131 work->shakeFrames = 4;
132 // Each mote flies off in a random direction at a speed of 256 to
133 // 767; its vertical speed is doubled, so the burst is twice as tall
134 // as it is wide.
135 for (j = 0; j != DJINN_ATTACKS_MOTES_PER_FLAME; j++) {
136 s32 angle;
137 s32 speed;
138
140 angle = Random16() & 0xffff;
141 speed = (Random16() & 0x1ff) + 256;
142 mote->x = flame->x << 16;
143 mote->y = flame->y << 16;
144 mote->velocityX = (Trig_Sin(angle) * speed) >> 8;
145 mote->velocityY = (Trig_Cos(angle) * speed) >> 7;
146 mote->variant = (Random16() & 15) + 32; // lives 32 to 47 frames
147 }
148 }
149 }
150 }
151
152 // The Djinni turns once every 32 frames. Its radius, 64 - 2 * frame
153 // (half that across), reaches 0 at frame 32, passing through the
154 // centre, and then grows on the other side.
155 if (frame <= 95) {
156 s32 x = ((Trig_Sin(frame << 11) * (64 - frame * 2)) >> 17) + 96;
157 s32 y = ((Trig_Cos(frame << 11) * (64 - frame * 2)) >> 16) + 60;
158
159 draw[1](canvas, work->sheet, x - 10, y - 17, 20, 34);
160 for (i = 0; i != MERCURY_FLAMES; i++) {
161 // Fire a flame from the Djinni on each launch frame; 6 frames later,
162 // a frame after it shatters, the targets flash white in their damage
163 // pose for 6 frames and play motion 6. velocityX keeps the launch x,
164 // which nothing reads.
165 if (frame == gDjinnAttacks_LaunchFrames[i]) {
166 struct EffectStep *shot = &work->particles[i];
167
168 if (shot->variant == -1) {
169 shot->x = x - 8;
170 shot->velocityX = x;
171 shot->y = y;
172 shot->variant = 0;
173 break;
174 }
175 }
176 if (frame == gDjinnAttacks_LaunchFrames[i] + 6) {
178 EFFECT_STRIKE_TARGET(work->effect, j, 6, 6);
179 }
180 }
181 }
182 }
183
184 // Motes shrink as they age and slow as they fall.
185 for (i = 0; i != MERCURY_MOTE_SLOTS; i++) {
186 mote = &PARTICLES[i];
187 if (mote->variant != -1) {
188 s32 size = mote->variant / 16 + 2;
189
190 EFFECT_DRAW_MOTE(draw[1], canvas, sheet, Q_16_16_TO_INT(mote->x),
191 Q_16_16_TO_INT(mote->y), size);
192 EffectStep_AdvanceWithGravity2D(mote, 62, 0x2000);
193 mote->variant--;
194 }
195 }
196 Camera_ApplyShake(4, 4);
197 EFFECT_END_FRAME(work);
198 frame++;
199 } while (frame != MERCURY_FRAMES);
201}
202
203#define JUPITER_FRAMES 96
204#define JUPITER_FLAMEBALLS 8 ///< flameballs that fall
205#define JUPITER_GROUND_Y 95 ///< where the flameballs land
206#define JUPITER_FLAMEBALL_CELLS 0x320 ///< after the 20x40 Djinni
207
208/// Jupiter Djinni fall: the small Jupiter Djinni spirals while eight flameballs
209/// fall from the top right to the bottom left, 4 frames apart; each shatters
210/// into 32 motes below line 95, hitting every target.
211///
212/// Abilities: Jupiter (kind 253).
213///
214/// work->particles holds the flameballs. Copies the Djinni's palette over the
215/// first 128 bytes of BG palette RAM, writes REG_BLDALPHA, sets
216/// work->shakeFrames as each ball lands, and ends with the transfer callback
217/// removed, the blitters freed and the canvas layer closed.
218///
219/// effect: the targets.
221 void **slots;
222 void **cursor;
223 struct BattleEffectWork *work;
224 void *canvas;
225 u8 *sheet;
226 BlitterPair blit;
227 DrawRectangle *draw;
228 struct EffectStep *ball;
229 struct EffectStep *mote;
230 s32 frame;
231 s32 i;
232 s32 j;
233 s32 angle;
234
235 EFFECT_GET_SLOTS(slots, cursor, work, canvas);
236 sheet = EFFECT_SLOT(slots, HEAP_SLOT_BATTLE_SHEET);
237 work->effect = effect;
239 REG_BLDALPHA = BLEND_ALPHA(16, 16);
240 draw = blit;
244 work->sheet, 1, 1);
246 work->sheet + JUPITER_FLAMEBALL_CELLS, 1, 0);
247 // Each transfer fades the canvas to 3/4.
249
250 // The flameballs start at x 64 to 127, y -80 to -17; 32 are placed, the
251 // first 8 fall. A ball is done once it is below the ground line.
252 for (i = 0; i != 32; i++) {
253 ball = &work->particles[i];
254 ball->x = (Random16() & 63) + 64;
255 ball->y = (Random16() & 63) - 80;
256 }
259 frame = 0;
260 angle = 0x8000; // 180 degrees
261 do {
262 if (frame == 56)
264
265 // The Djinni turns 11.25 degrees a frame. Its radius, 64 - 2 * frame
266 // (half that across), reaches 0 at frame 32, passing through the
267 // centre, and then grows on the other side.
268 if (frame <= 95) {
269 s32 x = (Trig_Sin(angle) * (64 - frame * 2)) >> 17;
270 s32 y = (Trig_Cos(angle) * (64 - frame * 2)) >> 16;
271
272 blit[0](canvas, work->sheet, x + 86, y + 28, 20, 40);
273 }
274
275 // Flameballs: one every 4 frames from frame 8, moving 6 pixels left and
276 // 12 down a frame. Landing throws its motes twice as fast up and down
277 // as across, and hits every target.
278 for (i = 0; i != JUPITER_FLAMEBALLS; i++) {
279 ball = &work->particles[i];
280 if (frame >= i * 4 + 8 && ball->y <= JUPITER_GROUND_Y) {
281 blit[0](canvas, work->sheet + JUPITER_FLAMEBALL_CELLS, ball->x - 20,
282 ball->y - 32, 40, 64);
283 ball->x -= 6;
284 ball->y += 12;
285 if (ball->y > JUPITER_GROUND_Y) {
286 for (j = 0; j != DJINN_ATTACKS_MOTES_PER_FLAME; j++) {
287 s32 direction;
288 s32 speed;
289
291 direction = Random16() & 0xffff;
292 speed = (Random16() & 0x1ff) + 256;
293 mote->x = ball->x << 16;
294 mote->y = ball->y << 16;
295 mote->velocityX = (Trig_Sin(direction) * speed) >> 7;
296 mote->velocityY = (Trig_Cos(direction) * speed) >> 6;
297 mote->variant = (Random16() & 15) + 32; // lives 32 to 47 frames
298 }
300 work->shakeFrames = 4;
302 EFFECT_STRIKE_TARGET(work->effect, j, 6, 6);
303 }
304 }
305 }
306 }
307
308 // Motes shrink as they age and slow as they fall.
309 for (i = 0; i != DJINN_ATTACKS_MOTE_SLOTS; i++) {
310 mote = &PARTICLES[i];
311 if (mote->variant != -1) {
312 s32 size = mote->variant / 16 + 1;
313
314 EFFECT_DRAW_MOTE(draw[1], canvas, sheet, Q_16_16_TO_INT(mote->x),
315 Q_16_16_TO_INT(mote->y), size);
316 EffectStep_AdvanceWithGravity2D(mote, 62, 0x2000);
317 mote->variant--;
318 }
319 }
320 Camera_ApplyShake(4, 4);
321 EFFECT_END_FRAME(work);
322 angle -= 0x800; // 11.25 degrees
323 frame++;
324 } while (frame != JUPITER_FRAMES);
326}
327
328/// Decompresses a resource whose first 128 bytes may be a palette.
329///
330/// Called by nearly every effect to load its pictures. Writes dst and, with
331/// copyPalette, the first 128 bytes of BG palette RAM.
332///
333/// id: the resource.
334/// dst: receives the decompressed data.
335/// skipPalette: the resource starts with a palette to skip.
336/// copyPalette: copy that palette to the start of background palette RAM.
337void Resource_LoadAndDecompress(s32 id, void *dst, s32 skipPalette,
338 s32 copyPalette) {
339 u8 *data = Resource_GetTableEntry(id);
340
341 if (copyPalette != 0)
342 Iwram_CopyWords((void *)BG_PLTT, data, 128);
343 if (skipPalette != 0)
344 data += 128;
345 Resource_DecodeType01(data, dst);
346}
347
348#define VENUS_FRAMES 96
349#define VENUS_COLUMNS 10 ///< columns of flame that rise
350/// The blue flame sheet, after the 20x38 Djinni, and its second flame.
351#define VENUS_FLAME_SHEET 0x2f8
352#define VENUS_COLUMN_CELLS (VENUS_FLAME_SHEET + DJINN_ATTACKS_FLAME2_CELLS)
353
354/// Venus Djinni columns: the small Venus Djinni sways while ten columns of
355/// flame in its colours rise from the ground one after another, each bursting
356/// into motes and hitting every target.
357///
358/// Abilities: Venus (kind 250).
359///
360/// work->particles holds the columns. Copies the Djinni's palette over the
361/// first 128 bytes of BG palette RAM, writes REG_BLDALPHA, sets
362/// work->shakeFrames as each column appears, and ends with the transfer
363/// callback removed, the blitters freed and the canvas layer closed.
364///
365/// effect: the targets.
367 void **slots;
368 void **cursor;
369 struct BattleEffectWork *work;
370 void *canvas;
371 s32 frame;
372 BlitterPair draw;
373 u8 *sheet;
374 struct EffectStep *column;
375 struct EffectStep *mote;
376 s32 i;
377 s32 j;
378 s32 angle;
379
380 EFFECT_GET_SLOTS(slots, cursor, work, canvas);
381 sheet = EFFECT_SLOT(slots, HEAP_SLOT_BATTLE_SHEET);
382 work->effect = effect;
384 REG_BLDALPHA = BLEND_ALPHA(16, 16);
389 draw[0] = EFFECT_SLOT(slots, HEAP_SLOT_BLITTER);
393 1, 1);
395 work->sheet + VENUS_FLAME_SHEET, 1, 0);
397 // The flame columns start at the bottom, at random x from 0 to 63; 32
398 // are placed, the first 10 rise. The columns draw flipped upside down.
399 for (i = 0; i != 32; i++) {
400 column = &work->particles[i];
401 column->x = Random16() & 63;
402 column->y = 104;
403 }
406 frame = 0;
407 angle = 0x8000;
408 do {
409 // Until frame 79 the Djinni sways 24 pixels from side to side, a turn
410 // every 32 frames, while its height swings on a radius that shrinks
411 // through 0 at frame 32.
412 if (frame <= 79) {
413 s32 x = (Trig_Sin(angle) * 24) >> 16;
414 s32 y = (Trig_Cos(angle) * (64 - frame * 2)) >> 16;
415
416 draw[1](canvas, work->sheet, x + 22, y + 29, 20, 38);
417 }
418 if (frame == 56)
420 // Ten flame columns rise 12 pixels a frame, one every 4 frames from
421 // frame 16; each throws 16 motes upwards (directions in the upper half
422 // turn) and hits every target as it appears, with a sound for odd ones.
423 for (i = 0; i != VENUS_COLUMNS; i++) {
424 column = &work->particles[i];
425 if (frame >= i * 4 + 16) {
426 draw[0](canvas, work->sheet + VENUS_COLUMN_CELLS, column->x - 17,
427 column->y - 32, 34, 65);
428 if (frame == i * 4 + 16) {
429 for (j = 0; j != 16; j++) {
430 s32 direction;
431 s32 speed;
432
434 direction = (Random16() & 0x7fff) + 0x4000;
435 speed = (Random16() & 0x1ff) + 256;
436 mote->x = column->x << 16;
437 mote->y = (column->y + 16) << 16;
438 mote->velocityX = (Trig_Sin(direction) * speed) >> 7;
439 mote->velocityY = (Trig_Cos(direction) * speed) >> 6;
440 mote->variant = (Random16() & 15) + 32;
441 }
442 if (i & 1)
444 work->shakeFrames = 4;
446 EFFECT_STRIKE_TARGET(work->effect, j, 6, 6);
447 }
448 }
449 column->y -= 12;
450 }
451 }
452 // Motes shrink as they age and slow as they fall.
453 for (i = 0; i != DJINN_ATTACKS_MOTE_SLOTS; i++) {
454 mote = &PARTICLES[i];
455 if (mote->variant != -1) {
456 s32 size = mote->variant / 16 + 2;
457
458 EFFECT_DRAW_MOTE(draw[1], canvas, sheet, Q_16_16_TO_INT(mote->x),
459 Q_16_16_TO_INT(mote->y), size);
460 EffectStep_AdvanceWithGravity2D(mote, 62, 0x2000);
461 mote->variant--;
462 }
463 }
464 Camera_ApplyShake(4, 4);
465 EFFECT_END_FRAME(work);
466 angle -= 0x800;
467 frame++;
468 } while (frame != VENUS_FRAMES);
470}
471
472#define MARS_FRAMES 112
473#define MARS_STRIKE_FRAME 32 ///< the Djinni strikes the ground
474#define MARS_FLAMES 9 ///< flames along the arc
475#define MARS_EMBERS_PER_FLAME 16 ///< embers in each flame
476#define MARS_ORB_CELLS 0x320 ///< six 40x40 orb pictures, after the Djinni
477
478/// Mars Djinni flames: a glowing orb flares, the small Mars Djinni dives to the
479/// ground, and nine flames erupt in a row while embers rise.
480///
481/// Abilities: Mars (kind 252).
482///
483/// The scene runs for 112 frames:
484///
485/// 0 to 23 the orb flares
486/// 20 to 31 the Djinni appears, then dives from frame 24
487/// 32 it strikes: the screen shakes and the flames start erupting
488/// 38 every target is hit
489/// 40 on the embers rise, 16 more every 2 frames
490///
491/// work->particles holds the nine flames, PARTICLES their 144 embers. The BG
492/// palette's first 128 bytes change three times: the glow orb's at the
493/// start, the Djinni's on frame 20 and the ember streak's on frame 32, when
494/// the streak sheet replaces the Djinni in work->sheet. Sets
495/// work->shakeFrames on the strike, and ends with the transfer callback
496/// removed, the blitters freed and the canvas layer closed.
497///
498/// effect: the targets.
500 void **slots;
501 void **cursor;
502 struct BattleEffectWork *work;
503 void *canvas;
504 u8 *sheet;
505 BlitterPair blitters;
506 DrawRectangle *draw;
507 struct EffectStep *step;
508 struct EffectStep *mote;
509 s32 index;
510 s32 frame;
511 s32 i;
512 s32 diveY;
513
514 EFFECT_GET_SLOTS(slots, cursor, work, canvas);
515 sheet = EFFECT_SLOT(slots, HEAP_SLOT_BATTLE_SHEET);
516 work->effect = effect;
518 draw = blitters;
522 1, 0);
524 work->sheet + MARS_ORB_CELLS, 1, 1);
526
527 // Nine flames along a flattened arc, 2 frames apart, each with 16
528 // embers that rise wobbling from the ground beneath it.
529 index = 0;
530 step = work->particles;
531 do {
532 s32 angle = index << 11;
533
534 step->x = (Trig_Sin(angle) * 24) >> 16;
535 step->y = ((Trig_Cos(angle) * 4) >> 16) + 52;
536 if (index & 1)
537 step->x = 32 - step->x;
538 else
539 step->x += 32;
540 step->variant = -(index * 2);
541 for (i = 0; i != MARS_EMBERS_PER_FLAME; i++) {
542 mote = &PARTICLES[index * MARS_EMBERS_PER_FLAME + i];
543 mote->x = (((Random16() & 15) + step->x) - 8) << 16;
544 mote->y = ((Random16() & 7) + 96) << 16;
545 mote->velocityX = ((Random16() & 127) - 64) << 11;
546 mote->velocityY = ((Random16() & 127) - 64) << 10;
547 mote->z = Random16() & 0xffff;
548 mote->velocityZ = Random16() & 0xffff;
549 }
550 step++;
551 index++;
552 } while (index != MARS_FLAMES);
553
555 frame = 0;
556 diveY = -172;
557 do {
558 if (frame == 56)
560 // A glowing orb flares, six pictures of 4 frames, then the Djinni shows
561 // beside it and from frame 24 dives down to the left, 4 pixels across
562 // and 8 down a frame.
563 if (frame <= 23)
564 blitters[0](canvas,
565 work->sheet + MARS_ORB_CELLS + (frame / 4) * (40 * 40), 40,
566 20, 40, 40);
567 // On frame 20 the small Djinni's palette replaces the start of the
568 // background palette.
569 if (frame == 20)
571 (void *)BG_PLTT,
573 if (frame >= 20 && frame <= 31) {
574 if (frame > 23)
575 draw[1](canvas, work->sheet, 146 - frame * 4, diveY, 20, 40);
576 else
577 blitters[0](canvas, work->sheet, 50, 20, 20, 40);
578 }
579 // At frame 32 it strikes: the screen shakes and the flames erupt. The
580 // Djinni is no longer drawn, so the ember streaks take its place in the
581 // sheet, with their palette.
582 if (frame == MARS_STRIKE_FRAME) {
584 work->shakeFrames = 8;
586 1, 1);
587 }
588 if (frame > 31) {
589 index = 0;
590 step = work->particles;
591 do {
592 // A flame plays the six puff cells, 8 frames each; its variant counts
593 // its frames, starting below 0 so the flames erupt 2 frames apart.
594 if (step->variant >= 0 && step->variant <= 47) {
595 s32 cell = step->variant / 8;
596 u32 width;
597
598 // UB: width is assigned in one argument and read in another.
599#ifdef UBFIX
600 width = gBattleFx_PuffArcCellWidths[cell];
601 blitters[0](canvas, work->sheet + gBattleFx_PuffArcCells[cell],
602 step->x - (width >> 1),
603 step->y + gBattleFx_PuffArcCellBiasY[cell], width,
605#else
606 blitters[0](canvas, work->sheet + gBattleFx_PuffArcCells[cell],
607 step->x -
608 ((width = gBattleFx_PuffArcCellWidths[cell]) >> 1),
609 step->y + gBattleFx_PuffArcCellBiasY[cell], width,
611#endif
612 }
613 index++;
614 step->variant++;
615 step++;
616 } while (index != MARS_FLAMES);
617 }
618 // The embers rise from frame 40, each flame's 16 two frames after the
619 // last's, swaying 4 pixels either way; an ember's z is its sway phase,
620 // stepped 1/32 of a turn a frame. Embers never die; they rise off the
621 // canvas.
622 step = PARTICLES;
623 index = 0;
624 do {
625 if (frame >= (index / MARS_EMBERS_PER_FLAME) * 2 + 40) {
626 s32 size;
627 s32 x;
628 s32 angle;
629
630 size = (index & 1) + 3;
631 x = Q_16_16_TO_INT(step->x) + ((Trig_Sin(step->z) * 4) >> 16);
632 draw[1](canvas, sheet + gBattleFx_MoteCells[size - 1],
633 x - ((u32)size >> 1), Q_16_16_TO_INT(step->y) - size, size,
634 size * 2);
635 EffectStep_AdvanceWithGravity2D(step, 64, -0x2000);
636 angle = step->z;
637 step->z = angle + 0x800;
638 if (step->z > 0xffff)
639 step->z = angle + 0x800 - 0xffff;
640 }
641 index++;
642 step++;
643 } while (index != MARS_FLAMES * MARS_EMBERS_PER_FLAME);
644
645 // Every target is hit on frame 38, flashing for 16 frames.
646 if (frame == 38) {
647 EFFECT_FOR_EACH_TARGET(index, work->effect) {
648 EFFECT_STRIKE_TARGET(work->effect, index, 16, 6);
649 }
650 }
651 Camera_ApplyShake(8, 8);
652 EFFECT_END_FRAME(work);
653 diveY += 8;
654 frame++;
655 } while (frame != MARS_FRAMES);
657}
658
659#undef MERCURY_FRAMES
660#undef MERCURY_FLAMES
661#undef DJINN_ATTACKS_MOTES_PER_FLAME
662#undef DJINN_ATTACKS_MOTE_SLOTS
663#undef JUPITER_FRAMES
664#undef JUPITER_FLAMEBALLS
665#undef JUPITER_GROUND_Y
666#undef VENUS_FRAMES
667#undef VENUS_COLUMNS
668#undef MARS_FRAMES
669#undef MARS_STRIKE_FRAME
670#undef MARS_FLAMES
671#undef MARS_EMBERS_PER_FLAME
672#undef DJINN_ATTACKS_FLAME2_CELLS
673#undef MERCURY_TALL_FLAME_CELLS
674#undef MERCURY_FLAME_CELLS
675#undef JUPITER_FLAMEBALL_CELLS
676#undef VENUS_FLAME_SHEET
677#undef VENUS_COLUMN_CELLS
678#undef MARS_ORB_CELLS
679#undef MERCURY_MOTE_SLOTS
@ COMPOSITE_FLIP_Y
@ COMPOSITE_ADDITIVE
@ COMPOSITE_MAX
BattleEffectDrawRectangle DrawRectangle
#define EFFECT_FOR_EACH_TARGET(i, effect)
Loops i over the effect's targets, effect->actors[0] to effect->actors[effect->count - 1]: the loops ...
void BattleFx_BeginCanvasLayer(s32 bgControl)
Opens the canvas layer: starts the background palette fade, makes BG2 the canvas, alpha-blended over ...
Definition canvas.c:314
#define JUPITER_FRAMES
#define MERCURY_FLAMES
flames thrown
#define DJINN_ATTACKS_MOTE_SLOTS
void BattleFx_RunMars(struct BattleEffectArgument *effect)
Mars Djinni flames: a glowing orb flares, the small Mars Djinni dives to the ground,...
#define MARS_STRIKE_FRAME
the Djinni strikes the ground
#define VENUS_FLAME_SHEET
The blue flame sheet, after the 20x38 Djinni, and its second flame.
#define JUPITER_GROUND_Y
where the flameballs land
#define MARS_FRAMES
void Graphics_TransposeCopy(const u8 *src, u8 *dst, s32 w, s32 h)
Copies a w x h byte picture into an h x w one turned 90 degrees clockwise: the top row of src becomes...
#define MERCURY_FRAMES
#define VENUS_FRAMES
#define DJINN_ATTACKS_MOTES_PER_FLAME
slots for each flame's motes
#define MERCURY_MOTE_SLOTS
The mote slots Mercury walks: room for more than MERCURY_FLAMES * DJINN_ATTACKS_MOTES_PER_FLAME.
#define DJINN_ATTACKS_FLAME2_CELLS
The blue flame sheet holds a 17x104 flame, then a 34x65 one; Mercury turns both on their side after i...
void BattleFx_RunMercury(struct BattleEffectArgument *effect)
Mercury Djinni flames: the small Mercury Djinni spirals around (96, 60) and fires five blue flames to...
#define JUPITER_FLAMEBALLS
flameballs that fall
#define VENUS_COLUMNS
columns of flame that rise
void BattleFx_RunJupiter(struct BattleEffectArgument *effect)
Jupiter Djinni fall: the small Jupiter Djinni spirals while eight flameballs fall from the top right ...
void Resource_LoadAndDecompress(s32 id, void *dst, s32 skipPalette, s32 copyPalette)
Decompresses a resource whose first 128 bytes may be a palette.
#define MARS_FLAMES
flames along the arc
#define JUPITER_FLAMEBALL_CELLS
after the 20x40 Djinni
#define MARS_ORB_CELLS
six 40x40 orb pictures, after the Djinni
#define VENUS_COLUMN_CELLS
#define MERCURY_FLAME_CELLS
65x34
#define MARS_EMBERS_PER_FLAME
embers in each flame
void BattleFx_RunVenus(struct BattleEffectArgument *effect)
Venus Djinni columns: the small Venus Djinni sways while ten columns of flame in its colours rise fro...
#define MERCURY_TALL_FLAME_CELLS
The first flame turned, 104x17, after the 20x34 Djinni; never drawn.
What every part of the battle effect object shares: its includes, macros and frame-loop helpers.
#define EFFECT_DRAW_MOTE(draw, canvas, sheet, x, y, size)
Particle sheets hold ten mote cells, 1x2 to 10x20 pixels.
@ CANVAS_COPY_AND_FADE
copy, keeping 50% or 75% (transferValue) of each pixel in the canvas for the next frame
#define EFFECT_SLOT(slots, slot)
A work slot read through a pointer to the effect's own slot, gWorkSlot[HEAP_SLOT_BATTLE_EFFECT].
#define EFFECT_FINISH_CANVAS()
The usual end of a canvas effect: stops the transfer callback before freeing what it reads,...
#define EFFECT_SHOW_DAMAGE(hitSound)
Lets the battle show the damage: resumes its paused playback, which plays hitSound (an SE_ id; 0 keep...
#define EFFECT_START_TRANSFER(work, mode, value)
Sets the transfer, then starts copying the canvas to VRAM once a frame.
#define EFFECT_FREE_PARTICLES(i, particles, count)
Marks particles[0] to particles[count - 1] free: a particle whose variant is -1 is not drawn or moved...
#define EFFECT_LOAD_BLITTER(slot, flags, mode)
Builds a blitter for the 128x128 canvas (1 << 7 pixels each way) in work slot slot: BattleFx_BuildBli...
#define EFFECT_GET_SLOTS(slots, cursor, work, canvas)
Starts at the effect's entry in the whole work-slot array.
#define EFFECT_END_FRAME(work)
The usual end of an effect frame: counts down the targets' flash timers (ObjectGroup_TickMemberTimers...
#define EFFECT_STRIKE_TARGET(effect, i, frames, motion)
Strikes target i: it flashes white in its damage pose for frames frames and plays battle motion motio...
u16 gBattleFx_PuffArcCells[]
u8 gBattleFx_PuffArcCellHeights[]
u8 gBattleFx_PuffArcCellBiasY[]
u16 gBattleFx_MoteCells[]
Mote cells: particle sheets hold ten, cell n (from 0) n + 1 pixels wide and twice that tall.
u8 gBattleFx_PuffArcCellWidths[]
u8 gDjinnAttacks_LaunchFrames[]
The frames on which the Djinni fires each of its five flames.
void AudioCommand_PlayFar(s32 id)
s32 Trig_Cos(s32 angle)
s32 Trig_Sin(s32 angle)
void Camera_ApplyShake(s32 rangeX, u32 rangeY)
Shakes the battle view while gBattleFxWork's shakeFrames lasts, moving BG1 and the projection centre ...
Definition hail.c:364
@ HEAP_SLOT_BLITTER_ALTERNATE
Definition heap_state.h:47
@ HEAP_SLOT_BATTLE_SHEET
Definition heap_state.h:44
@ HEAP_SLOT_BLITTER
Definition heap_state.h:46
#define BLEND_ALPHA(top, bottom)
A REG_BLDALPHA value: top and bottom are the two targets' weights, out of 16.
Definition io_reg.h:145
#define REG_BLDALPHA
Definition io_reg.h:142
#define BG_PLTT
Definition io_reg.h:157
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
Definition iwram_call.h:85
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
Definition math.c:10
void BattleFx_FetchRectangleBlitters(s32 flip, BlitterPair out)
Builds the two usual routines that draw onto the 128x128 canvas, both clipped on both axes.
void EffectStep_AdvanceWithGravity2D(struct EffectStep *step, s32 damping, s32 gravity)
Moves a particle one frame on the screen: adds its velocity, then gravity to its vertical speed,...
Definition positions.c:46
#define Ram_MapCellBuffer
Definition ram_buffer.h:10
char ResourceId_VenusDjinnSmallSheet
char ResourceId_MarsDjinnSmallSheet
char ResourceId_MercuryDjinnSmallSheet
char ResourceId_BlueFlameSheet
char ResourceId_ParticleSpritesA
char ResourceId_JupiterDjinnSmallSheet
char ResourceId_EmberStreakSheet
char ResourceId_FlameballSheet
char ResourceId_GlowOrbSheet
s32 Resource_DecodeType01(const void *source, void *destination)
Decodes a type-01 resource and returns its unpacked byte count.
Definition decompress.c:31
#define SE_162
Definition songs.h:157
#define SE_133
Definition songs.h:126
#define SE_136
Definition songs.h:129
#define SE_171
Definition songs.h:166
#define SE_141
Definition songs.h:134
#define SE_145
Definition songs.h:138
The command shared by an effect's caller, dispatcher and handlers.
The running battle effect's work: its canvas image, 64 particles, the display registers it stages and...
s32 frame
frame counter some effects keep, from 0
s32 shakeFrames
shake frames left; Camera_ApplyShake counts down
struct BattleEffectArgument * effect
the command being run
struct EffectStep particles[64]
free while variant is -1
A moving point of an effect: its position, its velocity and a value each effect uses its own way (a s...
Definition effect_step.h:13
s32 velocityX
16.16 fixed-point pixels per frame
Definition effect_step.h:28
s32 z
16.16 fixed-point pixels
Definition effect_step.h:26
s32 variant
each effect's own: a size, a countdown, -1 for idle
Definition effect_step.h:31
s32 x
16.16 fixed-point pixels
Definition effect_step.h:24
s32 y
16.16 fixed-point pixels
Definition effect_step.h:25
s32 velocityY
16.16 fixed-point pixels per frame
Definition effect_step.h:29
s32 velocityZ
16.16 fixed-point pixels per frame
Definition effect_step.h:30
void * Resource_GetTableEntry(s32 index)
Returns the ROM address of resource index from the resource directory.
Definition system.c:150
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
unsigned char u8
Definition types.h:11
#define EFFECT_CLIP_BOUNDS
Clips overflow on all four sides.
Definition effect.h:224
#define Q_16_16_TO_INT(v)
Definition effect.h:231
#define PARTICLES
The map cell buffer (gMapCellBuffer), which the effects borrow, has two views here: Ram_MapCellBuffer...
Definition effect.h:221
DrawRectangle BlitterPair[2]
A blitter pair: [0] built in HEAP_SLOT_BLITTER and [1] in HEAP_SLOT_BLITTER_ALTERNATE (BattleFx_Fetch...
Definition effect.h:244