Alchemy
Loading...
Searching...
No Matches

neptune.c

Go to the documentation of this file.
1/// @file
2/// The Neptune summon.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7/// Sets BG2's horizontal scale back to one texel a pixel, for the lines above
8/// Graphics_SetBg2AffineScaleHalf's interrupt. BattleFx_RunNeptune schedules
9/// it as a frame callback for its first stage.
11
12/// Stretches BG2 to twice its width from the current line down.
13/// BattleFx_RunNeptune installs it as the VCount interrupt handler, on line 0
14/// and from frame 152 on line 96, for its first stage.
16
17#define NEPTUNE_FLAME_GROUND 112 ///< where the blue flames throw sparks
18#define NEPTUNE_OBJECTS 8 ///< objects in the formation
19#define NEPTUNE_PARTICLES 1024 ///< PARTICLES slots: spray, then sparks
20#define NEPTUNE_FLARE_SHEET 0x4e20 ///< the flare pictures, after the spray
21/// The 48x48 light pictures (9 * 256 bytes each), after the spray sheet's
22/// 32x32 spray picture.
23#define NEPTUNE_LIGHT_CELLS 0x400
24/// The blue flame column's 34x65 head, after its 17x104 shaft.
25#define NEPTUNE_FLAME_HEAD 0x6e8
26
27/// Over dusk clouds a formation of objects flies in through rising spray,
28/// gathers a ring of flares into a burst of light, then five blue flame columns
29/// drop onto the targets, throwing sparks.
30///
31/// Abilities: Neptune (scene kind 6).
32///
33/// The scene runs in two stages. The first (244 frames; A or B ends it after
34/// frame 16) places NEPTUNE_OBJECTS objects at one and a half times their
35/// size, opens the window with an edge table built every frame, sprays
36/// particles under gravity, converges a ring of flares, then breaks into a
37/// burst of light; meanwhile a frame callback and an interrupt change BG2's
38/// horizontal scale. The second stage (144 frames) drops five blue flame
39/// columns onto the targets, one every 16 frames; each throws sparks when it
40/// reaches the ground (NEPTUNE_FLAME_GROUND). The battle shows the damage on
41/// its frame 96. The scene leaves gProjection.centerY at 240.
42///
43/// Particles: in the first stage work->particles 0 to 31 are the converging
44/// flares, then from frame 222 0 to 63 the burst points; PARTICLES holds the
45/// spray (variant counts its frames, -1 when free). In the second stage
46/// work->particles 0 to 4 are the flame columns (variant their frames on the
47/// ground) and PARTICLES the sparks (variant their frames left, 0 when free).
48/// The window's edge step, noise and scanline table use the map cell
49/// buffer's first 450 bytes on frames 0 to 15, over spray particles 0 to 16,
50/// which are already launched.
52 static struct SpriteScale unitScale = {{{0x18000, 0x18000}}};
53 struct SpritePlacement pos;
54 struct EffectPosition targetPosition;
55 void *canvas;
56 u8 *particleSheet;
57 s32 windowEdgeStep;
58 s32 formationX;
59 s32 formationZ;
60 s32 formationVelocityX;
61 s32 formationVelocityZ;
62 s32 savedBg1ScrollX;
63 struct BattleBackgroundView *background;
64 s32 j;
65 s32 emittedSparks;
66 s32 sparkOriginX;
67 u32 *cache;
68 struct BattleEffectWork *work;
69 s32 frame;
70 s32 t;
71 s32 i;
72 s32 n;
73 s32 s;
74 struct EffectStep *flareSeed;
75 struct EffectStep *flare;
76 struct EffectStep *burstSeed;
77 struct EffectStep *flameColumn;
78 DrawRectangle blit[2];
79 struct SpriteScale scale;
81
83 canvas = (void *)cache[0];
85 particleSheet = (u8 *)CANVAS_SLOT(cache, HEAP_SLOT_BATTLE_SHEET);
86 work->effect = effect;
89 PLTT_BACKDROP = 0;
90 *(u16 *)&BG_PLTT[1] = 0;
91 // BG2's scale per frame: one texel a pixel until the VCount line (0 here),
92 // twice the width from it down.
98 // Setup: wipe the battle away and close window 0 (its edge opens over the
99 // first 16 frames), swap in the dusk backdrop and load the pictures.
102 REG_WIN0H = WIN_RANGE(240, 240);
105 gProjection.centerY = 240;
106 WaitFrames(1);
109 0, 0);
111 1);
113 work->sheet + NEPTUNE_FLARE_SHEET, 0, 0);
115 // The formation starts at x 280, 200 deep, and flies in at 4 pixels a
116 // frame across and 8 forward (16.16), slowing as it comes.
117 windowEdgeStep = 1;
118 formationX = 140 << 17;
119 formationZ = 200 << 16;
120 formationVelocityX = -0x40000;
121 formationVelocityZ = -0x80000;
122 savedBg1ScrollX = gBgScroll[1].x;
123 background = (struct BattleBackgroundView *)CANVAS_SLOT(
126 // The scene owns BG1's scroll until the second stage.
127 background->busy = 1;
136
137 for (i = 0; i != NEPTUNE_PARTICLES; i++) {
138 PARTICLES[i].variant = -1;
139 }
140 // Seed the flares that converge during the formation burst: each starts
141 // 64 to 95 pixels out, in the quarter turn from 0x8000, and closes in over
142 // 32 frames.
143 for (i = 0, flareSeed = work->particles; i != 32; i++, flareSeed++) {
144 s32 a = (Random16() & 0x3fff) + 0x8000;
145 s32 r = (Random16() & 127) + 255;
146 flareSeed->x = (Trig_Sin(a) * r) >> 2;
147 flareSeed->y = (Trig_Cos(a) * r) >> 2;
148 flareSeed->velocityX = -flareSeed->x / 32;
149 flareSeed->velocityY = -flareSeed->y / 32;
150 flareSeed->variant = 0;
151 }
152 // Launch the first 712 spray particles from around (128, 96); the other
153 // slots stay free (variant -1).
154 for (i = 0; i != 712; i++) {
155 s32 r = Random16() & 255;
156 s32 a = Random16() & 0xffff;
157 PARTICLES[i].x = ((Trig_Sin(a) * r) >> 3) + 0x800000;
158 PARTICLES[i].y = ((Trig_Cos(a) * r) >> 4) + (192 << 15);
159 PARTICLES[i].velocityX = (-(Random16() & 0x1fff) - 0x800) << 5;
160 PARTICLES[i].velocityY = (-(Random16() & 0xfff) - 0x1800) << 5;
161 PARTICLES[i].variant = 0;
162 }
163
164 frame = 0;
165 do {
166 // The first stage: the window opens (frames 0 to 15), the formation flies
167 // (22 to 170), the spray falls (from 28, a second burst on 76), the flares
168 // converge (152 to 239), the beam of lines reaches the burst (from 176)
169 // and the burst breaks into light (from 222).
170 if (frame == 24) {
172 }
173 if (frame == 76) {
175 }
176 if (frame == 154) {
178 }
179 if (frame == 222) {
181 }
182 // Over the first 16 frames the window's right edge sweeps open by a
183 // growing step, ragged by 128 random offsets: frame 1 starts the
184 // callback that builds the edge table each frame, frame 15 stops it.
185 if (frame >= 0 && frame < 16) {
186 u16 *phase = (u16 *)Ram_MapCellBuffer;
187 if (frame == 1) {
188 u8 *noise = Ram_MapCellBuffer + 2;
189 s32 k;
190 for (k = 0; k != 128; k++) {
191 noise[k] = Random16() & 63;
192 }
193 *phase = 0;
196 }
197 *phase += windowEdgeStep;
198 windowEdgeStep += 3;
199 if (frame == 15) {
201 }
202 }
203
204 // From frame 22 the formation flies in and settles around depth 132 by
205 // frame 83, then drifts right while settling around depth 138, until
206 // frame 170. Its objects stand at one and a half times their offsets.
207 if (frame > 21) {
208 scale = unitScale;
209 if (frame <= 83) {
210 if (frame > 48) {
211 formationVelocityX = formationVelocityX * 60 / 64;
212 }
213 formationVelocityZ = formationVelocityZ * 60 / 64;
214 if (formationZ > 0x840000) {
215 formationVelocityZ -= 0x2000;
216 } else {
217 formationVelocityZ += 0x2000;
218 }
219 formationX += formationVelocityX;
220 formationZ += formationVelocityZ;
221 } else if (frame <= 170) {
222 if (frame <= 107) {
223 formationVelocityX += 0x2000;
224 }
225 formationVelocityX = formationVelocityX * 60 / 64;
226 formationX += formationVelocityX;
227 if (frame <= 117) {
228 if (formationZ > 0x8a0000) {
229 formationVelocityZ -= 0x2000;
230 } else {
231 formationVelocityZ += 0x2000;
232 }
233 formationVelocityZ = formationVelocityZ * 56 / 64;
234 formationZ += formationVelocityZ;
235 }
236 }
237 pos.groundHeight = 0;
238 pos.height = 0;
239 for (i = 0; i != NEPTUNE_OBJECTS; i++) {
240 pos.x =
241 (((gNeptune_ObjectX[i] * 3) >> 1) << 16) + formationX - 0x200000;
242 pos.y =
243 (((gNeptune_ObjectY[i] * 3) >> 1) << 16) + formationZ - 0x180000;
244 Object_ApplyProjectedPlacementFar(work->objects[i], &pos, &scale, 0);
245 }
246 }
247
248 if (frame == 76) {
249 for (i = 0; i != NEPTUNE_PARTICLES; i++) {
250 // Frame 76: a second spray from around (64, 96) out of every free
251 // slot.
252 if (PARTICLES[i].variant == -1) {
253 s32 r = Random16() & 255;
254 s32 a = Random16() & 0xffff;
255 PARTICLES[i].x = ((Trig_Sin(a) * r) >> 3) + 0x400000;
256 PARTICLES[i].y = ((Trig_Cos(a) * r) >> 4) + (192 << 15);
257 PARTICLES[i].velocityX = (32 - (Random16() & 63)) << 12;
258 PARTICLES[i].velocityY = (-(Random16() & 31) - 16) << 13;
259 PARTICLES[i].variant = 0;
260 }
261 }
262 }
263 // Frame 152: only the lines from 96 down stay stretched, and the battle
264 // backdrop's colours darken over 24 frames.
265 if (frame == 152) {
267 work->fadeFrames = 24;
268 work->fadeStep = 0;
269 }
270
271 // Frames 152 to 239: the 32 flares converge on (112, 62), four more
272 // starting each frame, each shown for 32 frames.
273 t = frame - 152;
274 if (t >= 0 && t < 88) {
275 for (i = 0, flare = work->particles; i != 32; i++, flare++) {
276 if (frame >= i / 4 + 152 && frame < i / 4 + 152 + 32) {
277 s32 fx = Q_16_16_TO_INT(flare->x) + 112;
278 s32 fy = Q_16_16_TO_INT(flare->y) + 62;
279 s32 r = (i & 3) + 5;
280 s = r * 2;
281 blit[0](canvas,
282 work->sheet + gBattleFx_FlareCells[r - 1] +
284 fx - r, fy - r, s, s);
285 flare->x += flare->velocityX;
286 flare->y += flare->velocityY;
287 }
288 }
289 }
290
291 if (frame == 222) {
292 for (i = 0; i != 64; i++) {
293 // Frame 222: 64 burst points around (100, 52), at least four pixels
294 // out, each moving six pixels left a frame; z and velocityY keep the
295 // start to restart from.
296 burstSeed = &work->particles[i];
297 burstSeed->x = (Random16() & 15) - 8;
298 burstSeed->y = (Random16() & 15) - 8;
299 if (burstSeed->x < 0) {
300 burstSeed->x -= 4;
301 } else {
302 burstSeed->x += 4;
303 }
304 if (burstSeed->y < 0) {
305 burstSeed->y -= 4;
306 } else {
307 burstSeed->y += 4;
308 }
309 burstSeed->x += 100;
310 burstSeed->y += 52;
311 burstSeed->velocityX = -6;
312 burstSeed->z = burstSeed->x;
313 burstSeed->velocityY = burstSeed->y;
314 burstSeed->variant = 0;
315 }
316 }
317 if (frame > 221) {
318 for (i = 0; i != 64; i++) {
319 // Two more burst points start each frame, as the smallest flare; one
320 // that leaves the top restarts.
321 u16 *cells = gBattleFx_FlareCells;
322 s32 r = 1;
323 if (frame >= i / 2 + 222) {
324 blit[0](canvas, work->sheet + cells[r - 1] + NEPTUNE_FLARE_SHEET,
325 work->particles[i].x - r, work->particles[i].y - r, r * 2,
326 r * 2);
327 work->particles[i].x += work->particles[i].velocityX;
328 work->particles[i].y += work->particles[i].velocityY;
329 if (work->particles[i].y < 0) {
330 work->particles[i].y = work->particles[i].velocityY;
331 work->particles[i].x = work->particles[i].z;
332 }
333 }
334 }
335 }
336
337 // From frame 176 a beam of lines runs from the top of the canvas to the
338 // burst: 5 lines, then from frame 222 40 lines, 60 on frames 223 and 224.
339 if (frame > 175) {
340 n = 5;
341 if (frame > 221) {
342 n = 60;
343 if (frame != 223 && frame != 224) {
344 n = 40;
345 }
346 }
347 if (n > 60) {
348 n = 60;
349 }
350 for (i = 0; i != n; i++) {
351 s32 w;
352 s32 d = (i + 1) / 2;
353 w = n * 2 - d * 4;
354 if (w < 12) {
355 w = 12;
356 }
357 if (w > 63) {
358 w = 63;
359 }
360 if (i & 1) {
361 d = -d;
362 }
363 BattleFx_DrawClippedCanvasLine(d + 48, 0, d / 2 + 111, 63 - (d + 1) / 2,
364 w);
365 }
366 }
367
368 // The flare at the centre of the burst grows from frame 152, and from
369 // frame 214 the light pictures cover it.
370 if (t >= 0 && t < 40) {
371 s32 z;
372 z = t / 2 + 1;
373 if (z > 4) {
374 z = 4;
375 }
376 blit[1](canvas,
377 work->sheet + gBattleFx_FlareCells[z - 1] + NEPTUNE_FLARE_SHEET,
378 108 - z, 60 - z, z * 2, z * 2);
379 }
380 if (frame >= 192 && frame < 200) {
381 s32 z;
382 z = (frame - 192) / 2 + 3;
383 if (z > 6) {
384 z = 6;
385 }
386 blit[1](canvas,
387 work->sheet + gBattleFx_FlareCells[z - 1] + NEPTUNE_FLARE_SHEET,
388 108 - z, 60 - z, z * 2, z * 2);
389 }
390 if (frame > 199) {
391 s32 z;
392 s32 u = frame - 200;
393 z = u / 4 + 5;
394 if (z > 8) {
395 z = 8;
396 }
397 blit[1](canvas,
398 work->sheet + gBattleFx_FlareCells[z - 1] + NEPTUNE_FLARE_SHEET,
399 108 - z, 60 - z, z * 2, z * 2);
400 if (frame <= 213) {
401 z = u / 4 + 1;
402 if (z > 4) {
403 z = 4;
404 }
405 blit[1](canvas,
406 work->sheet + gBattleFx_FlareCells[z - 1] + NEPTUNE_FLARE_SHEET,
407 100 - z, 52 - z, z * 2, z * 2);
408 }
409 }
410 if (frame >= 214 && frame < 222) {
411 s32 z;
412 z = (frame - 214) / 4;
413 if (z > 2) {
414 z = 2;
415 }
416 blit[1](canvas, work->sheet + z * 9 * 256 + NEPTUNE_LIGHT_CELLS, 63, 18,
417 48, 48);
418 }
419 if (frame > 221) {
420 s32 z;
421 z = (frame - 222) / 2 % 4 + 3;
422 blit[0](canvas, work->sheet + z * 9 * 256 + NEPTUNE_LIGHT_CELLS, 72, 30,
423 48, 48);
424 if (z == 5) {
425 blit[0](canvas, work->sheet + NEPTUNE_LIGHT_CELLS + 2 * (48 * 48), 66,
426 22, 48, 48);
427 }
428 }
429
430 // From frame 28 each live spray particle falls under its gravity
431 // (gNeptune_Gravity by index); one that falls below y 104 is freed.
432 if (frame > 27) {
433 DrawRectangle draw = blit[1];
434 for (i = 0; i != NEPTUNE_PARTICLES; i++) {
435 if (PARTICLES[i].variant >= 0) {
436 s32 k = i % 3 + 2;
437 EFFECT_DRAW_MOTE(draw, canvas, particleSheet,
439 Q_16_16_TO_INT(PARTICLES[i].y), k);
441 gNeptune_Gravity[i & 3]);
442 PARTICLES[i].variant++;
443 if (PARTICLES[i].velocityY > 0 &&
444 Q_16_16_TO_INT(PARTICLES[i].y) > 104) {
445 PARTICLES[i].variant = -1;
446 }
447 }
448 }
449 }
450 for (i = 0; i != 5; i++) {
451 // The scrolling strip of five spray pictures along the bottom.
452 blit[1](canvas, work->sheet, i * 32 + ((frame / 4) & 31) - 32, 88, 32,
453 32);
454 }
456 } while (++frame != 244 && (frame <= 16 || !(gKeysRepeat & (KEY_A | KEY_B))));
457
458 // The second stage: restore the backdrop, the scale callbacks and the
459 // display, free the spray as sparks (variant 0), and aim the five flame
460 // columns: column i drops onto target i's x when there is one, otherwise
461 // onto a random x.
462 gBgScroll[1].x = savedBg1ScrollX;
463 background->busy = 0;
467 REG_WIN0H = WIN_RANGE(0, 240);
469 for (i = 0; i != NEPTUNE_PARTICLES; i++) {
470 PARTICLES[i].variant = 0;
471 }
472 for (i = 0; i != 16; i++) {
473 work->particles[i].x = (Random16() & 31) + 32;
474 work->particles[i].y = 0;
475 work->particles[i].variant = 0;
476 }
479 &targetPosition);
480 work->particles[i].x = targetPosition.x / 2;
481 }
483 1);
485 REG_BG2PA = Q_8_8(0.5);
486 REG_BLDALPHA = BLEND_ALPHA(16, 16);
487
488 frame = 0;
489 do {
490 // The second stage, 144 frames: column i starts on frame 16i and lands
491 // on frame 16i + 7, at y 112 (NEPTUNE_FLAME_GROUND); the battle shows
492 // the damage on frame 96.
493 if (frame == 96) {
495 }
496 for (i = 0; i != 5; i++) {
497 flameColumn = &work->particles[i];
498 if (frame == i * 16 + 7) {
500 }
501 // A column, a scrolling shaft over a head, falls 16 pixels a frame.
502 // Once on the ground it counts its frames there, shakes the screen for
503 // the first eight and throws up to four sparks a frame for about 32
504 // frames.
505 if (frame >= i * 16 && flameColumn->variant <= 31) {
506 s32 wobble = frame * 16 % 104;
507 blit[1](canvas, work->sheet, flameColumn->x - 8,
508 flameColumn->y + wobble - 216, 17, 104);
509 blit[1](canvas, work->sheet, flameColumn->x - 8,
510 flameColumn->y + wobble - 112, 17, 104 - wobble);
511 blit[1](canvas, work->sheet + NEPTUNE_FLAME_HEAD, flameColumn->x - 17,
512 flameColumn->y - 65, 34, 65);
513 if (flameColumn->y <= 111) {
514 flameColumn->y += 16;
515 } else {
516 flameColumn->variant++;
517 }
518 if (flameColumn->y > 111) {
519 emittedSparks = 0;
520 sparkOriginX = flameColumn->x;
521 if (flameColumn->variant <= 7) {
522 work->shakeFrames = 4;
523 }
524 for (j = 0; j != NEPTUNE_PARTICLES; j++) {
525 if (PARTICLES[j].variant == 0) {
526 /* FAKEMATCH: the mask set before the call that it masks; as
527 * Random16() & 0x3ff, 5 instructions differ in tbs-en. */
528 s32 r = 0x3ff;
529 s32 a;
530 r &= Random16();
531 a = (Random16() & 0x7fff) - 0x4000;
532 PARTICLES[j].x = sparkOriginX << 16;
533 PARTICLES[j].y = ground << 16;
534 r += 32;
535 PARTICLES[j].velocityX = (Trig_Sin(a) * r) >> 7;
536 PARTICLES[j].velocityY = -(Trig_Cos(a) * r * 2) >> 7;
537 PARTICLES[j].variant = (Random16() & 7) + 32;
538 if (++emittedSparks == 4) {
539 break;
540 }
541 }
542 }
543 }
544 }
545 }
546 // Target i flashes and reels on frame 16i + 8, as its column lands.
548 if (frame == i * 16 + 8) {
550 POSE_DAMAGE, i, 8);
552 }
553 }
554 for (i = 0; i != NEPTUNE_PARTICLES; i++) {
555 if (PARTICLES[i].variant > 0) {
556 s32 x;
557 s32 y;
558 // Sparks fall under gravity and bounce at half speed below y 120;
559 // one off the canvas is not drawn.
560 PARTICLES[i].variant--;
562 y = PARTICLES[i].y >> 16;
563 if (y > 120) {
564 PARTICLES[i].velocityY = -PARTICLES[i].velocityY / 2;
565 } else if (PARTICLES[i].x >= 0 && (x = PARTICLES[i].x >> 16) <= 126 &&
566 PARTICLES[i].y >= 0) {
567 s32 k = PARTICLES[i].variant / 8 + 3;
568 EFFECT_DRAW_MOTE(blit[i & 1], canvas, particleSheet, x, y, k);
569 }
570 }
571 }
572 Camera_ApplyShake(4, 8);
573 EFFECT_END_FRAME(work);
574 } while (++frame != 144);
575
576 // The finish: release the formation's objects, then the canvas.
577 for (i = 0; i != NEPTUNE_OBJECTS; i++) {
579 }
581}
582
583#undef NEPTUNE_FLAME_GROUND
584#undef NEPTUNE_OBJECTS
585#undef NEPTUNE_PARTICLES
586#undef NEPTUNE_FLARE_SHEET
587#undef NEPTUNE_LIGHT_CELLS
588#undef NEPTUNE_FLAME_HEAD
@ SPRITE_COLOR_WHITE
solid colour 15, white
Definition animspr.h:26
@ POSE_DAMAGE
taking damage
Definition battle.h:176
@ 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_BeginCanvasLayer(s32 bgControl)
Opens the canvas layer: starts the background palette fade, makes BG2 the canvas, alpha-blended over ...
Definition canvas.c:314
void BattleFx_DrawClippedCanvasLine(s32 x0, s32 y0, s32 x1, s32 y1, s32 color)
Draws a line on the 128x128 8bpp canvas (16 tiles across), keeping the brighter colour where it cross...
Definition canvas.c:632
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.
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_BuildWindowEdgeTable(void)
Builds window 0's right edge for every scanline and restarts the HBlank DMA that writes it to WIN0H e...
Definition dispatch.c:148
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 EFFECT_CALLBACK_ORDER
The scheduler order of every per-frame effect callback (Scheduler_AddOrUpdateCallback sorts the frame...
#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_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_WIN0_LAYERS
Window 0, the battle view, shows BG0 to BG2, sprites and blending.
#define EFFECT_END_FRAME(work)
The usual end of an effect frame: counts down the targets' flash timers (ObjectGroup_TickMemberTimers...
u16 gBattleFx_FlareCells[]
Flare cells: the first ten are squares 2x2 to 20x20, cell n (from 0) n + 1 pixels from its centre to ...
u8 gNeptune_ObjectX[]
s32 gNeptune_Gravity[]
Spray gravity, by particle index & 3.
u8 gNeptune_ObjectY[]
void BattleFx_SpawnObjects(s32 entryCount, s32 source, u32 priority)
Creates the effect's animation objects in gBattleFxWork's objects.
Definition eruption.c:220
void BattleMotion_ApplyVariantMotionFar(s32 id, s32 variant)
void BattleBackground_LoadFar(s32 mode, s32 resource, s32 level)
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 Runtime_SetIrqHandler(u32 irq, s32 vcount, InterruptHandler handler)
Installs handler for interrupt irq and enables that interrupt, or with a null handler disables it and...
Definition frame.c:37
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
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_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_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 REG_WININ
Definition io_reg.h:81
#define BGCNT_256_COLORS
Definition io_reg.h:27
#define BGCNT_PRIORITY(n)
Definition io_reg.h:24
#define REG_WIN0H
Definition io_reg.h:74
#define WININ_WIN1_BG0
Definition io_reg.h:93
#define WININ_WIN1_CLR
Definition io_reg.h:98
@ KEY_B
Definition io_reg.h:244
@ KEY_A
Definition io_reg.h:243
#define PLTT_BACKDROP
Definition io_reg.h:155
#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 WIN_RANGE(start, end)
A REG_WINxH or REG_WINxV value: the window covers start up to, but not including, end.
Definition io_reg.h:80
#define BG_PLTT
Definition io_reg.h:157
#define REG_BG2PA
Definition io_reg.h:61
@ IRQ_VCOUNT
Definition irq.h:15
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 BattleFx_RunNeptune(struct BattleEffectArgument *effect)
Over dusk clouds a formation of objects flies in through rising spray, gathers a ring of flares into ...
Definition neptune.c:51
void Graphics_ResetBg2Pa(void)
Sets BG2's horizontal scale back to one texel a pixel, for the lines above Graphics_SetBg2AffineScale...
Definition neptune.c:10
void Graphics_SetBg2AffineScaleHalf(void)
Stretches BG2 to twice its width from the current line down.
Definition neptune.c:15
#define NEPTUNE_PARTICLES
PARTICLES slots: spray, then sparks.
Definition neptune.c:19
#define NEPTUNE_LIGHT_CELLS
The 48x48 light pictures (9 * 256 bytes each), after the spray sheet's 32x32 spray picture.
Definition neptune.c:23
#define NEPTUNE_FLAME_HEAD
The blue flame column's 34x65 head, after its 17x104 shaft.
Definition neptune.c:25
#define NEPTUNE_OBJECTS
objects in the formation
Definition neptune.c:18
#define NEPTUNE_FLARE_SHEET
the flare pictures, after the spray
Definition neptune.c:20
#define NEPTUNE_FLAME_GROUND
where the blue flames throw sparks
Definition neptune.c:17
void EffectPosition_ProjectScaledBattler(s32 id, struct EffectPosition *position)
The screen position of a battler, scaled for the battle view, 16 pixels higher.
Definition positions.c:88
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
struct Projection gProjection
#define Ram_MapCellBuffer
Definition ram_buffer.h:10
char ResourceId_ParticleSpritesD
char ResourceId_DuskCloudsBackdrop
char ResourceId_WaterSpraySheet
char ResourceId_BlueFlameSheet
char ResourceId_ParticleSpritesA
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
s32 Scheduler_RemoveCallback(SchedulerCallback callback)
Unschedules the task running callback: clears its routine and gives it order 0x7fff,...
Definition scheduler.c:146
#define SE_162
Definition songs.h:157
#define SE_142
Definition songs.h:135
#define SE_CAST
Definition songs.h:149
#define SE_164
Definition songs.h:159
#define SE_HEAVY_IMPACT
Definition songs.h:127
#define SE_145
Definition songs.h:138
#define SE_289
Definition songs.h:282
void * gWorkSlot[]
The battle background's work slot as the background code reads it: its display mode (2 draws it as an...
s32 busy
while set, BattleCamera_SetRange leaves BG1's scroll
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 frame
frame counter some effects keep, from 0
s32 fadeStep
CANVAS_FADE_STEPs the backdrop has darkened so far.
s32 shakeFrames
shake frames left; Camera_ApplyShake counts down
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...
struct BattleEffectArgument * effect
the command being run
struct EffectStep particles[64]
free while variant is -1
A point projected onto the screen, with its depth.
Definition effect_step.h:46
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 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 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.
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 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