summaryrefslogtreecommitdiff
path: root/arm9/src/text.c
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/src/text.c')
-rw-r--r--arm9/src/text.c564
1 files changed, 564 insertions, 0 deletions
diff --git a/arm9/src/text.c b/arm9/src/text.c
new file mode 100644
index 00000000..6207d913
--- /dev/null
+++ b/arm9/src/text.c
@@ -0,0 +1,564 @@
+#include "text.h"
+#include "heap.h"
+#include "string16.h"
+#include "MI_memory.h"
+
+const struct FontInfo *gFonts = NULL;
+
+u16 UNK_021C5734[0x100];
+u32 UNK_021C5714[8];
+u8 UNK_021C570C[8];
+
+extern u32 FUN_0200CA7C(void (*func)(u32, struct TextPrinter *), struct TextPrinter *printer, u32 param2);
+
+extern struct TextPrinter *FUN_0201B6C8(void);
+extern void FUN_0200CAB4(u32 param0);
+
+extern void FUN_0201C1A8(struct TextPrinter *printer);
+extern void CopyWindowToVram(u32 windowId);
+
+extern u32 FontFunc(u8 fontId, struct TextPrinter *printer);
+
+extern void *FUN_02006BB0(u32 param0, u32 param1, u32 param2, struct TextPrinter **param3, u32 param4);
+
+extern u32 FUN_0201AB0C(u32 windowId);
+extern void FUN_02019658(u32 param0, u32 param1, u32 param2, u32 param3, u32 param4, u32 param5, u32 param6, u32 param7, u32 param8, u32 param9);
+
+
+THUMB_FUNC void SetFontsPointer(const struct FontInfo *fonts)
+{
+ gFonts = fonts;
+}
+
+THUMB_FUNC u8 FUN_0201BCC8(void (*func)(u32, struct TextPrinter *), struct TextPrinter *printer, u32 param2)
+{
+ u32 *r4 = UNK_021C5714;
+ s32 i;
+ for (i = 0; i < 8; i++, r4++)
+ {
+ if (r4[0] != 0)
+ {
+ continue;
+ }
+ UNK_021C5714[i] = FUN_0200CA7C(func, printer, param2);
+ if (UNK_021C5714[i] != 0)
+ {
+ break;
+ }
+ i = 8;
+ break;
+ }
+ return (u8)i;
+}
+
+THUMB_FUNC void FUN_0201BCFC(u32 param0)
+{
+ GF_ASSERT(param0 < 8);
+ GF_ASSERT(UNK_021C5714[param0] != 0);
+ if (param0 >= 8)
+ {
+ return;
+ }
+ if (UNK_021C5714[param0] == 0)
+ {
+ return;
+ }
+ struct TextPrinter *printer = FUN_0201B6C8();
+ if (printer)
+ {
+ FUN_0201C238(printer);
+ FreeToHeap((void *)printer);
+ }
+ FUN_0200CAB4(UNK_021C5714[param0]);
+ UNK_021C5714[param0] = 0;
+}
+
+THUMB_FUNC BOOL FUN_0201BD44(u32 param0)
+{
+ return UNK_021C5714[param0] ? TRUE : FALSE;
+}
+
+THUMB_FUNC void FUN_0201BD5C(void)
+{
+ for (s32 i = 0; i < 8; i++)
+ {
+ UNK_021C5714[i] = 0;
+ }
+}
+
+THUMB_FUNC u8 FUN_0201BD70(u32 param0)
+{
+ return (u8)FUN_0201BD44(param0);
+}
+
+THUMB_FUNC void FUN_0201BD7C(u32 param0)
+{
+ FUN_0201BCFC(param0);
+}
+
+THUMB_FUNC u16 AddTextPrinterParameterized(u32 windowId, u8 fontId, const u16 *str, u32 x, u32 y, u32 speed, u8 (*callback)(struct TextPrinterTemplate *, u16))
+{
+ struct TextPrinterTemplate printerTemplate;
+
+ printerTemplate.windowId = windowId;
+ printerTemplate.currentChar = str;
+ printerTemplate.fontId = fontId;
+ printerTemplate.x = (u8)x;
+ printerTemplate.y = (u8)y;
+ printerTemplate.currentX = (u8)x;
+ printerTemplate.currentY = (u8)y;
+ printerTemplate.letterSpacing = gFonts[fontId].letterSpacing;
+ printerTemplate.lineSpacing = gFonts[fontId].lineSpacing;
+ printerTemplate.unk = gFonts[fontId].unk;
+ printerTemplate.fgColor = gFonts[fontId].fgColor;
+ printerTemplate.bgColor = gFonts[fontId].bgColor;
+ printerTemplate.shadowColor = gFonts[fontId].shadowColor;
+ printerTemplate.unk2 = 0;
+ printerTemplate.unk3 = 0;
+ printerTemplate.unk4 = 255;
+ return AddTextPrinter(&printerTemplate, speed, callback);
+}
+
+THUMB_FUNC u16 AddTextPrinterParameterized2(u32 windowId, u8 fontId, const u16 *str, u32 x, u32 y, u32 speed, u32 colors, u8 (*callback)(struct TextPrinterTemplate *, u16))
+{
+ struct TextPrinterTemplate printerTemplate;
+
+ printerTemplate.windowId = windowId;
+ printerTemplate.currentChar = str;
+ printerTemplate.fontId = fontId;
+ printerTemplate.x = (u8)x;
+ printerTemplate.y = (u8)y;
+ printerTemplate.currentX = (u8)x;
+ printerTemplate.currentY = (u8)y;
+ printerTemplate.letterSpacing = gFonts[fontId].letterSpacing;
+ printerTemplate.lineSpacing = gFonts[fontId].lineSpacing;
+ printerTemplate.unk = gFonts[fontId].unk;
+ printerTemplate.fgColor = (u8)(colors >> 16);
+ printerTemplate.shadowColor = (u8)(colors >> 8);
+ printerTemplate.bgColor = (u8)colors;
+ printerTemplate.unk2 = 0;
+ printerTemplate.unk3 = 0;
+ printerTemplate.unk4 = 255;
+ return AddTextPrinter(&printerTemplate, speed, callback);
+}
+
+THUMB_FUNC u16 AddTextPrinterParameterized3(u32 windowId, u8 fontId, const u16 *str, u32 x, u32 y, u32 speed, u32 colors, u32 letterSpacing, u32 lineSpacing, u8 (*callback)(struct TextPrinterTemplate *, u16))
+{
+ struct TextPrinterTemplate printerTemplate;
+
+ printerTemplate.windowId = windowId;
+ printerTemplate.currentChar = str;
+ printerTemplate.fontId = fontId;
+ printerTemplate.x = (u8)x;
+ printerTemplate.y = (u8)y;
+ printerTemplate.currentX = (u8)x;
+ printerTemplate.currentY = (u8)y;
+ printerTemplate.letterSpacing = (u8)letterSpacing;
+ printerTemplate.lineSpacing = (u8)lineSpacing;
+ printerTemplate.unk = gFonts[fontId].unk;
+ printerTemplate.fgColor = (u8)(colors >> 16);
+ printerTemplate.shadowColor = (u8)(colors >> 8);
+ printerTemplate.bgColor = (u8)colors;
+ printerTemplate.unk2 = 0;
+ printerTemplate.unk3 = 0;
+ printerTemplate.unk4 = 255;
+ return AddTextPrinter(&printerTemplate, speed, callback);
+}
+
+THUMB_FUNC u16 AddTextPrinter(struct TextPrinterTemplate *printerTemplate, u32 speed, u8 (*callback)(struct TextPrinterTemplate *, u16))
+{
+ if (!gFonts)
+ return 0xff;
+
+ struct TextPrinter *printer = (struct TextPrinter *)AllocFromHeap(0, sizeof(struct TextPrinter));
+
+ printer->active = TRUE;
+ printer->state = 0;
+ printer->textSpeedBottom = (u8)speed;
+ printer->delayCounter = 0;
+ printer->scrollDistance = 0;
+ printer->Unk29 = 0;
+
+ for (s32 i = 0; i < 7; i++)
+ {
+ printer->subStructFields[i] = 0;
+ }
+
+ printer->printerTemplate = *printerTemplate;
+ printer->printerTemplate.currentChar = String_c_str((struct String *)printer->printerTemplate.currentChar); //TODO clean up
+ printer->callback = callback;
+ UNK_021C570C[0] = 0;
+ FUN_0201C1A8(printer);
+ if (speed != 0xff && speed != 0)
+ {
+ printer->textSpeedBottom += 0xff;
+ printer->textSpeedTop = 1;
+ printer->minLetterSpacing = FUN_0201BCC8(RunTextPrinter, printer, 1);
+ return printer->minLetterSpacing;
+ }
+ else
+ {
+ u32 j = 0;
+ printer->textSpeedBottom = 0;
+ printer->textSpeedTop = 0;
+ GenerateFontHalfRowLookupTable(printerTemplate->fgColor, printerTemplate->bgColor, printerTemplate->shadowColor);
+ for (; j < 0x400; ++j)
+ {
+ if (RenderFont(printer) == 1)
+ {
+ break;
+ }
+ }
+ if (speed != 0xff)
+ {
+ CopyWindowToVram(printer->printerTemplate.windowId); // CopyWindowToVram?
+ }
+ FUN_0201C238(printer);
+ FreeToHeap((void *)printer);
+ return 8;
+ }
+}
+
+THUMB_FUNC void RunTextPrinter(u32 param0, struct TextPrinter *printer)
+{
+#pragma unused(param0)
+ if (UNK_021C570C[0] == 0)
+ {
+ if (printer->Unk29 == 0)
+ {
+ printer->Unk2A = 0;
+ GenerateFontHalfRowLookupTable(printer->printerTemplate.fgColor, printer->printerTemplate.bgColor, printer->printerTemplate.shadowColor);
+ u32 temp = RenderFont(printer);
+ switch (temp)
+ {
+ case 0:
+ CopyWindowToVram(printer->printerTemplate.windowId);
+ //fallthrough
+ case 3:
+ if (printer->callback == NULL)
+ {
+ return;
+ }
+ printer->Unk29 = printer->callback(&printer->printerTemplate, printer->Unk2A);
+ return;
+ case 1:
+ FUN_0201BCFC(printer->minLetterSpacing);
+ return;
+ default:
+ return;
+ }
+ }
+ else
+ {
+ printer->Unk29 = printer->callback(&printer->printerTemplate, printer->Unk2A);
+ }
+ }
+}
+
+THUMB_FUNC u32 RenderFont(struct TextPrinter *printer)
+{
+ u32 ret;
+ while (TRUE)
+ {
+ ret = FontFunc(printer->printerTemplate.fontId, printer);
+ if (ret != 2)
+ {
+ return ret;
+ }
+ }
+}
+
+#ifdef NONMATCHING
+THUMB_FUNC void GenerateFontHalfRowLookupTable(u8 fgColor, u8 bgColor, u8 shadowColor)
+{
+ u32 fg12, bg12, shadow12;
+ u32 temp;
+
+ u16 *current = UNK_021C570C;
+
+ bg12 = bgColor << 12;
+ fg12 = fgColor << 12;
+ shadow12 = shadowColor << 12;
+
+ temp = (bgColor << 8) | (bgColor << 4) | bgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (fgColor << 8) | (bgColor << 4) | bgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (shadowColor << 8) | (bgColor << 4) | bgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (bgColor << 8) | (fgColor << 4) | bgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (fgColor << 8) | (fgColor << 4) | bgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (shadowColor << 8) | (fgColor << 4) | bgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (bgColor << 8) | (shadowColor << 4) | bgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (fgColor << 8) | (shadowColor << 4) | bgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (shadowColor << 8) | (shadowColor << 4) | bgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (bgColor << 8) | (bgColor << 4) | fgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (fgColor << 8) | (bgColor << 4) | fgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (shadowColor << 8) | (bgColor << 4) | fgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (bgColor << 8) | (fgColor << 4) | fgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (fgColor << 8) | (fgColor << 4) | fgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (shadowColor << 8) | (fgColor << 4) | fgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (bgColor << 8) | (shadowColor << 4) | fgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (fgColor << 8) | (shadowColor << 4) | fgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (shadowColor << 8) | (shadowColor << 4) | fgColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (bgColor << 8) | (bgColor << 4) | shadowColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (fgColor << 8) | (bgColor << 4) | shadowColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (shadowColor << 8) | (bgColor << 4) | shadowColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (bgColor << 8) | (fgColor << 4) | shadowColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (fgColor << 8) | (fgColor << 4) | shadowColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (shadowColor << 8) | (fgColor << 4) | shadowColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (bgColor << 8) | (shadowColor << 4) | shadowColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (fgColor << 8) | (shadowColor << 4) | shadowColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+
+ temp = (shadowColor << 8) | (shadowColor << 4) | shadowColor;
+ *(current++) = (bg12) | temp;
+ *(current++) = (fg12) | temp;
+ *(current++) = (shadow12) | temp;
+}
+#else
+THUMB_FUNC void GenerateFontHalfRowLookupTable(u8 fgColor, u8 bgColor, u8 shadowColor) //TODO use asm preprocessor
+{
+ asm {
+ // push {r3-r7, lr}
+ sub sp, #0x30
+ ldr r3, =UNK_021C570C
+ mov r5, #0x0
+ str r5, [sp, #0x20]
+ str r0, [sp, #0x24]
+ str r2, [sp, #0x28]
+ str r1, [sp, #0x2c]
+ strh r1, [r3, #0x6]
+ strh r0, [r3, #0x2]
+ add r0, sp, #0x20
+ strh r2, [r3, #0x4]
+ str r5, [sp, #0x14]
+ str r0, [sp, #0x8]
+ mov r12, r0
+ mov lr, r0
+ str r0, [sp, #0x18]
+ _0201C07E:
+ mov r0, #0x0
+ str r0, [sp, #0x10]
+ ldr r0, [sp, #0x18]
+ str r0, [sp, #0x4]
+ ldr r0, [sp, #0x8]
+ ldr r0, [r0, #0x0]
+ str r0, [sp, #0x1c]
+ _0201C08C:
+ mov r0, #0x0
+ str r0, [sp, #0xc]
+ mov r0, lr
+ str r0, [sp, #0x0]
+ ldr r0, [sp, #0x4]
+ ldr r0, [r0, #0x0]
+ lsl r7, r0, #0x4
+ _0201C09A:
+ ldr r0, [sp, #0x0]
+ mov r3, #0x0
+ ldr r0, [r0, #0x0]
+ mov r4, r12
+ lsl r6, r0, #0x8
+ _0201C0A4:
+ ldr r0, [r4, #0x0]
+ add r1, r7, #0x0
+ lsl r0, r0, #0xc
+ orr r0, r6
+ orr r1, r0
+ ldr r0, [sp, #0x1c]
+ add r3, r3, #0x1
+ add r2, r0, #0x0
+ orr r2, r1
+ lsl r1, r5, #0x1
+ ldr r0, =UNK_021C5734
+ add r5, r5, #0x1
+ add r4, r4, #0x4
+ strh r2, [r0, r1]
+ cmp r3, #0x4
+ blt _0201C0A4
+ ldr r0, [sp, #0x0]
+ add r0, r0, #0x4
+ str r0, [sp, #0x0]
+ ldr r0, [sp, #0xc]
+ add r0, r0, #0x1
+ str r0, [sp, #0xc]
+ cmp r0, #0x4
+ blt _0201C09A
+ ldr r0, [sp, #0x4]
+ add r0, r0, #0x4
+ str r0, [sp, #0x4]
+ ldr r0, [sp, #0x10]
+ add r0, r0, #0x1
+ str r0, [sp, #0x10]
+ cmp r0, #0x4
+ blt _0201C08C
+ ldr r0, [sp, #0x8]
+ add r0, r0, #0x4
+ str r0, [sp, #0x8]
+ ldr r0, [sp, #0x14]
+ add r0, r0, #0x1
+ str r0, [sp, #0x14]
+ cmp r0, #0x4
+ blt _0201C07E
+ add sp, #0x30
+ // pop {r3-r7, pc}
+ }
+}
+#endif
+
+THUMB_FUNC void DecompressGlyphTile(const u16 *src, u16 *dst)
+{
+ dst[0] = UNK_021C5734[(u32)src[0] >> 8];
+ dst[1] = UNK_021C5734[(u8)src[0]];
+ dst[2] = UNK_021C5734[(u32)src[1] >> 8];
+ dst[3] = UNK_021C5734[(u8)src[1]];
+ dst[4] = UNK_021C5734[(u32)src[2] >> 8];
+ dst[5] = UNK_021C5734[(u8)src[2]];
+ dst[6] = UNK_021C5734[(u32)src[3] >> 8];
+ dst[7] = UNK_021C5734[(u8)src[3]];
+ dst[8] = UNK_021C5734[(u32)src[4] >> 8];
+ dst[9] = UNK_021C5734[(u8)src[4]];
+ dst[10] = UNK_021C5734[(u32)src[5] >> 8];
+ dst[11] = UNK_021C5734[(u8)src[5]];
+ dst[12] = UNK_021C5734[(u32)src[6] >> 8];
+ dst[13] = UNK_021C5734[(u8)src[6]];
+ dst[14] = UNK_021C5734[(u32)src[7] >> 8];
+ dst[15] = UNK_021C5734[(u8)src[7]];
+}
+
+THUMB_FUNC void FUN_0201C1A8(struct TextPrinter *printer)
+{
+ printer->Unk2C = NULL;
+}
+
+THUMB_FUNC void *FUN_0201C1B0(void)
+{
+ void *res = AllocFromHeap(0, sizeof(struct TextPrinter) * 32);
+ struct TextPrinter *var;
+ void *tmp = FUN_02006BB0(14, 5, 0, &var, 0);
+ MIi_CpuCopy32((void *)var->printerTemplate.Unk20, res, sizeof(struct TextPrinter) * 32); //todo Unk20 can't be right here
+ FreeToHeap(tmp);
+ return res;
+}
+
+THUMB_FUNC void FUN_0201C1EC(struct TextPrinter *printer, u32 param1, u32 param2, u32 param3)
+{
+#pragma unused (param1, param2)
+ u32 windowId = printer->printerTemplate.windowId;
+ if (printer->Unk2C == NULL)
+ {
+ printer->Unk2C = FUN_0201C1B0();
+ }
+ u32 r6 = (u32)printer->Unk2C + param3 * (sizeof(struct TextPrinter) * 8);
+ u32 r2 = ((FUN_0201AB0C(windowId) - 3) << 0x13) >> 0x10;
+ FUN_02019658(windowId, r6, 0, 0, 24, 32, r2, 0, 24, 32);
+}
+
+THUMB_FUNC void FUN_0201C238(struct TextPrinter *printer)
+{
+ if (printer->Unk2C == NULL)
+ {
+ return;
+ }
+ FreeToHeap(printer->Unk2C);
+ printer->Unk2C = NULL;
+}