Alchemy
Loading...
Searching...
No Matches

dispatch.c

Go to the documentation of this file.
1/// @file
2/// Running scene and table effects, and shared target helpers.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7/// Calls the empty BattleFx_DoNothing count times, without waiting for a
8/// frame: a busy delay that changes no state.
9///
10/// Called only by BattleFx_RunAnnihilation (annihilation.c), with 10000,
11/// before it releases the blitter it has just drawn with.
13 s32 callIndex;
14
15 callIndex = 0;
16 if (count != 0) {
17 do {
18 callIndex += 1;
20 } while (callIndex != count);
21 }
22}
23
24// Two of the battle's three entry points, BattleFx_RunSceneEffect and
25// BattleFx_RunTableEffect; README.md describes all three and the heap blocks
26// they lend an effect. The shared helpers after them manage the scanline
27// window and the targets' animation objects.
28
29/// Runs one of the large battle effects, the ones whose presentation flags
30/// have bit 15 set: takes the effect's sheet, work and canvas, runs the
31/// effect chosen by its kind to the end, and frees them again.
32///
33/// Called through BattleFx_RunSceneEffectFar by
34/// BattlePresentation_RunUnitTransition (battle/staging.c), when the plan's
35/// presentation flags have STAGING_SCENE, and by
36/// BattlePresentation_RunPairedUnitTransition (battle/auto_battle.c).
37///
38/// Each scene is named for the summon whose gBattle_ActionFlags entry selects
39/// its kind, as the handlers of gBattleFx_EffectHandlers are; kind 0, which no
40/// ability selects, runs Meteor's scene too. Takes heap slots
41/// HEAP_SLOT_BATTLE_SHEET, HEAP_SLOT_BATTLE_EFFECT and HEAP_SLOT_BATTLE_CANVAS
42/// and releases them in reverse, so the scene must have removed every callback
43/// that reads them. Unlike BattleFx_RunTableEffect it does not set
44/// work->effect: each scene does that itself.
48 sizeof(struct BattleEffectWork));
50
51 if (effect->kind == 0) {
52 BattleFx_RunMeteor(effect);
53 } else {
54 switch (effect->kind) {
56 BattleFx_RunRamses(effect);
57 break;
59 BattleFx_RunNereid(effect);
60 break;
62 BattleFx_RunKirin(effect);
63 break;
66 break;
68 BattleFx_RunCybele(effect);
69 break;
71 BattleFx_RunNeptune(effect);
72 break;
74 BattleFx_RunTiamat(effect);
75 break;
77 BattleFx_RunProcne(effect);
78 break;
81 break;
83 BattleFx_RunBoreas(effect);
84 break;
86 BattleFx_RunMeteor(effect);
87 break;
89 BattleFx_RunThor(effect);
90 break;
91 }
92 }
93
97}
98
99/// Runs an ordinary battle effect: takes the effect's sheet, work and
100/// canvas, runs the entry of gBattleFx_EffectHandlers for its kind,
101/// and frees them again.
102///
103/// Called through BattleFx_RunTableEffectFar by BattlePres_RunAttack,
104/// BattlePres_RunItem, BattlePres_RunPsynergyCast and
105/// BattlePresentation_RunUnitTransition (battle/staging.c, the last when the
106/// plan sets neither STAGING_SCENE nor STAGING_BY_ID_RANGE), and by
107/// BattlePres_RunUnitAction (battle/auto_battle.c).
108///
109/// Sets work->effect before the handler runs, which every handler and
110/// callback reads the effect through. Kind 0 is no effect and only clears
111/// effect->variant.
113 s32 kind;
114 struct BattleEffectWork *work;
115
118 sizeof(struct BattleEffectWork));
120
122 work->effect = effect;
123 kind = effect->kind;
124 if (kind == 0)
125 effect->variant = 0;
126 else
128
132}
133
134/// Builds window 0's right edge for every scanline and restarts the HBlank
135/// DMA that writes it to WIN0H each line.
136///
137/// Runs each frame as a scheduler callback added by BattleFx_RunNeptune
138/// (neptune.c) and BattleFx_RunBoreas (boreas.c), which fill the edge offsets
139/// and remove the callback again. Writes the WIN0H table and stops and re-arms
140/// DMA channel 0.
141///
142/// Ram_MapCellBuffer + 0 : the base right edge (u16)
143/// Ram_MapCellBuffer + 2 : how far each of lines 8 to 135 pulls the edge in
144/// (u8 x 128)
145/// Ram_MapCellBuffer + 0x82 : the WIN0H table built here (u16 x 160)
146/// Lines outside 8 to 135 get 0xfff1, a left edge past the right, so nothing
147/// of them is in the window. Edges are clamped to 0 to 240.
149 u16 *baseRightEdge;
150 u16 *scanlineEdges;
151 u8 *edgeOffsets;
152 s32 scanline;
153 s32 rightEdge;
154
155 baseRightEdge = (u16 *)Ram_MapCellBuffer;
156 scanlineEdges = (u16 *)(Ram_MapCellBuffer + 0x82);
157 edgeOffsets = Ram_MapCellBuffer + 2;
158 for (scanline = 0; scanline != 160; scanline++) {
159 if (scanline >= 8 && scanline <= 135) {
160 rightEdge = *baseRightEdge - edgeOffsets[scanline - 8];
161 CLAMP(rightEdge, 0, 240);
162 scanlineEdges[scanline] = rightEdge;
163 } else {
164 scanlineEdges[scanline] = 0xfff1;
165 }
166 }
167 {
168 volatile u16 *channel = REG_DMA0;
169
170 Dma_Stop(channel);
171 Dma_Set(Ram_MapCellBuffer + 0x82, (void *)&REG_WIN0H,
172 DMA_HBLANK_HALFWORD_PER_LINE, (volatile u32 *)channel);
173 }
174}
175
176/// Shows the battle objects of every unit with HP left on the targets' side:
177/// the enemies (units 128 to 133) when the first target is one, otherwise
178/// the party (units 0 to 7).
179///
180/// Called by the summon scenes (Ramses, Nereid, Kirin, Atalanta, Cybele,
181/// Neptune, Tiamat, Procne, Judgment, Boreas, Thor) and the particle streams
182/// as they open. Spawns the
183/// objects through BattleActor_SpawnObjectsForListFar.
185 s16 list[14];
186 s32 count;
187 s32 i;
188
189 count = 0;
190 if (effect->actors[0] > 127) {
191 for (i = 0; i != 6; i++) {
192 s32 id = i + 128;
193
194 if (UnitGetFar(id)->hp > 0)
195 list[count++] = id;
196 }
197 } else {
198 for (i = 0; i != 8; i++) {
199 if (UnitGetFar(i)->hp > 0)
200 list[count++] = i;
201 }
202 }
203 list[count] = 0xff; // the end of the list
205}
206
207/// Shows the BG1 battle background behind a cleared canvas: clears the canvas
208/// buffer and the 16 KiB of VRAM it is copied to, then blends BG2 over the
209/// rest at 14/16 and moves the projection centre down to line 120.
210///
211/// Called by the summon scenes (Ramses, Kirin, Atalanta, Neptune, Procne,
212/// Judgment, Boreas, Thor) and the particle streams as they close, to give
213/// the battle back its own background. Sets gBgScroll[1].y to 32, reloads
214/// BG1 with the battle's background, waits one frame with the display off
215/// but for mode 1, then writes REG_BLDALPHA, REG_BLDCNT and REG_DISPCNT and
216/// gProjection.centerY.
218 void **slots = &gWorkSlot[HEAP_SLOT_BATTLE];
220 struct BattleWork *battle = slots[0];
221 volatile u32 fill;
222
224 gBgScroll[1].y = 32;
225 BattleBackground_LoadFar(1, battle->background, 24);
226 Dma_Fill32Cell(fill, 0, canvas, CANVAS_BYTES);
228 WaitFrames(1);
229 REG_BLDALPHA = BLEND_ALPHA(14, 16);
230 REG_BLDCNT =
233 gProjection.centerY = 120;
234}
235
236/// Updates every animation group of one battler's object.
237///
238/// actorId: the battler whose object is updated.
239/// palette: the colour mode each sprite part takes (enum SpriteColorMode), 0
240/// for the battler's own, or -1 to leave the parts alone. A part
241/// that changes colours also restarts its frame.
242/// animation: the pose each group switches to (enum BattlePose), or -1 for
243/// none.
244/// timerSlot: the actor timer (gBattleFxWork's actorTimers) to set, or -1;
245/// ObjectGroup_TickMemberTimers restores the battler's palette
246/// when it runs out.
247/// timerFrames: the frames that timer counts.
248/// The parts and animations of a battler that is fading out stay as they are,
249/// but its timer is still set.
250///
251/// Called throughout the effects, most often through
252/// EFFECT_STRIKE_TARGET when a hit lands. Writes work->actorTimers[timerSlot]
253/// and each part's param and frame (0xff restarts it).
254void ObjectGroup_UpdateMembers(s32 actorId, s32 palette, s32 animation,
255 s32 timerSlot, s32 timerFrames) {
256 struct BattleObj *slot;
257 struct AnimationObject *group;
258 struct BattleEffectWork *work;
259 s32 groupIndex;
260
261 slot = GetBattleObjectSlotFar(actorId);
263 groupIndex = 0;
264
265 while ((group = GetMotionRecordFar(slot->object, groupIndex)) != NULL) {
266 // The timer's low byte, read through memory as the original does.
267 if (timerSlot != -1) {
268 work->actorTimers[timerSlot] = ((u8 *)&timerFrames)[0];
269 }
270 if (slot->fading == 0) {
271 if (palette != -1) {
272 s32 partIndex;
273
274 partIndex = 0;
275 if (group->count != 0) {
276 struct AnimationEntry **parts;
277
278 parts = group->entries;
279 do {
280 struct AnimationEntry *part;
281
282 // Every part but the battler's effect and animation entries.
283 part = *parts++;
284 if (part != NULL &&
285 part != (struct AnimationEntry *)slot->effectEntry &&
286 part != (struct AnimationEntry *)slot->animationEntry) {
287 if (palette == 0)
288 part->param = BattleMotion_GetSlotPaletteFar(actorId);
289 else
290 part->param = palette;
291 part->frame = 0xff;
292 }
293 partIndex++;
294 } while (partIndex != group->count);
295 }
296 }
297 if (animation != -1)
298 AnimationObjects_SelectAnimationFar(group, animation);
299 }
300 groupIndex++;
301 }
302}
303
304/// Writes the tiled canvas tilemap for BG2 (priority 1), then closes the
305/// canvas layer again, which fades the background palette back in.
306///
307/// Nothing in The Broken Seal calls it; The Lost Age keeps it too.
311}
void BattleFx_RunAtalanta(struct BattleEffectArgument *effect)
Rain of blades: under a violet sky, a 3x3 formation of objects flies along a stored path while sixtee...
Definition atalanta.c:50
void BattleFx_RunBoreas(struct BattleEffectArgument *effect)
Rocks and ice blocks: a window opens on rocks that crumble, a big ice block drops and throws up spray...
Definition boreas.c:45
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_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_RunCybele(struct BattleEffectArgument *effect)
Thorn vines: thorns fly in from the right, vines grow out of the ground and lift the targets while sp...
Definition cybele.c:50
#define Dma_Fill32Cell(cell, value, destination, size)
Dma_Fill32 through the caller's own volatile word cell, so a function that fills several blocks keeps...
Definition dma.h:42
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 BattleFx_CallDoNothing(s32 count)
Calls the empty BattleFx_DoNothing count times, without waiting for a frame: a busy delay that change...
Definition dispatch.c:12
void BattleFx_RunTableEffect(struct BattleEffectArgument *effect)
Runs an ordinary battle effect: takes the effect's sheet, work and canvas, runs the entry of gBattleF...
Definition dispatch.c:112
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
void BattleFx_RunSceneEffect(struct BattleEffectArgument *effect)
Runs one of the large battle effects, the ones whose presentation flags have bit 15 set: takes the ef...
Definition dispatch.c:45
UNUSED void BattleFx_InitTilemapAndFlushQueue(void)
Writes the tiled canvas tilemap for BG2 (priority 1), then closes the canvas layer again,...
Definition dispatch.c:308
What every part of the battle effect object shares: its includes, macros and frame-loop helpers.
#define CANVAS_BYTES
The canvas: 128x128 pixels, one byte each, in its heap slot and in VRAM at BG_CHAR_BLOCK(1).
#define MOTE_SET_BYTES
The bytes of one set of the ten mote cells: 2 * (1 + 4 + ... + 100).
static void Dma_Stop(volatile u16 *channel)
Stops a DMA channel: clears its repeat and start timing bits, then its enable bit,...
#define EFFECT_DISPCNT
The battle screen's display mode while an effect plays: background mode 1 with BG0 to BG2,...
BattleFxHandler gBattleFx_EffectHandlers[BATTLE_FX_KIND_COUNT - 1]
The effect handlers, indexed by effect kind minus one, which BattleFx_RunTableEffect calls; kind zero...
void BattleFx_DoNothing(void)
Does nothing.
Definition eruption.c:242
s32 BattleMotion_GetSlotPaletteFar(s32 id)
struct BattleObj * GetBattleObjectSlotFar(s32 objectId)
Far call to BattleObjGet.
void BattleActor_SpawnObjectsForListFar(s16 *list, s32 refresh)
void * GetMotionRecordFar(struct MotionObject *object, s32 record_index)
void BattleBackground_LoadFar(s32 mode, s32 resource, s32 level)
s32 AnimationObjects_SelectAnimationFar(struct AnimationObject *state, s32 flags)
struct BattleUnit * UnitGetFar(u32 owner)
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
void * Runtime_AllocateHeapBlock(s32 kind, s32 size)
Returns heap slot kind's block, first allocating size bytes for it (rounded up to words),...
Definition heap.c:47
@ HEAP_SLOT_BATTLE_EFFECT
Definition heap_state.h:42
@ HEAP_SLOT_BATTLE_SHEET
Definition heap_state.h:44
@ 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
#define DMA_HBLANK_HALFWORD_PER_LINE
Definition io_reg.h:228
#define BLDCNT_TGT1_BG2
Definition io_reg.h:125
#define BG_CHAR_BLOCK(n)
Definition io_reg.h:166
#define REG_DMA0
Definition io_reg.h:151
#define REG_WIN0H
Definition io_reg.h:74
@ DISPCNT_MODE_1
BG0 and BG1 text, BG2 affine.
Definition io_reg.h:37
#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 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 BLDCNT_TGT1_BG1
Definition io_reg.h:124
#define REG_BLDALPHA
Definition io_reg.h:142
#define REG_BLDCNT
Definition io_reg.h:119
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
void BattleFx_RunKirin(struct BattleEffectArgument *effect)
Over a scrolling forest a row of objects rides in on a wave trailing fire, then sweeps across the tar...
Definition kirin.c:28
#define CLAMP(v, low, high)
Keeps v within low to high, the low bound tested first.
Definition macros.h:23
struct BgScroll gBgScroll[]
void Runtime_ReleaseHeapBlock(s32 slot)
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 BattleFx_RunNereid(struct BattleEffectArgument *effect)
A formation of twelve objects sweeps in among embers and columns of fire, and explodes.
Definition nereid.c:37
void BattleFx_RunMeteor(struct BattleEffectArgument *effect)
A formation rises out of a dissolving starfield and bursts into embers and flashes: the particle stre...
void BattleFx_RunProcne(struct BattleEffectArgument *effect)
A whirlwind lifts the targets, then comets from a block of objects in a violet sky strike them.
Definition procne.c:41
struct Projection gProjection
#define Ram_MapCellBuffer
Definition ram_buffer.h:10
void BattleFx_RunRamses(struct BattleEffectArgument *effect)
Over the desert backdrop a formation stands while an orb circles above it, drops three times throwing...
Definition ramses.c:36
#define NULL
Definition bilibin.h:6
void * gWorkSlot[]
One animation layer of a sprite: its animation id, frames, running script and timer.
Definition animspr.h:37
u8 param
SpriteColorMode its pixels are drawn with; 0 when taken.
Definition animspr.h:45
u8 frame
frame shown, frameBase plus the facing offset; 255 none
Definition animspr.h:53
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
struct AnimationEntry * entries[4]
its layers; empty ones null
Definition animspr.h:130
u8 count
layers in use, up to the last one present
Definition animspr.h:129
The command shared by an effect's caller, dispatcher and handlers.
s32 kind
handler table index; 200 more for a critical hit
s16 actors[8]
the targets' unit ids, count of them
s32 variant
the ability's size, from 0 (Quake, then Earthquake)
The running battle effect's work: its canvas image, 64 particles, the display registers it stages and...
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
A unit's place on the battlefield: its sprite object, resources and animations, its anchor spot and s...
struct SpriteEntry * effectEntry
the effect sprite, or NULL
struct MotionObject * object
NULL once released.
s16 fading
set while a fallen enemy's picture is being removed
struct SpriteEntry * animationEntry
the status icon's sprite, or NULL
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
struct BattleObj slots[14]
u16 palette[128]
the backdrop's colours, before scaling
u16 y
pixels
Definition map_scroll.h:65
s32 centerY
screen pixels
Definition project.h:17
void BattleFx_RunThor(struct BattleEffectArgument *effect)
The scene plays in two parts on the effect canvas.
Definition thor.c:68
void BattleFx_RunTiamat(struct BattleEffectArgument *effect)
The rising embers with a formation of eight objects that sweeps in and explodes at the end.
Definition tiamat.c:17
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
#define UNUSED
Definition types.h:22
unsigned char u8
Definition types.h:11
@ SCENE_EFFECT_BOREAS
BattleFx_RunBoreas (boreas.c).
Definition effect.h:26
@ SCENE_EFFECT_NEPTUNE
BattleFx_RunNeptune (neptune.c).
Definition effect.h:22
@ SCENE_EFFECT_JUDGMENT
BattleFx_RunJudgment (judgment.c).
Definition effect.h:25
@ SCENE_EFFECT_CYBELE
BattleFx_RunCybele (cybele.c).
Definition effect.h:21
@ SCENE_EFFECT_NEREID
BattleFx_RunNereid (nereid.c).
Definition effect.h:18
@ SCENE_EFFECT_THOR
BattleFx_RunThor (thor.c).
Definition effect.h:28
@ SCENE_EFFECT_TIAMAT
BattleFx_RunTiamat (tiamat.c).
Definition effect.h:23
@ SCENE_EFFECT_KIRIN
BattleFx_RunKirin (kirin.c).
Definition effect.h:19
@ SCENE_EFFECT_RAMSES
BattleFx_RunRamses (ramses.c).
Definition effect.h:17
@ SCENE_EFFECT_METEOR
BattleFx_RunMeteor (particle_streams.c).
Definition effect.h:27
@ SCENE_EFFECT_PROCNE
BattleFx_RunProcne (procne.c).
Definition effect.h:24
@ SCENE_EFFECT_ATALANTA
BattleFx_RunAtalanta (atalanta.c).
Definition effect.h:20