Alchemy
Loading...
Searching...
No Matches

status.c

Go to the documentation of this file.
1/// @file
2/// The member chooser and the Status menu: its member row, status page,
3/// Psynergy page and equipment page.
4/// Part of menu.c, the menu object, compiled only through it.
5
6#include "../menu_internal.h"
7
8// The international editions show eight party figure rows, their longer
9// words need more window, and their larger numbers need fewer digits.
10//
11// How many party figure rows Menu_OpenCharacterSelector resets.
12#if TBS_PATCH_1
13#define CHARACTER_SELECTOR_OWNER_COUNT 8
14#else
15#define CHARACTER_SELECTOR_OWNER_COUNT 4
16#endif
17
18// The window tiles the Status menu saves and restores.
19#if TBS_PATCH_1
20#define STATUS_SAVED_TILE_BYTES 0x2000
21#else
22#define STATUS_SAVED_TILE_BYTES 0x800
23#endif
24
25// The longest status help text, in characters.
26#if TBS_PATCH_1
27#define STATUS_HELP_TEXT_MAX 0x80
28#else
29#define STATUS_HELP_TEXT_MAX 0x40
30#endif
31
32// The stat column of the status page's top rows.
33#if TBS_PATCH_1
34#define STATUS_STAT_DIGITS 3
35#define STATUS_STAT_X 200
36#else
37#define STATUS_STAT_DIGITS 4
38#define STATUS_STAT_X 192
39#endif
40
41// Items to a page of the equipment page's list.
42#if TBS_PATCH_1
43#define STATUS_EQUIP_PAGE_SIZE 5
44#else
45#define STATUS_EQUIP_PAGE_SIZE 6
46#endif
47
48// The hand cursor on the Psynergy page.
49#if TBS_PATCH_1
50#define STATUS_PSYNERGY_CURSOR_X 55
51#define STATUS_PSYNERGY_CURSOR_Y 60
52#else
53#define STATUS_PSYNERGY_CURSOR_X 58
54#define STATUS_PSYNERGY_CURSOR_Y 52
55#endif
56
57// The highlight over the equipment window's four slot rows.
58#if TBS_PATCH_1
59#define STATUS_EQUIP_SLOT_X 1
60#define STATUS_EQUIP_SLOT_WIDTH 12
61#else
62#define STATUS_EQUIP_SLOT_X 2
63#define STATUS_EQUIP_SLOT_WIDTH 9
64#endif
65
66// The equipment page's item list: its page icons, the item names, and the
67// Attack and Defense figures.
68#if TBS_PATCH_1
69#define SHOP_PAGE_ICONS_X 119
70#define SHOP_ITEM_NAME_X 128
71#define SHOP_STAT_X 80
72#else
73#define SHOP_PAGE_ICONS_X 123
74#define SHOP_ITEM_NAME_X 136
75#define SHOP_STAT_X 72
76#endif
77
78#if LANGUAGE == LANGUAGE_GERMAN
79#define SHOP_EMPTY_MESSAGE_X 112
80#else
81#define SHOP_EMPTY_MESSAGE_X 120
82#endif
83
84// The equipment window, and the equipped items' names in it.
85#if TBS_PATCH_1
86#define STATUS_EQUIP_WINDOW_WIDTH 15
87#define STATUS_EQUIPPED_NAME_X 8
88#else
89#define STATUS_EQUIP_WINDOW_WIDTH 13
90#define STATUS_EQUIPPED_NAME_X 16
91#endif
92
93/// Lets the player choose one party member, over the field (the Colosso scenes
94/// use it). Returns the chosen member's id, or -1 when the player backs out.
96 struct CharacterMenuState *state =
98 s32 result;
99 s32 index;
100
102 UiWindow_DrawFrameFar(0, 0, 30, 20);
103 WaitFrames(1);
105
108 state->selectorWindow = UiWindow_CreateFar(13, 0, 17, 5, 2);
109 for (index = 0; index < CHARACTER_SELECTOR_OWNER_COUNT; index++)
110 state->ownerY[index] = 30;
111 state->page = 3; // the member chooser
112
113 result = CharacterSelector_Run();
114
118 WaitFrames(1);
120 return result;
121}
122
123/// The member chooser's loop. Returns the chosen member's id, or -1.
125 struct CharacterMenuState *work = gMenuWork;
126 s32 result = 0;
127
128 /* FAKEMATCH(one-pass): the slot's clearing in a one-pass block stores the
129 * zero before the slot's offset is built; as a plain statement, 4 of 23
130 * instructions differ in tbs-en. */
131 do {
132 work->selectedSlots[0] = result;
133 } while (0);
134 if (CharacterMenu_SelectOwner(0) == -1)
135 result = -1;
136 else
137 result = work->selectedIds[0];
138 return result;
139}
140
141/// The Status menu an event opens (window command 4) over the field: saves the
142/// first two background palettes and the window tiles it draws over, sets up
143/// the party row and, when the party has Djinn, the four Djinn sprites, runs
144/// the status pages, then puts everything back. Returns their result.
146 struct CharacterMenuState *state =
148 void *palette = Runtime_BumpAllocateAlternatePool(64);
150 s32 result;
151 s32 index;
152
154 UiWindow_DrawFrameFar(0, 0, 30, 20);
155 WaitFrames(1);
158 state->page = 0;
161 Iwram_CopyWords(palette, (void *)BG_PLTT, 64);
162#if !TBS_PATCH_1
164#endif
166 // The first sprite palette into background palettes 0 and 1, each with a
167 // colour of palette 15 as its colour 14.
168 Dma_Set((void *)OBJ_PLTT, (void *)BG_PLTT, DMA_ENABLE << 16 | 16, REG_DMA3);
169 Dma_Set((void *)&BG_PLTT_COLOR(14, 4), (void *)&BG_PLTT_COLOR(0, 14),
170 DMA_ENABLE << 16 | 1, REG_DMA3);
171 Dma_Set((void *)OBJ_PLTT, (void *)&BG_PLTT_COLOR(1, 0), DMA_ENABLE << 16 | 16,
172 REG_DMA3);
173 Dma_Set((void *)&BG_PLTT_COLOR(15, 4), (void *)&BG_PLTT_COLOR(1, 14),
174 DMA_ENABLE << 16 | 1, REG_DMA3);
175#if TBS_PATCH_1
179#endif
180 state->selectorWindow = UiWindow_CreateFar(13, 0, 17, 5, 2);
181 for (index = 0; index < MENU_ROW_COUNT; index++)
182 state->ownerY[index] = 30;
183 if (Party_SumDjinnCountsFar(-1) != 0)
185 for (index = 0; index < 4; index++) {
186 state->rowX[index] = 130 + index * 32;
187 state->rowY[index] = 128;
188 }
190 // Run the pages.
192 state->page = 0;
193
194 result = Menu_RunActionFlow();
195
196 // Close, and put the palettes and tiles back.
201 UiWindow_DrawFrameFar(0, 0, 30, 20);
202 WaitFrames(1);
203#if TBS_PATCH_1
206 WaitFrames(1);
207#endif
208 Iwram_CopyWords((void *)BG_PLTT, palette, 64);
210 MemFree(tiles);
211 MemFree(palette);
214 UiWindow_DrawFrameFar(0, 0, 30, 20);
217 WaitFrames(1);
218 UiWindow_EraseBorderRectFar(0, 0, 30, 20);
220 return result;
221}
222
223/// The Status menu's pages: choose a party member, then their status page, A
224/// for their Psynergy page and A again for their equipment page; B steps back.
225/// Returns the last page's result, or -1 when the player backs out or presses
226/// Start.
228 struct CharacterMenuState *state = gMenuWork;
229 s32 step = 0;
230 s32 finished = step;
231 s32 result = 0;
232 u32 changed;
233
234 while (!finished && !GameFlag_TestFar(FLAG_MENU_START_PRESSED)) {
235 switch (step) {
236 case 0: // choose a member
237 state->selectedSlots[0] = finished;
238 if (CharacterMenu_SelectOwner(0) == -1) {
239 result = -1;
240 finished = 1;
241 }
242 step = 1;
243 break;
244 case 1: // their status
245 state->ownerCursors[0]->active = ICON_HIDDEN;
247 step = result == -1 ? 0 : 2;
248 break;
249 case 2: // their Psynergy
250 state->ownerCursors[0]->active = ICON_HIDDEN;
251 result = PsynergyMenu_SelectAction();
252 step = 0;
253 if (result != -1)
254 step = 3;
255 break;
256 case 3: // their equipment; back to the member after it
257 state->ownerCursors[0]->active = ICON_HIDDEN;
258 result = ItemMenu_SelectItem();
259 // step 1 for -1, step 0 otherwise.
260 changed = ~result;
261 step = (-changed | changed) >> 31;
262 break;
263 default:
264 finished = 1;
265 break;
266 }
267 }
268
270 result = -1;
271
272 return result;
273}
274
275/// Lets the player choose a party member in slot, from the one chosen last: the
276/// member chooser when the menu is on page 3, else the Status menu's party row.
277/// Game flag 0x172 adds a divider to the party window. Returns the chooser's
278/// result.
280 struct CharacterMenuState *menu;
281 struct RenderOutput *cursor;
282 s32 result;
283 s32 index;
284
285 menu = gMenuWork;
286 index = menu->ownerIndex[slot];
287 result = 0;
288 cursor = menu->ownerCursors[slot];
289 cursor->active = ICON_SHOWN;
290 cursor->animStep = 0;
292 if (GameFlag_TestFar(0x172))
293 UiWindow_DrawDividerLineFar(menu->ownerWindow, 9, 1, 9, 3);
294 if (index == -1)
295 menu->ownerIndex[slot] = 0;
296 else
297 UiMenu_SlideCursor(index * 24 - 10, 16);
298 if (menu->page == 3)
299 result = PsynergyMenu_SelectOwner();
300 else
302 cursor = menu->ownerCursors[slot];
303 UiIcon_PrepareObject(cursor);
304 WaitFrames(1);
305 return result;
306}
307
308/// Shows every Djinn the party has found, a column of seven for each element,
309/// until A, B or Select, then puts the Djinn menu back.
311 struct DjinnMenuWork *menu;
312 struct UiWindow *window;
313 s32 element;
314 s32 djinn;
315
316 menu = gMenuWork;
320 UiText_DrawCharacterAtOffsetFar(MsgReturnHelp, menu->helpWindow, 0, 16);
321 menu->cursor->active = ICON_HIDDEN;
323 WaitFrames(1);
324 window = menu->window;
325 {
326 s32 i;
327
328 for (i = 0; i < 4; i++) {
329 menu->slotX[i] = 32 + i * 56;
330 menu->slotY[i] = 70;
331 menu->ownerY[i] = 30;
332 }
333 }
335 UiWindow_DrawDividerLineFar(window, 0, 11, 28, 11);
336 UiText_DrawResourceFar(MsgCurrentDjinn, menu->helpWindow, -96, 132);
337 for (element = 0; element < 4; element++) {
338 for (djinn = 0; djinn < 7; djinn++) {
339 s32 id = element * 20 + djinn;
340
341 // Game flags 48 on: one per Djinn found, 20 to an element.
343 UiWindow_SetTilemapEntryFar(window, 0x1001 + element, element * 7 + 1,
344 djinn + 3, 0);
345 UiText_DrawCharacterAtOffsetFar(MsgDjinnName + id, window,
346 element * 56 + 16, djinn * 8 + 24);
347 }
348 }
349 }
350 ((struct UiWork *)gWindowWork[0])->dirty = 1;
351 for (;;) {
353 break;
354 WaitFrames(1);
356 break;
357 }
360 {
361 s32 i;
362
363 for (i = 0; i < 4; i++) {
364 menu->slotX[i] = 130 + i * 32;
365 menu->slotY[i] = 128;
366 }
367 }
368 menu->cursor->active = ICON_SHOWN;
371 // Returns no value: the bytes have the s32 epilogue (pop {r1}; bx r1) after
372 // this void call.
373#ifdef UBFIX
374 return 0;
375#endif
376}
377
378struct InventoryMenuState;
379
380/// Lowers the party figures, then raises the currently selected member.
381static __inline__ void
384 s32 rowIndex;
385
386 for (rowIndex = MENU_ROW_COUNT - 1; rowIndex >= 0; rowIndex--)
387 menu->ownerY[rowIndex] = 30;
388 menu->ownerY[selectedOwner] = 26;
389}
390
391/// The Status menu's party row: Left and Right choose a member, showing their
392/// status; L and R move the member one place along the party order; Select
393/// lists the Djinn found (once the first is caught, FLAG_DJINNI_0); A chooses
394/// the member and B backs out. Returns 1 or -1.
396 struct CharacterMenuState *menu;
399 s32 page;
400 s32 redraw;
401 s32 result;
402 s32 rowIndex;
403
404 menu = gMenuWork;
405 ownerIndex = menu->ownerIndex[0];
406 ownerCount = menu->ownerCount[0];
407 redraw = 1;
408 result = 0;
409 page = menu->page;
411 for (rowIndex = 0; rowIndex < 4; rowIndex++) {
412 menu->rowX[rowIndex] = 130 + rowIndex * 32;
413 menu->rowY[rowIndex] = 128;
414 }
415 // The highlight palette, and the first sprite palette into background
416 // palettes 0 and 1.
418 Dma_Set((void *)OBJ_PLTT, (void *)BG_PLTT, DMA_ENABLE << 16 | 16, REG_DMA3);
419 Dma_Set((void *)&BG_PLTT_COLOR(14, 4), (void *)&BG_PLTT_COLOR(0, 14),
420 DMA_ENABLE << 16 | 1, REG_DMA3);
421 Dma_Set((void *)OBJ_PLTT, (void *)&BG_PLTT_COLOR(1, 0), DMA_ENABLE << 16 | 16,
422 REG_DMA3);
423 Dma_Set((void *)&BG_PLTT_COLOR(15, 4), (void *)&BG_PLTT_COLOR(1, 14),
424 DMA_ENABLE << 16 | 1, REG_DMA3);
426 if (redraw) {
427 redraw = 0;
428 // The help lines, and the member's status and figure.
430 UiText_DrawCharacterAtOffsetFar(MsgRearrangeHelp, menu->selectorWindow, 0,
431 0);
433 UiText_DrawCharacterAtOffsetFar(MsgDjinnListHelp, menu->selectorWindow,
434 0, 16);
435 UiText_DrawCharacterAtOffsetFar(MsgRearrangeHelp - 3, // "A: Details"
436 menu->selectorWindow, 0, 8);
439 page = (page + 3) % 3;
443 }
444 UiMenu_PositionCursor(ownerIndex * 24 - 10, 16);
445 WaitFrames(1);
446 if (gKeysPressed & KEY_A) {
448 result = 1;
449 break;
450 }
451 if (gKeysPressed & KEY_B) {
453 result = -1;
454 break;
455 }
456 // L and R move the member along the party order.
457 if (gKeysRepeat & KEY_R) {
460 ownerIndex++;
464 } else {
466 }
467 WaitFrames(1);
468 } else if (gKeysRepeat & KEY_L) {
471 ownerIndex--;
475 } else {
477 }
478 WaitFrames(1);
481 redraw = 1;
482 } else {
483 if (gKeysRepeat & KEY_LEFT) {
485 if (ownerCount > 1) {
486 ownerIndex--;
487 redraw = 1;
488 }
489 }
490 if (gKeysRepeat & KEY_RIGHT) {
492 if (ownerCount > 1) {
493 redraw = 1;
494 ownerIndex++;
495 }
496 }
497 }
498 }
499 menu->ownerIndex[0] = ownerIndex;
500 menu->selectedOwner = menu->ownerIds[ownerIndex];
501 menu->selectedIds[0] = menu->ownerIds[ownerIndex];
502 return result;
503}
504
505/// The member chooser (menu page 3): Left and Right choose a party member,
506/// showing their status and Psynergy icons; A chooses and B backs out. Returns
507/// 1 or -1.
509 struct PsynergyMenuState *menu = gMenuWork;
510 s32 ownerIndex = menu->tabIndex[0];
511 s32 ownerCount = menu->tabCounts[0];
512 s32 redraw = 1;
513 s32 page = menu->flags;
514 s32 result;
515 s32 rowIndex;
516
517 UnitGetFar(menu->ownerTable[ownerIndex]);
519 UiText_DrawCharacterAtOffsetFar(MsgChooseCharacter, menu->messageWindow, 0,
520 0);
521 UiText_DrawCharacterAtOffsetFar(MsgChooseCharacter + 1, menu->messageWindow,
522 0, 16);
523 for (;;) {
524 if (redraw) {
525 redraw = 0;
526 ownerIndex = (ownerIndex + ownerCount) % ownerCount;
527 UnitGetFar(menu->ownerTable[ownerIndex]);
528 page = (page + 3) % 3;
529 Menu_CreateWindowAndEntryObjects(menu->ownerTable[ownerIndex], page);
530 PsynergyMenu_CallIconRoutineWithValue(menu, menu->ownerTable[ownerIndex]);
531 for (rowIndex = 0; rowIndex < MENU_ROW_COUNT; rowIndex++)
532 menu->rowPositions[rowIndex] = 30;
533 menu->rowPositions[ownerIndex] = 26;
535 UnitGetFar(menu->ownerTable[ownerIndex]), (u16 *)menu->psynergies, 0);
539 }
540 UiMenu_PositionCursor(ownerIndex * 24 - 10, 16);
541 WaitFrames(1);
542 if (gKeysPressed & KEY_A) {
544 result = 1;
545 break;
546 }
547 if (gKeysPressed & KEY_B) {
549 result = -1;
550 break;
551 }
552 {
553 if (gKeysRepeat & KEY_LEFT) {
555 if (ownerCount > 1) {
556 ownerIndex--;
557 redraw = 1;
558 }
559 }
560 if (gKeysRepeat & KEY_RIGHT) {
562 if (ownerCount > 1) {
563 ownerIndex++;
564 redraw = 1;
565 }
566 }
567 }
568 }
569 menu->tabIndex[0] = ownerIndex;
570 menu->selectedOwner = menu->ownerTable[ownerIndex];
571 menu->ownerIds[0] = menu->ownerTable[ownerIndex];
572 return result;
573}
574
575/// Moves the party member at selectedIndex one place later (direction 1) or
576/// earlier (0) in the party order. Returns 1, or 0 when it cannot move.
577s32 CharacterSelector_MoveEntry(s32 selectedIndex, s32 direction) {
578 struct CharacterMenuState *menu = gMenuWork;
579 u32 reordered[14];
580 s32 index;
581
582 if (menu->partyCount <= 1) {
583 return 0;
584 }
585 if (direction == 1) {
586 if (selectedIndex == menu->partyCount - 1) {
587 return 0;
588 }
589 } else {
590 if (selectedIndex == 0) {
591 return 0;
592 }
593 }
594
595 {
596 u32 zero = 0;
597#ifdef UBFIX
598 s32 clearIndex = 13;
599
600 // Avoid forming reordered - 1 after the final store. The plain indexed
601 // clear adds four native bytes, so matching builds retain the old cursor.
602 do {
603 reordered[clearIndex] = zero;
604 clearIndex--;
605 } while (clearIndex >= 0);
606#else
607 u32 *clear = &reordered[13];
608
609 do {
610 *clear = zero;
611 clear--;
612 } while ((s32)clear >= (s32)reordered);
613#endif
614 }
615 for (index = 0; index < menu->partyCount; index++) {
616 reordered[index] = menu->ownerIds[index];
617 }
618
619 if (direction == 1) {
620 index = reordered[selectedIndex];
621 reordered[selectedIndex] = reordered[selectedIndex + 1];
622 reordered[selectedIndex + 1] = index;
623 } else {
624 index = reordered[selectedIndex];
625 reordered[selectedIndex] = reordered[selectedIndex - 1];
626 reordered[selectedIndex - 1] = index;
627 }
628
629 // Rebuild the party in the new order.
630 for (index = 0; index < menu->partyCount; index++) {
632 }
633 for (index = 0; index < menu->partyCount; index++) {
634 Party_AddActiveOwnerFar(reordered[index]);
635 }
637 return 1;
638}
639
640/// Sets up the Status menu's first screen: the cursor window with the party's
641/// figures, no other windows yet, and an 8 by 2 cursor grid. The parameters are
642/// not used.
643void Menu_InitSelectorCursorAndEntries(s32 unused0, s32 unused1, s32 unused2,
644 s32 unused3) {
645 struct CharacterMenuState *state;
646
647 state = gMenuWork;
649 state->unknownWindow028 = 0;
650 state->statusWindow = 0;
651 state->helpWindow = 0;
652 state->actionWindow = 0;
653 state->selectedColumn = 0;
654 state->selectedRow = 0;
655 state->columnCount = 8;
656 state->rowCount = 2;
657}
658
659/// Shows member resource's status in the status window (0, 5, 30 by 15),
660/// opening it first with the member's portrait, the item icons on the chooser
661/// page, and the eight stat sprites; then draws the status and ailments.
663 s32 created;
664 struct UiWindow *window;
665 struct RenderOutput *cursor;
666 struct CharacterMenuState *menu;
667
668 menu = gMenuWork;
669 created = 0;
670 window = menu->statusWindow;
671 if (window == 0) {
672 created = UiWindow_UpdateOrCreate(&menu->statusWindow, 0, 5, 30, 15, 2);
673 window = menu->statusWindow;
674 }
675 if (created != 0) {
676 cursor = SideObject_CreateFar(resource, 0, 0, window, 0, 0);
677 menu->statusCursor = cursor;
678 if ((cursor->sentinel = 0xF0, menu->page) == 3) {
679 Menu_SpawnIconEntries((struct InventoryMenuState *)menu, window);
680 }
682 CharacterMenu_DrawStatusAilments(window, resource, 0x100);
683 return;
684 }
685 CharacterMenu_DrawStatusAilments(window, resource, 0);
686}
687
688/// The member's status page. The left pane lists their ailments (or the stat
689/// help when they have none) and the right pane the status entries (name and
690/// level, experience, HP, PP, Djinn when the party has any, elemental levels,
691/// Power and Resist); the cursor's entry is highlighted and explained in the
692/// help window. Up and Down move in a pane, Left and Right switch panes, L and
693/// R switch to the previous or next member; A goes on to the Psynergy page and
694/// B backs out. Returns 1 or -1.
696 struct CharacterMenuState *menu;
697 s32 pane;
698 s32 result;
699 s32 selected;
700 s8 count;
701 s32 hasAilments;
702 s32 done;
703 s32 hasDjinn;
704 s32 redraw;
705 s32 member;
706 s32 djinnTotal;
707 s32 i;
708 u8 entries[8];
709
710 menu = gMenuWork;
711 pane = 0;
712 result = 0;
713 selected = 0;
714 djinnTotal = Party_SumDjinnCountsFar(-1);
715 hasDjinn = 0;
716 if (djinnTotal != 0)
717 hasDjinn = 1;
718 UiWindow_UpdateOrCreate(&menu->helpWindow, 0, 0, 30, 5, 2);
720 for (i = 3; i >= 0; i--)
721 menu->rowY[i] = 104;
722 done = 0;
723 UiMenu_SlideCursor(-10, 88);
724
725 // One member's page at a time; L and R start the next.
726 while (done == 0 && GameFlag_TestFar(FLAG_MENU_START_PRESSED) == 0) {
727 UnitGetFar(menu->selectedIds[0]);
729 1);
731 hasAilments = 0;
732 if (count == 0)
733 count = 1;
734 else
735 hasAilments = 1;
736 redraw = 1;
737
739 if (redraw != 0) {
740 s32 limit;
741
742 redraw = 0;
743 limit = count;
744 pane = (pane + 2) % 2;
745 if (pane == 0) {
746 selected = (selected + limit) % limit;
748 if (hasAilments == 0) {
750 MsgSwitchCharacterHelp, menu->statusWindow, SWITCH_HELP_X, -24);
751 UiText_DrawCharacterAtOffsetFar(MsgSwitchCharacterHelp + 1,
752 menu->statusWindow, 0, -24);
753 }
754 } else {
756 if (hasDjinn != 0)
757 selected = (selected + 8) % 8;
758 else
759 selected = (selected + 7) % 7;
760 }
761 CharacterMenu_DrawSelectionCursor(pane, selected, entries, 0);
763 WaitFrames(1);
764 if (pane == 0)
766 entries);
767 else
769 hasDjinn);
770 }
771 menu->ownerCursors[0]->active = ICON_SHOWN;
772 if (pane == 0)
773 UiMenu_PositionCursor(-10, selected * 16 + 88);
774 else if (selected <= 3)
775 UiMenu_PositionCursor(24, selected * 8 + 48);
776 else
777 UiMenu_PositionCursor(48, selected * 8 + 80);
778 WaitFrames(1);
780 CharacterMenu_DrawSelectionCursor(pane, selected, entries, 1);
781 if (gKeysPressed & KEY_A) {
783 done = 1;
784 result = 1;
785 break;
786 }
787 if (gKeysPressed & KEY_B) {
789 done = 1;
790 result = -1;
791 break;
792 }
793 if (gKeysRepeat & KEY_UP) {
795 redraw = 1;
796 selected--;
797 }
798 if (gKeysRepeat & KEY_DOWN) {
800 redraw = 1;
801 selected++;
802 }
803 if (gKeysRepeat & KEY_RIGHT) {
805 redraw = 1;
806 pane++;
807 }
808 if (gKeysRepeat & KEY_LEFT) {
810 redraw = 1;
811 pane--;
812 }
813 // L and R: the previous or next member.
814 if ((gKeysRepeat & KEY_R) || (gKeysRepeat & KEY_L)) {
816 member = menu->ownerIndex[0];
817 if (gKeysRepeat & KEY_R)
818 member++;
819 else
820 member--;
821 member = (member + menu->partyCount) % menu->partyCount;
822 menu->selectedOwner = menu->ownerIds[member];
823 menu->selectedIds[0] = menu->ownerIds[member];
824 menu->ownerIndex[0] = member;
826 break;
827 }
828 }
829 }
832 UiWindow_ClearInteriorTilesFar(menu->statusWindow, 64, 56, 224, 96);
834 for (i = 3; i >= 0; i--)
835 menu->rowY[i] = 128;
837 return result;
838}
839
840/// Highlights (invert 0) or unhighlights (invert 1) the selected entry of the
841/// status page: in pane 0 the selected ailment row, as wide as its label
842/// (gCharacterMenu_CursorWidths); in pane 1 one of the first four status rows
843/// or of the rows below.
845 s32 invert) {
846 struct CharacterMenuState *menu = gMenuWork;
847 u32 different;
848 s32 count;
849 s32 index;
850 s32 x;
851 s32 y;
852 s32 palette;
853 u8 width;
854
855 if (mode == 0) {
856 y = selected * 2 + 5;
857 x = 0;
858 width = 5;
859 count = 0;
860 index = 0;
861 while (index <= 4) {
862 if (entries[index] != 0) {
863 if (selected == count) {
864 width = gCharacterMenu_CursorWidths[index];
865 break;
866 }
867 count++;
868 }
869 index++;
870 }
871 } else if (selected <= 3) {
872 y = selected;
873 x = 5;
874 width = 13;
875 } else {
876 y = selected + 4;
877 x = 8;
878 width = 20;
879 }
880
881 // Palette 14 (highlighted) when invert is 0, 15 when it is 1.
882 different = 1 ^ invert;
883 palette = 15 - (((0u - different) | different) >> 31);
884 Render_SetTilemapFlagRect(menu->statusWindow, x, y, width, 1, palette);
885}
886
887/// Writes the advice for the selected ailment (two lines, for example how to
888/// revive a member who is down) into window target, or that the member is well
889/// when they have no ailment.
890void CharacterMenu_DrawSelectionLabels(struct UiWindow *target, s32 selected,
891 const u8 *entries) {
892 s32 labelCount = 0;
893 s32 labelIndex = 0;
894
895 do {
896 if (entries[labelIndex] != 0) {
897 if (selected == labelCount) {
898 s32 messageId = MsgStatusAdvice + labelIndex * 2;
899 UiText_DrawResourceFar(messageId, target, 0, -1);
900 UiText_DrawResourceFar(messageId + 1, target, 0, 15);
901 }
902 labelCount++;
903 }
904 labelIndex++;
905 } while (labelIndex <= 4);
906
907 if (labelCount == 0)
908 UiText_DrawResourceFar(MsgStatusNormal, target, 0, 0);
909}
910
911// Native revisions keep different local widths; the text value consumes u32.
912#if TBS_PATCH_1
914#else
916#endif
917
918/// Writes the help text of status entry messageVariant into destination: the
919/// entries skip Djinn when the party has none (preserveVariant 0); the
920/// experience entry says how many points the next level needs, or, at level 99,
921/// gives the plain experience text.
923 s32 messageVariant,
924 s32 preserveVariant) {
925 struct CharacterMenuState *menu = gMenuWork;
926 void *buffer;
927
928 if (preserveVariant == 0 && messageVariant > 3) {
929 messageVariant++;
930 }
931 if (messageVariant == 1) {
932 struct BattleUnit *owner = UnitGetFar(menu->selectedIds[0]);
933
934 if (owner->level == 99) {
935 messageVariant = 8; // "These are your experience points."
936 } else {
937 ExperienceDifference remaining =
939 owner->level + 1) -
940 owner->experience;
941 UiWork_PushValueSlotFar(remaining, 5);
942 }
943 }
944
945 buffer = MemAlloc(STATUS_HELP_TEXT_MAX * 2);
946 UiText_CopyMessageStringFar(messageVariant + MsgProgressHelp, buffer,
948 UiText_RenderWideStringAtOffsetFar(buffer, destination, 0, -1);
949 MemFree(buffer);
950}
951
952/// Draws member ownerId's status page into window: the top rows (ItemMenu_
953/// DrawOwnerStatus), the ailment list or "Normal", and except on the chooser
954/// page the Djinn counts by element and, in mode 1, the elemental levels,
955/// Power and Resist. mode's 0x100 keeps what is drawn instead of clearing it.
956void CharacterMenu_DrawStatusAilments(struct UiWindow *window, s32 ownerId,
957 s32 mode) {
958 struct CharacterMenuState *menu = gMenuWork;
959 struct BattleUnit *unit;
960 s32 djinnRow;
961 s32 hasDjinn;
962 s32 keepDrawn;
963 s32 ailmentIndex;
964 u8 ailments[8];
965
966 if (Party_SumDjinnCountsFar(-1) != 0)
967 hasDjinn = 1;
968 else
969 hasDjinn = 0;
970 unit = UnitGetFar(ownerId);
971 if ((mode & 0xff) == 1)
972 djinnRow = 7;
973 else
974 djinnRow = 10;
976 ItemMenu_DrawOwnerStatus(window, ownerId, mode);
977 CharacterMenu_BuildAvailability(ailments, 1, ownerId);
979 keepDrawn = mode & 0x100;
980 if (keepDrawn == 0)
981 UiWindow_ClearInteriorTilesFar(window, 0, 40, 96, 96);
982 // The ailments, one a row, or "Normal".
983 ailmentIndex = 0;
984 if (ailments[CHARACTER_DOWN] != 0) {
985 UiText_DrawCharacterAtOffsetFar(MsgDownLabel, window, 16, 40);
986 ailmentIndex = 1;
987 }
988 if (ailments[CHARACTER_POISON] != 0) {
989 UiText_DrawCharacterAtOffsetFar(MsgPoisonLabel, window, 16,
990 ailmentIndex * 16 + 40);
991 ailmentIndex++;
992 }
993 if (ailments[CHARACTER_VENOM] != 0) {
994 UiText_DrawCharacterAtOffsetFar(MsgVenomLabel, window, 16,
995 ailmentIndex * 16 + 40);
996 ailmentIndex++;
997 }
998 if (ailments[CHARACTER_CURSE] != 0) {
999 UiText_DrawCharacterAtOffsetFar(MsgCurseLabel, window, 16,
1000 ailmentIndex * 16 + 40);
1001 ailmentIndex++;
1002 }
1003 if (ailments[CHARACTER_HAUNT] != 0) {
1004 UiText_DrawCharacterAtOffsetFar(MsgHauntLabel, window, 16,
1005 ailmentIndex * 16 + 40);
1006 ailmentIndex++;
1007 }
1008 if (ailmentIndex == 0)
1009 UiText_DrawCharacterAtOffsetFar(MsgNormalLabel, window, 0, 40);
1011 ItemMenu_ApplyFlags(ailments);
1012 if (menu->page == 3)
1013 return;
1014 if (keepDrawn == 0) {
1015 WaitFrames(1);
1016 UiWindow_ClearInteriorTilesFar(window, 64, 56, 224, 96);
1017 }
1018 // The four element icons, then the Djinn counts and, in mode 1, the
1019 // elemental levels, Power and Resist.
1021 if (mode == 1 || hasDjinn == 1) {
1022 UiWindow_SetTilemapEntryFar(window, 1, 15, djinnRow, 4);
1023 UiWindow_SetTilemapEntryFar(window, 2, 19, djinnRow, 4);
1024 UiWindow_SetTilemapEntryFar(window, 3, 23, djinnRow, 4);
1025 UiWindow_SetTilemapEntryFar(window, 4, 27, djinnRow, 4);
1026 }
1027 if (hasDjinn)
1028 UiText_DrawCharacterAtOffsetFar(MsgDjinnLabel, window, 64,
1029 djinnRow * 8 + 8);
1030 if (mode == 1) {
1031 if (!hasDjinn)
1032 djinnRow--;
1033 MENU_DRAW_STATUS_LABEL(gMenu_LvString, window, 64, djinnRow * 8 + 16);
1034 UiText_DrawCharacterAtOffsetFar(MsgPowerLabel, window, 64,
1035 djinnRow * 8 + 24);
1036 UiText_DrawCharacterAtOffsetFar(MsgPowerLabel + 1, window, 64,
1037 djinnRow * 8 + 32);
1038 }
1039 for (ailmentIndex = 0; ailmentIndex <= 3; ailmentIndex++) {
1040 if (hasDjinn)
1041 UiText_DrawNumberInWindowFar(unit->djinnOwnedCounts[ailmentIndex], 1,
1042 window, ailmentIndex * 32 + 120,
1043 djinnRow * 8 + 8);
1044 if ((mode & 0xff) == 1) {
1045 if (hasDjinn) {
1046 UiText_DrawNumberInWindowFar(unit->djinnActiveCounts[ailmentIndex], 1,
1047 window, ailmentIndex * 32 + 104,
1048 djinnRow * 8 + 8);
1050 ailmentIndex * 32 + 112, djinnRow * 8 + 8);
1051 }
1053 Unit_GetElementLevelFar(ownerId, ailmentIndex), 2, window,
1054 ailmentIndex * 32 + 112, djinnRow * 8 + 16);
1055 UiText_DrawNumberInWindowFar(unit->element[ailmentIndex].power, 3, window,
1056 ailmentIndex * 32 + 104, djinnRow * 8 + 24);
1057 UiText_DrawNumberInWindowFar(unit->element[ailmentIndex].resistance, 3,
1058 window, ailmentIndex * 32 + 104,
1059 djinnRow * 8 + 32);
1060 }
1061 }
1062}
1063
1064#if TBS_PATCH_1
1065/// Spins for 256 loop passes (international editions only).
1067 s32 count = 0xff;
1068
1069spin:
1070 count--;
1071 if (count >= 0)
1072 goto spin;
1073}
1074
1075#endif
1076
1077/// Draws the top rows of member ownerId's status page into window: name, class,
1078/// level, experience, HP and PP on the left, Attack, Defense, Agility and Luck
1079/// on the right. flags' 0x100 keeps what is drawn instead of clearing it.
1080void ItemMenu_DrawOwnerStatus(struct UiWindow *window, s32 ownerId, s32 flags) {
1081 struct InventoryMenuState *menu;
1082 struct BattleUnit *unit;
1083
1084 menu = gMenuWork;
1085 unit = UnitGetFar(ownerId);
1086 menu->cursor->active = ICON_SHOWN;
1087 flags &= 0x100;
1088 if (flags == 0) {
1089 UiWindow_ClearInteriorTilesFar(window, 0, 0, 128, 40);
1090 }
1091 UiText_DrawStringAtOffsetFar(unit->name, window, 40, 0);
1092 UiText_DrawCharacterAtOffsetFar(unit->classIndex + MsgClassName, window, 0,
1093 32);
1094 MENU_DRAW_STATUS_LABEL(gMenu_LvString, window, 104, 0);
1096 UiText_DrawNumberInWindowFar(unit->level, 2, window, 128, 0);
1097 MENU_DRAW_STATUS_LABEL(gMenu_HpString, window, 40, 16);
1098 UiText_DrawNumberInWindowFar(unit->hp, 4, window, 72, 16);
1099 UiText_DrawNumberInWindowFar(unit->maxHp, 4, window, 112, 16);
1101 MENU_DRAW_STATUS_LABEL(gMenu_PpString, window, 40, 24);
1102 UiText_DrawNumberInWindowFar(unit->pp, 4, window, 72, 24);
1103 UiText_DrawNumberInWindowFar(unit->maxPp, 4, window, 112, 24);
1105 UiText_DrawCharacterAtOffsetFar(MsgExpLabel, window, 40, 8);
1106 UiText_DrawNumberInWindowFar(unit->experience, 7, window, 88, 8);
1107 if (flags == 0) {
1108 WaitFrames(1);
1109 UiWindow_ClearInteriorTilesFar(window, 144, 0, 224, 40);
1110 }
1111 // The labels "Attack", "Defense", "Agility" and "Luck", 23 to 20 messages
1112 // before "Exp".
1113 UiText_DrawCharacterAtOffsetFar(MsgExpLabel - 23, window, 152, 0);
1114 UiText_DrawCharacterAtOffsetFar(MsgExpLabel - 22, window, 152, 8);
1115 UiText_DrawCharacterAtOffsetFar(MsgExpLabel - 21, window, 152, 16);
1116 UiText_DrawCharacterAtOffsetFar(MsgExpLabel - 20, window, 152, 24);
1118 STATUS_STAT_X, 0);
1120 STATUS_STAT_X, 8);
1122 STATUS_STAT_X, 16);
1124 STATUS_STAT_X, 24);
1125}
1126
1127/// Fills ailments[0..4] (CharacterAilment) with member ownerId's ailments: down
1128/// (only when requested is 1), poison or venom, curse and haunt. Returns how
1129/// many they have.
1130s32 CharacterMenu_BuildAvailability(u8 *ailments, s32 requested, s32 ownerId) {
1131 struct BattleUnit *unit;
1132 s32 ailmentIndex;
1133 s32 count;
1134 s32 poison;
1135
1136 unit = UnitGetFar(ownerId);
1137 for (ailmentIndex = 4; ailmentIndex >= 0; ailmentIndex--)
1138 ailments[ailmentIndex] = 0;
1139
1140 count = 0;
1141 if (unit->hp == 0 && requested == 1) {
1142 ailments[CHARACTER_DOWN] = requested;
1143 count = 1;
1144 }
1145
1146 poison = unit->poison;
1147 if (poison != 0) {
1148 if (poison == 1) // poison; any other value is venom
1149 ailments[CHARACTER_POISON] = poison;
1150 else
1151 ailments[CHARACTER_VENOM] = 1;
1152 count++;
1153 }
1154 if (unit->restraint != 0) {
1155 ailments[CHARACTER_CURSE] = 1;
1156 count++;
1157 }
1158 if (unit->haunt != 0) {
1159 ailments[CHARACTER_HAUNT] = 1;
1160 count++;
1161 }
1162 return count;
1163}
1164
1165/// Fills result with the item list of the member in pane index for the
1166/// equipment pages: their unit, the menu's item count, and the page and row of
1167/// the item chosen last for them, STATUS_EQUIP_PAGE_SIZE items to a page.
1168/// Returns 1.
1169s32 Menu_BuildPageResult(struct MenuResult *result, s32 index) {
1170 s32 unitBits;
1171 struct InventoryMenuState *menu = gMenuWork;
1172 s32 itemCount;
1173 s32 row;
1174 s32 page;
1175 s32 pageCount;
1176 s32 selected;
1177
1178 unitBits = (s32)UnitGetFar(menu->paneOwner[index]);
1179 itemCount = menu->itemCount;
1180 selected = menu->selectedIndexByOwner[menu->paneOwner[index]];
1181 if ((selected + 1) > itemCount) {
1182 selected = itemCount - 1;
1183 }
1184 if (itemCount == 0) {
1185 selected = 0;
1186 }
1187 page = selected / STATUS_EQUIP_PAGE_SIZE;
1188 row = selected % STATUS_EQUIP_PAGE_SIZE;
1189 pageCount = itemCount / STATUS_EQUIP_PAGE_SIZE;
1190 if (itemCount % STATUS_EQUIP_PAGE_SIZE != 0) {
1191 pageCount++;
1192 }
1193 result->ownerState = unitBits;
1194 result->page = page;
1195 result->pageCount = pageCount;
1196 result->row = row;
1197 result->entryCount = itemCount;
1198 result->selectedIndex = selected;
1199 return 1;
1200}
1201
1202static __inline__ u32 XorWord(u32 word, u32 mask) { return word ^ mask; }
1203
1204extern const struct TileMask gMenu_PatternRowMasks[];
1205
1206/// Builds twelve 8x8 tiles in the window tile area: two sets of six, each a
1207/// fill of colour 4 with the rows of gMenu_PatternRowMasks XORed in, the first
1208/// set growing row by row and the second skipping its top row.
1210#if TBS_PATCH_1
1211 u32 *vram = (u32 *)(BG_CHAR_BLOCK(1) + 0x1000);
1212#else
1213 u32 *vram = (u32 *)BG_CHAR_BLOCK(1);
1214#endif
1215 s32 set;
1216 s32 tileIndex;
1217
1218 for (set = 0; set < 2; set++) {
1219 for (tileIndex = 0; tileIndex < 6; tileIndex++) {
1220 u32 *tile = vram + set * 0x60 + tileIndex * 0x10;
1221 s32 rowIndex;
1222
1223 Iwram_FillWords(tile, 64, 0x44444444);
1224 for (rowIndex = 1; rowIndex <= 7; rowIndex++) {
1225 s32 mask = tileIndex;
1226
1227 if (set == 1 && rowIndex <= 1) {
1228 continue;
1229 }
1230 if (set == 0 && tileIndex > rowIndex - 2) {
1231 mask = rowIndex - 2;
1232 if (mask < 0) {
1233 mask = 0;
1234 }
1235 }
1236 tile[rowIndex] =
1237 XorWord(tile[rowIndex], gMenu_PatternRowMasks[mask].word0);
1238 tile[rowIndex + 8] =
1239 XorWord(tile[rowIndex + 8], gMenu_PatternRowMasks[mask].word1);
1240 }
1241 }
1242 }
1243}
1244
1245/// Draws a Psynergy range icon at (x, y) of window: three tiles from the
1246/// range icon tiles, the left one mirrored.
1247void PsynergyMenu_DrawRange(struct UiWindow *window, s32 x, s32 y, s32 range,
1248 s32 unused) {
1249 s32 iconIndex;
1250 s32 tile;
1251
1252 (void)unused;
1253
1254 iconIndex = range * 2;
1255 tile = iconIndex + RANGE_ICON_TILE + 1;
1256 UiWindow_SetTilemapEntryFar(window, 0x400 | tile, x, y, 0); // flipped
1257 UiWindow_SetTilemapEntryFar(window, iconIndex + RANGE_ICON_TILE, x + 1, y, 0);
1258 UiWindow_SetTilemapEntryFar(window, tile, x + 2, y, 0);
1259}
1260
1261/// Updates the Psynergy page for the row under the cursor: the Psynergy's
1262/// description in the info window, where it can be used (in the field, in
1263/// battle, or anywhere), and the row highlights with the range icons.
1265 struct MenuResult *state) {
1266 struct PsynergyMenuState *menu;
1267 struct BattleAct *ability;
1268 s32 row;
1269 s32 base;
1270
1271 menu = gMenuWork;
1272 state->selectedIndex = state->page * PAGE_ROWS + state->row;
1273#if TBS_PATCH_1 && !TBS_PATCH_4
1275#elif TBS_PATCH_4
1276 UiWindow_ClearInteriorTilesFar(menu->infoWindow, 0, 0, 224, 8);
1277#else
1279#endif
1280 WaitFrames(1);
1281 if (menu->psynergies[state->selectedIndex] != 0) {
1284 MsgAbilityDescription,
1285 menu->infoWindow, 0, 0);
1286 ability = BattleActGet(menu->psynergies[state->selectedIndex] &
1288#if LANGUAGE != LANGUAGE_JAPANESE
1289 UiWindow_ClearInteriorTilesFar(window, 0, 96, 224, 104);
1290 row = 0;
1291 if (ability->type0c != 0 ||
1292 (ability->flags & ACTION_USABLE_IN_FIELD) != 0) {
1293 row = 2;
1294 }
1295 if ((ability->flags & ACTION_USABLE_IN_BATTLE) != 0) {
1296 row |= 1;
1297 }
1298 if (row == 3) {
1299 UiText_DrawCharacterAtOffsetFar(MsgUsableAnywhere, window, 0, 96);
1300 } else if (row == 2) {
1301 UiText_DrawCharacterAtOffsetFar(MsgUsableInField, window, 0, 96);
1302 } else if (row == 1) {
1303 UiText_DrawCharacterAtOffsetFar(MsgUsableInBattle, window, 0, 96);
1304 }
1305#else
1306 UiWindow_ClearInteriorTilesFar(window, 0, 72, 64, 96);
1307 row = 0;
1308 if (ability->type0c != 0 ||
1309 (ability->flags & ACTION_USABLE_IN_FIELD) != 0) {
1310 UiText_DrawCharacterAtOffsetFar(MsgUsableInField, window, 0, 72);
1311 row = 1;
1312 }
1313 if ((ability->flags & ACTION_USABLE_IN_BATTLE) != 0) {
1314 UiText_DrawCharacterAtOffsetFar(MsgUsableInBattle, window, 0,
1315 row * 8 + 72);
1316 row++;
1317 }
1318 UiText_DrawCharacterAtOffsetFar(MsgCanBeUsed, window, 0, row * 8 + 72);
1319#endif
1320 }
1321
1322 base = state->page * PAGE_ROWS;
1323 for (row = 0; row <= PAGE_ROWS - 1; row++) {
1324 if (row == state->row) {
1325 ability =
1326 BattleActGet(menu->psynergies[base + row] & OWNER_ACTION_ID_MASK);
1327 if (ability->element != 4) {
1328 UiWindow_SetTilemapEntryFar(window, ability->element + 1, 24,
1329 row * 2 + LIST_FIRST_ROW, 0);
1330 Render_SetTilemapFlagRect(window, 9, row * 2 + LIST_FIRST_ROW, 15, 1,
1331 14);
1332 Render_SetTilemapFlagRect(window, 25, row * 2 + LIST_FIRST_ROW, 3, 1,
1333 14);
1334 } else {
1335 Render_SetTilemapFlagRect(window, 9, row * 2 + LIST_FIRST_ROW, 19, 1,
1336 14);
1337 }
1338 } else {
1339 ability =
1340 BattleActGet(menu->psynergies[base + row] & OWNER_ACTION_ID_MASK);
1341 if (ability->element != 4) {
1342 UiWindow_SetTilemapEntryFar(window, ability->element + 1, 24,
1343 row * 2 + LIST_FIRST_ROW, 4);
1344 Render_SetTilemapFlagRect(window, 9, row * 2 + LIST_FIRST_ROW, 15, 1,
1345 15);
1346 Render_SetTilemapFlagRect(window, 25, row * 2 + LIST_FIRST_ROW, 3, 1,
1347 15);
1348 } else {
1349 Render_SetTilemapFlagRect(window, 9, row * 2 + LIST_FIRST_ROW, 19, 1,
1350 15);
1351 }
1352 }
1353 }
1354 WaitFrames(1);
1355 return 1;
1356}
1357
1359 const struct MenuResult *res) {
1360 struct PsynergyMenuState *menu = gMenuWork;
1361 struct BattleUnit *owner;
1362 u32 firstEntry;
1363 u32 rows;
1364 u8 row;
1365 s32 entryIndex;
1366
1367 (void)unused;
1368
1369 owner = UnitGetFar(menu->ownerIds[0]);
1370
1372
1373 firstEntry = res->page * PAGE_ROWS;
1374 rows = (u8)(res->entryCount - firstEntry);
1375 if (rows > PAGE_ROWS) {
1376 rows = PAGE_ROWS;
1377 }
1378
1380 Menu_DrawPageIndicator(window, res->entryCount, PAGE_ROWS, res->page, 28);
1381
1382 UiText_DrawCharacterAtOffsetFar(MsgPsynergyPp, window, LIST_PP_X, 0);
1383
1384 row = 0;
1385 if (rows > row) {
1386 entryIndex = firstEntry;
1387 do {
1388 struct BattleAct *action;
1389 s32 messageId;
1390 s32 y;
1391 s32 range;
1392 action =
1393 BattleActGet(OWNER_ACTION_ID_MASK & menu->psynergies[entryIndex]);
1394 messageId = (menu->psynergies[entryIndex] & OWNER_ACTION_ID_MASK) +
1395 MsgAbilityName;
1396 y = row * 16 + LIST_FIRST_ROW * 8;
1397
1398 UiText_DrawCharacterAtOffsetFar(messageId, window, LIST_NAME_X, y);
1400 y);
1401
1402 range = action->range;
1403 if (range == 0xff) {
1404 range = 11;
1405 } else {
1406 range--;
1407 }
1408 PsynergyMenu_DrawRange(window, 25, row * 2 + LIST_FIRST_ROW, range, 0);
1409
1410 row++;
1411 entryIndex++;
1412 } while (rows > row);
1413 }
1414
1415 if (menu->psynergyCount == 0) {
1416 UiText_DrawCharacterAtOffsetFar(MsgNoPsynergy, window, 96, LIST_EMPTY_Y);
1417 }
1418
1419 UiText_DrawStringAtOffsetFar(owner->name, (void *)window, 40, 0);
1420 UiText_DrawCharacterAtOffsetFar(owner->classIndex + MsgClassName, window, 0,
1421 32);
1422#if LANGUAGE == LANGUAGE_SPANISH || LANGUAGE == LANGUAGE_FRENCH
1423 UiText_DrawStringAtOffsetFar(gMenu_LvString, (void *)window, 0, 48);
1424#else
1426#endif
1427 UiText_DrawNumberInWindowFar(owner->level, 2, window, 24, 48);
1428
1429 return 1;
1430}
1431
1433
1434 struct PsynergyMenuState *menu;
1435 s32 result;
1436 s32 done;
1437 s32 redraw;
1438 s32 listNeedsRedraw;
1439 s32 navigationResult;
1440 s32 ownerIndex;
1441 s32 iconIndex;
1442 struct MenuResult state;
1443
1444 menu = gMenuWork;
1445 result = 0;
1446 done = 0;
1449 UiWindow_UpdateOrCreate(&menu->infoWindow, 0, 0, 30, 5, 2);
1450 for (iconIndex = 3; iconIndex >= 0; iconIndex--)
1451 menu->slotY[iconIndex] = -16;
1452 {
1453 s32 priority = 245;
1454 struct RenderOutput **icons = menu->entryIcons;
1455
1456 for (iconIndex = 31; iconIndex >= 0; iconIndex--) {
1457 struct RenderOutput *icon = *icons++;
1458
1459 if (icon != 0)
1460 icon->sentinel = priority;
1461 }
1462 }
1465 UiText_DrawCharacterAtOffsetFar(MsgSwitchCharacterHelp, menu->statusWindow,
1466 SWITCH_HELP_X, -24);
1467 UiText_DrawCharacterAtOffsetFar(MsgSwitchCharacterHelp + 2,
1468 menu->statusWindow, 0, -24);
1469
1470 while (done == 0 && GameFlag_TestFar(FLAG_MENU_START_PRESSED) == 0) {
1474 UnitGetFar(menu->ownerIds[0]), menu->psynergies, 0);
1475 WaitFrames(1);
1476 Menu_BuildPageResult(&state, 0);
1478 menu->ownerIds[0]);
1479 redraw = 1;
1480 listNeedsRedraw = 1;
1481
1483 if (redraw != 0) {
1484 redraw = 0;
1485 if (listNeedsRedraw != 0) {
1486 listNeedsRedraw = 0;
1487 PsynergyMenu_DrawListPage(menu->statusWindow, 0, &state);
1488 }
1489 PsynergyMenu_DrawRangePage(menu->statusWindow, 0, &state);
1490 WaitFrames(1);
1491 }
1492 WaitFrames(1);
1493 navigationResult = Menu_HandlePageInput(0, state.entryCount, PAGE_ROWS,
1494 &state.row, &state.page);
1495 menu->paneIcon[0]->active = ICON_SHOWN;
1497 state.row * 16 + STATUS_PSYNERGY_CURSOR_Y);
1498 if (navigationResult == 1) {
1499 listNeedsRedraw = 1;
1500 redraw = 1;
1501 }
1502 if (navigationResult == 0)
1503 redraw = 1;
1504 if (navigationResult == -1)
1505 redraw = 0;
1506 if (gKeysPressed & KEY_A) {
1508 result = 1;
1509 done = 1;
1510 break;
1511 }
1512 if (gKeysPressed & KEY_B) {
1514 result = -1;
1515 done = 1;
1517 break;
1518 }
1519 if ((gKeysRepeat & KEY_R) || (gKeysRepeat & KEY_L)) {
1521 ownerIndex = menu->tabIndex[0];
1522 menu->selectedIndexByOwner[menu->ownerTable[ownerIndex]] =
1523 state.selectedIndex;
1524 if (gKeysRepeat & KEY_R)
1525 ownerIndex++;
1526 else
1527 ownerIndex--;
1528 ownerIndex = (ownerIndex + menu->ownerCount) % menu->ownerCount;
1529 menu->selectedOwner = menu->ownerTable[ownerIndex];
1530 menu->ownerIds[0] = menu->ownerTable[ownerIndex];
1531 menu->tabIndex[0] = ownerIndex;
1533 menu->ownerTable[ownerIndex]);
1534 break;
1535 }
1536 }
1537 }
1543 return result;
1544}
1545
1546/// A page callback.
1548
1549/// Draws this owner's prepared Psynergy list in the shared entry sprites.
1550void PsynergyMenu_DrawPreparedPsynergyIcons(const void *unused, s32 ownerId) {
1551 struct PsynergyMenuState *menu = gMenuWork;
1552
1553 UnitGetFar(ownerId);
1556}
1557
1558/// Reserved empty callback for the prepared Psynergy page.
1560
1561/// Reserved second empty callback for the prepared Psynergy page.
1563
1565 struct MenuResult *state) {
1566 struct InventoryMenuState *menu;
1567 struct ItemDefinition *item;
1568 s32 firstEntry;
1569 s32 rowIndex;
1570
1571 menu = gMenuWork;
1572 firstEntry = state->page * PAGE_ROWS;
1573 state->selectedIndex = firstEntry + state->row;
1574#if TBS_PATCH_1 && !TBS_PATCH_4
1576#elif TBS_PATCH_4
1577 UiWindow_ClearInteriorTilesFar(menu->infoWindow, 0, 0, 224, 8);
1578#else
1580#endif
1581 WaitFrames(1);
1582 if (menu->items[state->selectedIndex] != 0) {
1584 MsgItemPlainName,
1585 menu->infoWindow, 0, 0);
1586 }
1587
1588 for (rowIndex = 0; rowIndex < PAGE_ROWS; rowIndex++) {
1589 if (rowIndex == state->row) {
1590 item =
1592 if (item->element != 4) {
1593 UiWindow_SetTilemapEntryFar(window, item->element + 1, 27,
1594 rowIndex * 2 + 1, 0);
1595 Render_SetTilemapFlagRect(window, 14, rowIndex * 2 + 1, 13, 1, 14);
1596 } else {
1597 Render_SetTilemapFlagRect(window, 14, rowIndex * 2 + 1, 14, 1, 14);
1598 }
1599 } else {
1600 item =
1601 Item_GetDirectFar(menu->items[firstEntry + rowIndex] & ITEM_ID_MASK);
1602 if (item->element != 4) {
1603 UiWindow_SetTilemapEntryFar(window, item->element + 1, 27,
1604 rowIndex * 2 + 1, 4);
1605 Render_SetTilemapFlagRect(window, 14, rowIndex * 2 + 1, 13, 1, 15);
1606 } else {
1607 Render_SetTilemapFlagRect(window, 14, rowIndex * 2 + 1, 14, 1, 15);
1608 }
1609 }
1610 }
1611
1612 for (rowIndex = 0; rowIndex <= 3; rowIndex++) {
1614 rowIndex * 2 + 1, STATUS_EQUIP_SLOT_WIDTH, 1, 15);
1615 }
1616
1617 if (menu->items[state->selectedIndex] & INVENTORY_EQUIPPED) {
1618 item = Item_GetDirectFar(menu->items[state->selectedIndex] & ITEM_ID_MASK);
1619 switch (item->type) {
1620 case 1:
1623 break;
1624 case 4:
1627 break;
1628 case 3:
1631 break;
1632 case 2:
1635 break;
1636 }
1637 }
1638 WaitFrames(1);
1639 return 1;
1640}
1641
1642s32 Shop_DrawItemPage(struct UiWindow *window, s32 unused,
1643 struct MenuResult *state) {
1644 struct InventoryMenuState *menu = gMenuWork;
1645 struct BattleUnit *unit;
1646 u16 *inventoryEntry;
1647 s32 firstEntry;
1648 u32 rowCount;
1649 u32 rowIndex;
1650 s32 message;
1651
1652 unit = UnitGetFar(menu->paneOwner[0]);
1653 UiWindow_ClearInteriorTilesFar(window, 128, 8, 224, 96);
1654 firstEntry = state->page * PAGE_ROWS;
1655 rowCount = (u8)(state->entryCount - firstEntry);
1656 if (rowCount > PAGE_ROWS)
1657 rowCount = PAGE_ROWS;
1658 Menu_SetPageIcons(PAGE_ROWS, firstEntry, window, SHOP_PAGE_ICONS_X, 52);
1659 Menu_DrawPageIndicator(window, state->entryCount, PAGE_ROWS, state->page, 28);
1660 if (menu->itemCount == 0) {
1661 UiText_DrawCharacterAtOffsetFar(MsgItemMenuEmpty, window,
1663 } else {
1664 rowIndex = 0;
1665 if (rowCount > rowIndex) {
1666 inventoryEntry = &menu->items[firstEntry];
1667 do {
1669 (*inventoryEntry & ITEM_ID_MASK) + MsgItemName, window,
1670 SHOP_ITEM_NAME_X, (rowIndex << 4) + 8);
1671 rowIndex = (u8)(rowIndex + 1);
1672 inventoryEntry++;
1673 } while (rowCount > rowIndex);
1674 }
1675 }
1676 UiText_DrawStringAtOffsetFar(unit->name, window, 40, 0);
1677 message = MsgStatLabel;
1678 UiText_DrawCharacterAtOffsetFar(message, window, 32, 16);
1679 UiText_DrawCharacterAtOffsetFar(message + 1, window, 32, 24);
1680 UiText_DrawNumberInWindowFar(unit->atk, 3, window, SHOP_STAT_X, 16);
1681 UiText_DrawNumberInWindowFar(unit->def, 3, window, SHOP_STAT_X, 24);
1682 return 1;
1683}
1684
1686
1687 struct InventoryMenuState *menu;
1688 struct BattleUnit *owner;
1689 s32 result;
1690 s32 done;
1691 s32 redraw;
1692 s32 listNeedsRedraw;
1693 s32 navigationResult;
1694 s32 ownerIndex;
1695 s32 iconIndex;
1696 u16 savedInventory[15];
1697 struct MenuResult state;
1698
1699 menu = gMenuWork;
1700 {
1701 s32 ownerId = menu->paneOwner[0];
1702
1703 result = 0;
1704 UnitGetFar(menu->ownerIds[ownerId]);
1705 }
1707 10, 2);
1709
1710 for (iconIndex = 0; iconIndex < 32; iconIndex++) {
1711 struct RenderOutput *icon = menu->entryIcons[iconIndex];
1712
1713 if (icon != 0)
1714 icon->sentinel = 240;
1715 }
1716
1718 UiText_DrawCharacterAtOffsetFar(MsgSwitchCharacterHelp, menu->statusWindow,
1719 64, -24);
1720 UiText_DrawCharacterAtOffsetFar(MsgSwitchCharacterHelp + 3,
1721 menu->statusWindow, 0, -24);
1723 WaitFrames(1);
1725
1726 done = 0;
1727 while (done == 0 && GameFlag_TestFar(FLAG_MENU_START_PRESSED) == 0) {
1730 owner = UnitGetFar(menu->paneOwner[0]);
1731 for (iconIndex = 0; iconIndex <= 14; iconIndex++)
1732 savedInventory[iconIndex] = owner->inventory[iconIndex];
1733 menu->itemCount = ItemMenu_CollectItems(owner, menu->items, 0);
1735 Menu_BuildPageResult(&state, 0);
1737 ItemMenu_DrawCategory(menu->equipWindow, menu->paneOwner[0], 1);
1738 WaitFrames(1);
1739 ItemMenu_DrawIcons(menu->items, 0);
1740 redraw = 1;
1741 listNeedsRedraw = 1;
1742
1744 if (redraw != 0) {
1746 redraw = 0;
1747 if (listNeedsRedraw != 0) {
1748 listNeedsRedraw = 0;
1749 Shop_DrawItemPage(menu->statusWindow, 0, &state);
1750 }
1751 ItemMenu_DrawEquipPage(menu->statusWindow, 0, &state);
1752 }
1753 menu->paneIcons[0]->active = ICON_SHOWN;
1754 UiMenu_PositionCursor(96, state.row * 16 + 52);
1755 WaitFrames(1);
1756
1757 navigationResult = Menu_HandlePageInput(0, state.entryCount, PAGE_ROWS,
1758 &state.row, &state.page);
1759 if (navigationResult == 1) {
1760 listNeedsRedraw = 1;
1761 redraw = 1;
1762 }
1763 if (navigationResult == 0)
1764 redraw = 1;
1765 if (navigationResult == -1)
1766 redraw = 0;
1767
1768 if (gKeysPressed & KEY_A) {
1770 result = 1;
1771 done = 1;
1772 break;
1773 }
1774 if (gKeysPressed & KEY_B) {
1776 result = -1;
1777 done = 1;
1778 break;
1779 }
1780 if ((gKeysRepeat & KEY_R) || (gKeysRepeat & KEY_L)) {
1782 ownerIndex = menu->paneIndex[0];
1783 menu->selectedIndexByOwner[menu->ownerIds[ownerIndex]] =
1784 state.selectedIndex;
1785 if (gKeysRepeat & KEY_R)
1786 ownerIndex++;
1787 else
1788 ownerIndex--;
1789 for (iconIndex = 0; iconIndex <= 14; iconIndex++)
1790 owner->inventory[iconIndex] = savedInventory[iconIndex];
1791 ownerIndex = (ownerIndex + menu->partyCount) % menu->partyCount;
1792 menu->selectedOwner = menu->ownerIds[ownerIndex];
1793 menu->paneOwner[0] = menu->ownerIds[ownerIndex];
1794 menu->paneIndex[0] = ownerIndex;
1795 PsynergyMenu_CallIconRoutineWithValue(menu, menu->ownerIds[ownerIndex]);
1796 break;
1797 }
1798 }
1799 }
1800
1807 return result;
1808}
1809
1810/// Moves through the status grid's irregular rows and returns row * 9 + column.
1811s32 Menu_MoveGridCursor(s32 *columnOut, s32 *rowOut, s32 direction) {
1812 s32 row;
1813 s32 column;
1814
1815 column = *columnOut;
1816 row = *rowOut;
1817 switch (direction) {
1818 case KEY_UP:
1819 row -= 1;
1820 if (row < 0) {
1821 row = 5;
1822 }
1823 if (row <= 3) {
1824 if (row == 3) {
1825 if (column <= 4) {
1826 column = 0;
1827 } else {
1828 column = 1;
1829 }
1830 } else if (column > 1) {
1831 column = 1;
1832 }
1833 if ((row == 3) && (column == 1)) {
1834 row = 2;
1835 }
1836 }
1837 break;
1838 case KEY_DOWN:
1839 row += 1;
1840 if (row > 5) {
1841 row = 0;
1842 }
1843 if ((row == 3) && (column == 1)) {
1844 row = 4;
1845 }
1846 if (row == 4) {
1847 column = 0;
1848 }
1849 break;
1850 case KEY_LEFT:
1851 column -= 1;
1852 if (row == 3) {
1853 column += 1;
1854 } else if (row > 3) {
1855 if (column < 0) {
1856 column = 7;
1857 }
1858 } else if (column < 0) {
1859 column = 1;
1860 }
1861 break;
1862 case KEY_RIGHT:
1863 column += 1;
1864 if (row == 3) {
1865 column -= 1;
1866 } else if (row > 3) {
1867 if (column > 7) {
1868 column = 0;
1869 }
1870 } else if (column > 1) {
1871 column = 0;
1872 }
1873 break;
1874 }
1875 *columnOut = column;
1876 *rowOut = row;
1877 return (row * 9) + column;
1878}
1879
1880s32 Menu_ReservedStatusOne(void) { return 1; }
1881
1882/// Shows the owner's equipped items and optionally its category icons.
1883void ItemMenu_DrawCategory(struct UiWindow *window, s32 ownerId, s32 mode) {
1884 struct InventoryMenuState *menu = gMenuWork;
1885 u16 *items;
1886
1887 UnitGetFar(ownerId);
1890 UiText_DrawCharacterAtOffsetFar(MsgEquipSlotLabels, window, 0, 0);
1891 UiText_DrawCharacterAtOffsetFar(MsgEquipSlotLabels + 1, window, 0, 32);
1892 UiText_DrawCharacterAtOffsetFar(MsgEquipSlotLabels + 2, window, 0, 16);
1893 UiText_DrawCharacterAtOffsetFar(MsgEquipSlotLabels + 3, window, 0, 48);
1894 items = menu->items;
1896 if (mode == 0) {
1897 WaitFrames(1);
1900 }
1901}
1902
1903/// Draws the nonempty equipment entries by their item names.
1905 s32 slotIndex;
1906 s32 itemId;
1907
1908 for (slotIndex = 0; slotIndex < 15; slotIndex++) {
1909 if (items[slotIndex] & INVENTORY_EQUIPPED) {
1910 itemId = items[slotIndex] & ITEM_ID_MASK;
1911 switch (Item_GetDirectFar(itemId)->type) {
1912 case 1:
1913 UiText_DrawCharacterAtOffsetFar(itemId + MsgItemName, window,
1915 break;
1916 case 2:
1917 UiText_DrawCharacterAtOffsetFar(itemId + MsgItemName, window,
1919 break;
1920 case 3:
1921 UiText_DrawCharacterAtOffsetFar(itemId + MsgItemName, window,
1923 break;
1924 case 4:
1925 UiText_DrawCharacterAtOffsetFar(itemId + MsgItemName, window,
1927 break;
1928 }
1929 }
1930 }
1931}
1932
1933/// Positions the shared entry sprites on the requested grid.
1934void Menu_PlaceEntryObjectsInGrid(s32 originX, s32 originY, s32 columns) {
1935 s32 entryIndex;
1936 struct RenderOutput *icon;
1937 struct RenderOutput **icons;
1938
1939 entryIndex = 0;
1940 icons = ((struct InventoryMenuState *)gMenuWork)->entryIcons;
1941 do {
1942 icon = *icons++;
1943 if (icon != NULL) {
1944 Menu_PlaceEntryObjectInGrid(icon, entryIndex, originX, originY, columns);
1945 }
1946 entryIndex += 1;
1947 } while (entryIndex <= 0x1F);
1948}
1949
1950/// Positions one entry sprite in the requested number of grid columns.
1952 s32 originX, s32 originY, s32 columns) {
1953 s32 entryIndex;
1954
1955 entryIndex = index;
1956 if (entryIndex > 0x1F) {
1957 entryIndex = 0;
1958 }
1959 icon->y = (entryIndex / columns * 0x10) + originY;
1960 icon->x = (entryIndex % columns * 0x10) + originX;
1962}
1963
1964/// Loads and places the owner's equipment-category icons.
1966 struct InventoryMenuState *menu;
1967 struct RenderOutput *icon;
1968 s32 slotIndex;
1969
1970 menu = gMenuWork;
1972 for (slotIndex = 0; slotIndex < 15; slotIndex++) {
1973 if (items[slotIndex] != 0 && (items[slotIndex] & INVENTORY_EQUIPPED) != 0) {
1974 icon = menu->entryIcons[slotIndex];
1975 if (icon != 0) {
1976 switch (Item_GetDirectFar(items[slotIndex] & ITEM_ID_MASK)->type) {
1977 case 1:
1978 icon->x = 216;
1979 icon->y = 32;
1980 break;
1981 case 2:
1982 icon->x = 216;
1983 icon->y = 80;
1984 break;
1985 case 3:
1986 icon->x = 216;
1987 icon->y = 64;
1988 break;
1989 case 4:
1990 icon->x = 216;
1991 icon->y = 48;
1992 break;
1993 }
1995 }
1996 }
1997 }
1998}
1999
2000/// Moves all entry sprites off screen before arranging another category.
2002 struct InventoryMenuState *state = gMenuWork;
2003 s32 x = 248;
2004 struct RenderOutput **entry = state->entryIcons;
2005 s32 y = 168;
2006 s32 remaining = 31;
2007
2008 do {
2009 struct RenderOutput *object = *entry++;
2010
2011 if (object != 0) {
2012 object->x = x;
2013 object->y = y;
2014 UiIcon_PrepareObject(object);
2015 }
2016 remaining--;
2017 } while (remaining >= 0);
2018}
2019
2020/// Creates the eight shared category sprites, initially off screen.
2022 struct RenderOutput **slot;
2023 struct RenderOutput *icon;
2024 s32 slotIndex;
2025 struct InventoryMenuState *menu;
2026 s32 spriteFlags;
2027
2028 menu = gMenuWork;
2029 slotIndex = 0;
2030 spriteFlags = 0xA8;
2031 slot = menu->categoryIcons;
2032 do {
2033 icon = RenderOutput_CreateFromResourceFar(2, slotIndex, window, 0xF8,
2034 spriteFlags);
2035 slotIndex += 1;
2036 *slot = icon;
2037 slot += 1;
2038 } while (slotIndex <= 7);
2039 return 1;
2040}
2041
2042/// Shows enabled category icons down the left edge, sixteen pixels apart.
2044 /* FAKEMATCH(temporary): y stored through a pointer to the field keeps the
2045 * flag index a counter instead of a walking pointer; as entry->y = nextY,
2046 * 11 of 33 instructions differ in tbs-en. */
2047 struct InventoryMenuState *menu;
2048 struct RenderOutput **slot;
2049 struct RenderOutput *entry;
2050 s32 index;
2051 s32 nextY;
2052
2053 menu = gMenuWork;
2055 index = 0;
2056 slot = menu->categoryIcons;
2057 nextY = 88;
2058 do {
2059 entry = *slot++;
2060 if (entry != 0 && flags[index] != 0) {
2061 entry->x = 8;
2062 {
2063 s16 *y = &entry->y;
2064
2065 *y = nextY;
2066 }
2067 entry->sentinel = 240;
2068 UiIcon_PrepareObject(entry);
2069 nextY += 16;
2070 }
2071 index++;
2072 } while (index <= 4);
2073}
2074
2075/// Moves each category sprite off screen before it is reused.
2077 struct InventoryMenuState *state = gMenuWork;
2078 s32 index;
2079
2080 for (index = 0; index < 5; index++) {
2081 struct RenderOutput *object = state->categoryIcons[index];
2082
2083 if (object != 0) {
2084 object->x = 248;
2085 object->y = 168;
2086 object->sentinel = 240;
2087 UiIcon_PrepareObject(object);
2088 }
2089 }
2090}
2091
2092/// Loads each enabled ailment's icon into its category resource slot.
2094 struct InventoryMenuState *state = gMenuWork;
2095 s32 index = 0;
2096
2097 do {
2098 if (enabled[index] != 0) {
2099 s32 kind;
2100 switch (index) {
2101 case CHARACTER_DOWN:
2102 kind = 16;
2103 break;
2104 case CHARACTER_POISON:
2105 kind = 1;
2106 break;
2107 case CHARACTER_VENOM:
2108 kind = 2;
2109 break;
2110 case CHARACTER_CURSE:
2111 kind = 15;
2112 break;
2113 case CHARACTER_HAUNT:
2114 kind = 7;
2115 break;
2116 default:
2117 kind = 0;
2118 break;
2119 }
2121 (u8)state->categoryIcons[index]->index, 0);
2122 }
2123 index++;
2124 } while (index <= 4);
2125 return 1;
2126}
2127
2128#undef CHARACTER_SELECTOR_OWNER_COUNT
2129#undef STATUS_SAVED_TILE_BYTES
2130#undef STATUS_HELP_TEXT_MAX
2131#undef STATUS_STAT_DIGITS
2132#undef STATUS_STAT_X
2133#undef STATUS_EQUIP_PAGE_SIZE
2134#undef STATUS_PSYNERGY_CURSOR_X
2135#undef STATUS_PSYNERGY_CURSOR_Y
2136#undef STATUS_EQUIP_SLOT_X
2137#undef STATUS_EQUIP_SLOT_WIDTH
2138#undef SHOP_PAGE_ICONS_X
2139#undef SHOP_ITEM_NAME_X
2140#undef SHOP_STAT_X
2141#undef SHOP_EMPTY_MESSAGE_X
2142#undef STATUS_EQUIP_WINDOW_WIDTH
2143#undef STATUS_EQUIPPED_NAME_X
@ OWNER_ACTION_ID_MASK
Definition battle_unit.h:14
@ CHARACTER_DOWN
@ CHARACTER_HAUNT
@ CHARACTER_CURSE
@ CHARACTER_POISON
@ CHARACTER_VENOM
void UiMenu_SlideCursor(s32 x, s32 y)
Slides the hand cursor from where it is to (x, y) inside the menu's top-left window over two frames,...
Definition common.c:625
void Menu_ReleaseEntryObjects(void)
Releases the party figures PsynergyMenu_InitializeEntryObjects created and stops their placement call...
Definition common.c:555
struct UiWindow * UiMenu_CreateCursor(void *source)
Opens the menu's top-left window (13 by 5 tiles) and puts the hand cursor in it, hidden for now.
Definition common.c:483
s32 InventoryMenu_SortByListOrder(u16 *inventory, s32 mode)
Sorts a party member's 15 inventory slots by the list order of mode (see Menu_CopyListOrder): items a...
Definition common.c:824
void UiIcon_PrepareObject(struct RenderOutput *object)
Shows a menu icon at its stored position, without rotation or scaling.
Definition common.c:465
void Palette_LightenBankHighlight(s32 bank)
Copies the last background palette (15) into background palette bank and lightens its colour 4 by 9 s...
Definition common.c:1012
void PsynergyMenu_CallIconRoutineWithValue(const void *unused, s32 unit)
Loads the graphics of character unit into menu entry slot 0.
Definition common.c:477
void Menu_UpdateEntryObjectTransforms(void)
Scheduler callback: each frame, places every party member sprite created by PsynergyMenu_InitializeEn...
Definition common.c:580
void Render_SetTilemapFlagRect(const struct UiWindow *window, s32 x, s32 y, s32 width, s32 height, u32 palette)
Switches a rectangle of a window's text between palette 15 (normal) and 14 (the highlight made by Pal...
Definition common.c:1075
void Menu_DrawPageIndicator(struct UiWindow *window, s32 itemCount, s32 pageSize, s32 selectedPage, s32 rightEdge)
Draws a paged list's page numbers on the top border of window, ending at tile rightEdge: one digit pe...
Definition common.c:1040
void UiMenu_PositionCursor(s32 xOffset, s32 yOffset)
Places the hand cursor at (xOffset, yOffset) inside the menu's top-left window, bobbing.
Definition common.c:611
void Menu_CancelSoundReset(void)
Starts watching for Start: clears FLAG_MENU_START_PRESSED and adds Menu_CancelSoundTick.
Definition common.c:1199
s32 Menu_SuspendFieldTasks(void)
Suspends the overlay tasks and tile animations while a menu is open, and sets flags 0x152 and 0x166.
Definition common.c:52
void UiWindow_InitializeWork(s32 unused)
Clears the whole menu work and sets its defaults: no pane selected, one entry in each pane,...
Definition common.c:61
void PsynergyMenu_InitializeEntryObjects(void *source, s32 originX, s32 originY, s32 spacing, s32 unused)
Creates a walking figure for each active party member, side by side under the window source: origin (...
Definition common.c:511
void Menu_EnsureCancelSound(void)
Stops watching for Start, if Start has not removed the watch already.
Definition common.c:1205
s32 Menu_ResumeFieldTasks(void)
Resumes the overlay tasks and tile animations when a menu closes, and clears game flags 0x166 and 0x1...
Definition common.c:38
s32 Menu_HandlePageInput(s32 horizontal, s32 count, s32 pageSize, s32 *cursor, s32 *page)
Moves a paged list's cursor and page with the d-pad's repeating keys.
Definition common.c:931
void Menu_SetPageIcons(s32 pageSize, s32 first, struct UiWindow *window, s32 x, s32 y)
Shows the item icons of one page of the item list: entries first to first + pageSize - 1,...
Definition common.c:1131
s32 UiWindow_UpdateOrCreate(struct UiWindow **handle, s32 x, s32 y, s32 w, s32 h, s32 flags)
Opens the window kept in *handle, or redraws it if it is already open.
Definition common.c:78
void FourObjectMotion_ClearSlotsAndSchedule(void)
void FourObjectMotion_InitializeTopRow(void *unused0, s32 unused1)
Replaces the four displayed objects and starts their projected-position task.
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
s32 Party_AddActiveOwnerFar(s32 value)
struct BattleUnit * UnitGetFar(u32 owner)
struct ItemDefinition * Item_GetDirectFar(s32 item)
s32 Party_ListActiveOwnersFar(s16 *owners)
s32 GameFlag_TestFar(s32 flag)
struct BattleAct * BattleActGet(s32 actionId)
Far call to BattleAction_GetDirect.
s32 Unit_GetElementLevelFar(s32 owner, s32 index)
s32 Party_RemoveActiveOwnerFar(s32 value)
s32 Party_SumDjinnCountsFar(s32 index)
u32 Unit_GetExperienceForLevelFar(s32 owner, s32 level)
void AudioCommand_PlayFar(s32 id)
struct UiWindow * UiWindow_CreateFar(s32 x, s32 y, s32 width, s32 height, s32 attrs)
void UiWindow_DrawFrameFar(s32 x, s32 y, u32 width, u32 height)
void UiWindow_MarkVisibleTileAttributesFar(void)
void RenderOutput_ClearListFar(void *work)
void UiWindow_EraseBorderRectFar(s32 x, s32 y, u32 width, u32 height)
void UiText_DrawNumberInWindowFar(s32 arg0, s32 arg1, struct UiWindow *arg2, s32 arg3, s32 arg4)
void UiWork_SetParamNibbleFar(s32 param)
s32 Resource_LoadByModeIntoSlotFar(s32 mode, s32 value, s32 result, s32 option)
void Link_DrawShiftedTilePairFar(s32 offset)
struct RenderOutput * SideObject_CreateFar(s32 object_kind, s32 position, s32 side, struct UiWindow *arg3, s32 arg4, s32 arg5)
Far call to CreateSideObject.
s32 UiText_CopyMessageStringFar(s32 key, u16 *destination, u32 capacity)
void UiText_DrawNumberAtOffsetFar(s32 arg0, s32 arg1, const struct UiWindow *arg2, s32 arg3, s32 arg4)
void UiWindow_ClearInteriorTilesFar(const struct UiWindow *window, u32 left, u32 top, u32 right, u32 bottom)
void UiWindow_DrawDividerLineFar(struct UiWindow *win, u32 x1, u32 y1, u32 x2, u32 y2)
void UiText_DrawCharacterAtOffsetFar(s32 character, const struct UiWindow *position, u32 offsetX, u32 offsetY)
void UiText_RenderWideStringAtOffsetFar(u16 *text, struct UiWindow *window, s32 x, s32 y)
void UiText_DrawResourceFar(s32 arg0, struct UiWindow *arg1, s32 arg2, s32 arg3)
void UiText_DrawStringAtOffsetFar(const u8 *text, const struct UiWindow *work, s32 offsetX, s32 offsetY)
struct RenderOutput * RenderOutput_CreateFromResourceFar(s32 mode, s32 resource, struct UiWindow *input, s32 x, s32 y)
void UiWork_PushValueSlotFar(u32 value, u32 kind)
void UiWork_SetAltFlagAndClearTableFar(s32 flag)
void UiWindow_SetTilemapEntryFar(struct UiWindow *window, s32 value, s32 x, s32 y, u32 mode)
void RenderOutput_RedrawSavedRectFar(struct UiWindow *window)
void UiText_DrawStringInWindowFar(const u8 *text, struct UiWindow *arg1, u32 x, u32 y)
#define FLAG_DJINNI_0
the flag of Djinni 0, set once it is caught
Definition flags.h:15
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
void * gMenuWork
void * Runtime_BumpAllocateAlternatePool(s32 size)
As MemAlloc, but tries EWRAM first.
Definition heap.c:140
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
void * Runtime_AllocateHeapBlock(s32 kind, s32 size)
Returns heap slot kind's block, first allocating size bytes for it (rounded up to words),...
Definition heap.c:47
@ HEAP_SLOT_MENU
Definition heap_state.h:55
@ HEAP_SLOT_MENU_CONTROL
Definition heap_state.h:35
@ HEAP_SLOT_WINDOW
Definition heap_state.h:39
#define WORK_SLOT(n)
Reads slots through their own addresses; adjacent slots are reached by offsets.
Definition heap_state.h:14
#define OBJ_PLTT
Definition io_reg.h:159
#define BG_CHAR_BLOCK(n)
Definition io_reg.h:166
@ KEY_UP
Definition io_reg.h:249
@ KEY_B
Definition io_reg.h:244
@ KEY_SELECT
Definition io_reg.h:245
@ KEYS_DPAD
Definition io_reg.h:255
@ 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
#define REG_DMA3
Definition io_reg.h:153
#define BG_PLTT
Definition io_reg.h:157
#define BG_PLTT_COLOR(palette, color)
Definition io_reg.h:158
#define DMA_ENABLE
Definition io_reg.h:217
void ItemMenu_Close(void)
Closes the item menu: releases the party figures, hides the icons and the cursor, and closes every wi...
Definition item.c:962
void Menu_SpawnIconEntries(struct InventoryMenuState *state, struct UiWindow *window)
Creates the 32 item icon sprites in window, off screen until placed: slots 0 to 7 at x 248,...
Definition item.c:886
void ItemMenu_DrawIcons(u16 *inventoryEntries, s32 iconStyle)
Loads each listed item's icon into its item icon sprite, the first 15 entries of inventoryEntries,...
Definition item.c:1431
void Menu_HideEmptyEntryIcons(const u16 *items)
Hides the icon of each of the 32 list entries whose item is 0.
Definition item.c:1344
void ItemMenu_HideAllIcons(void)
Hides all 32 item icons.
Definition item.c:927
s32 ItemMenu_CollectItems(struct BattleUnit *unit, u16 *items, s32 mode)
Copies the unit's items into the list items (32 entries), skipping empty slots and clearing the rest.
Definition item.c:1409
@ INVENTORY_EQUIPPED
Definition item.h:17
@ ITEM_ID_MASK
Definition item.h:16
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
Definition iwram_call.h:85
static s32 Iwram_FillWords(void *destination, s32 size, u32 value)
Definition iwram_call.h:59
volatile u32 gKeysPressed
Keys that went down this frame.
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
void Runtime_ReleaseHeapBlock(s32 slot)
void MemFree(void *buffer)
s32 PsynergyMenu_CollectActions(struct BattleUnit *unit, u16 *actions, s32 mode)
Lists unit's Psynergy into actions (32 entries, cleared first) and returns how many there are.
Definition psynergy.c:849
void PsynergyMenu_DrawPsynergyIcons(u16 *psynergies)
Loads each listed Psynergy's icon into its icon sprite (32 entries) and hides the icons of empty entr...
Definition psynergy.c:825
const struct TileMask gMenu_PatternRowMasks[]
void ItemMenu_ArrangeCategoryItemIcons(u16 *items)
Loads and places the owner's equipment-category icons.
Definition status.c:1965
void StatusMenu_ShowOwnerProgressMessage(struct UiWindow *destination, s32 messageVariant, s32 preserveVariant)
Writes the help text of status entry messageVariant into destination: the entries skip Djinn when the...
Definition status.c:922
s32 Menu_MoveGridCursor(s32 *columnOut, s32 *rowOut, s32 direction)
Moves through the status grid's irregular rows and returns row * 9 + column.
Definition status.c:1811
void PsynergyMenu_DrawRange(struct UiWindow *window, s32 x, s32 y, s32 range, s32 unused)
Draws a Psynergy range icon at (x, y) of window: three tiles from the range icon tiles,...
Definition status.c:1247
s32 StatusMenu_Run(void)
The Status menu an event opens (window command 4) over the field: saves the first two background pale...
Definition status.c:145
#define STATUS_PSYNERGY_CURSOR_X
Definition status.c:50
s32 Menu_RunActionFlow(void)
The Status menu's pages: choose a party member, then their status page, A for their Psynergy page and...
Definition status.c:227
s32 Menu_ReservedStatusOne(void)
Definition status.c:1880
s32 Shop_DrawItemPage(struct UiWindow *window, s32 unused, struct MenuResult *state)
Definition status.c:1642
void Menu_InitSelectorCursorAndEntries(s32 unused0, s32 unused1, s32 unused2, s32 unused3)
Sets up the Status menu's first screen: the cursor window with the party's figures,...
Definition status.c:643
#define SHOP_EMPTY_MESSAGE_X
Definition status.c:81
s32 CharacterSelector_RunRearrange(void)
The Status menu's party row: Left and Right choose a member, showing their status; L and R move the m...
Definition status.c:395
void CharacterMenu_DrawSelectionLabels(struct UiWindow *target, s32 selected, const u8 *entries)
Writes the advice for the selected ailment (two lines, for example how to revive a member who is down...
Definition status.c:890
void ItemMenu_DrawCategory(struct UiWindow *window, s32 ownerId, s32 mode)
Shows the owner's equipped items and optionally its category icons.
Definition status.c:1883
s32 DjinnMenu_ShowCurrentList(void)
Shows every Djinn the party has found, a column of seven for each element, until A,...
Definition status.c:310
void ItemMenu_DrawOwnerStatus(struct UiWindow *window, s32 ownerId, s32 flags)
Draws the top rows of member ownerId's status page into window: name, class, level,...
Definition status.c:1080
void ItemMenu_ResetCategory(void)
Moves each category sprite off screen before it is reused.
Definition status.c:2076
s32 CharacterSelector_MoveEntry(s32 selectedIndex, s32 direction)
Moves the party member at selectedIndex one place later (direction 1) or earlier (0) in the party ord...
Definition status.c:577
s32 Menu_OpenCharacterSelector(void)
Lets the player choose one party member, over the field (the Colosso scenes use it).
Definition status.c:95
s32 CharacterMenu_SelectCommand(void)
The member's status page.
Definition status.c:695
void Menu_CreateWindowAndEntryObjects(s32 resource, s32 frame)
Shows member resource's status in the status window (0, 5, 30 by 15), opening it first with the membe...
Definition status.c:662
#define STATUS_EQUIP_WINDOW_WIDTH
Definition status.c:86
#define STATUS_STAT_X
Definition status.c:35
s32 CharacterMenu_SelectOwner(s32 slot)
Lets the player choose a party member in slot, from the one chosen last: the member chooser when the ...
Definition status.c:279
void PsynergyMenu_PreparedIconsSecondNoOp(void)
Reserved second empty callback for the prepared Psynergy page.
Definition status.c:1562
s32 ItemMenu_SelectItem(void)
Definition status.c:1685
void CharacterMenu_DrawStatusAilments(struct UiWindow *window, s32 ownerId, s32 mode)
Draws member ownerId's status page into window: the top rows (ItemMenu_ DrawOwnerStatus),...
Definition status.c:956
void ItemMenu_ApplyFlags(const u8 *flags)
Shows enabled category icons down the left edge, sixteen pixels apart.
Definition status.c:2043
#define STATUS_STAT_DIGITS
Definition status.c:34
#define STATUS_HELP_TEXT_MAX
Definition status.c:27
s32 CharacterSelector_Run(void)
The member chooser's loop. Returns the chosen member's id, or -1.
Definition status.c:124
void Menu_PlaceEntryObjectsInGrid(s32 originX, s32 originY, s32 columns)
Positions the shared entry sprites on the requested grid.
Definition status.c:1934
s32 Menu_BuildPageResult(struct MenuResult *result, s32 index)
Fills result with the item list of the member in pane index for the equipment pages: their unit,...
Definition status.c:1169
#define STATUS_EQUIP_PAGE_SIZE
Definition status.c:43
s32 Menu_CreateEightEntryObjects(struct UiWindow *window)
Creates the eight shared category sprites, initially off screen.
Definition status.c:2021
#define STATUS_EQUIP_SLOT_X
Definition status.c:59
#define STATUS_EQUIPPED_NAME_X
Definition status.c:87
s32 CharacterMenu_UpdateSelectionIcons(const u8 *enabled)
Loads each enabled ailment's icon into its category resource slot.
Definition status.c:2093
s32 ItemMenu_DrawEquipPage(struct UiWindow *window, s32 unused, struct MenuResult *state)
Definition status.c:1564
s32 CharacterMenu_BuildAvailability(u8 *ailments, s32 requested, s32 ownerId)
Fills ailments[0..4] (CharacterAilment) with member ownerId's ailments: down (only when requested is ...
Definition status.c:1130
#define SHOP_ITEM_NAME_X
Definition status.c:70
#define SHOP_STAT_X
Definition status.c:71
void PsynergyMenu_PreparedIconsNoOp(void)
Reserved empty callback for the prepared Psynergy page.
Definition status.c:1559
s32 PsynergyMenu_ActionReturnTrue(void)
A page callback.
Definition status.c:1547
void PsynergyMenu_DrawPreparedPsynergyIcons(const void *unused, s32 ownerId)
Draws this owner's prepared Psynergy list in the shared entry sprites.
Definition status.c:1550
void ItemMenu_DrawEquippedItemNames(struct UiWindow *window, u16 *items)
Draws the nonempty equipment entries by their item names.
Definition status.c:1904
#define SHOP_PAGE_ICONS_X
Definition status.c:69
static __inline__ void CharacterMenu_SetSelectedOwnerRow(struct CharacterMenuState *menu, s32 selectedOwner)
Lowers the party figures, then raises the currently selected member.
Definition status.c:382
void ItemMenu_PosCategory(void)
Moves all entry sprites off screen before arranging another category.
Definition status.c:2001
void Menu_PlaceEntryObjectInGrid(struct RenderOutput *icon, s32 index, s32 originX, s32 originY, s32 columns)
Positions one entry sprite in the requested number of grid columns.
Definition status.c:1951
#define STATUS_PSYNERGY_CURSOR_Y
Definition status.c:51
u64 ExperienceDifference
Definition status.c:913
#define STATUS_SAVED_TILE_BYTES
Definition status.c:20
static __inline__ u32 XorWord(u32 word, u32 mask)
Definition status.c:1202
s32 PsynergyMenu_DrawListPage(struct UiWindow *window, s32 unused, const struct MenuResult *res)
Definition status.c:1358
void Menu_BuildPatternTiles(void)
Builds twelve 8x8 tiles in the window tile area: two sets of six, each a fill of colour 4 with the ro...
Definition status.c:1209
void Runtime_RunBusyWaitDelay(void)
Spins for 256 loop passes (international editions only).
Definition status.c:1066
#define STATUS_EQUIP_SLOT_WIDTH
Definition status.c:60
#define CHARACTER_SELECTOR_OWNER_COUNT
Definition status.c:13
s32 PsynergyMenu_SelectAction(void)
Definition status.c:1432
s32 PsynergyMenu_DrawRangePage(struct UiWindow *window, s32 unused, struct MenuResult *state)
Updates the Psynergy page for the row under the cursor: the Psynergy's description in the info window...
Definition status.c:1264
void CharacterMenu_DrawSelectionCursor(s32 mode, s32 selected, u8 *entries, s32 invert)
Highlights (invert 0) or unhighlights (invert 1) the selected entry of the status page: in pane 0 the...
Definition status.c:844
s32 PsynergyMenu_SelectOwner(void)
The member chooser (menu page 3): Left and Right choose a party member, showing their status and Psyn...
Definition status.c:508
const u8 gMenu_LvString[]
const u8 gMenu_SlashString[]
const u8 gMenu_HpString[]
const u8 gMenu_PpString[]
struct ObjectSystemWork * gMenuCtrlWork
What every part of the menu object shares: its includes, and the macros and types more than one part ...
#define ACTION_USABLE_IN_FIELD
BattleAct.flags: where an ability or item can be used, as the Psynergy list says ("Usable in the fiel...
#define MENU_WORK_SIZE
The bytes of the menu work, heap block HEAP_SLOT_MENU.
#define ICON_HIDDEN
#define ACTION_USABLE_IN_BATTLE
#define ICON_SHOWN
RenderOutput.active as the menu sets it: shown, or hidden but kept.
#define TEXT_COLOR_NORMAL
#define FLAG_MENU_START_PRESSED
Game flags of the menus.
#define MENU_DRAW_INFO_TEXT
#define MENU_DRAW_STATUS_LABEL
u8 gCharacterMenu_CursorWidths[5]
Definition menudata.c:51
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 SE_MENU_CANCEL
Definition songs.h:106
#define SE_MENU_CURSOR_MOVE
Definition songs.h:104
#define SE_MENU_ERROR
Definition songs.h:107
#define SE_MENU_CONFIRM
Definition songs.h:105
#define NULL
Definition bilibin.h:6
u8 gWindowWork[]
An ability's definition, a row of gBattleAction_DefinitionTable: its targeting, kind,...
u8 type0c
The field Psynergy the ability works as, 1 (Move) to 16 (Avoid); 0 for none.
u8 ppCost
PP the ability costs.
u8 range
the aimed unit and range - 1 either side, or ABILITY_RANGE_ALL
u8 element
enum Element
u8 flags
bits: 7 usable in battle | 6 usable in the field | 5..4 clear in every row | 3..0 kind (ABILITY_KIND_...
s16 resistance
Elemental resistance to it.
Definition battle_unit.h:29
s16 power
Elemental power in the element.
Definition battle_unit.h:28
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
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
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
u16 agi
Agility, 0 to 999: the order of the round's actions.
u16 def
Defense, 0 to 999 (UnitCalc).
u16 inventory[15]
Items held, one entry each: bits 15..11 quantity | 10 broken | 9 equipped | 8..0 item id (INVENTORY_*...
The work of the member chooser and the Status menu, in the HEAP_SLOT_MENU work slot.
u16 page
3 for the member chooser, 0 for the Status menu
s8 ownerIndex[2]
each pane's member, in ownerIds
struct UiWindow * unknownWindow028
only cleared by name in TBS
struct UiWindow * actionWindow
s32 selectedOwner
the party member chosen
u16 ownerIds[8]
the party in order (Party_ListActiveOwners)
struct UiWindow * helpWindow
struct UiWindow * statusWindow
u8 selectedIds[2]
each pane's member
struct UiWindow * ownerWindow
s8 ownerCount[2]
members each pane chooses from
s16 rowX[4]
screen pixels
struct RenderOutput * statusCursor
s16 ownerY[8]
screen pixels
s16 rowY[4]
screen pixels
struct RenderOutput * ownerCursors[2]
struct UiWindow * selectorWindow
The Djinn menu's work, in the HEAP_SLOT_MENU work slot.
Definition djinn_menu.h:41
struct RenderOutput * cursor
Definition djinn_menu.h:46
struct UiWindow * window
Definition djinn_menu.h:50
struct UiWindow * helpWindow
Definition djinn_menu.h:56
struct RenderOutput * secondCursor
Definition djinn_menu.h:63
s16 ownerY[8]
screen pixels
Definition djinn_menu.h:59
The item menu's work, in the HEAP_SLOT_MENU work slot: its windows, the party figures,...
struct RenderOutput * cursor
struct UiWindow * equipWindow
s32 selectedOwner
the party member chosen
s8 selectedIndexByOwner[8]
each member's entry chosen last
struct UiWindow * infoWindow
struct RenderOutput * paneIcons[2]
The two panes: the member whose items are shown, and the one an item is given to.
u16 flags
1 while the item's name and command grid are drawn
u16 items[32]
the inventory entries listed
u8 paneOwner[2]
each pane's member
struct UiWindow * statusWindow
u16 ownerIds[8]
the party in order (Party_ListActiveOwners)
struct RenderOutput * entryIcons[32]
struct UiWindow * messageWindow
u8 mode
not named through this struct; PsynergyMenuState.mode
s8 paneIndex[2]
the member chosen, in ownerIds; -1 for none at first
struct RenderOutput * categoryIcons[8]
An item's definition: its price, type, who can equip it, its bonuses and unleash, its effects and the...
Definition item.h:104
u8 type
enum ItemType; 0 for an item that is not equipment
Definition item.h:106
s32 element
a weapon's attack element; 4 for none
Definition item.h:118
A paged list for one party member: their unit, the list's length and pages, and the page and row of t...
Definition menu_result.h:12
s32 selectedIndex
Definition menu_result.h:19
The object system's work: the flag that suspends sprite projection, the outline's edge and fill colou...
Definition animspr.h:66
s16 suspended
nonzero while a menu has suspended sprite projection
Definition animspr.h:69
The Psynergy menu: its windows, icons and cursors, the party members' tabs and the Psynergy listed fo...
s16 slotY[4]
screen pixels
s8 tabCounts[2]
members each pane chooses from
struct RenderOutput * entryIcons[32]
u16 psynergies[32]
the chosen member's Psynergy listed
struct RenderOutput * paneIcon[2]
each pane's cursor
struct UiWindow * messageWindow
u16 flags
bits: 1 the list shows the shortcut help | 0 set after a use or a cancelled target
struct UiWindow * statusWindow
s32 selectedOwner
the party member chosen
s8 selectedIndexByOwner[8]
each member's entry chosen last
s8 tabIndex[2]
each pane's member, in ownerTable
u8 ownerIds[2]
The user and the target: [1] is MENU_TARGET_WHOLE_PARTY for Psynergy on the whole party.
struct UiWindow * infoWindow
u16 ownerTable[8]
the party in order (Party_ListActiveOwners)
s16 rowPositions[8]
screen pixels
A render output: a sprite in a window's output list (a character, an icon or a portrait),...
u16 y
screen pixels
u8 sentinel
depth slot it is drawn at (254 for glyphs)
s8 active
its UI_SPRITE_ motion; 0 while free
u16 animStep
step of its motion's animation
u16 x
screen pixels
s8 index
VRAM cache slot, or a glyph's tile after glyphTiles.
One row's masks for a pair of bar-pattern tiles: a word XORed into each tile's row.
Definition graphics.h:86
u32 word1
Definition graphics.h:88
u32 word0
Definition graphics.h:87
The window system's work: the windows' tilemap, the windows, the three text channels,...
Definition window.h:19
u8 menuBusy
while set, the tilemap is not uploaded
Definition window.h:40
A window: a framed rectangle of the tilemap with its sprite outputs, its opening or closing animation...
Definition uiwindow.h:11
A view of the window system's work that names only its dirty bits and its menu busy flag.
Definition ui.h:14
unsigned dirty
Definition ui.h:16
#define SWITCH_HELP_X
#define RANGE_ICON_TILE
#define PAGE_ROWS
#define LIST_FIRST_ROW
#define LIST_EMPTY_Y
#define LIST_PP_NUMBER_X
#define LIST_NAME_X
#define MENU_ROW_COUNT
#define LIST_ICONS_Y
#define LIST_PP_X
#define LIST_ICONS_X
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
unsigned long long u64
Definition types.h:17
unsigned char u8
Definition types.h:11
#define UI_PAGE_ARROW_VRAM
Definition window.h:64