34 (
volatile u32 *)dma0);
126 if (state->
end == 64) {
154 scanlineData = state->
pages[1 ^ state->
page];
161 switch (state->
mode) {
163 *scanlineData++ = 0x7f7f;
165 value = state->
value;
167 value = 32 - (value & 31);
174 for (i = 0; i < 160; i++) {
175 leftEdge = (
Random16() * (241 - value)) >> 16;
176 scanlineData[0] = ((leftEdge << 8) | (leftEdge + value));
182 value = state->
value;
185 *scanlineData++ = shape->
first;
186 *scanlineData++ = shape->
second;
188 *scanlineData++ = shape->
second;
189 *scanlineData++ = shape->
first;
192 for (i = 0; i < 3; i++) {
193 span = &shape->
spans[i];
194 lineCount = span->
cnt;
196 if (lineCount != 0) {
198 for (k = 0; k < lineCount; k++) {
199 scanlineData[0] = right;
206 radiusSquaredQ16 = span->
x0;
210 for (k = 0; k < lineCount; k++) {
211 scanlineData[0] = (((radiusSquaredQ16 +
212 (delta - radiusSquaredQ16) * k / lineCount)
214 (left + (right - left) * k / lineCount));
223 value = state->
value - 1;
226 *scanlineData++ = 0x7f7f;
228 *scanlineData++ = 0x7f7f;
234 for (i = 0; i < 160; i++) {
235 horizontalExtent = (value << 4) + ((16 *
Random16()) >> 16);
236 if (horizontalExtent > 255) {
237 horizontalExtent = 255;
239 scanlineData[0] = horizontalExtent;
250 u8 *pageBytes = (
u8 *)state + (1 ^ state->
page) *
sizeof(state->
pages[0]);
251 const u16 header[4] = {0x7f7f, 1, 1, 0x7f7f};
252 u32 headerSize = 2 *
sizeof(
u16);
255 value = state->
value;
257 if ((
u32)value > 32) {
258 headerSize =
sizeof(header);
261 memcpy(pageBytes, header, headerSize);
262 pageBytes += headerSize;
264 *scanlineData++ = 0x7f7f;
266 if ((
u32)value > 32) {
268 *scanlineData++ = 0x7f7f;
276 radiusSquaredQ16 = (value * value) << 16;
277 for (i = 0; i < 160; i++) {
280 Iwram_Sqrt(radiusSquaredQ16 - ((value * value) << 16)) >> 8;
281 left = 120 - horizontalExtent;
282 right = horizontalExtent + 120;
296 edges = (left << 8) + right;
297 memcpy(pageBytes, &edges,
sizeof(edges));
298 pageBytes += 2 *
sizeof(
u16);
300 scanlineData[0] = ((left << 8) + right);
308 value = state->
value;
311 *scanlineData++ = 0x7f7f;
313 *scanlineData++ = 0x7f7f;
318 value = (
u32)(240 * (value & 31)) >> 5;
319 for (i = 0; i < 160; i += 2) {
320 oppositeEdges = ((240 - value) << 8) + 240;
321 scanlineData[0] = value;
322 scanlineData[2] = oppositeEdges;
331 ax = map->
viewX & 0xffff0000;
332 cameraY = map->
viewY & 0xffff0000;
335 ax = view7[0] & 0xffff0000;
336 cameraY = view7[1] & 0xffff0000;
340 centerX = (obj->
x - ax) / 0x10000;
341 centerY = ((obj->
z - obj->
y) - cameraY) / 0x10000 - 16;
347 *scanlineData++ = state->
active;
348 *scanlineData++ = state->
mask;
349 value = state->
value;
350 if ((value & 32) == 0) {
351 value = 32 - (value & 31);
362 radiusSquaredQ16 = (value * value) << 16;
363 for (i = 0; i < 160; i++) {
366 Iwram_Sqrt(radiusSquaredQ16 - ((value * value * 3) << 15)) >> 8;
367 left = centerX - horizontalExtent;
368 right = centerX + horizontalExtent;
381 scanlineData[0] = ((left << 8) + right);
388 cameraX = map->
viewX & 0xffff0000;
389 cameraY8 = map->
viewY & 0xffff0000;
392 cameraX = view8[0] & 0xffff0000;
393 cameraY8 = view8[1] & 0xffff0000;
398 centerX = (state->
centreX - cameraX) / 0x10000;
399 centerY = (state->
centreY - cameraY8) / 0x10000 - 16;
401 *scanlineData++ = state->
mask;
402 *scanlineData++ = state->
active;
403 value = state->
value;
405 value = 32 - (value & 31);
410 radiusSquaredQ16 = (value * value) << 16;
411 for (i = 0; i < 160; i++) {
414 Iwram_Sqrt(radiusSquaredQ16 - ((value * value * 3) << 15)) >> 8;
415 left = centerX - horizontalExtent;
416 right = centerX + horizontalExtent;
439 scanlineData[0] = ((left << 8) + right);
449 ax = map->
viewX & 0xffff0000;
450 cameraY = map->
viewY & 0xffff0000;
453 ax = view9[0] & 0xffff0000;
454 cameraY = view9[1] & 0xffff0000;
457 centerX = (obj->
x - ax) / 0x10000;
458 centerY = ((obj->
z - obj->
y) - cameraY) / 0x10000 - 16;
461 *scanlineData++ = state->
mask;
462 *scanlineData++ = state->
active;
463 value = state->
value;
465 value = 32 - (value & 31);
470 radiusSquaredQ16 = (value * value) << 16;
471 for (i = 0; i < 160; i++) {
474 Iwram_Sqrt(radiusSquaredQ16 - ((value * value * 3) << 15)) >> 8;
475 left = centerX - horizontalExtent;
476 right = centerX + horizontalExtent;
489 scanlineData[0] = ((left << 8) + right);
498 ax = map->
viewX & 0xffff0000;
499 cameraY = map->
viewY & 0xffff0000;
501 view77 = &map->
viewX;
502 ax = view77[0] & 0xffff0000;
503 cameraY = view77[1] & 0xffff0000;
506 centerX = (obj->
x - ax) / 0x10000;
508 centerY = ((obj->
z - obj->
y) - cameraY) / 0x10000 - 8;
511 *scanlineData++ = state->
mask;
512 *scanlineData++ = state->
active;
513 value = state->
value;
515 value = 32 - (value & 31);
521 radiusSquaredQ16 = (value * value) << 16;
522 for (i = 0; i < 160; i++) {
525 Iwram_Sqrt(radiusSquaredQ16 - ((value * value * 3) << 14)) >> 8;
526 left = centerX - horizontalExtent;
527 right = centerX + horizontalExtent;
540 scanlineData[0] = ((left << 8) + right);
566 state->
mask = 0x3f3f;
608 transitionKind = (mode >> 8) & 0xff;
610 variant = mode & 0xff;
611 switch (transitionKind) {
630 state->
mode = variant;
648 state->
mode = variant;
702 transitionKind = (
mode >> 8) & 0xff;
703 variant =
mode & 0xff;
704 switch (transitionKind) {
716 state->
mode = variant;
732 state->
mode = variant;
801 if (*duration != 0) {
804 if (*step >= *duration) {
821 edgeDistance = state->
value;
822 if (edgeDistance > 79) {
841 if (*duration != 0) {
844 if (*step >= *duration) {
859 edgeDistance = state->
value;
860 if (edgeDistance > 79) {
863 }
else if (edgeDistance != 0 && (
gFrameCount & 1)) {
915 if (scanline <= 158) {
954 ditherIndex = state->
value - 1;
957 if (ditherIndex & 32)
959 ditherIndex = (ditherIndex & 31) * 2;
960 for (i = 0; i <= 1; i++) {
964 *tileByte = (*tileByte & 0x0f) | (colorIndex << 4);
966 *tileByte = (*tileByte & 0xf0) | colorIndex;
986 for (remainingWords = 7; remainingWords >= 0; --remainingWords)
987 pattern = (pattern << 4) | color;
989 for (remainingWords = 7; remainingWords >= 0; --remainingWords)
void * ObjectTable_Get(u32 actorIndex)
Returns the actor in slot index (0 to 65), or NULL.
void(*) SchedulerCallback(void)
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_SetPrimaryBufferValue(u32 color)
Sets the buffer's source backdrop colour (BG colour 0 of its palette copy).
void BattleFx_StartBufferInterpolation(s32 frames)
Starts moving the shown colours to the target colours over frames frames: sets work->duration,...
void BattleFx_ApplyColorToSourceBuffer(s32 mode, s32 half)
Sets the colours the buffer shows now (see BattleFx_BuildBuffer).
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.
void Fade_ToBlack(s32 frames)
Fades out to black.
void Fade_FromBlack(s32 frames)
Fades in from black.
void UiWindow_FillFromSceneFar(void *dst)
void Runtime_SetIrqHandler(u32 irq, s32 vcount, InterruptHandler handler)
Installs handler for interrupt irq and enables that interrupt, or with a null handler disables it and...
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
volatile u32 gFrameCount
Frames WaitFrames has finished.
const s8 gDisplayTransition_EdgeOffsets[32]
The wobble of the circle edge of window transition mode 8.
const u8 gDisplayTransition_DitherTable[64]
0 to 63 shuffled: the order in which the dissolve sets the pixels.
const u8 gDisplayTransition_NoiseWidths[34]
The width of the bars of window transition mode 0, by progress.
struct GameState gGameState
struct DisplayTransitionState * gDisplayTransition
Slot 31.
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 DMA_HBLANK_WORD_PER_LINE
#define BG_SCREEN_BLOCK(n)
#define DMA_START_TIMING_DRQ_REPEAT
A DMA control's start timing (bits 12 and 13), cartridge request (bit 11) and repeat (bit 9): the bit...
@ DISPCNT_MODE_2
BG2 and BG3 affine.
#define WIN_RANGE(start, end)
A REG_WINxH or REG_WINxV value: the window covers start up to, but not including, end.
#define IO_WRITE_QUEUE_PUSH(address, value, control)
Disables interrupts to add one register write or DMA to the queue; a write to a full queue is dropped...
#define Io_Write16(v, reg)
Writes a value to a 16-bit register or memory location.
static s32 Iwram_Sqrt(s32 value)
static s32 Iwram_SignedDivide(s32 dividend, s32 divisor)
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
void DisplayTransition_InitializeBattleEffectState(s32 mode)
Starts window transition mode at value 0, with no duration: the caller moves it.
void DisplayState_ClearFlags(s32 clearBg3, s32 clearBg2, s32 clearBg1)
Clears the map's display-control bits for backgrounds 3, 2 and 1 (0x0800, 0x0400 and 0x0200) for each...
void DisplayTransition_FillTilemapAndSolidTile(s32 color)
Fills background screen block 4 with tile 0 in palette 15 and, unless color is -1,...
void DisplayTransition_UpdateScanline(void)
The VCount interrupt of the centre-line transition: switches the display to mode 2 (nothing shown) at...
void DisplayTransition_Start(s32 mode, s32 frames)
Fades the screen in over frames frames.
void DisplayTransition_Finish(s32 mode, s32 frames)
Fades the screen out over frames frames, as DisplayTransition_Start fades it in.
void DisplayTransition_UpdateScanlineTable(void)
Each frame of a window transition: advances its value toward its end (and at the end turns the window...
void BattleFx_StartWindowHBlankDma(void)
Each frame, before drawing: turns windows 0 and 1 on, writes the first four values of the shown page ...
void DisplayTransition_SuspendCallbacks(void)
Suspends the window transition's two callbacks.
void DisplayTransition_InitializeState(s32 value)
Starts a dissolve of the given mode and waits 120 frames.
void DisplayTransition_Update(void)
Each frame of the centre-line transition: moves the value toward its end and sets the two lines where...
struct DisplayTransitionState * DisplayTransition_AllocateAndClearState(void)
Allocates the display transition state (heap block 31) and clears it.
void DisplayTransition_UpdateFrame(void)
Each frame of the dissolve: moves the value toward its end and sets two more of the solid tile's 64 p...
void DisplayTransition_UpdateFromCentre(void)
As DisplayTransition_Update, but the lines flicker every other frame.
struct TransitionShape gDisplayTransition_Shapes[]
What every part of object.c shares: its includes and the macros and types more than one part uses.
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...
s32 Scheduler_SuspendTasks(SchedulerCallback callback)
Suspends the task running callback, or every task when callback is null, by setting bit 0 of its orde...
s32 Scheduler_RemoveCallback(SchedulerCallback callback)
Unschedules the task running callback: clears its routine and gives it order 0x7fff,...
The display transition state as the centre-line transition and the dissolve read it: the dissolve's t...
u8 ditherToggle
DisplayTransitionState's page: the dissolve flips it each frame and never reads it.
s8 start
the value's first step
u16 value
The progress, moved from start to end over duration frames: bit 5 says whether the dissolve fills or ...
s8 duration
frames; 0 when the value is not moving
s8 end
the value's last step
u8 paletteNibbles[0x22]
DisplayTransitionState's solidTile, as 4-bit pixels two a byte: the dissolve sets two more each frame...
The display transition state (heap block 31): two pages of window edges for every line,...
u16 value
The progress, moved from start to end over duration frames: bit 5 says whether the transition opens o...
u8 page
the pages entry shown; the next is built in the other
s16 active
WININ, or WINOUT by mode: 1 when a transition starts.
s8 nextMode
The mode taken when the value reaches its end; 0 ends the transition.
s8 end
the value's last step; 64 hides BG1 to BG3 and sprites
s8 start
the value's first step
u16 mode
The window transition's shape: modes are listed at DisplayTransition_UpdateScanlineTable.
s16 mask
WINOUT, or WININ by mode: 0x3f3f or 63 when a transition starts.
u16 pages[2][322]
Window edges, two pages: WININ and WINOUT, then a WIN0H and WIN1H pair, each (left << 8 | right),...
u32 solidTile[8]
The dissolve's solid tile, one 8 by 8 tile of 4-bit pixels.
s32 centreX
16.16 fixed-point pixels: the centre of the ellipse around a point (mode 8), set by the Reveal effect...
s8 duration
frames; 0 when the value is not moving
s32 centreY
as centreX: the target's z less its y
The map work's display fields that transitions use: its display control bits and the lines where the ...
u16 irqSecondLine
scanlines; secondLine as the VCount interrupt reads it
u16 firstLine
scanlines: where the screen is hidden, 200 when it is not
u16 irqFirstLine
scanlines; firstLine as the VCount interrupt reads it
u16 secondLine
scanlines: where the screen is shown again, 250 when it is not hidden
u16 irqPhase
The VCount interrupt's phase: 0 waiting for a line above 159, 1 neither line passed,...
u16 dispcnt
Display control bits ORed into DISPCNT; DisplayState_ClearFlags clears those of backgrounds 1 to 3.
s32 selectedActor
the leader: its unit and its actor
One of the 64 field objects in the object pool (heap slot 5): its script, position,...
s32 z
16.16 fixed-point pixels
s32 x
16.16 fixed-point pixels
s32 y
16.16 fixed-point pixels
One step of the shape window transition: the WININ and WINOUT values, swapped as the transition opens...
struct TransitionSpan spans[3]
A run of screen lines in a transition shape: one window edge pair for every line, or,...
void * memcpy(void *destination, const void *source, unsigned long size)