Alchemy
Loading...
Searching...
No Matches

rushing_strike.c

Go to the documentation of this file.
1/// @file
2/// Rushing strikes (Bone Charge, Brute Force, Onslaught, Headbutt).
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7/// Packs 288 rows of 40 bytes to half width, keeping every second byte
8/// (the bytes of the odd columns win).
9///
10/// Called by BattleFx_RunRushingStrike and twice by the casting impacts, to
11/// squeeze a 40-pixel-wide sheet into 20-pixel pictures. Writes only dst.
12///
13/// src: the rows to pack.
14/// dst: receives the packed rows, half the stride apart.
15/// stride: the bytes in one row of src.
16/// rowCount: ignored; 288 rows are always packed.
17void Graphics_PackTileRows(u8 *src, u8 *dst, s32 stride, s32 rowCount) {
18 s32 row = 0;
19 s32 rows = 288;
20 s32 offset = 0;
21
22 do {
23 s32 x;
24
25 for (x = 0; x != 40; x++) {
26 dst[offset / 2 + x / 2] = src[offset + x];
27 }
28 offset += stride;
29 row++;
30 } while (row != rows);
31}
32
33#define RUSHING_STRIKE_SPARK_COUNT 64 ///< sparks
34#define RUSHING_STRIKE_RING_BYTES 0x3c0 ///< one 20x48 ring picture
35
36/// Rushes the target and scatters sparks in the fire pillar palette.
37///
38/// Abilities: Bone Charge (kind 311).
41}
42/// Rushes the target and scatters sparks in the ice-block palette.
43///
44/// Abilities: Brute Force (kind 314).
47}
48/// Rushes the target and scatters sparks in the pink-burst palette.
49///
50/// Abilities: Onslaught (kind 326).
53}
54/// Rushes the target and scatters sparks in the blast palette.
55///
56/// Abilities: Headbutt (kind 339).
59}
60#define RUSHING_STRIKE_FRAMES 60
61#define RUSHING_STRIKE_FRAME 10 ///< the user strikes
62
63/// Rushing strike: the user rushes at the first target and strikes it on
64/// frame 10; a ring flares where it hits and 64 sparks scatter, over 60
65/// frames in all.
66///
67/// Called by the four wrappers above. work->particles holds the sparks, each
68/// variant its frames left; the six packed ring pictures go to
69/// Ram_MapCellBuffer. Moves the user with BattleFx_SetApproachMotion and does
70/// not bring it back. Copies the mode's palette over the first 128 bytes of
71/// BG palette RAM, sets work->shakeFrames on the strike, and ends with the
72/// transfer callback removed, the blitters freed and the canvas layer closed.
73///
74/// effect: the user and the targets.
75/// mode : the palette: 0 fire pillar, 1 ice block, 2 pink burst, 3 blast.
77 /* FAKEMATCH: the blitter and camera declarations and store order keep the
78 * spill slots and loop preheader order; as Ram_MapCellBuffer at the two
79 * uses of cells, 2 instructions differ in tbs-en. */
80 void **slots;
81 void **cursor;
82 struct BattleEffectWork *work;
83 void *canvas;
84 BlitterPair draw;
85 struct BattleCamera *camera;
86 u8 *sheet;
87 struct EffectStep *spark;
88 struct EffectStep *newSpark;
89 struct EffectPosition origin;
90 struct EffectPosition screen;
91 struct EffectPosition sparkScreen;
92 struct MotionObject *target;
93 s32 frame;
94 s32 i;
95 s32 size;
96 s32 ringFrame;
97 s32 paletteId;
98 u8 *cells;
99
100 cells = Ram_MapCellBuffer;
101 EFFECT_GET_SLOTS(slots, cursor, work, canvas);
102 camera = EFFECT_SLOT(slots, HEAP_SLOT_CAMERA);
103 sheet = EFFECT_SLOT(slots, HEAP_SLOT_BATTLE_SHEET);
104 work->effect = effect;
106
107 // The top half, and the bottom half flipped; mirrored on side 1.
108 if (work->effect->side == 0) {
112 } else {
117 }
120
121 // Pictures and palette: the ring is the yellow orb packed to half width,
122 // six 20x48 pictures, into the map cell buffer, so that the blue burst can
123 // take its place in the sheet.
126 0);
127 Graphics_PackTileRows(work->sheet, (u8 *)cells, 40, 288);
129 1);
130 switch (mode) {
131 case 0:
132 paletteId = (s32)&ResourceId_FirePillarSheetB;
133 break;
134 case 1:
135 paletteId = (s32)&ResourceId_IceBlockSheet;
136 break;
137 case 2:
138 paletteId = (s32)&ResourceId_PinkBurstSheet;
139 break;
140 default:
141 paletteId = (s32)&ResourceId_BlastSheet;
142 break;
143 }
144 Iwram_CopyWords((void *)BG_PLTT, Resource_GetTableEntry(paletteId), 128);
146
147 // Send the user in, 80% of the way over 10 frames, and ready the sparks
148 // at the target (they fly towards the middle of the field). Spark i lives
149 // 16 + i / 2 frames.
150 BattleFx_SetApproachMotion(work->effect->actor, work->effect->actors[0], 10);
151 target = GetBattleObjectSlotFar(work->effect->actors[0])->object;
152 for (i = 0; i != RUSHING_STRIKE_SPARK_COUNT; i++) {
153 newSpark = &work->particles[i];
154 newSpark->x = target->x;
155 newSpark->y = target->y + 0xa0000; // 10 pixels up
156 newSpark->z = target->z;
157 SET_VELOCITY(newSpark, (Random16() & 0x1ff) << 11,
158 ((Random16() & 255) - 64) << 11,
159 ((Random16() & 255) - 128) << 11);
160 if (newSpark->x > 0)
161 newSpark->velocityX = -newSpark->velocityX;
162 newSpark->variant = i / 2 + 16;
163 }
164 EffectPosition_ProjectBattler(work->effect->actors[0], &origin);
165
166 for (frame = 0; frame != RUSHING_STRIKE_FRAMES; frame++) {
167 // For 15 frames, draw the burst at the user as it rushes in: the top
168 // half, then the bottom half flipped below it.
169 if (frame <= 14) {
171 draw[0](canvas, work->sheet, screen.x / 2 - 16, screen.y - 48, 40, 32);
172 draw[1](canvas, work->sheet, screen.x / 2 - 16, screen.y - 16, 40, 32);
173 }
174 if (frame == RUSHING_STRIKE_FRAME) {
176 POSE_DAMAGE, 0, 8);
179 work->shakeFrames = 8;
180 }
181 // The ring: six pictures, 2 frames each, from frame 8, at the target's x
182 // and the height where the user was last drawn.
183 ringFrame = frame - 8;
184 if (ringFrame >= 0 && ringFrame <= 11) {
185 s32 ring = ringFrame / 2;
186 draw[0](canvas, cells + ring * RUSHING_STRIKE_RING_BYTES,
187 origin.x / 2 - 16, screen.y - 40, 20, 48);
188 }
189 // From frame 8 the sparks fly, shrinking as their lives run out and
190 // sinking slightly.
191 if (ringFrame >= 0 && ringFrame <= 55) {
193 for (i = 0; i != RUSHING_STRIKE_SPARK_COUNT; i++) {
194 spark = &work->particles[i];
195 size = spark->variant;
196 if (size > 0) {
197 EffectPosition_ProjectPoint(&spark->x, &sparkScreen);
198 size >>= 4;
199 size += 2;
200 sparkScreen.x >>= 1;
201 EFFECT_DRAW_MOTE(draw[0], canvas, sheet, sparkScreen.x, sparkScreen.y,
202 size);
203 EffectStep_AdvanceWithGravity3D(spark, 60, -0x200);
204 spark->variant--;
205 }
206 }
207 }
208 Camera_ApplyShake(8, 8);
209 EFFECT_END_FRAME(work);
210 }
212}
213
214#undef RUSHING_STRIKE_SPARK_COUNT
215#undef RUSHING_STRIKE_RING_BYTES
216#undef RUSHING_STRIKE_FRAMES
217#undef RUSHING_STRIKE_FRAME
@ SPRITE_COLOR_WHITE
solid colour 15, white
Definition animspr.h:26
@ POSE_DAMAGE
taking damage
Definition battle.h:176
@ COMPOSITE_FLIP_X
@ COMPOSITE_FLIP
@ COMPOSITE_FLIP_Y
@ COMPOSITE_MAX
BattleEffectDrawRectangle DrawRectangle
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 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_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_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()
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_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_VIEW_FROM_CAMERA(camera)
Starts a frame's 3D projection from the battle camera: resets the transform, then looks from camera->...
struct BattleObj * GetBattleObjectSlotFar(s32 objectId)
Far call to BattleObjGet.
void BattleMotion_ApplyVariantMotionFar(s32 id, s32 variant)
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_ALTERNATE
Definition heap_state.h:47
@ 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
#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_VELOCITY(p, vx, vy, vz)
Definition macros.h:18
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
Definition math.c:10
void EffectPosition_ProjectBattler(s32 id, struct EffectPosition *position)
The screen position of a battler, 16 pixels higher.
Definition positions.c:100
void EffectStep_AdvanceWithGravity3D(struct EffectStep *step, s32 damping, s32 gravity)
Moves a particle one frame in three dimensions: adds its velocity, then gravity to its vertical speed...
Definition positions.c:29
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_SetApproachMotion(s32 id, s32 targetId, s32 frames)
Moves a battler 80% of the way to another one over a number of frames, in its action pose.
#define Ram_MapCellBuffer
Definition ram_buffer.h:10
char ResourceId_PinkBurstSheet
char ResourceId_YellowOrbSheet
char ResourceId_BlueBurstSheet
char ResourceId_BlastSheet
char ResourceId_ParticleSpritesA
char ResourceId_IceBlockSheet
char ResourceId_FirePillarSheetB
void BattleFx_RunBoneCharge(struct BattleEffectArgument *effect)
Rushes the target and scatters sparks in the fire pillar palette.
void BattleFx_RunHeadbutt(struct BattleEffectArgument *effect)
Rushes the target and scatters sparks in the blast palette.
void BattleFx_RunOnslaught(struct BattleEffectArgument *effect)
Rushes the target and scatters sparks in the pink-burst palette.
#define RUSHING_STRIKE_SPARK_COUNT
sparks
void BattleFx_RunBruteForce(struct BattleEffectArgument *effect)
Rushes the target and scatters sparks in the ice-block palette.
#define RUSHING_STRIKE_RING_BYTES
one 20x48 ring picture
#define RUSHING_STRIKE_FRAMES
#define RUSHING_STRIKE_FRAME
the user strikes
void Graphics_PackTileRows(u8 *src, u8 *dst, s32 stride, s32 rowCount)
Packs 288 rows of 40 bytes to half width, keeping every second byte (the bytes of the odd columns win...
void BattleFx_RunRushingStrike(struct BattleEffectArgument *effect, s32 mode)
Rushing strike: the user rushes at the first target and strikes it on frame 10; a ring flares where i...
#define SE_HEAVY_IMPACT
Definition songs.h:127
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 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 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 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
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 y
16.16 fixed-point pixels
Definition motobj.h:24
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
unsigned char u8
Definition types.h:11
#define EFFECT_CLIP_BOUNDS
Clips overflow on all four sides.
Definition effect.h:224
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