Alchemy
Loading...
Searching...
No Matches

canvas.c

Go to the documentation of this file.
1/// @file
2/// The canvas layer: transfers, opening and closing, tile maps, lines.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7// The canvas layer's functions: opening and closing it, its transfers and
8// palette fades, clipping and the target flash timers. README.md describes
9// the canvas, its transfer modes and the two BG1 paths.
10//
11// A reaction may start one of the eight actor timers in the effect's work
12// block; ObjectGroup_TickMemberTimers counts them down each frame and gives
13// the battler its own palette back when one runs out. The timers are indexed
14// like effect->actors, so timer n belongs to actor n.
15
16/// Wipes the whole canvas to one colour with a ragged edge: each row (or
17/// column) lags a random 0 to 63 pixels behind the front, which speeds up as
18/// it goes. Returns when the wipe is done, a frame at a time.
19///
20/// Called by the summons and scenes that open on a wiped canvas: Boreas,
21/// Thor, Atalanta, Neptune, Kirin, Ramses, the particle streams and
22/// Judgment. Writes the canvas and sets work->transferPending each frame;
23/// the caller's transfer callback must already be running.
24///
25/// mode : 1 sweeps left to right; anything else sweeps top to bottom.
26/// value : 0 wipes to colour 1, 1 wipes to colour 0 (clears the canvas).
27void BattleFx_WipeCanvas(s32 mode, s32 value) {
28 // The pixel addresses and both bounds tests stay written out: as a shared
29 // helper or one merged test they compile differently.
30 struct BattleEffectWork *work;
31 u8 *canvas;
32 u8 delay[128];
33 s32 x;
34 s32 y;
35 s32 wipePosition;
36
39 for (x = 0; x != 128; x++)
40 delay[x] = Random16() & 0x3f;
41
42 // The canvas is 16x16 tiles of 8x8 pixels; (x, y) is byte
43 // ((y / 8 * 16 + x / 8) * 8 + y % 8) * 8 + x % 8. Across, the front
44 // speeds up by a column a frame and stops past 256 (128 columns plus the
45 // greatest lag); down, by two rows every frame, stopping past 191.
46 if (mode == 1) {
47 s32 front;
48 s32 speed;
49
50 front = 0;
51 speed = 1;
52 x = 0;
53 do {
54 front += speed;
55 speed++;
56 for (; x != front; x++) {
57 for (y = 0; y != 128; y++) {
58 wipePosition = x - delay[y];
59 if (wipePosition >= 0)
60 if (wipePosition <= 127)
61 canvas[(((y / 8) * 16 + wipePosition / 8) * 8 + (y & 7)) * 8 +
62 (wipePosition & 7)] = 1 - value;
63 }
64 }
66 } while (front <= 256);
67 } else {
68 s32 front;
69 s32 speed;
70
71 front = 0;
72 speed = 1;
73 y = 0;
74 do {
75 front += speed / 2;
76 speed += 4;
77 for (; y != front; y++) {
78 for (x = 0; x != 128; x++) {
79 wipePosition = y - delay[x];
80 if (wipePosition >= 0)
81 if (wipePosition <= 127)
82 canvas[(((wipePosition / 8) * 16 + x / 8) * 8 +
83 (wipePosition & 7)) *
84 8 +
85 (x & 7)] = 1 - value;
86 }
87 }
89 } while (front <= 191);
90 }
91}
92
93/// Copies the canvas to VRAM once the effect has finished drawing a frame
94/// (transferPending): the 128x128 canvas into BG2's character block 1, the
95/// way transferMode says, leaving the canvas cleared, faded, darkened or
96/// brightened for the next frame.
97///
98/// Runs each frame as a scheduler callback that nearly every canvas effect
99/// adds, most through EFFECT_START_TRANSFER, and removes before its blocks
100/// are freed (EFFECT_FINISH_CANVAS). Clears work->transferPending after a
101/// copy, and counts work->framesSinceTransfer: 1 on a frame that copied,
102/// one more on each frame that did not.
104 void **slots = gWorkSlot + HEAP_SLOT_BATTLE_EFFECT;
105 struct BattleEffectWork *work = slots[0];
106 void *source;
107 s32 *counter;
108 s32 nextCounter;
109
110 if (work->transferPending == 1) {
111 source = EFFECT_SLOT(slots, HEAP_SLOT_BATTLE_CANVAS);
112 switch (work->transferMode) {
113 case CANVAS_COPY:
114 Iwram_CopyWords((void *)BG_CHAR_BLOCK(1), source, CANVAS_BYTES);
115 break;
117 Iwram_CopyWords((void *)BG_CHAR_BLOCK(1), source, CANVAS_BYTES);
119 break;
121 // Any value but 50 keeps three quarters.
122 if (work->transferValue == 50) {
123 ColorBuffer_BackupAndHalve(source, (void *)BG_CHAR_BLOCK(1),
125 } else {
127 source, (void *)BG_CHAR_BLOCK(1), CANVAS_BYTES);
128 }
129 break;
132 (void *)BG_CHAR_BLOCK(1), CANVAS_BYTES);
133 break;
136 (void *)BG_CHAR_BLOCK(1), CANVAS_BYTES);
137 break;
138 }
139 work->transferPending = 0;
140 counter = &work->framesSinceTransfer;
141 nextCounter = 1;
142 } else {
143 counter = &work->framesSinceTransfer;
144 nextCounter = *counter + 1;
145 }
146 *counter = nextCounter;
147}
148
149/// Copies a full-screen picture to VRAM once the effect has finished drawing
150/// a frame: the 0x7800 bytes of Ram_MapCellBuffer into BG character block 2
151/// (0x06008000), the way transferMode says (modes 0 to 3; brightening is not
152/// offered).
153///
154/// Runs each frame as a scheduler callback added by
155/// BattleFx_RunParticleStreams, which removes it before it returns. Clears
156/// work->transferPending after a copy; unlike the canvas transfer it keeps
157/// no frame count.
159 // This switch stays apart from BattleFx_ProcessPendingGraphicsTransfer's:
160 // shared, both compile differently.
161 void **slots;
162 struct BattleEffectWork *work;
163 void *source;
165
167 work = slots[0];
168 source = Ram_MapCellBuffer;
169 if (work->transferPending != 1)
170 return;
171
173 switch (transferMode) {
174 case CANVAS_COPY:
175 Iwram_CopyWords((void *)BG_CHAR_BLOCK(2), source, 0x7800);
176 break;
178 Iwram_CopyWords((void *)BG_CHAR_BLOCK(2), source, 0x7800);
179 Iwram_FillWords(source, 0x7800, work->transferValue);
180 break;
182 if (work->transferValue == 50) {
183 ColorBuffer_BackupAndHalve(source, (void *)BG_CHAR_BLOCK(2), 0x7800);
184 } else {
186 0x7800);
187 }
188 break;
191 (void *)BG_CHAR_BLOCK(2), 0x7800);
192 break;
193 }
194
195 work->transferPending = 0;
196}
197
198/// One step of the background palette fade, in 1/65536ths of full
199/// brightness: 24 steps take it from full to 60%.
200#define CANVAS_FADE_STEP 1092
201
202/// Writes the window, display and blend registers the effect keeps in its
203/// work, all at once.
204///
205/// Nothing in the build calls it or takes its address. Writes WIN0H to
206/// BLDALPHA from the work block's copies.
209
210 REG_WIN0H = work->win0h;
211 REG_WIN0V = work->win0v;
212 REG_WIN1H = work->win1h;
213 REG_WIN1V = work->win1v;
214 REG_WININ = work->winin;
215 REG_WINOUT = work->winout;
216 REG_DISPCNT = work->dispcnt;
217 REG_BLDCNT = work->bldcnt;
218 REG_BLDALPHA = work->bldalpha;
219}
220
221/// Writes the effect's BG2 reference point (work->bg2x, work->bg2y) to BG2X
222/// and BG2Y.
223///
224/// Nothing in the build calls it or takes its address;
225/// BattleFx_AdvanceBg2OnInterval (display.c) writes the same pair itself.
228
229 REG_BG2X = work->bg2x;
230 REG_BG2Y = work->bg2y;
231}
232
233/// Darkens the battle backdrop while the canvas is open: for fadeFrames
234/// frames, writes the backdrop's colours one CANVAS_FADE_STEP darker each
235/// frame into background palettes 6 to 13, so the effect stands out.
236///
237/// Runs each frame as a scheduler callback added by
238/// BattleFx_BeginCanvasLayer and BattleFx_OpenCanvasLayer, and by
239/// BattleFx_RunRingAndSparkScene; BattleFx_EndCanvasLayer and
240/// BattleFx_EndElementStreaks remove it. It does nothing until the effect
241/// sets work->fadeFrames, which it counts down while counting
242/// work->fadeStep up.
244 struct BattleWork *battle = WORK_SLOT(HEAP_SLOT_BATTLE);
246
247 if (work->fadeFrames > 0) {
248 s32 step = ++work->fadeStep;
249
251 (void *)&BG_PLTT_COLOR(6, 0),
252 0x10000 - step * CANVAS_FADE_STEP, 128);
253 work->fadeFrames--;
254 }
255}
256
257/// Clears every target's flash timer (work->actorTimers).
258///
259/// Called as the canvas opens, by BattleFx_BeginCanvasLayer,
260/// BattleFx_OpenCanvasLayer and BattleFx_SetupCanvasTileMap, and by
261/// BattleFx_RunShatteringOpening, which opens its own.
264
265 Iwram_ClearWords(work->actorTimers, sizeof work->actorTimers);
266}
267
268/// Counts down each target's flash timer, which ObjectGroup_UpdateMembers
269/// starts; when one runs out, the target gets its own palette back. Timer n
270/// belongs to effect->actors[n].
271///
272/// Called once a frame by nearly every effect, most through
273/// EFFECT_END_FRAME. Changes work->actorTimers and, through
274/// ObjectGroup_UpdateMembers, the colour of a target whose timer ends.
276 struct BattleEffectWork *work;
277 s32 actorIndex;
278
280 actorIndex = 0;
281 do {
282 if (work->actorTimers[actorIndex] != 0) {
283 if ((work->actorTimers[actorIndex] = work->actorTimers[actorIndex] - 1) ==
284 0) {
285 ObjectGroup_UpdateMembers(work->effect->actors[actorIndex], 0, -1, -1,
286 0);
287 }
288 }
289 actorIndex += 1;
290 } while (actorIndex != 8);
291}
292
293// The canvas layer: BG2 shows the effect's 128x128 8bpp canvas (0x4000
294// bytes), its tiles from character block 1, stretched to twice the width
295// so it spans 256 pixels. Opening and closing it hide BG2 while its
296// settings change, through DISPCNT values queued two frames ahead.
297
298/// Opens the canvas layer: starts the background palette fade, makes BG2 the
299/// canvas, alpha-blended over the battle, inside the effect windows, and
300/// clears the canvas. It also stops any shake and saves BG1's scroll, which
301/// BattleFx_EndCanvasLayer restores.
302///
303/// Called at the start of nearly every canvas effect, most often through
304/// EFFECT_BEGIN_NARROW_CANVAS, and by BattleFx_BeginTiledCanvas. Waits five
305/// frames of its own. Writes BLDCNT, BLDALPHA, BG2CNT and BG2's affine
306/// registers, the windows, WININ and WINOUT, and queues DISPCNT; writes BG2's
307/// map in screen block 7, clears the canvas in its slot and in character block
308/// 1; adds Palette_StepFadeTransfer with work->fadeFrames 0, so the backdrop
309/// keeps its colours until the effect sets a count; sets gBgScroll[1].y to 32,
310/// clears work->actorTimers and work->shakeFrames, and saves gBgScroll[1]
311/// in work->savedBg1X and savedBg1Y.
312///
313/// bgControl : added to BG2CNT, the layer's priority (0 to 3) and so on.
316 struct BattleWork *battle = WORK_SLOT(HEAP_SLOT_BATTLE);
317 void *canvas = WORK_SLOT(HEAP_SLOT_BATTLE_CANVAS);
319 s32 row;
320 s32 column;
321 s32 offset;
322
323 // The background view's secondMode, which also sets BG1's scroll while it
324 // is 1, holds for the frames BG2 is being changed.
326 display->secondMode = 1;
327 WaitFrames(1);
328 REG_BLDCNT = 0;
330 gBgScroll[1].y = 32;
331 WaitFrames(1);
332
333 // Start the background palette fade.
335 work->fadeFrames = 0;
336 work->fadeStep = 0;
339
340 // Change BG2's settings while it is hidden (each queued DISPCNT lands two
341 // frames later).
346 0x20000);
347 WaitFrames(1);
348 REG_BG2CNT =
354 0x20000);
356 display->secondMode = 0;
357 WaitFrames(1);
358 // Show it: 14/16 of the canvas over all below, inside both windows.
360 REG_BLDALPHA = BLEND_ALPHA(14, 16);
367
368 // The screen map: the 16x16 tiles in order. An affine map has one byte
369 // per tile, so they are written two at a time.
370 offset = 0;
371 for (row = 0; row != 16; row++) {
372 EFFECT_WRITE_CANVAS_MAP_ROW(row, column, offset);
373 }
374
377 work->shakeFrames = 0;
378 work->savedBg1X = gBgScroll[1].x;
379 work->savedBg1Y = gBgScroll[1].y;
380 WaitFrames(1);
381}
382
383/// Opens the canvas layer as BattleFx_BeginCanvasLayer does, but with the
384/// windows off until the end, the backdrop palette starting half faded, and
385/// a 24-frame fade. It neither saves BG1's scroll nor resets the shake.
386///
387/// Nothing in the build calls it or takes its address. Writes the same
388/// registers, map and canvas as BattleFx_BeginCanvasLayer and sets
389/// work->fadeFrames to 24.
390///
391/// bgControl : added to BG2CNT, the layer's priority (0 to 3) and so on.
393 // The tile-map loop is written out here and in BattleFx_BeginCanvasLayer:
394 // shared, both compile 4 bytes shorter.
396 struct BattleWork *battle = WORK_SLOT(HEAP_SLOT_BATTLE);
397 void *canvas = WORK_SLOT(HEAP_SLOT_BATTLE_CANVAS);
399 s32 row;
400 s32 column;
401 s32 offset;
402
404 display->secondMode = 1;
405 WaitFrames(1);
406 REG_BLDCNT = 0;
410 0x20000);
411 gBgScroll[1].y = 32;
412 WaitFrames(1);
414 work->fadeFrames = 24;
415 work->fadeStep = 0;
421 0x20000);
422 WaitFrames(1);
423 REG_BG2CNT =
428 0x20000);
430 display->secondMode = 0;
431 WaitFrames(1);
432
434 REG_BLDALPHA = BLEND_ALPHA(14, 16);
441 WaitFrames(1);
442
443 offset = 0;
444 for (row = 0; row != 16; row++) {
445 EFFECT_WRITE_CANVAS_MAP_ROW(row, column, offset);
446 }
447
450 WaitFrames(1);
451}
452
453/// Opens the canvas layer with BG2 a wrapping 256x256 map: each row of the
454/// map is the canvas's 16 tiles followed by 16 of tile 0, so the canvas
455/// repeats across the screen with gaps.
456///
457/// Called by BattleFx_RunRay, BattleFx_RunCondemn,
458/// BattleFx_RunCastingImpact and BattleFx_InitTilemapAndFlushQueue. Opens
459/// the layer through BattleFx_BeginCanvasLayer, then rewrites BG2CNT and
460/// BG2's map in screen block 7.
461///
462/// bgControl : added to BG2CNT, the layer's priority (0 to 3) and so on.
464 s32 row;
465 s32 column;
466 s32 offset;
467
468 BattleFx_BeginCanvasLayer(bgControl);
469 REG_BG2CNT = bgControl | BGCNT_CHAR_BASE(1) | BGCNT_256_COLORS |
471 offset = 0;
472 for (row = 0; row != 16; row++) {
473 EFFECT_WRITE_CANVAS_MAP_ROW(row, column, offset);
474 for (column = 0; column != 8; column++, offset += 2) {
475 *(volatile u16 *)((u8 *)BG_CANVAS_MAP + offset) = 0;
476 }
477 }
478}
479
480/// Closes the canvas layer: plays the closing sound, restores BG1's scroll
481/// and the projection centre, clears the canvas tiles, stops the palette
482/// fade and brings the backdrop's palette back from level 21 to 0 over 8
483/// frames, then shows BG2 again and hides BG1.
484///
485/// Called at the end of nearly every canvas effect, most through
486/// EFFECT_FINISH_CANVAS, after the transfer callback is removed. Takes 11
487/// frames. Writes gBgScroll[1], gProjection's centre, BG2CNT (priority 3)
488/// and BLDCNT, clears character block 1, removes Palette_StepFadeTransfer
489/// and queues two DISPCNT values.
492 struct BattleWork *battle = WORK_SLOT(HEAP_SLOT_BATTLE);
493 s32 i;
494
496 gBgScroll[1].x = work->savedBg1X;
497 gBgScroll[1].y = work->savedBg1Y;
498 // The battle's projection centre, which Camera_ApplyShake moves.
499 gProjection.centerX = 120;
500 gProjection.centerY = 120;
505 // This overwrites the saved y restored above before any frame passes, so
506 // BG1 is always left at y 32.
507 gBgScroll[1].y = 32;
512 0x20000);
513 REG_BLDCNT = 0;
514 WaitFrames(1);
515
517 WaitFrames(1);
518 for (i = 0; i != 8; i++) {
520 WaitFrames(1);
521 }
522
527 0x20000);
528 WaitFrames(1);
529}
530
531/// Hides BG1 and the windows and starts bringing the backdrop's palette back.
532///
533/// Called by BattleFx_RunBeamSequence and BattleFx_RunRingAndSparkScene
534/// (beams.c). Sets the background view's secondMode to 1, queues DISPCNT for
535/// two frames later, starts the battle's palette fade (mode 2) and waits two
536/// frames.
538 struct BattleWork *battle;
539 s32 *flag;
540
541 flag = &((struct BattleBackgroundView *)
543 ->secondMode;
545 *flag = 1;
549 WaitFrames(1);
551 WaitFrames(1);
552}
553
554/// Shows the canvas on BG1 instead of BG2, at its own size: BG1 becomes a
555/// 256-colour layer whose map points 16 rows of 16 tiles at the canvas
556/// (tiles 0x100 onwards, which at 64 bytes a tile start at character block
557/// 1, where the canvas lives), with blank tile 0xff to the right, blended over
558/// the rest inside the effect windows. Also clears the canvas. The
559/// full-screen Ram_MapCellBuffer effects use
560/// BattleFx_FlushPendingGraphicsTransfer instead.
561///
562/// Called by BattleFx_RunBeamSequence and BattleFx_RunRingAndSparkScene
563/// (beams.c). Clears work->actorTimers, starts the battle's palette fade
564/// (mode 2), clears tile 0xff of character block 0 and writes BG1's map in
565/// screen block 31; writes DISPCNT, BG1CNT, BLDCNT, BLDALPHA, the windows,
566/// WININ and WINOUT directly; sets gBgScroll[1].y to 32 and the background
567/// view's secondMode to 0; clears the canvas and character block 1.
569 // UB: indexing past gBattleWork reaches the work slots after it.
570#ifdef UBFIX
571 void *canvas = WORK_SLOT(HEAP_SLOT_BATTLE_CANVAS);
572 struct BattleWork *screen = gBattleWork;
574#else
575 u8 **cells = (u8 **)&gBattleWork;
576 void *canvas = cells[31];
577 struct BattleWork *screen = (struct BattleWork *)cells[0];
578 struct BattleBackgroundView *layer = (struct BattleBackgroundView *)cells[35];
579#endif
580 s32 row;
581 s32 column;
582 s32 byteOffset;
583
586 gBgScroll[1].y = 32;
587 layer->secondMode = 0;
588 // Blank tile 0xff, then map rows 4 to 11 filled with 0xffff.
589 // XXX: what map entry 0xffff shows (tile 0x3ff, flipped, palette 15, in
590 // a 256-colour layer); a VRAM view of a beam scene would settle whether
591 // those rows are meant to show nothing.
592 Iwram_ClearWords(BG_CHAR_BLOCK(0) + 0xff * 64, 64);
593 Iwram_FillWords(BG_SCREEN_BLOCK(31) + 4 * 64, 0x200, -1);
594 // Rows 12 to 27: the canvas's 16 tiles from tile 0x100, then blank tile
595 // 0xff across the rest of the 32-tile row.
596 byteOffset = 0;
597 for (row = 0; row != 16; row++) {
598 for (column = 0; column != 32; column++, byteOffset += 2) {
599 if (column > 15)
600 *(volatile u16 *)(BG_SCREEN_BLOCK(31) + 12 * 64 + byteOffset) = 0xff;
601 else
602 *(volatile u16 *)(BG_SCREEN_BLOCK(31) + 12 * 64 + byteOffset) =
603 row * 16 + 0x100 + column;
604 }
605 }
614 REG_BLDALPHA = BLEND_ALPHA(14, 16);
617 WaitFrames(1);
618}
619
620/// Draws a line on the 128x128 8bpp canvas (16 tiles across), keeping the
621/// brighter colour where it crosses what is already drawn. The ends' y is
622/// kept on the canvas; x is not. The line steps a pixel at a time along its
623/// longer axis, following the other in 8-bit fixed point, and leaves out its
624/// last pixel on that axis.
625///
626/// Called by BattleFx_DrawStreaks (death_plunge.c) and BattleFx_RunNeptune.
627/// Writes only the canvas.
628///
629/// x0, y0 : the start, in pixels
630/// x1, y1 : the end, in pixels
631/// color : the colour index
632void BattleFx_DrawClippedCanvasLine(s32 x0, s32 y0, s32 x1, s32 y1, s32 color) {
633 s32 dx = x1 - x0;
634 s32 dy = y1 - y0;
635 s32 frac = 0x80; // 0.5 in 8-bit fixed point
636 u8 *canvas = ((u8 **)gBattleFxWork)[1];
637 s32 step;
638 s32 i;
639 s32 x;
640 s32 y;
641 s32 tmp;
642 u32 offset;
643
644 CLAMP(y0, 0, 127);
645 CLAMP(y1, 0, 127);
646
647 if (ABS(dx) < ABS(dy)) {
648 // Steep: step y a pixel at a time and follow x in fixed point.
649 if (dy < 0) {
650 tmp = x0;
651 x0 = x1;
652 x1 = tmp;
653 tmp = y0;
654 y0 = y1;
655 y1 = tmp;
656 dx = x1 - x0;
657 dy = y1 - y0;
658 }
659 step = (ABS(x1 - x0) << 8) / ABS(y1 - y0);
660 x = x0;
661 for (i = y0; i != y1; i++) {
662 offset = (((((u32)i >> 3) << 4) + ((u32)x >> 3)) << 3) + (i & 7);
663 offset = (offset << 3) + (x & 7);
664 if (canvas[offset] < color)
665 canvas[offset] = color;
666 frac += step;
667 if (frac & 0x100) {
668 if (dx > 0)
669 x++;
670 else
671 x--;
672 frac &= ~0x100;
673 }
674 }
675 } else {
676 // Shallow: step x a pixel at a time and follow y in fixed point.
677 if (dx < 0) {
678 tmp = x0;
679 x0 = x1;
680 x1 = tmp;
681 tmp = y0;
682 y0 = y1;
683 y1 = tmp;
684 dx = x1 - x0;
685 dy = y1 - y0;
686 }
687 step = (ABS(y1 - y0) << 8) / ABS(x1 - x0);
688 y = y0;
689 for (i = x0; i != x1; i++) {
690 offset = (((((u32)y >> 3) << 4) + ((u32)i >> 3)) << 3) + (y & 7);
691 offset = (offset << 3) + (i & 7);
692 if (canvas[offset] < color)
693 canvas[offset] = color;
694 frac += step;
695 if (frac & 0x100) {
696 if (dy > 0)
697 y++;
698 else
699 y--;
700 frac &= ~0x100;
701 }
702 }
703 }
704}
705
706#undef CANVAS_FADE_STEP
void * gBattleFxWork[]
struct BattleWork * gBattleWork
void Graphics_ApplyWindowBlendRegisters(void)
Writes the window, display and blend registers the effect keeps in its work, all at once.
Definition canvas.c:207
void Palette_StepFadeTransfer(void)
Darkens the battle backdrop while the canvas is open: for fadeFrames frames, writes the backdrop's co...
Definition canvas.c:243
void BattleFx_SetupCanvasTileMap(void)
Shows the canvas on BG1 instead of BG2, at its own size: BG1 becomes a 256-colour layer whose map poi...
Definition canvas.c:568
void ObjectGroup_TickMemberTimers(void)
Counts down each target's flash timer, which ObjectGroup_UpdateMembers starts; when one runs out,...
Definition canvas.c:275
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
#define CANVAS_FADE_STEP
One step of the background palette fade, in 1/65536ths of full brightness: 24 steps take it from full...
Definition canvas.c:200
void Display_ApplyBg2Reference(void)
Writes the effect's BG2 reference point (work->bg2x, work->bg2y) to BG2X and BG2Y.
Definition canvas.c:226
void BattleFx_EndCanvasLayer(void)
Closes the canvas layer: plays the closing sound, restores BG1's scroll and the projection centre,...
Definition canvas.c:490
void BattleFx_FlushPendingGraphicsTransfer(void)
Copies a full-screen picture to VRAM once the effect has finished drawing a frame: the 0x7800 bytes o...
Definition canvas.c:158
void BattleFx_HideBg1AndRestoreBackdrop(void)
Hides BG1 and the windows and starts bringing the backdrop's palette back.
Definition canvas.c:537
void BattleFx_ClearActorTimers(void)
Clears every target's flash timer (work->actorTimers).
Definition canvas.c:262
void BattleFx_BeginTiledCanvas(s32 bgControl)
Opens the canvas layer with BG2 a wrapping 256x256 map: each row of the map is the canvas's 16 tiles ...
Definition canvas.c:463
void BattleFx_OpenCanvasLayer(s32 bgControl)
Opens the canvas layer as BattleFx_BeginCanvasLayer does, but with the windows off until the end,...
Definition canvas.c:392
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 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
What every part of the battle effect object shares: its includes, macros and frame-loop helpers.
#define EFFECT_PRESENT_FRAME(work)
Ends a frame of a canvas effect: marks the canvas ready for the transfer callback,...
@ CANVAS_COPY
copy as drawn
@ CANVAS_COPY_AND_BRIGHTEN
copy, then brighten the canvas by transferValue
@ CANVAS_COPY_AND_CLEAR
copy, then fill the canvas with transferValue
@ CANVAS_COPY_AND_DARKEN
copy, then darken the canvas by transferValue
@ 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_SLOT(slots, slot)
A work slot read through a pointer to the effect's own slot, gWorkSlot[HEAP_SLOT_BATTLE_EFFECT].
#define EFFECT_WINOUT
Outside the battle view: BG0 and blending only.
#define EFFECT_DISPCNT
The battle screen's display mode while an effect plays: background mode 1 with BG0 to BG2,...
#define EFFECT_SET_BATTLE_WINDOWS()
Windows 0 and 1 both cover the battle view: the full width, lines 16 to.
#define EFFECT_PLAYBACK_ORDER
The order where the battle's own playback runs, which the palette fade and the element streaks take.
#define EFFECT_WIN0_LAYERS
Window 0, the battle view, shows BG0 to BG2, sprites and blending.
#define EFFECT_WRITE_CANVAS_MAP_ROW(row, column, offset)
Writes one row of BG2's map for the canvas: its 16 tiles of row row in order.
#define EFFECT_SET_CANVAS_AFFINE()
BG2 shows the canvas from screen line 16 down (BG2Y is -16.0), stretched to twice its width: the 128x...
void BattlePres_SetupTransitionSceneFar(s32 x, s32 depth, s32 y, s32 zoom)
s32 Graphics_ScaleRgb555ClampedFar(u16 *source, u16 *destination, s32 scale, s32 count)
void BattlePresentation_ConfigurePaletteFadeFar(s32 mode, s32 value, s32 fade)
void BattlePresentation_SetPaletteLevelFar(s32 unused, s32 level)
void AudioCommand_PlayFar(s32 id)
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_BATTLE_BACKGROUND
Definition heap_state.h:45
@ HEAP_SLOT_BATTLE
Definition heap_state.h:37
@ HEAP_SLOT_BATTLE_CANVAS
Definition heap_state.h:43
#define WORK_SLOT(n)
Reads slots through their own addresses; adjacent slots are reached by offsets.
Definition heap_state.h:14
void IoWriteQueue_Store16(u32 address, u32 value)
Queues a halfword store.
Definition io_queue.c:21
#define REG_WIN1H
Definition io_reg.h:75
#define BG_CANVAS_MAP
Definition io_reg.h:148
#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 BG_SCREEN_BLOCK(n)
Definition io_reg.h:167
#define BLDCNT_TGT1_BG2
Definition io_reg.h:125
#define BG_CHAR_BLOCK(n)
Definition io_reg.h:166
#define REG_WIN0H
Definition io_reg.h:74
#define WININ_WIN1_BG0
Definition io_reg.h:93
#define BGCNT_SIZE(n)
The background's size: for an affine one, 0 to 3 are 128, 256, 512 and 1024 pixels square.
Definition io_reg.h:33
#define WININ_WIN1_CLR
Definition io_reg.h:98
@ DISPCNT_OBJ_ON
Definition io_reg.h:44
@ DISPCNT_WIN0_ON
Definition io_reg.h:45
@ DISPCNT_BG0_ON
Definition io_reg.h:40
@ DISPCNT_OBJ_1D_MAP
Definition io_reg.h:39
@ DISPCNT_MODE_1
BG0 and BG1 text, BG2 affine.
Definition io_reg.h:37
@ DISPCNT_WIN1_ON
Definition io_reg.h:46
@ DISPCNT_BG2_ON
Definition io_reg.h:42
@ DISPCNT_BG1_ON
Definition io_reg.h:41
#define REG_BG2X
Definition io_reg.h:65
#define REG_DISPCNT
Definition io_reg.h:9
#define BLDCNT_EFFECT_BLEND
weighted by REG_BLDALPHA
Definition io_reg.h:131
#define BLDCNT_TGT2_ALL
Definition io_reg.h:140
#define REG_BG2Y
Definition io_reg.h:66
#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 BLDCNT_TGT1_BG1
Definition io_reg.h:124
#define REG_BG2CNT
Definition io_reg.h:21
#define REG_BLDALPHA
Definition io_reg.h:142
#define REG_WINOUT
Definition io_reg.h:82
#define WININ_WIN1_OBJ
Definition io_reg.h:97
#define REG_BLDCNT
Definition io_reg.h:119
#define REG_BG1CNT
Definition io_reg.h:20
#define BG_PLTT_COLOR(palette, color)
Definition io_reg.h:158
#define REG_WIN1V
Definition io_reg.h:77
#define WININ_WIN1_BG2
Definition io_reg.h:95
#define BGCNT_WRAP
Affine backgrounds only: wrap around instead of showing the backdrop.
Definition io_reg.h:30
#define REG_WIN0V
Definition io_reg.h:76
#define IO_WRITE_QUEUE_PUSH(address, value, control)
Disables interrupts to add one register write or DMA to the queue; a write to a full queue is dropped...
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
static s32 Iwram_ClearWords(void *destination, s32 size)
Definition iwram_call.h:55
#define ABS(v)
The magnitude of v. v is read twice.
Definition macros.h:32
#define CLAMP(v, low, high)
Keeps v within low to high, the low bound tested first.
Definition macros.h:23
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
struct Projection gProjection
#define Ram_WorkSlot
Definition ram_buffer.h:44
#define Ram_MapCellBuffer
Definition ram_buffer.h:10
void ColorBuffer_BackupAndScaleThreeQuarters(u8 *buffer, u8 *backup, u32 bytes)
Scales every pixel to three quarters.
Definition decompress.c:65
void ColorBuffer_BackupAndHalve(u8 *buffer, u8 *backup, u32 bytes)
Halves every pixel. Called by the battle effect canvas's transfers.
Definition decompress.c:75
void ColorBuffer_BackupAndBrighten(u8 *buffer, u32 amount, u8 *backup, u32 bytes)
Raises every pixel by amount, stopping at 63.
Definition decompress.c:47
void ColorBuffer_BackupAndDarken(u8 *buffer, u32 amount, u8 *backup, u32 bytes)
Lowers every pixel by amount, stopping at 0.
Definition decompress.c:56
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_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 secondMode
1 also sets BG1's scroll; one effect sets it
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 savedBg1Y
BG1 scroll restored when a shake ends.
s32 savedBg1X
BG1 scroll restored when a shake ends.
s32 framesSinceTransfer
1 on a canvas copy's frame, then counts up
s32 transferPending
1 once the effect has drawn a frame (EFFECT_PRESENT_FRAME); the canvas transfer callback copies the c...
s32 fadeStep
CANVAS_FADE_STEPs the backdrop has darkened so far.
s32 shakeFrames
shake frames left; Camera_ApplyShake counts down
s32 bg2x
BG2's reference point, written to BG2X and BG2Y by Display_ApplyBg2Reference and BattleFx_AdvanceBg2O...
u16 win0h
Window, display and blend registers, which Graphics_ApplyWindowBlendRegisters writes all at once.
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...
u8 actorTimers[8]
Each target's flash timer in frames, for effect->actors[n]: set by ObjectGroup_UpdateMembers,...
struct BattleEffectArgument * effect
the command being run
The battle's own work: its enemies, units and their objects, the turn's actions, the spoils,...
Definition battle_work.h:71
u16 background
the battle background's id
u16 palette[128]
the backdrop's colours, before scaling
u16 y
pixels
Definition map_scroll.h:65
s32 centerX
screen pixels
Definition project.h:16
s32 centerY
screen pixels
Definition project.h:17
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