Alchemy
Loading...
Searching...
No Matches

clear.c

Go to the documentation of this file.
1/// @file
2/// The file select overlay: the Golden Sun logo, the start menu (new game,
3/// continue, copy and delete), the door to the Battle Arena and the transfer of
4/// a save's data, by link or as a password.
5
6#include "scene_ids.h"
7#include "unit/menu/clear.h"
10#include "unit/game/game.h"
11#include "unit/window/window.h"
14#include "battle.h"
15#include "keystate.h"
16#include "debug.h"
17#include "field.h"
18#include "game.h"
19#include "graphics.h"
20#include "menu.h"
21#include "minigame.h"
22#include "sound.h"
23#include "system.h"
24#include "resource.h"
25#include "global_cells.h"
26#include "edition.h"
27#include "tbs_edition.h"
28#include "text_font.h"
29#include "types.h"
30#include "scene.h"
31#include "dma.h"
32#include "ram_buffer.h"
33#include "field_event.h"
34#include "engine_call.h"
35#include "resource_ids.h"
36#include "io_write_queue.h"
37#include "io_reg.h"
38#include "field_scene.h"
39#include "serial_runtime.h"
40#include "mem.h"
41#include "window.h"
42#include "item.h"
43#include "game_state.h"
44#include "uiwindow.h"
45#include "text/msg_ids.h"
46#include "songs.h"
47#include "frame.h"
48#include "map_scroll.h"
49#include "flags.h"
50#include "title.h"
51
52// Edition-specific text and window layout values.
53#if TBS_PATCH_1
54#define CLEAR_PASSWORD_BUFFER_SIZE 320
55#else
56#define CLEAR_PASSWORD_BUFFER_SIZE 260
57#endif
58
59#if (LANGUAGE == LANGUAGE_GERMAN) || (LANGUAGE == LANGUAGE_SPANISH) || \
60 (LANGUAGE == LANGUAGE_FRENCH) || (LANGUAGE == LANGUAGE_ITALIAN)
61#define CLEAR_LINK_WINDOW_X 4
62#define CLEAR_LINK_WINDOW_WIDTH 22
63#else
64#define CLEAR_LINK_WINDOW_X 6
65#define CLEAR_LINK_WINDOW_WIDTH 18
66#endif
67
68#if (LANGUAGE == LANGUAGE_GERMAN)
69#define CLEAR_LINK_LANGUAGE_TAG 'E'
70#elif (LANGUAGE == LANGUAGE_FRENCH)
71#define CLEAR_LINK_LANGUAGE_TAG 'F'
72#elif (LANGUAGE == LANGUAGE_SPANISH)
73#define CLEAR_LINK_LANGUAGE_TAG 'S'
74#elif (LANGUAGE == LANGUAGE_ITALIAN)
75#define CLEAR_LINK_LANGUAGE_TAG 'I'
76#elif (LANGUAGE == LANGUAGE_JAPANESE)
77#define CLEAR_LINK_LANGUAGE_TAG 'C'
78#else
79#define CLEAR_LINK_LANGUAGE_TAG 'U'
80#endif
81
82#if (LANGUAGE == LANGUAGE_GERMAN) || (LANGUAGE == LANGUAGE_SPANISH) || \
83 (LANGUAGE == LANGUAGE_FRENCH) || (LANGUAGE == LANGUAGE_ITALIAN)
84#define CLEAR_LINK_ERROR_WINDOW_X 4
85#define CLEAR_LINK_ERROR_WINDOW_WIDTH 22
86#else
87#define CLEAR_LINK_ERROR_WINDOW_X 5
88#define CLEAR_LINK_ERROR_WINDOW_WIDTH 20
89#endif
90
91#if (LANGUAGE == LANGUAGE_SPANISH) || (LANGUAGE == LANGUAGE_FRENCH) || \
92 (LANGUAGE == LANGUAGE_ITALIAN)
93#define CLEAR_HELP_WINDOW_X 8
94#define CLEAR_HELP_WINDOW_WIDTH 13
95#else
96#define CLEAR_HELP_WINDOW_X 10
97#define CLEAR_HELP_WINDOW_WIDTH 10
98#endif
99
100#if TBS_PATCH_1
101#define CLEAR_PAGE_LABEL_X 80
102#else
103#define CLEAR_PAGE_LABEL_X 0
104#endif
105
106#if (LANGUAGE == LANGUAGE_GERMAN) || (LANGUAGE == LANGUAGE_SPANISH) || \
107 (LANGUAGE == LANGUAGE_FRENCH) || (LANGUAGE == LANGUAGE_ITALIAN)
108#define CLEAR_MESSAGE_WINDOW_X 0
109#define CLEAR_MESSAGE_WINDOW_WIDTH 30
110#elif (LANGUAGE == LANGUAGE_JAPANESE)
111#define CLEAR_MESSAGE_WINDOW_X 3
112#define CLEAR_MESSAGE_WINDOW_WIDTH 24
113#else
114#define CLEAR_MESSAGE_WINDOW_X 1
115#define CLEAR_MESSAGE_WINDOW_WIDTH 28
116#endif
117
118#define PASSWORD_SYMBOLS_PER_PAGE 50
119#define PASSWORD_SYMBOL_MASK 0x3f
120
121/// Whether a key of the extra code is still held. UB: the flag is a word the
122/// code reads and writes as its low halfword; UBFIX uses the word.
123#ifdef UBFIX
124#define CLEAR_EXTRA_CODE_HELD gClear_ExtraCodeHeld
125#else
126#define CLEAR_EXTRA_CODE_HELD (*(s16 *)&gClear_ExtraCodeHeld)
127#endif
128
129static s32 Clear_PackPasswordData(s32 unused, s32 mode, u8 *out);
130static s32 Clear_EncodePassword(u8 *data, s32 size, u8 *out);
131static u16 Clear_ComputePasswordCrc16(u32 byteCount, u8 *data);
132
133/// The file select overlay's scene tables, for the scene loader: one entrance,
134/// the exit, and no placements or events.
136
137s32 SceneData_ReturnZero(void) { return 0; }
138
139u8 *Clear_GetExits(void) { return (u8 *)gClear_Exits; }
140
142
143u8 *Clear_GetEvents(void) { return (u8 *)gClear_Events; }
144
145/// Loads the Golden Sun logo, maps its tiles and resets background scroll.
146static void Clear_LoadBackground(void) {
147 u8 *resource;
148 s32 resourceId;
149 u16 *tilemap;
150 u32 x;
151 u32 y;
152 u16 tile;
153 struct BgScroll *scroll;
154 s32 blankTile;
155
156 resourceId = (s32)&ResourceId_GoldenSunLogo;
159 gBgScroll[2].y = 0;
160 blankTile = LOGO_BLANK_TILE;
161 resource = Engine_ResourceGetTableEntry(resourceId);
162 Dma_Set(resource, (void *)BG_PLTT, (DMA_ENABLE | DMA_32BIT) << 16 | 0x70,
163 REG_DMA3);
164 resource += 0x1c0;
167 (DMA_ENABLE | DMA_32BIT) << 16 | 0x2580, REG_DMA3);
168 // Build the visible 30-column logo map, padding to the 32-cell screen stride.
169 tilemap = LOGO_MAP;
170 tile = LOGO_FIRST_TILE;
171 for (y = 0; y < 20; y++) {
172 for (x = 0; x < 30; x++)
173 *tilemap++ = tile++;
174 *tilemap++ = blankTile;
175 *tilemap++ = blankTile;
176 }
177 scroll = gBgScroll;
178 for (y = 0; y <= 3; y++) {
179 scroll->y = 0;
180 scroll->x = 0;
181 scroll++;
182 }
184 ((struct MapScrollWork *)gMapWork[0])->flags =
186 {
187 struct FieldActor *leader;
188
190 leader->motionFlags = 0;
191 }
192}
193
194/// Advances the logo blend every two frames and removes itself at completion.
195static void Clear_UpdateBlend(void) {
196 s32 frame;
197 s32 level;
198
199 frame = *(u16 *)&gClear_BlendFrame + 1;
200 *(u16 *)&gClear_BlendFrame = frame;
201 level = (u16)frame >> 1;
202 // Blend BG0 and the sprites over the other layers, level sixteenths of
203 // the way in.
208 0x20000);
210 BLEND_ALPHA((u16)level, 16 - (u16)level), 0x20000);
211 if ((u16)level > 15)
213}
214
215/// Hidden command: sequence of pressed keys, terminated by 0.
216// clang-format off
219};
220
224};
225// clang-format on
226
227// The actual arrays have four and fifteen entries. The original one-element
228// view makes the second key an out-of-bounds access. Direct array reads also
229// reorder both native held-key stores (same 0xf8-byte function extent).
230#ifdef UBFIX
231#define CLEAR_SEQUENCE_KEYS(sequence) (sequence)
232#else
233#define CLEAR_SEQUENCE_KEYS(sequence) \
234 (((struct { u16 key[1]; } *)(sequence))->key)
235#endif
236
237/// Tracks two hidden key sequences, requiring a full release after each key.
238static void Clear_CheckButtonCodes(void) {
239 if (gClear_CodeUnlocked == 0) {
240 if (gClear_CodeHeld != 0) {
241 if (gKeysHeld == 0)
242 gClear_CodeHeld = 0;
243 } else if (gKeysHeld != 0) {
244 if (gKeysHeld ==
247 gClear_CodeHeld = 1;
249 0) {
252 }
253 } else {
255 }
256 }
257 }
258 if (gClear_ExtraCodeUnlocked == 0) {
259 if (CLEAR_EXTRA_CODE_HELD != 0) {
260 if (gKeysHeld == 0)
262 } else if (gKeysHeld != 0) {
263 if (gKeysHeld ==
272 }
273 } else {
275 }
276 }
277 }
278}
279
280#undef CLEAR_SEQUENCE_KEYS
281
282/// Converts a six-bit password symbol to the edition's one- or two-byte glyph.
283static void Clear_NameEntryCharacter(s32 cell, u8 *text) {
284 text[1] = 0;
285 text[2] = 0;
286#if (LANGUAGE != LANGUAGE_JAPANESE)
287 if (cell <= 7)
288 text[0] = cell + 'A';
289 else if (cell <= 12)
290 text[0] = cell + 'A' + 1;
291 else if (cell <= 23)
292 text[0] = cell + 'A' + 2;
293 else if (cell <= 31)
294 text[0] = cell + 26;
295 else if (cell <= 42)
296 text[0] = cell + 'A';
297 else if (cell <= 44)
298 text[0] = cell + 'A' + 1;
299 else if (cell <= 55)
300 text[0] = cell + 'A' + 2;
301 else if (cell == 56)
302 text[0] = '!';
303 else if (cell == 57)
304 text[0] = '?';
305 else if (cell == 58)
306 text[0] = '#';
307 else if (cell == 59)
308 text[0] = '&';
309 else if (cell == 60)
310 text[0] = '$';
311 else if (cell == 61)
312 text[0] = '%';
313 else if (cell == 62)
314 text[0] = '+';
315 else
316 text[0] = '=';
317#else
318 if (cell <= 14)
319 text[0] = cell - 111;
320 else if (cell <= 44)
321 text[0] = cell - 47;
322 else if (cell == 45)
323 text[0] = 0x86;
324 else {
325 if (cell <= 55)
326 text[0] = cell + 104;
327 else if (cell == 56)
328 text[0] = 0xe0;
329 else if (cell == 57)
330 text[0] = 0xe3;
331 else if (cell == 58)
332 text[0] = 0xe4;
333 else
334 text[0] = cell - 81;
335 text[1] = TEXT_MARK_VOICED;
336 }
337#endif
338}
339
340/// Returns -1 when the flagged saved scene blocks recovery, otherwise zero.
342 s32 sceneDifference;
343
345 return 0;
346 }
347 if (gGameState.sceneVariant == 2) {
348 return 0;
349 }
350 sceneDifference = gGameState.scene ^ (s32)&SceneId_WorldMap;
351 return -((u32)(-sceneDifference | sceneDifference) >> 31);
352}
353
354/// A view of the scene state that names its copy of the play time, checked
355/// against the loaded game's.
357 u8 unk000[0x100];
358 s32 word100; ///< frames
359};
360
361/// A linked console's signature: four letters naming its language and game.
365};
366
368
369/// Runs new/continue/copy/delete, arena entry and save-data transfer/password
370/// menus. Returns zero after choosing a destination; cancellation returns to
371/// selection.
373 s32 pageCount;
374 s32 encodedSize;
375 struct UiWindow *pageWindow;
376 // Keep encoded integer handles: the earlier typed-window split changes
377 // four native bytes. Integer windowHandle/passwordColumn and peerIndex/
378 // requiredLinkMask split plainly without changing the output.
379 s32 wrappedPage;
380 s32 glyphColumn;
381 s32 windowHandle;
382 s32 passwordColumn;
383 s32 tileValue;
384 // These three scalars each serve several phases: separate per-phase
385 // variables reorder the instructions or shorten the function.
386 s32 v5;
387 s32 v7;
388 s32 v6;
389 s32 linkMessage;
390 s32 peerIndex;
391 s32 requiredLinkMask;
392 s32 linkConnectionOk;
393 s32 pageGlyphIndex;
394 s32 passwordHeadingMessage;
395 s32 pageIndex;
396 s32 blendStarted;
397 struct UiWindow *helpWindow;
398 struct UiWindow *headingWindow;
399 u8 saveData[200];
401 u8 glyph[4];
402
403 blendStarted = 0;
406 gEventWork->startTransition = blendStarted;
409 // The end-of-game entry saves before returning to the world map.
410 if (gGameState.entrance == 2) {
411 L_ask:
412 UiText_ShowPositionedMessageAndWait(MsgSaveAdventureQuestion, 5);
413 v7 = Menu_AskYesNo(1);
415 if (v7 == 0) {
416 UiText_ShowPositionedMessageAndWait(MsgSaveAdventureQuestion + 1, 1);
417 gGameState.unk20f = 1;
419 if (v7 == -1) {
420 goto L_ask;
421 }
422 }
426 Engine_EventWait(0x12c);
428 return 0;
429 }
430 gSleepDisabled = blendStarted;
431// Choose a new game, existing save, arena entry, or data transfer.
432menu_top:;
434 if (v6 < 0) {
435 if (gDebugMode != 0) {
438 UiText_ShowCenteredMessage(MsgNoBackupMemory, 1, 8);
439 }
440 }
441 if (v6 == 0) {
442 if (blendStarted == 0) {
443 Engine_TaskWait(30);
446 blendStarted = 1;
447 }
448 }
449 if (v6 > 0) {
451 } else {
452 v6 = 0;
453 }
454 if (v6 == 0) {
455 // Hidden button codes expand the list of names offered for a new game.
458 v5 = 1;
459 v7 = 0;
460 for (;;) {
463 if (v6 == -1) {
464 if (v7 == 0) {
465 goto menu_top;
466 }
467 v7--;
468 continue;
469 }
470 if (gClear_CodeUnlocked != 0) {
471 v5 = 4;
472 }
473 if (gClear_ExtraCodeUnlocked != 0) {
474 v5 = 7;
475 }
476 if (++v7 >= v5) {
477 break;
478 }
479 }
482 gGameState.entrance = 20;
483 goto leave;
484 }
485 // Continue from a save, checking relocation/recovery conditions first.
486 if (v6 == 1) {
487 struct GameState *state;
488
490 if (v6 == -1) {
491 goto menu_top;
492 }
494 state = &gGameState;
495 PaletteGlow_Update(state->paletteGlow[0], state->paletteGlow[1]);
496 if (state->buildStamp != Runtime_GetBuildStampTime()) {
497 state->scene = state->savedScene;
498 state->entrance = state->savedEntrance;
500 } else if ((gKeysHeld & (KEY_L | KEY_START)) == (KEY_L | KEY_START)) {
502 UiText_ShowPositionedMessageAndWait(MsgSaveRecoveryFailed, 9);
503 goto menu_top;
504 }
505 state->scene = state->savedScene;
506 state->entrance = state->savedEntrance;
508 Engine_GameFlagSet(0x13e);
509 } else if (state->playTime !=
510 ((struct SaveMenuSceneState *)gSceneState)->word100) {
511 UiText_ShowPositionedMessageAndWait(MsgSaveDataCorrupted, 9);
512 UiText_ShowPositionedMessageAndWait(MsgSaveDataCorrupted + 1, 13);
513 if (Menu_RunConfirmSelection(1, 0, 0, 0) != 0) {
515 goto menu_top;
516 }
519 // MsgSaveRecoveryFailed, spelled as MsgSaveDataCorrupted + 2: the ROM
520 // adds 2 to the register holding the earlier message's number, and by
521 // name 108 of 921 instructions differ in tbs-en.
522 UiText_ShowPositionedMessageAndWait(MsgSaveDataCorrupted + 2, 9);
523 goto menu_top;
524 }
525 state->scene = state->savedScene;
526 state->entrance = state->savedEntrance;
528 Engine_GameFlagSet(0x13f);
529 }
531 goto leave;
532 }
533 if (v6 == 2) {
535 goto menu_top;
536 }
537 if (v6 == 3) {
539 goto menu_top;
540 }
541 if (v6 == 4) {
543 if (v6 == -1) {
544 goto menu_top;
545 }
557 }
562 gSleepDisabled = 1;
564 goto leave;
565 } else {
566 if (v6 != 5) {
567 goto menu_top;
568 }
569 link_load:;
571 if (v6 == -1) {
572 goto menu_top;
573 }
575 link_select:;
577 if (v6 == -1) {
578 goto link_load;
579 }
580 // Link transfer waits for the other game's edition-specific greeting.
581 if (v6 == 1) {
583 8, 2);
584 linkMessage = MsgClearSaveLabel;
585
586 UiText_DrawResource(linkMessage, (struct UiWindow *)v6, 0, 4);
587 UiText_DrawResource((linkMessage + 1), (struct UiWindow *)v6, 0, 16);
588 UiText_DrawResource((linkMessage + 3), (struct UiWindow *)v6, 0, 36);
590 Engine_TaskWait(10);
591 {
592 u16 *sync = (u16 *)gSerialTransfer.payload;
593
594 sync[0] = '0';
595 sync[1] = '0';
596 sync[2] = '0';
597 sync[3] = '0';
598 }
599 v7 = 0;
600 v5 = 3;
601 for (peerIndex = 0; peerIndex != 4; peerIndex++) {
602 u16 *greeting =
603 ((struct SaveLinkGreeting *)gLinkPeerSignatures)[peerIndex].code;
604
605 greeting[0] = '0';
606 greeting[1] = '0';
607 greeting[2] = '0';
608 greeting[3] = '0';
609 }
610 for (;;) {
611 if ((gKeysPressed & KEY_B) != 0) {
613 break;
614 }
615 if ((v5 & gLinkStatus) == v5) {
616 u32 control = REG_SIOCNT;
617 u32 peer = ((control << 26) >> 30) ^ 1;
618 u16 *received =
619 ((struct SaveLinkGreeting *)gLinkPeerSignatures)[peer].code;
620
621 if (received[0] == CLEAR_LINK_LANGUAGE_TAG) {
622 if (received[1] == 'V') {
623 if (received[2] == 'T') {
624 if (received[3] == 'S') {
625 v7 = 1;
626 break;
627 }
628 }
629 }
630 }
631 }
633 }
634 UiWork_Finalize((struct UiWindow *)v6, 2);
635 if (v7 == 0) {
636 goto link_select;
637 }
640
641 UiText_DrawResource(MsgClearSendingData, (struct UiWindow *)v6, 0, 4);
642 Engine_TaskWait(10);
644 Engine_TaskWait(10);
645 v5 = 0;
646 requiredLinkMask = 3;
647 linkConnectionOk = 1;
648 for (v7 = 0; v7 <= 0x927bf; v7++) {
649 v5 = (v5 + 1);
650 if ((requiredLinkMask & gLinkStatus) == requiredLinkMask) {
651 v5 = 0;
652 }
653 if (v5 == 10) {
654 linkConnectionOk = 0;
655 break;
656 }
657 if (gSerialSendSource == 0) {
658 break;
659 }
661 }
662 if (linkConnectionOk == 0) {
664 UiText_DrawResource(MsgClearCommunicationError, (struct UiWindow *)v6,
665 0, 4);
666 v5 = 1;
667 do {
669 } while ((gKeysPressed & v5) == 0);
670 }
671 Engine_TaskWait(10);
673 Engine_TaskWait(10);
674#if TBS_PATCH_4
675 UiWork_Finalize((struct UiWindow *)v6, 2);
677#else
679 UiWork_Finalize((struct UiWindow *)v6, 2);
680#endif
681 goto menu_top;
682 }
683 if (v6 == 0) {
684 // Password output packs save data, appends CRC bytes, then groups glyphs.
685 page_select:;
687
688 if (v6 == -1) {
689 goto link_select;
690 }
691 {
692 u8 *data = saveData;
693 s16 sum;
694
695 encodedSize = Clear_PackPasswordData(0, v6, data);
696 sum = Clear_ComputePasswordCrc16(encodedSize, data);
697 saveData[encodedSize] = (u16)sum >> 8;
698 saveData[encodedSize + 1] = sum;
699 encodedSize += 2;
700 encodedSize = Clear_EncodePassword(data, encodedSize, password);
701 }
702 v6 = 2;
704 pageWindow = UiWindow_Create(5, 4, 20, 12, v6);
705 pageIndex = 0;
706 pageCount = ((encodedSize / PASSWORD_SYMBOLS_PER_PAGE) + 1);
707 windowHandle = (s32)UiWindow_Create(CLEAR_HELP_WINDOW_X, 0,
709 passwordHeadingMessage = MsgClearPasswordLabel;
710 headingWindow = (struct UiWindow *)windowHandle;
711 UiText_DrawResource(passwordHeadingMessage, headingWindow, 6, 4);
712 v7 = 1;
713 if (pageCount == 1) {
714 windowHandle = (s32)UiWindow_Create(5, 16, 20, 3, v6);
715 helpWindow = (struct UiWindow *)windowHandle;
716 UiText_DrawCharacterAtOffset(passwordHeadingMessage - 2, helpWindow,
718 } else {
719 windowHandle = (s32)UiWindow_Create(CLEAR_MESSAGE_WINDOW_X, 16,
721 helpWindow = (struct UiWindow *)windowHandle;
722 UiText_DrawCharacterAtOffset(passwordHeadingMessage - 1, helpWindow, 0,
723 0);
724 }
727 for (;;) {
729 if ((gKeysPressed & KEY_B) != 0) {
732 UiWork_Finalize(pageWindow, 2);
733 UiWork_Finalize(helpWindow, 2);
734 UiWork_Finalize(headingWindow, 2);
735 goto page_select;
736 }
737 if ((gKeysPressed & KEY_A) != 0) {
738 pageIndex = (pageIndex + 1);
739 v7 = 1;
740 if (pageIndex == pageCount) {
743 UiWork_Finalize(pageWindow, 2);
744 UiWork_Finalize(helpWindow, 2);
745 UiWork_Finalize(headingWindow, 2);
747 goto menu_top;
748 }
750 } else {
751 if ((gKeysPressed & KEY_LEFT) != 0 && pageCount > 1) {
753 wrappedPage = pageIndex + pageCount;
754 wrappedPage--;
755 } else if ((gKeysPressed & KEY_RIGHT) != 0 && pageCount > 1) {
757 wrappedPage = pageIndex + pageCount;
758 wrappedPage++;
759 } else {
760 goto keys_done;
761 }
762 wrappedPage = (wrappedPage % pageCount);
763 v7 = 1;
764 pageIndex = wrappedPage;
765 }
766 keys_done:;
767 if (v7 != 1) {
768 v5 = passwordHeadingMessage;
769 } else {
771 v7 = 0;
772 v5 = 2;
773 do {
774 UiWindow_DrawDividerLine(pageWindow, 0, v5, 18, v5);
775 v5 = (v5 + 2);
776 v7 = (v7 + 1);
777 } while (v7 != 4);
778 if (pageCount > 1) {
779 v7 = 0;
780 if (pageCount != 0) {
781 v6 = 0;
782 do {
783 tileValue = v7 + 0xf301;
784 if (v7 == pageIndex) {
785 tileValue = v7 + 0xf30b;
786 }
787 UiWindow_SetTilemapEntry(pageWindow, tileValue,
788 v7 + 18 - pageCount, -1, v6);
789 v7 = (v7 + 1);
790 } while (v7 != pageCount);
791 }
792 v5 = 0;
794 (17 - (s32)pageCount), -1, 0);
796 0);
798 ((struct UiWindow *)pageWindow)->y);
799 }
800 // Each page holds 50 symbols in five rows, split into two groups.
801 v6 =
803 if (v6 > encodedSize) {
804 v6 = encodedSize;
805 }
806 for (v7 = pageIndex * PASSWORD_SYMBOLS_PER_PAGE, pageGlyphIndex = 0;
807 v7 != v6; v7++, pageGlyphIndex++) {
808 /* FAKEMATCH(one-pass): the block makes each draw call rebuild the
809 * glyph's address as the ROM does; without it, 98 of 921
810 * instructions differ in tbs-en. */
811 do {
813 glyph);
814 } while (0);
815 passwordColumn = (v7 % 10);
816 if (passwordColumn > 4) {
817 s32 row;
818
819 glyphColumn = (pageGlyphIndex % 10);
820 row = (pageGlyphIndex / 10);
821 UiText_DrawString(glyph, pageWindow, glyphColumn * 12 + 18,
822 (row << 4) + 2);
823 } else {
824 s32 row;
825
826 glyphColumn = (pageGlyphIndex % 10);
827 /* FAKEMATCH(wrapper): the division written as a call to
828 * __divsi3; as pageGlyphIndex / 10, 45 of 921 instructions
829 * differ in tbs-en. */
830 row = __divsi3(pageGlyphIndex, 10);
831 UiText_DrawString(glyph, pageWindow, glyphColumn * 12 + 8,
832 (row << 4) + 2);
833 }
834 }
835 v7 = 0;
836 }
838 }
839 }
840 Engine_TaskWait(0x12c);
841 goto menu_top;
842 }
843leave:;
844 gEventWork->requestedExit = 0x3e7;
850 return 0;
851}
852
853/// UNUSED: decodes tiles and maps a 16-by-eight window region in VRAM and
854/// shadow.
855UNUSED static void SaveMenu_FillTileGrid(struct UiWindow *window,
856 const void *compressedTiles) {
857 u16 *shadow;
858 u16 *vram;
859 void *decodedTiles;
860 s32 row;
861 s32 col;
862 s32 offset;
863
864 shadow = ((struct UiRenderWork *)gWindowWork[0])->tilemap;
865 decodedTiles = Runtime_BumpAllocateAlternatePool(0x300);
866 FieldResource_DecodeType01(compressedTiles, decodedTiles);
867 offset = (window->y * 32 + window->x) * 2;
868 vram = (u16 *)(0x06002000 + offset);
869 shadow = (u16 *)((u8 *)shadow + offset);
870 for (row = 0; row <= 7; row++) {
871 for (col = 0; col <= 15; col++) {
872 s16 tile = (window->width * row + col) | 0xf000;
873
874 *vram++ = tile;
875 *shadow++ = tile;
876 }
877 vram += 16;
878 shadow += 16;
879 }
880 Runtime_BumpFree(decodedTiles);
881}
882
883/// UNUSED: fills a 16-by-eight region with palette 15 tiles beginning at
884/// tile 32.
885UNUSED static void SaveMenu_FillTileBlock(const struct UiWindow *window) {
886 s16 *mirror = ((struct UiRenderWork *)gWindowWork[0])->tilemap;
887 s16 *buffer = Runtime_BumpAllocateAlternatePool(0x300);
888 s16 *vram;
889 s32 cell;
890 s32 row;
891 s32 base;
892
893 cell = window->y * 32 + window->x;
894 vram = (s16 *)0x06002000 + cell;
895 mirror += cell;
896 row = 0;
897 base = 0;
898 do {
899 s32 tile = base + 32;
900 s32 remaining = 15;
901
902 do {
903 s16 value = tile | -0x1000;
904
905 remaining--;
906 *vram = value;
907 tile++;
908 *mirror = value;
909 vram++;
910 mirror++;
911 } while (remaining >= 0);
912 row++;
913 vram += 16;
914 mirror += 16;
915 base += 16;
916 } while (row <= 7);
917 Runtime_BumpFree(buffer);
918}
919
920/// A party member's base stats, which the password clamps and packs.
929};
930
931/// A party member as the password reads them: their level, base stats,
932/// inventory and Djinn.
934 u8 unk00[0x0f];
937 u8 unk20[0xb8];
941};
942
943/// Packs selected flags, levels, Djinn and optional stats/inventories/coins.
944/// Clamps the source base stats and levels in place; returns the raw byte
945/// count.
946static s32 Clear_PackPasswordData(s32 unused, s32 mode, u8 *out) {
947 // A direct BattleUnit owner plus the real member table shrinks the native
948 // function from 0x400 to 0x3f4. The private view remains pending owner
949 // reconciliation; its fields below follow BattleUnit's actual base stats.
950 s32 length;
951 u32 levelBits;
952 u32 djinnBits;
953 u8 keyItemBits;
954 u8 flagBits;
955 u32 packedStats[8];
956 s32 i;
957 s32 outputIndex;
958 s32 bitOffset;
959 s32 j;
960 s32 k;
961 s32 n;
962
963 length = 11;
964 switch (mode) {
965 case 0:
966 length = 173;
967 break;
968 case 1:
969 length = 39;
970 break;
971 case 2:
972 length = 9;
973 break;
974 }
975 for (i = 0; i != length; i++) {
976 out[i] = 0;
977 }
978
979 levelBits = 0;
980 djinnBits = 0;
981 keyItemBits = 0;
982 flagBits = 0;
983 for (i = 0; i != 8; i++) {
984 packedStats[i] = 0;
985 }
986
987 // Preserve the selected story flags and four heroes' transfer data.
988 for (i = 0; i != 6; i++) {
989 if (Engine_GameFlagIsSet(((const u16 *)gClear_PasswordFlags)[i])) {
990 flagBits |= 1 << i;
991 }
992 }
993
994 for (i = 0; i != 4; i++) {
995 struct PasswordOwner *owner = (struct PasswordOwner *)UnitGet(
996 ((const struct { s32 id[4]; } *)gClear_PasswordMembers)->id[i]);
997 struct PasswordStats *stats = &owner->stats;
998
999 if (stats->baseHp > 1999) {
1000 stats->baseHp = 1999;
1001 }
1002 if (stats->baseHp < 0) {
1003 stats->baseHp = 0;
1004 }
1005 if (stats->basePp > 1999) {
1006 stats->basePp = 1999;
1007 }
1008 if (stats->basePp < 0) {
1009 stats->basePp = 0;
1010 }
1011 if (stats->baseAttack > 999) {
1012 stats->baseAttack = 999;
1013 }
1014 if (stats->baseDefense > 999) {
1015 stats->baseDefense = 999;
1016 }
1017 if (stats->baseAgility > 999) {
1018 stats->baseAgility = 999;
1019 }
1020 if (stats->baseLuck > 99) {
1021 stats->baseLuck = 99;
1022 }
1023 // Shift as unsigned: the permitted HP and Defense maxima exceed the
1024 // signed 32-bit range after packing, while their bit patterns are valid.
1025 packedStats[i * 2] =
1026 (u32)stats->baseHp << 21 | stats->basePp << 10 | stats->baseAttack;
1027 packedStats[i * 2 + 1] = (u32)stats->baseDefense << 22 |
1028 stats->baseAgility << 12 | stats->baseLuck << 4;
1029 if (owner->level > 99) {
1030 owner->level = 99;
1031 }
1032 if (owner->level == 0) {
1033 owner->level = 1;
1034 }
1035 levelBits |= owner->level << (i * 7);
1036 for (j = 0; j != 4; j++) {
1037 djinnBits += owner->djinnAvailable[j] << (j * 7);
1038 }
1039 for (j = 0; j != 15; j++) {
1040 u16 item = owner->inventory[j] & 0x1ff;
1041
1042 for (k = 0; k != 8; k++) {
1043 if (item == ((const u16 *)gClear_PasswordKeyItems)[k]) {
1044 keyItemBits |= 1 << k;
1045 }
1046 }
1047 }
1048 }
1049
1050 // The largest password also carries inventories, stack counts and coins.
1051 if (mode == 0) {
1052 outputIndex = 39;
1053 bitOffset = 0;
1054 for (i = 0; i != 4; i++) {
1055 struct PasswordOwner *owner = (struct PasswordOwner *)UnitGet(
1056 ((const struct { s32 id[4]; } *)gClear_PasswordMembers)->id[i]);
1057
1058 for (n = 0; n != 15; n++) {
1059 u16 item;
1060
1061 Item_Get(owner->inventory[n]);
1062 item = owner->inventory[n] & 0x1ff;
1063 out[outputIndex] += item >> (bitOffset + 1);
1064 out[outputIndex + 1] += item << (7 - bitOffset);
1065 bitOffset++;
1066 outputIndex++;
1067 if (bitOffset == 7) {
1068 bitOffset = 0;
1069 outputIndex++;
1070 }
1071 }
1072 }
1073
1074 outputIndex = 107;
1075 bitOffset = -1;
1076 for (i = 0; i != 4; i++) {
1077 struct PasswordOwner *owner = (struct PasswordOwner *)UnitGet(
1078 ((const struct { s32 id[4]; } *)gClear_PasswordMembers)->id[i]);
1079 s32 m;
1080
1081 for (m = 0; m != 23; m++) {
1082 UNUSED u16 quantity;
1083
1084 j = 0;
1085 for (n = 0; n != 15; n++) {
1086 if ((owner->inventory[n] & 0x1ff) ==
1087 ((const u16 *)gClear_PasswordStackItems)[m]) {
1088 j = (owner->inventory[n] & 0xf800) >> 11;
1089 }
1090 }
1091 /* FAKEMATCH(dead): a halfword copy of the quantity nothing reads,
1092 * which leaves the shift hoisted above the sign test; without it, 71
1093 * of 485 instructions differ in tbs-en. */
1094 quantity = j;
1095 if (bitOffset < 0) {
1096 out[outputIndex] += (u16)j >> -bitOffset;
1097 outputIndex++;
1098 bitOffset += 8;
1099 }
1100 out[outputIndex] += (u16)j << bitOffset;
1101 bitOffset -= 5;
1102 if (bitOffset == -5) {
1103 outputIndex++;
1104 bitOffset = 3;
1105 }
1106 }
1107 }
1108 out[165] = (u32)gGameState.coins >> 16;
1109 out[166] = (u32)gGameState.coins >> 8;
1110 out[167] = gGameState.coins;
1111 }
1112
1113 // The two larger forms include the packed base-stat rows.
1114 if (mode != 2) {
1115 s32 statsOffset = 8 + (mode != 0);
1116
1117 for (i = 0; i != 2; i++) {
1118 out[statsOffset] = packedStats[i * 4] >> 24;
1119 out[statsOffset + 1] = packedStats[i * 4] >> 16;
1120 out[statsOffset + 2] = packedStats[i * 4] >> 8;
1121 out[statsOffset + 3] = packedStats[i * 4];
1122 out[statsOffset + 4] = packedStats[i * 4 + 1] >> 24;
1123 out[statsOffset + 5] = packedStats[i * 4 + 1] >> 16;
1124 out[statsOffset + 6] = packedStats[i * 4 + 1] >> 8;
1125 out[statsOffset + 7] = packedStats[i * 4 + 1];
1126 out[statsOffset + 7] |= packedStats[i * 4 + 2] >> 28;
1127 out[statsOffset + 8] = packedStats[i * 4 + 2] >> 20;
1128 out[statsOffset + 9] = packedStats[i * 4 + 2] >> 12;
1129 out[statsOffset + 10] = packedStats[i * 4 + 2] >> 4;
1130 out[statsOffset + 11] = packedStats[i * 4 + 2] << 4;
1131 out[statsOffset + 11] |= packedStats[i * 4 + 3] >> 28;
1132 out[statsOffset + 12] = packedStats[i * 4 + 3] >> 20;
1133 out[statsOffset + 13] = packedStats[i * 4 + 3] >> 12;
1134 out[statsOffset + 14] = packedStats[i * 4 + 3] >> 4;
1135 statsOffset += 15;
1136 }
1137 }
1138
1139 out[0] = levelBits;
1140 out[1] = levelBits >> 8;
1141 out[2] = levelBits >> 16;
1142 out[3] = (levelBits >> 20 & 0xf0) | (djinnBits & 0x0f);
1143 out[4] = djinnBits >> 4;
1144 out[5] = djinnBits >> 12;
1145 out[6] = djinnBits >> 20;
1146 out[7] = flagBits;
1147 if (mode != 0) {
1148 out[8] = keyItemBits;
1149 }
1150 return length;
1151}
1152
1153/// Obscures the packed bytes and emits position-adjusted six-bit password
1154/// symbols.
1155static s32 Clear_EncodePassword(u8 *data, s32 size, u8 *out) {
1156 s32 xorKey;
1157 s32 symbolCount;
1158 s32 i;
1159 s32 j;
1160 s32 inputBit;
1161 s32 inputIndex;
1162 s32 symbol;
1163 s32 groupSum;
1164 s32 groupSymbols;
1165 s32 sourceBit;
1166
1167 // The final input byte obscures the preceding bytes.
1168 xorKey = data[size - 1];
1169 symbolCount = 0;
1170 for (i = 0; i != size - 1; i++)
1171 data[i] ^= xorKey;
1172 inputBit = 0;
1173 inputIndex = 0;
1174 groupSum = 0;
1175 groupSymbols = 0;
1176 // Extract six-bit symbols and append a checksum after every nine symbols.
1177 do {
1178 symbol = 0;
1179 for (j = 0; j != 6; j++) {
1180 sourceBit = (data[inputIndex] >> (7 - inputBit)) & 1;
1181 inputBit++;
1182 if (inputBit == 8) {
1183 inputBit = 0;
1184 inputIndex++;
1185 }
1186 symbol |= sourceBit << (5 - j);
1187 if (inputIndex == size)
1188 break;
1189 }
1190 groupSymbols++;
1191 out[symbolCount++] = symbol;
1192 groupSum += symbol;
1193 if (groupSymbols == 9) {
1194 out[symbolCount++] = groupSum & PASSWORD_SYMBOL_MASK;
1195 groupSum = 0;
1196 groupSymbols = 0;
1197 }
1198 } while (inputIndex != size);
1199 // Add each symbol's position, wrapping within the 64-character alphabet.
1200 for (i = 0; i != symbolCount; i++)
1201 out[i] = (out[i] + i) & PASSWORD_SYMBOL_MASK;
1202 return symbolCount;
1203}
1204
1205/// Runs the original shift/subtract checksum, initially 0xffff, and returns
1206/// its complemented low 16 bits.
1207static u16 Clear_ComputePasswordCrc16(u32 byteCount, u8 *data) {
1208 u32 crc;
1209 u32 byteIndex;
1210 u32 bitIndex;
1211
1212 byteIndex = 0;
1213 crc = 0xFFFF;
1214 if (byteCount != 0) {
1215 do {
1216 crc ^= *data << 8;
1217 bitIndex = 0;
1218 do {
1219 if ((crc & 0x8000) != 0) {
1220 crc = (crc << 1) + 0xFFFFEFDF;
1221 } else {
1222 crc <<= 1;
1223 }
1224 bitIndex++;
1225 } while (bitIndex != 8);
1226 byteIndex++;
1227 data++;
1228 } while (byteIndex != byteCount);
1229 }
1230 return ~crc;
1231}
1232
1234 {0, CONDITION_ALWAYS, 0, 0, 0, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
1236};
1237
1239 SCENE_EXITS(511),
1240};
1241
1244};
1245
1248};
1249
1251
1253
1255
1257
1259
1261
1263
1264// clang-format off
1266 0, 1, 2, 3,
1267};
1268
1270 0x9510941, 0x8d108b3, 0x868081e,
1271};
1272
1274 0xc900c8, 0xcb00ca, 0xcd00cc, 0xcf00ce,
1275};
1276
1278 180, 181, 182, 183, 186, 187, 188, 189,
1279 191, 192, 193, 194, 195, 196, 226, 227,
1280 228, 229, 236, 238, 239, 240, 241,
1281};
1282// clang-format on
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
s16 gClear_CodeUnlocked
Definition clear.c:1252
s32 SaveMenu_Run(void)
Runs new/continue/copy/delete, arena entry and save-data transfer/password menus.
Definition clear.c:372
#define CLEAR_MESSAGE_WINDOW_WIDTH
Definition clear.c:115
static s32 Clear_PackPasswordData(s32 unused, s32 mode, u8 *out)
Packs selected flags, levels, Djinn and optional stats/inventories/coins.
Definition clear.c:946
#define CLEAR_EXTRA_CODE_HELD
Whether a key of the extra code is still held.
Definition clear.c:126
u8 * Clear_GetExits(void)
Definition clear.c:139
#define CLEAR_SEQUENCE_KEYS(sequence)
Definition clear.c:233
static UNUSED void SaveMenu_FillTileBlock(const struct UiWindow *window)
UNUSED: fills a 16-by-eight region with palette 15 tiles beginning at tile 32.
Definition clear.c:885
#define PASSWORD_SYMBOL_MASK
Definition clear.c:119
#define CLEAR_LINK_ERROR_WINDOW_WIDTH
Definition clear.c:88
u32 gClear_PasswordFlags[]
Definition clear.c:1269
s16 gClear_ExtraCodeProgress
Definition clear.c:1258
s32 __divsi3(s32, s32)
static s32 Clear_GetSaveRecoveryBlockMask(void)
Returns -1 when the flagged saved scene blocks recovery, otherwise zero.
Definition clear.c:341
struct SceneEntrance gClear_Entrances[]
Definition clear.c:1233
const u16 gClear_ExtraCodeSequence[]
Definition clear.c:221
#define CLEAR_HELP_WINDOW_X
Definition clear.c:96
#define CLEAR_LINK_LANGUAGE_TAG
Definition clear.c:79
static void Clear_CheckButtonCodes(void)
Tracks two hidden key sequences, requiring a full release after each key.
Definition clear.c:238
#define CLEAR_LINK_ERROR_WINDOW_X
Definition clear.c:87
static void Clear_LoadBackground(void)
Loads the Golden Sun logo, maps its tiles and resets background scroll.
Definition clear.c:146
u16 gClear_PasswordStackItems[]
Definition clear.c:1277
const u16 gClear_CodeSequence[]
Hidden command: sequence of pressed keys, terminated by 0.
Definition clear.c:217
s16 gClear_BlendFrame
Definition clear.c:1250
s16 gClear_ExtraCodeUnlocked
Definition clear.c:1254
#define CLEAR_PASSWORD_BUFFER_SIZE
Definition clear.c:54
u8 * Clear_GetPlacements(void)
Definition clear.c:141
#define CLEAR_LINK_WINDOW_WIDTH
Definition clear.c:65
#define CLEAR_MESSAGE_WINDOW_X
Definition clear.c:114
#define CLEAR_HELP_WINDOW_WIDTH
Definition clear.c:97
u32 gClear_Exits[]
Definition clear.c:1238
struct ScenePlacement gClear_Placements[]
Definition clear.c:1242
static void Clear_NameEntryCharacter(s32 cell, u8 *text)
Converts a six-bit password symbol to the edition's one- or two-byte glyph.
Definition clear.c:283
s16 gClear_CodeProgress
Definition clear.c:1256
static UNUSED void SaveMenu_FillTileGrid(struct UiWindow *window, const void *compressedTiles)
UNUSED: decodes tiles and maps a 16-by-eight window region in VRAM and shadow.
Definition clear.c:855
s32 gClear_ExtraCodeHeld
Definition clear.c:1262
struct SceneEvent gClear_Events[]
Definition clear.c:1246
#define CLEAR_PAGE_LABEL_X
Definition clear.c:101
static u16 Clear_ComputePasswordCrc16(u32 byteCount, u8 *data)
Runs the original shift/subtract checksum, initially 0xffff, and returns its complemented low 16 bits...
Definition clear.c:1207
u8 * Clear_GetEvents(void)
Definition clear.c:143
u32 gClear_PasswordKeyItems[]
Definition clear.c:1273
u8 * Clear_GetEntrances(void)
The file select overlay's scene tables, for the scene loader: one entrance, the exit,...
Definition clear.c:135
u32 gClear_PasswordMembers[]
Definition clear.c:1265
static s32 Clear_EncodePassword(u8 *data, s32 size, u8 *out)
Obscures the packed bytes and emits position-adjusted six-bit password symbols.
Definition clear.c:1155
s16 gClear_CodeHeld
Definition clear.c:1260
static void Clear_UpdateBlend(void)
Advances the logo blend every two frames and removes itself at completion.
Definition clear.c:195
#define CLEAR_LINK_WINDOW_X
Definition clear.c:64
#define PASSWORD_SYMBOLS_PER_PAGE
Definition clear.c:118
The engine calls the debug menus import, and their palette swatch tiles.
DMA channel registers, and the DMA and CPU fills.
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
The edition's language, for C to compare (LANGUAGE == LANGUAGE_GERMAN).
The engine call layer: one typed inline for each of the thirteen main-image routines below that the s...
static s32 FieldScheduler_AddCallback(SchedulerCallback callback, s32 priority)
Registers a main-image scheduler callback.
Definition engine_call.h:36
static s32 FieldResource_DecodeType01(const void *source, void *destination)
Decodes type-01 compressed data.
Definition engine_call.h:90
The scene script layer: the engine services a scene's events call, declared once (Engine_EventBegin,...
u8 * Engine_ResourceGetTableEntry(s32 resource)
#define GameFlag_IsSet
s32 Engine_TaskRemoveCallback(void(*callback)(void))
void Engine_EventCloseScreen(void)
void Engine_EventWaitForScreen(void)
#define GameFlag_Set
void Engine_EventOpenScreen(void)
void Engine_BlendSetDarkenTarget16(s32 target)
void Engine_GameFlagSet(s32 flag)
s32 Engine_GameFlagIsSet(s32 flag)
u8 gSceneState[]
void Engine_EventWait(s32 frames)
The scene table formats: entrances, exits, placements and events, and the macros that write them.
#define SCENE_EVENTS_END
#define SCENE_EXITS(scene)
Definition field_scene.h:72
@ SCENE_TABLE_END
Definition field_scene.h:43
@ CONDITION_ALWAYS
Definition field_scene.h:44
@ FACING_SOUTH
Definition field_scene.h:28
void GameFlag_ClearBit(s32 flag)
Clears flag.
Definition flags.c:40
Game flags, named where their meaning is shown.
#define FLAG_RETREAT_BLOCKED
Retreat is blocked, from Psynergy or an item.
Definition flags.h:55
#define FLAG_KEEP_PARTY_POSITION
Definition flags.h:93
#define FLAG_INVENTORY_SNAPSHOT
Set while the Colosso holds the party's equipment (the inventory snapshot).
Definition flags.h:92
#define FLAG_IN_LINK_LOBBY
Set when the cleared game's menu goes to the link lobby: there Psynergy has no effect and the system ...
Definition flags.h:80
#define FLAG_MENU_OPEN
Set while the field menu is open; scenes hold their moving actors still.
Definition flags.h:23
The frame loop's globals: lag counts, the CPU load display and the VBlank flags.
volatile u8 gSleepDisabled
Nonzero: WaitFrames counts no idle time and ignores sleep requests.
u8 gDebugMode
Debug builds: Start+Select pauses the frame loop.
volatile u8 gIdleSleepEnabled
Sleep after three idle minutes.
void UiText_ShowPositionedMessageAndWait(s32 message, s32 flags)
Shows a message in a window centred on the screen, waits until it is typed out and closes it.
Definition frames.c:447
GameState, the game's state: play time, coins, the scene and the leader's position,...
struct GameState gGameState
The work slots of gWorkSlot, read through their own names.
void * gMapWork[]
u16 gLinkPeerSignatures[][12]
24 bytes per peer
The screen blend's globals and the graphics routines.
void * Runtime_BumpAllocateAlternatePool(s32 size)
As MemAlloc, but tries EWRAM first.
Definition heap.c:140
s32 Menu_RunConfirmSelection(s32 bottom, s32 message, s32 labelWidth, s32 selection)
Selects Yes/No (icons 5/6); canceling returns 1 (No).
Definition icon_menu.c:795
s32 Menu_SelectResourceLayout(s32 mode)
Selects either the transfer method (mode 0) or password level.
Definition icon_menu.c:675
s32 Menu_SelectSaveSlotAction(void)
Builds the title menu from the save summaries and optional send flags.
Definition icon_menu.c:511
The hardware's I/O registers and their bits, as pret names them.
#define BLDCNT_TGT2_BG2
Definition io_reg.h:136
#define BLDCNT_TGT1_OBJ
Definition io_reg.h:127
#define REG_BG0HOFS
Definition io_reg.h:149
@ DISPCNT_OBJ_ON
Definition io_reg.h:44
@ DISPCNT_BG2_ON
Definition io_reg.h:42
@ KEY_UP
Definition io_reg.h:249
@ KEY_B
Definition io_reg.h:244
@ KEY_SELECT
Definition io_reg.h:245
@ KEY_LEFT
Definition io_reg.h:248
@ KEY_START
Definition io_reg.h:246
@ KEY_RIGHT
Definition io_reg.h:247
@ KEY_A
Definition io_reg.h:243
@ KEY_DOWN
Definition io_reg.h:250
@ KEY_L
Definition io_reg.h:252
#define DMA_32BIT
Definition io_reg.h:210
#define BLDCNT_EFFECT_BLEND
weighted by REG_BLDALPHA
Definition io_reg.h:131
#define BLDCNT_TGT2_BG1
Definition io_reg.h:135
#define REG_DMA3
Definition io_reg.h:153
#define BLDCNT_TGT2_BG3
Definition io_reg.h:137
#define BLEND_ALPHA(top, bottom)
A REG_BLDALPHA value: top and bottom are the two targets' weights, out of 16.
Definition io_reg.h:145
#define REG_BG2CNT
Definition io_reg.h:21
#define REG_BLDALPHA
Definition io_reg.h:142
#define BG_PLTT
Definition io_reg.h:157
#define BLDCNT_TGT1_BG0
Definition io_reg.h:123
#define REG_SIOCNT
Definition io_reg.h:180
#define REG_BLDCNT
Definition io_reg.h:119
#define DMA_ENABLE
Definition io_reg.h:217
#define BLDCNT_TGT2_BD
Definition io_reg.h:139
The register write queue that VBlank carries out after each finished frame.
#define IO_WRITE_QUEUE_PUSH(address, value, control)
Disables interrupts to add one register write or DMA to the queue; a write to a full queue is dropped...
Items: their definitions, types, flags and effects.
struct ItemDefinition * Item_Get(s32 item)
The keypad state the VBlank interrupt keeps.
volatile u32 gKeysHeld
Keys down now.
volatile u32 gKeysPressed
Keys that went down this frame.
s32 SceneData_ReturnZero(void)
Definition level.c:51
The map layers' scroll work and the background scroll values.
struct BgScroll gBgScroll[]
The heaps: allocating and freeing blocks.
void Runtime_BumpFree(void *buffer)
The reel game's title lettering.
s32 NameEntry_EditOwnerName(s32 member)
The name entry screen for party member member: the player types a name of up to NAME_MAX_LETTERS lett...
Definition name_entry.c:232
s32 Menu_AskYesNo(s32 atBottom)
Asks yes or no at the top of the screen, or at the bottom with atBottom set.
Definition events.c:468
void Event_SetDestination(s32 scene, s32 entrance)
Makes the event leave for the given entrance of the given scene: raises the exit request 999 and writ...
Definition events.c:517
void PaletteGlow_Update(s32 phase, s32 brightness)
Sets the window colours (BG palette 15, colours 4 to 10) for a window hue (0 to 23) and brightness (0...
Definition options.c:152
s32 Party_RemoveActiveOwner(s32 owner)
Takes character owner out of the party: clears its game flag and closes the gap it leaves in gGameSta...
Definition party.c:154
s32 Party_AddActiveOwner(s32 owner)
Adds character owner to the end of the party: sets its game flag and appends it to gGameState....
Definition party.c:135
void Link_DrawShiftedTilePair(s32 offset)
Animates the two link indicator tiles with opposing two/three-pixel shifts.
Definition pictures.c:237
void Graphics_ExpandVramTilesByColorTable(u16 *dst)
Expands two palette variants of the ten source tile rows at 0x06000600, mapping each packed nibble th...
Definition pictures.c:256
The work pointers in the gWorkSlot table, by name.
#define Ram_MapCellBuffer
Definition ram_buffer.h:10
Resource numbers, named where their contents are known.
char ResourceId_GoldenSunLogo
FIELD_AT_OFFSET and the entity and camera views older scene code reads.
Scene numbers, named after their places.
char SceneId_ValeBabi
char SceneId_WorldMap
char SceneId_LinkLobby
s32 SerialRuntime_BeginSend(void *source, s32 size)
Starts sending size bytes from source to the partner in 20-byte blocks: sets the send source,...
Definition serial.c:454
void SerialRuntime_RemoveIrqHandlers(void)
Clears gSerialExchangeActive, which stops the per-frame exchange, and removes the link interrupt hand...
Definition serial.c:431
void SerialRuntime_Initialize(void)
Resets the serial port into multiplayer mode, installs the serial and timer 3 interrupt handlers,...
Definition serial.c:28
The link cable's runtime: serial packets, registers and transfer state.
volatile u16 gLinkStatus
Link status, updated by the VBlank exchange handler.
s32 gSerialSendSource
struct SerialTransferState gSerialTransfer
void InventorySnapshot_Restore(void)
Gives back the inventories, shortcuts and party order InventorySnapshot_Save put aside,...
Definition snapshot.c:82
Song and sound effect ids, indices into gSound_SongTable.
#define SE_MENU_CANCEL
Definition songs.h:106
#define SE_MENU_CURSOR_MOVE
Definition songs.h:104
#define MUS_017
Definition songs.h:27
#define SE_MENU_CONFIRM
Definition songs.h:105
#define SE_110
Definition songs.h:103
struct EventWork * gEventWork
void Engine_AudioPlayCue()
void Engine_TaskWait()
#define LOGO_MAP
Definition title.h:18
#define LOGO_FIRST_TILE
Definition title.h:19
#define LOGO_BLANK_TILE
The map entry after each row's 30 visible tiles.
Definition title.h:22
#define LOGO_BGCNT
Definition title.h:17
#define LOGO_TILES
Definition title.h:20
u8 gWindowWork[]
A background's hardware scroll offsets.
Definition map_scroll.h:64
u16 y
pixels
Definition map_scroll.h:65
s32 startTransition
SCENE_TRANSITION(style, variant).
Definition event_work.h:43
u16 requestedExit
the exit kind taken, which ends the scene
Definition event_work.h:28
A field actor: a person or thing on the field with a position, motion toward a target,...
Definition field_obj.h:30
u8 motionFlags
ActorMotionFlag bits; zero is free flight in 3D, and 3 is set on creation.
Definition field_obj.h:83
The game's state: play time, coins, the scene and the leader's position, the active party and the opt...
Definition game_state.h:14
u8 paletteGlow[2]
window hue (0 to 24), brightness
Definition game_state.h:62
u32 playTime
frames, copied from gPlayTimeFrames when saving
Definition game_state.h:18
u32 buildStamp
Runtime_GetBuildStampTime's value when the game was last saved; its low half goes into the file's sum...
Definition game_state.h:17
u8 unk20f
Set on saving at the end of the game; copied to the file's summary as sendFlag.
Definition game_state.h:70
u8 idleSleepEnabled
the option, saved from gIdleSleepEnabled
Definition game_state.h:91
s16 sceneVariant
the current scene's variant from its record
Definition game_state.h:107
s16 entrance
Definition game_state.h:37
s32 selectedActor
the leader: its unit and its actor
Definition game_state.h:59
s16 savedScene
where a defeat returns to without a defeat point
Definition game_state.h:38
s16 savedEntrance
where a defeat returns to without a defeat point
Definition game_state.h:39
The field map's work: the followed position, screen shake, tile animations, blend script,...
Definition map_scroll.h:27
u16 flags
REG_DISPCNT bits: objects and the BG1 to BG3 shown.
Definition map_scroll.h:35
A party member as the password reads them: their level, base stats, inventory and Djinn.
Definition clear.c:933
struct PasswordStats stats
Definition clear.c:936
u8 unk00[0x0f]
Definition clear.c:934
u32 djinnAvailable[4]
Definition clear.c:940
u16 inventory[15]
Definition clear.c:938
u8 unkf6[2]
Definition clear.c:939
u8 unk20[0xb8]
Definition clear.c:937
A party member's base stats, which the password clamps and packs.
Definition clear.c:921
u8 unk14[4]
Definition clear.c:924
u16 baseAttack
Definition clear.c:925
u16 baseDefense
Definition clear.c:926
u16 baseAgility
Definition clear.c:927
A linked console's signature: four letters naming its language and game.
Definition clear.c:362
u16 code[4]
Definition clear.c:363
u8 reserved[16]
Definition clear.c:364
A view of the scene state that names its copy of the play time, checked against the loaded game's.
Definition clear.c:356
s32 word100
frames
Definition clear.c:358
u8 unk000[0x100]
Definition clear.c:357
A scene entrance: where and facing which way the party arrives, and the camera's bounds there (-1 for...
Definition field_scene.h:54
A scene event: its kind and detail, the trigger it answers, its condition and its value (a message or...
An actor a scene places: its sprite, the condition for placing it, how it behaves,...
Definition field_scene.h:81
u8 payload[20]
one block of the data sent
The window system's work: the windows' tilemap, the windows, the three text channels,...
Definition window.h:19
u16 tilemap[640]
the windows' BG tilemap, 32 by 20 tiles
Definition window.h:20
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 width
tiles
Definition uiwindow.h:13
The system's routines and globals: interrupts, BIOS sound bias, random numbers and sleep.
u8 gSaveBuffer[]
Values that differ by patch level or language, chosen once for their code.
void Ui_LoadWindowGraphics(void)
Loads the window font and frame tiles into BG character block 0, the window palette into BG palette 1...
Definition text.c:180
The kanji glyphs and the text marks drawn with characters.
@ TEXT_MARK_VOICED
the voiced mark (dakuten)
Definition text_font.h:14
void UiText_DrawResource(s32 message, struct UiWindow *window, s32 x, s32 y)
Decodes a message and draws it into a text canvas window at pixel (x, y).
Definition text_tiles.c:538
void UiText_DrawString(const u8 *text, struct UiWindow *window, s32 x, s32 y)
Draws a byte string into a text canvas window at pixel (x, y).
Definition text_tiles.c:599
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_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
The integer types, TRUE, UNUSED and the fixed-address macros.
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
#define UNUSED
Definition types.h:22
unsigned char u8
Definition types.h:11
UiWindow, a window's work, and marking its tilemap rows for transfer.
#define UiRender_MarkRow(render, y)
Requests transfer of the four-row tilemap band containing window row y.
Definition uiwindow.h:73
#define UI_PAGE_ARROW_RIGHT
Definition window.h:67
#define UI_PAGE_ARROW_LEFT
Definition window.h:66
#define UI_PAGE_ARROW_VRAM
Definition window.h:64
struct BattleUnit * UnitGet(u32 owner)
Returns the unit record of owner: 0 to 7 are the playable characters in the game state,...
Definition units.c:73
void Party_BeginChildhood(void)
Sets FLAG_CHILDHOOD and recomputes Isaac, Garet and Jenna, whose classes then take their childhood fo...
Definition units.c:603
void GameState_InitDefaults(void)
Clears the game-state header, scene state, flags and save stamp; sets a new game's defaults: Isaac al...
Definition units.c:537
u32 Runtime_GetBuildStampTime(void)
Encodes the build-stamp time as ((hours * 16 + minutes) * 64 + seconds) with bit 12 set.
Definition units.c:482
s32 Save_WriteSelectedSlot(void)
The Save command: lets the player choose a file (the current one first), asks whether to save over it...
Definition save.c:1174
s32 SaveState_DeleteSelectedSlot(void)
The file menu's Erase: lets the player choose a file, asks whether to erase it and on Yes deletes bot...
Definition save.c:429
s32 SaveState_CopySlotPair(void)
The file menu's Copy: lets the player choose a file, reads both of its records into the save buffer a...
Definition save.c:377
s32 SaveState_LoadRecordIntoWork(s32 mode)
Lets the player choose a file in save menu mode (see SaveMenuMode) and loads it into the save buffer ...
Definition save.c:1232
s32 SaveState_ScanRecordFlags(void)
Loads the save file summaries for the title menu and returns how many files there are: plus 100 when ...
Definition save.c:111
void UiWork_FinalizePendingCore(void)
Closes each message channel's window whose text has ended, then waits ten frames.
Definition messages.c:302
void UiText_ShowCenteredMessage(s32 message, s32 mode, s32 yOffset)
Shows a message centred on the screen (yOffset tiles lower) and waits until it is typed out,...
Definition messages.c:325
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
The window renderer's work.
void RenderOutput_PrepareForRedraw(struct UiWindow *window)
Clears a window's contents: redraws its empty frame and releases the render outputs it carries.
Definition windows.c:392
void UiWork_Finalize(struct UiWindow *window, s32 instant)
Closes a window: clears its contents and remembers its last rectangle.
Definition windows.c:349
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