Alchemy
Loading...
Searching...
No Matches

background.c

Go to the documentation of this file.
1/// @file
2/// The battle background, its palette and perspective, the camera's zoom and
3/// the units' highlights.
4/// Part of battle.c, the battle object, compiled only through it.
5
7
8// The value Select picks in the debug value editor
9// (Runtime_AdjustDebugValueWithButtons), which the international editions
10// changed.
11#if TBS_PATCH_1
12#define DEBUG_SELECT_VALUE 0x18f
13#else
14#define DEBUG_SELECT_VALUE 480
15#endif
16
17/// BattlePresentation_SetPaletteLevel's and BattleBackground_Load's darkening
18/// step: each level takes 1092 from the 16.16 brightness, so level 60 is
19/// almost black.
20#define BACKGROUND_LEVEL_STEP 1092
21
22/// The perspective plane's BG2CNT for the first 256 picture tiles: a 256 by
23/// 256 affine map in screen block 7, 256 colours, priority 2.
24#define BACKGROUND_PLANE_UPPER \
25 (BGCNT_SIZE(1) | BGCNT_SCREEN_BASE(7) | BGCNT_256_COLORS | \
26 BGCNT_CHAR_BASE(2) | BGCNT_PRIORITY(2))
27/// The same map, reading the remaining picture tiles from character block 3.
28#define BACKGROUND_PLANE_LOWER \
29 (BGCNT_SIZE(1) | BGCNT_SCREEN_BASE(7) | BGCNT_256_COLORS | \
30 BGCNT_CHAR_BASE(3) | BGCNT_PRIORITY(2))
31/// Lines outside the plane read the padded map in screen block 31.
32#define BACKGROUND_PLANE_OFF \
33 (BGCNT_WRAP | BGCNT_SCREEN_BASE(31) | BGCNT_256_COLORS | \
34 BGCNT_CHAR_BASE(3) | BGCNT_PRIORITY(2))
35
36/// Copies the background's saved palette to BG palettes 6 to 13, darkened by
37/// level (0 for none).
38/// Called by BattlePres_RestorePalette with 0, and by effects that dim the
39/// background (beams.c, canvas.c). Sets BattleWork.brightness when it
40/// darkens; interrupts are off while it writes, as IME_DISABLE turns them off
41/// by storing REG_IME's own address, whose bit 0 is clear.
43 struct BattleWork *battle = gBattleWork;
44 u16 *palette = battle->palette;
45 u32 ime;
46 u32 *savedInterruptEnable = &ime;
47
48 /* FAKEMATCH(one-pass): the IME save in a one-pass block and a loop on a zero
49 * local, which keep it in its pointer's register; as a plain block, 4 of 43
50 * instructions differ in tbs-en. */
51 do {
52 u16 *interruptEnable = (u16 *)0x04000208;
53 s32 once = 0;
54
55 do {
56 *savedInterruptEnable = *interruptEnable;
57 *interruptEnable = (u32)interruptEnable;
58 } while (once);
59 } while (0);
60
61 if (level == 0) {
63 } else {
66 battle->brightness = 0x10000 - level * BACKGROUND_LEVEL_STEP, 128);
67 }
68 {
69 u32 saved = *savedInterruptEnable;
70
71 REG_IME = saved;
72 }
73}
74
75/// Switches the background's display mode, optionally sets its palette, and
76/// rebuilds both its maps.
77/// fade 0x80 restores the saved palette, another nonzero fade takes that
78/// much from each colour channel, and 0 leaves the palette alone; mode 1
79/// queues BATTLE_BG1CNT for BG1. Called with mode 1 by
80/// BattleFx_PlayUnitElementEffect and the effects' canvas layers (canvas.c),
81/// and with mode 2 by BattlePresentation_DispatchAction and
82/// Battle_ProcessRoundEnd. Sets BattleBackgroundView.mode, adds
83/// BattlePres_UpdateHBlankScroll when the mode was 0, and copies the first
84/// sprite palette to BG palette 5. unusedResource is not read.
86 s32 fade) {
87 struct BattleBackgroundView *transition =
89
90 if (transition->mode == 0) {
92 }
93 transition->mode = mode;
94
95 if (mode == 1) {
97 }
98
99 // XXX: BG palette 5 takes sprite palette 0 with colour 14 from BG palette
100 // 15's colour 4; which layer draws with it would say why.
101 Dma_Set((void *)OBJ_PLTT, (void *)&BG_PLTT_COLOR(5, 0),
103 *(u16 *)&BG_PLTT_COLOR(5, 14) = *(u16 *)&BG_PLTT_COLOR(15, 4);
104
105 if (fade == 0x80) {
107 REG_DMA3);
108 } else if (fade != 0) {
109 u16 *source = gBattleWork->palette;
110 u16 *destination = BATTLE_BG_PALETTE;
111 s32 colorIndex;
112
113 for (colorIndex = 0; colorIndex != 128; colorIndex++) {
114 s32 red = source[colorIndex] & 31;
115 s32 green = (source[colorIndex] >> 5) & 31;
116 s32 blue = (source[colorIndex] >> 10) & 31;
117
118 if (red > fade) {
119 red -= fade;
120 } else {
121 red = 0;
122 }
123 if (green > fade) {
124 green -= fade;
125 } else {
126 green = 0;
127 }
128 if (blue > fade) {
129 blue -= fade;
130 } else {
131 blue = 0;
132 }
133 destination[colorIndex] = (blue << 10) | (green << 5) | red;
134 }
135 }
136
139}
140
141/// Allocates the perspective plane's scanline work (heap slot 10) cleared,
142/// and sets the background's mode to 0, so the next load adds its scanline
143/// callback.
144/// Called once by Battle_RunEncounter before BattleBackground_Load.
146 struct BattleAffineHdma *work;
147 struct BattleBackgroundView *state;
148 work = Runtime_AllocateBlock(10, sizeof *work);
149 state = (struct BattleBackgroundView *)gTransitionWork;
150 Dma_Fill32(0, work, sizeof *work);
151 state->mode = 0;
152}
153
154/// Frees the perspective plane's scanline work (heap slot 10); called by
155/// Battle_RunEncounter as the battle ends.
157
158/// The bit decoder BattleBackground_Load copies to RAM and runs.
159typedef void (*BitDecoder)(const u8 *source, void *destination);
160
161/// Loads a battle background: its picture into character blocks 2 and 3, its
162/// palette into BattleWork.palette and, darkened by level, BG palettes 6 to
163/// 13, and both its maps.
164/// A negative level leaves the BG palettes alone. The resource is 256 bytes
165/// of palette and then the packed picture, which the RAM copy of
166/// BitDecoder_DecodeImage (heap slot 49) unpacks. Called with mode 1 by
167/// Battle_RunEncounter as the battle opens, and by the Atalanta and Boreas
168/// effects for their violet sky. Sets BattleBackgroundView.mode, and adds
169/// BattlePres_UpdateHBlankScroll when the mode was 0.
170void BattleBackground_Load(s32 mode, s32 resourceId, s32 level) {
172 u8 *backgroundData = Resource_GetTableEntry(resourceId);
173 struct BattleWork *battle = WORK_SLOT(HEAP_SLOT_BATTLE);
174 u16 *palette;
175
177 {
178 u32 offset = 0x100;
179 void *vram;
180
181 /* FAKEMATCH(dead): two updates that cancel, under a test that emits
182 * nothing, end a CSE block so the VRAM address loads before the data's
183 * add; without them, 2 of 103 instructions differ in tbs-en. */
184 if (battle) {
185 offset++;
186 offset--;
187 }
188 vram = BG_CHAR_BLOCK(2);
189 ((BitDecoder)WORK_SLOT(49))(backgroundData + offset, vram);
190 }
192 palette = battle->palette;
193 Dma_Set(backgroundData, palette, DMA_COPY_WORDS(64), REG_DMA3);
194 if (level >= 0)
197 battle->brightness = 0x10000 - level * BACKGROUND_LEVEL_STEP, 128);
198 Dma_Set((void *)OBJ_PLTT, (void *)&BG_PLTT_COLOR(5, 0),
200 *(u16 *)&BG_PLTT_COLOR(5, 14) = *(u16 *)&BG_PLTT_COLOR(15, 4);
203 // Clears BG1's last row, 0x7c0 bytes in, which BuildTilemap leaves.
204 Iwram_ClearWords((BG_SCREEN_BLOCK(31) + 0x7c0), 64);
205 if (view->mode == 0)
207 view->mode = mode;
208 if (mode == 1)
210}
211
212/// Builds the perspective plane's next page for a zoom of scale about centerX
213/// and centerY (all 16.16), shifted by offsetX and offsetY (8.8 pixels), and
214/// shows it.
215/// The page holds the affine parameters and each line's BG2CNT: which half of
216/// the picture a line shows, or none. At a zoom of 1 or more the plane wraps
217/// and turns sideways with the camera's yaw. While the background is in mode
218/// 1 (or secondMode is) and not busy, it also sets BG1's horizontal scroll.
219/// Called by BattlePres_SetupTransitionScene, by
220/// BattlePresentation_UpdateCamera and the shoulder-key camera
221/// (DEFINE_ADJUST_CAMERA) while BattlePresentationTransition.flag is 0, by
222/// Battle_RunEncounter and by Camera_ConfigureScene. Does nothing before heap
223/// slot 10 is allocated, and builds no page unless the mode is 2.
224void BattleCamera_SetRange(s32 centerX, s32 centerY, s32 offsetX, s32 offsetY,
225 s32 scale) {
227 struct BattleAffineHdma *scanlines = WORK_SLOT(10);
228 struct BattleCamera *camera = WORK_SLOT(HEAP_SLOT_CAMERA);
229 u16 wrap;
230 s32 panX;
231 u16 *line;
232 struct BattleAffine *affine;
233 s32 ratio;
234 s32 step;
235 s32 x;
236 s32 y;
237 u32 scanline;
238 u32 lowerHalfLine;
239
240 // The sideways pan, 8.8 pixels: 8 when zoomed out, else 104 less three
241 // times the yaw, so the picture turns with the camera.
242 panX = 0x800;
243 wrap = 0;
244 if (scale >= 0x10000) {
245 wrap = BGCNT_WRAP;
246 panX = 0x6800 + -(s16)camera->yaw * 3;
247 }
248 if (scanlines == NULL)
249 return;
250 if ((view->mode == 1 || view->secondMode == 1) && view->busy == 0)
251 gBgScroll[1].x = panX >> 8;
252 if (view->mode != 2)
253 return;
254
255 // The affine parameters: a plain zoom, the reference point moved so the
256 // centre stays put, 16 pixels up.
257 line = scanlines->lines[scanlines->page ^ 1];
258 ratio = Iwram_RatioMulQ14(scale, 0x10000);
259 step = ratio >> 8;
260 affine = &scanlines->affine;
261 affine->pa = step;
262 affine->pb = 0;
263 affine->pc = 0;
264 affine->pd = step;
265 x = Iwram_MulQ16(ratio, Iwram_MulQ16(centerX, scale - 0x10000));
266 y = Iwram_MulQ16(ratio, Iwram_MulQ16(centerY, scale - 0x10000));
267 affine->x = ((x + 0x7fff) >> 8) + offsetX + panX;
268 y = ((y + 0x7fff) >> 8) + offsetY - 0x1000;
269 affine->y = y;
270
271 // The picture's lower half starts at map row 8, 64 pixels (0x4000 in 8.8)
272 // down the plane: the first screen line that reaches it at this zoom.
273 lowerHalfLine = (Iwram_RatioMulQ14((s16)step, 0x4000 - y) >> 16) + 1;
274
275 // Each line's BG2CNT. The plane covers lines 0 to 135, above the status
276 // window; its top 16 lines are left off except while commands are chosen.
277 scanline = 0;
279 for (; scanline < 16; scanline++)
280 *line++ = BACKGROUND_PLANE_OFF;
281 }
282 if (lowerHalfLine > 136)
283 lowerHalfLine = 136;
284 for (; scanline < lowerHalfLine; scanline++)
285 *line++ = wrap | BACKGROUND_PLANE_UPPER;
286 for (; scanline < 136; scanline++)
287 *line++ = wrap | BACKGROUND_PLANE_LOWER;
288 for (; scanline < 160; scanline++)
289 *line++ = BACKGROUND_PLANE_OFF;
290 scanlines->page ^= 1;
291}
292
293/// Sets the camera's eye at its stored distance without taking a zoom;
294/// nothing in the source calls it.
295/// The original zoom is an uninitialized local; UBFIX makes it an explicit
296/// percentage argument, as in BattlePres_SetupTransitionScene.
297#ifdef UBFIX
299 s32 zoom) {
300#else
302#endif
303 s32 span = 0x01fe0000;
304 // BUG: zoom is uninitialized; reads entry r4 directly (lsls r0, r4, #16).
305#ifndef UBFIX
306 s32 zoom;
307#endif
308 struct BattleCamera *camera = gCameraWork;
309 s32 *focus = camera->pos;
310 s32 scale = (zoom << 16) / 100;
311 s32 renderBounds[3];
312 s32 measuredBounds[3];
313 s32 sourceBounds[3];
314 s32 alpha;
315 s32 half;
316 s32 width;
317 u32 result;
318
319 SET_VECTOR(focus, x, depth, y);
320 sourceBounds[0] = 0;
321 alpha = 0xc000;
322 sourceBounds[1] = 0;
323 sourceBounds[2] = 0;
324
325 result = Iwram_RatioMulQ14(span, alpha);
326 Projection_Set(span, result, span * 2);
331 renderBounds[0] = 0;
332 renderBounds[1] = 0;
333 renderBounds[2] = camera->distance;
334 Iwram_TransformVector(renderBounds, (s32 *)camera);
335 gProjection.centerX = 120;
336 gProjection.centerY = 120;
338 Transform_SetLookAt(camera->eye, focus);
339 Render_ProjectPoint(sourceBounds, measuredBounds);
340
341 BattleCamera_SetRange(0x780000, 0x780000, (120 - measuredBounds[0]) << 8,
342 (120 - measuredBounds[1]) << 8, scale);
343 half = scale * 0xff;
344 width = half * 2;
345 result = Iwram_RatioMulQ14(width, alpha);
346 Projection_Set(width, result, half * 4);
347}
348
349/// Points the battle camera at (x, depth, y) with a zoom in percent, and lines
350/// the perspective plane up with it.
351/// The camera's eye is set 510 pixels from the focus along its yaw and pitch;
352/// where the battlefield's origin then projects decides the plane's offset
353/// (BattleCamera_SetRange), and the projection's focal length and depth range
354/// are then scaled by the zoom. Called by the battle's staging
355/// (BattlePres_RunEntryTransition, Battle_RunEncounter, staging.c,
356/// auto_battle.c), BattlePres_SetupTransitionAtPairMidpoint and several
357/// effects. Writes the camera's pos and eye, gProjection, and the plane's
358/// next page.
360 struct BattleCamera *camera = gCameraWork;
361 s32 *focus = camera->pos;
362 s32 scale = (zoom << 16) / 100;
363 s32 renderBounds[3];
364 s32 measuredBounds[3];
365 s32 sourceBounds[3];
366 s32 span = 0x01fe0000;
367 s32 alpha;
368 s32 half;
369 s32 width;
370 u32 result;
371
372 SET_VECTOR(focus, x, depth, y);
373 sourceBounds[0] = 0;
374 alpha = 0xc000;
375 sourceBounds[1] = 0;
376 sourceBounds[2] = 0;
377
378 result = Iwram_RatioMulQ14(span, alpha);
379 Projection_Set(span, result, span * 2);
384 renderBounds[0] = 0;
385 renderBounds[1] = 0;
386 renderBounds[2] = span;
387 Iwram_TransformVector(renderBounds, (s32 *)camera);
388 gProjection.centerX = 120;
389 gProjection.centerY = 120;
391 Transform_SetLookAt(camera->eye, focus);
392 Render_ProjectPoint(sourceBounds, measuredBounds);
393
394 BattleCamera_SetRange(0x780000, 0x780000, (120 - measuredBounds[0]) << 8,
395 (120 - measuredBounds[1]) << 8, scale);
396 half = scale * 0xff;
397 width = half * 2;
398 result = Iwram_RatioMulQ14(width, alpha);
399 Projection_Set(width, result, half * 4);
400}
401
402/// Points the battle camera, through BattlePres_SetupTransitionScene, at the
403/// ground between two units' battle objects, with a zoom in percent.
404/// Called by the staging of a paired action (staging.c) and by the beam
405/// effects (beams.c).
406void BattlePres_SetupTransitionAtPairMidpoint(s32 firstUnitId, s32 secondUnitId,
407 s32 zoom) {
408 struct MotionObject *firstObject = BattleObjGet(firstUnitId)->object;
409 struct MotionObject *secondObject = BattleObjGet(secondUnitId)->object;
410 s32 firstX = firstObject->x;
411 s32 secondX = secondObject->x;
412 s32 firstZ = firstObject->z;
413 s32 secondZ = secondObject->z;
414 s32 x = (secondX + firstX) / 2;
415 s32 z = (secondZ + firstZ) / 2;
416
418}
419
420/// Fades BG2 out over the backdrop in eight frames, its blend weight falling
421/// by 2 a frame from 15, while the backdrop's stays 16.
422/// Reached only through its entry in FarCall_BattleTable, which no code in
423/// TBS names. Leaves REG_BLDCNT blending BG2 over the backdrop.
425 s32 alphaStep;
426
428 for (alphaStep = 1; alphaStep <= 16; alphaStep += 2) {
429 REG_BLDALPHA = BLEND_ALPHA(16, 16) - alphaStep;
430 WaitFrames(1);
431 }
432}
433
434/// Fades BG2 in over the backdrop in eight frames, its blend weight rising by
435/// 2 a frame from 1, while the backdrop's stays 16.
436/// Reached only through its entry in FarCall_BattleTable, which no code in
437/// TBS names. Leaves REG_BLDCNT blending BG2 over the backdrop.
439 s32 step;
440
442 for (step = 1; step <= 16; step += 2) {
443 REG_BLDALPHA = step + BLEND_ALPHA(0, 16);
444 WaitFrames(1);
445 }
446}
447
448/// What BattlePresentation_InitializeTransitionEntries treats as an array of
449/// these; Transform_SetIdentity writes over it as a matrix.
451 u32 value; ///< the first word, read before and after the identity is set
452 u32 sum; ///< set to the first word's old value plus its new one
455};
456
457/// Sets REG_BLDCNT to lighten every layer by REG_BLDY; nothing calls it.
460}
461
462/// Sets entries to the identity transform, then stores the first word's old
463/// value plus its new one in the second; nothing calls it.
464/// XXX: what the sum is for; a caller, which TBS lacks, would show it.
466 struct BattleTransitionEntry *entries) {
467 u32 previous = entries[0].value;
468
469 CAMELOT_ASM("the fixed-register identity store of transform.h")
470 Transform_SetIdentity(entries);
471 entries[0].sum = previous + entries[0].value;
472}
473
474/// Nothing calls it.
475s32 BattlePres_DivideBy16(s32 value) { return value / 16; }
476
477/// A debug aid: while Start is held, edits BattleWork.debugValue with the
478/// d-pad (1 left and right, 100 up and down) until A takes it as the result;
479/// with Select held, returns DEBUG_SELECT_VALUE instead.
480/// Nothing in TBS calls it; it returns selectedValue unchanged otherwise.
482 struct BattleWork *battle;
483
484 if (gKeysHeld & KEY_START) {
485 for (;;) {
486 battle = gBattleWork;
487 if (gKeysRepeat & KEY_LEFT)
488 battle->debugValue -= 1;
490 battle->debugValue += 1;
491 if (gKeysRepeat & KEY_UP)
492 battle->debugValue -= 100;
493 if (gKeysRepeat & KEY_DOWN)
494 battle->debugValue += 100;
495 if (gKeysPressed & KEY_A)
496 selectedValue = battle->debugValue;
497 else {
498 WaitFrames(1);
499 continue;
500 }
501 break;
502 }
503 }
504 if (gKeysHeld & KEY_SELECT)
505 selectedValue = DEBUG_SELECT_VALUE;
506 return selectedValue;
507}
508
509/// Sets the OBJ mode (1 semi-transparent, 0 normal) of every sprite of a
510/// unit's battle object, the picture and its shadow.
511/// Does nothing for a unit with no battle object or motion object. Called by
512/// BattlePres_SetActorModes and its helpers here, by the opening's storm
513/// (BattlePres_RunEntryTransition), by the staging (staging.c) and by auto
514/// battle (auto_battle.c).
516 struct BattleObj *slot = BattleObjGet(actorId);
517 struct MotionObject *object;
518 struct AnimationObject *record;
519 struct AnimationObject **records;
520 s32 recordIndex;
521
522 if (slot == 0)
523 return;
524 object = slot->object;
525 if (object == 0)
526 return;
527 switch (object->recordStorageKind & RECORDS_KIND_MASK) {
528 case RECORDS_SINGLE: {
529 record = object->records;
530 record->image.objectMode = mode;
531 record->shadow.objectMode = mode;
532 break;
533 }
534 case RECORDS_TABLE: {
535 records = object->records;
536 recordIndex = 0;
537 do {
538 record = *records++;
539 if (record == 0)
540 break;
541 record->image.objectMode = mode;
542 record->shadow.objectMode = mode;
543 recordIndex++;
544 } while (recordIndex <= RECORDS_TABLE_SIZE - 1);
545 break;
546 }
547 }
548}
549
550/// Makes every unit's sprites semi-transparent but selectedUnitId's, which are
551/// left as they are; nothing calls it.
553 s16 unitIds[14];
554 s32 unitCount = BattleParty_ListActorIds(BATTLE_SIDE_BOTH, unitIds);
555 s32 unitIndex;
556
557 for (unitIndex = 0; unitIndex < unitCount; unitIndex++) {
558 if (unitIds[unitIndex] != selectedUnitId)
559 BattlePres_SetActorRecordMode(unitIds[unitIndex], 1);
560 }
561}
562
563/// Returns every unit's sprites to OBJ mode 0; called by
564/// BattlePres_SetActorModes when the highlight stops.
566 s16 unitIds[14];
567 s32 unitCount = BattleParty_ListActorIds(BATTLE_SIDE_BOTH, unitIds);
568 s32 unitIndex;
569
570 for (unitIndex = 0; unitIndex < unitCount; unitIndex++)
571 BattlePres_SetActorRecordMode(unitIds[unitIndex], 0);
572}
573
574/// Lightens the opaque sprites, the highlighted units, by the next step of
575/// gBattleFx_HighlightBlendRamp.
576/// The ramp's first sixteen steps play once, then its second sixteen over
577/// and over. Runs each frame as a scheduler callback added by
578/// BattlePres_SetActorModes while BattleWork.highlightMode is set; writes
579/// REG_BLDCNT, REG_BLDALPHA, REG_BLDY and BattleWork.highlightStep.
581 struct BattleWork *battle = gBattleWork;
582 s8 *blendRamp;
583 u16 rampIndex;
584 s32 nextIndex;
585
586 if (battle != NULL && battle->highlightMode != 0) {
588 REG_BLDALPHA = BLEND_ALPHA(16, 0);
590 REG_BLDY = blendRamp[battle->highlightStep];
591 // From step 15 on, the next step stays in 16 to 31.
592 rampIndex = battle->highlightStep;
593 nextIndex = (rampIndex + 1) & 0xf;
594 if (rampIndex > 14)
595 nextIndex |= 0x10;
596 battle->highlightStep = nextIndex;
597 }
598}
599
600/// Highlights the units in selectedUnits, a list ended by
601/// BATTLE_UNIT_LIST_END, or with mode 0 stops the highlight.
602/// With an odd mode every other unit's sprites turn semi-transparent and the
603/// selected units' stay opaque, so only they take the pulsing lightening of
604/// Graphics_AdvancePaletteCycle. Called with the acting unit by
605/// BattlePresentation_DispatchAction, with the targets being chosen by the
606/// command menu (party_commands.c, targets.c, selection.c), and with 0 when
607/// either is done. Sets BattleWork.highlightMode and highlightStep, and adds
608/// or removes the callback.
609void BattlePres_SetActorModes(u16 *selectedUnits, s32 mode) {
610 s16 unitIds[14];
611 struct BattleWork *battle = gBattleWork;
612 u32 unitCount;
613 u32 unitIndex;
614
615 if (mode == 0) {
617 REG_BLDY = mode;
619 WaitFrames(1);
621 }
622 if (battle != 0 && mode != 0) {
623 battle->highlightMode = mode;
624 battle->highlightStep = 0;
625 REG_BLDY = 0;
627
628 unitCount = BattleParty_ListActorIds(BATTLE_SIDE_BOTH, unitIds);
629 for (unitIndex = 0; unitIndex < unitCount; unitIndex++)
630 BattlePres_SetActorRecordMode(unitIds[unitIndex], mode & 1);
631
632 if (selectedUnits != 0) {
633 u32 unitId = *selectedUnits;
634 unitIndex = 0;
635 selectedUnits++;
636 if (unitId != BATTLE_UNIT_LIST_END) {
637 do {
638 BattlePres_SetActorRecordMode(unitId, (mode & 1) ^ 1);
639 unitIndex++;
640 // A unit list holds at most 14.
641 if (unitIndex > 13)
642 break;
643 unitId = *selectedUnits++;
644 } while (unitId != BATTLE_UNIT_LIST_END);
645 }
646 }
647 WaitFrames(1);
650 }
651}
652
653#undef BACKGROUND_LEVEL_STEP
654#undef BACKGROUND_PLANE_UPPER
655#undef BACKGROUND_PLANE_LOWER
656#undef BACKGROUND_PLANE_OFF
void BattlePresentation_InitializeWorkAndResetState(void)
Allocates the perspective plane's scanline work (heap slot 10) cleared, and sets the background's mod...
Definition background.c:145
#define DEBUG_SELECT_VALUE
Definition background.c:12
void BattlePres_SetOtherActorRecordModes(s32 selectedUnitId)
Makes every unit's sprites semi-transparent but selectedUnitId's, which are left as they are; nothing...
Definition background.c:552
void Runtime_ReleaseHeapBlock10(void)
Frees the perspective plane's scanline work (heap slot 10); called by Battle_RunEncounter as the batt...
Definition background.c:156
void BattlePres_ClearAllActorRecordModes(void)
Returns every unit's sprites to OBJ mode 0; called by BattlePres_SetActorModes when the highlight sto...
Definition background.c:565
void BattlePres_SetActorRecordMode(s32 actorId, s32 mode)
Sets the OBJ mode (1 semi-transparent, 0 normal) of every sprite of a unit's battle object,...
Definition background.c:515
void Graphics_SetBlendControl(void)
Sets REG_BLDCNT to lighten every layer by REG_BLDY; nothing calls it.
Definition background.c:458
#define BACKGROUND_PLANE_LOWER
The same map, reading the remaining picture tiles from character block 3.
Definition background.c:28
void BattlePresentation_InitializeTransitionEntries(struct BattleTransitionEntry *entries)
Sets entries to the identity transform, then stores the first word's old value plus its new one in th...
Definition background.c:465
s32 BattlePres_DivideBy16(s32 value)
Nothing calls it.
Definition background.c:475
#define BACKGROUND_LEVEL_STEP
BattlePresentation_SetPaletteLevel's and BattleBackground_Load's darkening step: each level takes 109...
Definition background.c:20
void Graphics_FadeAlphaIn(void)
Fades BG2 in over the backdrop in eight frames, its blend weight rising by 2 a frame from 1,...
Definition background.c:438
void Graphics_AdvancePaletteCycle(void)
Lightens the opaque sprites, the highlighted units, by the next step of gBattleFx_HighlightBlendRamp.
Definition background.c:580
void BattlePres_SetupTransitionAtPairMidpoint(s32 firstUnitId, s32 secondUnitId, s32 zoom)
Points the battle camera, through BattlePres_SetupTransitionScene, at the ground between two units' b...
Definition background.c:406
void Graphics_FadeAlphaOut(void)
Fades BG2 out over the backdrop in eight frames, its blend weight falling by 2 a frame from 15,...
Definition background.c:424
void BattleBackground_Load(s32 mode, s32 resourceId, s32 level)
Loads a battle background: its picture into character blocks 2 and 3, its palette into BattleWork....
Definition background.c:170
#define BACKGROUND_PLANE_UPPER
The perspective plane's BG2CNT for the first 256 picture tiles: a 256 by 256 affine map in screen blo...
Definition background.c:24
s32 Runtime_AdjustDebugValueWithButtons(s32 selectedValue)
A debug aid: while Start is held, edits BattleWork.debugValue with the d-pad (1 left and right,...
Definition background.c:481
void BattlePres_SetupTransitionScene(s32 x, s32 depth, s32 y, s32 zoom)
Points the battle camera at (x, depth, y) with a zoom in percent, and lines the perspective plane up ...
Definition background.c:359
#define BACKGROUND_PLANE_OFF
Lines outside the plane read the padded map in screen block 31.
Definition background.c:32
void(*) BitDecoder(const u8 *source, void *destination)
The bit decoder BattleBackground_Load copies to RAM and runs.
Definition background.c:159
void BattlePresentation_ConfigurePaletteFade(s32 mode, s32 unusedResource, s32 fade)
Switches the background's display mode, optionally sets its palette, and rebuilds both its maps.
Definition background.c:85
void BattlePres_SetActorModes(u16 *selectedUnits, s32 mode)
Highlights the units in selectedUnits, a list ended by BATTLE_UNIT_LIST_END, or with mode 0 stops the...
Definition background.c:609
void BattleCamera_SetRange(s32 centerX, s32 centerY, s32 offsetX, s32 offsetY, s32 scale)
Builds the perspective plane's next page for a zoom of scale about centerX and centerY (all 16....
Definition background.c:224
void BattlePresentation_SetPaletteLevel(s32 unused, s32 level)
Copies the background's saved palette to BG palettes 6 to 13, darkened by level (0 for none).
Definition background.c:42
UNUSED void BattlePres_SetupTransitionSceneAtDepth(s32 x, s32 depth, s32 y)
Sets the camera's eye at its stored distance without taking a zoom; nothing in the source calls it.
Definition background.c:301
s32 BattleParty_ListActorIds(s32 sideMask, u16 *unitIds)
Lists the units in the battle's unit lists on the sides in sideMask, party first, skipping those remo...
Definition encounter.c:510
struct BattleObj * BattleObjGet(s32 unitId)
Returns unitId's battle object, through its place, or null for a unit with no place.
Definition objects.c:480
void BattlePresentation_BuildTilemap(void *tilemap)
Builds BG1's flat map of the same picture: rows 0 to 3 0xffff, rows 4 and 5 tile 0x3ff,...
Definition transition.c:106
void BattlePres_UpdateHBlankScroll(void)
Shows the perspective plane's finished page each frame while the background is in mode 2: its first l...
Definition transition.c:132
void Graphics_BuildSequentialTileTable(void *tilemap)
Builds the perspective plane's 32 by 32 affine map: tiles 0 to 255 in its first eight rows,...
Definition transition.c:75
void BitDecoder_DecodeImage(void)
struct BattlePresentationTransition * gTransitionWork
u8 BitDecoder_Size[]
s8 gBattleFx_HighlightBlendRamp[]
struct BattleCamera * gCameraWork
What every part of the battle object shares: its includes, in their original order,...
#define RECORDS_KIND_MASK
#define BATTLE_BG_PALETTE
The battle background's colours: BG palettes 6 to 13, filled from BattleWork.palette,...
#define BATTLE_BG1CNT
BG1 during a battle: 256 colours, priority 3, its map in screen block 31.
#define RECORDS_SINGLE
#define RECORDS_TABLE
#define RECORDS_TABLE_SIZE
@ BATTLE_UNIT_LIST_END
ends the list
@ BATTLE_SIDE_BOTH
struct BattleWork * gBattleWork
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...
Definition dma.h:62
#define Dma_Fill32(value, destination, size)
Fills size bytes at destination with the word value by DMA3.
Definition dma.h:30
s32 GameFlag_TestFar(s32 flag)
#define FLAG_CHOOSING_COMMANDS
set while the commands are chosen
Definition flags.h:67
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
void * Runtime_AllocateBlock(s32 kind, s32 size)
As Runtime_AllocateHeapBlock, but tries EWRAM first, for blocks that need room more than speed: the b...
Definition heap.c:80
@ HEAP_SLOT_BATTLE_BACKGROUND
Definition heap_state.h:45
@ HEAP_SLOT_CAMERA
Definition heap_state.h:38
@ HEAP_SLOT_BATTLE
Definition heap_state.h:37
#define WORK_SLOT(n)
Reads slots through their own addresses; adjacent slots are reached by offsets.
Definition heap_state.h:14
void IoWriteQueue_Store16(u32 address, u32 value)
Queues a halfword store.
Definition io_queue.c:21
#define OBJ_PLTT
Definition io_reg.h:159
#define BLDCNT_TGT1_OBJ
Definition io_reg.h:127
#define BG_SCREEN_BLOCK(n)
Definition io_reg.h:167
#define BLDCNT_TGT1_BG2
Definition io_reg.h:125
#define BG_CHAR_BLOCK(n)
Definition io_reg.h:166
#define REG_BLDY
Definition io_reg.h:146
@ KEY_UP
Definition io_reg.h:249
@ KEY_SELECT
Definition io_reg.h:245
@ KEY_LEFT
Definition io_reg.h:248
@ KEY_START
Definition io_reg.h:246
@ KEY_RIGHT
Definition io_reg.h:247
@ KEY_A
Definition io_reg.h:243
@ KEY_DOWN
Definition io_reg.h:250
#define BLDCNT_EFFECT_LIGHTEN
towards white by REG_BLDY
Definition io_reg.h:132
#define DMA_COPY_HALFWORDS(n)
Definition io_reg.h:227
#define BLDCNT_EFFECT_BLEND
weighted by REG_BLDALPHA
Definition io_reg.h:131
#define REG_IME
Definition io_reg.h:308
#define BLDCNT_TGT2_ALL
Definition io_reg.h:140
#define REG_DMA3
Definition io_reg.h:153
#define BLEND_ALPHA(top, bottom)
A REG_BLDALPHA value: top and bottom are the two targets' weights, out of 16.
Definition io_reg.h:145
#define DMA_COPY_WORDS(n)
Definition io_reg.h:226
#define REG_BLDALPHA
Definition io_reg.h:142
#define BLDCNT_TGT1_ALL
Definition io_reg.h:129
#define REG_BLDCNT
Definition io_reg.h:119
#define REG_BG1CNT
Definition io_reg.h:20
#define BG_PLTT_COLOR(palette, color)
Definition io_reg.h:158
#define BLDCNT_TGT2_BD
Definition io_reg.h:139
#define BGCNT_WRAP
Affine backgrounds only: wrap around instead of showing the backdrop.
Definition io_reg.h:30
#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.
Definition iowrite.h:14
static s32 Iwram_RatioMulQ14(s32 divisor, s32 value)
All calls go through this layer.
Definition iwram_call.h:51
#define Iwram_MulQ16(left, right)
Definition iwram_call.h:127
static s32 Iwram_TransformVector(const void *vector, s32 *result)
Definition iwram_call.h:65
static s32 Iwram_ClearWords(void *destination, s32 size)
Definition iwram_call.h:55
volatile u32 gKeysHeld
Keys down now.
volatile u32 gKeysPressed
Keys that went down this frame.
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
#define SET_VECTOR(v, x, y, z)
Sets the x, y and z of a three-part vector: a position about to be projected, a per-frame step,...
Definition macros.h:12
struct BgScroll gBgScroll[]
void Runtime_ReleaseHeapBlock(s32 slot)
struct Projection gProjection
#define RamCode_LoadSlot(slot, code, bytes)
Allocates a work-slot copy; release it with Runtime_ReleaseHeapBlock.
Definition ramcode.h:26
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
s32 Scheduler_RemoveCallback(SchedulerCallback callback)
Unschedules the task running callback: clears its routine and gives it order 0x7fff,...
Definition scheduler.c:146
#define NULL
Definition bilibin.h:6
s32 Graphics_ScaleRgb555Clamped(u16 *source, u16 *destination, s32 scale, s32 count)
Copies count colours from source to destination, each channel scaled by scale (16....
Definition star_field.c:315
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
struct AnimationSpritePart shadow
Definition animspr.h:110
struct AnimationSpritePart image
Definition animspr.h:109
u8 slot
VRAM cache entry holding its tiles.
Definition animspr.h:112
The battle background's scanline work in heap slot 10: two pages of per-line BG2CNT values,...
u32 page
the page of lines shown; the other one is built
u16 lines[2][160]
struct BattleAffine affine
The battle background's affine parameters and reference point, copied whole to the BG2PA registers.
The battle background's work slot as the background code reads it: its display mode (2 draws it as an...
s32 mode
2 draws the affine plane; 1 sets BG1's scroll too
s32 busy
while set, BattleCamera_SetRange leaves BG1's scroll
s32 secondMode
1 also sets BG1's scroll; one effect sets it
The battle camera: its eye, the focus it turns about, and its pitch, yaw and distance.
u16 pitch
1/65536 turns
s32 distance
eye to focus, 16.16 fixed-point pixels
u16 yaw
1/65536 turns
s32 pos[3]
the focus, 16.16 fixed-point pixels
s32 eye[3]
The eye, 16.16 fixed-point pixels: written each frame distance behind the focus along the turned view...
A unit's place on the battlefield: its sprite object, resources and animations, its anchor spot and s...
struct MotionObject * object
NULL once released.
What BattlePresentation_InitializeTransitionEntries treats as an array of these; Transform_SetIdentit...
Definition background.c:450
u32 sum
set to the first word's old value plus its new one
Definition background.c:452
u32 value
the first word, read before and after the identity is set
Definition background.c:451
The battle's own work: its enemies, units and their objects, the turn's actions, the spoils,...
Definition battle_work.h:71
u16 highlightStep
index into gBattleFx_HighlightBlendRamp
s32 brightness
the backdrop's brightness, 16.16, 0x10000 full
s32 debugValue
A value Runtime_AdjustDebugValueWithButtons edits with the d-pad while Start is held.
u16 palette[128]
the backdrop's colours, before scaling
u16 highlightMode
nonzero while the units are highlighted
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
u8 recordStorageKind
bits: 3..0 RECORDS_NONE, RECORDS_SINGLE or RECORDS_TABLE
Definition motobj.h:52
s32 x
16.16 fixed-point pixels
Definition motobj.h:23
s32 centerX
screen pixels
Definition project.h:16
s32 centerY
screen pixels
Definition project.h:17
void * Resource_GetTableEntry(s32 index)
Returns the ROM address of resource index from the resource directory.
Definition system.c:150
void SceneTransform_ApplyYaw(s32 angle)
Rotates gTransform about the Y axis by angle.
Definition transform.c:113
void Projection_Set(u32 focal, u32 nearDepth, u32 farDepth)
Sets gProjection's focal length and depth range directly.
Definition transform.c:350
s32 Render_ProjectPoint(const void *point, s32 *screen)
Reads three word-aligned coordinates from point, transforms them by gTransform and projects them to t...
Definition transform.c:364
void SceneTransform_ApplyPitch(s32 angle)
Rotates gTransform about the X axis by angle.
Definition transform.c:97
void SceneTransform_ApplyPosition(const s32 *position)
Translates gTransform by position (x, y, z in 16.16).
Definition transform.c:145
void Render_ResetTransformState(void)
Allocates the one-level save area (heap slot HEAP_SLOT_TRANSFORM_STACK), clears gTransformStackDepth ...
Definition transform.c:19
void Transform_SetLookAt(s32 *eye, s32 *target)
Makes the camera at eye looking at target the whole of gTransform.
Definition transform.c:318
static __inline__ void Transform_SetIdentity(void *matrix)
Definition transform.h:17
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed char s8
Definition types.h:10
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
#define UNUSED
Definition types.h:22
unsigned char u8
Definition types.h:11
#define CAMELOT_ASM(proof)
Definition types.h:46