Alchemy
Loading...
Searching...
No Matches

annihilation.c

Go to the documentation of this file.
1/// @file
2/// Annihilation.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7#define ANNIHILATION_FRAMES 64
8
9/// The user closes on the first target and fire bursts from it in a shower of
10/// shards.
11///
12/// Abilities: Annihilation (kind 55).
13///
14/// Its frames:
15///
16/// 4 on 64 shards scatter from the target and fall
17/// 6 to 11 a fire streak flares in front of the user
18/// 8 the target is struck; the canvas is filled
19/// 16 to 47 a fire burst grows over the target in three steps
20///
21/// effect: the user and the target; a nonzero variant gives the burst its
22/// second picture and a sound.
24 void **slots;
25 void **cursor;
26 struct BattleEffectWork *work;
27 void *canvas;
28 u8 *particleSheet;
29 struct BattleCamera *camera;
30 struct MotionObject *targetObject;
31 struct EffectStep *shard;
32 struct EffectPosition position;
33 struct EffectPosition origin;
34 struct EffectPosition out;
35 DrawRectangle blitters[2];
36 s32 i;
37 s32 frame;
38 s32 size;
39 u8 *burstPixels;
40
42 cursor = slots;
43 EFFECT_GET_WORK_AND_CANVAS(cursor, work, canvas);
44 particleSheet = EFFECT_SLOT(slots, HEAP_SLOT_BATTLE_SHEET);
45 camera = EFFECT_SLOT(slots, HEAP_SLOT_CAMERA);
46 burstPixels = Ram_MapCellBuffer;
47 work->effect = effect;
50 1);
52 1);
54 0, 0);
56 4, 0);
57 WaitFrames(1);
58 targetObject = GetBattleObjectSlotFar(work->effect->actors[0])->object;
59
60 i = 0;
61 do {
62 // 64 shards start at the target, flying across towards the middle of
63 // the field; each group of four lives two frames longer than the last.
64 struct EffectStep *seed = &work->particles[i];
65
66 SET_POSITION(seed, targetObject->x, targetObject->y, targetObject->z);
67 SET_VELOCITY(seed, (Random16() & 255) << 11,
68 ((Random16() & 255) - 127) << 12,
69 ((Random16() & 255) - 127) << 12);
70 if (seed->x > 0)
71 seed->velocityX = -seed->velocityX;
72 seed->variant = i / 4 * 2 + 16;
73 i++;
74 } while (i != 64);
75
80
81 for (frame = 0; frame != ANNIHILATION_FRAMES; frame++) {
82 if (frame == 8)
84 if (work->effect->variant != 0 && frame == 8)
87 // The fire streak, one picture a frame in front of the user, drawn
88 // additively and mirrored for side 1 with a blitter made for this one
89 // drawing.
90 if (frame >= 6 && frame <= 11) {
91 if (work->effect->side == 0)
94 else
99 if (work->effect->side == 0)
100 blitters[0](canvas, work->sheet + (frame - 6) * (48 * 72),
101 position.x / 2 - 24, position.y - 24, 48, 72);
102 else
103 blitters[0](canvas, work->sheet + (frame - 6) * (48 * 72),
104 position.x / 2, position.y - 24, 48, 72);
106 }
107 // The fire burst over the target grows a step every two frames up to
108 // the third (frame 20) and holds it to frame 47; a nonzero variant takes
109 // the second strip of pictures.
110 if (frame >= 16 && frame <= 47) {
111 s32 step = (frame - 16) / 2;
112 s32 strip;
113
116 if (step > 2)
117 step = 2;
118 // Each strip holds three 40x80 pictures.
119 if (work->effect->variant == 0)
120 strip = 0;
121 else
122 strip = 3 * (40 * 80);
123 blitters[0](canvas, Ram_MapCellBuffer + strip + step * (40 * 80),
124 origin.x / 2 - 20, origin.y - 48, 40, 80);
125 // A busy delay before the blitter is freed (BattleFx_CallDoNothing).
126 // XXX: why it waits, as nothing here depends on the time; the Lost
127 // Age's Annihilation would show whether it is a leftover.
130 }
131 // The strike fills the canvas with level 63, a flash that the transfer
132 // then fades.
133 if (frame == 8) {
134 Dma_Fill32(0x3f3f3f3f, canvas, CANVAS_BYTES);
135 }
137 // Shards shrink as their lives run down; pairs of shards alternate
138 // between the normal and mirrored blitters.
139 if (frame > 3) {
141 for (i = 0; i != 64; i++) {
142 s32 life;
143
144 shard = &work->particles[i];
145 life = shard->variant;
146 if (life > 0) {
147 EffectPosition_ProjectPoint(shard, &out);
148 out.x >>= 1;
149 out.y = out.y + origin.y - 112;
150 size = (life >> 3) + 2;
151 EFFECT_DRAW_MOTE(blitters[(i / 2) & 1], canvas, particleSheet, out.x,
152 out.y, size);
153 EffectStep_AdvanceWithGravity3D(shard, 60, -0x400);
154 shard->variant--;
155 }
156 }
158 }
159 if (frame == 8) {
161 work->shakeFrames = 4;
162 }
163 // The target glows red on frames 6 and 14.
164 if (frame == 6)
166 -1, -1, 0);
167 if (frame == 14)
169 -1, -1, 0);
170 Camera_ApplyShake(16, 16);
171 EFFECT_END_FRAME(work);
172 }
175}
176
177#undef ANNIHILATION_FRAMES
@ SPRITE_COLOR_RED_TINT
red raised to full
Definition animspr.h:28
void BattleFx_RunAnnihilation(struct BattleEffectArgument *effect)
The user closes on the first target and fire bursts from it in a shower of shards.
#define ANNIHILATION_FRAMES
Definition annihilation.c:7
@ COMPOSITE_FLIP_X
@ COMPOSITE_ADDITIVE
@ COMPOSITE_MAX
BattleEffectDrawRectangle DrawRectangle
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 Resource_LoadAndDecompress(s32 id, void *dst, s32 skipPalette, s32 copyPalette)
Decompresses a resource whose first 128 bytes may be a palette.
#define Dma_Fill32(value, destination, size)
Fills size bytes at destination with the word value by DMA3.
Definition dma.h:30
void BattleFx_CallDoNothing(s32 count)
Calls the empty BattleFx_DoNothing count times, without waiting for a frame: a busy delay that change...
Definition dispatch.c:12
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
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_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_AND_FADE
copy, keeping 50% or 75% (transferValue) of each pixel in the canvas for the next frame
#define EFFECT_GET_WORK_AND_CANVAS(cursor, work, canvas)
The work block and canvas occupy adjacent slots, starting at HEAP_SLOT_BATTLE_EFFECT.
#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 EFFECT_SLOT(slots, slot)
A work slot read through a pointer to the effect's own slot, gWorkSlot[HEAP_SLOT_BATTLE_EFFECT].
#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 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->...
struct BattleObj * GetBattleObjectSlotFar(s32 objectId)
Far call to BattleObjGet.
void BattleMotion_ApproachTargetFar(s32 actorId, s32 targetId, s32 travel_divisor, s32 initial_velocity_y)
void BattleMotion_ApplyVariantMotionFar(s32 id, s32 variant)
void AudioCommand_PlayFar(s32 id)
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
void Camera_ApplyShake(s32 rangeX, u32 rangeY)
Shakes the battle view while gBattleFxWork's shakeFrames lasts, moving BG1 and the projection centre ...
Definition hail.c:364
@ HEAP_SLOT_BATTLE_EFFECT
Definition heap_state.h:42
@ 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
#define SET_VELOCITY(p, vx, vy, vz)
Definition macros.h:18
#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
void Runtime_ReleaseHeapBlock(s32 slot)
void BattleFx_FetchRectangleBlitters(s32 flip, BlitterPair out)
Builds the two usual routines that draw onto the 128x128 canvas, both clipped on both axes.
void EffectPosition_ProjectScaledBattler(s32 id, struct EffectPosition *position)
The screen position of a battler, scaled for the battle view, 16 pixels higher.
Definition positions.c:88
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...
Definition positions.c:29
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 Ram_MapCellBuffer
Definition ram_buffer.h:10
char ResourceId_FireStreakSheet
char ResourceId_FireBurstSheet
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...
Definition scheduler.c:102
s32 Scheduler_RemoveCallback(SchedulerCallback callback)
Unschedules the task running callback: clears its routine and gives it order 0x7fff,...
Definition scheduler.c:146
#define SE_212
Definition songs.h:207
#define SE_HEAVY_IMPACT
Definition songs.h:127
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.
s32 actor
the user's unit id
s32 side
1 when the targets are the party, 0 for enemies
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 shakeFrames
shake frames left; Camera_ApplyShake counts down
struct BattleEffectArgument * effect
the command being run
struct EffectStep particles[64]
free while variant is -1
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 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 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
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
s32 x
16.16 fixed-point pixels
Definition motobj.h:23
signed int s32
Definition types.h:14
unsigned char u8
Definition types.h:11
#define EFFECT_CLIP_BOUNDS
Clips overflow on all four sides.
Definition effect.h:224