Alchemy
Loading...
Searching...
No Matches

procne.c

Go to the documentation of this file.
1/// @file
2/// The Procne summon.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7/// The whirlwind sheet holds three 48x64 frames, then the dust; the violet
8/// comets are decoded further on.
9#define PROCNE_DUST_CELLS (3 * (48 * 64))
10#define PROCNE_COMET_CELLS 0x3600
11
12/// A whirlwind lifts the targets, then comets from a block of objects in a
13/// violet sky strike them.
14///
15/// Abilities: Procne (scene kind 8).
16///
17/// 400 frames:
18/// 0 to 159 : a whirlwind rises over the field and lifts the targets,
19/// spinning them round it and drawing them in, while dust
20/// spirals up;
21/// 160 : the backdrop becomes the violet sky, and a 3x3 block of
22/// nine objects appears and sways;
23/// 256 to 329 : motes gather into the middle of the block;
24/// 330 to 372 : four comets shoot out of it, 12 frames apart, each with a
25/// ring of sparks, striking the targets on frames 334, 347,
26/// 359 and 372 (gProcne_Frames);
27/// 395 : the targets fall back to the ground.
28/// Pressing A or B skips to frame 160, or from there to frame 395. At the
29/// end the battle shows the damage and the targets go back to their places.
30///
31/// work->particles hold the dust (0 to 23 drawn), then from frame 160 the
32/// gathering motes (0 to 31), the comets' rings (32 to 59) and the four
33/// comets (60 to 63). PARTICLES 0 to 511 hold the sparks, 128 for each comet
34/// of which 96 are thrown. The scene moves the targets' objects (position,
35/// height, angle and gravity) and puts back their places and angles at the
36/// end; it loads the whirlwind's and then the comets' palette into the first
37/// 64 background colours, moves gProjection.centerX to 72 from frame 160 and
38/// back to 120, and sets work->shakeFrames on each comet. It spawns the nine
39/// objects of the block on frame 160 and releases them before closing the
40/// canvas.
42 static struct SpriteScale unitScale = {{{0x10000, 0x10000}}};
43 void **slots;
44 void *canvas;
45 struct BattleCamera *camera;
46 struct BattleEffectWork *work;
47 BlitterPair draw;
48 s32 frame;
49 u8 *graphics;
50 struct Point2D wave;
51 struct Point2D drift;
52 struct MotionObject *object;
53 struct BattleObj *battleObject;
54 struct EffectStep *point;
55 struct EffectStep *spark;
56 struct EffectStep *mark;
57 u8 *resource;
58 u8 *image;
59 s32 index;
60 s32 slot;
61 s32 size;
62 s32 span;
63 s32 dist;
64 s32 alive;
65 s32 width;
66 s32 heading[8];
67 s32 radius[8];
68 s32 spin[8];
69 struct Point2D home[8];
70 s32 baseAngle[8];
71 struct Vector3 world;
72 struct EffectPosition screen;
73 struct Vector3 depthOffset;
74 struct SpritePlacement place;
75 struct SpriteScale scale;
76
78 canvas = slots[0];
79 camera = CANVAS_SLOT(slots, HEAP_SLOT_CAMERA);
82 work->effect = effect;
83
89 draw[1] = (DrawRectangle)
91
93 Iwram_CopyWords((void *)BG_PLTT, resource, 0x80);
94 resource += 0x80;
95 Resource_DecodeType01(resource, work->sheet);
98
99 // Trails keep half of each pixel a frame.
101
102 // wave is where the block of objects sways, from (128, 40); drift is a
103 // push from each comet.
104 wave.x = 0x800000;
105 wave.y = 0x280000;
106 drift.x = 0;
107 drift.y = 0;
108
109 // Remember each target's place, and its heading and distance from the
110 // middle of the field for the whirlwind to turn.
111 EFFECT_FOR_EACH_TARGET(index, work->effect) {
112 battleObject = GetBattleObjectSlotFar(work->effect->actors[index]);
113 object = battleObject->object;
114 home[index].x = object->x;
115 home[index].y = object->z;
116 baseAngle[index] = object->angle;
117 heading[index] = (u16)ArcTan2(object->x, object->z);
118 radius[index] = Iwram_Sqrt((object->x >> 8) * (object->x >> 8) +
119 (object->z >> 8) * (object->z >> 8)) >>
120 7;
121 spin[index] = 0;
122 object->verticalMotionStrength = 0;
123 }
124
125 // The dust: each mote starts 120 out, after a random delay (variant). z
126 // is its distance from the whirlwind's axis; velocityY is its heading
127 // round the axis and, doubled, its rise; velocityX the turn added to it.
128 // The draw before the delay is discarded but still advances the random
129 // sequence.
130 index = 0;
131 do {
132 point = &work->particles[index];
133 point->z = 120;
134 point->y = 0;
135 Random16();
136 point->velocityY = 0;
137 point->velocityX = 0;
138 point->variant = Random16() & 63;
139 index++;
140 } while (index != 64);
141
142 width = 48;
143 frame = 0;
144 do {
145 // A or B skips ahead.
146 if ((gKeysRepeat & (KEY_A | KEY_B)) != 0) {
147 if (frame <= 159)
148 frame = 160;
149 else if (frame <= 394)
150 frame = 395;
151 }
152
154
155 if (frame == 16)
157 if (frame == 256)
159 if (frame == 334)
161 if (frame == 347)
163 if (frame == 359)
165 if (frame == 372)
167
168 // The targets, from 16i frames: spin faster round the middle and close
169 // in, rising quickly once near it, until frame 160; they keep turning
170 // until frame 490 (past the end), fall on frame 395 and flash on each
171 // comet strike.
172 EFFECT_FOR_EACH_TARGET(index, work->effect) {
173 if (frame > index * 16) {
174 battleObject = GetBattleObjectSlotFar(work->effect->actors[index]);
175 object = battleObject->object;
176 object->x = (radius[index] * Trig_Sin(heading[index])) >> 1;
177 object->z = (radius[index] * Trig_Cos(heading[index])) >> 1;
178
179 if (frame <= 159) {
180 if (frame > index * 16 + 16)
181 spin[index] += 48;
182 if (radius[index] <= 31)
183 object->y += 0x60000;
184 else
185 object->y += 0x8000;
186 if (object->y > 0x7c0000)
187 object->y = 0x7c0000;
188 }
189
190 if (frame <= 490) {
191 heading[index] += spin[index];
192 if (heading[index] > 0x10000)
193 heading[index] -= 0x10000;
194 object->angle += spin[index] / 4;
195 }
196
197 if (frame == 395)
198 object->verticalMotionStrength = 0xab85;
199
200 slot = 0;
201 do {
202 if (frame == gProcne_Frames[slot]) {
203 object->velocityY = 0;
206 8);
207 }
208 slot++;
209 } while (slot != 4);
210
211 if (radius[index] > 16)
212 radius[index] -= 2;
213 }
214 }
215
216 // The whirlwind: three 48x64 images in turn, growing up from the ground
217 // over frames 16 to 159 (its bottom rows first), a second section above
218 // it from frame 48, and both at full height from frame 160 to 399.
219 if ((u32)(frame - 16) <= 143) {
220 size = frame * 2 - 32;
221 if (size > 48)
222 size = 48;
223 draw[0](canvas,
224 &work->sheet[frame / 4 % 3 * (48 * 64) + (width - size) * 48], 32,
225 112 - size, width, size);
226 }
227
228 if ((u32)(frame - 48) <= 111) {
229 size = frame * 2 - 96;
230 if (size > 64)
231 size = 64;
232 draw[0](canvas,
233 &work->sheet[frame / 4 % 3 * (48 * 64) + (64 - size) * 48], 32,
234 64 - size, width, size);
235 }
236
237 if ((u32)(frame - 160) <= 239) {
238 image = work->sheet + frame / 4 % 3 * (48 * 64);
239 draw[0](canvas, image, 8, 0, width, 64);
240 draw[0](canvas, image, 8, 64, width, 64);
241 }
242
243 // The dust (24 motes): spiral in and up, starting again from the
244 // bottom when it passes 48 pixels up.
245 if (frame <= 159) {
246 index = 0;
247 point = work->particles;
248 do {
249 if (point[index].variant == 0) {
250 world.x = point[index].z * Trig_Sin(point[index].velocityY);
251 world.y = point[index].y;
252 world.z = point[index].z * Trig_Cos(point[index].velocityY);
253 EffectPosition_ProjectPoint(&world.x, &screen);
254 screen.x >>= 1;
255 if (point[index].y <= 0x3fffff) {
256 draw[0](canvas, work->sheet + PROCNE_DUST_CELLS, screen.x - 12,
257 screen.y - 12, 16, 16);
258 }
259 if (point[index].z > 24)
260 point[index].z -= 4;
261 point[index].velocityY += point[index].velocityX * 2;
262 if (point[index].velocityY > 0x10000)
263 point[index].velocityY -= 0x10000;
264 point[index].velocityX += 50;
265 if (point[index].velocityX > 4096)
266 point[index].velocityX = 4096;
267 point[index].velocityY += 2048;
268 point[index].y += point[index].velocityY * 2;
269 if (point[index].y > 0x300000) {
270 point[index].y = 0;
271 point[index].z = 100;
272 point[index].velocityY = 0;
273 point[index].velocityX = 0;
274 }
275 } else {
276 point[index].variant--;
277 }
278 index++;
279 } while (index != 24);
280 }
281
282 // Frame 160: the violet sky, the nine objects and the comet images; the
283 // sparks are cleared, the targets hang at random heights, the 32 motes
284 // that will gather are scattered round the block, and the targets
285 // settle into a tight, fast orbit.
286 if (frame == 160) {
287 s32 speed;
288 s32 angle;
289
294 BattleFx_SpawnObjects(9, 376, 2);
295
297 Iwram_CopyWords((void *)BG_PLTT, resource, 0x80);
298 resource += 0x80;
299 Resource_DecodeType01(resource, work->sheet + PROCNE_COMET_CELLS);
300
301 index = 0;
302 do {
303 PARTICLES[index].variant = 0;
304 index++;
305 } while (index != 512);
306
307 EFFECT_FOR_EACH_TARGET(index, work->effect) {
308 battleObject = GetBattleObjectSlotFar(work->effect->actors[index]);
309 object = battleObject->object;
310 object->y = ((Random16() & 15) + 8) << 16;
311 }
312
313 // The block and its comets are projected about a centre left of the
314 // screen's.
315 gProjection.centerX = 72;
316
317 index = 0;
318 do {
319 speed = Random16() & 127;
320 angle = (Random16() & 0x7fff) + 0x9fff;
321 work->particles[index].x = Trig_Sin(angle) * speed;
322 work->particles[index].y = Trig_Cos(angle) * speed;
323 work->particles[index].z = (Random16() % 200 - 100) << 16;
324 work->particles[index].variant = 0;
325 index++;
326 } while (index != 32);
327
328 EFFECT_FOR_EACH_TARGET(index, work->effect) {
329 radius[index] = 16;
330 spin[index] = 6000;
331 }
332 }
333
334 // From frame 160: sway the block of objects, faster for its first 64
335 // frames, plus what is left of each comet's push.
336 if (frame > 159) {
337 scale = unitScale;
338 size = 16;
339 if (frame - 160 <= 64)
340 size = 32;
341
342 wave.x -= (Trig_Sin((frame - 160) << 7) * 32) >> 6;
343 wave.y += (Trig_Sin((frame - 160) << 9) * size) >> 6;
344 wave.x += drift.x;
345 wave.y += drift.y;
346 drift.x /= 2;
347 drift.y /= 2;
348
349 scale.x = 0x10000;
350 scale.y = 0x10000;
351 place.groundHeight = 0;
352 index = 0;
353 do {
354 place.x = (gProcne_GridX[index] << 16) + wave.x + 0x280000;
355 place.height = 0xff0000 + index * 0x400000;
356 place.y = ((gProcne_GridY[index] + index * 64) << 16) + wave.y;
357 Object_ApplyProjectedPlacementFar(work->objects[index], &place, &scale,
358 0);
359 index++;
360 } while (index != 9);
361
362 // From frame 256 the motes, sparks and comets are drawn 256 pixels
363 // into the scene.
364 if (frame > 255) {
365 s32 threshold;
366
367 depthOffset.z = 0x1000000;
368 alive = 0;
369 depthOffset.x = 0;
370 depthOffset.y = 0;
373
374 // Frames 256 to 329: the motes close in on the middle of the
375 // block a pixel a frame; those that arrive swell one mote there.
376 if (frame <= 329) {
377 index = 0;
378 do {
379 s32 xx;
380 s32 yy;
381 s32 zz;
382
383 point = &work->particles[index];
384 xx = (point->x >> 8) * (point->x >> 8);
385 yy = (point->y >> 8) * (point->y >> 8);
386 zz = (point->z >> 8) * (point->z >> 8);
387 dist = Iwram_Sqrt(xx + yy + zz) >> 9;
388 if (dist != 0) {
389 EffectPosition_ProjectPoint(&point->x, &screen);
390 screen.x = (screen.x >> 17) + (wave.x >> 17) + 32;
391 screen.y = (screen.y >> 16) + (wave.y >> 16) - 4;
392 screen.depth >>= 16;
393 if (screen.depth <= 169)
394 screen.depth = 170;
395 if (screen.depth > 350)
396 screen.depth = 350;
397 span = 6 - (screen.depth - 170) / 36;
398 EFFECT_DRAW_MOTE(draw[1], canvas, graphics, screen.x, screen.y,
399 span);
400 point->x -= point->x / dist;
401 point->y -= point->y / dist;
402 point->z -= point->z / dist;
403 } else {
404 alive++;
405 }
406 index++;
407 } while (index != 32);
408
409 if (alive > 0) {
410 span = alive / 10 + 1;
411 draw[1](canvas, graphics + gBattleFx_MoteCells[span - 1],
412 (wave.x >> 17) - span / 2 + 32, (wave.y >> 16) - span - 4,
413 span, span * 2);
414 }
415 }
416
417 // Each strike throws out 96 sparks.
418 slot = 0;
419 do {
420 if (frame == gProcne_Frames[slot]) {
421 s32 speed;
422 s32 angle;
423
424 index = 0;
425 do {
426 speed = (Random16() & 127) + 16;
427 angle = Random16() & 0xffff;
428 spark = &PARTICLES[slot * 128 + index];
429 spark->velocityX = (Trig_Sin(angle) * speed) >> 6;
430 spark->velocityY = -(Trig_Cos(angle) * speed) >> 6;
431 // Each spark lives 64 to 79 frames in its comet's 128 map
432 // particles; the speed just set is overwritten at once.
433 spark->velocityY = ((Random16() & 255) - 128) << 10;
434 SET_POSITION(spark, 0, 0, 0);
435 spark->variant = (Random16() & 15) + 64;
436 index++;
437 } while (index != 96);
438 }
439
440 // Every live spark is drawn and moved once per comet slot, so the
441 // sparks step four times a frame; z moves by velocityY as y does.
442 if (frame >= gProcne_Frames[0]) {
443 spark = PARTICLES;
444 index = 0;
445 do {
446 if (spark[index].variant > 0) {
447 EffectPosition_ProjectPoint(&spark[index].x, &screen);
448 screen.x = (screen.x >> 17) + 32;
449 screen.y = (screen.y >> 16) + 56;
450 screen.depth >>= 16;
451 if (screen.depth <= 169)
452 screen.depth = 170;
453 if (screen.depth > 350)
454 screen.depth = 350;
455 span = 3 - (screen.depth - 170) / 90;
456 EFFECT_DRAW_MOTE(draw[0], canvas, graphics, screen.x, screen.y,
457 span);
458 spark[index].x += spark[index].velocityX;
459 spark[index].y += spark[index].velocityY;
460 spark[index].z += spark[index].velocityY;
461 spark[index].variant--;
462 }
463 index++;
464 } while (index != 512);
465 }
466 slot++;
467 } while (slot != 4);
468
469 // The four comets, from frame 330 + 12i: each leaves the middle of
470 // the block, flies down to the left growing through three images,
471 // and spreads a ring of 28 motes for 8 frames; it pushes the block
472 // and shakes the screen.
473 index = 0;
474 do {
475 mark = &work->particles[index + 60];
476 threshold = index * 12 + 330;
477 if (frame == threshold) {
478 mark->x = (wave.x >> 17) + 32;
479 mark->y = (wave.y >> 16) - 4;
480 mark->velocityX = (wave.x >> 17) + 32;
481 mark->velocityY = (wave.y >> 16) - 4;
482
483 slot = 0;
484 do {
485 work->particles[slot + 32].variant = 4;
486 slot++;
487 } while (slot != 28);
488
489 drift.x = 0x80000;
490 drift.y = -0x20000;
491 work->shakeFrames = 8;
492 }
493
494 if (frame >= threshold) {
495 s32 size;
496
497 size = (frame - threshold) / 2;
498 if (size > 2)
499 size = 2;
500 draw[1](canvas, work->sheet + gProcne_Cells[size], mark->x,
501 mark->y - gProcne_CellBiasY[size], gProcne_CellWidths[size],
502 gProcne_CellHeights[size]);
503 mark->x -= 8;
504 mark->y += 2;
505
506 if (frame < threshold + 8) {
507 // The ring is work->particles 32 to 59, each variant its radius,
508 // growing 2 a frame round where the comet left the block (kept
509 // in its mark's velocity); each comet turns the view further.
512
513 slot = 0;
514 spark = &work->particles[32];
515 do {
516 struct EffectStep *step;
517
518 step = &spark[slot];
519 world.x = 0;
520 world.y = step->variant * Trig_Cos(slot * 2340);
521 world.z = step->variant * Trig_Sin(slot * 2340);
522 step->variant += 2;
523 EffectPosition_ProjectPoint(&world.x, &screen);
524 screen.x =
525 (screen.x >> 17) + work->particles[index + 60].velocityX;
526 screen.y =
527 (screen.y >> 16) + work->particles[index + 60].velocityY;
528 screen.depth >>= 16;
529 if (screen.depth <= 169)
530 screen.depth = 170;
531 if (screen.depth > 350)
532 screen.depth = 350;
533 span = 3 - (screen.depth - 170) / 90;
534 EFFECT_DRAW_MOTE(draw[0], canvas, graphics, screen.x, screen.y,
535 span);
536 slot++;
537 } while (slot != 28);
538 }
539 }
540 index++;
541 } while (index != 4);
542 }
543 }
544
545 EFFECT_END_FRAME(work);
546 frame++;
547 } while (frame != 400);
548
549 // The end.
551
552 // Put the targets back.
553 EFFECT_FOR_EACH_TARGET(index, work->effect) {
554 struct MotionObject *obj;
555
556 battleObject = GetBattleObjectSlotFar(work->effect->actors[index]);
557 obj = battleObject->object;
558 obj->x = home[index].x;
559 obj->z = home[index].y;
560 obj->angle = baseAngle[index];
561 }
562
563 gProjection.centerX = 120;
564
566
567 index = 0;
568 do {
570 index++;
571 } while (index != 9);
572
574}
575
576#undef PROCNE_DUST_CELLS
577#undef PROCNE_COMET_CELLS
@ 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_BeginCanvasLayer(s32 bgControl)
Opens the canvas layer: starts the background palette fade, makes BG2 the canvas, alpha-blended over ...
Definition canvas.c:314
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_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_DRAW_MOTE(draw, canvas, sheet, x, y, size)
Particle sheets hold ten mote cells, 1x2 to 10x20 pixels.
@ CANVAS_COPY_AND_FADE
copy, keeping 50% or 75% (transferValue) of each pixel in the canvas for the next 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_START_TRANSFER(work, mode, value)
Sets the transfer, then starts copying the canvas to VRAM once a frame.
#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_END_FRAME(work)
The usual end of an effect frame: counts down the targets' flash timers (ObjectGroup_TickMemberTimers...
#define EFFECT_VIEW_FROM_CAMERA(camera)
Starts a frame's 3D projection from the battle camera: resets the transform, then looks from camera->...
u16 gBattleFx_MoteCells[]
Mote cells: particle sheets hold ten, cell n (from 0) n + 1 pixels wide and twice that tall.
u16 gProcne_Cells[]
u8 gProcne_GridY[]
u8 gProcne_GridX[]
u8 gProcne_CellWidths[]
u16 gProcne_Frames[]
u8 gProcne_CellBiasY[]
u8 gProcne_CellHeights[]
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 BattleBackground_LoadFar(s32 mode, s32 resource, s32 level)
void BattlePresentation_ConfigurePaletteFadeFar(s32 mode, s32 value, s32 fade)
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)
@ HEAP_SLOT_BATTLE_EFFECT
Definition heap_state.h:42
@ HEAP_SLOT_BLITTER_ALTERNATE
Definition heap_state.h:47
@ HEAP_SLOT_BATTLE_SHEET
Definition heap_state.h:44
@ HEAP_SLOT_CAMERA
Definition heap_state.h:38
@ HEAP_SLOT_BLITTER
Definition heap_state.h:46
@ HEAP_SLOT_BATTLE_CANVAS
Definition heap_state.h:43
@ KEY_B
Definition io_reg.h:244
@ KEY_A
Definition io_reg.h:243
#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
static s32 Iwram_Sqrt(s32 value)
Definition iwram_call.h:63
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
#define SET_POSITION(p, px, py, pz)
Sets the position or the velocity of a particle, a piece of debris or an object in one statement.
Definition macros.h:16
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
Definition math.c:10
s32 ArcTan2(s32 x, s32 y)
Returns the angle of the vector (x, y), in 1/65536 turns, measured from the y axis: 0 along +y,...
Definition math.c:36
s32 EffectPosition_ProjectPoint(const void *point, struct EffectPosition *position)
Projects a point in the current transform onto the screen, 16 pixels higher, and returns the projecti...
Definition positions.c:64
#define PROCNE_COMET_CELLS
Definition procne.c:10
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
#define PROCNE_DUST_CELLS
The whirlwind sheet holds three 48x64 frames, then the dust; the violet comets are decoded further on...
Definition procne.c:9
struct Projection gProjection
char ResourceId_VioletSkyBackdrop
char ResourceId_WhirlwindSheet
char ResourceId_ParticleSpritesA
char ResourceId_VioletCometSheet
s32 Resource_DecodeType01(const void *source, void *destination)
Decodes a type-01 resource and returns its unpacked byte count.
Definition decompress.c:31
#define SE_141
Definition songs.h:134
#define SE_212
Definition songs.h:207
#define SE_HEAVY_IMPACT
Definition songs.h:127
#define SE_140
Definition songs.h:133
void * gWorkSlot[]
The battle camera: its eye, the focus it turns about, and its pitch, yaw and distance.
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 frame
frame counter some effects keep, from 0
s32 shakeFrames
shake frames left; Camera_ApplyShake counts down
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
A unit's place on the battlefield: its sprite object, resources and animations, its anchor spot and s...
struct MotionObject * object
NULL once released.
A point projected onto the screen, with its depth.
Definition effect_step.h:46
s32 y
screen pixels
Definition effect_step.h:59
s32 depth
projected depth, larger further away
Definition effect_step.h:60
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
An effect object that moves and draws one sprite: its position, scale, velocity and target,...
Definition motobj.h:20
s32 z
16.16 fixed-point pixels
Definition motobj.h:25
s32 y
16.16 fixed-point pixels
Definition motobj.h:24
u16 angle
1/65536 turns
Definition motobj.h:22
s32 x
16.16 fixed-point pixels
Definition motobj.h:23
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
s32 centerX
screen pixels
Definition project.h:16
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.
Three coordinates, x, y and z: a position, a velocity or a direction.
Definition vector3.h:11
s32 z
Definition vector3.h:24
s32 x
Definition vector3.h:22
s32 y
Definition vector3.h:23
void * Resource_GetTableEntry(s32 index)
Returns the ROM address of resource index from the resource directory.
Definition system.c:150
void SceneTransform_ApplyYaw(s32 angle)
Rotates gTransform about the Y axis by angle.
Definition transform.c:113
void SceneTransform_ApplyPosition(const s32 *position)
Translates gTransform by position (x, y, z in 16.16).
Definition transform.c:145
void Render_ResetTransformState(void)
Allocates the one-level save area (heap slot HEAP_SLOT_TRANSFORM_STACK), clears gTransformStackDepth ...
Definition transform.c:19
void SceneTransform_ApplyRoll(s32 angle)
Rotates gTransform about the Z axis by angle.
Definition transform.c:129
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 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
static const s32 * Vector3_Coordinates(const struct Vector3 *vector)
Returns the vector's three coordinates as an array.
Definition vector3.h:31