17#define NEPTUNE_FLAME_GROUND 112
18#define NEPTUNE_OBJECTS 8
19#define NEPTUNE_PARTICLES 1024
20#define NEPTUNE_FLARE_SHEET 0x4e20
23#define NEPTUNE_LIGHT_CELLS 0x400
25#define NEPTUNE_FLAME_HEAD 0x6e8
52 static struct SpriteScale unitScale = {{{0x18000, 0x18000}}};
60 s32 formationVelocityX;
61 s32 formationVelocityZ;
83 canvas = (
void *)cache[0];
118 formationX = 140 << 17;
119 formationZ = 200 << 16;
120 formationVelocityX = -0x40000;
121 formationVelocityZ = -0x80000;
127 background->
busy = 1;
143 for (i = 0, flareSeed = work->
particles; i != 32; i++, flareSeed++) {
154 for (i = 0; i != 712; i++) {
185 if (frame >= 0 && frame < 16) {
190 for (k = 0; k != 128; k++) {
197 *phase += windowEdgeStep;
211 formationVelocityX = formationVelocityX * 60 / 64;
213 formationVelocityZ = formationVelocityZ * 60 / 64;
214 if (formationZ > 0x840000) {
215 formationVelocityZ -= 0x2000;
217 formationVelocityZ += 0x2000;
219 formationX += formationVelocityX;
220 formationZ += formationVelocityZ;
221 }
else if (frame <= 170) {
223 formationVelocityX += 0x2000;
225 formationVelocityX = formationVelocityX * 60 / 64;
226 formationX += formationVelocityX;
228 if (formationZ > 0x8a0000) {
229 formationVelocityZ -= 0x2000;
231 formationVelocityZ += 0x2000;
233 formationVelocityZ = formationVelocityZ * 56 / 64;
234 formationZ += formationVelocityZ;
274 if (t >= 0 && t < 88) {
275 for (i = 0, flare = work->
particles; i != 32; i++, flare++) {
276 if (frame >= i / 4 + 152 && frame < i / 4 + 152 + 32) {
284 fx - r, fy - r, s, s);
292 for (i = 0; i != 64; i++) {
299 if (burstSeed->
x < 0) {
304 if (burstSeed->
y < 0) {
312 burstSeed->
z = burstSeed->
x;
318 for (i = 0; i != 64; i++) {
323 if (frame >= i / 2 + 222) {
343 if (frame != 223 && frame != 224) {
350 for (i = 0; i != n; i++) {
370 if (t >= 0 && t < 40) {
378 108 - z, 60 - z, z * 2, z * 2);
380 if (frame >= 192 && frame < 200) {
382 z = (frame - 192) / 2 + 3;
388 108 - z, 60 - z, z * 2, z * 2);
399 108 - z, 60 - z, z * 2, z * 2);
407 100 - z, 52 - z, z * 2, z * 2);
410 if (frame >= 214 && frame < 222) {
412 z = (frame - 214) / 4;
421 z = (frame - 222) / 2 % 4 + 3;
450 for (i = 0; i != 5; i++) {
452 blit[1](canvas, work->sheet, i * 32 + ((frame / 4) & 31) - 32, 88, 32,
463 background->
busy = 0;
472 for (i = 0; i != 16; i++) {
496 for (i = 0; i != 5; i++) {
498 if (frame == i * 16 + 7) {
505 if (frame >= i * 16 && flameColumn->
variant <= 31) {
506 s32 wobble = frame * 16 % 104;
507 blit[1](canvas, work->sheet, flameColumn->
x - 8,
508 flameColumn->
y + wobble - 216, 17, 104);
509 blit[1](canvas, work->sheet, flameColumn->
x - 8,
510 flameColumn->
y + wobble - 112, 17, 104 - wobble);
512 flameColumn->
y - 65, 34, 65);
513 if (flameColumn->
y <= 111) {
514 flameColumn->
y += 16;
518 if (flameColumn->
y > 111) {
520 sparkOriginX = flameColumn->
x;
521 if (flameColumn->
variant <= 7) {
538 if (++emittedSparks == 4) {
548 if (frame == i * 16 + 8) {
574 }
while (++frame != 144);
583#undef NEPTUNE_FLAME_GROUND
584#undef NEPTUNE_OBJECTS
585#undef NEPTUNE_PARTICLES
586#undef NEPTUNE_FLARE_SHEET
587#undef NEPTUNE_LIGHT_CELLS
588#undef NEPTUNE_FLAME_HEAD
@ SPRITE_COLOR_WHITE
solid colour 15, white
@ POSE_DAMAGE
taking damage
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_ProcessPendingGraphicsTransfer(void)
Copies the canvas to VRAM once the effect has finished drawing a frame (transferPending): the 128x128...
void BattleFx_BeginCanvasLayer(s32 bgControl)
Opens the canvas layer: starts the background palette fade, makes BG2 the canvas, alpha-blended over ...
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...
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...
void BattleFx_ConfigureEffectDisplay(void)
Puts the battle screen back into the display state every effect starts from and ends with: no blendin...
void Resource_LoadAndDecompress(s32 id, void *dst, s32 skipPalette, s32 copyPalette)
Decompresses a resource whose first 128 bytes may be a palette.
void ObjectGroup_UpdateMembers(s32 actorId, s32 palette, s32 animation, s32 timerSlot, s32 timerFrames)
Updates every animation group of one battler's object.
void BattleFx_BuildWindowEdgeTable(void)
Builds window 0's right edge for every scanline and restarts the HBlank DMA that writes it to WIN0H e...
void BattleFx_SetupBlendedDisplay(void)
Shows the BG1 battle background behind a cleared canvas: clears the canvas buffer and the 16 KiB of V...
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...
What every part of the battle effect object shares: its includes, macros and frame-loop helpers.
#define EFFECT_SHOW_WIDE_CANVAS(top)
Shows the canvas: the effect display mode, BG2 stretched to twice its width (the 128-pixel canvas sho...
#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,...
#define EFFECT_SET_TRANSFER(work, mode, value)
Sets how the canvas transfer treats what is left in the canvas after each copy: mode with value (see ...
@ CANVAS_COPY
copy as drawn
@ CANVAS_COPY_AND_FADE
copy, keeping 50% or 75% (transferValue) of each pixel in the canvas for the next frame
#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_SHOW_DAMAGE(hitSound)
Lets the battle show the damage: resumes its paused playback, which plays hitSound (an SE_ id; 0 keep...
#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_WIN0_LAYERS
Window 0, the battle view, shows BG0 to BG2, sprites and blending.
#define EFFECT_END_FRAME(work)
The usual end of an effect frame: counts down the targets' flash timers (ObjectGroup_TickMemberTimers...
u16 gBattleFx_FlareCells[]
Flare cells: the first ten are squares 2x2 to 20x20, cell n (from 0) n + 1 pixels from its centre to ...
s32 gNeptune_Gravity[]
Spray gravity, by particle index & 3.
void BattleFx_SpawnObjects(s32 entryCount, s32 source, u32 priority)
Creates the effect's animation objects in gBattleFxWork's objects.
void BattleMotion_ApplyVariantMotionFar(s32 id, s32 variant)
void BattleBackground_LoadFar(s32 mode, s32 resource, s32 level)
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)
void Runtime_SetIrqHandler(u32 irq, s32 vcount, InterruptHandler handler)
Installs handler for interrupt irq and enables that interrupt, or with a null handler disables it and...
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
void Camera_ApplyShake(s32 rangeX, u32 rangeY)
Shakes the battle view while gBattleFxWork's shakeFrames lasts, moving BG1 and the projection centre ...
@ HEAP_SLOT_BATTLE_EFFECT
@ HEAP_SLOT_BLITTER_ALTERNATE
@ HEAP_SLOT_BATTLE_BACKGROUND
@ HEAP_SLOT_BATTLE_CANVAS
#define Q_8_8(n)
The BG2/BG3 affine matrix entries are signed 8.8 fixed point: texels stepped per screen pixel.
#define BGCNT_CHAR_BASE(block)
#define BGCNT_PRIORITY(n)
#define BLEND_ALPHA(top, bottom)
A REG_BLDALPHA value: top and bottom are the two targets' weights, out of 16.
#define BGCNT_SCREEN_BASE(block)
#define WIN_RANGE(start, end)
A REG_WINxH or REG_WINxV value: the window covers start up to, but not including, end.
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),...
void BattleFx_RunNeptune(struct BattleEffectArgument *effect)
Over dusk clouds a formation of objects flies in through rising spray, gathers a ring of flares into ...
void Graphics_ResetBg2Pa(void)
Sets BG2's horizontal scale back to one texel a pixel, for the lines above Graphics_SetBg2AffineScale...
void Graphics_SetBg2AffineScaleHalf(void)
Stretches BG2 to twice its width from the current line down.
#define NEPTUNE_PARTICLES
PARTICLES slots: spray, then sparks.
#define NEPTUNE_LIGHT_CELLS
The 48x48 light pictures (9 * 256 bytes each), after the spray sheet's 32x32 spray picture.
#define NEPTUNE_FLAME_HEAD
The blue flame column's 34x65 head, after its 17x104 shaft.
#define NEPTUNE_OBJECTS
objects in the formation
#define NEPTUNE_FLARE_SHEET
the flare pictures, after the spray
#define NEPTUNE_FLAME_GROUND
where the blue flames throw sparks
void EffectPosition_ProjectScaledBattler(s32 id, struct EffectPosition *position)
The screen position of a battler, scaled for the battle view, 16 pixels higher.
void EffectStep_AdvanceWithGravity2D(struct EffectStep *step, s32 damping, s32 gravity)
Moves a particle one frame on the screen: adds its velocity, then gravity to its vertical speed,...
struct Projection gProjection
#define Ram_MapCellBuffer
char ResourceId_ParticleSpritesD
char ResourceId_DuskCloudsBackdrop
char ResourceId_WaterSpraySheet
char ResourceId_BlueFlameSheet
char ResourceId_ParticleSpritesA
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...
s32 Scheduler_RemoveCallback(SchedulerCallback callback)
Unschedules the task running callback: clears its routine and gives it order 0x7fff,...
The battle background's work slot as the background code reads it: its display mode (2 draws it as an...
s32 busy
while set, BattleCamera_SetRange leaves BG1's scroll
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 fadeFrames
backdrop fade frames left (Palette_StepFadeTransfer)
s32 frame
frame counter some effects keep, from 0
s32 fadeStep
CANVAS_FADE_STEPs the backdrop has darkened so far.
s32 shakeFrames
shake frames left; Camera_ApplyShake counts down
struct AnimationObject * objects[16]
the effect's animation objects
s32 transferMode
How the canvas transfer callbacks treat the canvas after each copy (enum CanvasTransferMode in effect...
struct BattleEffectArgument * effect
the command being run
struct EffectStep particles[64]
free while variant is -1
A point projected onto the screen, with its depth.
A moving point of an effect: its position, its velocity and a value each effect uses its own way (a s...
s32 velocityX
16.16 fixed-point pixels per frame
s32 z
16.16 fixed-point pixels
s32 variant
each effect's own: a size, a countdown, -1 for idle
s32 x
16.16 fixed-point pixels
s32 y
16.16 fixed-point pixels
s32 velocityY
16.16 fixed-point pixels per frame
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.
#define EFFECT_CLIP_BOUNDS
Clips overflow on all four sides.
#define Q_16_16_TO_INT(v)
#define PARTICLES
The map cell buffer (gMapCellBuffer), which the effects borrow, has two views here: Ram_MapCellBuffer...