Alchemy
Loading...
Searching...
No Matches

credits.c

Go to the documentation of this file.
2#ifdef UBFIX
3// This object uses the credits' views of the borrowed flash work cells.
4#define OWN_Flash_Handler0
5#define OWN_gFlash
6#define OWN_gFlashNumRemainingBytes
7#endif
9#include "dma.h"
10#include "io_reg.h"
11#include "types.h"
12#include "battle.h"
13#include "debug.h"
14#include "field.h"
15#include "game.h"
16#include "graphics.h"
17#include "menu.h"
18#include "minigame.h"
19#include "sound.h"
20#include "system.h"
21#include "mem.h"
22#include "resource.h"
23#include "ramcode.h"
24#include "callback_scheduler.h"
25#include "io_write_queue.h"
26#include "iowrite.h"
27#include "map_scroll.h"
28#include "heap_state.h"
29#include "resource_ids.h"
30#include "edition.h"
31#include "iwram_call.h"
32#include "static_assert.h"
33#include "battle_party.h"
34#include "battle_system.h"
35#include "frame.h"
36#include "flags.h"
37
38// Credits text uses six 32-pixel sprites across each 192-pixel line. Its
39// 32 tile rows form a ring, with sixteen rows visible at a time.
40#define CREDITS_LINE_PIXELS 192
41#define CREDITS_VISIBLE_ROWS 16
42#define CREDITS_COLUMNS 6
43#define CREDITS_RING_ROWS 32
44#define CREDITS_LINE_TILES 24
45#define CREDITS_RING_TILES (CREDITS_RING_ROWS * CREDITS_LINE_TILES)
46#define CREDITS_RING_BYTES (CREDITS_RING_TILES * TILE_SIZE_4BPP)
47#define CREDITS_BUFFER_BYTES 0x900
48#define CREDITS_RASTER_STRIDE 256
49#define CREDITS_DECODER_HEAP_SLOT 49
50#define CREDITS_BORDER_SPRITES 24
51#define CREDITS_OAM_ENTRIES 128
52
53/// Fills 30 KB of 256-color tiles with color 1 and clears 128 palette colors.
54/// Called by the credits slideshow before loading a backdrop into a half.
55/// @param alternate 0 selects the first half (VRAM 0x06000000, palette 0-127).
56/// 1 selects the second half (VRAM 0x06008000, palette 128-255, fill 129).
58 u32 fillColor;
59 void *tileDestination;
60 void *paletteDestination;
61 volatile u32 dmaFill;
62
63 // Use a solid pixel in the palette being cleared, producing an opaque
64 // black layer for the next crossfade.
65 if (alternate == 0) {
66 fillColor = 0x01010101;
67 tileDestination = BG_CHAR_BLOCK(0);
68 paletteDestination = (void *)BG_PLTT;
69 } else {
70 fillColor = 0x81818181;
71 tileDestination = BG_CHAR_BLOCK(2);
72 paletteDestination = (void *)&BG_PLTT[128];
73 }
74 Dma_Fill32Cell(dmaFill, fillColor, tileDestination, 0x7800);
75 Dma_Fill32Cell(dmaFill, 0, paletteDestination, 0x100);
76}
77
78typedef s32 (*PackedDecoder)(const u8 *source, void *destination, u32 fill);
79
80/// Battle backgrounds shown in the credits; 0 clears the display.
81// clang-format off
115 0 // Clear
116};
117// clang-format on
118
119/// Loads a credits backdrop into one of the two tile/palette halves. A zero
120/// resource clears that half; the second half offsets its palette indices.
121/// Called by DisplayScroll_RunSlideshow for each picture.
122void Graphics_LoadCharacterBlockAndPalette(u32 resourceId, s32 alternate) {
123 const u8 *resourceData;
124 u32 paletteDestination;
125 u32 paletteOffset;
126 void *tileDestination;
127
128 if (resourceId == 0) {
130 return;
131 }
132 resourceData = Resource_GetTableEntry(resourceId);
133 if (alternate == 0) {
134 paletteOffset = 0;
135 tileDestination = BG_CHAR_BLOCK(0);
136 paletteDestination = (u32)BG_PLTT;
137 } else {
138 paletteOffset = 0x80808080;
139 tileDestination = BG_CHAR_BLOCK(2);
140 paletteDestination = (u32)&BG_PLTT[128];
141 }
142 // Offset every pixel into the selected palette half so both backdrops
143 // can remain visible throughout a crossfade.
147 resourceData + 256, tileDestination, paletteOffset);
149
150 // Queue palette RAM writes for VBlank rather than transferring colours
151 // during the active display.
152 IO_WRITE_QUEUE_PUSH(paletteDestination, (u32)resourceData,
153 DMA_COPY_WORDS(0x40));
154}
155
156/// Builds the 512 tilemap words surrounding a sliding credits backdrop:
157/// blank margins, 240 consecutive tile pairs, then a zero-filled tail.
158/// Called by DisplayScroll_RunSlideshow.
160 s32 remaining;
161 u32 blankTiles = 0x01FF01FF;
162 u32 tilePair = 0x10000;
163
164 // Pad above and below the picture so vertical wrapping stays blank.
165 remaining = 31;
166 do {
167 remaining--;
168 *destination++ = blankTiles;
169 } while (remaining >= 0);
170 remaining = 239;
171 do {
172 remaining--;
173 *destination++ = tilePair;
174 tilePair += 0x20002;
175 } while (remaining >= 0);
176 remaining = 47;
177 do {
178 remaining--;
179 *destination++ = blankTiles;
180 } while (remaining >= 0);
181 tilePair = 0;
182 remaining = 191;
183 do {
184 remaining--;
185 *destination++ = tilePair;
186 } while (remaining >= 0);
187}
188
189/// A VBlank task of the credits slideshow: drifts both backdrops together,
190/// keeping their horizontal offsets aligned throughout the crossfade.
192 if ((gFrameTick & 3) == 0) {
193 u32 decrement = 0xffff;
194
195 gBgScroll[2].x += decrement;
196 gBgScroll[3].x += decrement;
197 }
198}
199
200/// Crossfades the credits backdrop sequence through alternating tile banks
201/// while the staff names scroll over it, then restores the display for the
202/// following screen. Reached through the scroll far-call table at the end of
203/// the game.
205 u32 slide;
206 s32 alpha;
207
208 gOamCopyEnabled = 0;
215 // Each layer owns its map, tiles and palette half. Load the invisible
216 // half while the other remains on screen.
224 &REG_BG2CNT);
226 &REG_BG3CNT);
229 &REG_DISPCNT);
232 &REG_BLDCNT);
233 // Give the names a five-second lead before the first backdrop.
235 WaitFrames(300);
236 // Alternate the hidden layer after each 64-frame crossfade. Loading it
237 // cannot overwrite the picture that is still showing.
238 for (slide = 0; slide < sizeof(gDisplayScroll_SlideResources) /
240 slide++) {
242 (slide & 1) ^ 1);
243 // The two weights are written out, bottom first: through BLEND_ALPHA
244 // the operands swap and the crossfade's registers change.
245 for (alpha = 1; alpha <= 16; alpha++) {
246 if (slide & 1)
247 Io_Write16((alpha << 8) | (16 - alpha), &REG_BLDALPHA);
248 else
249 Io_Write16(((16 - alpha) << 8) | alpha, &REG_BLDALPHA);
250 WaitFrames(4);
251 }
252 WaitFrames(267);
253 }
258 gOamCopyEnabled = 1;
259 return 0;
260}
261
262/// One eight-byte OAM entry in the credits' private sprite buffer.
264 u32 attr01; ///< Attribute 0 in the low half, attribute 1 in the high half.
265 u32 attr2; ///< Attribute 2 in the low half; the unused high half stays zero.
266};
267
269
270/// Credits scroll position in pixels, in the low half of a flash work cell.
271extern u16 gFlash_Handler3;
272
273// ewram.s reserves four bytes for each cell. The credits replace the task table
274// and borrow them while flash operations are inactive: a sprite-buffer pointer,
275// the last rendered pixel position, and a zero/-1 end-of-text latch.
276// UB: the native casts alias the flash declarations and store a pointer through
277// a declared u16. UBFIX gives these assembler-backed cells their credits views.
278#ifdef UBFIX
280extern s16 gFlash;
281extern s16 gFlash_Handler0;
282
283#define SCROLL_OBJECTS gFlashNumRemainingBytes
284#define CREDITS_LAST_LINE_POSITION gFlash
285#define CREDITS_END_OF_TEXT gFlash_Handler0
286#else
287#define SCROLL_OBJECTS \
288 (*(struct DisplayScrollObject **)&gFlashNumRemainingBytes)
289#define CREDITS_LAST_LINE_POSITION (*(s16 *)&gFlash)
290#define CREDITS_END_OF_TEXT (*(s16 *)&gFlash_Handler0)
291#endif
292
293/// Blank credits line
294static const u8 sBlankCreditLine[] = "";
295
296// These labels are translated credits content, not gameplay patch selectors.
297#if LANGUAGE == LANGUAGE_JAPANESE
298#define CREDITS_STAFF_TITLE "OUGON NO TAIYO STAFF"
299#define CREDITS_FACES_SUBTITLE "& Faces"
300#define CREDITS_SOUND_DIRECTION_LABEL "Sound Direction"
301#define CREDITS_GRAPHICS_SUPPORT_LABEL "Graphic Support"
302#define CREDITS_ARTWORK_LABEL "Artwork Design"
303#else
304#define CREDITS_STAFF_TITLE "GOLDEN SUN STAFF CREDITS"
305#define CREDITS_FACES_SUBTITLE " & Faces"
306#define CREDITS_SOUND_DIRECTION_LABEL "Sound Director"
307#define CREDITS_GRAPHICS_SUPPORT_LABEL "Graphic Supports"
308#define CREDITS_ARTWORK_LABEL "Artwork"
309#endif
310
311/// Credits text, one row per line, terminated by 0.
312// clang-format off
323 "Game Planning",
325 "Hiroyuki Takahashi",
326 "Shugo Takahashi",
332 "Scenario",
334 "Hiroyuki Takahashi",
340 "Director",
342 "Shugo Takahashi",
348 "Assistant Director",
350 "Yusuke Sugimoto",
356 "Game Design",
358 "Yusuke Sugimoto",
359 "Shuji Shimizu",
360 "Ayumu Shindo",
361 "Kentaro Sakou",
367 "Programming",
369 "System",
371 "Yasuhiro Taguchi",
376 "Battle",
378 "Haruki Kodera",
379 "Toru Takamatsu",
384 "Field",
386 "Kaoru Shimada",
387 "Hiroyuki Ichikawa",
388 "Akiko Sato",
393 "User Interface",
395 "Yutaka Yamamoto",
396 "Yasushi Kazawa",
401 "Support",
403 "Kenji Numaya",
404 "P. E. Jareth Hein",
410 "Graphic Arts",
412 "Character Design",
414 "Shin Yamanouchi",
419 "Monster Design",
421 "Hiroshi Kajiyama",
426 "Battle Characters",
428 "Junko Nakamura",
429 "Kaori Matsunaga",
434 "Battle Effects",
437 "Junichi Ochiai",
442 "Battle Backgrounds",
444 "Hiroto Nakashima",
449 "Maps",
451 "Masayuki Hashimoto",
452 "Mitsumasa Muraishi",
453 "Mitsuru Fukumoto",
454 "Masashi Mikami",
455 "Akihito Kimura",
456 "Shinichiro Sugimoto",
461 "Map Characters",
463 "Mieko Koguchi",
464 "Kanako Horiguchi",
469 "Graphics Direction",
471 "Fumihide Aoki",
477 "Staff Coordination",
479 "Akiko Sato",
480 "Kenji Numaya",
486 "Music",
488 "Motoi Sakuraba",
494 "Sound Effects",
496 "Hiroyuki Hamada",
504 "Masaaki Uno",
510 "Illustration",
512 "Shin Yamanouchi",
513 "Masanori Sato",
521 "Yoichi Kotabe",
522 "Masanori Sato",
530 "Yoshitaka Nishikawa",
531 "Mamoru Sakurai",
532 "Nanako Kinoshita",
538#if (LANGUAGE != LANGUAGE_JAPANESE)
539 "Coordination",
541 "Masaaki Uno",
542 "Toshiharu Izuno",
543 "Atsushi Okada",
544 "Kenichi Nishida",
549#endif
550#if (LANGUAGE == LANGUAGE_JAPANESE)
551 "Public Relations",
553 "Mitsuaki Hagishima",
554 "Asako Haruhana",
560 "Coordination",
562 "Masaaki Uno",
563 "Toshiharu Izuno",
564 "Kenichi Nishida",
570 "Special Thanks to",
571 "Super Mario Club Staff",
573 "Tomohiko Komada",
574 "Nobuaki Maeda",
575 "Naoki Inoue",
576 "Keisuke Moriyasu",
577 "Kei Nadabe",
578 "Syunsuke Nose",
579 "Keiichiro Nishimoto",
580 "Toshimasa Minegishi",
581 "Hiroyuki Murata",
582 "Hisashi Takizaki",
583 "Satoru Uno",
584 "Akira Nakatsumi",
585 "Takeshi Morishima",
586 "Yoshikazu Tanaka",
587 "Haruka Kato",
588 "Kazuyo Ikeda",
589 "Yayoi Yagi",
590 "Katsunori Masutani",
591 "Takafumi Harano",
592 "Shinya Tashiro",
593 "Tomohiro Nishigaki",
594 "Natsuko Shigeta",
595 "Takahisa Ohfuji",
596 "Masaru Ikeshita",
597 "Masaharu Shima",
598 "Kouichi Osaka",
599 "Naoki Tsuta",
600 "Yoshihiro Muramatsu",
601 "Tsutomu Mukai",
602 "Naotaka Matsumoto",
603 "Naoki Takami",
604 "Junya Hanai",
605 "Kouzou Uchida",
606 "Kouji Okamoto",
607 "Tomoko Yuasa",
608 "Youichiro Ushijima",
609 "Koutaro Haneda",
610 "Yukio Homma",
611 "Kotoe Arihara",
612 "Yuji Yamashita",
613 "Syogo Tachibana",
614 "Mitsuhiro Seno",
615 "Takehiko Asaka",
616 "Masato Mizuta",
625 "Produced by",
627 "Shinji Hatano",
628 "Hiroyuki Takahashi",
629 "Shugo Takahashi",
636 "Executive Producer",
638 "Hiroshi Yamauchi",
648 "Copyrights of Game, Scenario",
649 "and Program reserved by",
651 "NINTENDO Co.,Ltd.",
652 "and",
653 "CAMELOT Co.,Ltd.",
655 "Copyrights of All Characters",
656 "and Music reserved by",
658 "NINTENDO Co.,Ltd.",
662 0
663#elif (LANGUAGE == LANGUAGE_ENGLISH)
665 "North American",
666 " Localization",
671 "Translation",
672 " Coordination",
674 "Bill Trinen",
679 "Writing",
680 " & Editing",
682 "Richard Amtower",
683 "Nate Bihldorf",
688 "Additional",
689 " Localization",
691 "Tim O'Leary",
692 "Scot Ritchey",
697 "Localization",
698 " Management",
700 "Leslie Swan",
701 "Jeff Miller",
706 "Testing &",
707 " Debugging",
709 "Michael Kelbaugh",
710 "Todd Buechele",
711 "NOA Product Testing",
712 " Department",
717 "Special Thanks to",
719 "Motoyasu Tojima",
720 "Mike Fukuda",
722 " and",
725 "Minoru Arakawa",
734 "Producer",
736 "Shinji Hatano",
737 "Hiroyuki Takahashi",
738 "Shugo Takahashi",
745 "Executive Producer",
747 "Hiroshi Yamauchi",
757 "Copyrights of Game, Scenario,",
758 "and Program reserved by",
760 "NINTENDO and CAMELOT.",
762 "Copyrights of all characters",
763 "and music reserved by",
765 "NINTENDO.",
769 0
770#else
771 // European releases share this order, with local staff and publisher rows.
772 "North American",
773 " Localization",
777 "Translation",
778 " Coordination",
780 "Bill Trinen",
784 "Writing",
785 " & Editing",
787 "Richard Amtower",
788 "Nate Bihldorf",
792 "Additional ",
793 " Localization",
795 "Tim O'Leary",
796 "Scot Ritchey",
800 "Localization",
801 " Management ",
803 "Leslie Swan",
804 "Jeff Miller",
808 "Localization & ",
809 " Testing Europe",
811 "Andy Fey",
812 "Kai Zeh",
813 "Tanja Baar",
817#if (LANGUAGE == LANGUAGE_GERMAN)
818 "German Translation",
820 "Micky Auer",
821 "Martina Deimel",
822#elif (LANGUAGE == LANGUAGE_SPANISH)
823 "Spanish Translation",
825 "Carlos Montilla",
826 "Miguel Lopez",
827#elif (LANGUAGE == LANGUAGE_FRENCH)
828 "French Translation",
830 "Daniel Charbit",
831 "Steven Arhan",
832#elif (LANGUAGE == LANGUAGE_ITALIAN)
833 "Italian Translation",
835 "Andrea Salvi",
836 "Calimero Tiiijun",
837#endif
841#if (LANGUAGE == LANGUAGE_GERMAN)
842 "German Testing",
844 "Maurice Tisdale",
845 "Andreas Dietz",
846 "Rudolf Schnitzer",
847 "Wolfgang Weber",
848 "Frank Heuchle",
849 "Zoran Tasevski",
850#elif (LANGUAGE == LANGUAGE_SPANISH)
851 "Spanish Testing",
853 "Maurice Tisdale",
854 "Andreas Dietz",
855 "Luis Martinez",
856 "Jose Ramon Diaz",
857 "Ana Paris",
858 "Monica Gomez",
859#elif (LANGUAGE == LANGUAGE_FRENCH)
860 "French Testing",
862 "Maurice Tisdale",
863 "Peter Ehlert",
864 "Emeline Condy",
865 "Pascal Di Pasquale",
866 "Kamel Chelirem",
867 "Sebastien Aubre",
868 "Michael Troger",
869#elif (LANGUAGE == LANGUAGE_ITALIAN)
870 "Italian Testing",
872 "Maurice Tisdale",
873 "Andreas Dietz",
874 "Sonia Trepiccioni",
875 "Michele Liuzzi",
876 "Luca Riccioni",
877 "Andrea De Benedetto",
878#endif
882 "Special Thanks to",
884 "Motoyasu Tojima",
885 "Takako Morita",
890 "Producer",
892 "Shinji Hatano",
893 "Hiroyuki Takahashi",
894 "Shugo Takahashi",
898 "Executive Producer",
900 "Hiroshi Yamauchi",
909 "Copyrights of Game, Scenario,",
910 "and Program reserved by",
912 "NINTENDO and CAMELOT.",
914 "Copyrights of all characters",
915 "and music reserved by",
917#if (LANGUAGE != LANGUAGE_FRENCH)
918 "NINTENDO.",
919#endif
923 0
924#endif
925};
926// clang-format on
927
929
930/// A VBlank task scheduled by DisplayScroll_InitObjectTable: maps the visible
931/// sixteen rows onto the tile ring and uploads their sprites. Advances one
932/// pixel every fourth frame until the end-of-text latch stops the scroll.
934 u32 frame = gFlash_Handler3;
935 u32 scrollWithinTile = frame & 7;
936 s32 tileIndex =
937 (((s16)frame / 8) & (CREDITS_RING_ROWS - 1)) * CREDITS_LINE_TILES;
938 u32 *oamWords = (u32 *)(SCROLL_OBJECTS + CREDITS_BORDER_SPRITES);
939 s32 row;
940
941 for (row = 0; row < CREDITS_VISIBLE_ROWS; row++) {
942 s32 column;
943
944 for (column = 0; column < CREDITS_COLUMNS; column++) {
945 *oamWords++ = (row * 8 + 16 - scrollWithinTile) |
946 ((column * 32 + 24) << 16) | 0x40004000;
947 *oamWords++ = tileIndex;
948 tileIndex += 4;
949 if (tileIndex == CREDITS_RING_TILES)
950 tileIndex = 0;
951 }
952 }
954 if (CREDITS_END_OF_TEXT == 0 && (gFrameTick & 3) == 0)
956}
957
958/// A main-loop task scheduled by DisplayScroll_InitObjectTable: renders each
959/// entering line sixteen rows ahead of the visible top, into the hidden half
960/// of the tile ring. A null table entry latches the end-of-text state.
962 u32 scrollPosition;
963 s32 lineIndex;
964
965 if (CREDITS_END_OF_TEXT == 0) {
966 scrollPosition = gFlash_Handler3;
968 lineIndex = (s16)gFlash_Handler3 / 8;
969 CREDITS_LAST_LINE_POSITION = scrollPosition;
971 gDisplayScroll_LineTable[lineIndex],
972 ((lineIndex + CREDITS_VISIBLE_ROWS) & (CREDITS_RING_ROWS - 1)) *
974 1);
975 }
976 }
977}
978
979/// Allocates the credits sprites, builds the blank border and text rows,
980/// clears the tile ring and schedules scrolling and line rendering. Called by
981/// DisplayScroll_RunSlideshow; the credits keep their state in borrowed
982/// flash-library cells (see the graphics README).
984 // Sharing the three border-strip loops through an ordinary inline helper
985 // changes registers at the same 0x178-byte native English extent.
986 volatile u32 dmaFill;
987 u32 *oamWords;
988 u32 row;
989 u32 column;
990
993 // Solid border sprites immediately after the ring mask the partial text
994 // rows at the top and bottom of the window.
995 Dma_Fill32Cell(dmaFill, 0, (void *)OBJ_VRAM0, CREDITS_RING_BYTES);
996 Dma_Fill32Cell(dmaFill, 0x11111111, (void *)(OBJ_VRAM0 + CREDITS_RING_BYTES),
997 0x100);
998
999 // OAM attributes 0 and 1 share the first word; attribute 2 is the second.
1000 oamWords = (u32 *)SCROLL_OBJECTS;
1001 for (row = 0; row < 8; row++) {
1002 *oamWords++ = (row << 21) | 0x80004000;
1003 *oamWords++ = CREDITS_RING_TILES;
1004 }
1005 for (row = 0; row < 8; row++) {
1006 *oamWords++ = (row << 21) | 0x80004088;
1007 *oamWords++ = CREDITS_RING_TILES;
1008 }
1009 for (row = 0; row < 8; row++) {
1010 *oamWords++ = (row << 21) | 0x40004098;
1011 *oamWords++ = CREDITS_RING_TILES;
1012 }
1013 for (row = 0; row < CREDITS_VISIBLE_ROWS; row++) {
1014 for (column = 0; column < CREDITS_COLUMNS; column++) {
1015 u32 tileIndex = (row * 3) * 8 + column * 4;
1016 *oamWords++ = (row * 8 + 16) | ((column * 32 + 24) << 16) | 0x40004000;
1017 *oamWords++ = tileIndex;
1018 }
1019 }
1020 for (row = 0; row < 8; row++) {
1021 *oamWords++ = 0x00c000c0;
1022 *oamWords++ = CREDITS_RING_TILES;
1023 }
1024 gFlash_Handler3 = 0;
1031 for (row = 0; row < CREDITS_RING_ROWS; row++)
1033 row * CREDITS_LINE_TILES, 1);
1034}
1035
1036/// Centers, right-aligns or left-aligns one credits line in a 192-pixel row.
1037/// Rasterizes its glyphs and shadow, packs 4-bit pixels and uploads 24 tiles
1038/// beginning at firstTile. Called by the line-rendering task and, for the blank
1039/// rows, by DisplayScroll_InitObjectTable. Returns -1 at the null end marker,
1040/// otherwise zero.
1041s32 DisplayScroll_DrawLine(const u8 *text, s32 firstTile, s32 alignment) {
1043 s32 startX = 0;
1044 s32 lineWidth = CREDITS_LINE_PIXELS;
1045 const u8 *font = gDisplayScroll_Font;
1046 s32 tileCount;
1047 s32 textAdvance;
1048 const u8 *sourceBytes;
1049 u8 *destination;
1050 u32 sourceValue;
1051 s32 glyphIndex;
1052 s32 glyphWidth;
1053 s32 row;
1054 s32 columnIndex;
1055 u32 glyphBits;
1056 u32 glyphMask;
1057
1058 /* FAKEMATCH: unused local; its 32 bytes are the native frame space no
1059 * instruction touches. Without it differ 4 on tbs-ja, tbs-en and tbs-de: sub
1060 * sp, #12 for #44 and the matching add. */
1061 UNUSED u32 unused[8];
1062
1063 if (text == NULL) {
1064 // BUG: the end marker is checked after allocation, leaking one line
1065 // buffer. MemFree rewinds this bump pool to the allocation's start.
1066#ifdef BUGFIX
1067 if (linePixels != NULL)
1068 MemFree(linePixels);
1069#endif
1070 return -1;
1071 }
1072 // The ninth raster row holds the shadow below this line. Carry it into
1073 // the next line before clearing the rest of the reused scratch buffer.
1075 Iwram_FillWords(linePixels, CREDITS_BUFFER_BYTES, 0);
1077 } else {
1078 Iwram_CopyWords(linePixels, linePixels + 0x800, 0x100);
1079 Iwram_FillWords(linePixels + 0x100, 0x800, 0);
1080 }
1081
1082 // Measure text with the actual credits font before choosing its start.
1083 // A previous character/pixel cursor split grew the frame 44 -> 48 bytes
1084 // and changed native registers; retain the shared byte cursors here.
1085 sourceBytes = text;
1086 textAdvance = 0;
1087 while ((sourceValue = *sourceBytes++) != 0) {
1088 if (sourceValue > 31)
1089 textAdvance += gDisplayScroll_GlyphWidths[sourceValue - 32];
1090 }
1091 if (alignment == 2)
1092 startX = lineWidth - textAdvance;
1093 else if (alignment == 1)
1094 startX = (lineWidth - textAdvance) / 2;
1095
1096 // Rasterize each glyph and its one-pixel shadow at the aligned start.
1097 sourceBytes = text;
1098 textAdvance = 0;
1099 while ((sourceValue = *text++) != 0) {
1100 if (sourceValue > 31) {
1101 glyphIndex = sourceValue - 32;
1102 sourceBytes = font + glyphIndex * 8;
1103 destination = linePixels + startX + textAdvance;
1104 for (row = 0; row < 8; row++) {
1105 glyphBits = *sourceBytes++;
1106 glyphMask = 0x80;
1107 for (columnIndex = 7; columnIndex >= 0; columnIndex--) {
1108 if (glyphBits & glyphMask) {
1109 destination[0x101] = 1;
1110 destination[0] = 15;
1111 }
1112 destination++;
1113 glyphMask >>= 1;
1114 }
1115 destination += CREDITS_RASTER_STRIDE - 8;
1116 }
1117 glyphWidth = 1;
1118 if (sourceValue > 31)
1119 glyphWidth = gDisplayScroll_GlyphWidths[glyphIndex];
1120 textAdvance += glyphWidth;
1121 }
1122 }
1123
1124 // Pack pairs of pixel indices into bytes, keeping the 256-pixel stride.
1125 tileCount = lineWidth / 8;
1126 sourceBytes = linePixels;
1127 destination = linePixels;
1128 for (row = 0; row < 8; row++) {
1129 for (columnIndex = 0; columnIndex < tileCount * 4; columnIndex++) {
1130 sourceValue = *sourceBytes++;
1131 sourceValue |= *sourceBytes++ << 4;
1132 *destination++ = sourceValue;
1133 }
1134 destination += CREDITS_RASTER_STRIDE - tileCount * 4;
1135 sourceBytes += CREDITS_RASTER_STRIDE - tileCount * 8;
1136 }
1137
1138 // Transpose raster rows into the tile ring used by the scrolling sprites.
1139 for (row = 0; row < tileCount; row++) {
1140 s32 tileIndex = firstTile + row;
1141 u32 *words = (u32 *)linePixels + row;
1142
1143 *(u32 *)(OBJ_VRAM0 + tileIndex * 32) = words[0x000];
1144 *(u32 *)(0x06010004 + tileIndex * 32) = words[0x040];
1145 *(u32 *)(0x06010008 + tileIndex * 32) = words[0x080];
1146 *(u32 *)(0x0601000c + tileIndex * 32) = words[0x0c0];
1147 *(u32 *)(0x06010010 + tileIndex * 32) = words[0x100];
1148 *(u32 *)(0x06010014 + tileIndex * 32) = words[0x140];
1149 *(u32 *)(0x06010018 + tileIndex * 32) = words[0x180];
1150 *(u32 *)(0x0601001c + tileIndex * 32) = words[0x1c0];
1151 }
1152 MemFree(linePixels);
1153 return 0;
1154}
u16 gFlashNumRemainingBytes
Which units are in a battle, and the Djinn recovery list.
BattleUnit_Recalculate, which recalculates a unit's stats.
The task scheduler: tasks, their order and the scheduler's state.
#define SCHEDULER_KEY_VBLANK
A task's order: the high byte picks the pass that runs it, the low byte ranks it within the pass (hig...
#define SCHEDULER_KEY_MAIN_LOOP
#define CREDITS_STAFF_TITLE
Definition credits.c:304
#define CREDITS_ARTWORK_LABEL
Definition credits.c:308
const u32 gDisplayScroll_SlideResources[]
Battle backgrounds shown in the credits; 0 clears the display.
Definition credits.c:82
#define CREDITS_RING_TILES
Definition credits.c:45
void Graphics_LoadCharacterBlockAndPalette(u32 resourceId, s32 alternate)
Loads a credits backdrop into one of the two tile/palette halves.
Definition credits.c:122
#define CREDITS_SOUND_DIRECTION_LABEL
Definition credits.c:306
void DisplayScroll_RenderEnteringLine(void)
A main-loop task scheduled by DisplayScroll_InitObjectTable: renders each entering line sixteen rows ...
Definition credits.c:961
#define CREDITS_COLUMNS
Definition credits.c:42
s32(*) PackedDecoder(const u8 *source, void *destination, u32 fill)
Definition credits.c:78
#define CREDITS_RING_BYTES
Definition credits.c:46
#define CREDITS_BORDER_SPRITES
Definition credits.c:50
void DisplayScroll_BuildHblankWordTable(u32 *destination)
Builds the 512 tilemap words surrounding a sliding credits backdrop: blank margins,...
Definition credits.c:159
#define CREDITS_LAST_LINE_POSITION
Definition credits.c:289
#define CREDITS_OAM_ENTRIES
Definition credits.c:51
void DisplayScroll_InitObjectTable(void)
Allocates the credits sprites, builds the blank border and text rows, clears the tile ring and schedu...
Definition credits.c:983
u16 gFlash_Handler3
Credits scroll position in pixels, in the low half of a flash work cell.
#define CREDITS_FACES_SUBTITLE
Definition credits.c:305
void Graphics_ClearCharacterBlockAndPalette(s32 alternate)
Fills 30 KB of 256-color tiles with color 1 and clears 128 palette colors.
Definition credits.c:57
const void * gDisplayScroll_LineTable[]
Credits text, one row per line, terminated by 0.
Definition credits.c:313
#define CREDITS_LINE_TILES
Definition credits.c:44
#define CREDITS_RING_ROWS
Definition credits.c:43
#define CREDITS_VISIBLE_ROWS
Definition credits.c:41
#define CREDITS_BUFFER_BYTES
Definition credits.c:47
static const u8 sBlankCreditLine[]
Blank credits line.
Definition credits.c:294
#define CREDITS_RASTER_STRIDE
Definition credits.c:48
#define CREDITS_LINE_PIXELS
Definition credits.c:40
#define CREDITS_GRAPHICS_SUPPORT_LABEL
Definition credits.c:307
s32 DisplayScroll_RunSlideshow(void)
Crossfades the credits backdrop sequence through alternating tile banks while the staff names scroll ...
Definition credits.c:204
#define SCROLL_OBJECTS
Definition credits.c:287
#define CREDITS_END_OF_TEXT
Definition credits.c:290
void DisplayScroll_StepPositionEveryFourFrames(void)
A VBlank task of the credits slideshow: drifts both backdrops together, keeping their horizontal offs...
Definition credits.c:191
s32 DisplayScroll_DrawLine(const u8 *text, s32 firstTile, s32 alignment)
Centers, right-aligns or left-aligns one credits line in a 192-pixel row.
Definition credits.c:1041
void DisplayScroll_UpdateObjects(void)
A VBlank task scheduled by DisplayScroll_InitObjectTable: maps the visible sixteen rows onto the tile...
Definition credits.c:933
#define CREDITS_DECODER_HEAP_SLOT
Definition credits.c:49
The engine calls the debug menus import, and their palette swatch tiles.
DMA channel registers, and the DMA and CPU fills.
#define Dma_Fill32Cell(cell, value, destination, size)
Dma_Fill32 through the caller's own volatile word cell, so a function that fills several blocks keeps...
Definition dma.h:42
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).
s32 GameFlag_TestFar(s32 flag)
s32 GameFlag_SetBitFar(s32 flag)
Game flags, named where their meaning is shown.
#define FLAG_SCENE_TEMP_00
Definition flags.h:713
u32 gFlash_Handler0
const struct FlashType * gFlash
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
The frame loop's globals: lag counts, the CPU load display and the VBlank flags.
volatile u8 gCpuLoadDisplayEnabled
Debug: WaitFrames measures the CPU load into gCpuLoadPeak when set.
u32 gFrameTick
Counted up by every VBlank.
u8 gOamCopyEnabled
The VBlank handler copies the OAM list only while it is set; scenes clear it to keep their own sprite...
volatile u8 gIdleSleepEnabled
Sleep after three idle minutes.
The staff credits font's advance widths in pixels, characters 0x20 to 0x7f, beside the font (credits....
const u8 gDisplayScroll_GlyphWidths[96]
Definition glyph_widths.h:7
The screen blend's globals and the graphics routines.
const u8 gDisplayScroll_Font[]
u8 BattleEffect_ExpandCodeSize[]
const u8 BattleEffect_Expand[]
void * Runtime_BumpAllocateAlternatePool(s32 size)
As MemAlloc, but tries EWRAM first.
Definition heap.c:140
The heap's work slots and HeapState.
The hardware's I/O registers and their bits, as pret names them.
#define BGCNT_CHAR_BASE(block)
Definition io_reg.h:25
#define BGCNT_256_COLORS
Definition io_reg.h:27
#define BGCNT_PRIORITY(n)
Definition io_reg.h:24
#define BG_SCREEN_BLOCK(n)
Definition io_reg.h:167
#define REG_BG3CNT
Definition io_reg.h:22
#define BLDCNT_TGT1_BG2
Definition io_reg.h:125
#define BG_CHAR_BLOCK(n)
Definition io_reg.h:166
#define OAM
Definition io_reg.h:239
#define OAM_SIZE
OAM's size in bytes: 128 sprites of 8 bytes.
Definition io_reg.h:241
#define OBJ_VRAM0
Sprite tile memory, as pret names it: the 32 KB from 0x06010000.
Definition io_reg.h:170
@ DISPCNT_OBJ_ON
Definition io_reg.h:44
@ DISPCNT_BG3_ON
Definition io_reg.h:43
@ DISPCNT_OBJ_1D_MAP
Definition io_reg.h:39
@ DISPCNT_BG2_ON
Definition io_reg.h:42
#define REG_DISPCNT
Definition io_reg.h:9
#define BLDCNT_EFFECT_BLEND
weighted by REG_BLDALPHA
Definition io_reg.h:131
#define REG_DMA3
Definition io_reg.h:153
#define BLDCNT_TGT2_BG3
Definition io_reg.h:137
#define BGCNT_SCREEN_BASE(block)
Definition io_reg.h:28
#define REG_BG2CNT
Definition io_reg.h:21
#define DMA_COPY_WORDS(n)
Definition io_reg.h:226
#define REG_BLDALPHA
Definition io_reg.h:142
#define BG_PLTT
Definition io_reg.h:157
#define REG_BLDCNT
Definition io_reg.h:119
#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...
Io_Write16, a 16-bit write to a register or memory.
#define Io_Write16(v, reg)
Writes a value to a 16-bit register or memory location.
Definition iowrite.h:14
The IWRAM call layer: the routines the game keeps resident in IWRAM, each at its fixed address,...
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
The map layers' scroll work and the background scroll values.
struct BgScroll gBgScroll[]
The heaps: allocating and freeing blocks.
void Runtime_ReleaseHeapBlock(s32 slot)
void MemFree(void *buffer)
The reel game's title lettering.
Copying ARM routines to RAM to run them there.
#define RamCode_LoadSlot(slot, code, bytes)
Allocates a work-slot copy; release it with Runtime_ReleaseHeapBlock.
Definition ramcode.h:26
Resource numbers, named where their contents are known.
char ResourceId_SuhallaGateBackdrop
char ResourceId_TolbiShipInteriorsBackdrop
char ResourceId_TunnelRuinsBackdrop
char ResourceId_ImilFuchinFallsBackdrop
char ResourceId_LamakanDesertBackdrop
char ResourceId_VenusLighthouseBackdrop
char ResourceId_ValeStormBackdrop
char ResourceId_TretTreeBranchBackdrop
char ResourceId_ForestBackdrop
char ResourceId_VioletSkyBackdrop
char ResourceId_TolbiShipDeckBackdrop
char ResourceId_ColossoBackdrop
char ResourceId_MercuryLighthouseBackdrop
char ResourceId_AltinPeakBackdrop
char ResourceId_VenusLighthouseAerieBackdrop
char ResourceId_SolSanctumBackdrop
char ResourceId_MogallForestBackdrop
char ResourceId_SnowfieldBackdrop
char ResourceId_BeachBackdrop
char ResourceId_CrossboneIsleCaveBackdrop
char ResourceId_DuskCloudsBackdrop
char ResourceId_VenusLighthouseAerieStormBackdrop
char ResourceId_PirateShipBackdrop
char ResourceId_TretTreeInteriorsBackdrop
char ResourceId_GomaCaveBackdrop
char ResourceId_GrasslandBackdrop
char ResourceId_AltmillerCaveBackdrop
char ResourceId_MercuryLighthouseAerieBackdrop
char ResourceId_InteriorBackdrop
char ResourceId_BabiLighthouseBackdrop
char ResourceId_SuhallaDesertBackdrop
char ResourceId_KolimaForestBackdrop
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
void Scheduler_ResetTaskTable(void)
Empties the task table: every slot gets no routine, order 0xffff (sorted last) and no flags.
Definition scheduler.c:19
#define NULL
Definition bilibin.h:6
void * gWorkSlot[]
STATIC_ASSERT, a compile-time check that emits nothing.
#define STATIC_ASSERT(condition)
C89 permits repeated extern declarations of the same array.
One eight-byte OAM entry in the credits' private sprite buffer.
Definition credits.c:263
u32 attr01
Attribute 0 in the low half, attribute 1 in the high half.
Definition credits.c:264
u32 attr2
Attribute 2 in the low half; the unused high half stays zero.
Definition credits.c:265
void * Resource_GetTableEntry(s32 index)
Returns the ROM address of resource index from the resource directory.
Definition system.c:150
The system's routines and globals: interrupts, BIOS sound bias, random numbers and sleep.
u8 gDebugTextEnabled
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
void DebugText_Clear(void)
Blanks the debug text screen, homes the cursor and points BG0 at it.
Definition text.c:170
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