Alchemy
Loading...
Searching...
No Matches

volcano.c

Go to the documentation of this file.
1/// @file
2/// Volcano.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7// The fire pillars stand at random distances on the targets' side and scroll
8// a column of fire up with a flickering flame at its foot. Each erupts with a
9// fountain of 200 sparks and keeps spitting 4 a frame into one pool of 1024
10// in PARTICLES. The sparks move in 24.8 fixed point, with z holding the speed
11// across, and drift upwards; a spark's variant is its remaining life, 0 when
12// idle.
13
14#define VOLCANO_FRAMES 96
15#define VOLCANO_ERUPTION 200 ///< sparks thrown as a pillar starts
16#define VOLCANO_TRICKLE 4 ///< and each frame after
17#define VOLCANO_SPARK_POOL 1024 ///< sparks in PARTICLES
18#define VOLCANO_FLAME_IMAGE_ODD 0xdd0 ///< the flame on odd frames
19#define VOLCANO_FLAME_IMAGE_EVEN 0x10b4 ///< the flame on even frames
20
21/// One, two or four columns of fire (gVolcano_Counts by effect->variant) rise
22/// near the far edge on the targets' side, at the depths of gVolcano_Depths,
23/// starting at gVolcano_StartFrames; each erupts with a fountain of 200 sparks
24/// and keeps spitting more, and each eruption knocks the targets back.
25///
26/// Abilities: Volcano, Eruption, Pyroclasm, Lava Shower, Molten Bath, Magma
27/// Storm (kind 13).
28///
29/// The battle shows the damage on frame 16. Variant 0 is red, 2 orange; variant
30/// 2 also swings the camera round over the first 64 frames.
31///
32/// work->particles 0 to 3 are the pillars' feet, battle positions in 16.16.
33/// Sets REG_BLDALPHA, loads the red or orange palette into the first 64
34/// background colours (variant 1 keeps the fire pillar sheet's), turns the
35/// camera's yaw (variant 2) and sets work->shakeFrames at each eruption.
37 void **slots;
38 void **cursor;
39 struct BattleEffectWork *work;
40 void *canvas;
41 s32 frame;
42 s32 pillar;
43 u8 *sheet;
44 struct EffectPosition screen;
45 BlitterPair draw;
46 struct MotionObject *object;
47 struct BattleCamera *camera;
48 s32 i;
49
51 cursor = slots;
52 EFFECT_GET_WORK_AND_CANVAS(cursor, work, canvas);
53 sheet = EFFECT_SLOT(slots, HEAP_SLOT_BATTLE_SHEET);
54 work->effect = effect;
56 REG_BLDALPHA = BLEND_ALPHA(16, 16);
58 1);
60 if (work->effect->variant == 0)
63 else if (work->effect->variant == 2)
66 128);
72
73 for (i = 0; i != VOLCANO_SPARK_POOL; i++)
74 PARTICLES[i].variant = 0;
75
76 // The pillars stand 72 to 87 pixels out on the first target's side.
77 object = GetBattleObjectSlotFar(work->effect->actors[0])->object;
78 for (i = 0; i != 4; i++) {
79 struct EffectStep *base = &work->particles[i];
80 s32 x;
81
82 x = ((Random16() & 15) + 72) << 16;
83 base->y = 0;
84 base->x = x;
85 base->z = gVolcano_Depths[work->effect->variant][i] << 16;
86 if (object->x < 0)
87 base->x = -x;
88 }
89
90 // Trails keep half of each pixel a frame.
92
93 for (frame = 0; frame != VOLCANO_FRAMES; frame++) {
94 camera = gCameraWork;
95 if (work->effect->variant == 2 && frame < 64) {
96 if (work->effect->side == 0)
97 camera->yaw = camera->yaw + 192;
98 else
99 camera->yaw = (s16)camera->yaw - 192;
100 }
101 if (frame == 16)
104
105 if (frame < 64) {
106 for (pillar = 0; pillar != gVolcano_Counts[work->effect->variant];
107 pillar++) {
108 EffectPosition_ProjectPoint(&work->particles[pillar], &screen);
109 screen.x /= 2;
110 screen.y -= 8;
111 if (frame == gVolcano_StartFrames[pillar])
113 // From 4 frames after it starts: the column, scrolling up 16
114 // pixels a frame, and a flickering flame at its foot.
115 if (frame >= gVolcano_StartFrames[pillar] + 4) {
116 s32 scroll = (frame * 16 + pillar * 25) % 104;
117
118 draw[pillar & 1](canvas, work->sheet, screen.x - 17,
119 screen.y - scroll - 104, 34, 104);
120 draw[pillar & 1](canvas, work->sheet, screen.x - 17,
121 screen.y - scroll, 34, scroll);
122 if (frame & 1) {
123 draw[0](canvas, work->sheet + VOLCANO_FLAME_IMAGE_ODD,
124 screen.x - 20, screen.y - 24, 20, 37);
125 draw[1](canvas, work->sheet + VOLCANO_FLAME_IMAGE_ODD, screen.x,
126 screen.y - 24, 20, 37);
127 } else {
128 draw[0](canvas, work->sheet + VOLCANO_FLAME_IMAGE_EVEN,
129 screen.x - 20, screen.y - 24, 20, 37);
130 draw[1](canvas, work->sheet + VOLCANO_FLAME_IMAGE_EVEN, screen.x,
131 screen.y - 24, 20, 37);
132 }
133 }
134 // Sparks: 200 at the start, living 48 to 55 frames, then 4 a frame
135 // from 16 frames on, living 24 to 31; anywhere in the upper half
136 // circle, twice as hard up as across.
137 if (frame == gVolcano_StartFrames[pillar] ||
138 frame >= gVolcano_StartFrames[pillar] + 16) {
139 s32 spawned = 0;
140
141 for (i = 0; i != VOLCANO_SPARK_POOL; i++) {
142 struct EffectStep *spark = &PARTICLES[i];
143
144 if (spark->variant == 0) {
145 s32 speed;
146 s32 angle;
147
148 speed = (Random16() & 0x3ff) + 32;
149 angle = (Random16() & 0x7fff) - 0x4000;
150 SET_POSITION(spark, screen.x << 8, (screen.y << 8) + 0x1000,
151 (Trig_Sin(angle) * speed) >> 15);
152 spark->velocityY = -(Trig_Cos(angle) * speed * 2) >> 15;
153 spawned++;
154 if (frame == gVolcano_StartFrames[pillar]) {
155 spark->variant = (Random16() & 7) + 48;
156 if (spawned == VOLCANO_ERUPTION)
157 break;
158 } else {
159 spark->variant = (Random16() & 7) + 24;
160 if (spawned == VOLCANO_TRICKLE)
161 break;
162 }
163 }
164 }
165 }
166 if (frame == gVolcano_StartFrames[pillar]) {
167 work->shakeFrames = 2;
172 }
173 }
174 }
175 }
176
177 // The sparks, in 24.8 fixed point (z holds the speed across): slow to
178 // 60/64 a frame while pulled up by 1/16 pixel a frame, so they settle
179 // at a rise of 1 pixel a frame; one below y 120 bounces back at half
180 // speed instead of being drawn. A spark shrinks with its life.
181 for (i = 0; i != VOLCANO_SPARK_POOL; i++) {
182 struct EffectStep *spark = &PARTICLES[i];
183 s32 life = spark->variant;
184
185 if (life > 0) {
186 s32 x;
187 s32 y;
188 s32 py;
189
190 spark->variant = life - 1;
191 x = spark->x += spark->z;
192 y = spark->y += spark->velocityY;
193 spark->z = spark->z * 60 / 64;
194 spark->velocityY = spark->velocityY * 60 / 64 - 16;
195 py = y / 256;
196 if (py > 120) {
197 spark->velocityY = -spark->velocityY / 2;
198 } else if (x >= 0 && x >> 8 <= 126 && y >= 0) {
199 s32 px = x >> 8;
200 s32 size = (life - 17) / 8;
201
202 if (size <= 0)
203 size = 1;
204 EFFECT_DRAW_MOTE(draw[i & 1], canvas, sheet, px, py, size);
205 }
206 }
207 }
208 Camera_ApplyShake(16, 16);
209 EFFECT_END_FRAME(work);
210 }
211
215}
216
217#undef VOLCANO_FRAMES
218#undef VOLCANO_ERUPTION
219#undef VOLCANO_TRICKLE
220#undef VOLCANO_SPARK_POOL
221#undef VOLCANO_FLAME_IMAGE_ODD
222#undef VOLCANO_FLAME_IMAGE_EVEN
@ SPRITE_COLOR_RED_TINT
red raised to full
Definition animspr.h:28
@ POSE_DAMAGE
taking damage
Definition battle.h:176
struct BattleCamera * gCameraWork
@ COMPOSITE_FLIP_X
@ 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_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.
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.
@ 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 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_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_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->...
u8 gVolcano_Counts[]
How many pillars stand, by variant.
u8 gVolcano_StartFrames[]
The frame each pillar starts.
s8 gVolcano_Depths[][4]
Each pillar's depth, by variant.
struct BattleObj * GetBattleObjectSlotFar(s32 objectId)
Far call to BattleObjGet.
void BattleMotion_ApplyVariantMotionFar(s32 id, s32 variant)
void AudioCommand_PlayFar(s32 id)
s32 Trig_Cos(s32 angle)
s32 Trig_Sin(s32 angle)
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_BLITTER_ALTERNATE
Definition heap_state.h:47
@ HEAP_SLOT_BATTLE_SHEET
Definition heap_state.h:44
@ HEAP_SLOT_BLITTER
Definition heap_state.h:46
#define BLEND_ALPHA(top, bottom)
A REG_BLDALPHA value: top and bottom are the two targets' weights, out of 16.
Definition io_reg.h:145
#define REG_BLDALPHA
Definition io_reg.h:142
#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
#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 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
char ResourceId_OrangePaletteB
char ResourceId_FirePillarSheetA
char ResourceId_ParticleSpritesA
char ResourceId_RedPaletteB
s32 Scheduler_RemoveCallback(SchedulerCallback callback)
Unschedules the task running callback: clears its routine and gives it order 0x7fff,...
Definition scheduler.c:146
#define SE_HEAVY_IMPACT
Definition songs.h:127
#define SE_145
Definition songs.h:138
void * gWorkSlot[]
The battle camera: its eye, the focus it turns about, and its pitch, yaw and distance.
u16 yaw
1/65536 turns
The command shared by an effect's caller, dispatcher and handlers.
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 frame
frame counter some effects keep, from 0
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 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 x
16.16 fixed-point pixels
Definition motobj.h:23
void * Resource_GetTableEntry(s32 index)
Returns the ROM address of resource index from the resource directory.
Definition system.c:150
signed int s32
Definition types.h:14
signed short s16
Definition types.h:12
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
void BattleFx_RunVolcano(struct BattleEffectArgument *effect)
One, two or four columns of fire (gVolcano_Counts by effect->variant) rise near the far edge on the t...
Definition volcano.c:36
#define VOLCANO_FLAME_IMAGE_EVEN
the flame on even frames
Definition volcano.c:19
#define VOLCANO_FLAME_IMAGE_ODD
the flame on odd frames
Definition volcano.c:18
#define VOLCANO_FRAMES
Definition volcano.c:14
#define VOLCANO_SPARK_POOL
sparks in PARTICLES
Definition volcano.c:17
#define VOLCANO_ERUPTION
sparks thrown as a pillar starts
Definition volcano.c:15
#define VOLCANO_TRICKLE
and each frame after
Definition volcano.c:16