Alchemy
Loading...
Searching...
No Matches

torch.c

Go to the documentation of this file.
1/// @file
2/// Torch and Kite.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7#define TORCH_FRAMES 96
8
9/// A fiery disc fades in, its rings running outward while every scanline
10/// ripples, then fades out.
11///
12/// Abilities: Torch (kind 214).
13///
14/// The disc is a mirrored radial picture whose pixels hold their distance from
15/// the middle, so rotating the palette moves the rings. It follows a Mars
16/// Djinni's entrance over the user, fades in over the first 9 frames, ripples
17/// throughout as BG2's x reference is fed line by line
18/// (BattleFx_ArmBg2AffineHBlankDma), and fades out over the last 7.
20 void **slots;
21 struct BattleEffectWork *work;
22 void *canvas;
23 s32 screenY;
24 s32 screenX;
25 DrawRectangle draw[2];
26 s32 x;
27 s32 y;
28 s32 dx;
29 s32 dy;
30 s32 cy;
31 s32 d;
32 s32 i;
33 s32 t;
34 s32 r;
35 s32 g;
36 s32 b;
37 s32 frame;
38 s32 wave;
39 s32 level;
40 u16 *pal;
41 s32 angle;
42 s32 *line;
43
44 slots = gBattleFxWork;
45 EFFECT_GET_WORK_AND_CANVAS(slots, work, canvas);
46 work->effect = effect;
48 // The Mars Djinni's long entrance (mode 6), over the user (anchor 2).
49 BattleFx_RunDjinniEntrance(effect, 6, work->effect->side, 2, &screenX,
50 &screenY);
54 REG_BG2PA = Q_8_8(1.0 / 1.5);
57
58 // Fill the 128x128 sheet with each pixel's distance from the middle,
59 // halved and held to 1 to 63, so the distance picks the colour. Rows count
60 // 7/8 of a pixel each, so the rings are a little taller than wide. Build
61 // one quadrant and mirror it into the other three.
62 for (y = 0; y != 64; y++) {
63 for (x = 0; x != 64; x++) {
64 cy = y / 8 + 64;
65 dy = y - cy;
66 dx = x - 64;
67 d = Iwram_Sqrt(dx * dx + dy * dy);
68 d /= 2;
69 if (d == 0)
70 d = 1;
71 if (d > 63)
72 d = 63;
73 work->sheet[y * 128 + x] = d;
74 work->sheet[y * 128 + 127 - x] = d;
75 work->sheet[(127 - y) * 128 + x] = d;
76 work->sheet[(127 - y) * 128 + 127 - x] = d;
77 }
78 }
79
80 // Colours 1 to 63: a fiery ramp that brightens to colour 31 and darkens
81 // again, written to the background palette and to a copy in
82 // Ram_MapCellBuffer that the frame loop rotates.
83 pal = (u16 *)Ram_MapCellBuffer;
84 for (i = 1; i != 64; i++) {
85 if (i > 31)
86 t = 64 - i;
87 else
88 t = i;
89 r = t * 9;
90 g = t * 7 - 42;
91 b = t * 7 - 56;
92 if (r < 0)
93 r = 0;
94 if (g < 0)
95 g = 0;
96 if (b < 0)
97 b = 0;
98 if (r > 255)
99 r = 255;
100 if (g > 255)
101 g = 255;
102 if (b > 250)
103 b = 250;
104 r >>= 3;
105 g >>= 3;
106 b >>= 3;
107 pal[i] = ((u16 *)BG_PLTT)[i] = b << 10 | g << 5 | r;
108 }
109
110 draw[0](canvas, work->sheet, 0, 0, 128, 128);
111 work->transferPending = 1;
114
115 // Fade the radial picture in (frames 0 to 8), ripple each scanline, then
116 // fade it out (frames 89 to 95, from 14 sixteenths down to 2).
117 for (frame = 0; frame != TORCH_FRAMES; frame++) {
118 if (frame <= 8) {
119 level = frame * 2;
120 wave = level;
121 REG_BLDALPHA = BLEND_ALPHA(level, 16);
122 } else {
123 wave = frame * 2;
124 }
125 if (frame > 88)
126 REG_BLDALPHA = BLEND_ALPHA(0xc0 - frame * 2, 16);
127
128 // BG2's x reference for each of the 160 scanlines: a sine wave whose
129 // phase advances with wave, which the HBlank DMA applies.
130 line = work->bg2xLines;
131 for (i = 0, angle = -(wave << 9); i != 160; i++) {
132 *line++ = ((i << 18) - ((Trig_Sin(angle) * 128)) + 0x40000) >> 10;
133 angle += 0x200;
134 }
135
136 // Rotate colours 2 to 63 up by one, so the rings run outward: colour 63
137 // goes to colour 1 first, and the backward 62-halfword copy then moves 1
138 // to 62 up to 2 to 63, leaving colour 1 equal to the new colour 2. Then
139 // queue colours 1 to 63 for the background palette. The test against
140 // frame 127 never holds within the 96 frames.
141 if (frame > 127) {
142 work->transferPending = 1;
143 } else {
144 pal[1] = pal[63];
145 Dma_Set(pal + 62, pal + 63, 0x80a0003e, REG_DMA3);
146 IO_WRITE_QUEUE_PUSH((u32)&BG_PLTT[1], (u32)(pal + 1), 0x8000003f);
147 }
148 WaitFrames(1);
149 }
150
153}
154
155/// Shows the extended Jupiter Djinni prelude over the first target, mirrored
156/// from the usual side; the Djinni's entrance is the whole effect.
157///
158/// Abilities: Kite (kind 217).
160 struct BattleEffectWork *work;
161 s32 originX;
162 s32 originY;
163
165 work->effect = effect;
167 BattleFx_RunDjinniEntrance(effect, 7, work->effect->side ^ 1, 0, &originX,
168 &originY);
170}
171
172#undef TORCH_FRAMES
void * gBattleFxWork[]
BattleEffectDrawRectangle DrawRectangle
void BattleFx_ArmBg2AffineHBlankDma(void)
Arms DMA 0 to copy one word of gBattleFxWork's bg2xLines table into BG2X at each horizontal blank,...
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_EndCanvasLayer(void)
Closes the canvas layer: plays the closing sound, restores BG1's scroll and the projection centre,...
Definition canvas.c:490
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
What every part of the battle effect object shares: its includes, macros and frame-loop helpers.
@ CANVAS_COPY_AND_FADE
copy, keeping 50% or 75% (transferValue) of each pixel in the canvas for the next frame
#define EFFECT_GET_WORK_AND_CANVAS(cursor, work, canvas)
The work block and canvas occupy adjacent slots, starting at HEAP_SLOT_BATTLE_EFFECT.
#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_START_TRANSFER(work, mode, value)
Sets the transfer, then starts copying the canvas to VRAM once a frame.
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
#define WORK_SLOT(n)
Reads slots through their own addresses; adjacent slots are reached by offsets.
Definition heap_state.h:14
#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 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 BGCNT_WRAP
Affine backgrounds only: wrap around instead of showing the backdrop.
Definition io_reg.h:30
#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_Sqrt(s32 value)
Definition iwram_call.h:63
void BattleFx_FetchRectangleBlitters(s32 flip, BlitterPair out)
Builds the two usual routines that draw onto the 128x128 canvas, both clipped on both axes.
void BattleFx_RunDjinniEntrance(struct BattleEffectArgument *effect, s32 mode, s32 side, s32 anchor, s32 *outX, s32 *outY)
Djinni entrance: sparks swirl around a point that travels from the user to the goal and gather into t...
Definition projectiles.c:29
#define Ram_MapCellBuffer
Definition ram_buffer.h:10
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
The command shared by an effect's caller, dispatcher and handlers.
s32 side
1 when the targets are the party, 0 for enemies
The running battle effect's work: its canvas image, 64 particles, the display registers it stages and...
s32 frame
frame counter some effects keep, from 0
s32 transferPending
1 once the effect has drawn a frame (EFFECT_PRESENT_FRAME); the canvas transfer callback copies the c...
struct BattleEffectArgument * effect
the command being run
void BattleFx_RunKite(struct BattleEffectArgument *effect)
Shows the extended Jupiter Djinni prelude over the first target, mirrored from the usual side; the Dj...
Definition torch.c:159
void BattleFx_RunTorch(struct BattleEffectArgument *effect)
A fiery disc fades in, its rings running outward while every scanline ripples, then fades out.
Definition torch.c:19
#define TORCH_FRAMES
Definition torch.c:7
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
unsigned short u16
Definition types.h:13