Alchemy
Loading...
Searching...
No Matches

spire.c

Go to the documentation of this file.
1/// @file
2/// Spire.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7#define SPIRE_ROCK_WIDTH 34 ///< the boulder picture, the first in the sheet
8#define SPIRE_ROCK_HEIGHT 62 ///< the boulder picture's height
9/// The shard pictures in the sheet, after the boulder.
10#define SPIRE_SHARD_CELLS (SPIRE_ROCK_WIDTH * SPIRE_ROCK_HEIGHT)
11#define SPIRE_SHARDS 21 ///< shards per rock
12/// Frames a boulder falls, from its drop frame (gSpire_DropFrames) until it
13/// lands, shakes the screen and strikes the targets.
14#define SPIRE_FALL_FRAMES 18
15
16/// Shattering rocks: boulders drop along the row of targets, centred on it, and
17/// burst into tumbling shards, hitting every target as each lands.
18///
19/// Abilities: Spire, Clay Spire, Stone Spire (kind 2).
20///
21/// effect: the targets; its variant picks the number of boulders
22/// (gSpire_RockCounts).
24 void **slots;
25 void **cursor;
26 struct BattleEffectWork *work;
27 void *canvas;
28 DrawRectangle blit;
29 s32 rockCount;
30 struct EffectPosition first;
31 struct EffectPosition last;
32 struct EffectStep *rock;
33 struct EffectStep *shard;
34 s32 frame;
35 s32 i;
36 s32 j;
37 s32 cell;
38 u32 width;
39 u32 height;
40
41 EFFECT_GET_SLOTS(slots, cursor, work, canvas);
42 work->effect = effect;
44 REG_BLDCNT = 0;
48 blit = EFFECT_SLOT(slots, HEAP_SLOT_BLITTER);
49 // BG2 is scrolled so that canvas column 64 is the middle of the row of
50 // targets.
53 work->effect->actors[work->effect->count - 1], &last);
54 first.x += (last.x - first.x) / 2;
55 REG_BG2X = (64 - first.x) << 8;
57 // The rocks wait 64 pixels above the canvas until they drop.
58 rockCount = gSpire_RockCounts[work->effect->variant];
59 for (i = 0; i != rockCount; i++) {
60 rock = &work->particles[i];
61 rock->y = -0x400000;
62 rock->velocityY = 0;
63 }
64 // Each rock breaks into 21 shards, thrown up from where it lands: under a
65 // pixel a frame to either side and 1 to 5 pixels a frame up. z is the
66 // shard's tumbling speed and variant how far it has tumbled.
67 for (i = 0; i != rockCount; i++) {
68 for (j = 0; j != SPIRE_SHARDS; j++) {
69 struct EffectStep *shard = &PARTICLES[i * SPIRE_SHARDS + j];
70
72 << 16;
73 shard->y = gSpire_ShardOffsets[j][SPIRE_SHARD_Y] << 16;
74 shard->velocityX = ((Random16() % 96) - 48) << 10;
75 shard->velocityY = -((Random16() & 127) + 32) << 11;
76 shard->z = 32;
77 shard->variant = 0;
78 }
79 }
80 // The scene lasts until 80 frames after the last rock drops; the damage
81 // shows 30 frames after that rock lands.
82 for (frame = 0; frame != gSpire_DropFrames[rockCount - 1] + 80; frame++) {
83 if (frame == gSpire_DropFrames[rockCount - 1] + 48)
85 for (i = 0; i != rockCount; i++) {
86 rock = &work->particles[i];
87 if (frame == gSpire_DropFrames[i] + SPIRE_FALL_FRAMES) {
89 work->shakeFrames = 4;
90 }
91 // From its landing on, the rock is gone and its shards fly.
92 if (frame >= gSpire_DropFrames[i] + SPIRE_FALL_FRAMES) {
93 for (j = 0; j != SPIRE_SHARDS; j++) {
94 shard = &PARTICLES[i * SPIRE_SHARDS + j];
95 // Five shard shapes, each tumbling through three pictures; z is the
96 // tumbling speed, slowing by one every other frame down to 1.
97 cell = (j % 5) * 3 + shard->variant / 96 % 3;
98 // UB: width is assigned in one argument and read in another.
99#ifdef UBFIX
100 width = gSpire_ShardWidths[cell];
101 height = gSpire_ShardHeights[cell];
102 blit(canvas,
103 work->sheet + gSpire_ShardCells[cell] + SPIRE_SHARD_CELLS,
104 Q_16_16_TO_INT(shard->x) - (width >> 1),
105 Q_16_16_TO_INT(shard->y) - (height >> 1), width, height);
106#else
107 blit(canvas,
108 work->sheet + gSpire_ShardCells[cell] + SPIRE_SHARD_CELLS,
109 Q_16_16_TO_INT(shard->x) -
110 ((width = gSpire_ShardWidths[cell]) >> 1),
111 Q_16_16_TO_INT(shard->y) -
112 ((height = gSpire_ShardHeights[cell]) >> 1),
113 width, height);
114#endif
115 EffectStep_AdvanceWithGravity2D(shard, 64, 0x4000);
116 shard->variant += shard->z;
117 if (shard->z > 1 && (frame & 1))
118 shard->z--;
119 }
120 }
121 // The rock falls from its drop frame, a pixel a frame faster each
122 // frame, never lower than y 50; it is drawn centred over its column.
123 if (frame < gSpire_DropFrames[i] + SPIRE_FALL_FRAMES) {
124 if (frame >= gSpire_DropFrames[i])
125 blit(canvas, work->sheet, gSpire_RockX[i] + 64 - SPIRE_ROCK_WIDTH / 2,
127 rock->y += rock->velocityY;
128 if (frame > gSpire_DropFrames[i])
129 rock->velocityY += 0x10000;
130 if (rock->y > 0x320000)
131 rock->y = 0x320000;
132 }
133 if (frame == gSpire_DropFrames[i] + SPIRE_FALL_FRAMES) {
136 POSE_DAMAGE, j, 8);
137 }
138 }
139 Camera_ApplyShake(2, 4);
140 EFFECT_END_FRAME(work);
141 }
143}
144
145#undef SPIRE_ROCK_WIDTH
146#undef SPIRE_ROCK_HEIGHT
147#undef SPIRE_SHARD_CELLS
148#undef SPIRE_SHARDS
149#undef SPIRE_FALL_FRAMES
@ SPRITE_COLOR_WHITE
solid colour 15, white
Definition animspr.h:26
@ POSE_DAMAGE
taking damage
Definition battle.h:176
@ COMPOSITE_TRANSPARENT
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 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.
@ CANVAS_COPY_AND_CLEAR
copy, then fill the canvas with transferValue
#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_FINISH_CANVAS_ONE_BLITTER()
The same for an effect that drew through one blitter.
#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_GET_SLOTS(slots, cursor, work, canvas)
Starts at the effect's entry in the whole work-slot array.
#define EFFECT_END_FRAME(work)
The usual end of an effect frame: counts down the targets' flash timers (ObjectGroup_TickMemberTimers...
#define EFFECT_BEGIN_NARROW_CANVAS(bgControl)
Opens the canvas layer at the canvas's own width, one texel per pixel, where BattleFx_BeginCanvasLaye...
u8 gSpire_RockCounts[]
u8 gSpire_DropFrames[]
s8 gSpire_RockX[]
u16 gSpire_ShardCells[]
u8 gSpire_ShardOffsets[32][2]
Where each of a rock's 21 shards starts, x then y, before the rock's offset across.
u8 gSpire_ShardHeights[]
u8 gSpire_ShardWidths[]
@ SPIRE_SHARD_Y
canvas y
@ SPIRE_SHARD_X
canvas x
void AudioCommand_PlayFar(s32 id)
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_BLITTER
Definition heap_state.h:46
#define REG_BG2X
Definition io_reg.h:65
#define REG_BLDCNT
Definition io_reg.h:119
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
Definition math.c:10
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_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
char ResourceId_BoulderSheet
#define SE_132
Definition songs.h:125
#define SE_HEAVY_IMPACT
Definition songs.h:127
#define SPIRE_SHARDS
shards per rock
Definition spire.c:11
#define SPIRE_ROCK_WIDTH
the boulder picture, the first in the sheet
Definition spire.c:7
#define SPIRE_FALL_FRAMES
Frames a boulder falls, from its drop frame (gSpire_DropFrames) until it lands, shakes the screen and...
Definition spire.c:14
#define SPIRE_ROCK_HEIGHT
the boulder picture's height
Definition spire.c:8
void BattleFx_RunSpire(struct BattleEffectArgument *effect)
Shattering rocks: boulders drop along the row of targets, centred on it, and burst into tumbling shar...
Definition spire.c:23
#define SPIRE_SHARD_CELLS
The shard pictures in the sheet, after the boulder.
Definition spire.c:10
The command shared by an effect's caller, dispatcher and handlers.
s16 actors[8]
the targets' unit ids, count of them
s32 variant
the ability's size, from 0 (Quake, then Earthquake)
s32 count
targets in actors, at least 1
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
A point projected onto the screen, with its depth.
Definition effect_step.h:46
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
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
#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