Alchemy
Loading...
Searching...
No Matches

status.c

Go to the documentation of this file.
1/// @file
2/// The status screen.
3/// Part of battle_command.c, the menu object, compiled only through it.
4
6
7#if TBS_PATCH_1
8#define OWNER_STATUS_TEXT_MAX 0x80
9#define OWNER_STATUS_VALUE_X 184
10#else
11#define OWNER_STATUS_TEXT_MAX 0x40
12#define OWNER_STATUS_VALUE_X 176
13#endif
14
15#if (LANGUAGE == LANGUAGE_SPANISH) || (LANGUAGE == LANGUAGE_ITALIAN)
16#define OWNER_STATUS_LABEL(row) (MsgOwnerStatusAttack + (row))
17#else
18#define OWNER_STATUS_LABEL(row) (MsgOwnerStatusExp - 10 + (row))
19#endif
20
21#define STATUS_CURSOR_GENERAL 0
22#define STATUS_CURSOR_COMBAT_STATS 1
23#define STATUS_CURSOR_CONDITIONS 2
24
25/// The status screen's cursor: its place in each group, the help entry it
26/// shows and where it points.
28 /// XOR2 navigation can transiently use index3; keep all five positions.
34 s32 column; ///< tiles
35 s32 row; ///< tiles
36};
37
38/// Shows a party member's stats and condition help until B or the link session
39/// ends. The supplied list enables shoulder-button member switching. Measure
40/// stage deltas temporarily, then restore the unit from its snapshot.
41s32 Ui_RunOwnerStatusScreen(u16 *list, s32 listCount, s32 owner) {
42 struct MenuSprite portraitSprite;
43 struct MenuSprite cursorSprite;
44 s32 statusSlots[11];
45 s8 statusKinds[11];
46 struct MenuSprite statusSprites[11];
47 struct MenuSprite nameSprite;
48 struct StatusCursor cursor;
49 struct UiRenderWork *render;
50 struct UiWindow *statusWindow;
51 struct UiWindow *helpWindow;
52 s32 ownerIndex;
53 s32 cursorSlot;
54 struct MenuPoint cursorPosition;
55 s32 portraitSlot;
56 s32 statusCount;
57 s32 hasDjinn;
58 s32 keys;
59 u16 *helpText;
60 s32 statusKind;
61 s32 *statusSlot;
62 s32 defenseDelta;
63 s32 i;
64 s32 j;
65 s32 attackDelta;
66 s32 redraw;
67 struct BattleUnit *unit;
68 struct BattleUnit *savedUnit;
69 const struct OwnerStatusStatCursor *cursorStop;
70 struct MenuSprite *statusSprite;
71 s32 agilityDelta;
72 s32 helpValue;
73 s32 groupPosition;
74 struct BattleMenuWork *navigation;
75 s32 iconX;
76
77 render = UI_WORK;
78 redraw = 1;
79 ownerIndex = -1;
80 portraitSlot = VramCache_AllocEntry(0x200);
81 statusCount = 0;
82 hasDjinn = Party_SumDjinnCountsFar(-1);
83
84 navigation = ((struct BattleMenuWork *)gWindowWork[42]);
85 navigation->timerHidden = 1;
86 if (navigation->timerWindow != 0) {
87 UiWork_Finalize((struct UiWindow *)navigation->timerWindow, 1);
88 navigation->timerWindow = 0;
89 }
91
92 for (i = 4; i >= 0; i--) {
93 cursor.groupPositions[i] = 0;
94 }
95 cursor.helpEntry = 0;
96 cursor.drawnHelpEntry = 0;
98
99 cursorSlot = VramCache_AllocEntry(0x80);
100 for (i = 0; i <= 10; i++) {
101 statusSlots[i] = VramCache_AllocEntry(0x80);
102 statusKinds[i] = -1;
103 }
104
105 if (listCount != 0) {
106 for (i = 0; i <= 5; i++) {
107 s32 kind = list[i];
108
109 if (kind == 0xFF) {
110 break;
111 }
112 if (kind != 0xFE) {
113 if (kind == owner) {
114 ownerIndex = i;
115 break;
116 }
117 }
118 }
119 }
120
121 cursorPosition.x = 0;
122 cursorPosition.y = 0;
123 // The stat grid and its explanation have separate lifetimes and redraws.
124 statusWindow = UiWindow_Create(0, 0, 30, 20, 6);
125 helpWindow = UiWindow_Create(0, 14, 30, 6, 10);
127
128 for (;;) {
129 keys = gKeysRepeat;
130
131 nameSprite.oam.word.attr01 = 0x80000400;
132 nameSprite.oam.word.attr23 = 0;
133 nameSprite.oam.f.tile = UiGlyph_LoadPortrait(owner, portraitSlot);
134 nameSprite.oam.f.x = 8;
135 nameSprite.oam.f.y = 24;
136 nameSprite.oam.f.palette = 14;
137 Runtime_PushSlotEntry((s32 *)&nameSprite, 240);
138
139 switch (cursor.helpEntry) {
140 case 0:
141 case 2:
142 case 3:
143 case 4:
144 case 5:
145 case 6:
146 case 7:
147 case 8:
148 case 9:
149 default:
151 if (hasDjinn != 0) {
152 cursor.groupSize = 9;
153 } else {
154 cursor.groupSize = 7;
155 }
156 break;
157 case 10:
158 case 11:
159 case 12:
160 case 13:
162 cursor.groupSize = 4;
163 break;
164 case 14:
165 case 15:
166 case 16:
167 case 17:
168 case 18:
169 case 19:
170 case 20:
171 case 21:
173 cursor.groupSize = statusCount;
174 break;
175 }
176
177 Ui_SetRectHighlight(statusWindow->x, statusWindow->y, statusWindow->width,
178 statusWindow->height, 15);
179
180 if (statusCount != 0) {
181 if ((u32)cursor.group <= STATUS_CURSOR_COMBAT_STATS) {
182 groupPosition = cursor.groupPositions[cursor.group];
183 if ((keys & KEY_DOWN) != 0) {
184 keys = 0;
186 groupPosition++;
187 if (groupPosition >= cursor.groupSize) {
188 groupPosition = 0;
189 if (cursor.group == STATUS_CURSOR_COMBAT_STATS) {
191 groupPosition = cursor.groupPositions[cursor.group];
192 }
193 }
194 } else if ((keys & KEY_UP) != 0) {
195 keys = 0;
197 groupPosition--;
198 if (groupPosition < 0) {
199 groupPosition = cursor.groupSize - 1;
200 if (cursor.group == STATUS_CURSOR_COMBAT_STATS) {
202 groupPosition = cursor.groupPositions[cursor.group];
203 }
204 }
205 } else if ((keys & 0x31) != 0) {
206 keys = 0;
208 // Toggle toward conditions; group3 is transient until reclassified.
210 if ((gKeysRepeat & KEY_A) != 0) {
211 groupPosition = cursor.groupPositions[cursor.group];
212 } else if ((gKeysRepeat & KEY_LEFT) != 0) {
213 groupPosition = statusCount - 1;
214 } else {
215 groupPosition = 0;
216 }
217 }
218 cursor.groupPositions[cursor.group] = (s8)groupPosition;
219 } else if (cursor.group == STATUS_CURSOR_CONDITIONS) {
220 groupPosition = cursor.groupPositions[cursor.group];
221 if (groupPosition >= cursor.groupSize) {
222 groupPosition = cursor.groupSize - 1;
223 }
224 if (groupPosition < 0) {
226 groupPosition = cursor.groupPositions[0];
227 } else if ((keys & KEY_RIGHT) != 0) {
228 keys = 0;
229 groupPosition++;
230 if (groupPosition >= cursor.groupSize) {
232 groupPosition = cursor.groupPositions[0];
233 }
235 } else if ((keys & KEY_LEFT) != 0) {
236 keys = 0;
237 groupPosition--;
238 if (groupPosition < 0) {
240 groupPosition = cursor.groupPositions[0];
241 }
243 } else if ((keys & 0xC1) != 0) {
244 keys = 0;
246 groupPosition = cursor.groupPositions[0];
248 }
249 cursor.groupPositions[cursor.group] = (s8)groupPosition;
250 }
251 }
252
253 if (cursor.group == STATUS_CURSOR_GENERAL) {
254 s32 k = cursor.groupPositions[cursor.group];
255
256 if (hasDjinn == 0) {
257 k += 9;
258 }
259 cursorStop = &gOwnerStatus_StatCursors[k];
260 cursor.helpEntry = cursorStop->entry;
261 cursor.column = cursorStop->column;
262 cursor.row = cursorStop->row;
263 Ui_SetRectHighlight(statusWindow->x + cursorStop->highlightColumn + 1,
264 statusWindow->y + cursorStop->highlightRow + 1,
265 cursorStop->highlightWidth, 1, 14);
266 } else if (cursor.group == STATUS_CURSOR_COMBAT_STATS) {
267 cursor.helpEntry =
269 .entry;
270 cursor.column =
272 .column;
273 cursor.row =
275 .row;
276 } else if (cursor.group == STATUS_CURSOR_CONDITIONS) {
277 cursor.helpEntry =
279 .entry;
280 cursor.column =
282 .column;
283 cursor.row =
285 .row;
286 }
287
288 if (cursor.drawnHelpEntry != cursor.helpEntry) {
289 cursor.drawnHelpEntry = cursor.helpEntry;
290 redraw = 2;
291 }
292 cursorPosition.x = cursor.column * 8;
293 cursorPosition.y = cursor.row * 8;
294
295 {
296 struct MenuSprite *face = GetBattleObjectSlotFar(owner)->object->records;
297
298 portraitSprite.oam.word.attr01 = 0xC0002400;
299 portraitSprite.oam.word.attr23 = 0;
300#if TBS_PATCH_4
301 /* FAKEMATCH(barrier): an empty asm, so the move into sl comes between
302 * the two stores and the face tile loads before 0xFC00, as native;
303 * without it, 13 of 1458 instructions differ in tbs-es. */
304 asm("");
305#endif
306 portraitSprite.oam.f.tile = face->oam.f.tile;
307 portraitSprite.oam.f.x = 0xAC;
308 portraitSprite.oam.f.y = 56;
309 Runtime_PushSlotEntry((s32 *)&portraitSprite, 240);
310 }
311
312 cursorSprite.oam.word.attr01 = 0x40000400;
313 cursorSprite.oam.word.attr23 = 0;
314 /* FAKEMATCH(barrier): counted as 4 bytes, the empty asm puts gFrameCount's
315 * literal in the next pool, as native; without it, 13 of 1392
316 * instructions differ in tbs-en. */
317 asm("");
318 cursorSprite.oam.f.tile =
320 cursorSprite.oam.f.x =
321 (cursorPosition.x + statusWindow->x * 8 - ((gFrameCount & 4) >> 2)) +
322 16;
323 cursorSprite.oam.f.y = (u8)((cursorPosition.y + statusWindow->y * 8 -
324 ((gFrameCount & 4) >> 2)) +
325 16);
326 cursorSprite.oam.f.affineIndex = 8;
327 Runtime_PushSlotEntry((s32 *)&cursorSprite, 241);
328
329 if (redraw != 0) {
330 unit = UnitGetFar(owner);
331#if TBS_PATCH_1
333#endif
335
336 if ((redraw & 1) != 0) {
337 RenderOutput_RedrawSavedRect(statusWindow);
338 UiWindow_MapTextCanvasTiles(helpWindow->x, helpWindow->y,
339 helpWindow->width, helpWindow->height, 0);
340 UiWindow_DrawDividerLine(statusWindow, 0, 14, 29, 14);
341
342#if (LANGUAGE == LANGUAGE_SPANISH) || (LANGUAGE == LANGUAGE_ITALIAN)
343 switch (System_GetLanguage()) {
344 case 2:
345 UiText_DrawStringAtOffset((u8 *)unit->name, statusWindow, 0, 0);
346 UiText_DrawStringAtOffset((u8 *)gOwnerStatus_NivString, statusWindow,
347 51, 0);
348 UiText_DrawNumberInWindow(unit->level, 2, statusWindow, 72, 0);
349 break;
350 case 3:
351 UiText_DrawStringAtOffset((u8 *)unit->name, statusWindow, 0, 0);
352 UiText_DrawStringAtOffset((u8 *)gOwnerStatus_NvString, statusWindow,
353 56, 0);
354 UiText_DrawNumberInWindow(unit->level, 2, statusWindow, 72, 0);
355 break;
356 default:
357 UiText_DrawStringAtOffset((u8 *)unit->name, statusWindow, 0, 0);
359 statusWindow, 56, 0);
360 UiText_DrawNumberInWindow(unit->level, 2, statusWindow, 72, 0);
361 break;
362 }
363#else
364 UiText_DrawStringAtOffset((u8 *)unit->name, statusWindow, 0, 0);
367 UiText_DrawNumberInWindow(unit->level, 2, statusWindow, 72, 0);
368#endif
369 UiText_DrawCharacterAtOffset(MsgOwnerStatusExp, statusWindow, 0, 8);
370 UiText_DrawNumberInWindow(unit->experience, 8, statusWindow, 40, 8);
371
372#if (LANGUAGE == LANGUAGE_SPANISH) || (LANGUAGE == LANGUAGE_ITALIAN)
373 switch (System_GetLanguage()) {
374 case 1:
375 UiText_DrawStringAtOffset((u8 *)gOwnerStatus_KpString, statusWindow,
376 40, 24);
377 break;
378 case 2:
379 UiText_DrawStringAtOffset((u8 *)gOwnerStatus_PvString, statusWindow,
380 40, 24);
381 break;
382 case 3:
383 UiText_DrawStringAtOffset((u8 *)gOwnerStatus_PvString, statusWindow,
384 40, 24);
385 break;
386 case 4:
388 40, 24);
389 break;
390 }
391#else
393 24);
394#endif
395 UiText_DrawNumberInWindow(unit->hp, 4, statusWindow, 56, 24);
397 88, 24);
398 UiText_DrawNumberInWindow(unit->maxHp, 4, statusWindow, 96, 24);
400 32);
401 UiText_DrawNumberInWindow(unit->pp, 4, statusWindow, 56, 32);
403 88, 32);
404 UiText_DrawNumberInWindow(unit->maxPp, 4, statusWindow, 96, 32);
405
407 16);
408 UiText_DrawNumberInWindow(unit->atk, 3, statusWindow,
411 24);
412 UiText_DrawNumberInWindow(unit->def, 3, statusWindow,
415 32);
416 UiText_DrawNumberInWindow(unit->agi, 3, statusWindow,
419 40);
420 UiText_DrawNumberInWindow(unit->luck, 3, statusWindow,
422
423 UiText_DrawCharacterAtOffset(MsgClassName + unit->classIndex,
424 statusWindow, 0, 48);
425 if (hasDjinn != 0) {
427 72);
428 }
430 80);
432 88);
434 96);
435
436 for (j = 0; j <= 3; j++) {
437 s32 pal;
438
439 pal = 1;
440 if (hasDjinn != 0) {
441 pal = 0;
442 }
443 UiWindow_SetTilemapEntry(statusWindow, 0x5001 + j, 7 + j * 4, pal + 8,
444 0);
445 if (hasDjinn != 0) {
447 statusWindow, 40 + j * 32, 72);
449 statusWindow, 48 + j * 32, 72);
451 statusWindow, 48 + j * 32 + 8, 72);
452 }
454 statusWindow, 48 + j * 32, 80);
455 UiText_DrawNumberInWindow(unit->element[j].power, 3, statusWindow,
456 40 + j * 32, 88);
458 statusWindow, 40 + j * 32, 96);
459 }
460
461 i = 0;
462 if (unit->hp == 0) {
463 statusKinds[0] = 16;
464 i = 1;
465 }
466 do {
467 if (unit->restraint != 0) {
468 statusKinds[i++] = 15;
469 }
470 if (i > 7) {
471 break;
472 }
473 if (unit->grimReaper != 0) {
474 statusKinds[i++] = 8;
475 }
476 if (i > 7) {
477 break;
478 }
479 if (unit->poison == 1) {
480 statusKinds[i++] = 1;
481 }
482 if (i > 7) {
483 break;
484 }
485 if (unit->poison == 2) {
486 statusKinds[i++] = 2;
487 }
488 if (i > 7) {
489 break;
490 }
491 if (unit->psySeal != 0) {
492 statusKinds[i++] = 4;
493 }
494 if (i > 7) {
495 break;
496 }
497 if (unit->stun != 0) {
498 statusKinds[i++] = 3;
499 }
500 if (i > 7) {
501 break;
502 }
503 if (unit->sleep != 0) {
504 statusKinds[i++] = 5;
505 }
506 if (i > 7) {
507 break;
508 }
509 if (unit->haunt != 0) {
510 statusKinds[i++] = 7;
511 }
512 if (i > 7) {
513 break;
514 }
515 if (unit->delusion != 0) {
516 statusKinds[i++] = 6;
517 }
518 if (i > 7) {
519 break;
520 }
521 if (unit->attackTurns != 0) {
522 if (unit->attackStage > 0) {
523 statusKinds[i++] = 9;
524 }
525 if (unit->attackStage < 0) {
526 statusKinds[i++] = 10;
527 }
528 }
529 if (i > 7) {
530 break;
531 }
532 if (unit->defenseTurns != 0) {
533 if (unit->defenseStage > 0) {
534 statusKinds[i++] = 11;
535 }
536 if (unit->defenseStage < 0) {
537 statusKinds[i++] = 12;
538 }
539 }
540 if (i > 7) {
541 break;
542 }
543 if (unit->resistanceTurns != 0) {
544 if (unit->resistanceStage > 0) {
545 statusKinds[i++] = 13;
546 }
547 if (unit->resistanceStage < 0) {
548 statusKinds[i++] = 14;
549 }
550 }
551 if (i > 7) {
552 break;
553 }
554 if (unit->agilityStage > 0) {
555 statusKinds[i++] = 17;
556 }
557 if (unit->agilityStage < 0) {
558 statusKinds[i++] = 18;
559 }
560 } while (0);
561
562 for (j = 0; j < i; j++) {
563 Resource_LoadTableEntryToBuffer(statusKinds[j], statusSlots[j]);
564 }
565 if (i == 0) {
566 statusKinds[0] = 0;
567 i = 1;
568 }
569 if (i <= 10) {
570 for (j = i; j < 11; j++) {
571 statusKinds[j] = -1;
572 }
573 }
574 statusCount = i;
575 if (statusKinds[0] == 0) {
576 UiText_DrawCharacterAtOffset(unit->hp != 0 ? MsgOwnerStatusNormal
577 : MsgOwnerStatusDowned,
578 statusWindow, 112, 0);
579 }
580 }
581
582 helpText = (u16 *)MemAlloc(OWNER_STATUS_TEXT_MAX * sizeof(*helpText));
583 if ((u32)cursor.helpEntry > 13) {
584 statusKind = statusKinds[cursor.helpEntry - 14];
585 if (statusKind == 0 && unit->hp == 0) {
586 statusKind = 16;
587 }
588
589 // Remove stages on a snapshot to measure their displayed contribution.
590 savedUnit = (struct BattleUnit *)MemAlloc(sizeof(*unit));
591 helpValue = 0;
592 Iwram_CopyWords(savedUnit, unit, sizeof(*unit));
593
594 attackDelta = unit->atk;
595 defenseDelta = unit->def;
596 agilityDelta = unit->agi;
597 unit->attackStage = 0;
598 unit->defenseStage = 0;
599 unit->agilityStage = 0;
600 UnitCalcFar(owner);
601 attackDelta -= unit->atk;
602 defenseDelta -= unit->def;
603 agilityDelta -= unit->agi;
604 Iwram_CopyWords(unit, savedUnit, sizeof(*unit));
605 MemFree(savedUnit);
606
607 switch (statusKind) {
608 case 8:
609 helpValue = unit->grimReaper;
610 break;
611 case 9:
612 helpValue = attackDelta;
613 break;
614 case 10:
615 helpValue = -attackDelta;
616 break;
617 case 11:
618 helpValue = defenseDelta;
619 break;
620 case 12:
621 helpValue = -defenseDelta;
622 break;
623 case 17:
624 helpValue = agilityDelta;
625 break;
626 case 18:
627 helpValue = -agilityDelta;
628 break;
629 case 13:
630 case 14:
631 helpValue = unit->resistanceStage * 20;
632#if (LANGUAGE == LANGUAGE_SPANISH) || (LANGUAGE == LANGUAGE_ITALIAN)
633 if (helpValue < 0) {
634 helpValue = -helpValue;
635 }
636#endif
637 break;
638 default:
639 break;
640 }
641 UiWork_PushValueSlot(helpValue, 5);
642 UiText_CopyMessageString(statusKind + MsgOwnerStatusConditionHelp,
643 helpText, OWNER_STATUS_TEXT_MAX);
644 } else if (cursor.helpEntry == 2 && unit->level <= 98) {
646 Unit_GetExperienceForLevelFar(owner, unit->level + 1) -
647 unit->experience,
648 5);
649 UiText_CopyMessageString(MsgOwnerStatusNextLevel, helpText,
651 } else {
652 UiText_CopyMessageString(cursor.helpEntry + MsgOwnerStatusEntryHelp,
653 helpText, OWNER_STATUS_TEXT_MAX);
654 }
655
656 UiText_RenderWideStringAtOffset(helpText, (struct UiWindow *)helpWindow,
657 0, 4);
658 MemFree(helpText);
659 redraw = 0;
660 render->dirty = 1;
661 }
662
663 statusSprite = statusSprites;
664 statusSlot = statusSlots;
665 {
666 struct VramBlockCacheEntry *cache;
667
668 for (i = 0, cache = gVramBlockCache, iconX = 112; i <= 10; i++) {
669 statusSprite->oam.word.attr01 = 0x40000400;
670 statusSprite->oam.word.attr23 = 0;
671 statusSprite->oam.f.tile = cache[*statusSlot++].offset >> 5;
672 statusSprite->oam.f.x = iconX;
673 statusSprite->oam.f.y = (u8)(statusWindow->y * 8 + 8);
674 if (statusKinds[i] > 0) {
675 Runtime_PushSlotEntry((s32 *)statusSprite, 240);
676 }
677 iconX += 15;
678 statusSprite++;
679 }
680 }
681
682 if (gLinkCountdownWork->timer == 0) {
683 break;
684 }
685 if ((gKeysPressed & KEY_B) != 0) {
686 break;
687 }
688
689 if (listCount != 0) {
690 if ((keys & KEY_R) != 0) {
691 ownerIndex++;
692 if (ownerIndex >= listCount) {
693 ownerIndex = 0;
694 }
695 owner = list[ownerIndex];
696 redraw = 1;
698 } else if ((keys & KEY_L) != 0) {
699 ownerIndex--;
700 if (ownerIndex < 0) {
701 ownerIndex = listCount - 1;
702 }
703 owner = list[ownerIndex];
704 redraw = 1;
706 }
707 }
708 WaitFrames(1);
709 }
710
711 {
712 s32 *statusSlotCursor = statusSlots;
713
714 for (i = 10; i >= 0; i--) {
715 Resource_ResetEntry(*statusSlotCursor++);
716 }
717 }
718 Resource_ResetEntry(portraitSlot);
719 Resource_ResetEntry(cursorSlot);
720 WaitFrames(1);
721#if TBS_PATCH_1
723#endif
724 UiWork_Finalize(statusWindow, 1);
725 UiWork_Finalize(helpWindow, 1);
727 // UB: the indexed scalar pointer steps outside gBattleWork to slot 57.
728 // The named slot changes native instructions at the same 0xcf8-byte EN
729 // extent; using gWorkSlot instead adds eight bytes.
730#ifdef UBFIX
732#else
733 ((struct BattleMenuWork **)&gBattleWork)[HEAP_SLOT_WINDOW + 42 -
735 ->timerHidden = 0;
736#endif
737 WaitFrames(1);
738 return 0;
739}
What every part of the menu object shares: its includes, edition values, macros and the link round st...
#define OWNER_STATUS_LEVEL_X
struct BattleWork * gBattleWork
void Ui_SetRectHighlight(s32 x, s32 y, s32 width, s32 height, s32 paletteBit)
Sets bit 12 of each tile in a screen-space rectangle, preserving the other tile attributes.
struct BattleObj * GetBattleObjectSlotFar(s32 objectId)
Far call to BattleObjGet.
struct BattleUnit * UnitGetFar(u32 owner)
s32 Unit_GetElementLevelFar(s32 owner, s32 index)
s32 Party_SumDjinnCountsFar(s32 index)
u32 Unit_GetExperienceForLevelFar(s32 owner, s32 level)
void UnitCalcFar(s32 owner)
void AudioCommand_PlayFar(s32 id)
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
volatile u32 gFrameCount
Frames WaitFrames has finished.
void UiWindow_MapTextCanvasTiles(s32 x, s32 y, u32 width, u32 height, s32 fullWidth)
Maps the text canvas tiles into the interior of a window at tile (x, y).
Definition frames.c:176
void UiText_RenderWideStringAtOffset(u16 *text, struct UiWindow *window, s32 x, s32 y)
Draws a zero-terminated string of 16-bit character codes into a text canvas window at pixel (x,...
Definition glyphs.c:258
u8 gResource_FixedBlockBTiles[]
void * MemAlloc(s32 size)
Allocates size bytes (rounded up to words) with no slot, from IWRAM when they fit and EWRAM otherwise...
Definition heap.c:115
@ HEAP_SLOT_WINDOW
Definition heap_state.h:39
@ HEAP_SLOT_BATTLE
Definition heap_state.h:37
@ KEY_UP
Definition io_reg.h:249
@ KEY_B
Definition io_reg.h:244
@ KEY_LEFT
Definition io_reg.h:248
@ KEY_RIGHT
Definition io_reg.h:247
@ KEY_R
Definition io_reg.h:251
@ KEY_A
Definition io_reg.h:243
@ KEY_DOWN
Definition io_reg.h:250
@ KEY_L
Definition io_reg.h:252
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
Definition iwram_call.h:85
volatile u32 gKeysPressed
Keys that went down this frame.
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
void MemFree(void *buffer)
struct BattleMenuWork * gLinkCountdownWork
void PartyStatusDraw(s32 flags)
Draws the party status window with flags (see PARTY_STATUS_*): each member's name,...
s32 Resource_LoadTableEntryToBuffer(s32 resource, s32 index)
Composes a table-entry glyph in temporary transfer work, reloads its cache slot, then releases the te...
Definition pictures.c:299
s32 UiGlyph_LoadPortrait(u32 member, s32 cacheSlot)
Loads a party portrait into the supplied cache slot and returns its tile.
Definition pictures.c:341
void Runtime_PushSlotEntry(void *slotEntry, s32 slot)
Links a sprite entry into depth slot slot (clamped to 0..255) for this frame.
Definition render.c:79
#define SE_MENU_CURSOR_MOVE
Definition songs.h:104
#define SE_MENU_CONFIRM
Definition songs.h:105
u8 gWindowWork[]
s16 resistance
Elemental resistance to it.
Definition battle_unit.h:29
s16 power
Elemental power in the element.
Definition battle_unit.h:28
The battle command menus' work, heap slot 57 (0x104 bytes), reached as gLinkCountdownWork.
Definition menu_list.h:107
s32 timerWindow
The window that shows the link battle's seconds left, a struct UiWindow pointer kept as a word (as a ...
Definition menu_list.h:126
s32 timerHidden
Set while the status screen is open, so the timer opens no window.
Definition menu_list.h:128
s32 timer
Frames left to choose commands in a link battle; -1 outside link battles.
Definition menu_list.h:131
struct MotionObject * object
NULL once released.
A unit in battle: a party member's or an enemy's stats, Psynergy, items, Djinn and ailments.
u8 luck
0 to 99 (UnitCalc)
u8 djinnOwnedCounts[4]
the Djinn held in each element, at most 10
u8 grimReaper
The Grim Reaper's countdown: 7 when cursed, down one at each turn's end; at 0 the unit falls.
u8 psySeal
bits: 7..3 Luff (16 when cast, minus 8 a turn) | 2..0 Bind's turns (7 when cast).
s16 maxPp
0 to 1999 for a character, 9999 for an enemy (UnitCalc)
s8 poison
1 poisoned, 2 deadly poison
u8 djinnActiveCounts[4]
the Djinn set in each element; the class's element levels are read from these
u8 name[0x0f]
The name, one byte a character, ending in 0.
u8 haunt
set while an evil spirit grips the unit
s16 hp
current HP, 0 when downed
struct BattleElementStats element[4]
Power and resistance in each element, 0 to 200, after equipment, element levels and Resistance stages...
s16 pp
current PP
s8 restraint
The curse.
s16 maxHp
0 to 1999 for a character, 9999 for an enemy (UnitCalc)
u32 experience
a character's experience points
s8 agilityStage
The Agility stage: -4 (Vine) to 8 (Zephyr, twice the Agility).
u8 classIndex
The character's class, worked out from its Djinn (Unit_UpdateClass); 0 marks an enemy,...
u16 atk
Attack, 0 to 999 (UnitCalc).
u8 level
1 to 99 for a character
u8 attackTurns
Each stat change: the turns it has left, and its stage (UnitCalc: an eighth of Attack,...
u16 agi
Agility, 0 to 999: the order of the round's actions.
u16 def
Defense, 0 to 999 (UnitCalc).
u8 delusion
Delusion to sleep: the turns each status has left, 7 when it lands; each may end sooner at the end of...
u8 partyStatus
PARTY_STATUS_SUMMONS or PARTY_STATUS_NO_SUMMONS.
Definition battle_work.h:86
A point on the screen where a menu shows its cursor.
Definition menu_list.h:97
s32 y
screen pixels
Definition menu_list.h:99
s32 x
screen pixels
Definition menu_list.h:98
A menu sprite: a list link and its OAM attributes, as two words or as fields.
Definition menu_list.h:24
union MenuSprite::@002225022013150231017316170057321303227123371224 oam
void * records
one sprite, or a table of up to four (recordStorageKind)
Definition motobj.h:50
u8 row
tiles
Definition ui.h:38
u8 column
tiles
Definition ui.h:37
A cursor stop among the status screen's stats: its help entry, where the cursor points and the run of...
Definition ui.h:23
u8 column
tiles
Definition ui.h:25
u8 highlightColumn
tiles
Definition ui.h:27
u8 highlightWidth
tiles
Definition ui.h:29
u8 row
tiles
Definition ui.h:26
u8 highlightRow
tiles
Definition ui.h:28
The status screen's cursor: its place in each group, the help entry it shows and where it points.
Definition status.c:27
s8 groupPositions[5]
XOR2 navigation can transiently use index3; keep all five positions.
Definition status.c:29
s32 group
Definition status.c:32
s32 groupSize
Definition status.c:33
s32 column
tiles
Definition status.c:34
s32 helpEntry
Definition status.c:30
s32 drawnHelpEntry
Definition status.c:31
s32 row
tiles
Definition status.c:35
The window system's work: the windows' tilemap, the windows, the three text channels,...
Definition window.h:19
u8 dirty
The tilemap's 4-row bands to upload: bit 0 for all, bit n + 1 for band n.
Definition window.h:32
A window: a framed rectangle of the tilemap with its sprite outputs, its opening or closing animation...
Definition uiwindow.h:11
u16 y
tiles
Definition uiwindow.h:16
u16 x
tiles
Definition uiwindow.h:15
u16 height
tiles
Definition uiwindow.h:14
u16 width
tiles
Definition uiwindow.h:13
A sprite slot of the VRAM cache: the size of its block and where the block starts in OBJ VRAM.
Definition vram_tab.h:23
u16 offset
bytes from the start of OBJ VRAM
Definition vram_tab.h:25
void UiWindow_DrawDividerLine(struct UiWindow *win, u32 x1, u32 y1, u32 x2, u32 y2)
Draws a straight divider line inside a window from tile (x1, y1) to (x2, y2), horizontal or vertical:...
Definition text_tiles.c:365
void UiText_DrawStringAtOffset(const u8 *text, const struct UiWindow *work, s32 offsetX, s32 offsetY)
Draws a byte string as tiles in window work at pixel (offsetX, offsetY) of its interior.
Definition text_tiles.c:614
void UiText_DrawNumberInWindow(s32 value, s32 width, struct UiWindow *window, s32 x, s32 y)
Draws a number (width as UiText_FormatNumber) into a window's tilemap at pixel (x,...
Definition text_tiles.c:678
void UiWindow_MarkVisibleTileAttributes(void)
Marks the text tiles the tilemap shows, and frees those it no longer shows.
Definition text_tiles.c:299
void UiText_DrawCharacterAtOffset(s32 message, const struct UiWindow *window, u32 offsetX, u32 offsetY)
Decodes a message and draws it as tiles in a window at pixel (offsetX, offsetY) of its interior.
Definition text_tiles.c:552
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed char s8
Definition types.h:10
unsigned short u16
Definition types.h:13
unsigned char u8
Definition types.h:11
const u8 gOwnerStatus_HpString[]
const u8 gOwnerStatus_LevelString[]
const struct OwnerStatusCursor gOwnerStatus_EquipmentCursors[]
const u8 gOwnerStatus_PpString[]
const struct OwnerStatusStatCursor gOwnerStatus_StatCursors[]
const u8 gOwnerStatus_SlashString[]
const struct OwnerStatusCursor gOwnerStatus_ConditionCursors[]
s32 System_GetLanguage(void)
#define UI_WORK
Definition window.h:267
s32 VramCache_AllocEntry(s32 size)
Takes a free cache entry, gives it size bytes of sprite VRAM and returns its number.
Definition vram_cache.c:227
s32 VramCache_Reload(s32 no, s32 src)
Copies src again into entry no's VRAM, keeping its size.
Definition vram_cache.c:238
s32 Resource_ResetEntry(u32 no)
Frees cache entry no: its blocks go back and the entry is marked free (offset 0xffff).
Definition vram_cache.c:106
struct VramBlockCacheEntry gVramBlockCache[]
#define OWNER_STATUS_LABEL(row)
Definition status.c:18
#define STATUS_CURSOR_CONDITIONS
Definition status.c:23
s32 Ui_RunOwnerStatusScreen(u16 *list, s32 listCount, s32 owner)
Shows a party member's stats and condition help until B or the link session ends.
Definition status.c:41
#define OWNER_STATUS_VALUE_X
Definition status.c:9
#define STATUS_CURSOR_GENERAL
Definition status.c:21
#define STATUS_CURSOR_COMBAT_STATS
Definition status.c:22
#define OWNER_STATUS_TEXT_MAX
Definition status.c:8
void UiWork_PushValueSlot(u32 value, u32 kind)
Adds a message argument of kind (MSG_ARG_) with value to the first free place of the argument table; ...
Definition messages.c:216
s32 UiText_CopyMessageString(s32 message, u16 *destination, u32 capacity)
Decodes message into destination as a zero-terminated string of at most capacity entries,...
Definition messages.c:15
void UiWindow_SetTilemapEntry(struct UiWindow *window, s32 value, s32 x, s32 y, u32 mode)
Writes value into a window's tilemap at tile (x, y) of its interior, with the palette mode names (TIL...
Definition sprites.c:345
s32 Ui_FillVramBlockPattern(void)
Fills the text canvas with the window background colour (4).
Definition windows.c:619
void UiWork_Finalize(struct UiWindow *window, s32 instant)
Closes a window: clears its contents and remembers its last rectangle.
Definition windows.c:349
void RenderOutput_RedrawSavedRect(struct UiWindow *window)
Redraws a window's empty frame at its current rectangle.
Definition windows.c:400
struct UiWindow * UiWindow_Create(s32 x, s32 y, s32 width, s32 height, s32 attrs)
Opens a window at tile (x, y) of width by height tiles in the first free window slot,...
Definition windows.c:279