28#define DEATH_PLUNGE_FRAMES 96
75 x = user->
x + percent * (target->
x - user->
x) / 100;
76 z = user->
z + percent * (target->
z - user->
z) / 100;
106 user->
y += userHeight;
107 target->
y += targetHeight;
133 if (frame == 54 || frame == 55)
134 draw[0](canvas, work->sheet, screen.
x - 16, screen.
y - 16, 32, 64);
135 if (frame >= 56 && frame <= 67) {
138 for (i = 0; i != 16; i++) {
144 rx = screen.
x + ((
Trig_Sin(angle) * (frame - 46)) >> 16);
145 ry = ((
Trig_Cos(angle) * (frame - 46)) >> 16) - frame + 100;
146 draw[0](canvas, work->sheet + (((frame - 56) / 2) << 11), rx - 16, ry,
155 user->
y -= userHeight;
156 target->
y -= targetHeight;
175#define BLADE_RAIN_FRAMES 120
226 for (i = 0; i != 64; i++) {
232 blade->
y = (24 - i / 4) << 16;
235 else if (column <= 51)
237 else if (column <= 59)
239 else if (column <= 67)
241 else if (column <= 75)
243 else if (column <= 83)
270 for (i = 15; i != -1; i--) {
281 if (frame < i * 4 + 25) {
290 (blade->
x >> 16) - (width >> 1),
291 (blade->
y >> 16) - (height >> 1), width, height);
293 blit[(
u32)drift >> 31](
299 if (frame >= i * 4 + 16) {
311 (blade->
x >> 16) - (width >> 1),
312 (blade->
y >> 16) - (height >> 1), width,
315 blit[(
u32)drift >> 31](
327 if (frame >= 23 && frame <= 87 && (frame & 3) == 0) {
331 if ((frame & 7) == 0)
340#define ELEMENT_PILLAR_FRAMES 56
404 for (i = 0; i != 128; i++) {
452 draw[1](canvas, work->sheet + n * (17 * 64), 47, ground.
y - 64, 17, 64);
454 glow = work->sheet + n * 1032 + 0x1100;
455 draw[1](canvas, glow, 40, ground.
y - 36, 24, 43);
461 draw[1](canvas, work->sheet + n * (17 * 64), 64, ground.
y - 64, 17, 64);
462 draw[1](canvas, glow, 64, ground.
y - 36, 24, 43);
473 for (i = 0; i != 32; i++) {
479 point[0] = fleck->
z *
Trig_Sin(fleck->
x) >> 4;
480 point[2] = -(fleck->
z *
Trig_Cos(fleck->
x) >> 4);
486 screenPosition.
x /= 2;
489 screenPosition.
y, size);
512#define SHATTERING_OPENING_PLOT_PIXEL(x, y) \
513 (*(Ram_MapCellBuffer + ((x) & 7) + (x) / 8 * 64 + ((y) & 7) * 8 + \
518#define SHATTERING_OPENING_PLOT_CORNERS(x1, x2, y1, y2) \
519 (SHATTERING_OPENING_PLOT_PIXEL(x2, y2), \
520 SHATTERING_OPENING_PLOT_PIXEL(x2, y1), \
521 SHATTERING_OPENING_PLOT_PIXEL(x1, y2), \
522 SHATTERING_OPENING_PLOT_PIXEL(x1, y1))
524#define SHATTERING_OPENING_FRAMES 128
525#define SHATTERING_OPENING_FLASHES 32
526#define SHATTERING_OPENING_PIECES 33
527#define SHATTERING_OPENING_DISC_X 96
528#define SHATTERING_OPENING_DISC_Y 60
611 for (k = 0; k != 16; k++) {
612 for (j = 0; j != 8; j++, i += 2) {
615 entry = ((k * 16 + j * 2 + 1) << 8) | ((k * 8 + j) * 2);
616 *(
volatile s16 *)(0x06003800 + i) = entry;
626 work->imageStorage, 1, 1);
650 vx = (
x - 0x200000) >> 2;
651 vy = (
y - 0x3c0000) >> 2;
702 for (i = 0; i != 128; i++) {
703 s32 red = *color & 0x1f;
704 s32 green = (*color >> 5) & 0x1f;
705 s32 blue = (*color >> 10) & 0x1f;
707 s32 goalGreen = (battle->
palette[i] >> 5) & 0x1f;
708 s32 goalBlue = (battle->
palette[i] >> 10) & 0x1f;
712 else if (red > goalRed)
714 if (green < goalGreen)
716 else if (green > goalGreen)
720 else if (blue > goalBlue)
722 *color++ =
RGB(red, green, blue);
736 targetRadius = frame * 32;
740 for (; radius != targetRadius; radius++) {
748 while (octantX >= octantY) {
749 x2 = octantX + centreX;
750 x1 = centreX - octantX;
752 y1 = centreY - octantY;
753 y2 = octantY + centreY;
771 x2 = octantY + centreX;
772 x1 = centreX - octantY;
774 y2 = octantX + centreY;
775 y1 = centreY - octantX;
793 error -= octantY * 2 + 1;
795 error += octantX * 2 - 2;
819 if (frame >= 8 && frame <= 50) {
834 for (i = 1; i != 64; i++) {
845 piece->
x = ((
Random16() & 31) + 32) << 16;
846 piece->
y = ((
Random16() & 31) + 80) << 16;
861 if (frame >= i / 4 + 52 && piece->
variant <= 39) {
867 draw[1](canvas, work->sheet + (cell << 11),
969 for (i = 0; i != 128; i++) {
975 for (i = 0; i != 64; i++) {
1002 draw[0](canvas, work->sheet + (
frame - 28) / 3 * (48 * 48) + 0x1400, 40,
1003 ground.
y - 24, 48, 48);
1012 for (i = 0; i != 4; i++) {
1017 draw[1](canvas, work->sheet + (picture << 10),
gDeathPlunge_X[i] + 32,
1024 for (i = 0; i != 64; i++) {
1027 if (mote->
variant >= 0 && mote->
y > 0) {
1071 frame = (work->
frame)++;
1073 for (i = 0; i != 256; i++) {
1077 seed->
head = r + 48;
1078 seed->
tail = r + 40;
1087 for (; i != 64; i++) {
1089 if (frame > i / 4 && streak->
head > 0) {
1096 point.
x = streak->
head;
1100 point.
x = streak->
tail;
1106 if (streak->
tail < 0)
1112 fade = -streak->
tail / 2;
1194#undef DEATH_PLUNGE_FRAMES
1195#undef BLADE_RAIN_FRAMES
1196#undef ELEMENT_PILLAR_FRAMES
1197#undef SHATTERING_OPENING_PLOT_PIXEL
1198#undef SHATTERING_OPENING_PLOT_CORNERS
1199#undef SHATTERING_OPENING_FRAMES
1200#undef SHATTERING_OPENING_FLASHES
1201#undef SHATTERING_OPENING_PIECES
1202#undef SHATTERING_OPENING_DISC_X
1203#undef SHATTERING_OPENING_DISC_Y
@ SPRITE_COLOR_WHITE
solid colour 15, white
@ POSE_DAMAGE
taking damage
struct BattleCamera * gCameraWork
BattleEffectDrawRectangle DrawRectangle
void Palette_StepFadeTransfer(void)
Darkens the battle backdrop while the canvas is open: for fadeFrames frames, writes the backdrop's co...
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_EndCanvasLayer(void)
Closes the canvas layer: plays the closing sound, restores BG1's scroll and the projection centre,...
void BattleFx_ClearActorTimers(void)
Clears every target's flash timer (work->actorTimers).
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...
#define SHATTERING_OPENING_DISC_X
the centre of the opening disc
#define SHATTERING_OPENING_PLOT_CORNERS(x1, x2, y1, y2)
Plots the four corners (x1 or x2, y1 or y2): one point of the circle mirrored into four octants.
void BattleFx_RunShatteringOpening(struct BattleEffectArgument *effect)
The shattering opening of the battle on the Venus aerie storm backdrop: the screen turns white and a ...
#define SHATTERING_OPENING_FLASHES
flashes thrown as the picture breaks
void BattleFx_DrawStreaks(void)
Draws a frame of the element streak burst: on its first frame seeds 256 streaks with random axes,...
#define SHATTERING_OPENING_DISC_Y
the centre of the opening disc
#define SHATTERING_OPENING_PIECES
pieces the picture breaks into
void BattleFx_RunDeathPlunge(struct BattleEffectArgument *effect)
The user runs 9/10 of the way to the first target, then both leap and turn upside down in the air; on...
#define ELEMENT_PILLAR_FRAMES
void BattleFx_EndElementStreaks(void)
Ends the element streak burst that BattleFx_StartElementStreaks started: stops its callbacks and the ...
#define SHATTERING_OPENING_FRAMES
void BattleFx_StartElementStreaks(s32 element)
Starts the element streak burst and returns at once: opens the canvas and schedules BattleFx_DrawStre...
#define DEATH_PLUNGE_FRAMES
UNUSED void BattleFx_RunBladeRain(struct BattleEffectArgument *effect)
Drops 16 swords, one every 4 frames, slanting in towards the first target (the middle of the canvas,...
#define BLADE_RAIN_FRAMES
void BattleFx_RunElementBurst(struct BattleEffectArgument *effect)
The burst of an element over a unit, for 56 frames: sparks flare at the four corners around the unit,...
void BattleFx_RunElementPillar(struct BattleEffectArgument *effect)
The glow of an element around a unit: a symmetrical pillar of light stands at the unit's feet while m...
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.
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_PRESENT_FRAME(work)
Ends a frame of a canvas effect: marks the canvas ready for the transfer callback,...
#define EFFECT_DRAW_FLARE(draw, canvas, sheet, x, y, size)
Draws flare cell size of sheet, a square size pixels from its centre to each edge,...
@ CANVAS_COPY_AND_CLEAR
copy, then fill the canvas with transferValue
@ CANVAS_COPY_AND_DARKEN
copy, then darken the canvas by transferValue
@ CANVAS_COPY_AND_FADE
copy, keeping 50% or 75% (transferValue) of each pixel in the canvas for the next frame
#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).
#define EFFECT_SLOT(slots, slot)
A work slot read through a pointer to the effect's own slot, gWorkSlot[HEAP_SLOT_BATTLE_EFFECT].
#define EFFECT_FINISH_CANVAS()
The usual end of a canvas effect: stops the transfer callback before freeing what it reads,...
#define EFFECT_FINISH_CANVAS_ONE_BLITTER()
The same for an effect that drew through one blitter.
#define EFFECT_WINOUT
Outside the battle view: BG0 and blending only.
#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 EFFECT_DISPCNT
The battle screen's display mode while an effect plays: background mode 1 with BG0 to BG2,...
#define EFFECT_SET_BATTLE_WINDOWS()
Windows 0 and 1 both cover the battle view: the full width, lines 16 to.
#define EFFECT_PLAYBACK_ORDER
The order where the battle's own playback runs, which the palette fade and the element streaks take.
#define EFFECT_GET_SLOTS(slots, cursor, work, canvas)
Starts at the effect's entry in the whole work-slot array.
#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...
#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...
#define EFFECT_SET_CANVAS_AFFINE()
BG2 shows the canvas from screen line 16 down (BG2Y is -16.0), stretched to twice its width: the 128x...
u8 gDeathPlunge_PieceStartY[]
u8 gDeathPlunge_DrawFlags[]
u8 gDeathPlunge_CellHeights[]
u8 gDeathPlunge_PieceStartX[]
u16 gDeathPlunge_PieceCells[]
u8 gDeathPlunge_PieceHeights[]
u8 gDeathPlunge_PieceWidths[]
The 33 pieces of the TileAnimationMask picture: where each starts on the canvas, its size,...
u8 gDeathPlunge_CellWidths[]
struct BattleObj * GetBattleObjectSlotFar(s32 objectId)
Far call to BattleObjGet.
void BattlePres_SetupTransitionSceneFar(s32 x, s32 depth, s32 y, s32 zoom)
s32 BattleUnit_GetEffectHeightFar(s32 id)
void BattleBackground_LoadFar(s32 mode, s32 resource, s32 level)
void BattlePresentation_ConfigurePaletteFadeFar(s32 mode, s32 value, s32 fade)
void ObjectDispatch_SelectAnimationFar(void *raw, s32 no)
void Object_SetMoveTargetFar(struct ObjectRuntime *object, s32 x, s32 y, s32 z)
void ObjectDispatch_StartIdleFar(struct DispatchObject *obj)
void AudioCommand_PlayFar(s32 id)
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 ...
void * Runtime_AllocateHeapBlock(s32 kind, s32 size)
Returns heap slot kind's block, first allocating size bytes for it (rounded up to words),...
@ HEAP_SLOT_BATTLE_EFFECT
@ HEAP_SLOT_BLITTER_ALTERNATE
@ HEAP_SLOT_BATTLE_BACKGROUND
@ HEAP_SLOT_BATTLE_CANVAS
#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 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...
@ DISPCNT_MODE_1
BG0 and BG1 text, BG2 affine.
#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 IO_WRITE_QUEUE_PUSH(address, value, control)
Disables interrupts to add one register write or DMA to the queue; a write to a full queue is dropped...
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
static s32 Iwram_FillWords(void *destination, s32 size, u32 value)
static s32 Iwram_ClearWords(void *destination, s32 size)
#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,...
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
void Runtime_ReleaseHeapBlock(s32 slot)
void EffectPosition_ProjectBattler(s32 id, struct EffectPosition *position)
The screen position of a battler, 16 pixels higher.
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,...
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...
#define Ram_MapCellBuffer
char ResourceId_RedPaletteA
char ResourceId_CyanSparkSheet
char ResourceId_VioletPaletteD
char ResourceId_CrystalSheet
char ResourceId_SwordSlashSheet
char ResourceId_ParticleSpritesD
char ResourceId_YellowPaletteA
char ResourceId_DustPuffSheet
char ResourceId_TileAnimationMask
char ResourceId_YellowPaletteB
char ResourceId_VioletPaletteA
char ResourceId_IceTileSheet
char ResourceId_FlashBurstSheet
char ResourceId_EmberStreakSheet
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
s32 secondMode
1 also sets BG1's scroll; one effect sets it
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 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...
s32 fadeFrames
backdrop fade frames left (Palette_StepFadeTransfer)
s32 frame
frame counter some effects keep, from 0
s32 savedBg1Y
BG1 scroll restored when a shake ends.
s32 savedBg1X
BG1 scroll restored when a shake ends.
s32 transferPending
1 once the effect has drawn a frame (EFFECT_PRESENT_FRAME); the canvas transfer callback copies the c...
s32 fadeStep
CANVAS_FADE_STEPs the backdrop has darkened so far.
s32 shakeFrames
shake frames left; Camera_ApplyShake counts down
s32 transferMode
How the canvas transfer callbacks treat the canvas after each copy (enum CanvasTransferMode in effect...
s32 transferValue
The transfer mode's argument: the fill value, the share kept (50 or 75 percent) or the darken or brig...
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.
The battle's own work: its enemies, units and their objects, the turn's actions, the spoils,...
u16 background
the battle background's id
u16 palette[128]
the backdrop's colours, before scaling
A field object as the object dispatcher's far calls take it.
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
An effect object that moves and draws one sprite: its position, scale, velocity and target,...
s32 speedLimit
16.16 fixed-point pixels per frame
s32 z
16.16 fixed-point pixels
u8 snapToTarget
nonzero: lands exactly on the target, else brakes in
s32 y
16.16 fixed-point pixels
s32 velocityY
16.16 fixed-point pixels per frame
s32 acceleration
Horizontal speed gained each frame towards the target, or lost braking without one,...
s32 scaleY
16.16 fixed point, 0x10000 full size
s32 x
16.16 fixed-point pixels
s32 verticalMotionStrength
Gravity: taken from velocityY each frame above the ground with motionFlags bit 1, in 16....
u8 autoFaceMotion
bit 0 turns the object to face where it moves
One of the 64 field objects in the object pool (heap slot 5): its script, position,...
One streak of light of the element streak burst, laid over the same 28-byte records as PARTICLES: a l...
s32 tail
the tail's distance, 8 less; both close in 4 a frame
s32 yaw
the axis's turn, a random 16-bit angle
s32 unused08
the EffectStep's z, which the streaks leave alone
s32 unused18
the EffectStep's variant, which the streaks leave alone
s32 head
the head's distance from the centre, 48 to 63 at first
s32 pitch
the axis's turn, a random 16-bit angle
s32 roll
the axis's turn, a random 16-bit angle
Three coordinates, x, y and z: a position, a velocity or a direction.
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...
DrawRectangle BlitterPair[2]
A blitter pair: [0] built in HEAP_SLOT_BLITTER and [1] in HEAP_SLOT_BLITTER_ALTERNATE (BattleFx_Fetch...