16 s32 cameraX = camera[0];
17 s32 cameraZ = camera[1];
26 if (--particle->
timer == 0xffff)
33 x = (particle->
posX - cameraX) / 0x10000 + *frame++;
34 y = (particle->
posZ - particle->
posY - cameraZ) / 0x10000 + *frame++;
35 if ((
x >= -16 &&
x <= 239) &&
y >= -32 &&
y <= 159) {
42 particle->
size = *(
u8 *)(frame + 1);
45 if (particle->
timer == 0) {
48 x = leader[0] + (
Random16() << 8) - 0x800000;
49 y = leader[2] + (
Random16() << 8) - 0x800000;
76 ((intervalDraw * 400) >> 16) - ((intervalJitter * 100) >> 16) + 150;
131 words = (
u32 *)particle;
133 *words++ = 0x40000400;
140 particle->
timer = (i & 15) + 1;
171 if (--mote->
timer != 0xffff) {
173 s32 cameraX = camera[0];
174 s32 cameraZ = camera[1];
177 u32 secondJitterDraw;
185 x = ((mote->
posX - cameraX) >> 16) +
186 (((firstJitterDraw & 1) + (secondJitterDraw & 1)) >> 1) - 1;
187 y = ((mote->
posZ - mote->
posY - cameraZ) >> 16) - age;
188 if ((
u32)(
x + 16) <= 255 &&
y >= -32 &&
y <= 159) {
189 if (mote->
timer < 60) {
192 }
else if (mote->
timer < 90) {
201 mote->
y =
y - (mote->
delay >> 2);
209 if (spawned < 8 && mote->
timer == 0) {
212 x = leader[0] + (
Random16() << 8) - 0x800000;
213 y = leader[2] + (
Random16() << 8) - 0x800000;
255 *(
s32 *)p = 0x40000400;
263 mote->
timer = (i & 15) + 1;
301 camera = &map->
viewX;
310 if (sparkle->
timer != 0) {
318 x = ((sparkle->
posX - cameraX) >> 16) + (((a & 1) + (b & 1)) >> 1);
320 sy = (sparkle->
posZ - sparkle->
posY - cameraZ) / 0x10000 +
323 if ((
u32)(
x + 15) <= 255 && sy >= -32 && sy <= 159) {
343 if (spawned <= 3 && sparkle->
timer == 0 && work->
stopped == 0) {
346 sparkle->
posX = spawnX;
347 sparkle->
posZ = spawnZ;
353 }
else if ((
Random16() & 255) == 0) {
356 spawnX = leader[0] + (
Random16() << 8) - 0x800000;
357 spawnZ = leader[2] + (
Random16() << 8) - 0x800000;
358 sparkle->
posX = spawnX;
359 sparkle->
posZ = spawnZ;
404 *(
u32 *)attr = clear;
407 *(
u32 *)attr = 0x40000400;
409 *(
u32 *)attr = 0xd400;
412 sparkle->
posX = clear;
413 sparkle->
posZ = clear;
415 sparkle->
timer = (i & 15) + 1;
445 state->
timer = 0x7FFF;
const u8 gFieldFx_GroundParticleTiles[]
struct BattleEffectBuffers * gPaletteBufferWork
void BattleFx_InterpolateBuffers(s16 *source, s16 *target, s16 *step, s32 frames)
Sets each of the 1344 colour channels of step to the amount to add each frame for source to reach tar...
void BattleFx_ApplyColorToTargetBuffer(s32 mode, s32 half)
Sets the colours the buffer moves toward (see BattleFx_BuildBuffer); does nothing without a colour bu...
void BattleFx_BuildBuffer(u32 mode, u16 *src, u16 *dst, s32 half)
Builds colours for the colour buffer from the palette src into dst, which holds each colour as B,...
static __inline__ void Dma_Set(const volatile void *source, volatile void *destination, u32 control, volatile u32 *channel)
Starts a DMA transfer: stores the source, destination and control words into channel's registers with...
#define Dma_Fill32(value, destination, size)
Fills size bytes at destination with the word value by DMA3.
s32 Map_GetTerrainHeightFar(s32 layer, s32 x, s32 y)
s32 GameFlag_TestFar(s32 flag)
void AudioCommand_PlayFar(s32 id)
const u8 gFieldFx_SparkleTiles[]
const u8 gFieldFx_MoteTiles[]
volatile u32 gFrameCount
Frames WaitFrames has finished.
const struct SparkleFrame gFieldFx_SparkleFrames[32]
{dy, tile}
const s16 gFieldFx_GroundParticleFrames[80]
{dx, dy, tile, shape, size} for each of 16 frames.
void * gFieldBlendWork[]
From slot 24.
void * Runtime_AllocateBlock(s32 kind, s32 size)
As Runtime_AllocateHeapBlock, but tries EWRAM first, for blocks that need room more than speed: the b...
#define WORK_SLOT(n)
Reads slots through their own addresses; adjacent slots are reached by offsets.
#define BLEND_ALPHA(top, bottom)
A REG_BLDALPHA value: top and bottom are the two targets' weights, out of 16.
#define Io_Write16(v, reg)
Writes a value to a 16-bit register or memory location.
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
void Runtime_ReleaseHeapBlock(s32 slot)
#define FIELD_WEATHER_PARTICLE_COUNT
What every part of psynergy_effects.c shares: its includes and the macros and types more than one par...
void Runtime_PushSlotEntry(void *slotEntry, s32 slot)
Links a sprite entry into depth slot slot (clamped to 0..255) for this frame.
void BattleFx_SetQueuedSoundAndPlay(s32 soundId)
Plays SE_298, then soundId (SE_289 for -1), and remembers soundId for BattleFx_PlayQueuedSound in the...
s32 Resource_DecodeByteLz(const void *source, void *destination)
Decodes a byte-oriented LZ resource and returns its unpacked byte count.
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...
The colour buffer (heap block 32) that fades the BG and OBJ palettes: the source palette,...
u16 target[0x540]
the colours current moves toward, as current
The storm's lightning work: the colours it flashes between and their difference, the countdown to the...
s16 loud
nonzero plays the louder thunderclap, SE_172 for SE_171
s16 from[0x540]
The storm's dark colours (PALETTE_TRANSFORM_WARM), as the colour buffer's B, G and R channels: each f...
s16 delta[0x540]
the 12-frame steps from to back to from
s16 to[0x540]
the lit colours (PALETTE_TRANSFORM_PALE), as from
s16 enabled
Nonzero arms the next flash a random 51 to 549 frames after each, with a thunderclap.
s16 timer
Frames to the next flash, which comes in three, 5 frames apart; below 0 stops the lightning.
Work slot 29 while ground particles, motes or sparkles run.
struct GroundParticle particles[FIELD_WEATHER_PARTICLE_COUNT]
s32 tileBase
Their first tile in VRAM.
s32 stopped
Prevent new sparkle bursts while set.
s32 entry
Resource entry holding the effect's tiles.
One weather particle: OAM attributes followed by its world position.
u16 timer
Frames left; zero frees the particle.
s32 delay
Motes: height risen; sparkles: phase within a burst.
s32 posY
The ground's height there.
u16 y
The OAM entry's attributes 0 to 2: the start routines write them whole as semi-transparent,...
u16 size
From the ground particle frame; motes, sparkles: 1.
u16 tile
The work's tileBase plus the frame's tile.
s32 posZ
World position, in 16.16 pixels.
u16 affineIndex
Sparkles: 8 on alternate frames, else 0.
u16 shape
From the ground particle frame; motes, sparkles: 0.
s32 posX
World position, in 16.16 pixels.
A particle's first word, seen as a value or a link.
s32 Resource_FindFreeEntry(void)
Returns the number of the first free cache entry, or VRAM_CACHE_ENTRY_COUNT when all are taken.
s32 VramCache_Load(u32 no, u32 size, const void *src)
Gives cache entry no size bytes of sprite VRAM and copies src there.
void FieldMotes_Update(void)
Scheduler callback: the floating motes.
void FieldFx_ResumeLightning(void)
Restarts the lightning: the next flash in 128 frames, repeating.
void FieldFx_UpdateLightning(void)
Scheduler callback for the storm: every 150 to 550 frames lightning flashes the palette three times (...
void FieldMotes_Start(void)
Starts the floating motes (FieldMotes_Update): loads their tiles and puts 32 of them under the leader...
void FieldFx_StartLightning(void)
Starts the storm's lightning (FieldFx_UpdateLightning): builds the dark (0x10003) and lit (0x10005) p...
void BattleFx_StartBufferBlend(s32 from, s32 to)
Flashes the palette once, 120 frames from now, from palette from to palette to (BattleFx_BuildBuffer ...
void FieldFx_UpdateGroundParticles(void)
Scheduler callback: animates the ground particles.
void FieldEffect_UpdateSparkles(void)
Scheduler callback: the sparkles.
void FieldFx_StopLightning(void)
Stops the lightning: no flash for 0x7fff frames, and none after.
void FieldEffect_InitSparkles(void)
Starts the sparkles (FieldEffect_UpdateSparkles): loads their tiles and clears the 32 sparkles.
void FieldFx_StartGroundParticles(void)
Starts the ground particles (FieldFx_UpdateGroundParticles) with sound 170: loads their tiles and put...
void FieldFx_LastLightning(void)
One last flash of lightning in 12 frames, then no more.