Alchemy
Loading...
Searching...
No Matches

stars.c

Go to the documentation of this file.
1/// @file
2/// Astral Blast and Shining Star.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7// Astral Blast flies three ten-pointed rings at the target, knocking it back;
8// Shining Star drops eight ten-pointed stars that bounce near the target.
9// Each outline is drawn from ten corner points, a tenth of a turn (0x199a)
10// apart, projected onto the canvas and stored in the velocity fields of
11// PARTICLES, ten for each ring or star; each edge is sampled at evenly
12// spaced points and a mote is stamped at each.
13
14/// Three star-shaped rings of light fly from 40 pixels above the user at the
15/// first target, 12 frames apart, growing and spinning as they go, while the
16/// camera swings round; each knocks the target back on arrival, and the third
17/// lets the battle show the damage.
18///
19/// Abilities: Astral Blast (kind 68).
20///
21/// work->particles 0 to 2 are the rings, battle positions in 16.16. Loads the
22/// rune palette into the first 64 background colours, sets the user's
23/// animation (2, at speed 48), turns the camera's yaw, sends the target
24/// back with its motion fields and sets work->shakeFrames.
26 struct EffectPosition screenPosition;
27#ifndef UBFIX
28 struct EffectPosition base;
29#endif
30 struct Vector3 scale;
31 struct BattleEffectWork *work;
32 void *canvas;
33 s32 frame;
34 /* FAKEMATCH: only draw[0] is used; the unused second word fills four bytes
35 of the frame; as one DrawRectangle, 48 instructions differ in tbs-en. */
36 BlitterPair draw;
37 s32 i;
38 u8 *graphics;
39 struct BattleCamera *camera;
40 struct MotionObject *caster;
41 struct MotionObject *source;
42 struct MotionObject *target;
43 struct EffectStep *point;
44 struct EffectStep *step;
45 s32 start;
46 s32 peak;
47 s32 size;
48 s32 j;
49 s32 k;
50 struct EffectStep *trails;
51
56 caster = GetBattleObjectSlotFar(effect->actor)->object;
57 work->effect = effect;
66 // Trails keep 75% of each pixel a frame.
68 work->transferValue = 75;
72
73 source = GetBattleObjectSlotFar(work->effect->actor)->object;
74 target = GetBattleObjectSlotFar(work->effect->actors[0])->object;
75 // Each ring reaches the target in 12 frames; the second and third aim
76 // twice as far across, past it.
77 for (i = 0, point = work->particles; i != 3; i++) {
78 SET_POSITION(point, source->x, source->y + 0x280000, source->z);
79 if (i == 0)
80 point->velocityX = (target->x - point->x) / 12;
81 else
82 point->velocityX = (target->x * 2 - point->x) / 12;
83 point->velocityY = (target->y - point->y + 0x280000) / 12;
84 point->velocityZ = (target->z - point->z) / 12;
85 point->variant = 0;
86 point++;
87 }
88
89 trails = PARTICLES;
90 for (frame = 0; frame != 60; frame++) {
91 // Swing the camera round, slowing over frames 40 to 47.
92 if (frame <= 47) {
94 s32 speed;
95
96 if (frame <= 39)
97 speed = 128;
98 else
99 speed = 0x300 - frame * 16;
100 if (work->effect->side == 0)
101 view->yaw -= speed;
102 else
103 view->yaw += speed;
104 }
105 for (i = 0; i != 3; i++) {
106 start = i * 12;
107 if (frame >= start) {
108 step = &work->particles[i];
109 size = (frame - start) / 4 + 2;
110 if (size > 10)
111 size = 10;
114 // The ring's ten points, alternately near and far from its centre,
115 // projected onto the canvas; peak is the farthest depth.
116 peak = 0;
117 for (j = 0; j != 10; j++) {
118 s32 depth;
119
121 SceneTransform_ApplyRoll((frame - start) << 10);
123 scale.x = ((frame - start) << 12) + 0x1000;
124 if (scale.x > 0x10000)
125 scale.x = 0x10000;
126 scale.y = scale.x;
127 scale.z = scale.x;
129 SceneTransform_ApplyRoll(j * 0x199a);
131 &screenPosition);
132 if (peak < depth)
133 peak = depth;
134 screenPosition.x >>= 1;
135#ifndef UBFIX
136 // These first stores read base, which is never set; the next two
137 // overwrite them. UBFIX leaves them out.
138 trails[i * 10 + j].velocityX = screenPosition.x + base.x;
139 trails[i * 10 + j].velocityY = screenPosition.y + base.y;
140#endif
141 trails[i * 10 + j].velocityX = screenPosition.x;
142 trails[i * 10 + j].velocityY = screenPosition.y;
144 }
145 // Join the points with 16 motes each, unless the ring is too far
146 // away.
147 if (peak <= 399999) {
148 for (j = 0; j != 10; j++) {
149 struct EffectStep *from =
150 &((struct EffectStep *)PARTICLES)[j + i * 10];
151 struct EffectStep *to =
152 &((struct EffectStep *)PARTICLES)[(j + 1) % 10 + i * 10];
153
154 for (k = 0; k != 16; k++) {
155 s32 x =
156 from->velocityX + (to->velocityX - from->velocityX) * k / 16;
157 s32 y =
158 from->velocityY + (to->velocityY - from->velocityY) * k / 16;
159
160 EFFECT_DRAW_MOTE(draw[0], canvas, graphics, x, y, size);
161 }
162 }
163 }
164 step->x += step->velocityX;
165 step->y += step->velocityY;
166 step->z += step->velocityZ;
167 // Ring i hits 10 + i frames after its launch: knock the target 40
168 // pixels back, away from the middle, and shake the screen. The third
169 // ring lets the battle show the damage; the others flash the target.
170 if (frame == start + i + 10) {
171 target->acceleration = 0x20000;
172 target->speedLimit = 0x80000;
173 target->velocityY = 0x50000;
174 target->verticalMotionStrength = 0xab85;
175 target->autoFaceMotion = 0;
177 if (target->x < 0)
178 Object_SetMoveTargetFar((struct ObjectRuntime *)target,
179 target->x - 0x280000, 0, target->z);
180 else
181 Object_SetMoveTargetFar((struct ObjectRuntime *)target,
182 target->x + 0x280000, 0, target->z);
183 if (i == 2) {
185 } else {
189 }
190 work->shakeFrames = 4;
191 }
192 }
193 }
194 Camera_ApplyShake(8, 8);
195 EFFECT_END_FRAME(work);
196 }
197
199}
200
201/// Eight spinning star outlines fall from 120 pixels above the user towards the
202/// first target, a few frames apart, and bounce off the ground near it, each
203/// bounce shaking the screen and flashing the targets; the battle shows the
204/// damage on frame 96.
205///
206/// Abilities: Shining Star (kind 62).
207///
208/// 128 frames. work->particles 0 to 7 are the stars, battle positions in
209/// 16.16, each variant the frame it starts. Rebuilds the background ramp
210/// each frame (Graphics_UpdatePhasePalette, after loading the rune palette)
211/// and sets work->shakeFrames at each bounce.
213 struct BattleEffectWork *work;
214 void *canvas;
215 s32 frame;
216 /* FAKEMATCH: only draw[0] is used; the unused second word fills four bytes
217 of the frame; as one DrawRectangle, 40 instructions differ in tbs-en. */
218 BlitterPair draw;
219 s32 i;
220 u8 *graphics;
221 struct BattleCamera *camera;
222 struct MotionObject *source;
223 struct MotionObject *target;
224 struct EffectStep *point;
225 struct EffectStep *step;
226 struct EffectPosition screenPosition;
227 s32 size;
228 s32 j;
229 s32 k;
230 struct EffectStep *trails;
231
235 camera = WORK_SLOT(HEAP_SLOT_CAMERA);
236 work->effect = effect;
238 Iwram_CopyWords((void *)BG_PLTT,
243 // Trails keep half of each pixel a frame.
245 work->transferValue = 50;
246 draw[0] = (DrawRectangle) * (gWorkSlot + HEAP_SLOT_BLITTER);
249
250 source = GetBattleObjectSlotFar(work->effect->actor)->object;
251 target = GetBattleObjectSlotFar(work->effect->actors[0])->object;
252 // Each star starts 120 pixels above the user, at half its x (towards the
253 // middle of the field), aims at a random spot up to 64 pixels either side
254 // of the target, 20 pixels up, over 12 frames, and starts 8i to 8i + 15
255 // frames in (its variant).
256 for (i = 0, point = work->particles; i != 8; i++) {
257 s32 delay = i * 8;
258
259 SET_POSITION(point, source->x / 2, source->y + 0x780000, source->z);
260 // The signed -64..63 pixel offset scales without a negative left shift.
261 point->velocityX =
262 (target->x + ((s32)((Random16() & 0x7f) - 64) * 65536) - point->x) / 12;
263 point->velocityY = (target->y - point->y + 0x140000) / 12;
264 point->velocityZ = (target->z - point->z) / 12;
265 point->variant = (Random16() & 15) + delay;
266 point++;
267 }
268
269 size = 2;
270 trails = PARTICLES;
271 for (frame = 0; frame != 128; frame++) {
272 // The three channels sway a third of a turn apart.
273 Graphics_UpdatePhasePalette(frame, 0xaaab, 0x5555, 0);
274 if (frame == 96)
276 for (i = 0; i != 8; i++) {
277 step = &work->particles[i];
278 if (frame >= step->variant) {
280 EffectPosition_ProjectPoint(step, &screenPosition);
281 screenPosition.x >>= 1;
282 // On the canvas, draw the star: ten points, alternately near and
283 // far, turning as it falls, joined by 12 motes each.
284 if (screenPosition.x >= -8 && screenPosition.x <= 127) {
285 if (screenPosition.y <= 127) {
286 if (screenPosition.y >= -8) {
287 for (j = 0; j != 10; j++) {
288 trails[i * 10 + j].velocityX =
289 screenPosition.x +
290 ((Trig_Sin(j * 0x199a - ((frame - step->variant) << 11)) *
291 gStars_Radii[j & 1]) /
292 2 >>
293 16);
294 trails[i * 10 + j].velocityY =
295 screenPosition.y -
296 (Trig_Cos(j * 0x199a - ((frame - step->variant) << 11)) *
297 gStars_Radii[j & 1] >>
298 16);
299 }
300 for (j = 0; j != 10; j++) {
301 struct EffectStep *from = &trails[j + i * 10];
302 struct EffectStep *to = &trails[i * 10 + (j + 1) % 10];
303
304 for (k = 0; k != 12; k++) {
305 s32 x = from->velocityX +
306 (to->velocityX - from->velocityX) * k / 12;
307 s32 y = from->velocityY +
308 (to->velocityY - from->velocityY) * k / 12;
309
310 EFFECT_DRAW_MOTE(draw[0], canvas, graphics, x, y, size);
311 }
312 }
313 }
314 }
315 }
316 // Bounce below 30 pixels up, losing half the speed across.
317 if (step->y <= 0x1dffff) {
318 step->velocityY = -step->velocityY;
319 step->velocityX /= 2;
320 step->velocityZ /= 2;
321 work->shakeFrames = 4;
326 }
327 step->x += step->velocityX;
328 step->y += step->velocityY;
329 step->z += step->velocityZ;
330 }
331 }
332 Camera_ApplyShake(4, 4);
333 EFFECT_END_FRAME(work);
334 }
335
337}
@ SPRITE_COLOR_WHITE
solid colour 15, white
Definition animspr.h:26
@ POSE_DAMAGE
taking damage
Definition battle.h:176
@ 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 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_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_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 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->...
static const s32 * EffectStep_Coordinates(const struct EffectStep *step)
Returns the step's three coordinates as an array.
Definition effect_step.h:37
struct Vector3 gStars_Points[]
The two star points, 48 and 28 pixels up (16.16).
u8 gStars_Radii[]
struct BattleObj * GetBattleObjectSlotFar(s32 objectId)
Far call to BattleObjGet.
void ObjectDispatch_SelectAnimationFar(void *raw, s32 no)
void ObjectDispatch_SetAnimationSpeedFar(struct DispatchObject *obj, s32 val)
void Object_SetMoveTargetFar(struct ObjectRuntime *object, s32 x, s32 y, s32 z)
void ObjectDispatch_StartIdleFar(struct DispatchObject *obj)
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_BATTLE_SHEET
Definition heap_state.h:44
@ HEAP_SLOT_CAMERA
Definition heap_state.h:38
@ HEAP_SLOT_BLITTER
Definition heap_state.h:46
@ HEAP_SLOT_BATTLE_CANVAS
Definition heap_state.h:43
#define WORK_SLOT(n)
Reads slots through their own addresses; adjacent slots are reached by offsets.
Definition heap_state.h:14
#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
void Graphics_UpdatePhasePalette(s32 frame, s32 redPhase, s32 greenPhase, s32 bluePhase)
Rebuilds the background palette's first ramp as a grey ramp whose red, green and blue each sway with ...
Definition prism.c:183
char ResourceId_ParticleSpritesA
char ResourceId_RuneSheet
s32 Resource_DecodeType01(const void *source, void *destination)
Decodes a type-01 resource and returns its unpacked byte count.
Definition decompress.c:31
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
#define SE_HEAVY_IMPACT
Definition songs.h:127
void * gWorkSlot[]
void BattleFx_RunShiningStar(struct BattleEffectArgument *effect)
Eight spinning star outlines fall from 120 pixels above the user towards the first target,...
Definition stars.c:212
void BattleFx_RunAstralBlast(struct BattleEffectArgument *effect)
Three star-shaped rings of light fly from 40 pixels above the user at the first target,...
Definition stars.c:25
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 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
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 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
struct MotionObject * object
NULL once released.
A field object as the object dispatcher's far calls take it.
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 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
s32 velocityZ
16.16 fixed-point pixels per frame
Definition effect_step.h:30
An effect object that moves and draws one sprite: its position, scale, velocity and target,...
Definition motobj.h:20
s32 speedLimit
16.16 fixed-point pixels per frame
Definition motobj.h:34
s32 z
16.16 fixed-point pixels
Definition motobj.h:25
s32 y
16.16 fixed-point pixels
Definition motobj.h:24
s32 velocityY
16.16 fixed-point pixels per frame
Definition motobj.h:32
s32 acceleration
Horizontal speed gained each frame towards the target, or lost braking without one,...
Definition motobj.h:37
s32 x
16.16 fixed-point pixels
Definition motobj.h:23
s32 verticalMotionStrength
Gravity: taken from velocityY each frame above the ground with motionFlags bit 1, in 16....
Definition motobj.h:48
u8 autoFaceMotion
bit 0 turns the object to face where it moves
Definition motobj.h:59
One of the 64 field objects in the object pool (heap slot 5): its script, position,...
Three coordinates, x, y and z: a position, a velocity or a direction.
Definition vector3.h:11
s32 z
Definition vector3.h:24
s32 x
Definition vector3.h:22
s32 y
Definition vector3.h:23
void * Resource_GetTableEntry(s32 index)
Returns the ROM address of resource index from the resource directory.
Definition system.c:150
void SceneTransform_ApplyYaw(s32 angle)
Rotates gTransform about the Y axis by angle.
Definition transform.c:113
void Transform_Pop(void)
Restores gTransform from the save area, if Transform_Push saved it.
Definition transform.c:49
void SceneTransform_ApplyPosition(const s32 *position)
Translates gTransform by position (x, y, z in 16.16).
Definition transform.c:145
void Transform_Push(void)
Saves gTransform into the save area (one level deep; a second save is ignored).
Definition transform.c:30
void SceneTransform_ApplyScale(const s32 *scale)
Scales gTransform by scale (x, y, z factors in 16.16).
Definition transform.c:158
void SceneTransform_ApplyRoll(s32 angle)
Rotates gTransform about the Z axis by angle.
Definition transform.c:129
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
#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
static const s32 * Vector3_Coordinates(const struct Vector3 *vector)
Returns the vector's three coordinates as an array.
Definition vector3.h:31