16 for (i = 0; i != 63; i++) {
17 s32 blue = (*color >> 10) & 0x1f;
18 s32 green = (*color >> 5) & 0x1f;
19 s32 red = *color & 0x1f;
30 *color++ =
RGB(red, green, blue);
47 (
volatile u32 *)channel);
68#define PARTICLE_STREAMS_EMBERS (&PARTICLES[128])
70#define PARTICLE_STREAMS_RISE_FRAMES 192
71#define PARTICLE_STREAMS_BURST_FRAMES 54
74#define PARTICLE_STREAMS_MOTE_CELLS 0x3200
105 void *colors = (
void *)
BG_PLTT;
109 void ParticleStreams_SpawnFlame(
s32 x,
s32 y,
s32 velocityX) {
112 for (i = 0; i != 16; i++) {
130 for (i = 0; i != 32; i++) {
162 if (direction == 1) {
167 object->verticalMotionStrength = 0x91eb;
170 direction = work->
effect->
side == 1 ? mode : -1;
185 for (i = 0; i != 2; i++) {
217 for (i = 0; i != 63; i++) {
226 for (i = 0; i != 256; i++) {
231 ((
u8 *)canvas)[((y / 8 * 16 + x / 8) * 8 + (y & 7)) * 8 + (x & 7)] = shade;
248 for (i = 0; i != 128; i++)
258 for (; row != limit; row++) {
261 for (x = 0; x != 256; x++) {
262 s32 y = row - offsets[x & 127];
271 }
while (limit <= 191);
301 s32 angle = frame << 8;
305 register s32 count
asm(
"r2") = work->
frame;
308 register u8 *base
asm(
"r0") = (
u8 *)work;
309 s32 heat = count / 4;
318 asm(
"" :
"=r"(base) :
"0"(base),
"r"(count));
319 line = (
u16 *)(base + 0x1f80);
333 asm(
"" :
"=r"(hold));
339 asm(
"" : :
"r"(hold));
345 for (i = 0; i != 15; i++)
347 for (; i != 135; i++) {
355 register s32 level
asm(
"r2");
366 *line++ =
RGB(green >> 1, green, blue);
368 for (; i != 160; i++)
378 position.
height = 0xff0000;
380 size = angle + 0xa000;
383 position.
x = (x << 16) + 0x500000;
384 position.
y = (64 - y) << 16;
390 size = angle + 0x10000;
393 position.
x = (x << 16) + 0x600000;
394 position.
y = (96 - y) << 16;
400 for (i = 0, y = 32 - y; i != 32; i++) {
401 struct EffectStep *mote = &work->particles[i];
407 mote->
x = ((
x + 96) << 16) +
Trig_Sin(angle) * 30 / 65536 * size;
408 mote->
y = (
y << 16) -
Trig_Cos(angle) * 30 / 65536 * size;
416 point.
depth = 0x2000000;
421 for (i = 0; i != 7; i++) {
429 screenPosition->
y - 4, 8, 8);
438 for (i = 0; i != 7; i++) {
445 ParticleStreams_SpawnFlame(
448 for (i = 0; i != 32; i++) {
449 struct EffectStep *mote = &work->particles[i];
457 mote->
x -= direction * 0x14000;
491 for (i = 0; i != 32; i++) {
497 for (i = 0; i != 128; i++) {
505 for (i = 0; i != 512; i++) {
519 s32 size = (frame + 0x1d0) << 8;
521 s32 elapsed = frame - 16;
542 for (i = 0; i != 64; i++) {
552 if (point.
depth <= 159)
554 if (point.
depth > 799)
556 size = 9 - (point.
depth - 160) / 64;
561 point.
x - size / 2, point.
y - size, size, size * 2);
563 if (ember->
y <= 0x140000) {
572 for (i = 0; i != 64; i++) {
583 mote->
x - size / 2, mote->
y - size, size, size * 2);
584 mote->
y = mote->
y - rise - 8;
588 for (i = 0; i != 64; i++) {
594 if (i / 3 < elapsed && flash->
y >= 0) {
610 flash->
z = ((
Random16() & 255) - 127) << 16;
623 grow = (frame << 8) + 0x20000;
625 position.
height = 0xff0000;
629 position.
x = (
x << 16) + 0x600000;
630 position.
y = (96 -
y) << 16;
636 position.
x = (
x << 16) + 0x600000;
637 position.
y = (96 -
y) << 16;
651#undef PARTICLE_STREAMS_EMBERS
652#undef PARTICLE_STREAMS_RISE_FRAMES
653#undef PARTICLE_STREAMS_BURST_FRAMES
654#undef PARTICLE_STREAMS_MOTE_CELLS
struct BattleCamera * gCameraWork
BattleEffectDrawRectangle DrawRectangle
s32 BattleFx_BuildBlitter(s32 slot, s32 widthShift, s32 heightShift, s32 flags, u32 mode)
Writes a drawing routine for the canvas into heap slot slot, built from the template BattleFx_Composi...
void BattleFx_ProcessPendingGraphicsTransfer(void)
Copies the canvas to VRAM once the effect has finished drawing a frame (transferPending): the 128x128...
void BattleFx_EndCanvasLayer(void)
Closes the canvas layer: plays the closing sound, restores BG1's scroll and the projection centre,...
void BattleFx_FlushPendingGraphicsTransfer(void)
Copies a full-screen picture to VRAM once the effect has finished drawing a frame: the 0x7800 bytes o...
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 BattleFx_AdvanceBg2OnInterval(void)
Slides the affine BG2 in steps: once every scrollInterval frames, writes the work block's reference p...
void Resource_LoadAndDecompress(s32 id, void *dst, s32 skipPalette, s32 copyPalette)
Decompresses a resource whose first 128 bytes may be a palette.
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...
void ObjectGroup_UpdateMembers(s32 actorId, s32 palette, s32 animation, s32 timerSlot, s32 timerFrames)
Updates every animation group of one battler's object.
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_PRESENT_FRAME(work)
Ends a frame of a canvas effect: marks the canvas ready for the transfer callback,...
#define DMA_FILL_WORDS(n)
DMA control word that fills n words from one fixed source word.
#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_CLEAR
copy, then fill the canvas with transferValue
@ CANVAS_COPY_AND_DARKEN
copy, then darken the canvas by transferValue
#define CANVAS_BYTES
The canvas: 128x128 pixels, one byte each, in its heap slot and in VRAM at BG_CHAR_BLOCK(1).
#define EFFECT_CALLBACK_ORDER
The scheduler order of every per-frame effect callback (Scheduler_AddOrUpdateCallback sorts the frame...
#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_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...
#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 EFFECT_VIEW_FROM_CAMERA(camera)
Starts a frame's 3D projection from the battle camera: resets the transform, then looks from camera->...
#define EFFECT_BEGIN_NARROW_CANVAS(bgControl)
Opens the canvas layer at the canvas's own width, one texel per pixel, where BattleFx_BeginCanvasLaye...
static s32 * EffectPosition_Coordinates(struct EffectPosition *position)
Returns the position's three coordinates as an array.
s16 gParticleStreams_DropPoints[][2]
Where the seven drops fall, in pixels.
u16 gParticleStreams_FlashCells[]
s16 gParticleStreams_OrbitPoints[][3]
The seven sparks that orbit the rising formation.
u16 gBattleFx_MoteCells[]
Mote cells: particle sheets hold ten, cell n (from 0) n + 1 pixels wide and twice that tall.
u16 gParticleStreams_FlashSizes[]
void BattleFx_SpawnObjects(s32 entryCount, s32 source, u32 priority)
Creates the effect's animation objects in gBattleFxWork's objects.
struct BattleObj * GetBattleObjectSlotFar(s32 objectId)
Far call to BattleObjGet.
void BattleActor_CommitPlacementFar(void)
Far call to BattleObjPut.
s32 AnimationObjects_SelectAnimationFar(struct AnimationObject *state, s32 flags)
struct AnimationObject * ResourceObject_CreateFar(s32 id)
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 WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
#define SPRITE_SECOND_PART
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_BATTLE_BACKGROUND
#define WORK_SLOT(n)
Reads slots through their own addresses; adjacent slots are reached by offsets.
#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 DMA_HBLANK_HALFWORD_PER_LINE
#define RGB(r, g, b)
A 15-bit colour from its red, green and blue levels (0 to 31 each), as the palette stores it: blue in...
#define BLDCNT_EFFECT_BLEND
weighted by REG_BLDALPHA
#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 BG_PLTT_COLOR(palette, color)
#define BGCNT_WRAP
Affine backgrounds only: wrap around instead of showing the backdrop.
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
#define SET_VELOCITY(p, vx, vy, vz)
#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.
#define SET_VECTOR(v, x, y, z)
Sets the x, y and z of a three-part vector: a position about to be projected, a per-frame step,...
#define CLAMP(v, low, high)
Keeps v within low to high, the low bound tested first.
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
void Runtime_ReleaseHeapBlock(s32 slot)
#define PARTICLE_STREAMS_EMBERS
The burst's embers, 512 in PARTICLES after its 128 flashes.
#define PARTICLE_STREAMS_BURST_FRAMES
frames of the burst
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_RunOuterSpace(struct BattleEffectArgument *effect)
The user leaps up, and two objects rise out of a dissolving starfield and burst into embers and flash...
#define PARTICLE_STREAMS_RISE_FRAMES
frames, at most, of the rise
#define PARTICLE_STREAMS_MOTE_CELLS
The mote pictures in the sheet: two sets, MOTE_SET_BYTES apart.
void BattleFx_ArmPaletteHBlankDma(void)
Arms DMA 0 to write one halfword of the table at work->sheet + 0x1f80 into background colour 0 at eac...
void BattleFx_RunParticleStreams(struct BattleEffectArgument *effect, s32 mode)
The stream runs in two halves.
void Palette_BrightenBgEntries(s32 blueStep, s32 greenStep, s32 redStep)
Adds per-channel steps to background colours 1 to 63, capped at 31.
void EffectStep_AdvanceWithGravity3D(struct EffectStep *step, s32 damping, s32 gravity)
Moves a particle one frame in three dimensions: adds its velocity, then gravity to its vertical speed...
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...
struct Projection gProjection
#define Ram_MapCellBuffer
char ResourceId_BlastSheet
char ResourceId_LightningBoltSheet
char ResourceId_FlameSheetB
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,...
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
struct AnimationSpritePart image
u16 priority
2 when created
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.
s32 actor
the user's unit id
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 shakeFrames
shake frames left; Camera_ApplyShake counts down
s32 bg2x
BG2's reference point, written to BG2X and BG2Y by Display_ApplyBg2Reference and BattleFx_AdvanceBg2O...
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...
s32 scrollStepY
added to BG1 or BG2 y at each step
s32 scrollTimer
frames since the last interval scroll step
struct BattleEffectArgument * effect
the command being run
s32 scrollStepX
added to BG1 or BG2 x at each step
s32 scrollInterval
frames between interval scroll steps
struct EffectStep particles[64]
free while variant is -1
struct MotionObject * object
NULL once released.
The battle background's work slot as the camera reads it: the yaw the camera eases toward and the fra...
s32 active
BattleBackgroundView's busy, at the same offset.
A point projected onto the screen, with its depth.
s32 depth
projected depth, larger further away
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
An effect object that moves and draws one sprite: its position, scale, velocity and target,...
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.
void * Resource_GetTableEntry(s32 index)
Returns the ROM address of resource index from the resource directory.
#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...