Alchemy
Loading...
Searching...
No Matches

ramses.c

Go to the documentation of this file.
1/// @file
2/// The Ramses summon.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7// Ramses' slots: objects 0 to 6 are the formation, 7 and 8 the orb and 9 to
8// 14 the rocks. work->particles 0 to 5 move the rocks (variant counts their
9// bounces), 6 to 29 are the orb's puffs (eight kept per drop, four thrown)
10// and 30 to 41 the rocks' puffs, two per rock. PARTICLES holds the sparks.
11#define RAMSES_FRAMES 320
12#define RAMSES_STRIKE_FRAME 260 ///< the orb's burst strikes the targets
13#define RAMSES_ROCKS 6 ///< rocks that fall and bounce
14#define RAMSES_FIRST_PUFF 6 ///< the first puff in work->particles
15#define RAMSES_FIRST_ROCK_PUFF 30 ///< the first rock puff in work->particles
16#define RAMSES_SPARKS 512 ///< sparks of the orb's burst
17
18/// Over the desert backdrop a formation stands while an orb circles above it,
19/// drops three times throwing puffs, and flies off; RAMSES_ROCKS rocks fall and
20/// bounce, and the orb's flight ends in a burst of RAMSES_SPARKS sparks from
21/// PARTICLES.
22///
23/// Abilities: Ramses (scene kind 1).
24///
25/// Up to RAMSES_FRAMES frames; A or B ends it early.
26///
27/// 0 to 90 the orb circles above the formation
28/// 91 to 196 it drops three times, 40 frames apart, throwing puffs, and
29/// rises again; the screen shakes over frames 96 to 251
30/// 244 to 275 it flies off to the left, speeding up
31/// 260 the targets are struck and the sparks burst out
32///
33/// After frame 96 the rocks fall and bounce. Within a frame the order of the
34/// steps matters: later steps draw over earlier ones, and several of them
35/// consume random numbers.
37 // Every object of the scene takes this scale.
38 static struct SpriteScale unitScale = {{{0x10000, 0x10000}}};
39 struct SpritePlacement position;
40 DrawRectangle draw[2];
41 struct SpriteScale scale;
42 void **slots;
43 void *canvas;
44 struct BattleEffectWork *work;
45 s32 frame;
46 u8 *sheet;
47 struct Point2D base;
48 struct Point2D orb;
49 s32 i;
50 s32 k;
51
52 slots = &gBattleFxWork[1];
53 canvas = slots[0];
56 work->effect = effect;
59 // A wipe to black (colour 1) hides the battle; the desert backdrop loads
60 // behind it, and a second wipe clears the canvas to show it.
61 PLTT_BACKDROP = 0;
62 *(u16 *)&BG_PLTT[1] = 0;
68 // Nine objects of resource 379, the formation (0 to 6) and the orb (7 and
69 // 8), then the six rocks from resource 390, each playing one of its three
70 // animations.
71 BattleFx_SpawnObjects(9, 379, 2);
72 for (i = 0; i != RAMSES_ROCKS; i++) {
73 struct AnimationObject *object = ResourceObject_CreateFar(390);
74
75 work->objects[9 + i] = object;
76 if (object != 0) {
77 object->flags = 0;
79 work->objects[9 + i]->image.priority = 1;
80 }
81 }
87 // Keep the effect between lines 16 and 136.
90 REG_WIN0H = WIN_RANGE(0, 240);
91 REG_WIN1V = WIN_RANGE(16, 136);
92 WaitFrames(1);
99 // The formation's corner at (188, 92) and the orb at (160, 92); the rocks
100 // wait 16 pixels apart above the field at random columns.
101 base.x = 0xbc0000;
102 base.y = 0x5c0000;
103 orb.x = 0xa00000;
104 orb.y = 0x5c0000;
105 for (i = 0; i != RAMSES_ROCKS; i++) {
106 struct EffectStep *rock = &work->particles[i];
107
108 rock->x = (Random16() & 127) << 16;
109 rock->y = i * -0x100000;
110 rock->velocityX = 0;
111 rock->velocityY = 0;
112 rock->variant = 0;
113 }
114 // A puff's variant counts up and from 24 it is no longer drawn; every puff
115 // and spark starts finished. The puffs end at particle 41, but the clear
116 // runs to 63.
117 for (i = 0; i != 58; i++)
118 work->particles[RAMSES_FIRST_PUFF + i].variant = 24;
120 // Restart the background palette fade over 24 frames
121 // (Palette_StepFadeTransfer, added by BattleFx_BeginCanvasLayer).
122 work->fadeFrames = 24;
123 work->fadeStep = 0;
124
125 for (frame = 0; frame != RAMSES_FRAMES && !(gKeysRepeat & (KEY_A | KEY_B));
126 frame++) {
127 if (frame == 94)
129 if (frame == 136)
131 if (frame == 178)
133 if (frame == RAMSES_STRIKE_FRAME)
135 scale = unitScale;
136 // One frame of shake at a time, renewed each frame over frames 96 to 251
137 // and 260 to 263.
138 if (frame >= 96 && frame <= 251)
139 work->shakeFrames = 1;
140 else if (frame >= RAMSES_STRIKE_FRAME && frame <= 263)
141 work->shakeFrames = 1;
142 position.groundHeight = 0;
143 position.height = 0;
144 for (i = 0; i != 7; i++) {
145 position.x = (gRamses_ObjectColumns[i] << 16) + base.x - 0x200000;
146 position.y = (gRamses_ObjectRows[i] << 16) + base.y - 0x200000;
147 Object_ApplyProjectedPlacementFar(work->objects[i], &position, &scale, 0);
148 }
149 // The orb circles until frame 90, 16 pixels around (156, 92), a 128th
150 // of a turn a frame.
151 if (frame <= 90) {
152 orb.x = Trig_Sin(frame << 9) * 16 + 0x9c0000;
153 orb.y = Trig_Cos(frame << 9) * 16 + 0x5c0000;
154 }
155 // Then it drops 32 pixels three times, 40 frames apart, throwing four
156 // puffs as it lands and rising back over 16 frames.
157 if (frame <= 196) {
158 s32 start;
159
160 for (i = 0, start = 91; i != 3; start += 40, i++) {
161 if (frame >= start && frame < start + 4)
162 orb.y += 0x80000;
163 if (frame == start + 3) {
164 for (k = 0; k != 4; k++) {
165 struct EffectStep *puff =
166 &work->particles[RAMSES_FIRST_PUFF + i * 8 + k];
167
168 puff->x = 0x400000;
169 puff->y = 0x600000;
170 puff->velocityX = ((Random16() & 255) - 127) << 10;
171 puff->velocityY = ((Random16() & 255) - 127) << 10;
172 puff->variant = Random16() & 15;
173 }
174 }
175 if (frame >= start + 20 && frame < start + 36)
176 orb.y -= 0x20000;
177 }
178 }
179 // From frame 244 it flies off to the left, faster each frame from 252.
180 if (frame >= 244 && frame <= 251)
181 orb.x -= 0x10000;
182 if (frame >= 252 && frame <= 275)
183 orb.x -= (frame - 250) << 16;
184 // The orb's two objects, 32 pixels apart, high above the field.
185 if (frame <= 259) {
186 position.x = orb.x;
187 position.height = -0x1000000;
188 position.y = orb.y - 0x1000000;
189 Object_ApplyProjectedPlacementFar(work->objects[7], &position, &scale, 0);
190 position.x = orb.x + 0x200000;
191 Object_ApplyProjectedPlacementFar(work->objects[8], &position, &scale, 0);
192 }
193 position.height = 0;
194 // The rocks fall after frame 96. Past row 120 a rock bounces back at
195 // half speed, throwing two puffs; on its next landing it starts again
196 // from the top until frame 199, and after that it is left where it
197 // lands.
198 for (i = 0; i != RAMSES_ROCKS; i++) {
199 struct EffectStep *rock = &work->particles[i];
200
201 if (rock->variant != 2) {
202 position.x = rock->x;
203 position.y = rock->y;
204 Object_ApplyProjectedPlacementFar(work->objects[9 + i], &position,
205 &scale, 0);
206 rock->x += rock->velocityX;
207 rock->y += rock->velocityY;
208 if (frame > 96)
209 rock->velocityY += 0x4000;
210 if (rock->y > 0x780000) {
211 rock->variant++;
212 if (rock->variant == 1) {
213 rock->velocityY = -rock->velocityY / 2;
214 for (k = 0; k != 2; k++) {
215 struct EffectStep *puff =
216 &work->particles[RAMSES_FIRST_ROCK_PUFF + i * 2 + k];
217
218 puff->x = rock->x / 2;
219 puff->y = rock->y - 0x200000;
220 puff->velocityX = ((Random16() & 255) - 127) << 10;
221 puff->velocityY = ((Random16() & 255) - 127) << 10;
222 puff->variant = Random16() & 15;
223 }
224 } else if (frame <= 199) {
225 rock->y = 0;
226 rock->velocityY = 0;
227 rock->variant = 0;
228 }
229 }
230 }
231 }
232 // Puffs show the last four puff cells, six frames each, as they drift
233 // upward; each starts at a random point of its first 16 frames.
234 for (i = 0; i != 56; i++) {
235 struct EffectStep *puff = &work->particles[RAMSES_FIRST_PUFF + i];
236
237 if (puff->variant >= 0) {
238 if (puff->variant >= 0 && puff->variant <= 23) {
239 s32 cell = puff->variant / 6 + 3;
240
241 draw[0](canvas, work->sheet + gRamses_PuffCells[cell],
242 Q_16_16_TO_INT(puff->x) - gRamses_PuffSizes[cell] / 2,
243 Q_16_16_TO_INT(puff->y) - gRamses_PuffSizes[cell] / 2,
245 }
246 EffectStep_AdvanceWithGravity2D(puff, 60, -0x4000);
247 puff->variant++;
248 }
249 }
250 if (frame == RAMSES_STRIKE_FRAME) {
251 // The strike: every target recoils and flashes white, and the screen
252 // shakes.
256 -1, i, 8);
257 }
258 work->shakeFrames = 8;
259 }
260 // The ROM tests the strike frame again here.
261 if (frame == RAMSES_STRIKE_FRAME) {
262 // Throw the sparks from (32, 92) at random angles and speeds, twice as
263 // hard up and down as across, each living 32 to 47 frames.
264 for (i = 0; i != RAMSES_SPARKS; i++) {
265 struct EffectStep *spark = &PARTICLES[i];
266 s32 speed;
267 s32 angle;
268
269 /* FAKEMATCH: the mask set before the Random16() call it masks; as
270 * Random16() & 0x3ff, 5 instructions differ in tbs-en. */
271 speed = 0x3ff;
272 speed &= Random16();
273 angle = Random16() & 0xffff;
274 spark->x = 0x200000;
275 spark->y = 0x5c0000;
276 spark->velocityX = Trig_Sin(angle) * (speed + 32) >> 7;
277 spark->velocityY = -(Trig_Cos(angle) * (speed + 32) << 1) >> 7;
278 spark->variant = (Random16() & 15) + 32;
279 }
280 }
281 // Sparks shrink as their lives run down; alternate sparks are drawn
282 // additively, the others brightest-wins.
283 for (i = 0; i != RAMSES_SPARKS; i++) {
284 struct EffectStep *spark = &PARTICLES[i];
285
286 if (spark->variant >= 0) {
287 s32 size = (spark->variant >> 3) + 1;
288
289 EFFECT_DRAW_MOTE(draw[i & 1], canvas, sheet, Q_16_16_TO_INT(spark->x),
290 Q_16_16_TO_INT(spark->y), size);
291 EffectStep_AdvanceWithGravity2D(spark, 62, 0x1000);
292 spark->variant--;
293 }
294 }
295 Camera_ApplyShake(8, 8);
296 EFFECT_END_FRAME(work);
297 }
298
299 // The battle shows the damage once the scene is over, and gets its own
300 // background back.
303 for (i = 0; i != 15; i++)
306}
307
308#undef RAMSES_FRAMES
309#undef RAMSES_STRIKE_FRAME
310#undef RAMSES_ROCKS
311#undef RAMSES_FIRST_PUFF
312#undef RAMSES_FIRST_ROCK_PUFF
313#undef RAMSES_SPARKS
@ SPRITE_COLOR_WHITE
solid colour 15, white
Definition animspr.h:26
void * gBattleFxWork[]
@ COMPOSITE_ADDITIVE
@ 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_WipeCanvas(s32 mode, s32 value)
Wipes the whole canvas to one colour with a ragged edge: each row (or column) lags a random 0 to 63 p...
Definition canvas.c:27
void BattleFx_ConfigureEffectDisplay(void)
Puts the battle screen back into the display state every effect starts from and ends with: no blendin...
Definition display.c:16
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
void BattleFx_SetupBlendedDisplay(void)
Shows the BG1 battle background behind a cleared canvas: clears the canvas buffer and the 16 KiB of V...
Definition dispatch.c:217
void BattleFx_SelectLivingTargets(struct BattleEffectArgument *effect)
Shows the battle objects of every unit with HP left on the targets' side: the enemies (units 128 to 1...
Definition dispatch.c:184
What every part of the battle effect object shares: its includes, macros and frame-loop helpers.
#define EFFECT_SHOW_WIDE_CANVAS(top)
Shows the canvas: the effect display mode, BG2 stretched to twice its width (the 128-pixel canvas sho...
#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
copy as drawn
@ 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_FREE_PARTICLES(i, particles, count)
Marks particles[0] to particles[count - 1] free: a particle whose variant is -1 is not drawn or moved...
#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_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...
u16 gRamses_PuffCells[]
u8 gRamses_ObjectColumns[]
u8 gRamses_ObjectRows[]
u16 gRamses_PuffSizes[]
void BattleFx_SpawnObjects(s32 entryCount, s32 source, u32 priority)
Creates the effect's animation objects in gBattleFxWork's objects.
Definition eruption.c:220
void BattleMotion_ApplyVariantMotionFar(s32 id, s32 variant)
void BattleBackground_LoadFar(s32 mode, s32 resource, s32 level)
s32 AnimationObjects_SelectAnimationFar(struct AnimationObject *state, s32 flags)
struct AnimationObject * ResourceObject_CreateFar(s32 id)
void Object_ApplyProjectedPlacementFar(struct AnimationObject *sprite, const struct SpritePlacement *position, const struct SpriteScale *scale, s32 facing)
Far call to Render_ApplyProjectedPlacement.
void ResourceObject_ReleaseFar(struct AnimationObject *sprite)
void AudioCommand_PlayFar(s32 id)
s32 Trig_Cos(s32 angle)
s32 Trig_Sin(s32 angle)
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_BLITTER_ALTERNATE
Definition heap_state.h:47
@ HEAP_SLOT_BATTLE_SHEET
Definition heap_state.h:44
@ HEAP_SLOT_BLITTER
Definition heap_state.h:46
@ HEAP_SLOT_BATTLE_CANVAS
Definition heap_state.h:43
#define REG_WININ
Definition io_reg.h:81
#define REG_WIN0H
Definition io_reg.h:74
#define WININ_WIN1_BG0
Definition io_reg.h:93
#define WININ_WIN1_CLR
Definition io_reg.h:98
@ KEY_B
Definition io_reg.h:244
@ KEY_A
Definition io_reg.h:243
#define PLTT_BACKDROP
Definition io_reg.h:155
#define WIN_RANGE(start, end)
A REG_WINxH or REG_WINxV value: the window covers start up to, but not including, end.
Definition io_reg.h:80
#define WININ_WIN1_BG1
Definition io_reg.h:94
#define BG_PLTT
Definition io_reg.h:157
#define REG_WIN1V
Definition io_reg.h:77
#define WININ_WIN1_BG2
Definition io_reg.h:95
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
Definition math.c:10
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,...
Definition positions.c:46
#define RAMSES_FIRST_PUFF
the first puff in work->particles
Definition ramses.c:14
#define RAMSES_ROCKS
rocks that fall and bounce
Definition ramses.c:13
#define RAMSES_FIRST_ROCK_PUFF
the first rock puff in work->particles
Definition ramses.c:15
#define RAMSES_FRAMES
Definition ramses.c:11
#define RAMSES_SPARKS
sparks of the orb's burst
Definition ramses.c:16
void BattleFx_RunRamses(struct BattleEffectArgument *effect)
Over the desert backdrop a formation stands while an orb circles above it, drops three times throwing...
Definition ramses.c:36
#define RAMSES_STRIKE_FRAME
the orb's burst strikes the targets
Definition ramses.c:12
char ResourceId_BlastSheet
char ResourceId_DesertBackdrop
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
#define SE_156
Definition songs.h:151
#define SE_HEAVY_IMPACT
Definition songs.h:127
#define SE_145
Definition songs.h:138
void * gWorkSlot[]
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
struct AnimationSpritePart image
Definition animspr.h:109
u16 priority
2 when created
Definition animspr.h:100
The command shared by an effect's caller, dispatcher and handlers.
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 fadeFrames
backdrop fade frames left (Palette_StepFadeTransfer)
s32 frame
frame counter some effects keep, from 0
s32 fadeStep
CANVAS_FADE_STEPs the backdrop has darkened so far.
s32 shakeFrames
shake frames left; Camera_ApplyShake counts down
struct AnimationObject * objects[16]
the effect's animation objects
s32 transferMode
How the canvas transfer callbacks treat the canvas after each copy (enum CanvasTransferMode in effect...
struct BattleEffectArgument * effect
the command being run
struct EffectStep particles[64]
free while variant is -1
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
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
Two-dimensional {x, y} pair for position or velocity, a local of the summon scenes (Nereid,...
Definition effect.h:236
s32 y
16.16 pixels
Definition effect.h:238
s32 x
16.16 pixels in every scene that uses it
Definition effect.h:237
A sprite's screen position and its two vertical offsets, in 16.16 pixels.
s32 x
screen x of the sprite's centre
s32 y
screen y at the ground; sets the depth slot
s32 groundHeight
how far the shadow is raised above y
s32 height
how far the image is raised above y
Horizontal and vertical sprite scale; 0x10000 is the original size.
signed int s32
Definition types.h:14
unsigned short u16
Definition types.h:13
unsigned char u8
Definition types.h:11
#define EFFECT_CLIP_BOUNDS
Clips overflow on all four sides.
Definition effect.h:224
#define Q_16_16_TO_INT(v)
Definition effect.h:231
#define PARTICLES
The map cell buffer (gMapCellBuffer), which the effects borrow, has two views here: Ram_MapCellBuffer...
Definition effect.h:221