Alchemy
Loading...
Searching...
No Matches

judgment.c

Go to the documentation of this file.
1/// @file
2/// The Judgment summon.
3/// Part of effect.c, the battle effect object, compiled only through it. The
4/// folder README describes its two parts, the gathering and the sweep, under
5/// "Effect families".
6
8
9/// The bytes of Judgment's work block before its dimmed mote copies.
10#define JUDGMENT_SHEET_BYTES 0x2710
11
12/// Judgment's work block, laid over struct BattleEffectWork from its start.
13/// The sweep's 120x120 wave picture, from the block's start, later overwrites
14/// both fields.
16 /// The gathering's pictures: the pink burst, the burst's quarters and the
17 /// tornado sheet.
19 /// Eight copies of the mote sheet, copy i with every level capped at
20 /// 64 - 7i; the gathering's ring of motes steps through them.
22};
23
24/// The gathering's 128 sparks, after its 128 motes in PARTICLES.
25#define JUDGMENT_SPARKS (&PARTICLES[128])
26
27#define JUDGMENT_GATHER_FRAMES 160 ///< frames of the gathering
28#define JUDGMENT_SWEEP_FRAMES 320 ///< frames of the sweep
29#define JUDGMENT_SHEET_FLARE_B 0x4240 ///< the second 24x24 flare picture
30#define JUDGMENT_FORMATION_OBJECTS 16 ///< objects in the formation, 4x4
31#define JUDGMENT_DEBRIS_OBJECTS 16 ///< debris objects of the sweep
32#define JUDGMENT_SHEET_BURST 0x600 ///< the burst's quarter pictures
33/// The tornado sheet, whose six glint pictures are the burst's shards
34/// (gJudgment_ShardCells counts from the sheet's start).
35#define JUDGMENT_SHEET_TORNADO 0x95c
36/// The explosion's four 32x54 pictures, loaded over the flares on the sweep's
37/// frame 64.
38#define JUDGMENT_SHEET_EXPLOSION 0x4000
39/// The first 24x24 flare picture, from the crescent sheet the sweep loads.
40#define JUDGMENT_SHEET_FLARE_A 0x4000
41/// The 16x17 small flash, the first of OverlayImageA's three pictures.
42#define JUDGMENT_SHEET_FLASH_SMALL 0x6000
43/// The 24x41 large flash picture.
44#define JUDGMENT_SHEET_FLASH_LARGE 0x6110
45/// The 22x44 flash streak picture.
46#define JUDGMENT_SHEET_FLASH_STREAK 0x64e8
47#define JUDGMENT_EXPLOSION_CELL_BYTES 1728 ///< bytes in each explosion picture
48#define JUDGMENT_WAVE_SIZE 120 ///< the wave picture is 120x120
49/// DMA word that fills the 128x128 canvas.
50#define JUDGMENT_DMA_FILL_CANVAS DMA_FILL_WORDS(0x1000)
51/// DMA word that fills the 120x120 wave picture.
52#define JUDGMENT_DMA_FILL_WAVE DMA_FILL_WORDS(0xe10)
53
54/// The battle wipes away to a violet sky where a formation flies forward while
55/// motes gather into it, bursts in a flash and sends out a ring of light.
56///
57/// Abilities: Judgment (scene kind 9).
58///
59/// The scene then cuts to an aerial view where the blast spreads in rings, to a
60/// beach, and to a forest swept by an explosion front, before brightening back
61/// into the battle. The folder README describes both parts. The scene leaves
62/// gProjection.centerY at 240.
64 static struct SpriteScale unitScale = {{{0x10000, 0x10000}}};
65 s32 anchor[3];
66 struct EffectPosition projectedPosition;
67 struct SpritePlacement place;
68 volatile u32 fill;
69 struct SpritePlacement debrisPlace;
70 struct SpriteScale pair;
71 struct SpriteScale scale;
72 void *canvas;
73 struct BattleEffectWork *work;
75 DrawRectangle draw[2];
76 s32 frame;
77 u8 *ramp;
78 struct BattleCamera *camera;
79 s32 depth;
80 s32 zoom;
81 s32 minimumDepth;
82 s32 maximumDepth;
83 void **cache;
84 DrawRectangle *slots;
85 s32 cx;
86 s32 cy;
87 s32 squash;
88 s32 sx;
89 s32 ring;
90 s32 rings;
91 s32 shift;
92 s32 i;
93 s32 j;
94 struct EffectStep *particle;
95 DrawRectangle blit;
96 volatile u16 *ime;
97
99 ime = (u16 *)&REG_IME;
100 canvas = cache[0];
103 ramp = CANVAS_SLOT(cache, HEAP_SLOT_BATTLE_SHEET);
104 camera = CANVAS_SLOT(cache, HEAP_SLOT_CAMERA);
105 work->effect = effect;
108 PLTT_BACKDROP = 0;
109 *(u16 *)&BG_PLTT[1] = 0;
116 // Setup: wipe the battle away, change the backdrop behind it, wipe back.
120 gProjection.centerY = 240;
121 WaitFrames(1);
123 // The scene owns BG1's scroll until frame 280 of the sweep.
124 ctrl->active = 1;
125 gBgScroll[1].x = 0;
128 // The formation starts 64 pixels back and comes forward 8 pixels a frame
129 // (16.16); the depth range is kept only by the dead spark stage.
130 depth = 0xffc00000;
131 zoom = 0x80000;
132 minimumDepth = 0xffff;
133 maximumDepth = 0;
135 1);
137 work->sheet + JUDGMENT_SHEET_BURST, 0, 0);
139 work->sheet + JUDGMENT_SHEET_TORNADO, 1, 0);
141
142 // Eight ever darker copies of the particle sprites, for fading: copy i
143 // caps every colour level at 64 - 7i, and the ring of motes from frame 144
144 // steps through them.
145 for (i = 0; i != 8; i++) {
146 u8 *src = ramp;
147 for (j = 0; j != MOTE_SET_BYTES; j++) {
148 s32 v = *src++;
149 EFFECT_CAP_LEVEL(v, 64 - i * 7);
150 ((struct JudgmentWork *)work)->ramp[i][j] = v;
151 }
152 }
153
154 Iwram_CopyWords((void *)BG_PLTT,
156 128);
157
158 for (i = 0; i != 128; i++) {
159 // A mote's radius is its x and its angles its velocities. It takes four
160 // random numbers: the fourth overwrites velocityY, losing the third.
161 PARTICLES[i].x = (Random16() & 15) + 72;
162 PARTICLES[i].velocityX = Random16() & 0xffff;
163 PARTICLES[i].velocityY = Random16() & 0xffff;
164 PARTICLES[i].velocityY = Random16() & 0xffff;
165 }
166
167 for (i = 0; i != 128; i++) {
168 // Sparks on a ring, 32 to 95 pixels up; only the dead stage in the frame
169 // loop reads them, but their random numbers still count.
170 s32 angle = Random16() & 0xffff;
171 /* FAKEMATCH: the amplitude is a value the native hoists into sl; as 255
172 * at both multiplies, 142 of 2455 instructions differ in tbs-en. */
173 s32 amp = 255;
174 /* FAKEMATCH: the velocities' zero is a value loop.c hoists into r8; as 0
175 * stored directly, 138 of 2455 instructions differ in tbs-en. */
176 s32 speed = 0;
177 JUDGMENT_SPARKS[i].x = (Trig_Sin(angle) * amp) >> 2;
178 JUDGMENT_SPARKS[i].z = (Trig_Cos(angle) * amp) >> 2;
179 JUDGMENT_SPARKS[i].y = ((Random16() & 63) + 32) << 16;
180 JUDGMENT_SPARKS[i].velocityX = speed;
181 JUDGMENT_SPARKS[i].velocityY = speed;
182 JUDGMENT_SPARKS[i].variant = angle;
183 }
184
188
189 // The gathering. A or B ends it after frame 4; on frame 143 the whole
190 // canvas flashes.
191 for (frame = 0; frame != JUDGMENT_GATHER_FRAMES &&
192 (frame <= 4 || !(gKeysRepeat & (KEY_A | KEY_B)));
193 frame++) {
194 /* FAKEMATCH: the frame > 143 block calls through a pointer to the slot
195 * table, set each frame; as the table named at the uses, 581 instructions
196 * differ in tbs-en. */
197 slots = (DrawRectangle *)gWorkSlot;
198 if (frame == 143) {
199 Iwram_FillWords(canvas, CANVAS_BYTES, 0x2a2a2a2a);
201 }
202 if (frame == 80) {
204 }
205
206 // DEAD: frame starts at 0 and only grows, so the sparks are never drawn;
207 // the ROM keeps the test and the stage.
208 if (frame < 0) {
210 for (i = 0; i != 128; i++) {
211 s32 z;
212 s32 size;
213
215 EffectPosition_ProjectPoint(&JUDGMENT_SPARKS[i], &projectedPosition);
216 projectedPosition.x >>= 1;
217 projectedPosition.y -= 120;
218 if (projectedPosition.depth < 100) {
219 projectedPosition.depth = 100;
220 }
221 if (projectedPosition.depth > 900) {
222 projectedPosition.depth = 900;
223 }
224 z = projectedPosition.depth - 100;
225 projectedPosition.depth = z;
226 size = (z / 100) + 1;
227 if (minimumDepth > z) {
228 minimumDepth = z;
229 }
230 if (maximumDepth < z) {
231 maximumDepth = z;
232 }
233 EFFECT_DRAW_MOTE(draw[0], canvas, ramp, projectedPosition.x,
234 projectedPosition.y, size);
235 if (frame == 64) {
236 JUDGMENT_SPARKS[i].velocityX +=
237 (Trig_Sin(JUDGMENT_SPARKS[i].variant) * 255) >> 3;
238 JUDGMENT_SPARKS[i].velocityY +=
239 (Trig_Cos(JUDGMENT_SPARKS[i].variant) * 255) >> 3;
240 }
241 }
242 }
243
244 // Frame 72: the backdrop starts its 24-frame fade
245 // (Palette_StepFadeTransfer).
246 if (frame == 72) {
247 work->fadeFrames = 24;
248 work->fadeStep = 0;
249 }
250
251 // Motes 0 to 63: from frame 81 + i / 4, mote i spins about the
252 // formation's centre on its own axes while its radius shrinks by 2 a
253 // frame to nothing. Nearer motes are drawn larger.
254 anchor[2] = 0;
255 anchor[1] = 0;
256 for (i = 0; i != 64; i++) {
257 if (frame > i / 4 + 80 && PARTICLES[i].x > 0) {
258 s32 size;
259
263 SceneTransform_ApplyYaw(PARTICLES[i].velocityY + (frame << 9));
264 anchor[0] = PARTICLES[i].x;
265 PARTICLES[i].x -= 2;
266 if (PARTICLES[i].x < 0) {
267 PARTICLES[i].x = 0;
268 }
269 EffectPosition_ProjectPoint(anchor, &projectedPosition);
270 if (projectedPosition.depth < -60) {
271 projectedPosition.depth = -60;
272 }
273 if (projectedPosition.depth > 60) {
274 projectedPosition.depth = 60;
275 }
276 projectedPosition.depth += 60;
277 size = projectedPosition.depth / 20 + 2;
278 projectedPosition.x += 60;
279 projectedPosition.y += 80;
280 EFFECT_DRAW_MOTE(draw[0], canvas, ramp, projectedPosition.x,
281 projectedPosition.y, size);
282 }
283 }
284
285 // Place the 4x4 formation at its natural size, then move it: it slows
286 // over the first 48 frames and eases towards a stop from frame 33,
287 // jumps back on frame 144 and drifts forward from 146. Frames 72 and 76
288 // change its animation.
289 pair = unitScale;
290 place.groundHeight = 0;
291 place.height = 0;
292 for (i = 0; i != JUDGMENT_FORMATION_OBJECTS; i++) {
293 place.x = ((i % 4) << 21) + (152 << 15);
294 place.y = ((i / 4) << 21) + depth;
295 Object_ApplyProjectedPlacementFar(work->objects[i], &place, &pair, 0);
296 }
297
298 depth += zoom;
299 if (frame <= 47) {
300 zoom -= 0x4000;
301 }
302 if (frame > 32) {
303 zoom = zoom * 60 / 64;
304 }
305 if (frame == 144) {
306 zoom = -0x80000;
307 }
308 if (frame == 146) {
309 zoom = 0x10000;
310 }
311
312 if (frame == 72) {
313 for (i = 0; i != JUDGMENT_FORMATION_OBJECTS; i++) {
315 }
316 }
317 if (frame == 76) {
318 for (i = 0; i != JUDGMENT_FORMATION_OBJECTS; i++) {
320 }
321 }
322
323 // Frames 116 to 143: the burst grows a picture every 4 frames at
324 // (60, 80), drawn as four mirrored quarters, and six shards scatter
325 // around it each frame.
326 if (frame >= 116 && frame < 144) {
327 s32 high;
328 s32 cell;
329 s32 n = (frame - 116) / 4;
330 if (n > 6) {
331 n = 6;
332 }
333 // Four explicit draws: a shared load, draw and release helper grew
334 // this runner by eight bytes in English (0x167c to 0x1684).
335 high = gJudgment_BurstHeights[n];
337
341 canvas, work->sheet + cell, 60 - high, 80 - high * 2, high, high * 2);
346 canvas, work->sheet + cell, 60, 80 - high * 2, high, high * 2);
351 canvas, work->sheet + cell, 60 - high, 80, high, high * 2);
358 canvas, work->sheet + cell, 60, 80, high, high * 2);
360
361 for (i = 0; i != 6; i++) {
362 s32 k = i & 3;
363 s32 angle = Random16() & 0xffff;
364 s32 x = ((Trig_Sin(angle) * 16) >> 16) - gJudgment_ShardWidths[k] / 2;
365 s32 y = ((Trig_Cos(angle) * 16) >> 16) - gJudgment_ShardHeights[k] / 2;
366 draw[0](canvas, work->sheet + gJudgment_ShardCells[k], x + 60, y + 80,
368 }
369 }
370
371 // From frame 144: a mirrored beam slides down 16 pixels a frame, the
372 // canvas keeps 75% of each frame, and for 14 frames a ring of 128 motes
373 // spreads from (60, 72) by 10 pixels a frame, a dimmer copy every 2
374 // frames. Each draw loads the alternate blitter and releases it at once.
375 if (frame > 143) {
376 s32 top = (frame << 4) - 2272;
377 s32 n;
378 s32 r;
381 (slots[HEAP_SLOT_BLITTER_ALTERNATE])(canvas, work->sheet, 36, top, 24,
382 64);
387 (slots[HEAP_SLOT_BLITTER_ALTERNATE])(canvas, work->sheet, 60, top, 24,
388 64);
390
391 n = (frame - 144) / 2;
392 r = frame * 10 - 1424;
393 work->transferValue = 75;
394 if (n <= 6) {
395 // The 8x16 mote of dimmed copy n in JudgmentWork's ramp.
396 s32 cell =
398 /* FAKEMATCH: the height is a value, so high / 2 is hoisted into fp; as
399 * the literals 4, 8 and 16, 690 of 2455 instructions differ in
400 * tbs-en. */
401 s32 high = 8;
404 blit = slots[HEAP_SLOT_BLITTER_ALTERNATE];
405 for (i = 0; i != 128; i++) {
406 s32 angle = i << 9;
407 s32 x = ((r * Trig_Sin(angle)) >> 16) - high / 2;
408 s32 y = (r * Trig_Cos(angle)) >> 17;
409 blit(canvas, work->sheet + cell, x + 60, y + 72, high, high * 2);
410 }
412 }
413 }
414
416 }
417
418 // The sweep's setup: replace the formation with 16 debris objects in three
419 // animations, load the crescent sheet and show the aerial view at the
420 // canvas's own width.
421 Iwram_FillWords(canvas, CANVAS_BYTES, 0);
422
423 for (i = 0; i != JUDGMENT_FORMATION_OBJECTS; i++) {
425 }
426
427 for (i = 0; i != JUDGMENT_DEBRIS_OBJECTS; i++) {
428 struct AnimationObject *obj = ResourceObject_CreateFar(390);
429 work->objects[i] = obj;
430 if (obj != 0) {
431 obj->flags = 0;
433 work->objects[i]->image.priority = 0;
434 }
435 }
436
441 work->sheet + JUDGMENT_SHEET_FLARE_A, 1, 1);
442
443 {
444 // Darken the mote sheet for the sweep: levels above 32 lose 32 (224
445 // added to a byte wraps), and the other nonzero levels become 1.
446 u8 *c = ramp;
447 for (i = 0; i != MOTE_SET_BYTES; i++, c++) {
448 if (*c > 32) {
449 *c += 224;
450 } else if (*c != 0) {
451 *c = 1;
452 }
453 }
454 }
455
456 // Stop the backdrop fade; the canvas, one texel a pixel, starts 60 pixels
457 // from the left, so the 120-pixel wave picture is centred on the screen.
458 work->fadeFrames = 0;
459 work->fadeStep = 0;
461 REG_BG2PA = Q_8_8(1);
462 REG_BG2X = -0x3c00;
465
466 fill = 0;
467 Dma_Set((const void *)&fill, canvas, JUDGMENT_DMA_FILL_CANVAS, REG_DMA3);
468
469 // The rings' centre in the wave picture (cx, cy), their width in eighths
470 // (sx, which also scales them above the centre), their depth below it
471 // (squash) and how many are drawn a frame. shift is the explosion
472 // front's x.
473 cx = 60;
474 cy = 44;
475 squash = 6;
476 shift = 0;
477 ring = 0;
478 sx = 8;
479 rings = 2;
481
482 // Clear the wave picture over the gathering's pictures (shift is still 0).
483 fill = shift;
484 Dma_Set((const void *)&fill, work, JUDGMENT_DMA_FILL_WAVE, REG_DMA3);
485
486 // The sweep, on its own frame clock: the impact on the aerial view (0 to
487 // 149), the beach (150 to 213), the forest (214 to 279), and from 280 the
488 // battle again, brightening a step every frame. On frame 300 the battle
489 // shows the damage.
490 for (frame = 0; frame != JUDGMENT_SWEEP_FRAMES; frame++) {
491 if (frame == 66) {
494 }
495 if (frame == 155) {
497 }
498 if (frame == 217) {
500 }
501 if (frame == 280) {
503 }
504 if (frame == 300) {
506 }
507
508 // A or B jumps to the next part: 150, 214 or 280. The jump to the beach
509 // also does the part of frame 64's change it would pass over.
510 if (gKeysRepeat & (KEY_A | KEY_B)) {
511 if (frame >= 5 && frame < 150) {
512 frame = 150;
513 IO_WRITE_QUEUE_PUSH_IME(ime, (u32)&REG_BG2PA, Q_8_8(0.5), 0x20000);
514 IO_WRITE_QUEUE_PUSH_IME(ime, (u32)&REG_BG2X, 0, 0x30000);
516 work->sheet + JUDGMENT_SHEET_EXPLOSION, 1,
517 0);
518 } else if (frame >= 155 && frame < 214) {
519 frame = 214;
520 } else if (frame >= 219 && frame < 280) {
521 frame = 280;
522 }
523 }
524
525 // Frame 64: BG2 back to twice the width, through the I/O write queue so
526 // that the scale changes 2 frames on and the position 3, once the cleared
527 // canvas reaches VRAM; then load the explosion and flash pictures.
528 if (frame == 64) {
529 IO_WRITE_QUEUE_PUSH_IME(ime, (u32)&REG_BG2PA, Q_8_8(0.5), 0x20000);
530 IO_WRITE_QUEUE_PUSH_IME(ime, (u32)&REG_BG2X, 0, 0x30000);
531 fill = 0;
532 Dma_Set((const void *)&fill, canvas, JUDGMENT_DMA_FILL_CANVAS, REG_DMA3);
534 work->sheet + JUDGMENT_SHEET_EXPLOSION, 1, 0);
536 work->sheet + JUDGMENT_SHEET_FLASH_SMALL, 0,
537 0);
538 }
539
540 if (frame == 66) {
541 // Invert the backdrop's colours, background palettes 6 to 13.
542 u16 *pal = (u16 *)&BG_PLTT_COLOR(6, 0);
543 for (i = 0; i != 128; i++, pal++) {
544 *pal ^= 0x7fff;
545 }
546 }
547
548 // Frames 69, 182 and 238 flash the whole canvas.
549 if (frame == 69) {
550 fill = 0x3f3f3f3f;
551 Dma_Set((const void *)&fill, canvas, JUDGMENT_DMA_FILL_CANVAS, REG_DMA3);
552 }
553
554 // Frame 70: undo the inversion, rewriting the backdrop's palette from the
555 // battle's copy with every channel 7 levels darker.
556 if (frame == 70) {
559 }
560
561 // Frame 150, the beach: the rings restart from (112, 32), four a frame
562 // and as deep below the centre as they are wide.
563 if (frame == 150) {
564 cx = 112;
565 cy = 32;
566 ring = 0;
567 fill = 0;
568 rings = 4;
569 squash = 8;
570 Dma_Set((const void *)&fill, work, JUDGMENT_DMA_FILL_WAVE, REG_DMA3);
571 fill = 0x3f3f3f3f;
572 Dma_Set((const void *)&fill, canvas, JUDGMENT_DMA_FILL_CANVAS, REG_DMA3);
574 }
575
576 // Frame 214, the forest: 16 debris pieces start rising from the forest
577 // floor, those further right drawn smaller.
578 if (frame == 214) {
579 fill = 0;
580 Dma_Set((const void *)&fill, work, JUDGMENT_DMA_FILL_WAVE, REG_DMA3);
581 fill = 0x3f3f3f3f;
582 Dma_Set((const void *)&fill, canvas, JUDGMENT_DMA_FILL_CANVAS, REG_DMA3);
584 for (i = 0; i != JUDGMENT_DEBRIS_OBJECTS; i++) {
585 particle = &work->particles[i];
586 particle->x = ((Random16() & 63) + 32) << 16;
587 particle->y = ((Random16() & 31) + 96) << 16;
588 particle->velocityY = ((Random16() & 15) + 16) << 15;
589 particle->z = 0x8000 - (particle->x >> 7);
590 particle->variant = 1;
591 }
592 }
593
594 if (frame == 280) {
595 // Back to the battle: blend the canvas over it again, fill the canvas
596 // with colour 1 and restart the debris off the right of the screen,
597 // where the explosion front now scrolls back from.
599 fill = 0;
600 Dma_Set((const void *)&fill, work, JUDGMENT_DMA_FILL_WAVE, REG_DMA3);
601 fill = 0x01010101;
602 Dma_Set((const void *)&fill, canvas, JUDGMENT_DMA_FILL_CANVAS, REG_DMA3);
603 ctrl->active = 0;
604 REG_BLDALPHA = BLEND_ALPHA(16, 16);
605 for (i = 0; i != JUDGMENT_DEBRIS_OBJECTS; i++) {
606 particle = &work->particles[i];
607 particle->x = ((Random16() & 63) + 256) << 16;
608 particle->y = ((Random16() & 31) + 96) << 16;
609 particle->velocityY = ((Random16() & 15) + 16) << 15;
610 particle->z = 0;
611 }
612 shift = 272;
614 }
615
616 // From frame 280 the canvas's palette ramp, background colours 1 to 63,
617 // brightens one step a channel each frame, reaching white by frame 311.
618 if (frame > 279) {
619 /* FAKEMATCH: palette RAM through a volatile pointer: the native keeps
620 red's mask 31 in the loop rather than hoisting it; a plain pointer
621 differs in 52 of 2455 rows. */
622 volatile u16 *pal = (volatile u16 *)0x05000002;
623 for (i = 0; i != 63; i++, pal++) {
624 s32 c = *pal;
625 s32 b = ((u16)c >> 10) & 31;
626 s32 g = ((u16)c >> 5) & 31;
627 s32 r = c & 31;
628 b++;
629 g++;
630 r++;
631 if (b > 31) {
632 b = 31;
633 }
634 if (g > 31) {
635 g = 31;
636 }
637 if (r > 31) {
638 r = 31;
639 }
640 *pal = RGB(r, g, b);
641 }
642 }
643
644 if (frame == 182) {
645 fill = 0x3f3f3f3f;
646 Dma_Set((const void *)&fill, canvas, JUDGMENT_DMA_FILL_CANVAS, REG_DMA3);
647 }
648
649 // Frames 0 to 63: a flare falls onto the aerial view, drawn as four
650 // mirrored quarters, its picture flickering every 4 frames.
651 if (frame <= 63) {
652 u8 *sheet;
653 s32 top = frame - 4;
654 if ((frame & 7) < 4) {
655 sheet = work->sheet + JUDGMENT_SHEET_FLARE_A;
656 } else {
657 sheet = work->sheet + JUDGMENT_SHEET_FLARE_B;
658 }
662 canvas, sheet, 36, top - 24, 24, 24);
667 canvas, sheet, 59, top - 24, 24, 24);
672 canvas, sheet, 36, top - 1, 24, 24);
679 canvas, sheet, 59, top - 1, 24, 24);
681 }
682
683 // Frames 64 to 85: the flash plays twice: a small picture, a large one,
684 // then four streaks that close in (68 to 75) or spread out (82 to 85).
685 if (frame >= 64 && frame < 66) {
686 draw[0](canvas, work->sheet + JUDGMENT_SHEET_FLASH_SMALL, 52, 51, 16, 17);
687 }
688 if (frame >= 66 && frame < 68) {
689 draw[0](canvas, work->sheet + JUDGMENT_SHEET_FLASH_LARGE, 48, 40, 24, 41);
690 }
691 if (frame >= 68 && frame < 76) {
692 s32 d = 76 - frame;
693 draw[0](canvas, work->sheet + JUDGMENT_SHEET_FLASH_STREAK, 49 - d / 2,
694 38 - d, 22, 44);
695 draw[0](canvas, work->sheet + JUDGMENT_SHEET_FLASH_STREAK, 49 - d / 2,
696 d + 38, 22, 44);
697 draw[0](canvas, work->sheet + JUDGMENT_SHEET_FLASH_STREAK, d / 2 + 49,
698 38 - d, 22, 44);
699 draw[0](canvas, work->sheet + JUDGMENT_SHEET_FLASH_STREAK, d / 2 + 49,
700 d + 38, 22, 44);
701 }
702 if (frame >= 78 && frame < 80) {
703 draw[0](canvas, work->sheet + JUDGMENT_SHEET_FLASH_SMALL, 52, 51, 16, 17);
704 }
705 if (frame >= 80 && frame < 82) {
706 draw[0](canvas, work->sheet + JUDGMENT_SHEET_FLASH_LARGE, 48, 40, 24, 41);
707 }
708 if (frame >= 82 && frame < 86) {
709 s32 d = frame * 2 - 164;
710 draw[0](canvas, work->sheet + JUDGMENT_SHEET_FLASH_STREAK, 49 - d / 4,
711 38 - d, 22, 44);
712 draw[0](canvas, work->sheet + JUDGMENT_SHEET_FLASH_STREAK, 49 - d / 4,
713 d + 38, 22, 44);
714 draw[0](canvas, work->sheet + JUDGMENT_SHEET_FLASH_STREAK, d / 4 + 49,
715 38 - d, 22, 44);
716 draw[0](canvas, work->sheet + JUDGMENT_SHEET_FLASH_STREAK, d / 4 + 49,
717 d + 38, 22, 44);
718 }
719
720 // Frames 72 to 75: a ring of 256 motes grows around (60, 50).
721 if (frame >= 72 && frame < 76) {
722 s32 r2 = (frame << 4) - 1136;
723 /* FAKEMATCH: the size is a value, so 5 and 20 are hoisted into fp and sl;
724 * as the literals, 100 of 2455 instructions differ in tbs-en. */
725 s32 size = 10;
726 for (i = 0; i != 256; i++) {
727 s32 angle = i << 8;
728 s32 x = ((Trig_Sin(angle) * r2) >> 16) - (size >> 1);
729 s32 y = (Trig_Cos(angle) * r2) >> 17;
730 draw[0](canvas, ramp + gBattleFx_MoteCells[size - 1], x + 60, y + 50,
731 size, size * 2);
732 }
733 }
734
735 if (frame > 85) {
736 // Frames 86 to 213: draw that many more rings a frame into the wave
737 // picture, each one pixel wider than the last.
738 if (frame <= 213) {
739 for (i = 0; i != rings; i++, ring++) {
740 s32 radius = ring;
741 s32 slope = 0;
742 s32 err = ring;
743 // A midpoint circle, one point plotting all eight octants, scaled
744 // by sx and squash. The rise above the centre takes sx, not
745 // squash, so the rings are lopsided; each point is plotted again
746 // with half unscaled, one pixel to the right.
747 while (radius >= slope) {
748 s32 half;
749 s32 halfSlope;
750 s32 left;
751 s32 right;
752 s32 top;
753 s32 bottom;
754 s32 dx;
755
756 half = radius / 2;
757 dx = (half * sx) / 8;
758 right = cx + dx;
759 /* FAKEMATCH: a dead branch restores the label CSE and reload saw
760 * between the edges; without it, 67 of 2455 instructions differ
761 * in tbs-en. */
762 if (dx > cx) {
763 left = 0;
764 }
765 left = cx - dx;
766 bottom = cy + (slope * squash) / 8;
767 top = cy - (slope * sx) / 8;
768 if (top < 0) {
769 top = 0;
770 }
771 if (bottom > 119) {
772 bottom = 119;
773 }
774 if (left < 0) {
775 left = 0;
776 }
777 if (right > 119) {
778 right = 119;
779 }
780 work->sheet[bottom * JUDGMENT_WAVE_SIZE + right] = 20;
781 work->sheet[top * JUDGMENT_WAVE_SIZE + right] = 20;
782 work->sheet[bottom * JUDGMENT_WAVE_SIZE + left] = 20;
783 work->sheet[top * JUDGMENT_WAVE_SIZE + left] = 20;
784 right = cx + half + 1;
785 left = cx - half + 1;
786 if (left < 0) {
787 left = 0;
788 }
789 if (right > 119) {
790 right = 119;
791 }
792 work->sheet[bottom * JUDGMENT_WAVE_SIZE + right] = 20;
793 work->sheet[top * JUDGMENT_WAVE_SIZE + right] = 20;
794 work->sheet[bottom * JUDGMENT_WAVE_SIZE + left] = 20;
795 work->sheet[top * JUDGMENT_WAVE_SIZE + left] = 20;
796
797 halfSlope = slope / 2;
798 dx = (halfSlope * sx) / 8;
799 right = cx + dx;
800 /* FAKEMATCH: a dead branch restores the label CSE and reload saw
801 * between the edges; without it, 1954 of 2455 instructions differ
802 * in tbs-en. */
803 if (dx > cx) {
804 left = 0;
805 }
806 left = cx - dx;
807 bottom = cy + (radius * squash) / 8;
808 top = cy - (radius * sx) / 8;
809 if (left < 0) {
810 left = 0;
811 }
812 if (right > 119) {
813 right = 119;
814 }
815 if (top < 0) {
816 top = 0;
817 }
818 if (bottom > 119) {
819 bottom = 119;
820 }
821 work->sheet[bottom * JUDGMENT_WAVE_SIZE + right] = 20;
822 work->sheet[top * JUDGMENT_WAVE_SIZE + right] = 20;
823 work->sheet[bottom * JUDGMENT_WAVE_SIZE + left] = 20;
824 work->sheet[top * JUDGMENT_WAVE_SIZE + left] = 20;
825 right = cx + halfSlope + 1;
826 left = cx - halfSlope + 1;
827 if (left < 0) {
828 left = 0;
829 }
830 if (right > 119) {
831 right = 119;
832 }
833 work->sheet[bottom * JUDGMENT_WAVE_SIZE + right] = 20;
834 work->sheet[top * JUDGMENT_WAVE_SIZE + right] = 20;
835 work->sheet[bottom * JUDGMENT_WAVE_SIZE + left] = 20;
836 work->sheet[top * JUDGMENT_WAVE_SIZE + left] = 20;
837
838 err = err - slope * 2 - 1;
839 if (err < 0) {
840 err = err + radius * 2 - 2;
841 radius--;
842 }
843 slope++;
844 }
845 }
846 }
847 }
848
849 // Frames 86 to 149: nine animated explosions fan out downward from the
850 // impact.
851 if (frame >= 86 && frame < 150) {
852 s32 angle = -0x4000;
853 for (i = 0; i != 9; i++, angle += 0x1000) {
854 s32 x = ((frame - 86) * Trig_Sin(angle)) >> 16;
855 s32 y = ((frame - 70) * Trig_Cos(angle)) >> 16;
856 draw[0](canvas,
857 work->sheet +
858 ((frame / 2 + i) % 4) * JUDGMENT_EXPLOSION_CELL_BYTES +
860 x + 44, y + 17, 32, 54);
861 }
862 }
863
867 if (frame > 85) {
868 // From frame 86 add the wave picture over the canvas.
869 draw[1](canvas, work->sheet, 0, 0, JUDGMENT_WAVE_SIZE,
871 }
872
873 if (frame > 279) {
874 shift -= 8;
875 }
876
877 // DEAD: never true, as the sweep's last frame is 319; the ROM keeps the
878 // test and the targets' reaction.
879 if (frame > 319) {
882 POSE_DAMAGE, -1, 0);
883 }
884 }
885
886 if (frame == 238) {
887 fill = 0x3f3f3f3f;
888 Dma_Set((const void *)&fill, canvas, JUDGMENT_DMA_FILL_CANVAS, REG_DMA3);
889 }
890
891 // Frames 214 to 279: the forest scrolls 8 pixels a frame, and from 246
892 // the explosion front follows it over a plain canvas copy; from 280 the
893 // front scrolls back.
894 if (frame >= 214 && frame < 280) {
895 gBgScroll[1].x += 8;
896 }
897
898 if (frame >= 246 && frame < 280) {
899 shift += 8;
901 }
902
903 // From frame 214 each live debris object is placed from its particle (x
904 // and y on the field, 255 pixels below the ground line, scaled by z plus
905 // 1/128 of y but never below 1/32) and rises. One that leaves the top
906 // comes back near the explosion front, ahead of it while it scrolls right
907 // and behind it after; after frame 301 it stays gone. Then the front:
908 // eight jittering explosions in two columns, leaning the way it scrolls.
909 if (frame > 213) {
910 debrisPlace.groundHeight = 0;
911 debrisPlace.height = 0;
912 for (i = 0; i != JUDGMENT_DEBRIS_OBJECTS; i++) {
913 particle = &work->particles[i];
914 if (particle->variant != 0) {
915 scale.x = particle->z + (particle->y >> 7);
916 if (scale.x < 0x800) {
917 scale.x = 0x800;
918 }
919 scale.y = scale.x;
920 debrisPlace.x = particle->x;
921 debrisPlace.height = 0xff0000;
922 debrisPlace.y = particle->y + 0xff0000;
923 Object_ApplyProjectedPlacementFar(work->objects[i], &debrisPlace,
924 &scale, 0);
925 particle->y -= particle->velocityY;
926 if (particle->y < 0x100000) {
927 if (frame <= 279) {
928 particle->x = ((Random16() & 63) + shift + 32) << 16;
929 } else {
930 particle->x = ((Random16() & 63) + shift - 32) << 16;
931 }
932 if (frame > 301) {
933 particle->variant = 0;
934 } else if (frame > 245) {
935 particle->y = 0x600000;
936 } else {
937 particle->y = 0xc00000 - particle->x;
938 }
939 }
940 }
941 }
942
943 if (frame <= 279) {
944 for (i = 0; i != 8; i++) {
945 s32 x =
946 (i & 1) * 20 - (Random16() & 15) + (i / 2) * 4 + shift / 2 - 16;
947 s32 y = (i / 2) * 32 - (Random16() & 15);
948 draw[1](canvas,
949 work->sheet +
950 ((frame / 2 + i) % 4) * JUDGMENT_EXPLOSION_CELL_BYTES +
952 x, y, 32, 54);
953 }
954 } else {
955 for (i = 0; i != 8; i++) {
956 s32 x =
957 (i & 1) * 20 + (Random16() & 15) - (i / 2) * 4 + shift / 2 - 16;
958 s32 y = (i / 2) * 32 - (Random16() & 15);
959 draw[1](canvas,
960 work->sheet +
961 ((frame / 2 + i) % 4) * JUDGMENT_EXPLOSION_CELL_BYTES +
963 x, y, 32, 54);
964 }
965 }
966 }
967
969
970 // From frame 64 the backdrop shakes up and down.
971 if (frame > 63) {
972 /* FAKEMATCH: forced temporary: the shake value through an s32 keeps the
973 * AND constant an immediate; as a direct store to gBgScroll[1].y, 17 of
974 * 2455 instructions differ in tbs-en. */
975 s32 shake = (Random16() & 3) + 30;
976
977 gBgScroll[1].y = shake;
978 }
979
981 }
982
983 // The finish: release the debris objects, then the canvas and its blitter.
984 for (i = 0; i != JUDGMENT_DEBRIS_OBJECTS; i++) {
986 }
987
989}
990
991#undef JUDGMENT_SHEET_BYTES
992#undef JUDGMENT_SPARKS
993#undef JUDGMENT_SHEET_TORNADO
994#undef JUDGMENT_GATHER_FRAMES
995#undef JUDGMENT_SWEEP_FRAMES
996#undef JUDGMENT_SHEET_FLARE_B
997#undef JUDGMENT_FORMATION_OBJECTS
998#undef JUDGMENT_DEBRIS_OBJECTS
999#undef JUDGMENT_SHEET_BURST
1000#undef JUDGMENT_SHEET_EXPLOSION
1001#undef JUDGMENT_SHEET_FLARE_A
1002#undef JUDGMENT_SHEET_FLASH_SMALL
1003#undef JUDGMENT_SHEET_FLASH_LARGE
1004#undef JUDGMENT_SHEET_FLASH_STREAK
1005#undef JUDGMENT_EXPLOSION_CELL_BYTES
1006#undef JUDGMENT_WAVE_SIZE
1007#undef JUDGMENT_DMA_FILL_CANVAS
1008#undef JUDGMENT_DMA_FILL_WAVE
@ SPRITE_COLOR_BLACK
solid colour 1, black
Definition animspr.h:31
@ POSE_DAMAGE
taking damage
Definition battle.h:176
@ COMPOSITE_FLIP_X
@ 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_ProcessPendingGraphicsTransfer(void)
Copies the canvas to VRAM once the effect has finished drawing a frame (transferPending): the 128x128...
Definition canvas.c:103
void BattleFx_WipeCanvas(s32 mode, s32 value)
Wipes the whole canvas to one colour with a ragged edge: each row (or column) lags a random 0 to 63 p...
Definition canvas.c:27
void BattleFx_ConfigureEffectDisplay(void)
Puts the battle screen back into the display state every effect starts from and ends with: no blendin...
Definition display.c:16
void Resource_LoadAndDecompress(s32 id, void *dst, s32 skipPalette, s32 copyPalette)
Decompresses a resource whose first 128 bytes may be a palette.
static __inline__ void Dma_Set(const volatile void *source, volatile void *destination, u32 control, volatile u32 *channel)
Starts a DMA transfer: stores the source, destination and control words into channel's registers with...
Definition dma.h:62
void ObjectGroup_UpdateMembers(s32 actorId, s32 palette, s32 animation, s32 timerSlot, s32 timerFrames)
Updates every animation group of one battler's object.
Definition dispatch.c:254
void BattleFx_SetupBlendedDisplay(void)
Shows the BG1 battle background behind a cleared canvas: clears the canvas buffer and the 16 KiB of V...
Definition dispatch.c:217
void BattleFx_SelectLivingTargets(struct BattleEffectArgument *effect)
Shows the battle objects of every unit with HP left on the targets' side: the enemies (units 128 to 1...
Definition dispatch.c:184
What every part of the battle effect object shares: its includes, macros and frame-loop helpers.
#define EFFECT_SHOW_WIDE_CANVAS(top)
Shows the canvas: the effect display mode, BG2 stretched to twice its width (the 128-pixel canvas sho...
#define EFFECT_DRAW_MOTE(draw, canvas, sheet, x, y, size)
Particle sheets hold ten mote cells, 1x2 to 10x20 pixels.
#define EFFECT_PRESENT_FRAME(work)
Ends a frame of a canvas effect: marks the canvas ready for the transfer callback,...
#define EFFECT_SET_TRANSFER(work, mode, value)
Sets how the canvas transfer treats what is left in the canvas after each copy: mode with value (see ...
@ CANVAS_COPY
copy as drawn
@ CANVAS_COPY_AND_FADE
copy, keeping 50% or 75% (transferValue) of each pixel in the canvas for the next frame
#define CANVAS_BYTES
The canvas: 128x128 pixels, one byte each, in its heap slot and in VRAM at BG_CHAR_BLOCK(1).
#define EFFECT_CALLBACK_ORDER
The scheduler order of every per-frame effect callback (Scheduler_AddOrUpdateCallback sorts the frame...
#define MOTE_SET_BYTES
The bytes of one set of the ten mote cells: 2 * (1 + 4 + ... + 100).
#define EFFECT_FINISH_CANVAS_ONE_BLITTER()
The same for an effect that drew through one blitter.
#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_LOAD_BLITTER(slot, flags, mode)
Builds a blitter for the 128x128 canvas (1 << 7 pixels each way) in work slot slot: BattleFx_BuildBli...
#define CANVAS_SLOT(slots, slot)
A work slot read through a pointer to the canvas slot, gWorkSlot[HEAP_SLOT_BATTLE_CANVAS],...
#define EFFECT_CAP_LEVEL(level, cap)
Caps a colour level at cap, and at 0 from below.
#define EFFECT_VIEW_FROM_CAMERA(camera)
Starts a frame's 3D projection from the battle camera: resets the transform, then looks from camera->...
#define EFFECT_BEGIN_NARROW_CANVAS(bgControl)
Opens the canvas layer at the canvas's own width, one texel per pixel, where BattleFx_BeginCanvasLaye...
u16 gJudgment_ShardCells[]
u8 gJudgment_ShardWidths[]
u16 gBattleFx_MoteCells[]
Mote cells: particle sheets hold ten, cell n (from 0) n + 1 pixels wide and twice that tall.
u8 gJudgment_BurstHeights[]
u16 gJudgment_BurstCells[]
u8 gJudgment_ShardHeights[]
void BattleFx_SpawnObjects(s32 entryCount, s32 source, u32 priority)
Creates the effect's animation objects in gBattleFxWork's objects.
Definition eruption.c:220
void BattleBackground_LoadFar(s32 mode, s32 resource, s32 level)
void BattlePresentation_ConfigurePaletteFadeFar(s32 mode, s32 value, s32 fade)
s32 AnimationObjects_SelectAnimationFar(struct AnimationObject *state, s32 flags)
struct AnimationObject * ResourceObject_CreateFar(s32 id)
void Object_ApplyProjectedPlacementFar(struct AnimationObject *sprite, const struct SpritePlacement *position, const struct SpriteScale *scale, s32 facing)
Far call to Render_ApplyProjectedPlacement.
void ResourceObject_ReleaseFar(struct AnimationObject *sprite)
void AudioCommand_PlayFar(s32 id)
s32 Trig_Cos(s32 angle)
s32 Trig_Sin(s32 angle)
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
@ HEAP_SLOT_BATTLE_EFFECT
Definition heap_state.h:42
@ HEAP_SLOT_BLITTER_ALTERNATE
Definition heap_state.h:47
@ HEAP_SLOT_BATTLE_BACKGROUND
Definition heap_state.h:45
@ HEAP_SLOT_BATTLE_SHEET
Definition heap_state.h:44
@ HEAP_SLOT_CAMERA
Definition heap_state.h:38
@ HEAP_SLOT_BLITTER
Definition heap_state.h:46
@ HEAP_SLOT_BATTLE_CANVAS
Definition heap_state.h:43
#define Q_8_8(n)
The BG2/BG3 affine matrix entries are signed 8.8 fixed point: texels stepped per screen pixel.
Definition io_reg.h:59
#define BGCNT_CHAR_BASE(block)
Definition io_reg.h:25
#define BGCNT_256_COLORS
Definition io_reg.h:27
#define BGCNT_PRIORITY(n)
Definition io_reg.h:24
#define RGB(r, g, b)
A 15-bit colour from its red, green and blue levels (0 to 31 each), as the palette stores it: blue in...
Definition io_reg.h:164
@ KEY_B
Definition io_reg.h:244
@ KEY_A
Definition io_reg.h:243
#define REG_BG2X
Definition io_reg.h:65
#define PLTT_BACKDROP
Definition io_reg.h:155
#define REG_IME
Definition io_reg.h:308
#define REG_DMA3
Definition io_reg.h:153
#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 BGCNT_SCREEN_BASE(block)
Definition io_reg.h:28
#define REG_BG2CNT
Definition io_reg.h:21
#define REG_BLDALPHA
Definition io_reg.h:142
#define BG_PLTT
Definition io_reg.h:157
#define REG_BG2PA
Definition io_reg.h:61
#define BG_PLTT_COLOR(palette, color)
Definition io_reg.h:158
#define BGCNT_WRAP
Affine backgrounds only: wrap around instead of showing the backdrop.
Definition io_reg.h:30
#define IO_WRITE_QUEUE_PUSH_IME(ime, address, value, control)
Like IO_WRITE_QUEUE_PUSH, but keeps IME's address in the caller's ime variable while disabling and re...
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
Definition iwram_call.h:85
static s32 Iwram_FillWords(void *destination, s32 size, u32 value)
Definition iwram_call.h:59
#define JUDGMENT_SHEET_FLARE_A
The first 24x24 flare picture, from the crescent sheet the sweep loads.
Definition judgment.c:40
#define JUDGMENT_GATHER_FRAMES
frames of the gathering
Definition judgment.c:27
#define JUDGMENT_WAVE_SIZE
the wave picture is 120x120
Definition judgment.c:48
#define JUDGMENT_SHEET_FLASH_LARGE
The 24x41 large flash picture.
Definition judgment.c:44
#define JUDGMENT_SHEET_BURST
the burst's quarter pictures
Definition judgment.c:32
#define JUDGMENT_SWEEP_FRAMES
frames of the sweep
Definition judgment.c:28
#define JUDGMENT_DMA_FILL_CANVAS
DMA word that fills the 128x128 canvas.
Definition judgment.c:50
#define JUDGMENT_SHEET_FLARE_B
the second 24x24 flare picture
Definition judgment.c:29
#define JUDGMENT_DEBRIS_OBJECTS
debris objects of the sweep
Definition judgment.c:31
#define JUDGMENT_SHEET_TORNADO
The tornado sheet, whose six glint pictures are the burst's shards (gJudgment_ShardCells counts from ...
Definition judgment.c:35
#define JUDGMENT_SHEET_EXPLOSION
The explosion's four 32x54 pictures, loaded over the flares on the sweep's frame 64.
Definition judgment.c:38
#define JUDGMENT_SHEET_BYTES
The bytes of Judgment's work block before its dimmed mote copies.
Definition judgment.c:10
#define JUDGMENT_SPARKS
The gathering's 128 sparks, after its 128 motes in PARTICLES.
Definition judgment.c:25
#define JUDGMENT_DMA_FILL_WAVE
DMA word that fills the 120x120 wave picture.
Definition judgment.c:52
void BattleFx_RunJudgment(struct BattleEffectArgument *effect)
The battle wipes away to a violet sky where a formation flies forward while motes gather into it,...
Definition judgment.c:63
#define JUDGMENT_SHEET_FLASH_SMALL
The 16x17 small flash, the first of OverlayImageA's three pictures.
Definition judgment.c:42
#define JUDGMENT_SHEET_FLASH_STREAK
The 22x44 flash streak picture.
Definition judgment.c:46
#define JUDGMENT_EXPLOSION_CELL_BYTES
bytes in each explosion picture
Definition judgment.c:47
#define JUDGMENT_FORMATION_OBJECTS
objects in the formation, 4x4
Definition judgment.c:30
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
struct BgScroll gBgScroll[]
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
Definition math.c:10
void Runtime_ReleaseHeapBlock(s32 slot)
void EffectStep_AdvanceWithGravity3D(struct EffectStep *step, s32 damping, s32 gravity)
Moves a particle one frame in three dimensions: adds its velocity, then gravity to its vertical speed...
Definition positions.c:29
s32 EffectPosition_ProjectPoint(const void *point, struct EffectPosition *position)
Projects a point in the current transform onto the screen, 16 pixels higher, and returns the projecti...
Definition positions.c:64
struct Projection gProjection
char ResourceId_PinkBurstSheet
char ResourceId_TornadoSheet
char ResourceId_ForestBackdrop
char ResourceId_AerialViewBackdrop
char ResourceId_VioletSkyBackdrop
char ResourceId_OverlayImageA
char ResourceId_ExplosionSheet
char ResourceId_BeachBackdrop
char ResourceId_OverlayImageB
char ResourceId_ParticleSpritesA
char ResourceId_BlueCrescentSheet
s32 Scheduler_AddOrUpdateCallback(SchedulerCallback callback, s32 order)
Schedules callback with order, or gives a task already running it the new order, and re-sorts the tab...
Definition scheduler.c:102
#define SE_162
Definition songs.h:157
#define SE_156
Definition songs.h:151
#define SE_GATE_MOVE
Definition songs.h:152
#define SE_142
Definition songs.h:135
#define SE_141
Definition songs.h:134
#define SE_145
Definition songs.h:138
void * gWorkSlot[]
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
struct AnimationSpritePart image
Definition animspr.h:109
u8 flags
bits: 1 outlined in ObjectSystemWork's edge and fill colours | 0 shadow drawn (set when created)
Definition animspr.h:128
s32 scale
16.16 fixed point, 0x10000 full size
Definition animspr.h:111
u16 priority
2 when created
Definition animspr.h:100
The battle camera: its eye, the focus it turns about, and its pitch, yaw and distance.
The command shared by an effect's caller, dispatcher and handlers.
s16 actors[8]
the targets' unit ids, count of them
The running battle effect's work: its canvas image, 64 particles, the display registers it stages and...
s32 fadeFrames
backdrop fade frames left (Palette_StepFadeTransfer)
s32 fadeStep
CANVAS_FADE_STEPs the backdrop has darkened so far.
struct AnimationObject * objects[16]
the effect's animation objects
s32 transferMode
How the canvas transfer callbacks treat the canvas after each copy (enum CanvasTransferMode in effect...
s32 transferValue
The transfer mode's argument: the fill value, the share kept (50 or 75 percent) or the darken or brig...
struct BattleEffectArgument * effect
the command being run
struct EffectStep particles[64]
free while variant is -1
The battle background's work slot as the camera reads it: the yaw the camera eases toward and the fra...
s32 active
BattleBackgroundView's busy, at the same offset.
u16 y
pixels
Definition map_scroll.h:65
A point projected onto the screen, with its depth.
Definition effect_step.h:46
s32 y
screen pixels
Definition effect_step.h:59
s32 depth
projected depth, larger further away
Definition effect_step.h:60
s32 x
screen pixels
Definition effect_step.h:58
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 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
Judgment's work block, laid over struct BattleEffectWork from its start.
Definition judgment.c:15
u8 sheet[JUDGMENT_SHEET_BYTES]
The gathering's pictures: the pink burst, the burst's quarters and the tornado sheet.
Definition judgment.c:18
u8 ramp[8][MOTE_SET_BYTES]
Eight copies of the mote sheet, copy i with every level capped at 64 - 7i; the gathering's ring of mo...
Definition judgment.c:21
s32 centerY
screen pixels
Definition project.h:17
A sprite's screen position and its two vertical offsets, in 16.16 pixels.
s32 x
screen x of the sprite's centre
s32 y
screen y at the ground; sets the depth slot
s32 groundHeight
how far the shadow is raised above y
s32 height
how far the image is raised above y
Horizontal and vertical sprite scale; 0x10000 is the original size.
void * Resource_GetTableEntry(s32 index)
Returns the ROM address of resource index from the resource directory.
Definition system.c:150
void SceneTransform_ApplyYaw(s32 angle)
Rotates gTransform about the Y axis by angle.
Definition transform.c:113
void SceneTransform_ApplyPitch(s32 angle)
Rotates gTransform about the X axis by angle.
Definition transform.c:97
void Render_ResetTransformState(void)
Allocates the one-level save area (heap slot HEAP_SLOT_TRANSFORM_STACK), clears gTransformStackDepth ...
Definition transform.c:19
void SceneTransform_ApplyRoll(s32 angle)
Rotates gTransform about the Z axis by angle.
Definition transform.c:129
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
unsigned short u16
Definition types.h:13
unsigned char u8
Definition types.h:11
#define EFFECT_CLIP_BOUNDS
Clips overflow on all four sides.
Definition effect.h:224
#define PARTICLES
The map cell buffer (gMapCellBuffer), which the effects borrow, has two views here: Ram_MapCellBuffer...
Definition effect.h:221