pokeemerald/gflib/text.c

2543 lines
73 KiB
C
Raw Normal View History

2017-03-07 14:44:41 +01:00
#include "global.h"
2018-01-24 22:45:37 +01:00
#include "battle.h"
2017-03-07 14:44:41 +01:00
#include "main.h"
2018-01-24 22:45:37 +01:00
#include "m4a.h"
2017-03-07 14:44:41 +01:00
#include "palette.h"
2018-01-24 22:45:37 +01:00
#include "sound.h"
2018-02-28 13:07:58 +01:00
#include "constants/songs.h"
2017-03-07 14:44:41 +01:00
#include "string_util.h"
2017-03-30 02:02:15 +02:00
#include "window.h"
2017-09-23 03:26:37 +02:00
#include "text.h"
2018-02-28 13:07:58 +01:00
#include "blit.h"
2018-12-24 00:02:29 +01:00
#include "menu.h"
#include "dynamic_placeholder_text_util.h"
2017-03-07 14:44:41 +01:00
2017-09-02 00:21:11 +02:00
EWRAM_DATA struct TextPrinter gTempTextPrinter = {0};
EWRAM_DATA struct TextPrinter gTextPrinters[NUM_TEXT_PRINTERS] = {0};
2017-03-28 02:30:49 +02:00
2017-03-28 06:20:55 +02:00
static u16 gFontHalfRowLookupTable[0x51];
static u16 gLastTextBgColor;
static u16 gLastTextFgColor;
static u16 gLastTextShadowColor;
2017-03-07 14:44:41 +01:00
2017-03-28 06:20:55 +02:00
const struct FontInfo *gFonts;
u8 gUnknown_03002F84;
2018-11-05 21:42:12 +01:00
struct Struct_03002F90 gUnknown_03002F90;
2017-09-22 05:43:13 +02:00
TextFlags gTextFlags;
2017-03-28 02:30:49 +02:00
2018-11-21 21:58:35 +01:00
const u8 gFontHalfRowOffsets[] =
{
2018-01-24 22:45:37 +01:00
0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00,
2017-03-28 02:30:49 +02:00
0x09, 0x0A, 0x0B, 0x09, 0x0C, 0x0D, 0x0E, 0x0C, 0x0F, 0x10, 0x11, 0x0F, 0x09, 0x0A, 0x0B, 0x09,
0x12, 0x13, 0x14, 0x12, 0x15, 0x16, 0x17, 0x15, 0x18, 0x19, 0x1A, 0x18, 0x12, 0x13, 0x14, 0x12,
2018-01-24 22:45:37 +01:00
0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00,
2017-03-28 02:30:49 +02:00
0x1B, 0x1C, 0x1D, 0x1B, 0x1E, 0x1F, 0x20, 0x1E, 0x21, 0x22, 0x23, 0x21, 0x1B, 0x1C, 0x1D, 0x1B,
0x24, 0x25, 0x26, 0x24, 0x27, 0x28, 0x29, 0x27, 0x2A, 0x2B, 0x2C, 0x2A, 0x24, 0x25, 0x26, 0x24,
2018-01-24 22:45:37 +01:00
0x2D, 0x2E, 0x2F, 0x2D, 0x30, 0x31, 0x32, 0x30, 0x33, 0x34, 0x35, 0x33, 0x2D, 0x2E, 0x2F, 0x2D,
2017-03-28 02:30:49 +02:00
0x1B, 0x1C, 0x1D, 0x1B, 0x1E, 0x1F, 0x20, 0x1E, 0x21, 0x22, 0x23, 0x21, 0x1B, 0x1C, 0x1D, 0x1B,
0x36, 0x37, 0x38, 0x36, 0x39, 0x3A, 0x3B, 0x39, 0x3C, 0x3D, 0x3E, 0x3C, 0x36, 0x37, 0x38, 0x36,
2018-01-24 22:45:37 +01:00
0x3F, 0x40, 0x41, 0x3F, 0x42, 0x43, 0x44, 0x42, 0x45, 0x46, 0x47, 0x45, 0x3F, 0x40, 0x41, 0x3F,
2017-03-28 02:30:49 +02:00
0x48, 0x49, 0x4A, 0x48, 0x4B, 0x4C, 0x4D, 0x4B, 0x4E, 0x4F, 0x50, 0x4E, 0x48, 0x49, 0x4A, 0x48,
0x36, 0x37, 0x38, 0x36, 0x39, 0x3A, 0x3B, 0x39, 0x3C, 0x3D, 0x3E, 0x3C, 0x36, 0x37, 0x38, 0x36,
2018-01-24 22:45:37 +01:00
0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00,
2017-03-28 02:30:49 +02:00
0x09, 0x0A, 0x0B, 0x09, 0x0C, 0x0D, 0x0E, 0x0C, 0x0F, 0x10, 0x11, 0x0F, 0x09, 0x0A, 0x0B, 0x09,
0x12, 0x13, 0x14, 0x12, 0x15, 0x16, 0x17, 0x15, 0x18, 0x19, 0x1A, 0x18, 0x12, 0x13, 0x14, 0x12,
2018-01-24 22:45:37 +01:00
0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00
2017-03-28 02:30:49 +02:00
};
const u8 gDownArrowTiles[] = INCBIN_U8("graphics/fonts/down_arrow.4bpp");
const u8 gDarkDownArrowTiles[] = INCBIN_U8("graphics/fonts/down_arrow_RS.4bpp");
const u8 gUnusedFRLGBlankedDownArrow[] = INCBIN_U8("graphics/fonts/unused_frlg_blanked_down_arrow.4bpp");
const u8 gUnusedFRLGDownArrow[] = INCBIN_U8("graphics/fonts/unused_frlg_down_arrow.4bpp");
2017-03-28 02:30:49 +02:00
const u8 gDownArrowYCoords[] = { 0x0, 0x1, 0x2, 0x1 };
const u8 gWindowVerticalScrollSpeeds[] = { 0x1, 0x2, 0x4, 0x0 };
2018-11-21 21:58:35 +01:00
const struct GlyphWidthFunc gGlyphWidthFuncs[] =
{
2017-03-28 02:30:49 +02:00
{ 0x0, GetGlyphWidthFont0 },
{ 0x1, GetGlyphWidthFont1 },
{ 0x2, GetGlyphWidthFont2 },
{ 0x3, GetGlyphWidthFont2 },
{ 0x4, GetGlyphWidthFont2 },
{ 0x5, GetGlyphWidthFont2 },
{ 0x6, GetGlyphWidthFont6 },
{ 0x7, GetGlyphWidthFont7 },
{ 0x8, GetGlyphWidthFont8 }
};
2018-11-21 21:58:35 +01:00
const struct KeypadIcon gKeypadIcons[] =
{
2017-03-28 02:30:49 +02:00
{ 0x0, 0x8, 0xC },
{ 0x1, 0x8, 0xC },
{ 0x2, 0x10, 0xC },
{ 0x4, 0x10, 0xC },
{ 0x6, 0x18, 0xC },
{ 0x9, 0x18, 0xC },
{ 0xC, 0x8, 0xC },
{ 0xD, 0x8, 0xC },
{ 0xE, 0x8, 0xC },
{ 0xF, 0x8, 0xC },
{ 0x20, 0x8, 0xC },
{ 0x21, 0x8, 0xC },
{ 0x22, 0x8, 0xC }
};
const u8 gKeypadIconTiles[] = INCBIN_U8("graphics/fonts/keypad_icons.4bpp");
2017-03-08 21:44:44 +01:00
2018-11-21 21:58:35 +01:00
const struct FontInfo gFontInfos[] =
{
2017-03-28 02:30:49 +02:00
{ Font0Func, 0x5, 0xC, 0x0, 0x0, 0x0, 0x2, 0x1, 0x3 },
{ Font1Func, 0x6, 0x10, 0x0, 0x0, 0x0, 0x2, 0x1, 0x3 },
{ Font2Func, 0x6, 0xE, 0x0, 0x0, 0x0, 0x2, 0x1, 0x3 },
{ Font3Func, 0x6, 0xE, 0x0, 0x0, 0x0, 0x2, 0x1, 0x3 },
{ Font4Func, 0x6, 0xE, 0x0, 0x0, 0x0, 0x2, 0x1, 0x3 },
{ Font5Func, 0x6, 0xE, 0x0, 0x0, 0x0, 0x2, 0x1, 0x3 },
{ Font6Func, 0x8, 0x10, 0x0, 0x8, 0x0, 0x2, 0x1, 0x3 },
{ Font7Func, 0x5, 0x10, 0x0, 0x0, 0x0, 0x2, 0x1, 0x3 },
{ Font8Func, 0x5, 0x8, 0x0, 0x0, 0x0, 0x2, 0x1, 0x3 },
{ NULL, 0x8, 0x8, 0x0, 0x0, 0x0, 0x1, 0x2, 0xF }
};
2017-03-07 14:44:41 +01:00
2018-11-21 21:58:35 +01:00
const u8 gMenuCursorDimensions[][2] =
{
2017-03-28 02:30:49 +02:00
{ 0x8, 0xC },
{ 0x8, 0xF },
{ 0x8, 0xE },
{ 0x8, 0xE },
{ 0x8, 0xE },
{ 0x8, 0xE },
{ 0x8, 0x10 },
{ 0x8, 0xF },
{ 0x8, 0x8 },
{ 0x0, 0x0 }
};
const u16 gFont9JapaneseGlyphs[] = INCBIN_U16("graphics/fonts/font9.hwjpnfont");
2017-03-28 02:30:49 +02:00
extern const u16 gFont8LatinGlyphs[];
extern const u8 gFont8LatinGlyphWidths[];
extern const u16 gFont0LatinGlyphs[];
extern const u8 gFont0LatinGlyphWidths[];
extern const u16 gFont7LatinGlyphs[];
extern const u8 gFont7LatinGlyphWidths[];
extern const u16 gFont2LatinGlyphs[];
extern const u8 gFont2LatinGlyphWidths[];
extern const u16 gFont1LatinGlyphs[];
extern const u8 gFont1LatinGlyphWidths[];
extern const u16 gFont0JapaneseGlyphs[];
extern const u16 gFont1JapaneseGlyphs[];
extern const u16 gFont2JapaneseGlyphs[];
extern const u8 gFont2JapaneseGlyphWidths[];
void SetFontsPointer(const struct FontInfo *fonts)
2017-03-07 14:44:41 +01:00
{
gFonts = fonts;
}
void DeactivateAllTextPrinters(void)
2017-03-07 14:44:41 +01:00
{
int printer;
for (printer = 0; printer < NUM_TEXT_PRINTERS; ++printer)
2018-11-05 21:42:12 +01:00
gTextPrinters[printer].active = 0;
2017-03-07 14:44:41 +01:00
}
2018-11-06 17:44:48 +01:00
u16 AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 speed, void (*callback)(struct TextPrinterTemplate *, u16))
2017-03-07 14:44:41 +01:00
{
2018-11-06 17:44:48 +01:00
struct TextPrinterTemplate printerTemplate;
printerTemplate.currentChar = str;
printerTemplate.windowId = windowId;
printerTemplate.fontId = fontId;
printerTemplate.x = x;
printerTemplate.y = y;
printerTemplate.currentX = x;
printerTemplate.currentY = y;
printerTemplate.letterSpacing = gFonts[fontId].letterSpacing;
printerTemplate.lineSpacing = gFonts[fontId].lineSpacing;
2018-11-06 18:30:21 +01:00
printerTemplate.unk = gFonts[fontId].unk;
2018-11-06 17:44:48 +01:00
printerTemplate.fgColor = gFonts[fontId].fgColor;
printerTemplate.bgColor = gFonts[fontId].bgColor;
printerTemplate.shadowColor = gFonts[fontId].shadowColor;
return AddTextPrinter(&printerTemplate, speed, callback);
2017-03-07 14:44:41 +01:00
}
2018-11-06 17:44:48 +01:00
bool16 AddTextPrinter(struct TextPrinterTemplate *printerTemplate, u8 speed, void (*callback)(struct TextPrinterTemplate *, u16))
2017-03-07 14:44:41 +01:00
{
int i;
u16 j;
2018-11-05 21:42:12 +01:00
u8 *ptr;
2017-03-07 14:44:41 +01:00
if (!gFonts)
return FALSE;
2017-09-02 00:21:11 +02:00
2018-11-05 21:42:12 +01:00
gTempTextPrinter.active = 1;
2017-03-07 14:44:41 +01:00
gTempTextPrinter.state = 0;
2018-11-05 21:42:12 +01:00
gTempTextPrinter.textSpeed = speed;
2017-03-07 14:44:41 +01:00
gTempTextPrinter.delayCounter = 0;
gTempTextPrinter.scrollDistance = 0;
2017-09-02 00:21:11 +02:00
2018-11-05 21:42:12 +01:00
for (i = 0; i < 7; i++)
2017-03-07 14:44:41 +01:00
{
2020-05-21 04:07:49 +02:00
gTempTextPrinter.subStructFields[i] = 0;
2017-03-07 14:44:41 +01:00
}
2017-09-02 00:21:11 +02:00
2018-11-06 17:44:48 +01:00
gTempTextPrinter.printerTemplate = *printerTemplate;
2017-03-07 14:44:41 +01:00
gTempTextPrinter.callback = callback;
gTempTextPrinter.minLetterSpacing = 0;
gTempTextPrinter.japanese = 0;
2018-11-06 17:44:48 +01:00
GenerateFontHalfRowLookupTable(printerTemplate->fgColor, printerTemplate->bgColor, printerTemplate->shadowColor);
2020-05-21 04:07:49 +02:00
if (speed != TEXT_SPEED_FF && speed != 0)
2017-03-07 14:44:41 +01:00
{
2018-11-05 21:42:12 +01:00
--gTempTextPrinter.textSpeed;
2018-11-06 17:44:48 +01:00
gTextPrinters[printerTemplate->windowId] = gTempTextPrinter;
2017-03-07 14:44:41 +01:00
}
else
{
2018-11-05 21:42:12 +01:00
gTempTextPrinter.textSpeed = 0;
2017-03-07 14:44:41 +01:00
for (j = 0; j < 0x400; ++j)
{
2019-07-01 21:08:49 +02:00
if (RenderFont(&gTempTextPrinter) == 1)
2017-03-07 14:44:41 +01:00
break;
}
2017-09-02 00:21:11 +02:00
2017-11-19 22:48:46 +01:00
if (speed != TEXT_SPEED_FF)
2020-05-21 04:28:17 +02:00
CopyWindowToVram(gTempTextPrinter.printerTemplate.windowId, 2);
2018-11-06 17:44:48 +01:00
gTextPrinters[printerTemplate->windowId].active = 0;
2017-03-07 14:44:41 +01:00
}
2017-03-28 06:20:55 +02:00
gUnknown_03002F84 = 0;
2017-03-07 14:44:41 +01:00
return TRUE;
}
2017-03-08 21:44:44 +01:00
void RunTextPrinters(void)
{
int i;
2017-03-28 06:20:55 +02:00
if (gUnknown_03002F84 == 0)
2017-03-08 21:44:44 +01:00
{
2020-05-21 04:28:17 +02:00
for (i = 0; i < NUM_TEXT_PRINTERS; ++i)
2017-03-08 21:44:44 +01:00
{
2018-11-21 21:58:35 +01:00
if (gTextPrinters[i].active)
2017-03-08 21:44:44 +01:00
{
2018-11-21 21:58:35 +01:00
u16 temp = RenderFont(&gTextPrinters[i]);
switch (temp)
{
case 0:
CopyWindowToVram(gTextPrinters[i].printerTemplate.windowId, 2);
case 3:
if (gTextPrinters[i].callback != 0)
gTextPrinters[i].callback(&gTextPrinters[i].printerTemplate, temp);
break;
case 1:
gTextPrinters[i].active = 0;
break;
2017-03-08 21:44:44 +01:00
}
}
}
}
}
2017-09-18 23:48:47 +02:00
bool16 IsTextPrinterActive(u8 id)
2017-03-08 21:44:44 +01:00
{
2018-11-05 21:42:12 +01:00
return gTextPrinters[id].active;
2017-03-08 21:44:44 +01:00
}
u32 RenderFont(struct TextPrinter *textPrinter)
{
u32 ret;
while (TRUE)
{
2018-11-06 17:44:48 +01:00
ret = gFonts[textPrinter->printerTemplate.fontId].fontFunction(textPrinter);
2017-03-08 21:44:44 +01:00
if (ret != 2)
return ret;
}
}
void GenerateFontHalfRowLookupTable(u8 fgColor, u8 bgColor, u8 shadowColor)
{
2018-11-25 20:16:41 +01:00
u32 fg12, bg12, shadow12;
u32 temp;
u16 *current = gFontHalfRowLookupTable;
2017-09-02 00:21:11 +02:00
2017-03-08 21:44:44 +01:00
gLastTextBgColor = bgColor;
gLastTextFgColor = fgColor;
gLastTextShadowColor = shadowColor;
2017-09-02 00:21:11 +02:00
2018-11-25 20:16:41 +01:00
bg12 = bgColor << 12;
fg12 = fgColor << 12;
shadow12 = shadowColor << 12;
2018-11-26 20:19:52 +01:00
temp = (bgColor << 8) | (bgColor << 4) | bgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (fgColor << 8) | (bgColor << 4) | bgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (shadowColor << 8) | (bgColor << 4) | bgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (bgColor << 8) | (fgColor << 4) | bgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (fgColor << 8) | (fgColor << 4) | bgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (shadowColor << 8) | (fgColor << 4) | bgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (bgColor << 8) | (shadowColor << 4) | bgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (fgColor << 8) | (shadowColor << 4) | bgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (shadowColor << 8) | (shadowColor << 4) | bgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (bgColor << 8) | (bgColor << 4) | fgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (fgColor << 8) | (bgColor << 4) | fgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (shadowColor << 8) | (bgColor << 4) | fgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (bgColor << 8) | (fgColor << 4) | fgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (fgColor << 8) | (fgColor << 4) | fgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (shadowColor << 8) | (fgColor << 4) | fgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (bgColor << 8) | (shadowColor << 4) | fgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (fgColor << 8) | (shadowColor << 4) | fgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (shadowColor << 8) | (shadowColor << 4) | fgColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (bgColor << 8) | (bgColor << 4) | shadowColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (fgColor << 8) | (bgColor << 4) | shadowColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (shadowColor << 8) | (bgColor << 4) | shadowColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (bgColor << 8) | (fgColor << 4) | shadowColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (fgColor << 8) | (fgColor << 4) | shadowColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (shadowColor << 8) | (fgColor << 4) | shadowColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (bgColor << 8) | (shadowColor << 4) | shadowColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (fgColor << 8) | (shadowColor << 4) | shadowColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2018-11-26 20:19:52 +01:00
temp = (shadowColor << 8) | (shadowColor << 4) | shadowColor;
2018-11-25 20:16:41 +01:00
*(current++) = (bg12) | temp;
*(current++) = (fg12) | temp;
*(current++) = (shadow12) | temp;
2017-03-08 21:44:44 +01:00
}
void SaveTextColors(u8 *fgColor, u8 *bgColor, u8 *shadowColor)
{
*bgColor = gLastTextBgColor;
*fgColor = gLastTextFgColor;
*shadowColor = gLastTextShadowColor;
}
void RestoreTextColors(u8 *fgColor, u8 *bgColor, u8 *shadowColor)
{
GenerateFontHalfRowLookupTable(*fgColor, *bgColor, *shadowColor);
}
2018-11-21 23:30:50 +01:00
void DecompressGlyphTile(const void *src_, void *dest_)
2017-03-08 21:44:44 +01:00
{
u32 temp;
2018-11-21 23:30:04 +01:00
const u16 *src = src_;
2018-11-21 21:58:35 +01:00
u32 *dest = dest_;
2018-11-21 23:30:04 +01:00
temp = *(src++);
2018-11-21 21:58:35 +01:00
*(dest)++ = ((gFontHalfRowLookupTable[gFontHalfRowOffsets[temp & 0xFF]]) << 16) | (gFontHalfRowLookupTable[gFontHalfRowOffsets[temp >> 8]]);
2017-09-02 00:21:11 +02:00
2018-11-21 23:30:04 +01:00
temp = *(src++);
*(dest++) = ((gFontHalfRowLookupTable[gFontHalfRowOffsets[temp & 0xFF]]) << 16) | (gFontHalfRowLookupTable[gFontHalfRowOffsets[temp >> 8]]);
2018-11-21 21:58:35 +01:00
2017-03-08 21:44:44 +01:00
temp = *(src++);
2018-11-21 21:58:35 +01:00
*(dest++) = ((gFontHalfRowLookupTable[gFontHalfRowOffsets[temp & 0xFF]]) << 16) | (gFontHalfRowLookupTable[gFontHalfRowOffsets[temp >> 8]]);
2017-03-08 21:44:44 +01:00
temp = *(src++);
2018-11-21 21:58:35 +01:00
*(dest++) = ((gFontHalfRowLookupTable[gFontHalfRowOffsets[temp & 0xFF]]) << 16) | (gFontHalfRowLookupTable[gFontHalfRowOffsets[temp >> 8]]);
2017-03-08 21:44:44 +01:00
temp = *(src++);
2018-11-21 21:58:35 +01:00
*(dest++) = ((gFontHalfRowLookupTable[gFontHalfRowOffsets[temp & 0xFF]]) << 16) | (gFontHalfRowLookupTable[gFontHalfRowOffsets[temp >> 8]]);
2017-03-08 21:44:44 +01:00
temp = *(src++);
2018-11-21 21:58:35 +01:00
*(dest++) = ((gFontHalfRowLookupTable[gFontHalfRowOffsets[temp & 0xFF]]) << 16) | (gFontHalfRowLookupTable[gFontHalfRowOffsets[temp >> 8]]);
temp = *(src++);
*(dest++) = ((gFontHalfRowLookupTable[gFontHalfRowOffsets[temp & 0xFF]]) << 16) | (gFontHalfRowLookupTable[gFontHalfRowOffsets[temp >> 8]]);
temp = *(src++);
*(dest++) = ((gFontHalfRowLookupTable[gFontHalfRowOffsets[temp & 0xFF]]) << 16) | (gFontHalfRowLookupTable[gFontHalfRowOffsets[temp >> 8]]);
2017-03-08 21:44:44 +01:00
}
u8 GetLastTextColor(u8 colorType)
{
switch (colorType)
{
2018-11-21 21:58:35 +01:00
case 0:
return gLastTextFgColor;
case 2:
return gLastTextBgColor;
case 1:
return gLastTextShadowColor;
default:
return 0;
2017-03-08 21:44:44 +01:00
}
}
#ifdef NONMATCHING
#define GLYPH_COPY(fromY_, toY_, fromX_, toX_, unk) \
{ \
u32 i, j, *ptr, toY, fromX, toX, r5, toOrr, bits; \
u8 *dst; \
\
j = fromX_; \
i = fromY_; \
ptr = unk; \
toX = toX_; \
toY = toY_; \
fromX = fromX_; \
\
for (; i < toY; i++) \
{ \
r5 = *(ptr++); \
for (j = fromX; j < toX; j++) \
{ \
toOrr = r5 & 0xF; \
if (toOrr) \
{ \
dst = windowTiles + ((j / 8) * 32) + ((j & 7) / 2) + ((i / 8) * widthOffset) + ((i & 7) * 4); \
bits = ((j & 1) << 2); \
*dst = ((toOrr << bits) | (*dst & (0xF0 >> bits))); \
} \
r5 >>= 4; \
} \
} \
}
void CopyGlyphToWindow(struct TextPrinter *textPrinter)
{
struct Window *win;
struct WindowTemplate *winTempl;
struct Struct_03002F90 *unkStruct;
u32 currX, widthOffset, currY;
s32 r4, r0;
u8 *windowTiles;
win = &gWindows[textPrinter->printerTemplate.windowId];
winTempl = &win->window;
r4 = (winTempl->width * 8) - textPrinter->printerTemplate.currentX;
if (r4 > gUnknown_03002F90.unk80)
r4 = gUnknown_03002F90.unk80;
r0 = (winTempl->height * 8) - textPrinter->printerTemplate.currentY;
if (r0 > gUnknown_03002F90.unk81)
r0 = gUnknown_03002F90.unk81;
currX = textPrinter->printerTemplate.currentX;
currY = textPrinter->printerTemplate.currentY;
unkStruct = &gUnknown_03002F90;
windowTiles = win->tileData;
widthOffset = winTempl->width * 32;
if (r4 <= 8)
{
if (r0 <= 8)
{
GLYPH_COPY(currY, currY + r0, currX, currX + r4, unkStruct->unk0);
}
else
{
u32 temp;
GLYPH_COPY(currY, currY + 8, currX, currX + r4, unkStruct->unk0);
temp = currY + 8;
GLYPH_COPY(temp, (temp - 8) + r0, currX, currX + r4, unkStruct->unk40);
}
}
else
{
if (r0 <= 8)
{
u32 temp;
GLYPH_COPY(currY, currY + r0, currX, currX + 8, unkStruct->unk0);
temp = currX + 8;
GLYPH_COPY(currY, currY + r0, temp, (temp - 8) + r4, unkStruct->unk20);
}
else
{
u32 temp;
GLYPH_COPY(currY, currY + 8, currX, currX + 8, unkStruct->unk0);
temp = currX + 8;
GLYPH_COPY(currY, currY + 8, temp, temp - 8 + r4, unkStruct->unk20);
temp = currY + 8;
GLYPH_COPY(temp, temp - 8 + r0, currX, currX + 8, unkStruct->unk40);
{
u32 tempX, tempY;
tempX = currX + 8;
tempY = currY + 8;
GLYPH_COPY(tempY, tempY - 8 + r0, tempX, tempX - 8 + r4, unkStruct->unk60);
}
}
}
}
#else
NAKED
2017-03-28 02:30:49 +02:00
void CopyGlyphToWindow(struct TextPrinter *x)
{
asm("push {r4-r7,lr}\n\
2018-01-24 22:45:37 +01:00
mov r7, r10\n\
mov r6, r9\n\
mov r5, r8\n\
push {r5-r7}\n\
sub sp, #0x8C\n\
add r3, r0, #0\n\
ldrb r1, [r3, #0x4]\n\
lsl r0, r1, #1\n\
add r0, r1\n\
lsl r0, #2\n\
ldr r1, =gWindows\n\
add r1, r0, r1\n\
add r2, r1, #0\n\
ldrb r7, [r1, #0x3]\n\
lsl r0, r7, #3\n\
ldrb r6, [r3, #0x8]\n\
sub r4, r0, r6\n\
ldr r5, =gUnknown_03002F90\n\
add r0, r5, #0\n\
add r0, #0x80\n\
ldrb r0, [r0]\n\
cmp r4, r0\n\
ble _08004DD2\n\
add r4, r0, #0\n\
2017-03-28 02:30:49 +02:00
_08004DD2:\n\
2018-01-24 22:45:37 +01:00
ldrb r0, [r1, #0x4]\n\
lsl r0, #3\n\
ldrb r3, [r3, #0x9]\n\
sub r0, r3\n\
add r1, r5, #0\n\
add r1, #0x81\n\
ldrb r1, [r1]\n\
cmp r0, r1\n\
ble _08004DE6\n\
add r0, r1, #0\n\
2017-03-28 02:30:49 +02:00
_08004DE6:\n\
2018-01-24 22:45:37 +01:00
str r6, [sp]\n\
mov r8, r3\n\
add r3, r5, #0\n\
ldr r2, [r2, #0x8]\n\
mov r9, r2\n\
lsl r1, r7, #5\n\
str r1, [sp, #0x4]\n\
cmp r4, #0x8\n\
ble _08004DFA\n\
b _08004F94\n\
2017-03-28 02:30:49 +02:00
_08004DFA:\n\
2018-01-24 22:45:37 +01:00
cmp r0, #0x8\n\
bgt _08004E84\n\
mov r1, r8\n\
str r3, [sp, #0x8]\n\
add r2, r6, #0\n\
add r2, r4\n\
mov r8, r2\n\
add r0, r1, r0\n\
str r0, [sp, #0xC]\n\
str r6, [sp, #0x10]\n\
cmp r1, r0\n\
bcc _08004E14\n\
b _080052AA\n\
2017-03-28 02:30:49 +02:00
_08004E14:\n\
2018-01-24 22:45:37 +01:00
ldr r3, [sp, #0x8]\n\
ldm r3!, {r5}\n\
str r3, [sp, #0x8]\n\
ldr r4, [sp, #0x10]\n\
add r0, r1, #0x1\n\
mov r10, r0\n\
cmp r4, r8\n\
bcs _08004E72\n\
mov r2, #0x7\n\
mov r12, r2\n\
lsr r0, r1, #3\n\
ldr r2, [sp, #0x4]\n\
add r3, r0, #0\n\
mul r3, r2\n\
add r7, r3, #0\n\
mov r3, r12\n\
and r1, r3\n\
lsl r6, r1, #2\n\
2017-03-28 02:30:49 +02:00
_08004E38:\n\
2018-01-24 22:45:37 +01:00
add r3, r5, #0\n\
mov r0, #0xF\n\
and r3, r0\n\
cmp r3, #0\n\
beq _08004E6A\n\
lsr r2, r4, #3\n\
lsl r2, #5\n\
add r2, r9\n\
add r0, r4, #0\n\
mov r1, r12\n\
and r0, r1\n\
lsr r0, #1\n\
add r2, r0\n\
add r2, r7\n\
add r2, r6\n\
mov r1, #0x1\n\
and r1, r4\n\
lsl r1, #2\n\
lsl r3, r1\n\
mov r0, #0xF0\n\
asr r0, r1\n\
ldrb r1, [r2]\n\
and r0, r1\n\
orr r3, r0\n\
strb r3, [r2]\n\
2017-03-28 02:30:49 +02:00
_08004E6A:\n\
2018-01-24 22:45:37 +01:00
lsr r5, #4\n\
add r4, #0x1\n\
cmp r4, r8\n\
bcc _08004E38\n\
2017-03-28 02:30:49 +02:00
_08004E72:\n\
2018-01-24 22:45:37 +01:00
mov r1, r10\n\
ldr r2, [sp, #0xC]\n\
cmp r1, r2\n\
bcc _08004E14\n\
b _080052AA\n\
.pool\n\
2017-03-28 02:30:49 +02:00
_08004E84:\n\
2018-01-24 22:45:37 +01:00
mov r1, r8\n\
str r3, [sp, #0x14]\n\
ldr r3, [sp]\n\
add r3, r4\n\
mov r12, r3\n\
add r2, r1, #0\n\
add r2, #0x8\n\
str r2, [sp, #0x18]\n\
ldr r3, [sp]\n\
str r3, [sp, #0x1C]\n\
mov r2, r12\n\
str r2, [sp, #0x74]\n\
ldr r3, [sp, #0x18]\n\
str r3, [sp, #0x88]\n\
sub r0, #0x8\n\
str r0, [sp, #0x80]\n\
cmp r1, r3\n\
bcs _08004F0E\n\
2017-03-28 02:30:49 +02:00
_08004EA8:\n\
2018-01-24 22:45:37 +01:00
ldr r0, [sp, #0x14]\n\
ldm r0!, {r5}\n\
str r0, [sp, #0x14]\n\
ldr r4, [sp, #0x1C]\n\
add r2, r1, #0x1\n\
mov r8, r2\n\
cmp r4, r12\n\
bcs _08004F06\n\
mov r3, #0x7\n\
mov r10, r3\n\
lsr r0, r1, #3\n\
ldr r3, [sp, #0x4]\n\
add r2, r0, #0\n\
mul r2, r3\n\
add r7, r2, #0\n\
mov r0, r10\n\
and r1, r0\n\
lsl r6, r1, #2\n\
2017-03-28 02:30:49 +02:00
_08004ECC:\n\
2018-01-24 22:45:37 +01:00
add r3, r5, #0\n\
mov r1, #0xF\n\
and r3, r1\n\
cmp r3, #0\n\
beq _08004EFE\n\
lsr r2, r4, #3\n\
lsl r2, #5\n\
add r2, r9\n\
add r0, r4, #0\n\
mov r1, r10\n\
and r0, r1\n\
lsr r0, #1\n\
add r2, r0\n\
add r2, r7\n\
add r2, r6\n\
mov r1, #0x1\n\
and r1, r4\n\
lsl r1, #2\n\
lsl r3, r1\n\
mov r0, #0xF0\n\
asr r0, r1\n\
ldrb r1, [r2]\n\
and r0, r1\n\
orr r3, r0\n\
strb r3, [r2]\n\
2017-03-28 02:30:49 +02:00
_08004EFE:\n\
2018-01-24 22:45:37 +01:00
lsr r5, #4\n\
add r4, #0x1\n\
cmp r4, r12\n\
bcc _08004ECC\n\
2017-03-28 02:30:49 +02:00
_08004F06:\n\
2018-01-24 22:45:37 +01:00
mov r1, r8\n\
ldr r2, [sp, #0x18]\n\
cmp r1, r2\n\
bcc _08004EA8\n\
2017-03-28 02:30:49 +02:00
_08004F0E:\n\
2018-01-24 22:45:37 +01:00
ldr r1, [sp, #0x88]\n\
2018-11-05 21:42:12 +01:00
ldr r3, =gUnknown_03002F90 + 0x40\n\
2018-01-24 22:45:37 +01:00
str r3, [sp, #0x20]\n\
ldr r0, [sp, #0x74]\n\
mov r8, r0\n\
ldr r2, [sp, #0x80]\n\
add r2, r1, r2\n\
str r2, [sp, #0x24]\n\
ldr r3, [sp]\n\
str r3, [sp, #0x28]\n\
cmp r1, r2\n\
bcc _08004F28\n\
b _080052AA\n\
2017-03-28 02:30:49 +02:00
_08004F28:\n\
2018-01-24 22:45:37 +01:00
ldr r0, [sp, #0x20]\n\
ldm r0!, {r5}\n\
str r0, [sp, #0x20]\n\
ldr r4, [sp, #0x28]\n\
add r2, r1, #0x1\n\
mov r10, r2\n\
cmp r4, r8\n\
bcs _08004F86\n\
mov r3, #0x7\n\
mov r12, r3\n\
lsr r0, r1, #3\n\
ldr r3, [sp, #0x4]\n\
add r2, r0, #0\n\
mul r2, r3\n\
add r7, r2, #0\n\
mov r0, r12\n\
and r1, r0\n\
lsl r6, r1, #2\n\
2017-03-28 02:30:49 +02:00
_08004F4C:\n\
2018-01-24 22:45:37 +01:00
add r3, r5, #0\n\
mov r1, #0xF\n\
and r3, r1\n\
cmp r3, #0\n\
beq _08004F7E\n\
lsr r2, r4, #3\n\
lsl r2, #5\n\
add r2, r9\n\
add r0, r4, #0\n\
mov r1, r12\n\
and r0, r1\n\
lsr r0, #1\n\
add r2, r0\n\
add r2, r7\n\
add r2, r6\n\
mov r1, #0x1\n\
and r1, r4\n\
lsl r1, #2\n\
lsl r3, r1\n\
mov r0, #0xF0\n\
asr r0, r1\n\
ldrb r1, [r2]\n\
and r0, r1\n\
orr r3, r0\n\
strb r3, [r2]\n\
2017-03-28 02:30:49 +02:00
_08004F7E:\n\
2018-01-24 22:45:37 +01:00
lsr r5, #4\n\
add r4, #0x1\n\
cmp r4, r8\n\
bcc _08004F4C\n\
2017-03-28 02:30:49 +02:00
_08004F86:\n\
2018-01-24 22:45:37 +01:00
mov r1, r10\n\
ldr r2, [sp, #0x24]\n\
cmp r1, r2\n\
bcc _08004F28\n\
b _080052AA\n\
.pool\n\
2017-03-28 02:30:49 +02:00
_08004F94:\n\
2018-01-24 22:45:37 +01:00
cmp r0, #0x8\n\
ble _08004F9A\n\
b _080050A4\n\
2017-03-28 02:30:49 +02:00
_08004F9A:\n\
2018-01-24 22:45:37 +01:00
mov r1, r8\n\
str r3, [sp, #0x2C]\n\
ldr r3, [sp]\n\
add r3, #0x8\n\
mov r12, r3\n\
add r0, r8\n\
str r0, [sp, #0x30]\n\
ldr r0, [sp]\n\
str r0, [sp, #0x34]\n\
ldr r2, [sp, #0x30]\n\
str r2, [sp, #0x78]\n\
str r3, [sp, #0x84]\n\
sub r4, #0x8\n\
str r4, [sp, #0x7C]\n\
cmp r8, r2\n\
bcs _0800501C\n\
2017-03-28 02:30:49 +02:00
_08004FBA:\n\
2018-01-24 22:45:37 +01:00
ldr r0, [sp, #0x2C]\n\
ldm r0!, {r5}\n\
str r0, [sp, #0x2C]\n\
ldr r4, [sp, #0x34]\n\
add r2, r1, #0x1\n\
mov r10, r2\n\
cmp r4, r12\n\
bcs _08005014\n\
lsr r0, r1, #3\n\
ldr r2, [sp, #0x4]\n\
add r3, r0, #0\n\
mul r3, r2\n\
add r7, r3, #0\n\
mov r3, #0x7\n\
and r1, r3\n\
lsl r6, r1, #2\n\
2017-03-28 02:30:49 +02:00
_08004FDA:\n\
2018-01-24 22:45:37 +01:00
add r3, r5, #0\n\
mov r0, #0xF\n\
and r3, r0\n\
cmp r3, #0\n\
beq _0800500C\n\
lsr r2, r4, #3\n\
lsl r2, #5\n\
add r2, r9\n\
add r0, r4, #0\n\
mov r1, #0x7\n\
and r0, r1\n\
lsr r0, #1\n\
add r2, r0\n\
add r2, r7\n\
add r2, r6\n\
mov r1, #0x1\n\
and r1, r4\n\
lsl r1, #2\n\
lsl r3, r1\n\
mov r0, #0xF0\n\
asr r0, r1\n\
ldrb r1, [r2]\n\
and r0, r1\n\
orr r3, r0\n\
strb r3, [r2]\n\
2017-03-28 02:30:49 +02:00
_0800500C:\n\
2018-01-24 22:45:37 +01:00
lsr r5, #4\n\
add r4, #0x1\n\
cmp r4, r12\n\
bcc _08004FDA\n\
2017-03-28 02:30:49 +02:00
_08005014:\n\
2018-01-24 22:45:37 +01:00
mov r1, r10\n\
ldr r2, [sp, #0x30]\n\
cmp r1, r2\n\
bcc _08004FBA\n\
2017-03-28 02:30:49 +02:00
_0800501C:\n\
2018-01-24 22:45:37 +01:00
mov r1, r8\n\
2018-11-05 21:42:12 +01:00
ldr r3, =gUnknown_03002F90 + 0x20\n\
2018-01-24 22:45:37 +01:00
str r3, [sp, #0x38]\n\
ldr r0, [sp, #0x84]\n\
ldr r2, [sp, #0x7C]\n\
add r0, r2\n\
mov r8, r0\n\
ldr r3, [sp, #0x78]\n\
str r3, [sp, #0x3C]\n\
ldr r0, [sp, #0x84]\n\
str r0, [sp, #0x40]\n\
cmp r1, r3\n\
bcc _08005038\n\
b _080052AA\n\
2017-03-28 02:30:49 +02:00
_08005038:\n\
2018-01-24 22:45:37 +01:00
ldr r2, [sp, #0x38]\n\
ldm r2!, {r5}\n\
str r2, [sp, #0x38]\n\
ldr r4, [sp, #0x40]\n\
add r3, r1, #0x1\n\
mov r10, r3\n\
cmp r4, r8\n\
bcs _08005096\n\
mov r0, #0x7\n\
mov r12, r0\n\
lsr r0, r1, #3\n\
ldr r3, [sp, #0x4]\n\
add r2, r0, #0\n\
mul r2, r3\n\
add r7, r2, #0\n\
mov r0, r12\n\
and r1, r0\n\
lsl r6, r1, #2\n\
2017-03-28 02:30:49 +02:00
_0800505C:\n\
2018-01-24 22:45:37 +01:00
add r3, r5, #0\n\
mov r1, #0xF\n\
and r3, r1\n\
cmp r3, #0\n\
beq _0800508E\n\
lsr r2, r4, #3\n\
lsl r2, #5\n\
add r2, r9\n\
add r0, r4, #0\n\
mov r1, r12\n\
and r0, r1\n\
lsr r0, #1\n\
add r2, r0\n\
add r2, r7\n\
add r2, r6\n\
mov r1, #0x1\n\
and r1, r4\n\
lsl r1, #2\n\
lsl r3, r1\n\
mov r0, #0xF0\n\
asr r0, r1\n\
ldrb r1, [r2]\n\
and r0, r1\n\
orr r3, r0\n\
strb r3, [r2]\n\
2017-03-28 02:30:49 +02:00
_0800508E:\n\
2018-01-24 22:45:37 +01:00
lsr r5, #4\n\
add r4, #0x1\n\
cmp r4, r8\n\
bcc _0800505C\n\
2017-03-28 02:30:49 +02:00
_08005096:\n\
2018-01-24 22:45:37 +01:00
mov r1, r10\n\
ldr r2, [sp, #0x3C]\n\
cmp r1, r2\n\
bcc _08005038\n\
b _080052AA\n\
.pool\n\
2017-03-28 02:30:49 +02:00
_080050A4:\n\
2018-01-24 22:45:37 +01:00
mov r1, r8\n\
str r5, [sp, #0x44]\n\
ldr r3, [sp]\n\
add r3, #0x8\n\
mov r12, r3\n\
mov r2, r8\n\
add r2, #0x8\n\
str r2, [sp, #0x48]\n\
ldr r3, [sp]\n\
str r3, [sp, #0x4C]\n\
str r2, [sp, #0x88]\n\
sub r0, #0x8\n\
str r0, [sp, #0x80]\n\
mov r0, r12\n\
str r0, [sp, #0x84]\n\
sub r4, #0x8\n\
str r4, [sp, #0x7C]\n\
cmp r8, r2\n\
bcs _0800512C\n\
2017-03-28 02:30:49 +02:00
_080050CA:\n\
2018-01-24 22:45:37 +01:00
ldr r2, [sp, #0x44]\n\
ldm r2!, {r5}\n\
str r2, [sp, #0x44]\n\
ldr r4, [sp, #0x4C]\n\
add r3, r1, #0x1\n\
mov r10, r3\n\
cmp r4, r12\n\
bcs _08005124\n\
lsr r0, r1, #3\n\
ldr r3, [sp, #0x4]\n\
add r2, r0, #0\n\
mul r2, r3\n\
add r7, r2, #0\n\
mov r0, #0x7\n\
and r1, r0\n\
lsl r6, r1, #2\n\
2017-03-28 02:30:49 +02:00
_080050EA:\n\
2018-01-24 22:45:37 +01:00
add r3, r5, #0\n\
mov r1, #0xF\n\
and r3, r1\n\
cmp r3, #0\n\
beq _0800511C\n\
lsr r2, r4, #3\n\
lsl r2, #5\n\
add r2, r9\n\
add r0, r4, #0\n\
mov r1, #0x7\n\
and r0, r1\n\
lsr r0, #1\n\
add r2, r0\n\
add r2, r7\n\
add r2, r6\n\
mov r1, #0x1\n\
and r1, r4\n\
lsl r1, #2\n\
lsl r3, r1\n\
mov r0, #0xF0\n\
asr r0, r1\n\
ldrb r1, [r2]\n\
and r0, r1\n\
orr r3, r0\n\
strb r3, [r2]\n\
2017-03-28 02:30:49 +02:00
_0800511C:\n\
2018-01-24 22:45:37 +01:00
lsr r5, #4\n\
add r4, #0x1\n\
cmp r4, r12\n\
bcc _080050EA\n\
2017-03-28 02:30:49 +02:00
_08005124:\n\
2018-01-24 22:45:37 +01:00
mov r1, r10\n\
ldr r2, [sp, #0x48]\n\
cmp r1, r2\n\
bcc _080050CA\n\
2017-03-28 02:30:49 +02:00
_0800512C:\n\
2018-01-24 22:45:37 +01:00
mov r1, r8\n\
2018-11-05 21:42:12 +01:00
ldr r3, =gUnknown_03002F90 + 0x20\n\
2018-01-24 22:45:37 +01:00
str r3, [sp, #0x50]\n\
ldr r0, [sp, #0x84]\n\
ldr r2, [sp, #0x7C]\n\
add r0, r2\n\
mov r8, r0\n\
ldr r3, [sp, #0x88]\n\
str r3, [sp, #0x54]\n\
ldr r0, [sp, #0x84]\n\
str r0, [sp, #0x58]\n\
cmp r1, r3\n\
bcs _080051AC\n\
2017-03-28 02:30:49 +02:00
_08005146:\n\
2018-01-24 22:45:37 +01:00
ldr r2, [sp, #0x50]\n\
ldm r2!, {r5}\n\
str r2, [sp, #0x50]\n\
ldr r4, [sp, #0x58]\n\
add r3, r1, #0x1\n\
mov r10, r3\n\
cmp r4, r8\n\
bcs _080051A4\n\
mov r0, #0x7\n\
mov r12, r0\n\
lsr r0, r1, #3\n\
ldr r3, [sp, #0x4]\n\
add r2, r0, #0\n\
mul r2, r3\n\
add r7, r2, #0\n\
mov r0, r12\n\
and r1, r0\n\
lsl r6, r1, #2\n\
2017-03-28 02:30:49 +02:00
_0800516A:\n\
2018-01-24 22:45:37 +01:00
add r3, r5, #0\n\
mov r1, #0xF\n\
and r3, r1\n\
cmp r3, #0\n\
beq _0800519C\n\
lsr r2, r4, #3\n\
lsl r2, #5\n\
add r2, r9\n\
add r0, r4, #0\n\
mov r1, r12\n\
and r0, r1\n\
lsr r0, #1\n\
add r2, r0\n\
add r2, r7\n\
add r2, r6\n\
mov r1, #0x1\n\
and r1, r4\n\
lsl r1, #2\n\
lsl r3, r1\n\
mov r0, #0xF0\n\
asr r0, r1\n\
ldrb r1, [r2]\n\
and r0, r1\n\
orr r3, r0\n\
strb r3, [r2]\n\
2017-03-28 02:30:49 +02:00
_0800519C:\n\
2018-01-24 22:45:37 +01:00
lsr r5, #4\n\
add r4, #0x1\n\
cmp r4, r8\n\
bcc _0800516A\n\
2017-03-28 02:30:49 +02:00
_080051A4:\n\
2018-01-24 22:45:37 +01:00
mov r1, r10\n\
ldr r2, [sp, #0x54]\n\
cmp r1, r2\n\
bcc _08005146\n\
2017-03-28 02:30:49 +02:00
_080051AC:\n\
2018-01-24 22:45:37 +01:00
ldr r1, [sp, #0x88]\n\
2018-11-05 21:42:12 +01:00
ldr r3, =gUnknown_03002F90 + 0x40\n\
2018-01-24 22:45:37 +01:00
str r3, [sp, #0x5C]\n\
ldr r0, [sp, #0x84]\n\
mov r8, r0\n\
ldr r2, [sp, #0x80]\n\
add r2, r1, r2\n\
str r2, [sp, #0x60]\n\
ldr r3, [sp]\n\
str r3, [sp, #0x64]\n\
cmp r1, r2\n\
bcs _0800522A\n\
2017-03-28 02:30:49 +02:00
_080051C4:\n\
2018-01-24 22:45:37 +01:00
ldr r0, [sp, #0x5C]\n\
ldm r0!, {r5}\n\
str r0, [sp, #0x5C]\n\
ldr r4, [sp, #0x64]\n\
add r2, r1, #0x1\n\
mov r10, r2\n\
cmp r4, r8\n\
bcs _08005222\n\
mov r3, #0x7\n\
mov r12, r3\n\
lsr r0, r1, #3\n\
ldr r3, [sp, #0x4]\n\
add r2, r0, #0\n\
mul r2, r3\n\
add r7, r2, #0\n\
mov r0, r12\n\
and r1, r0\n\
lsl r6, r1, #2\n\
2017-03-28 02:30:49 +02:00
_080051E8:\n\
2018-01-24 22:45:37 +01:00
add r3, r5, #0\n\
mov r1, #0xF\n\
and r3, r1\n\
cmp r3, #0\n\
beq _0800521A\n\
lsr r2, r4, #3\n\
lsl r2, #5\n\
add r2, r9\n\
add r0, r4, #0\n\
mov r1, r12\n\
and r0, r1\n\
lsr r0, #1\n\
add r2, r0\n\
add r2, r7\n\
add r2, r6\n\
mov r1, #0x1\n\
and r1, r4\n\
lsl r1, #2\n\
lsl r3, r1\n\
mov r0, #0xF0\n\
asr r0, r1\n\
ldrb r1, [r2]\n\
and r0, r1\n\
orr r3, r0\n\
strb r3, [r2]\n\
2017-03-28 02:30:49 +02:00
_0800521A:\n\
2018-01-24 22:45:37 +01:00
lsr r5, #4\n\
add r4, #0x1\n\
cmp r4, r8\n\
bcc _080051E8\n\
2017-03-28 02:30:49 +02:00
_08005222:\n\
2018-01-24 22:45:37 +01:00
mov r1, r10\n\
ldr r2, [sp, #0x60]\n\
cmp r1, r2\n\
bcc _080051C4\n\
2017-03-28 02:30:49 +02:00
_0800522A:\n\
2018-01-24 22:45:37 +01:00
ldr r4, [sp, #0x84]\n\
ldr r1, [sp, #0x88]\n\
2018-11-05 21:42:12 +01:00
ldr r3, =gUnknown_03002F90 + 0x60\n\
2018-01-24 22:45:37 +01:00
str r3, [sp, #0x68]\n\
ldr r0, [sp, #0x7C]\n\
add r0, r4\n\
mov r8, r0\n\
ldr r2, [sp, #0x80]\n\
add r2, r1, r2\n\
str r2, [sp, #0x6C]\n\
str r4, [sp, #0x70]\n\
cmp r1, r2\n\
bcs _080052AA\n\
2017-03-28 02:30:49 +02:00
_08005244:\n\
2018-01-24 22:45:37 +01:00
ldr r3, [sp, #0x68]\n\
ldm r3!, {r5}\n\
str r3, [sp, #0x68]\n\
ldr r4, [sp, #0x70]\n\
add r0, r1, #0x1\n\
mov r10, r0\n\
cmp r4, r8\n\
bcs _080052A2\n\
mov r2, #0x7\n\
mov r12, r2\n\
lsr r0, r1, #3\n\
ldr r2, [sp, #0x4]\n\
add r3, r0, #0\n\
mul r3, r2\n\
add r7, r3, #0\n\
mov r3, r12\n\
and r1, r3\n\
lsl r6, r1, #2\n\
2017-03-28 02:30:49 +02:00
_08005268:\n\
2018-01-24 22:45:37 +01:00
add r3, r5, #0\n\
mov r0, #0xF\n\
and r3, r0\n\
cmp r3, #0\n\
beq _0800529A\n\
lsr r2, r4, #3\n\
lsl r2, #5\n\
add r2, r9\n\
add r0, r4, #0\n\
mov r1, r12\n\
and r0, r1\n\
lsr r0, #1\n\
add r2, r0\n\
add r2, r7\n\
add r2, r6\n\
mov r1, #0x1\n\
and r1, r4\n\
lsl r1, #2\n\
lsl r3, r1\n\
mov r0, #0xF0\n\
asr r0, r1\n\
ldrb r1, [r2]\n\
and r0, r1\n\
orr r3, r0\n\
strb r3, [r2]\n\
2017-03-28 02:30:49 +02:00
_0800529A:\n\
2018-01-24 22:45:37 +01:00
lsr r5, #4\n\
add r4, #0x1\n\
cmp r4, r8\n\
bcc _08005268\n\
2017-03-28 02:30:49 +02:00
_080052A2:\n\
2018-01-24 22:45:37 +01:00
mov r1, r10\n\
ldr r2, [sp, #0x6C]\n\
cmp r1, r2\n\
bcc _08005244\n\
2017-03-28 02:30:49 +02:00
_080052AA:\n\
2018-01-24 22:45:37 +01:00
add sp, #0x8C\n\
pop {r3-r5}\n\
mov r8, r3\n\
mov r9, r4\n\
mov r10, r5\n\
pop {r4-r7}\n\
pop {r0}\n\
bx r0\n\
.pool");
2017-03-28 02:30:49 +02:00
}
#endif // NONMATCHING
2017-03-28 02:30:49 +02:00
void ClearTextSpan(struct TextPrinter *textPrinter, u32 width)
{
struct Window *window;
struct Bitmap pixels_data;
2018-11-05 21:42:12 +01:00
struct Struct_03002F90 *gUnk;
2017-03-28 02:30:49 +02:00
u8* glyphHeight;
if (gLastTextBgColor != 0)
{
2018-11-06 17:44:48 +01:00
window = &gWindows[textPrinter->printerTemplate.windowId];
2017-03-28 02:30:49 +02:00
pixels_data.pixels = window->tileData;
2017-04-05 22:51:55 +02:00
pixels_data.width = window->window.width << 3;
pixels_data.height = window->window.height << 3;
2017-09-02 00:21:11 +02:00
2018-11-05 21:42:12 +01:00
gUnk = &gUnknown_03002F90;
glyphHeight = &gUnk->unk81;
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
FillBitmapRect4Bit(
&pixels_data,
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentX,
textPrinter->printerTemplate.currentY,
2017-03-28 02:30:49 +02:00
width,
*glyphHeight,
gLastTextBgColor);
}
}
u16 Font0Func(struct TextPrinter *textPrinter)
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2018-11-06 17:44:48 +01:00
if (subStruct->hasGlyphIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
subStruct->glyphId = 0;
2018-11-06 17:44:48 +01:00
subStruct->hasGlyphIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
u16 Font1Func(struct TextPrinter *textPrinter)
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2018-11-06 17:44:48 +01:00
if (subStruct->hasGlyphIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
subStruct->glyphId = 1;
2018-11-06 17:44:48 +01:00
subStruct->hasGlyphIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
u16 Font2Func(struct TextPrinter *textPrinter)
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2018-11-06 17:44:48 +01:00
if (subStruct->hasGlyphIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
subStruct->glyphId = 2;
2018-11-06 17:44:48 +01:00
subStruct->hasGlyphIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
2017-03-08 21:44:44 +01:00
2017-03-28 02:30:49 +02:00
u16 Font3Func(struct TextPrinter *textPrinter)
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2018-11-06 17:44:48 +01:00
if (subStruct->hasGlyphIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
subStruct->glyphId = 3;
2018-11-06 17:44:48 +01:00
subStruct->hasGlyphIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
u16 Font4Func(struct TextPrinter *textPrinter)
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2018-11-06 17:44:48 +01:00
if (subStruct->hasGlyphIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
subStruct->glyphId = 4;
2018-11-06 17:44:48 +01:00
subStruct->hasGlyphIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
u16 Font5Func(struct TextPrinter *textPrinter)
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2018-11-06 17:44:48 +01:00
if (subStruct->hasGlyphIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
subStruct->glyphId = 5;
2018-11-06 17:44:48 +01:00
subStruct->hasGlyphIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
u16 Font7Func(struct TextPrinter *textPrinter)
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2018-11-06 17:44:48 +01:00
if (subStruct->hasGlyphIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
subStruct->glyphId = 7;
2018-11-06 17:44:48 +01:00
subStruct->hasGlyphIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
u16 Font8Func(struct TextPrinter *textPrinter)
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2018-11-06 17:44:48 +01:00
if (subStruct->hasGlyphIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
subStruct->glyphId = 8;
2018-11-06 17:44:48 +01:00
subStruct->hasGlyphIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
void TextPrinterInitDownArrowCounters(struct TextPrinter *textPrinter)
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2018-11-06 18:30:21 +01:00
if (gTextFlags.autoScroll == 1)
2020-05-21 04:07:49 +02:00
{
2018-11-06 18:30:21 +01:00
subStruct->autoScrollDelay = 0;
2020-05-21 04:07:49 +02:00
}
2017-03-28 02:30:49 +02:00
else
{
2018-11-06 17:44:48 +01:00
subStruct->downArrowYPosIdx = 0;
subStruct->downArrowDelay = 0;
2017-03-28 02:30:49 +02:00
}
}
void TextPrinterDrawDownArrow(struct TextPrinter *textPrinter)
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-03-28 02:30:49 +02:00
const u8 *arrowTiles;
2018-11-06 18:30:21 +01:00
if (gTextFlags.autoScroll == 0)
2017-03-28 02:30:49 +02:00
{
2018-11-06 17:44:48 +01:00
if (subStruct->downArrowDelay != 0)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
subStruct->downArrowDelay--;
2017-03-28 02:30:49 +02:00
}
else
{
FillWindowPixelRect(
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.windowId,
textPrinter->printerTemplate.bgColor << 4 | textPrinter->printerTemplate.bgColor,
textPrinter->printerTemplate.currentX,
textPrinter->printerTemplate.currentY,
2020-05-21 04:07:49 +02:00
8,
16);
2017-09-02 00:21:11 +02:00
2018-11-06 18:30:21 +01:00
switch (gTextFlags.useAlternateDownArrow)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
case FALSE:
2017-03-28 02:30:49 +02:00
default:
arrowTiles = gDownArrowTiles;
break;
2020-05-21 04:07:49 +02:00
case TRUE:
2017-03-28 02:30:49 +02:00
arrowTiles = gDarkDownArrowTiles;
break;
}
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
BlitBitmapRectToWindow(
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.windowId,
2017-03-28 02:30:49 +02:00
arrowTiles,
0,
2020-05-21 04:07:49 +02:00
gDownArrowYCoords[subStruct->downArrowYPosIdx],
8,
16,
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentX,
textPrinter->printerTemplate.currentY,
2020-05-21 04:07:49 +02:00
8,
16);
CopyWindowToVram(textPrinter->printerTemplate.windowId, 2);
2017-09-02 00:21:11 +02:00
2020-05-21 04:07:49 +02:00
subStruct->downArrowDelay = 8;
subStruct->downArrowYPosIdx++;
2017-03-28 02:30:49 +02:00
}
}
}
void TextPrinterClearDownArrow(struct TextPrinter *textPrinter)
{
FillWindowPixelRect(
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.windowId,
textPrinter->printerTemplate.bgColor << 4 | textPrinter->printerTemplate.bgColor,
textPrinter->printerTemplate.currentX,
textPrinter->printerTemplate.currentY,
2020-05-21 04:07:49 +02:00
8,
16);
CopyWindowToVram(textPrinter->printerTemplate.windowId, 2);
2017-03-28 02:30:49 +02:00
}
bool8 TextPrinterWaitAutoMode(struct TextPrinter *textPrinter)
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2018-11-06 18:30:21 +01:00
if (subStruct->autoScrollDelay == 49)
2017-03-28 02:30:49 +02:00
{
return TRUE;
}
else
{
2020-05-21 04:07:49 +02:00
subStruct->autoScrollDelay++;
2017-03-28 02:30:49 +02:00
return FALSE;
}
}
2017-09-22 05:43:13 +02:00
bool16 TextPrinterWaitWithDownArrow(struct TextPrinter *textPrinter)
2017-03-28 02:30:49 +02:00
{
2017-03-28 06:20:55 +02:00
bool8 result = FALSE;
2018-11-06 18:30:21 +01:00
if (gTextFlags.autoScroll != 0)
2017-03-28 02:30:49 +02:00
{
result = TextPrinterWaitAutoMode(textPrinter);
}
else
{
TextPrinterDrawDownArrow(textPrinter);
if (gMain.newKeys & (A_BUTTON | B_BUTTON))
{
2017-03-28 06:20:55 +02:00
result = TRUE;
2018-02-28 13:07:58 +01:00
PlaySE(SE_SELECT);
2017-03-28 02:30:49 +02:00
}
}
return result;
}
2017-09-22 05:43:13 +02:00
bool16 TextPrinterWait(struct TextPrinter *textPrinter)
2017-03-28 02:30:49 +02:00
{
2017-09-22 05:43:13 +02:00
bool16 result = FALSE;
2018-11-06 18:30:21 +01:00
if (gTextFlags.autoScroll != 0)
2017-03-28 02:30:49 +02:00
{
result = TextPrinterWaitAutoMode(textPrinter);
}
else
{
if (gMain.newKeys & (A_BUTTON | B_BUTTON))
{
2017-03-28 06:20:55 +02:00
result = TRUE;
2018-02-28 13:07:58 +01:00
PlaySE(SE_SELECT);
2017-03-28 02:30:49 +02:00
}
}
return result;
}
void DrawDownArrow(u8 windowId, u16 x, u16 y, u8 bgColor, bool8 drawArrow, u8 *counter, u8 *yCoordIndex)
{
const u8 *arrowTiles;
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
if (*counter != 0)
{
--*counter;
}
else
{
FillWindowPixelRect(windowId, (bgColor << 4) | bgColor, x, y, 0x8, 0x10);
if (drawArrow == 0)
{
2018-11-06 18:30:21 +01:00
switch (gTextFlags.useAlternateDownArrow)
2017-03-28 02:30:49 +02:00
{
case 0:
default:
arrowTiles = gDownArrowTiles;
break;
case 1:
arrowTiles = gDarkDownArrowTiles;
break;
}
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
BlitBitmapRectToWindow(
windowId,
arrowTiles,
0,
gDownArrowYCoords[*yCoordIndex & 3],
0x8,
0x10,
x,
y - 2,
0x8,
0x10);
CopyWindowToVram(windowId, 0x2);
*counter = 8;
++*yCoordIndex;
}
}
}
2018-11-04 23:09:10 +01:00
2018-01-24 22:45:37 +01:00
u16 RenderText(struct TextPrinter *textPrinter)
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
u16 currChar;
s32 width;
2018-11-04 23:09:10 +01:00
s32 widthHelper;
2017-03-28 02:30:49 +02:00
2018-11-04 23:09:10 +01:00
switch (textPrinter->state)
2018-01-24 22:45:37 +01:00
{
2018-11-05 21:42:12 +01:00
case 0:
2018-11-06 17:44:48 +01:00
if ((gMain.heldKeys & (A_BUTTON | B_BUTTON)) && subStruct->hasPrintBeenSpedUp)
textPrinter->delayCounter = 0;
2018-11-05 21:42:12 +01:00
if (textPrinter->delayCounter && textPrinter->textSpeed)
{
textPrinter->delayCounter--;
2018-11-06 17:44:48 +01:00
if (gTextFlags.canABSpeedUpPrint && (gMain.newKeys & (A_BUTTON | B_BUTTON)))
2018-01-24 22:45:37 +01:00
{
2018-11-06 17:44:48 +01:00
subStruct->hasPrintBeenSpedUp = TRUE;
textPrinter->delayCounter = 0;
2018-01-24 22:45:37 +01:00
}
return 3;
}
2018-11-06 18:30:21 +01:00
if (!(gBattleTypeFlags & BATTLE_TYPE_RECORDED) && gTextFlags.autoScroll)
textPrinter->delayCounter = 3;
else
2018-11-05 21:42:12 +01:00
textPrinter->delayCounter = textPrinter->textSpeed;
2018-11-06 17:44:48 +01:00
currChar = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
2018-11-04 23:09:10 +01:00
switch (currChar)
{
2018-11-04 23:09:10 +01:00
case CHAR_NEWLINE:
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentX = textPrinter->printerTemplate.x;
textPrinter->printerTemplate.currentY += (gFonts[textPrinter->printerTemplate.fontId].maxLetterHeight + textPrinter->printerTemplate.lineSpacing);
return 2;
2018-11-04 23:09:10 +01:00
case PLACEHOLDER_BEGIN:
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentChar++;
return 2;
2018-11-04 23:09:10 +01:00
case EXT_CTRL_CODE_BEGIN:
2018-11-06 17:44:48 +01:00
currChar = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
2018-11-04 23:09:10 +01:00
switch (currChar)
2018-01-24 22:45:37 +01:00
{
2018-11-06 17:44:48 +01:00
case 1:
textPrinter->printerTemplate.fgColor = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
GenerateFontHalfRowLookupTable(textPrinter->printerTemplate.fgColor, textPrinter->printerTemplate.bgColor, textPrinter->printerTemplate.shadowColor);
return 2;
2018-11-06 17:44:48 +01:00
case 2:
textPrinter->printerTemplate.bgColor = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
GenerateFontHalfRowLookupTable(textPrinter->printerTemplate.fgColor, textPrinter->printerTemplate.bgColor, textPrinter->printerTemplate.shadowColor);
return 2;
2018-11-06 17:44:48 +01:00
case 3:
textPrinter->printerTemplate.shadowColor = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
GenerateFontHalfRowLookupTable(textPrinter->printerTemplate.fgColor, textPrinter->printerTemplate.bgColor, textPrinter->printerTemplate.shadowColor);
return 2;
2018-11-06 17:44:48 +01:00
case 4:
textPrinter->printerTemplate.fgColor = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
textPrinter->printerTemplate.bgColor = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
textPrinter->printerTemplate.shadowColor = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
GenerateFontHalfRowLookupTable(textPrinter->printerTemplate.fgColor, textPrinter->printerTemplate.bgColor, textPrinter->printerTemplate.shadowColor);
return 2;
2018-11-06 17:44:48 +01:00
case 5:
textPrinter->printerTemplate.currentChar++;
return 2;
2018-11-06 17:44:48 +01:00
case 6:
subStruct->glyphId = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
return 2;
case EXT_CTRL_CODE_UNKNOWN_7:
return 2;
2018-11-06 17:44:48 +01:00
case 8:
textPrinter->delayCounter = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
textPrinter->state = 6;
return 2;
2018-11-06 17:44:48 +01:00
case 9:
textPrinter->state = 1;
2018-11-06 18:30:21 +01:00
if (gTextFlags.autoScroll)
subStruct->autoScrollDelay = 0;
return 3;
2018-11-06 17:44:48 +01:00
case 10:
textPrinter->state = 5;
return 3;
2018-11-06 17:44:48 +01:00
case 11:
currChar = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
currChar |= *textPrinter->printerTemplate.currentChar << 8;
textPrinter->printerTemplate.currentChar++;
PlayBGM(currChar);
return 2;
2018-11-06 17:44:48 +01:00
case 12:
currChar = *textPrinter->printerTemplate.currentChar | 0x100;
textPrinter->printerTemplate.currentChar++;
2018-11-04 23:09:10 +01:00
break;
2018-11-06 17:44:48 +01:00
case 16:
currChar = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
currChar |= (*textPrinter->printerTemplate.currentChar << 8);
textPrinter->printerTemplate.currentChar++;
PlaySE(currChar);
return 2;
2018-11-06 17:44:48 +01:00
case 13:
textPrinter->printerTemplate.currentX = textPrinter->printerTemplate.x + *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
return 2;
2018-11-06 17:44:48 +01:00
case 14:
textPrinter->printerTemplate.currentY = textPrinter->printerTemplate.y + *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
return 2;
2018-11-06 17:44:48 +01:00
case 15:
FillWindowPixelBuffer(textPrinter->printerTemplate.windowId, PIXEL_FILL(textPrinter->printerTemplate.bgColor));
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentX = textPrinter->printerTemplate.x;
textPrinter->printerTemplate.currentY = textPrinter->printerTemplate.y;
return 2;
2018-11-06 17:44:48 +01:00
case 23:
m4aMPlayStop(&gMPlayInfo_BGM);
return 2;
2018-11-06 17:44:48 +01:00
case 24:
m4aMPlayContinue(&gMPlayInfo_BGM);
return 2;
case EXT_CTRL_CODE_CLEAR:
2018-11-06 17:44:48 +01:00
width = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
if (width > 0)
2018-01-24 22:45:37 +01:00
{
ClearTextSpan(textPrinter, width);
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentX += width;
return 0;
2018-01-24 22:45:37 +01:00
}
return 2;
2018-11-06 17:44:48 +01:00
case 18:
textPrinter->printerTemplate.currentX = *textPrinter->printerTemplate.currentChar + textPrinter->printerTemplate.x;
textPrinter->printerTemplate.currentChar++;
return 2;
case EXT_CTRL_CODE_CLEAR_TO:
2018-01-24 22:45:37 +01:00
{
2018-11-06 17:44:48 +01:00
widthHelper = *textPrinter->printerTemplate.currentChar;
widthHelper += textPrinter->printerTemplate.x;
textPrinter->printerTemplate.currentChar++;
width = widthHelper - textPrinter->printerTemplate.currentX;
if (width > 0)
{
ClearTextSpan(textPrinter, width);
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentX += width;
return 0;
}
2018-01-24 22:45:37 +01:00
}
return 2;
case EXT_CTRL_CODE_MIN_LETTER_SPACING:
2018-11-06 17:44:48 +01:00
textPrinter->minLetterSpacing = *textPrinter->printerTemplate.currentChar++;
return 2;
case EXT_CTRL_CODE_JPN:
textPrinter->japanese = 1;
return 2;
case EXT_CTRL_CODE_ENG:
textPrinter->japanese = 0;
return 2;
2018-01-24 22:45:37 +01:00
}
break;
2018-11-04 23:09:10 +01:00
case CHAR_PROMPT_CLEAR:
textPrinter->state = 2;
TextPrinterInitDownArrowCounters(textPrinter);
2018-01-24 22:45:37 +01:00
return 3;
2018-11-04 23:09:10 +01:00
case CHAR_PROMPT_SCROLL:
textPrinter->state = 3;
TextPrinterInitDownArrowCounters(textPrinter);
2018-01-24 22:45:37 +01:00
return 3;
2018-11-04 23:09:10 +01:00
case CHAR_SPECIAL_F9:
2018-11-06 17:44:48 +01:00
currChar = *textPrinter->printerTemplate.currentChar | 0x100;
textPrinter->printerTemplate.currentChar++;
break;
2018-11-04 23:09:10 +01:00
case CHAR_SPECIAL_F8:
2018-11-06 17:44:48 +01:00
currChar = *textPrinter->printerTemplate.currentChar++;
gUnknown_03002F90.unk80 = DrawKeypadIcon(textPrinter->printerTemplate.windowId, currChar, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY);
textPrinter->printerTemplate.currentX += gUnknown_03002F90.unk80 + textPrinter->printerTemplate.letterSpacing;
return 0;
2018-11-04 23:09:10 +01:00
case EOS:
return 1;
}
2018-11-06 17:44:48 +01:00
switch (subStruct->glyphId)
{
2018-11-06 17:44:48 +01:00
case 0:
DecompressGlyphFont0(currChar, textPrinter->japanese);
break;
2018-11-06 17:44:48 +01:00
case 1:
DecompressGlyphFont1(currChar, textPrinter->japanese);
break;
case 2:
case 3:
case 4:
2018-11-06 17:44:48 +01:00
case 5:
DecompressGlyphFont2(currChar, textPrinter->japanese);
break;
2018-11-06 17:44:48 +01:00
case 7:
DecompressGlyphFont7(currChar, textPrinter->japanese);
break;
2018-11-06 17:44:48 +01:00
case 8:
DecompressGlyphFont8(currChar, textPrinter->japanese);
break;
2018-11-06 17:44:48 +01:00
case 6:
break;
}
2018-11-04 23:09:10 +01:00
CopyGlyphToWindow(textPrinter);
if (textPrinter->minLetterSpacing)
{
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentX += gUnknown_03002F90.unk80;
2018-11-05 21:42:12 +01:00
width = textPrinter->minLetterSpacing - gUnknown_03002F90.unk80;
if (width > 0)
2018-01-24 22:45:37 +01:00
{
ClearTextSpan(textPrinter, width);
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentX += width;
2018-01-24 22:45:37 +01:00
}
}
2018-11-04 23:09:10 +01:00
else
{
if (textPrinter->japanese)
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentX += (gUnknown_03002F90.unk80 + textPrinter->printerTemplate.letterSpacing);
else
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentX += gUnknown_03002F90.unk80;
}
return 0;
2018-11-04 23:09:10 +01:00
case 1:
if (TextPrinterWait(textPrinter))
textPrinter->state = 0;
return 3;
2018-11-04 23:09:10 +01:00
case 2:
if (TextPrinterWaitWithDownArrow(textPrinter))
{
FillWindowPixelBuffer(textPrinter->printerTemplate.windowId, PIXEL_FILL(textPrinter->printerTemplate.bgColor));
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentX = textPrinter->printerTemplate.x;
textPrinter->printerTemplate.currentY = textPrinter->printerTemplate.y;
textPrinter->state = 0;
}
return 3;
2018-11-04 23:09:10 +01:00
case 3:
if (TextPrinterWaitWithDownArrow(textPrinter))
{
TextPrinterClearDownArrow(textPrinter);
2018-11-06 17:44:48 +01:00
textPrinter->scrollDistance = gFonts[textPrinter->printerTemplate.fontId].maxLetterHeight + textPrinter->printerTemplate.lineSpacing;
textPrinter->printerTemplate.currentX = textPrinter->printerTemplate.x;
textPrinter->state = 4;
}
return 3;
2018-11-04 23:09:10 +01:00
case 4:
if (textPrinter->scrollDistance)
{
2018-11-06 18:30:21 +01:00
int scrollSpeed = GetPlayerTextSpeed();
int speed = gWindowVerticalScrollSpeeds[scrollSpeed];
if (textPrinter->scrollDistance < speed)
2018-01-24 22:45:37 +01:00
{
ScrollWindow(textPrinter->printerTemplate.windowId, 0, textPrinter->scrollDistance, PIXEL_FILL(textPrinter->printerTemplate.bgColor));
textPrinter->scrollDistance = 0;
2018-01-24 22:45:37 +01:00
}
else
{
ScrollWindow(textPrinter->printerTemplate.windowId, 0, speed, PIXEL_FILL(textPrinter->printerTemplate.bgColor));
textPrinter->scrollDistance -= speed;
}
2018-11-06 17:44:48 +01:00
CopyWindowToVram(textPrinter->printerTemplate.windowId, 2);
}
else
{
textPrinter->state = 0;
}
return 3;
2018-11-04 23:09:10 +01:00
case 5:
if (!IsSEPlaying())
textPrinter->state = 0;
return 3;
2018-11-06 17:44:48 +01:00
case 6:
if (textPrinter->delayCounter != 0)
textPrinter->delayCounter--;
else
textPrinter->state = 0;
return 3;
2018-01-24 22:45:37 +01:00
}
2018-01-24 22:45:37 +01:00
return 1;
}
2017-03-28 02:30:49 +02:00
2017-09-18 17:26:45 +02:00
u32 GetStringWidthFixedWidthFont(const u8 *str, u8 fontId, u8 letterSpacing)
2017-03-28 02:30:49 +02:00
{
int i;
u8 width;
int temp;
int temp2;
u8 line;
int strPos;
u8 lineWidths[8];
2017-09-18 17:26:45 +02:00
const u8 *strLocal;
2017-03-28 02:30:49 +02:00
for (i = 0; i < 8; i++)
{
lineWidths[i] = 0;
}
width = 0;
line = 0;
strLocal = str;
strPos = 0;
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
do
{
temp = strLocal[strPos++];
switch (temp)
{
2018-11-05 21:42:12 +01:00
case CHAR_NEWLINE:
case EOS:
lineWidths[line] = width;
width = 0;
line++;
break;
case EXT_CTRL_CODE_BEGIN:
temp2 = strLocal[strPos++];
switch (temp2)
{
case 0x4:
2017-03-28 02:30:49 +02:00
++strPos;
2018-11-05 21:42:12 +01:00
case 0xB:
case 0x10:
++strPos;
case 0x1:
case 0x2:
case 0x3:
case 0x5:
case 0x6:
case 0x8:
case 0xC:
case 0xD:
case 0xE:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
2017-03-28 02:30:49 +02:00
++strPos;
2018-11-05 21:42:12 +01:00
break;
case EXT_CTRL_CODE_UNKNOWN_7:
2018-11-05 21:42:12 +01:00
case 0x9:
case 0xA:
case 0xF:
case EXT_CTRL_CODE_JPN:
case EXT_CTRL_CODE_ENG:
2017-03-28 02:30:49 +02:00
default:
break;
2018-11-05 21:42:12 +01:00
}
break;
case CHAR_SPECIAL_F7:
case PLACEHOLDER_BEGIN:
++strPos;
break;
case CHAR_PROMPT_SCROLL:
case CHAR_PROMPT_CLEAR:
break;
case CHAR_SPECIAL_F8:
case CHAR_SPECIAL_F9:
++strPos;
default:
++width;
break;
2017-03-28 02:30:49 +02:00
}
2018-10-14 15:04:25 +02:00
} while (temp != EOS);
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
for (width = 0, strPos = 0; strPos < 8; ++strPos)
{
if (width < lineWidths[strPos])
width = lineWidths[strPos];
}
2017-09-02 00:21:11 +02:00
2018-07-15 13:23:38 +02:00
return (u8)(GetFontAttribute(fontId, FONTATTR_MAX_LETTER_WIDTH) + letterSpacing) * width;
2017-03-28 02:30:49 +02:00
}
u32 (*GetFontWidthFunc(u8 glyphId))(u16, bool32)
{
u32 i;
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
for (i = 0; i < 9; ++i)
{
2018-11-06 18:30:21 +01:00
if (glyphId == gGlyphWidthFuncs[i].fontId)
2017-03-28 02:30:49 +02:00
return gGlyphWidthFuncs[i].func;
}
2017-09-02 00:21:11 +02:00
return NULL;
2017-03-28 02:30:49 +02:00
}
2018-12-15 23:58:47 +01:00
s32 GetStringWidth(u8 fontId, const u8 *str, s16 letterSpacing)
2017-03-28 02:30:49 +02:00
{
bool8 isJapanese;
int minGlyphWidth;
u32 (*func)(u16 glyphId, bool32 isJapanese);
s32 result;
int localLetterSpacing;
u32 lineWidth;
const u8 *bufferPointer;
2017-03-28 02:30:49 +02:00
int glyphWidth;
2018-12-15 23:58:47 +01:00
s32 width;
2017-03-28 02:30:49 +02:00
isJapanese = 0;
minGlyphWidth = 0;
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
func = GetFontWidthFunc(fontId);
if (func == NULL)
return 0;
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
if (letterSpacing == -1)
2018-07-15 13:23:38 +02:00
localLetterSpacing = GetFontAttribute(fontId, FONTATTR_LETTER_SPACING);
2017-03-28 02:30:49 +02:00
else
localLetterSpacing = letterSpacing;
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
width = 0;
lineWidth = 0;
bufferPointer = 0;
2017-09-02 00:21:11 +02:00
2018-10-14 15:04:25 +02:00
while (*str != EOS)
2017-03-28 02:30:49 +02:00
{
switch (*str)
{
2018-11-05 21:42:12 +01:00
case CHAR_NEWLINE:
if (lineWidth > width)
width = lineWidth;
lineWidth = 0;
break;
case PLACEHOLDER_BEGIN:
switch (*++str)
{
case 0x2:
bufferPointer = gStringVar1;
break;
case 0x3:
bufferPointer = gStringVar2;
break;
case 0x4:
bufferPointer = gStringVar3;
break;
default:
return 0;
}
case CHAR_SPECIAL_F7:
if (bufferPointer == NULL)
bufferPointer = DynamicPlaceholderTextUtil_GetPlaceholderPtr(*++str);
while (*bufferPointer != EOS)
{
glyphWidth = func(*bufferPointer++, isJapanese);
2017-03-28 02:30:49 +02:00
if (minGlyphWidth > 0)
{
if (glyphWidth < minGlyphWidth)
glyphWidth = minGlyphWidth;
lineWidth += glyphWidth;
}
else
{
lineWidth += glyphWidth;
2018-10-14 15:04:25 +02:00
if (isJapanese && str[1] != EOS)
2017-03-28 02:30:49 +02:00
lineWidth += localLetterSpacing;
}
2018-11-05 21:42:12 +01:00
}
bufferPointer = 0;
break;
case EXT_CTRL_CODE_BEGIN:
switch (*++str)
{
case 0x4:
++str;
case 0xB:
case 0x10:
++str;
case 0x1:
case 0x2:
case 0x3:
case 0x5:
case 0x8:
case 0xC:
case 0xD:
case 0xE:
++str;
break;
case 0x6:
func = GetFontWidthFunc(*++str);
if (func == NULL)
return 0;
if (letterSpacing == -1)
localLetterSpacing = GetFontAttribute(*str, FONTATTR_LETTER_SPACING);
break;
case 0x11:
glyphWidth = *++str;
lineWidth += glyphWidth;
break;
case 0x12:
lineWidth = *++str;
2017-03-28 02:30:49 +02:00
break;
2018-11-05 21:42:12 +01:00
case 0x13:
if (*++str > lineWidth)
lineWidth = *str;
2017-03-28 02:30:49 +02:00
break;
2018-11-05 21:42:12 +01:00
case 0x14:
minGlyphWidth = *++str;
break;
case EXT_CTRL_CODE_JPN:
2018-11-05 21:42:12 +01:00
isJapanese = 1;
break;
case EXT_CTRL_CODE_ENG:
2018-11-05 21:42:12 +01:00
isJapanese = 0;
break;
case EXT_CTRL_CODE_UNKNOWN_7:
2018-11-05 21:42:12 +01:00
case 0x9:
case 0xA:
case 0xF:
2017-03-28 02:30:49 +02:00
default:
break;
2018-11-05 21:42:12 +01:00
}
break;
case CHAR_SPECIAL_F8:
case CHAR_SPECIAL_F9:
if (*str == CHAR_SPECIAL_F9)
glyphWidth = func(*++str | 0x100, isJapanese);
else
glyphWidth = GetKeypadIconWidth(*++str);
if (minGlyphWidth > 0)
{
if (glyphWidth < minGlyphWidth)
glyphWidth = minGlyphWidth;
lineWidth += glyphWidth;
}
else
{
lineWidth += glyphWidth;
if (isJapanese && str[1] != EOS)
lineWidth += localLetterSpacing;
}
break;
case CHAR_PROMPT_SCROLL:
case CHAR_PROMPT_CLEAR:
break;
default:
glyphWidth = func(*str, isJapanese);
if (minGlyphWidth > 0)
{
if (glyphWidth < minGlyphWidth)
glyphWidth = minGlyphWidth;
lineWidth += glyphWidth;
}
else
{
lineWidth += glyphWidth;
if (isJapanese && str[1] != EOS)
lineWidth += localLetterSpacing;
}
break;
2017-03-28 02:30:49 +02:00
}
++str;
}
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
if (lineWidth > width)
return lineWidth;
2018-12-15 23:58:47 +01:00
else
return width;
2017-03-28 02:30:49 +02:00
}
u8 RenderTextFont9(u8 *pixels, u8 fontId, u8 *str)
{
u8 shadowColor;
u8 *strLocal;
int strPos;
int temp;
int temp2;
u8 colorBackup[3];
u8 fgColor;
u8 bgColor;
SaveTextColors(&colorBackup[0], &colorBackup[1], &colorBackup[2]);
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
fgColor = 1;
bgColor = 0;
shadowColor = 3;
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
GenerateFontHalfRowLookupTable(1, 0, 3);
strLocal = str;
strPos = 0;
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
do
{
temp = strLocal[strPos++];
switch (temp)
{
2018-11-05 21:42:12 +01:00
case EXT_CTRL_CODE_BEGIN:
temp2 = strLocal[strPos++];
switch (temp2)
{
case 0x4:
fgColor = strLocal[strPos++];
bgColor = strLocal[strPos++];
shadowColor = strLocal[strPos++];
GenerateFontHalfRowLookupTable(fgColor, bgColor, shadowColor);
continue;
case 0x1:
fgColor = strLocal[strPos++];
GenerateFontHalfRowLookupTable(fgColor, bgColor, shadowColor);
continue;
case 0x2:
bgColor = strLocal[strPos++];
GenerateFontHalfRowLookupTable(fgColor, bgColor, shadowColor);
continue;
case 0x3:
shadowColor = strLocal[strPos++];
GenerateFontHalfRowLookupTable(fgColor, bgColor, shadowColor);
continue;
case 0x6:
fontId = strLocal[strPos++];
2017-03-28 02:30:49 +02:00
break;
2018-11-05 21:42:12 +01:00
case 0xB:
case 0x10:
++strPos;
case 0x5:
case 0x8:
case 0xC:
case 0xD:
case 0xE:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
2017-03-28 02:30:49 +02:00
++strPos;
break;
case EXT_CTRL_CODE_UNKNOWN_7:
2018-11-05 21:42:12 +01:00
case 0x9:
case 0xA:
case 0xF:
case EXT_CTRL_CODE_JPN:
case EXT_CTRL_CODE_ENG:
2018-11-05 21:42:12 +01:00
default:
continue;
}
break;
case CHAR_SPECIAL_F7:
case CHAR_SPECIAL_F8:
case CHAR_SPECIAL_F9:
case PLACEHOLDER_BEGIN:
++strPos;
break;
case CHAR_PROMPT_SCROLL:
case CHAR_PROMPT_CLEAR:
case CHAR_NEWLINE:
case EOS:
break;
default:
switch (fontId)
{
case 9:
DecompressGlyphFont9(temp);
2017-03-28 02:30:49 +02:00
break;
2018-11-05 21:42:12 +01:00
case 1:
2017-03-28 02:30:49 +02:00
default:
2018-11-05 21:42:12 +01:00
DecompressGlyphFont1(temp, 1);
2017-03-28 02:30:49 +02:00
break;
2018-11-05 21:42:12 +01:00
}
CpuCopy32(gUnknown_03002F90.unk0, pixels, 0x20);
CpuCopy32(gUnknown_03002F90.unk40, pixels + 0x20, 0x20);
pixels += 0x40;
break;
2017-03-28 02:30:49 +02:00
}
}
2018-10-14 15:04:25 +02:00
while (temp != EOS);
2017-09-02 00:21:11 +02:00
2017-03-28 02:30:49 +02:00
RestoreTextColors(&colorBackup[0], &colorBackup[1], &colorBackup[2]);
return 1;
}
u8 DrawKeypadIcon(u8 windowId, u8 keypadIconId, u16 x, u16 y)
{
BlitBitmapRectToWindow(
windowId,
2018-11-06 18:30:21 +01:00
gKeypadIconTiles + (gKeypadIcons[keypadIconId].tileOffset * 0x20),
2017-03-28 02:30:49 +02:00
0,
0,
0x80,
0x80,
x,
y,
gKeypadIcons[keypadIconId].width,
gKeypadIcons[keypadIconId].height);
return gKeypadIcons[keypadIconId].width;
}
u8 GetKeypadIconTileOffset(u8 keypadIconId)
{
2018-11-06 18:30:21 +01:00
return gKeypadIcons[keypadIconId].tileOffset;
2017-03-28 02:30:49 +02:00
}
u8 GetKeypadIconWidth(u8 keypadIconId)
{
return gKeypadIcons[keypadIconId].width;
}
u8 GetKeypadIconHeight(u8 keypadIconId)
{
return gKeypadIcons[keypadIconId].height;
}
2017-03-28 06:20:55 +02:00
void SetDefaultFontsPointer(void)
2017-03-28 02:30:49 +02:00
{
SetFontsPointer(&gFontInfos[0]);
}
u8 GetFontAttribute(u8 fontId, u8 attributeId)
{
int result = 0;
switch (attributeId)
{
2018-07-15 13:23:38 +02:00
case FONTATTR_MAX_LETTER_WIDTH:
2017-03-28 02:30:49 +02:00
result = gFontInfos[fontId].maxLetterWidth;
break;
2018-07-15 13:23:38 +02:00
case FONTATTR_MAX_LETTER_HEIGHT:
2017-03-28 02:30:49 +02:00
result = gFontInfos[fontId].maxLetterHeight;
break;
2018-07-15 13:23:38 +02:00
case FONTATTR_LETTER_SPACING:
2017-03-28 02:30:49 +02:00
result = gFontInfos[fontId].letterSpacing;
break;
2018-07-15 13:23:38 +02:00
case FONTATTR_LINE_SPACING:
2017-03-28 02:30:49 +02:00
result = gFontInfos[fontId].lineSpacing;
break;
2018-11-06 18:30:21 +01:00
case FONTATTR_UNKNOWN:
result = gFontInfos[fontId].unk;
2017-03-28 02:30:49 +02:00
break;
2018-07-15 13:23:38 +02:00
case FONTATTR_COLOR_FOREGROUND:
2018-01-25 22:25:35 +01:00
result = gFontInfos[fontId].fgColor;
2017-03-28 02:30:49 +02:00
break;
2018-07-15 13:23:38 +02:00
case FONTATTR_COLOR_BACKGROUND:
2017-03-28 02:30:49 +02:00
result = gFontInfos[fontId].bgColor;
break;
2018-07-15 13:23:38 +02:00
case FONTATTR_COLOR_SHADOW:
2017-03-28 02:30:49 +02:00
result = gFontInfos[fontId].shadowColor;
break;
}
return result;
}
u8 GetMenuCursorDimensionByFont(u8 fontId, u8 whichDimension)
{
return gMenuCursorDimensions[fontId][whichDimension];
}
void DecompressGlyphFont0(u16 glyphId, bool32 isJapanese)
{
const u16* glyphs;
if (isJapanese == 1)
{
glyphs = gFont0JapaneseGlyphs + (0x100 * (glyphId >> 0x4)) + (0x8 * (glyphId & 0xF));
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x80, gUnknown_03002F90.unk40); // gUnknown_03002F90 + 0x40
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk80 = 8; // gGlyphWidth
gUnknown_03002F90.unk81 = 12; // gGlyphHeight
2017-03-28 02:30:49 +02:00
}
else
{
glyphs = gFont0LatinGlyphs + (0x20 * glyphId);
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk80 = gFont0LatinGlyphWidths[glyphId];
2017-09-02 00:21:11 +02:00
2018-11-05 21:42:12 +01:00
if (gUnknown_03002F90.unk80 <= 8)
2017-03-28 02:30:49 +02:00
{
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x10, gUnknown_03002F90.unk40);
2017-03-28 02:30:49 +02:00
}
else
{
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x8, gUnknown_03002F90.unk20);
DecompressGlyphTile(glyphs + 0x10, gUnknown_03002F90.unk40);
DecompressGlyphTile(glyphs + 0x18, gUnknown_03002F90.unk60);
2017-03-28 02:30:49 +02:00
}
2017-09-02 00:21:11 +02:00
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk81 = 13;
2017-03-28 02:30:49 +02:00
}
}
u32 GetGlyphWidthFont0(u16 glyphId, bool32 isJapanese)
{
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
return 8;
else
return gFont0LatinGlyphWidths[glyphId];
}
void DecompressGlyphFont7(u16 glyphId, bool32 isJapanese)
{
const u16* glyphs;
2017-09-02 00:21:11 +02:00
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
{
int eff;
glyphs = gFont1JapaneseGlyphs + (0x100 * (glyphId >> 0x4)) + (0x8 * (glyphId & (eff = 0xF))); // shh, no questions, only matching now
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x80, gUnknown_03002F90.unk40); // gUnknown_03002F90 + 0x40
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk80 = 8; // gGlyphWidth
gUnknown_03002F90.unk81 = 15; // gGlyphHeight
2017-03-28 02:30:49 +02:00
}
else
{
glyphs = gFont7LatinGlyphs + (0x20 * glyphId);
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk80 = gFont7LatinGlyphWidths[glyphId];
2017-09-02 00:21:11 +02:00
2018-11-05 21:42:12 +01:00
if (gUnknown_03002F90.unk80 <= 8)
2017-03-28 02:30:49 +02:00
{
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x10, gUnknown_03002F90.unk40);
2017-03-28 02:30:49 +02:00
}
else
{
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x8, gUnknown_03002F90.unk20);
DecompressGlyphTile(glyphs + 0x10, gUnknown_03002F90.unk40);
DecompressGlyphTile(glyphs + 0x18, gUnknown_03002F90.unk60);
2017-03-28 02:30:49 +02:00
}
2017-09-02 00:21:11 +02:00
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk81 = 15;
2017-03-28 02:30:49 +02:00
}
}
u32 GetGlyphWidthFont7(u16 glyphId, bool32 isJapanese)
{
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
return 8;
else
return gFont7LatinGlyphWidths[glyphId];
}
void DecompressGlyphFont8(u16 glyphId, bool32 isJapanese)
{
const u16* glyphs;
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
{
glyphs = gFont0JapaneseGlyphs + (0x100 * (glyphId >> 0x4)) + (0x8 * (glyphId & 0xF));
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x80, gUnknown_03002F90.unk40); // gUnknown_03002F90 + 0x40
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk80 = 8; // gGlyphWidth
gUnknown_03002F90.unk81 = 12; // gGlyphHeight
2017-03-28 02:30:49 +02:00
}
else
{
glyphs = gFont8LatinGlyphs + (0x20 * glyphId);
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk80 = gFont8LatinGlyphWidths[glyphId];
2017-09-02 00:21:11 +02:00
2018-11-05 21:42:12 +01:00
if (gUnknown_03002F90.unk80 <= 8)
2017-03-28 02:30:49 +02:00
{
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x10, gUnknown_03002F90.unk40);
2017-03-28 02:30:49 +02:00
}
else
{
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x8, gUnknown_03002F90.unk20);
DecompressGlyphTile(glyphs + 0x10, gUnknown_03002F90.unk40);
DecompressGlyphTile(glyphs + 0x18, gUnknown_03002F90.unk60);
2017-03-28 02:30:49 +02:00
}
2017-09-02 00:21:11 +02:00
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk81 = 12;
2017-03-28 02:30:49 +02:00
}
}
u32 GetGlyphWidthFont8(u16 glyphId, bool32 isJapanese)
{
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
return 8;
else
return gFont8LatinGlyphWidths[glyphId];
}
void DecompressGlyphFont2(u16 glyphId, bool32 isJapanese)
{
const u16* glyphs;
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
{
glyphs = gFont2JapaneseGlyphs + (0x100 * (glyphId >> 0x3)) + (0x10 * (glyphId & 0x7));
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x8, gUnknown_03002F90.unk20); // gUnknown_03002F90 + 0x40
DecompressGlyphTile(glyphs + 0x80, gUnknown_03002F90.unk40); // gUnknown_03002F90 + 0x20
DecompressGlyphTile(glyphs + 0x88, gUnknown_03002F90.unk60); // gUnknown_03002F90 + 0x60
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk80 = gFont2JapaneseGlyphWidths[glyphId]; // gGlyphWidth
gUnknown_03002F90.unk81 = 14; // gGlyphHeight
2017-03-28 02:30:49 +02:00
}
else
{
glyphs = gFont2LatinGlyphs + (0x20 * glyphId);
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk80 = gFont2LatinGlyphWidths[glyphId];
2017-09-02 00:21:11 +02:00
2018-11-05 21:42:12 +01:00
if (gUnknown_03002F90.unk80 <= 8)
2017-03-28 02:30:49 +02:00
{
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x10, gUnknown_03002F90.unk40);
2017-03-28 02:30:49 +02:00
}
else
{
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x8, gUnknown_03002F90.unk20);
DecompressGlyphTile(glyphs + 0x10, gUnknown_03002F90.unk40);
DecompressGlyphTile(glyphs + 0x18, gUnknown_03002F90.unk60);
2017-03-28 02:30:49 +02:00
}
2017-09-02 00:21:11 +02:00
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk81 = 14;
2017-03-28 02:30:49 +02:00
}
}
u32 GetGlyphWidthFont2(u16 glyphId, bool32 isJapanese)
{
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
return gFont2JapaneseGlyphWidths[glyphId];
else
return gFont2LatinGlyphWidths[glyphId];
}
void DecompressGlyphFont1(u16 glyphId, bool32 isJapanese)
{
const u16* glyphs;
2017-09-02 00:21:11 +02:00
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
{
int eff;
glyphs = gFont1JapaneseGlyphs + (0x100 * (glyphId >> 0x4)) + (0x8 * (glyphId & (eff = 0xF))); // shh, no questions, only matching now
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x80, gUnknown_03002F90.unk40); // gUnknown_03002F90 + 0x40
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk80 = 8; // gGlyphWidth
gUnknown_03002F90.unk81 = 15; // gGlyphHeight
2017-03-28 02:30:49 +02:00
}
else
{
glyphs = gFont1LatinGlyphs + (0x20 * glyphId);
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk80 = gFont1LatinGlyphWidths[glyphId];
2017-09-02 00:21:11 +02:00
2018-11-05 21:42:12 +01:00
if (gUnknown_03002F90.unk80 <= 8)
2017-03-28 02:30:49 +02:00
{
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x10, gUnknown_03002F90.unk40);
2017-03-28 02:30:49 +02:00
}
else
{
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x8, gUnknown_03002F90.unk20);
DecompressGlyphTile(glyphs + 0x10, gUnknown_03002F90.unk40);
DecompressGlyphTile(glyphs + 0x18, gUnknown_03002F90.unk60);
2017-03-28 02:30:49 +02:00
}
2017-09-02 00:21:11 +02:00
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk81 = 15;
2017-03-28 02:30:49 +02:00
}
}
u32 GetGlyphWidthFont1(u16 glyphId, bool32 isJapanese)
{
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
return 8;
else
return gFont1LatinGlyphWidths[glyphId];
}
void DecompressGlyphFont9(u16 glyphId)
{
const u16* glyphs;
glyphs = gFont9JapaneseGlyphs + (0x100 * (glyphId >> 4)) + (0x8 * (glyphId & 0xF));
2018-11-21 21:58:35 +01:00
DecompressGlyphTile(glyphs, gUnknown_03002F90.unk0);
DecompressGlyphTile(glyphs + 0x80, gUnknown_03002F90.unk40);
2018-11-05 21:42:12 +01:00
gUnknown_03002F90.unk80 = 8;
gUnknown_03002F90.unk81 = 12;
2017-03-28 02:30:49 +02:00
}