Alchemy
Loading...
Searching...
No Matches

djinn_beams.c

Go to the documentation of this file.
1/// @file
2/// Revive, Water of Life, Quartz and Dew.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7// Beams of light: a Djinni appears, motes drift down, and a column of
8// light falls from the sky onto each target.
9
10// Images in work->sheet.
11#define DJINN_BEAMS_MOTE_CELLS 0x2710 ///< the motes (CrescentMoonSheet, 24x24)
12#define DJINN_BEAMS_DJINNI_CELLS 0x65c0 ///< the Djinni (40x40)
13
14/// With a Venus Djinni: beams of light, where motes drift down over each target
15/// and a column of light falls on it.
16///
17/// Abilities: Revive, Water of Life (kind 25); Quartz (kind 201).
19 BattleFx_RunDjinnBeams(effect, 0);
20}
21/// With a Mercury Djinni: the same beams of light as Revive.
22///
23/// Abilities: Dew (kind 209).
25 BattleFx_RunDjinnBeams(effect, 1);
26}
27/// When effect->prelude is 1, a Djinni appears, sways and then rises out of
28/// sight. Over each target in turn, 16 frames apart, eight motes drift down,
29/// and from 72 frames after its turn starts a column of light falls on it
30/// and narrows away; the battle shows the result on frame 80.
31///
32/// Called by BattleFx_RunRevive and BattleFx_RunDew. Runs
33/// BattleFx_RunDjinniEntrance first when effect->prelude is 1. Loads three
34/// palettes over the first 64 background colours in turn, so the Djinni's
35/// is the one shown; fills PARTICLES 0 to 511, sets BG2PA and BG2X, and
36/// builds and frees its blitters every frame.
37///
38/// mode : 0 a Venus Djinni, 1 a Mercury Djinni.
40 struct EffectPosition one;
41 struct EffectPosition screenPosition;
42 s32 ground[3];
43 s32 point[3];
44 s32 djinnX;
45 s32 djinnY;
46 BlitterPair draw;
47 void **cursor;
48 struct BattleEffectWork *work;
49 void *canvas;
50 s32 frame;
51 s32 offsetX;
52 u8 *palette;
53 s32 i;
54 s32 k;
55
56 cursor = gBattleFxWork;
57 EFFECT_GET_WORK_AND_CANVAS(cursor, work, canvas);
58 work->effect = effect;
60 // Setup. The entrance (over the first target) mirrors the Djinni when the
61 // targets are enemies (side ^ 1), and returns where it ends in djinnX and
62 // djinnY.
63 if (work->effect->prelude == 1)
65 work->effect->side ^ work->effect->prelude, 0,
66 &djinnX, &djinnY);
68 Iwram_CopyWords((void *)BG_PLTT, palette, 128);
69 palette += 128;
70 Resource_DecodeType01(palette, work->sheet);
72 Iwram_CopyWords((void *)BG_PLTT, palette, 128);
73 palette += 128;
74 Resource_DecodeType01(palette, work->sheet + DJINN_BEAMS_MOTE_CELLS);
75 if (mode == 0)
77 else
79 Iwram_CopyWords((void *)BG_PLTT, palette, 128);
80 palette += 128;
81 Resource_DecodeType01(palette, work->sheet + DJINN_BEAMS_DJINNI_CELLS);
82
83 // The motes start 80 pixels up, up to 8 pixels off in z, each at a random
84 // point of its sway. Target k uses PARTICLES 64k to 64k + 7 of the 512.
85 for (i = 0; i != 512; i++) {
86 PARTICLES[i].x = 0;
87 PARTICLES[i].y = 80 << 16;
88 PARTICLES[i].z = (Random16() | -32) << 14;
89 PARTICLES[i].variant = Random16() & 255;
90 }
91
92 // With one target, scroll BG2 so the target is at the canvas's x 64;
93 // with several, the canvas covers the targets' side of the field.
94 REG_BG2PA = Q_8_8(1);
95 if (work->effect->count == 1) {
97 offsetX = 64 - one.x;
98 } else {
99 if (work->effect->side == 1)
100 offsetX = -112;
101 else
102 offsetX = 0;
103 }
104 REG_BG2X = offsetX << 8;
105 // Trails keep half a frame.
107
108 for (frame = 0; frame != work->effect->count * 16 + 116; frame++) {
109 struct BattleCamera *camera = gCameraWork;
110
111 // Frame loop. The sound on 64 and the damage on 80 come at fixed
112 // frames, whatever the number of targets.
113 if (frame == 64)
115 if (frame == 80)
117
118 // The Djinni sways 20 pixels either way and from frame 32 rises 2
119 // pixels a frame; it is drawn twice over its first four frames, which
120 // with additive drawing makes it brighter as it appears.
121 k = work->effect->prelude;
122 if (k == 1) {
123 s32 angle = frame << 11;
124 s32 x = (-Trig_Sin(angle) * 20 >> 16) + djinnX + offsetX - 20;
125 s32 y = (Trig_Cos(angle) * 4 >> 16) + djinnY - 24;
126
127 // Facing as in the entrance; k is the prelude, 1.
129 if (frame > 32)
130 y = y - frame * 2 + 64;
131 draw[1](canvas, work->sheet + DJINN_BEAMS_DJINNI_CELLS, x, y, 40, 40);
132 if (frame <= 3)
133 draw[1](canvas, work->sheet + DJINN_BEAMS_DJINNI_CELLS, x, y, 40, 40);
135 }
141
142 // Motes: one every 8 frames, swaying up to 16 pixels either way (odd
143 // motes mirrored) as they sink a pixel a frame; they go out 8 pixels
144 // above the ground. Each is placed relative to its target.
146 struct MotionObject *target =
148 s32 start = k * 16;
149
151 SET_VECTOR(point, target->x, 0, target->z);
153 if (frame > start) {
154 for (i = 0; i != 8; i++) {
155 struct EffectStep *mote = &PARTICLES[k * 64 + i];
156
157 if (frame > i * 8 + start && mote->y > 8 << 16) {
158 s32 sway;
159
160 EffectPosition_ProjectPoint(mote, &screenPosition);
161 screenPosition.x += offsetX;
162 sway = Trig_Sin(mote->variant << 10) * 16 >> 16;
163 if (i & 1)
164 screenPosition.x -= sway;
165 else
166 screenPosition.x += sway;
167 draw[i & 1](canvas,
168 work->sheet +
169 gDjinnBeams_MotePictures[mote->variant / 8 & 7] *
170 (24 * 24) +
172 screenPosition.x - 12, screenPosition.y - 12, 24, 24);
173 mote->y -= 1 << 16;
174 mote->variant++;
175 }
176 }
177 }
178 }
179
180 // The column: drawn in two mirrored halves from the top of the canvas
181 // down to the target's feet, 6 pixels each, narrowing by a pixel every
182 // 3 frames from 16 frames after it falls. The target glows meanwhile.
183 // The glow at its feet goes 28 frames after the column falls, the
184 // column itself at 32.
186 s32 start = i * 16;
187
188 if (frame >= start + 72) {
189 struct MotionObject *target =
191
193 if (frame == start + 72)
195 -1, -1, 0);
196 if (frame == start + 88)
197 ObjectGroup_UpdateMembers(work->effect->actors[i], 0, -1, -1, 0);
198 SET_VECTOR(ground, target->x, 0, target->z);
199 EffectPosition_ProjectPoint(ground, &screenPosition);
200 screenPosition.x += offsetX;
201 if (frame < start + 104) {
202 s32 pic = frame / 4;
203 s32 width = 6;
204
205 if (frame > start + 88)
206 width = 6 - (frame - start - 88) / 3;
207 // The glow's image counts from the effect's first frame, not the
208 // column's: 1 and 2 by turns, four frames each.
209 if (pic > 2)
210 pic = (pic & 1) + 1;
211 // The glow at the target's feet.
212 if (frame < start + 100) {
213 draw[0](canvas, work->sheet + gDjinnBeams_HeadOffsets[pic],
214 screenPosition.x - gDjinnBeams_HeadWidths[pic],
215 screenPosition.y - gDjinnBeams_HeadHeights[pic] + 8,
217 draw[1](canvas, work->sheet + gDjinnBeams_HeadOffsets[pic],
218 screenPosition.x,
219 screenPosition.y - gDjinnBeams_HeadHeights[pic] + 8,
221 }
222 // The column, a row at a time, each row the same strip from byte 5
223 // of the sheet's first picture.
224 for (k = 0; k != screenPosition.y; k++) {
225 draw[0](canvas, work->sheet + 5, screenPosition.x - width, k, width,
226 1);
227 draw[1](canvas, work->sheet + 5, screenPosition.x, k, width, 1);
228 }
229 }
230 }
231 }
234 }
235
236 // Finish: the blitters were freed each frame.
239}
240
241#undef DJINN_BEAMS_MOTE_CELLS
242#undef DJINN_BEAMS_DJINNI_CELLS
@ SPRITE_COLOR_GRB
red and green swapped
Definition animspr.h:20
void * gBattleFxWork[]
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 BattleFx_RunDew(struct BattleEffectArgument *effect)
With a Mercury Djinni: the same beams of light as Revive.
Definition djinn_beams.c:24
void BattleFx_RunDjinnBeams(struct BattleEffectArgument *effect, s32 mode)
When effect->prelude is 1, a Djinni appears, sways and then rises out of sight.
Definition djinn_beams.c:39
void BattleFx_RunRevive(struct BattleEffectArgument *effect)
With a Venus Djinni: beams of light, where motes drift down over each target and a column of light fa...
Definition djinn_beams.c:18
#define DJINN_BEAMS_DJINNI_CELLS
the Djinni (40x40)
Definition djinn_beams.c:12
#define DJINN_BEAMS_MOTE_CELLS
the motes (CrescentMoonSheet, 24x24)
Definition djinn_beams.c:11
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_PRESENT_FRAME(work)
Ends a frame of a canvas effect: marks the canvas ready for the transfer callback,...
@ 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_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_VIEW_FROM_CAMERA(camera)
Starts a frame's 3D projection from the battle camera: resets the transform, then looks from camera->...
u8 gDjinnBeams_HeadHeights[]
u8 gDjinnBeams_HeadWidths[]
u8 gDjinnBeams_MotePictures[]
The picture of each step of a mote's eight-step cycle.
u16 gDjinnBeams_HeadOffsets[]
struct BattleObj * GetBattleObjectSlotFar(s32 objectId)
Far call to BattleObjGet.
void AudioCommand_PlayFar(s32 id)
s32 Trig_Cos(s32 angle)
s32 Trig_Sin(s32 angle)
@ HEAP_SLOT_BLITTER_ALTERNATE
Definition heap_state.h:47
@ HEAP_SLOT_BLITTER
Definition heap_state.h:46
#define Q_8_8(n)
The BG2/BG3 affine matrix entries are signed 8.8 fixed point: texels stepped per screen pixel.
Definition io_reg.h:59
#define REG_BG2X
Definition io_reg.h:65
#define BG_PLTT
Definition io_reg.h:157
#define REG_BG2PA
Definition io_reg.h:61
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
Definition iwram_call.h:85
#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,...
Definition macros.h:12
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
Definition math.c:10
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
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 BattleFx_RunDjinniEntrance(struct BattleEffectArgument *effect, s32 mode, s32 side, s32 anchor, s32 *outX, s32 *outY)
Djinni entrance: sparks swirl around a point that travels from the user to the goal and gather into t...
Definition projectiles.c:29
char ResourceId_CrescentMoonSheet
char ResourceId_VenusDjinnSheet
char ResourceId_EarthWallSheet
char ResourceId_MercuryDjinnSheet
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_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
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 side
1 when the targets are the party, 0 for enemies
s16 actors[8]
the targets' unit ids, count of them
s32 count
targets in actors, at least 1
s32 prelude
1 plays a prelude: in some effects a Djinni appears
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
struct BattleEffectArgument * effect
the command being run
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 variant
each effect's own: a size, a countdown, -1 for idle
Definition effect_step.h:31
s32 y
16.16 fixed-point pixels
Definition effect_step.h:25
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 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
void SceneTransform_ApplyPosition(const s32 *position)
Translates gTransform by position (x, y, z in 16.16).
Definition transform.c:145
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