Alchemy
Loading...
Searching...
No Matches

nereid.c

Go to the documentation of this file.
1/// @file
2/// The Nereid summon.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7// Nereid's embers burst from one point, fall back under gravity, and from
8// frame 80 rise away; one that falls below the band goes out and its slot
9// is lit again. The Titan Blade (titan_blade.c) throws its dust the same
10// way.
11
12#define NEREID_FRAMES 124
13
14#define NEREID_OBJECTS 12 ///< objects in the sweeping formation
15#define NEREID_COLUMNS 3 ///< wrapping columns of fire
16#define NEREID_EMBERS 1024 ///< embers in PARTICLES
17#define NEREID_COLUMN_IMAGE 0x6e4 ///< the column of fire in the sheet
18
19/// A formation of twelve objects sweeps in among embers and columns of fire,
20/// and explodes.
21///
22/// Abilities: Nereid (scene kind 2).
23///
24/// 124 frames; pressing A
25/// or B during frames 33 to 97 skips to frame 98. A formation of twelve
26/// objects sweeps in from the right; embers burst up on frame 28 and over
27/// frames 32 to 79, fall back under gravity and from frame 80 rise away,
28/// while three columns of fire stream upwards over frames 32 to 79 and the
29/// targets bounce. At the end the formation explodes with
30/// BattleFx_RunImpactBurst; the battle shows the damage on frame 120.
31///
32/// The embers are PARTICLES 0 to 1023, canvas pixels in 16.16, a variant of
33/// -1 marking an idle one. Loads the water spray palette into the first 64
34/// background colours, sets REG_BLDALPHA, spawns the twelve formation objects
35/// (released at the end) and gives the targets an upward speed and the usual
36/// battle gravity at each bounce.
38 BlitterPair draw;
39 void **cursor;
40 void *canvas;
41 struct BattleEffectWork *work;
42 u8 *graphics;
43 u8 *palette;
44
46 canvas = cursor[0];
49 work->effect = effect;
51 REG_BLDALPHA = BLEND_ALPHA(16, 16);
53
54 // The band along the bottom from WaterSpray, the columns from FirePillarA
55 // (at sheet + 0x6e4).
57 Iwram_CopyWords((void *)BG_PLTT, palette, 128);
58 palette += 128;
59 Resource_DecodeType01(palette, work->sheet);
61 palette += 128;
62 Resource_DecodeType01(palette, work->sheet + NEREID_COLUMN_IMAGE);
65 // Trails keep 75% of each pixel a frame.
67 {
68 struct Point2D focus;
69 struct Point2D velocity;
70 s32 rise;
71 s32 frame;
72 s32 k;
73 struct EffectStep *point;
74 struct EffectStep *spark;
75 struct EffectStep *sparks;
76 s32 *life;
77
78 // The formation comes in from (256, 88), heading left.
79 rise = 0;
80 focus.x = 256 << 16;
81 focus.y = 88 << 16;
82 velocity.x = -(16 << 16);
83 velocity.y = -(4 << 16);
84 // work->particles 24 to 39 are given a place and a delay that nothing in
85 // the scene reads again.
86 EFFECT_FREE_PARTICLES(k, work->particles, 64);
87 for (k = 0; k != 16; k++) {
88 point = &work->particles[24 + k];
89 point->x = Random16() & 127;
90 point->y = (Random16() & 7) + 56;
91 point->variant = -(Random16() & 15);
92 }
93 life = &PARTICLES->variant;
94 for (k = 0; k != NEREID_EMBERS; k++) {
95 *life = -1;
96 life += 7; // sizeof(struct EffectStep) / 4
97 }
98 sparks = PARTICLES;
100 WaitFrames(1);
102
103 for (frame = 0; frame != NEREID_FRAMES; frame++) {
104 if ((gKeysRepeat & (KEY_A | KEY_B)) && frame > 32 && frame <= 97)
105 frame = 98;
106 if (frame == 120)
108 // The band rises 2 pixels a frame for the first 16 frames.
109 if (frame <= 15)
110 rise += 2;
111
112 // The formation slows to 58/64 of its speed across and 56/64 down
113 // each frame, and is pushed back right when left of x 120.
114 if (frame <= 99) {
115 focus.x += velocity.x;
116 focus.y += velocity.y;
117 velocity.x = velocity.x * 58 / 64;
118 velocity.y = velocity.y * 56 / 64;
119 if (focus.x < 120 << 16)
120 velocity.x += 0x8000;
121 }
122 BattleFx_PlaceFormationObjects(1, focus.x, focus.y);
123
124 // Embers burst up from an oval around (32, 96), twice as tall as wide,
125 // with a random spread: every idle one of the first 256 on frame 28,
126 // then up to 16 a frame over frames 32 to 79.
127 if (frame == 28) {
128 for (k = 0; k != 256; k++) {
129 spark = &sparks[k];
130 if (spark->variant == -1) {
131 s32 radius = Random16() & 63;
132 s32 angle = Random16() & 0xffff;
133
134 spark->x = ((Trig_Sin(angle) * radius) >> 3) + (32 << 16);
135 spark->y = ((Trig_Cos(angle) * radius) >> 2) + (96 << 16);
136 spark->velocityX = ((Random16() & 63) - 32) << 14;
137 spark->velocityY = (-(Random16() & 63) - 8) << 13;
138 spark->variant = 0;
139 }
140 }
141 }
142 if (frame >= 32 && frame < 80) {
143 s32 spawned = 0;
144
145 for (k = 0; k != NEREID_EMBERS; k++) {
146 spark = &sparks[k];
147 if (spark->variant == -1) {
148 s32 radius = Random16() & 63;
149 s32 angle = Random16() & 0xffff;
150
151 spark->x = ((Trig_Sin(angle) * radius) >> 3) + (32 << 16);
152 spark->y = ((Trig_Cos(angle) * radius) >> 2) + (96 << 16);
153 spark->velocityX = ((Random16() & 63) - 32) << 14;
154 spark->velocityY = (-(Random16() & 63) - 8) << 13;
155 spark->variant = 0;
156 spawned++;
157 if (spawned == 16)
158 break;
159 }
160 }
161 }
162 if (frame == 0)
164 if (frame == 32)
166 if (frame == 80)
168
169 // The columns: a 104-pixel image scrolling up 16 pixels a frame,
170 // drawn twice to wrap round.
171 if (frame >= 32 && frame < 80) {
172 for (k = 0; k != NEREID_COLUMNS; k++) {
173 s32 span = (frame * 16 - 256 + k * 25) % 104;
174
175 draw[0](canvas, work->sheet + NEREID_COLUMN_IMAGE,
177 gNereid_Columns[k][NEREID_COLUMN_Y] - span - 104, 34, 104);
178 draw[0](canvas, work->sheet + NEREID_COLUMN_IMAGE,
180 gNereid_Columns[k][NEREID_COLUMN_Y] - span, 34, span);
181 }
182 }
183
184 // The band along the bottom: five 32x32 images that rise 32 pixels
185 // over the first 16 frames and drift right.
186 if (frame <= 95) {
187 for (k = 0; k != 5; k++)
188 draw[0](canvas, work->sheet, k * 32 + ((frame / 4) & 31) - 32,
189 120 - rise, 32, 32);
190 }
191
192 // Embers: 2 to 4 pixels by index, 2 more while falling, swelling to 10
193 // over frames 69 to 77 as they clear; those falling are drawn
194 // additively. Until frame 80 they fall under gNereid_Gravity, then
195 // speed upwards; they slow to 62/64 a frame, and go out when they fall
196 // below y 104.
197 for (k = 0; k != NEREID_EMBERS; k++) {
198 spark = &sparks[k];
199 if (spark->variant >= 0) {
200 s32 size = k % 3 + 2;
201
202 if (spark->velocityY > 0)
203 size += 2;
204 if (frame > 68 && size <= 5)
205 size = 6;
206 if (frame > 70 && size <= 6)
207 size = 7;
208 if (frame > 72 && size <= 7)
209 size = 8;
210 if (frame > 74 && size <= 8)
211 size = 9;
212 if (frame > 76)
213 size = 10;
214 EFFECT_DRAW_MOTE(draw[spark->velocityY > 0], canvas, graphics,
215 Q_16_16_TO_INT(spark->x), Q_16_16_TO_INT(spark->y),
216 size);
217 spark->x += spark->velocityX;
218 spark->y += spark->velocityY;
219 if (frame > 80)
220 spark->velocityY += -0x8000;
221 else
222 spark->velocityY += gNereid_Gravity[k & 3];
223 spark->velocityX = spark->velocityX * 62 / 64;
224 spark->velocityY = spark->velocityY * 62 / 64;
225 spark->variant++;
226 if (spark->velocityY > 0 && Q_16_16_TO_INT(spark->y) > 104)
227 spark->variant = -1;
228 }
229 }
230
231 // The targets bounce and flash white on frames 36, 48, 60 and 72,
232 // getting their colours back 6 frames later.
233 if (frame <= 79) {
235 if (frame > 29) {
236 s32 phase = frame % 12;
237
238 if (phase == 0) {
239 struct MotionObject *obj =
241
244 obj->velocityY = 0x48000;
245 obj->verticalMotionStrength = 0xab85;
246 }
247 if (phase == 6)
249 -1, 0);
250 }
251 }
252 }
254 }
255
256 // The impact burst builds its own blitters and transfer.
259 BattleFx_RunImpactBurst(1, focus.x, focus.y);
260 for (k = 0; k != NEREID_OBJECTS; k++)
262 }
264}
265
266#undef NEREID_FRAMES
267#undef NEREID_OBJECTS
268#undef NEREID_COLUMNS
269#undef NEREID_EMBERS
270#undef NEREID_COLUMN_IMAGE
@ SPRITE_COLOR_WHITE
solid colour 15, white
Definition animspr.h:26
@ POSE_DAMAGE
taking damage
Definition battle.h:176
#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_EndCanvasLayer(void)
Closes the canvas layer: plays the closing sound, restores BG1's scroll and the projection centre,...
Definition canvas.c:490
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_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_RELEASE_BLITTERS()
Frees the two blitters, the alternate first.
#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,...
@ CANVAS_COPY_AND_FADE
copy, keeping 50% or 75% (transferValue) of each pixel in the canvas for the next frame
#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_START_TRANSFER(work, mode, value)
Sets the transfer, then starts copying the canvas to VRAM once a frame.
#define EFFECT_FREE_PARTICLES(i, particles, count)
Marks particles[0] to particles[count - 1] free: a particle whose variant is -1 is not drawn or moved...
s32 gNereid_Gravity[]
Ember gravity while falling, by ember index & 3.
u8 gNereid_Columns[][2]
Nereid's four columns of fire (NEREID_COLUMN_X, NEREID_COLUMN_Y).
@ NEREID_COLUMN_Y
canvas y of its foot
@ NEREID_COLUMN_X
canvas x of the column's middle
void BattleFx_SpawnObjects(s32 entryCount, s32 source, u32 priority)
Creates the effect's animation objects in gBattleFxWork's objects.
Definition eruption.c:220
struct BattleObj * GetBattleObjectSlotFar(s32 objectId)
Far call to BattleObjGet.
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_BATTLE_SHEET
Definition heap_state.h:44
@ HEAP_SLOT_BATTLE_CANVAS
Definition heap_state.h:43
void BattleFx_RunImpactBurst(s32 formation, s32 x, s32 y)
Opens an impact flash and scatters sparks and fragments, keeping the effect's objects in formation fo...
void BattleFx_PlaceFormationObjects(s32 formation, s32 x, s32 z)
Arranges work->objects in a formation; x and z are its origin in 16.16 pixels.
@ KEY_B
Definition io_reg.h:244
@ KEY_A
Definition io_reg.h:243
#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 REG_BLDALPHA
Definition io_reg.h:142
#define BG_PLTT
Definition io_reg.h:157
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
Definition iwram_call.h:85
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
Definition math.c:10
void BattleFx_FetchRectangleBlitters(s32 flip, BlitterPair out)
Builds the two usual routines that draw onto the 128x128 canvas, both clipped on both axes.
#define NEREID_EMBERS
embers in PARTICLES
Definition nereid.c:16
#define NEREID_FRAMES
Definition nereid.c:12
#define NEREID_COLUMN_IMAGE
the column of fire in the sheet
Definition nereid.c:17
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
#define NEREID_COLUMNS
wrapping columns of fire
Definition nereid.c:15
#define NEREID_OBJECTS
objects in the sweeping formation
Definition nereid.c:14
char ResourceId_FirePillarSheetA
char ResourceId_WaterSpraySheet
char ResourceId_ParticleSpritesA
s32 Resource_DecodeType01(const void *source, void *destination)
Decodes a type-01 resource and returns its unpacked byte count.
Definition decompress.c:31
s32 Scheduler_RemoveCallback(SchedulerCallback callback)
Unschedules the task running callback: clears its routine and gives it order 0x7fff,...
Definition scheduler.c:146
#define SE_144
Definition songs.h:137
#define SE_164
Definition songs.h:159
#define SE_HEAVY_IMPACT
Definition songs.h:127
#define SE_145
Definition songs.h:138
void * gWorkSlot[]
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...
struct AnimationObject * objects[16]
the effect's animation objects
struct BattleEffectArgument * effect
the command being run
struct EffectStep particles[64]
free while variant is -1
struct MotionObject * object
NULL once released.
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 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
An effect object that moves and draws one sprite: its position, scale, velocity and target,...
Definition motobj.h:20
s32 velocityY
16.16 fixed-point pixels per frame
Definition motobj.h:32
s32 verticalMotionStrength
Gravity: taken from velocityY each frame above the ground with motionFlags bit 1, in 16....
Definition motobj.h:48
Two-dimensional {x, y} pair for position or velocity, a local of the summon scenes (Nereid,...
Definition effect.h:236
s32 y
16.16 pixels
Definition effect.h:238
s32 x
16.16 pixels in every scene that uses it
Definition effect.h:237
void * Resource_GetTableEntry(s32 index)
Returns the ROM address of resource index from the resource directory.
Definition system.c:150
signed int s32
Definition types.h:14
unsigned char u8
Definition types.h:11
#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
DrawRectangle BlitterPair[2]
A blitter pair: [0] built in HEAP_SLOT_BLITTER and [1] in HEAP_SLOT_BLITTER_ALTERNATE (BattleFx_Fetch...
Definition effect.h:244