pokeemerald/gflib/text.c

1927 lines
64 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"
2021-10-31 06:44:18 +01:00
#include "fonts.h"
2017-03-07 14:44:41 +01:00
2021-11-14 15:55:30 +01:00
static u16 RenderText(struct TextPrinter *);
static u32 RenderFont(struct TextPrinter *);
2021-10-30 22:47:37 +02:00
static u16 FontFunc_Small(struct TextPrinter *);
static u16 FontFunc_Normal(struct TextPrinter *);
static u16 FontFunc_Short(struct TextPrinter *);
static u16 FontFunc_ShortCopy1(struct TextPrinter *);
static u16 FontFunc_ShortCopy2(struct TextPrinter *);
static u16 FontFunc_ShortCopy3(struct TextPrinter *);
static u16 FontFunc_Narrow(struct TextPrinter *);
static u16 FontFunc_SmallNarrow(struct TextPrinter *);
2021-11-14 15:55:30 +01:00
static void DecompressGlyph_Small(u16, bool32);
static void DecompressGlyph_Normal(u16, bool32);
static void DecompressGlyph_Short(u16, bool32);
static void DecompressGlyph_Narrow(u16, bool32);
static void DecompressGlyph_SmallNarrow(u16, bool32);
static void DecompressGlyph_Bold(u16);
static u32 GetGlyphWidth_Small(u16, bool32);
static u32 GetGlyphWidth_Normal(u16, bool32);
static u32 GetGlyphWidth_Short(u16, bool32);
static u32 GetGlyphWidth_Narrow(u16, bool32);
static u32 GetGlyphWidth_SmallNarrow(u16, bool32);
static EWRAM_DATA struct TextPrinter sTempTextPrinter = {0};
static EWRAM_DATA struct TextPrinter sTextPrinters[WINDOWS_MAX] = {0};
2021-11-14 15:55:30 +01:00
static u16 sFontHalfRowLookupTable[0x51];
static u16 sLastTextBgColor;
static u16 sLastTextFgColor;
static u16 sLastTextShadowColor;
2017-03-07 14:44:41 +01:00
2017-03-28 06:20:55 +02:00
const struct FontInfo *gFonts;
bool8 gDisableTextPrinters;
2021-03-29 18:20:00 +02:00
struct TextGlyph gCurGlyph;
2017-09-22 05:43:13 +02:00
TextFlags gTextFlags;
2017-03-28 02:30:49 +02:00
2021-11-14 15:55:30 +01:00
static const u8 sFontHalfRowOffsets[] =
2018-11-21 21:58:35 +01:00
{
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
};
2021-11-14 15:55:30 +01:00
static const u8 sDownArrowTiles[] = INCBIN_U8("graphics/fonts/down_arrow.4bpp");
static const u8 sDarkDownArrowTiles[] = INCBIN_U8("graphics/fonts/down_arrow_alt.4bpp");
static const u8 sUnusedFRLGBlankedDownArrow[] = INCBIN_U8("graphics/fonts/unused_frlg_blanked_down_arrow.4bpp");
static const u8 sUnusedFRLGDownArrow[] = INCBIN_U8("graphics/fonts/unused_frlg_down_arrow.4bpp");
static const u8 sDownArrowYCoords[] = { 0, 1, 2, 1 };
2022-09-11 20:14:49 +02:00
static const u8 sWindowVerticalScrollSpeeds[] = {
2021-11-14 15:55:30 +01:00
[OPTIONS_TEXT_SPEED_SLOW] = 1,
[OPTIONS_TEXT_SPEED_MID] = 2,
[OPTIONS_TEXT_SPEED_FAST] = 4,
};
2017-03-28 02:30:49 +02:00
2021-10-30 22:47:37 +02:00
static const struct GlyphWidthFunc sGlyphWidthFuncs[] =
2018-11-21 21:58:35 +01:00
{
2021-10-30 22:47:37 +02:00
{ FONT_SMALL, GetGlyphWidth_Small },
{ FONT_NORMAL, GetGlyphWidth_Normal },
{ FONT_SHORT, GetGlyphWidth_Short },
{ FONT_SHORT_COPY_1, GetGlyphWidth_Short },
{ FONT_SHORT_COPY_2, GetGlyphWidth_Short },
{ FONT_SHORT_COPY_3, GetGlyphWidth_Short },
{ FONT_BRAILLE, GetGlyphWidth_Braille },
{ FONT_NARROW, GetGlyphWidth_Narrow },
{ FONT_SMALL_NARROW, GetGlyphWidth_SmallNarrow }
2017-03-28 02:30:49 +02:00
};
2021-11-14 15:55:30 +01:00
struct
{
u16 tileOffset;
u8 width;
u8 height;
} static const sKeypadIcons[] =
2018-11-21 21:58:35 +01:00
{
2021-11-14 15:55:30 +01:00
[CHAR_A_BUTTON] = { 0x00, 8, 12 },
[CHAR_B_BUTTON] = { 0x01, 8, 12 },
[CHAR_L_BUTTON] = { 0x02, 16, 12 },
[CHAR_R_BUTTON] = { 0x04, 16, 12 },
[CHAR_START_BUTTON] = { 0x06, 24, 12 },
[CHAR_SELECT_BUTTON] = { 0x09, 24, 12 },
[CHAR_DPAD_UP] = { 0x0C, 8, 12 },
[CHAR_DPAD_DOWN] = { 0x0D, 8, 12 },
[CHAR_DPAD_LEFT] = { 0x0E, 8, 12 },
[CHAR_DPAD_RIGHT] = { 0x0F, 8, 12 },
[CHAR_DPAD_UPDOWN] = { 0x20, 8, 12 },
[CHAR_DPAD_LEFTRIGHT] = { 0x21, 8, 12 },
[CHAR_DPAD_NONE] = { 0x22, 8, 12 }
2017-03-28 02:30:49 +02:00
};
2021-11-14 15:55:30 +01:00
static const u8 sKeypadIconTiles[] = INCBIN_U8("graphics/fonts/keypad_icons.4bpp");
2017-03-08 21:44:44 +01:00
2021-10-30 22:47:37 +02:00
static const struct FontInfo sFontInfos[] =
2018-11-21 21:58:35 +01:00
{
2021-10-30 22:47:37 +02:00
[FONT_SMALL] = {
.fontFunction = FontFunc_Small,
.maxLetterWidth = 5,
.maxLetterHeight = 12,
.letterSpacing = 0,
.lineSpacing = 0,
.fgColor = 2,
.bgColor = 1,
.shadowColor = 3,
},
[FONT_NORMAL] = {
.fontFunction = FontFunc_Normal,
.maxLetterWidth = 6,
.maxLetterHeight = 16,
.letterSpacing = 0,
.lineSpacing = 0,
.fgColor = 2,
.bgColor = 1,
.shadowColor = 3,
},
[FONT_SHORT] = {
.fontFunction = FontFunc_Short,
.maxLetterWidth = 6,
.maxLetterHeight = 14,
.letterSpacing = 0,
.lineSpacing = 0,
.fgColor = 2,
.bgColor = 1,
.shadowColor = 3,
},
[FONT_SHORT_COPY_1] = {
.fontFunction = FontFunc_ShortCopy1,
.maxLetterWidth = 6,
.maxLetterHeight = 14,
.letterSpacing = 0,
.lineSpacing = 0,
.fgColor = 2,
.bgColor = 1,
.shadowColor = 3,
},
[FONT_SHORT_COPY_2] = {
.fontFunction = FontFunc_ShortCopy2,
.maxLetterWidth = 6,
.maxLetterHeight = 14,
.letterSpacing = 0,
.lineSpacing = 0,
.fgColor = 2,
.bgColor = 1,
.shadowColor = 3,
},
[FONT_SHORT_COPY_3] = {
.fontFunction = FontFunc_ShortCopy3,
.maxLetterWidth = 6,
.maxLetterHeight = 14,
.letterSpacing = 0,
.lineSpacing = 0,
.fgColor = 2,
.bgColor = 1,
.shadowColor = 3,
},
[FONT_BRAILLE] = {
.fontFunction = FontFunc_Braille,
.maxLetterWidth = 8,
.maxLetterHeight = 16,
.letterSpacing = 0,
.lineSpacing = 8,
.fgColor = 2,
.bgColor = 1,
.shadowColor = 3,
},
[FONT_NARROW] = {
.fontFunction = FontFunc_Narrow,
.maxLetterWidth = 5,
.maxLetterHeight = 16,
.letterSpacing = 0,
.lineSpacing = 0,
.fgColor = 2,
.bgColor = 1,
.shadowColor = 3,
},
[FONT_SMALL_NARROW] = {
.fontFunction = FontFunc_SmallNarrow,
.maxLetterWidth = 5,
.maxLetterHeight = 8,
.letterSpacing = 0,
.lineSpacing = 0,
.fgColor = 2,
.bgColor = 1,
.shadowColor = 3,
},
[FONT_BOLD] = {
.fontFunction = NULL,
.maxLetterWidth = 8,
.maxLetterHeight = 8,
.letterSpacing = 0,
.lineSpacing = 0,
.fgColor = 1,
.bgColor = 2,
.shadowColor = 15,
}
2017-03-28 02:30:49 +02:00
};
2017-03-07 14:44:41 +01:00
2021-10-30 22:47:37 +02:00
static const u8 sMenuCursorDimensions[][2] =
2018-11-21 21:58:35 +01:00
{
2021-10-30 22:47:37 +02:00
[FONT_SMALL] = { 8, 12 },
[FONT_NORMAL] = { 8, 15 },
[FONT_SHORT] = { 8, 14 },
[FONT_SHORT_COPY_1] = { 8, 14 },
[FONT_SHORT_COPY_2] = { 8, 14 },
[FONT_SHORT_COPY_3] = { 8, 14 },
[FONT_BRAILLE] = { 8, 16 },
[FONT_NARROW] = { 8, 15 },
[FONT_SMALL_NARROW] = { 8, 8 },
[FONT_BOLD] = {}
2017-03-28 02:30:49 +02:00
};
2021-11-14 15:55:30 +01:00
static const u16 sFontBoldJapaneseGlyphs[] = INCBIN_U16("graphics/fonts/bold.hwjpnfont");
2021-10-30 22:47:37 +02:00
static 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 < WINDOWS_MAX; ++printer)
2021-11-14 15:55:30 +01:00
sTextPrinters[printer].active = FALSE;
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;
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;
if (!gFonts)
return FALSE;
2017-09-02 00:21:11 +02:00
2021-11-14 15:55:30 +01:00
sTempTextPrinter.active = TRUE;
sTempTextPrinter.state = RENDER_STATE_HANDLE_CHAR;
sTempTextPrinter.textSpeed = speed;
sTempTextPrinter.delayCounter = 0;
sTempTextPrinter.scrollDistance = 0;
2017-09-02 00:21:11 +02:00
2021-11-14 15:55:30 +01:00
for (i = 0; i < (int)ARRAY_COUNT(sTempTextPrinter.subStructFields); i++)
sTempTextPrinter.subStructFields[i] = 0;
2017-09-02 00:21:11 +02:00
2021-11-14 15:55:30 +01:00
sTempTextPrinter.printerTemplate = *printerTemplate;
sTempTextPrinter.callback = callback;
sTempTextPrinter.minLetterSpacing = 0;
sTempTextPrinter.japanese = 0;
2017-03-07 14:44:41 +01:00
2018-11-06 17:44:48 +01:00
GenerateFontHalfRowLookupTable(printerTemplate->fgColor, printerTemplate->bgColor, printerTemplate->shadowColor);
if (speed != TEXT_SKIP_DRAW && speed != 0)
2017-03-07 14:44:41 +01:00
{
2021-11-14 15:55:30 +01:00
--sTempTextPrinter.textSpeed;
sTextPrinters[printerTemplate->windowId] = sTempTextPrinter;
2017-03-07 14:44:41 +01:00
}
else
{
2021-11-14 15:55:30 +01:00
sTempTextPrinter.textSpeed = 0;
2022-09-11 20:14:49 +02:00
// Render all text (up to limit) at once
2017-03-07 14:44:41 +01:00
for (j = 0; j < 0x400; ++j)
{
2021-11-14 15:55:30 +01:00
if (RenderFont(&sTempTextPrinter) == RENDER_FINISH)
2017-03-07 14:44:41 +01:00
break;
}
2017-09-02 00:21:11 +02:00
// All the text is rendered to the window but don't draw it yet.
if (speed != TEXT_SKIP_DRAW)
2021-11-14 15:55:30 +01:00
CopyWindowToVram(sTempTextPrinter.printerTemplate.windowId, COPYWIN_GFX);
sTextPrinters[printerTemplate->windowId].active = FALSE;
2017-03-07 14:44:41 +01:00
}
gDisableTextPrinters = FALSE;
2017-03-07 14:44:41 +01:00
return TRUE;
}
2017-03-08 21:44:44 +01:00
void RunTextPrinters(void)
{
int i;
if (!gDisableTextPrinters)
2017-03-08 21:44:44 +01:00
{
for (i = 0; i < WINDOWS_MAX; ++i)
2017-03-08 21:44:44 +01:00
{
2021-11-14 15:55:30 +01:00
if (sTextPrinters[i].active)
2017-03-08 21:44:44 +01:00
{
2022-06-01 18:41:57 +02:00
u16 renderCmd = RenderFont(&sTextPrinters[i]);
2023-11-12 02:43:13 +01:00
CopyWindowToVram(sTextPrinters[i].printerTemplate.windowId, COPYWIN_GFX);
2022-06-01 18:41:57 +02:00
switch (renderCmd)
2018-11-21 21:58:35 +01:00
{
case RENDER_PRINT:
case RENDER_UPDATE:
2022-06-01 18:41:57 +02:00
if (sTextPrinters[i].callback != NULL)
sTextPrinters[i].callback(&sTextPrinters[i].printerTemplate, renderCmd);
2018-11-21 21:58:35 +01:00
break;
case RENDER_FINISH:
2021-11-14 15:55:30 +01:00
sTextPrinters[i].active = FALSE;
2018-11-21 21:58:35 +01:00
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
{
2021-11-14 15:55:30 +01:00
return sTextPrinters[id].active;
2017-03-08 21:44:44 +01:00
}
static u32 RenderFont(struct TextPrinter *textPrinter)
2017-03-08 21:44:44 +01:00
{
u32 ret;
while (TRUE)
{
2018-11-06 17:44:48 +01:00
ret = gFonts[textPrinter->printerTemplate.fontId].fontFunction(textPrinter);
if (ret != RENDER_REPEAT)
2017-03-08 21:44:44 +01:00
return ret;
}
}
void GenerateFontHalfRowLookupTable(u8 fgColor, u8 bgColor, u8 shadowColor)
{
2018-11-25 20:16:41 +01:00
u32 fg12, bg12, shadow12;
u32 temp;
2021-11-14 15:55:30 +01:00
u16 *current = sFontHalfRowLookupTable;
2017-09-02 00:21:11 +02:00
2021-11-14 15:55:30 +01:00
sLastTextBgColor = bgColor;
sLastTextFgColor = fgColor;
sLastTextShadowColor = 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)
{
2021-11-14 15:55:30 +01:00
*bgColor = sLastTextBgColor;
*fgColor = sLastTextFgColor;
*shadowColor = sLastTextShadowColor;
2017-03-08 21:44:44 +01:00
}
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++);
2021-11-14 15:55:30 +01:00
*(dest)++ = ((sFontHalfRowLookupTable[sFontHalfRowOffsets[temp & 0xFF]]) << 16) | (sFontHalfRowLookupTable[sFontHalfRowOffsets[temp >> 8]]);
2017-09-02 00:21:11 +02:00
2018-11-21 23:30:04 +01:00
temp = *(src++);
2021-11-14 15:55:30 +01:00
*(dest++) = ((sFontHalfRowLookupTable[sFontHalfRowOffsets[temp & 0xFF]]) << 16) | (sFontHalfRowLookupTable[sFontHalfRowOffsets[temp >> 8]]);
2018-11-21 21:58:35 +01:00
2017-03-08 21:44:44 +01:00
temp = *(src++);
2021-11-14 15:55:30 +01:00
*(dest++) = ((sFontHalfRowLookupTable[sFontHalfRowOffsets[temp & 0xFF]]) << 16) | (sFontHalfRowLookupTable[sFontHalfRowOffsets[temp >> 8]]);
2018-11-21 21:58:35 +01:00
2017-03-08 21:44:44 +01:00
temp = *(src++);
2021-11-14 15:55:30 +01:00
*(dest++) = ((sFontHalfRowLookupTable[sFontHalfRowOffsets[temp & 0xFF]]) << 16) | (sFontHalfRowLookupTable[sFontHalfRowOffsets[temp >> 8]]);
2018-11-21 21:58:35 +01:00
2017-03-08 21:44:44 +01:00
temp = *(src++);
2021-11-14 15:55:30 +01:00
*(dest++) = ((sFontHalfRowLookupTable[sFontHalfRowOffsets[temp & 0xFF]]) << 16) | (sFontHalfRowLookupTable[sFontHalfRowOffsets[temp >> 8]]);
2018-11-21 21:58:35 +01:00
2017-03-08 21:44:44 +01:00
temp = *(src++);
2021-11-14 15:55:30 +01:00
*(dest++) = ((sFontHalfRowLookupTable[sFontHalfRowOffsets[temp & 0xFF]]) << 16) | (sFontHalfRowLookupTable[sFontHalfRowOffsets[temp >> 8]]);
2018-11-21 21:58:35 +01:00
temp = *(src++);
2021-11-14 15:55:30 +01:00
*(dest++) = ((sFontHalfRowLookupTable[sFontHalfRowOffsets[temp & 0xFF]]) << 16) | (sFontHalfRowLookupTable[sFontHalfRowOffsets[temp >> 8]]);
2018-11-21 21:58:35 +01:00
temp = *(src++);
2021-11-14 15:55:30 +01:00
*(dest++) = ((sFontHalfRowLookupTable[sFontHalfRowOffsets[temp & 0xFF]]) << 16) | (sFontHalfRowLookupTable[sFontHalfRowOffsets[temp >> 8]]);
2017-03-08 21:44:44 +01:00
}
2021-11-14 15:55:30 +01:00
// Unused
static u8 GetLastTextColor(u8 colorType)
2017-03-08 21:44:44 +01:00
{
switch (colorType)
{
case 0:
2021-11-14 15:55:30 +01:00
return sLastTextFgColor;
case 2:
2021-11-14 15:55:30 +01:00
return sLastTextBgColor;
case 1:
2021-11-14 15:55:30 +01:00
return sLastTextShadowColor;
2018-11-21 21:58:35 +01:00
default:
return 0;
2017-03-08 21:44:44 +01:00
}
}
2021-03-29 18:20:00 +02:00
inline static void GLYPH_COPY(u8 *windowTiles, u32 widthOffset, u32 j, u32 i, u32 *glyphPixels, s32 width, s32 height)
2020-10-21 10:26:45 +02:00
{
2021-03-29 18:20:00 +02:00
u32 xAdd, yAdd, pixelData, bits, toOrr, dummyX;
2020-10-21 10:26:45 +02:00
u8 *dst;
xAdd = j + width;
yAdd = i + height;
dummyX = j;
for (; i < yAdd; i++)
{
2021-03-29 18:20:00 +02:00
pixelData = *glyphPixels++;
2020-10-21 10:26:45 +02:00
for (j = dummyX; j < xAdd; j++)
{
2021-03-29 18:20:00 +02:00
if ((toOrr = pixelData & 0xF))
2020-10-21 10:26:45 +02:00
{
dst = windowTiles + ((j / 8) * 32) + ((j % 8) / 2) + ((i / 8) * widthOffset) + ((i % 8) * 4);
bits = ((j & 1) * 4);
*dst = (toOrr << bits) | (*dst & (0xF0 >> bits));
}
2021-03-29 18:20:00 +02:00
pixelData >>= 4;
2020-10-21 10:26:45 +02:00
}
}
}
2020-08-03 20:21:51 +02:00
void CopyGlyphToWindow(struct TextPrinter *textPrinter)
{
2021-03-29 18:20:00 +02:00
struct Window *window;
struct WindowTemplate *template;
u32 *glyphPixels;
2020-10-21 10:26:45 +02:00
u32 currX, currY, widthOffset;
2021-03-29 18:20:00 +02:00
s32 glyphWidth, glyphHeight;
u8 *windowTiles;
2021-03-29 18:20:00 +02:00
window = &gWindows[textPrinter->printerTemplate.windowId];
template = &window->window;
2021-03-29 18:20:00 +02:00
if ((glyphWidth = (template->width * 8) - textPrinter->printerTemplate.currentX) > gCurGlyph.width)
glyphWidth = gCurGlyph.width;
2021-03-29 18:20:00 +02:00
if ((glyphHeight = (template->height * 8) - textPrinter->printerTemplate.currentY) > gCurGlyph.height)
glyphHeight = gCurGlyph.height;
currX = textPrinter->printerTemplate.currentX;
currY = textPrinter->printerTemplate.currentY;
2021-03-29 18:20:00 +02:00
glyphPixels = gCurGlyph.gfxBufferTop;
windowTiles = window->tileData;
widthOffset = template->width * 32;
2021-03-29 18:20:00 +02:00
if (glyphWidth < 9)
{
2021-03-29 18:20:00 +02:00
if (glyphHeight < 9)
{
2021-03-29 18:20:00 +02:00
GLYPH_COPY(windowTiles, widthOffset, currX, currY, glyphPixels, glyphWidth, glyphHeight);
}
else
{
2021-03-29 18:20:00 +02:00
GLYPH_COPY(windowTiles, widthOffset, currX, currY, glyphPixels, glyphWidth, 8);
GLYPH_COPY(windowTiles, widthOffset, currX, currY + 8, glyphPixels + 16, glyphWidth, glyphHeight - 8);
}
}
else
{
2021-03-29 18:20:00 +02:00
if (glyphHeight < 9)
{
2021-03-29 18:20:00 +02:00
GLYPH_COPY(windowTiles, widthOffset, currX, currY, glyphPixels, 8, glyphHeight);
GLYPH_COPY(windowTiles, widthOffset, currX + 8, currY, glyphPixels + 8, glyphWidth - 8, glyphHeight);
}
else
{
2021-03-29 18:20:00 +02:00
GLYPH_COPY(windowTiles, widthOffset, currX, currY, glyphPixels, 8, 8);
GLYPH_COPY(windowTiles, widthOffset, currX + 8, currY, glyphPixels + 8, glyphWidth - 8, 8);
GLYPH_COPY(windowTiles, widthOffset, currX, currY + 8, glyphPixels + 16, 8, glyphHeight - 8);
GLYPH_COPY(windowTiles, widthOffset, currX + 8, currY + 8, glyphPixels + 24, glyphWidth - 8, glyphHeight - 8);
}
}
}
2017-03-28 02:30:49 +02:00
void ClearTextSpan(struct TextPrinter *textPrinter, u32 width)
{
struct Window *window;
struct Bitmap pixels_data;
2021-03-29 18:20:00 +02:00
struct TextGlyph *glyph;
u8 *glyphHeight;
2017-03-28 02:30:49 +02:00
2021-11-14 15:55:30 +01:00
if (sLastTextBgColor != TEXT_COLOR_TRANSPARENT)
2017-03-28 02:30:49 +02:00
{
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
2021-03-29 18:20:00 +02:00
glyph = &gCurGlyph;
glyphHeight = &glyph->height;
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,
2021-11-14 15:55:30 +01:00
sLastTextBgColor);
2017-03-28 02:30:49 +02:00
}
}
2021-10-30 22:47:37 +02:00
static u16 FontFunc_Small(struct TextPrinter *textPrinter)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2021-10-30 22:47:37 +02:00
if (subStruct->hasFontIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2021-10-30 22:47:37 +02:00
subStruct->fontId = FONT_SMALL;
subStruct->hasFontIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
2021-10-30 22:47:37 +02:00
static u16 FontFunc_Normal(struct TextPrinter *textPrinter)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2021-10-30 22:47:37 +02:00
if (subStruct->hasFontIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2021-10-30 22:47:37 +02:00
subStruct->fontId = FONT_NORMAL;
subStruct->hasFontIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
2021-10-30 22:47:37 +02:00
static u16 FontFunc_Short(struct TextPrinter *textPrinter)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2021-10-30 22:47:37 +02:00
if (subStruct->hasFontIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2021-10-30 22:47:37 +02:00
subStruct->fontId = FONT_SHORT;
subStruct->hasFontIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
2017-03-08 21:44:44 +01:00
2021-10-30 22:47:37 +02:00
static u16 FontFunc_ShortCopy1(struct TextPrinter *textPrinter)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2021-10-30 22:47:37 +02:00
if (subStruct->hasFontIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2021-10-30 22:47:37 +02:00
subStruct->fontId = FONT_SHORT_COPY_1;
subStruct->hasFontIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
2021-10-30 22:47:37 +02:00
static u16 FontFunc_ShortCopy2(struct TextPrinter *textPrinter)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2021-10-30 22:47:37 +02:00
if (subStruct->hasFontIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2021-10-30 22:47:37 +02:00
subStruct->fontId = FONT_SHORT_COPY_2;
subStruct->hasFontIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
2021-10-30 22:47:37 +02:00
static u16 FontFunc_ShortCopy3(struct TextPrinter *textPrinter)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2021-10-30 22:47:37 +02:00
if (subStruct->hasFontIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2021-10-30 22:47:37 +02:00
subStruct->fontId = FONT_SHORT_COPY_3;
subStruct->hasFontIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
2021-10-30 22:47:37 +02:00
static u16 FontFunc_Narrow(struct TextPrinter *textPrinter)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2021-10-30 22:47:37 +02:00
if (subStruct->hasFontIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2021-10-30 22:47:37 +02:00
subStruct->fontId = FONT_NARROW;
subStruct->hasFontIdBeenSet = TRUE;
2017-03-28 02:30:49 +02:00
}
return RenderText(textPrinter);
}
2021-10-30 22:47:37 +02:00
static u16 FontFunc_SmallNarrow(struct TextPrinter *textPrinter)
2017-03-28 02:30:49 +02:00
{
2020-05-21 04:07:49 +02:00
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
2017-09-02 00:21:11 +02:00
2021-10-30 22:47:37 +02:00
if (subStruct->hasFontIdBeenSet == FALSE)
2017-03-28 02:30:49 +02:00
{
2021-10-30 22:47:37 +02:00
subStruct->fontId = FONT_SMALL_NARROW;
subStruct->hasFontIdBeenSet = 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
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;
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
{
2021-11-14 15:55:30 +01:00
case FALSE:
default:
arrowTiles = sDownArrowTiles;
break;
case TRUE:
arrowTiles = sDarkDownArrowTiles;
break;
2017-03-28 02:30:49 +02:00
}
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,
2021-11-14 15:55:30 +01:00
sDownArrowYCoords[subStruct->downArrowYPosIdx],
2020-05-21 04:07:49 +02:00
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);
2021-11-03 20:29:18 +01:00
CopyWindowToVram(textPrinter->printerTemplate.windowId, COPYWIN_GFX);
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);
2021-11-03 20:29:18 +01:00
CopyWindowToVram(textPrinter->printerTemplate.windowId, COPYWIN_GFX);
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;
if (gTextFlags.autoScroll != 0)
2017-03-28 02:30:49 +02:00
{
result = TextPrinterWaitAutoMode(textPrinter);
}
else
{
TextPrinterDrawDownArrow(textPrinter);
if (JOY_NEW(A_BUTTON | B_BUTTON))
2017-03-28 02:30:49 +02:00
{
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;
if (gTextFlags.autoScroll != 0)
2017-03-28 02:30:49 +02:00
{
result = TextPrinterWaitAutoMode(textPrinter);
}
else
2017-03-28 02:30:49 +02:00
{
if (JOY_NEW(A_BUTTON | B_BUTTON))
{
result = TRUE;
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)
2017-03-28 02:30:49 +02:00
{
2018-11-06 18:30:21 +01:00
switch (gTextFlags.useAlternateDownArrow)
2017-03-28 02:30:49 +02:00
{
2021-11-14 15:55:30 +01:00
case FALSE:
default:
arrowTiles = sDownArrowTiles;
break;
case TRUE:
arrowTiles = sDarkDownArrowTiles;
break;
2017-03-28 02:30:49 +02:00
}
2017-09-02 00:21:11 +02:00
2021-11-14 15:55:30 +01:00
BlitBitmapRectToWindow(windowId, arrowTiles, 0, sDownArrowYCoords[*yCoordIndex & 3], 8, 16, x, y - 2, 8, 16);
2021-11-03 20:29:18 +01:00
CopyWindowToVram(windowId, COPYWIN_GFX);
2017-03-28 02:30:49 +02:00
*counter = 8;
++*yCoordIndex;
}
}
}
2018-11-04 23:09:10 +01:00
static u16 RenderText(struct TextPrinter *textPrinter)
2018-01-24 22:45:37 +01:00
{
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;
2023-11-12 02:43:13 +01:00
u8 repeats;
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
{
case RENDER_STATE_HANDLE_CHAR:
2021-11-14 15:55:30 +01:00
if (JOY_HELD(A_BUTTON | B_BUTTON) && subStruct->hasPrintBeenSpedUp)
textPrinter->delayCounter = 0;
2018-11-05 21:42:12 +01:00
if (textPrinter->delayCounter && textPrinter->textSpeed)
{
textPrinter->delayCounter--;
if (gTextFlags.canABSpeedUpPrint && (JOY_NEW(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 RENDER_UPDATE;
}
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;
2023-11-12 02:43:13 +01:00
switch (GetPlayerTextSpeed())
{
2023-11-12 02:43:13 +01:00
case OPTIONS_TEXT_SPEED_SLOW:
repeats = 1;
break;
case OPTIONS_TEXT_SPEED_MID:
repeats = 2;
break;
case OPTIONS_TEXT_SPEED_FAST:
repeats = 4;
break;
}
do {
2018-11-06 17:44:48 +01:00
currChar = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
2023-11-12 02:43:13 +01:00
2018-11-04 23:09:10 +01:00
switch (currChar)
2018-01-24 22:45:37 +01:00
{
2023-11-12 02:43:13 +01:00
case CHAR_NEWLINE:
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentX = textPrinter->printerTemplate.x;
2023-11-12 02:43:13 +01:00
textPrinter->printerTemplate.currentY += (gFonts[textPrinter->printerTemplate.fontId].maxLetterHeight + textPrinter->printerTemplate.lineSpacing);
return RENDER_REPEAT;
2023-11-12 02:43:13 +01:00
case PLACEHOLDER_BEGIN:
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentChar++;
return RENDER_REPEAT;
2023-11-12 02:43:13 +01:00
case EXT_CTRL_CODE_BEGIN:
currChar = *textPrinter->printerTemplate.currentChar;
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentChar++;
2023-11-12 02:43:13 +01:00
switch (currChar)
2018-01-24 22:45:37 +01:00
{
2023-11-12 02:43:13 +01:00
case EXT_CTRL_CODE_COLOR:
textPrinter->printerTemplate.fgColor = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
GenerateFontHalfRowLookupTable(textPrinter->printerTemplate.fgColor, textPrinter->printerTemplate.bgColor, textPrinter->printerTemplate.shadowColor);
return RENDER_REPEAT;
case EXT_CTRL_CODE_HIGHLIGHT:
textPrinter->printerTemplate.bgColor = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
GenerateFontHalfRowLookupTable(textPrinter->printerTemplate.fgColor, textPrinter->printerTemplate.bgColor, textPrinter->printerTemplate.shadowColor);
return RENDER_REPEAT;
case EXT_CTRL_CODE_SHADOW:
textPrinter->printerTemplate.shadowColor = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
GenerateFontHalfRowLookupTable(textPrinter->printerTemplate.fgColor, textPrinter->printerTemplate.bgColor, textPrinter->printerTemplate.shadowColor);
return RENDER_REPEAT;
case EXT_CTRL_CODE_COLOR_HIGHLIGHT_SHADOW:
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 RENDER_REPEAT;
case EXT_CTRL_CODE_PALETTE:
textPrinter->printerTemplate.currentChar++;
return RENDER_REPEAT;
case EXT_CTRL_CODE_FONT:
subStruct->fontId = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
return RENDER_REPEAT;
case EXT_CTRL_CODE_RESET_FONT:
return RENDER_REPEAT;
case EXT_CTRL_CODE_PAUSE:
textPrinter->delayCounter = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
textPrinter->state = RENDER_STATE_PAUSE;
return RENDER_REPEAT;
case EXT_CTRL_CODE_PAUSE_UNTIL_PRESS:
textPrinter->state = RENDER_STATE_WAIT;
if (gTextFlags.autoScroll)
subStruct->autoScrollDelay = 0;
return RENDER_UPDATE;
case EXT_CTRL_CODE_WAIT_SE:
textPrinter->state = RENDER_STATE_WAIT_SE;
return RENDER_UPDATE;
case EXT_CTRL_CODE_PLAY_BGM:
currChar = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
currChar |= *textPrinter->printerTemplate.currentChar << 8;
textPrinter->printerTemplate.currentChar++;
PlayBGM(currChar);
return RENDER_REPEAT;
case EXT_CTRL_CODE_ESCAPE:
currChar = *textPrinter->printerTemplate.currentChar | 0x100;
textPrinter->printerTemplate.currentChar++;
break;
case EXT_CTRL_CODE_PLAY_SE:
currChar = *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
currChar |= (*textPrinter->printerTemplate.currentChar << 8);
textPrinter->printerTemplate.currentChar++;
PlaySE(currChar);
return RENDER_REPEAT;
case EXT_CTRL_CODE_SHIFT_RIGHT:
textPrinter->printerTemplate.currentX = textPrinter->printerTemplate.x + *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
return RENDER_REPEAT;
case EXT_CTRL_CODE_SHIFT_DOWN:
textPrinter->printerTemplate.currentY = textPrinter->printerTemplate.y + *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++;
return RENDER_REPEAT;
case EXT_CTRL_CODE_FILL_WINDOW:
FillWindowPixelBuffer(textPrinter->printerTemplate.windowId, PIXEL_FILL(textPrinter->printerTemplate.bgColor));
textPrinter->printerTemplate.currentX = textPrinter->printerTemplate.x;
textPrinter->printerTemplate.currentY = textPrinter->printerTemplate.y;
return RENDER_REPEAT;
case EXT_CTRL_CODE_PAUSE_MUSIC:
m4aMPlayStop(&gMPlayInfo_BGM);
return RENDER_REPEAT;
case EXT_CTRL_CODE_RESUME_MUSIC:
m4aMPlayContinue(&gMPlayInfo_BGM);
return RENDER_REPEAT;
case EXT_CTRL_CODE_CLEAR:
width = *textPrinter->printerTemplate.currentChar;
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentChar++;
if (width > 0)
{
ClearTextSpan(textPrinter, width);
2018-11-06 17:44:48 +01:00
textPrinter->printerTemplate.currentX += width;
return RENDER_PRINT;
}
2023-11-12 02:43:13 +01:00
return RENDER_REPEAT;
case EXT_CTRL_CODE_SKIP:
textPrinter->printerTemplate.currentX = *textPrinter->printerTemplate.currentChar + textPrinter->printerTemplate.x;
textPrinter->printerTemplate.currentChar++;
return RENDER_REPEAT;
case EXT_CTRL_CODE_CLEAR_TO:
{
widthHelper = *textPrinter->printerTemplate.currentChar;
widthHelper += textPrinter->printerTemplate.x;
textPrinter->printerTemplate.currentChar++;
width = widthHelper - textPrinter->printerTemplate.currentX;
if (width > 0)
{
ClearTextSpan(textPrinter, width);
textPrinter->printerTemplate.currentX += width;
return RENDER_PRINT;
}
}
return RENDER_REPEAT;
case EXT_CTRL_CODE_MIN_LETTER_SPACING:
textPrinter->minLetterSpacing = *textPrinter->printerTemplate.currentChar++;
return RENDER_REPEAT;
case EXT_CTRL_CODE_JPN:
textPrinter->japanese = TRUE;
return RENDER_REPEAT;
case EXT_CTRL_CODE_ENG:
textPrinter->japanese = FALSE;
return RENDER_REPEAT;
2018-01-24 22:45:37 +01:00
}
2023-11-12 02:43:13 +01:00
break;
case CHAR_PROMPT_CLEAR:
textPrinter->state = RENDER_STATE_CLEAR;
TextPrinterInitDownArrowCounters(textPrinter);
return RENDER_UPDATE;
case CHAR_PROMPT_SCROLL:
textPrinter->state = RENDER_STATE_SCROLL_START;
TextPrinterInitDownArrowCounters(textPrinter);
return RENDER_UPDATE;
case CHAR_EXTRA_SYMBOL:
currChar = *textPrinter->printerTemplate.currentChar | 0x100;
textPrinter->printerTemplate.currentChar++;
break;
case CHAR_KEYPAD_ICON:
currChar = *textPrinter->printerTemplate.currentChar++;
gCurGlyph.width = DrawKeypadIcon(textPrinter->printerTemplate.windowId, currChar, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY);
textPrinter->printerTemplate.currentX += gCurGlyph.width + textPrinter->printerTemplate.letterSpacing;
return RENDER_PRINT;
case EOS:
return RENDER_FINISH;
2018-01-24 22:45:37 +01:00
}
2023-11-12 02:43:13 +01:00
switch (subStruct->fontId)
{
case FONT_SMALL:
DecompressGlyph_Small(currChar, textPrinter->japanese);
break;
case FONT_NORMAL:
DecompressGlyph_Normal(currChar, textPrinter->japanese);
break;
case FONT_SHORT:
case FONT_SHORT_COPY_1:
case FONT_SHORT_COPY_2:
case FONT_SHORT_COPY_3:
DecompressGlyph_Short(currChar, textPrinter->japanese);
break;
case FONT_NARROW:
DecompressGlyph_Narrow(currChar, textPrinter->japanese);
break;
case FONT_SMALL_NARROW:
DecompressGlyph_SmallNarrow(currChar, textPrinter->japanese);
break;
case FONT_BRAILLE:
break;
}
2023-11-12 02:43:13 +01:00
CopyGlyphToWindow(textPrinter);
2023-11-12 02:43:13 +01:00
if (textPrinter->minLetterSpacing)
2018-01-24 22:45:37 +01:00
{
2023-11-12 02:43:13 +01:00
textPrinter->printerTemplate.currentX += gCurGlyph.width;
width = textPrinter->minLetterSpacing - gCurGlyph.width;
if (width > 0)
{
ClearTextSpan(textPrinter, width);
textPrinter->printerTemplate.currentX += width;
}
2018-01-24 22:45:37 +01:00
}
else
2023-11-12 02:43:13 +01:00
{
if (textPrinter->japanese)
textPrinter->printerTemplate.currentX += (gCurGlyph.width + textPrinter->printerTemplate.letterSpacing);
else
textPrinter->printerTemplate.currentX += gCurGlyph.width;
}
repeats--;
} while (repeats > 0);
return RENDER_PRINT;
case RENDER_STATE_WAIT:
if (TextPrinterWait(textPrinter))
textPrinter->state = RENDER_STATE_HANDLE_CHAR;
return RENDER_UPDATE;
case RENDER_STATE_CLEAR:
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 = RENDER_STATE_HANDLE_CHAR;
}
return RENDER_UPDATE;
case RENDER_STATE_SCROLL_START:
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 = RENDER_STATE_SCROLL;
}
return RENDER_UPDATE;
case RENDER_STATE_SCROLL:
if (textPrinter->scrollDistance)
{
2018-11-06 18:30:21 +01:00
int scrollSpeed = GetPlayerTextSpeed();
2021-11-14 15:55:30 +01:00
int speed = sWindowVerticalScrollSpeeds[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;
}
2021-11-03 20:29:18 +01:00
CopyWindowToVram(textPrinter->printerTemplate.windowId, COPYWIN_GFX);
}
else
{
textPrinter->state = RENDER_STATE_HANDLE_CHAR;
}
return RENDER_UPDATE;
case RENDER_STATE_WAIT_SE:
if (!IsSEPlaying())
textPrinter->state = RENDER_STATE_HANDLE_CHAR;
return RENDER_UPDATE;
case RENDER_STATE_PAUSE:
if (textPrinter->delayCounter != 0)
textPrinter->delayCounter--;
else
textPrinter->state = RENDER_STATE_HANDLE_CHAR;
return RENDER_UPDATE;
2018-01-24 22:45:37 +01:00
}
return RENDER_FINISH;
2018-01-24 22:45:37 +01:00
}
2017-03-28 02:30:49 +02:00
2021-10-30 22:47:37 +02:00
// Unused
static 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
2021-10-30 22:47:37 +02:00
for (i = 0; i < (int)ARRAY_COUNT(lineWidths); i++)
2017-03-28 02:30:49 +02:00
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)
{
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_COLOR_HIGHLIGHT_SHADOW:
2017-03-28 02:30:49 +02:00
++strPos;
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_PLAY_BGM:
case EXT_CTRL_CODE_PLAY_SE:
2018-11-05 21:42:12 +01:00
++strPos;
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_COLOR:
case EXT_CTRL_CODE_HIGHLIGHT:
case EXT_CTRL_CODE_SHADOW:
case EXT_CTRL_CODE_PALETTE:
case EXT_CTRL_CODE_FONT:
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_PAUSE:
case EXT_CTRL_CODE_ESCAPE:
2022-11-24 03:13:00 +01:00
case EXT_CTRL_CODE_SHIFT_RIGHT:
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_SHIFT_DOWN:
case EXT_CTRL_CODE_CLEAR:
case EXT_CTRL_CODE_SKIP:
case EXT_CTRL_CODE_CLEAR_TO:
case EXT_CTRL_CODE_MIN_LETTER_SPACING:
2017-03-28 02:30:49 +02:00
++strPos;
2018-11-05 21:42:12 +01:00
break;
2022-11-24 03:13:00 +01:00
case EXT_CTRL_CODE_RESET_FONT:
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_PAUSE_UNTIL_PRESS:
case EXT_CTRL_CODE_WAIT_SE:
case EXT_CTRL_CODE_FILL_WINDOW:
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;
2020-08-11 05:50:49 +02:00
case CHAR_DYNAMIC:
2018-11-05 21:42:12 +01:00
case PLACEHOLDER_BEGIN:
++strPos;
break;
case CHAR_PROMPT_SCROLL:
case CHAR_PROMPT_CLEAR:
break;
2020-08-11 05:50:49 +02:00
case CHAR_KEYPAD_ICON:
case CHAR_EXTRA_SYMBOL:
2018-11-05 21:42:12 +01:00
++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
}
2021-10-30 22:47:37 +02:00
static u32 (*GetFontWidthFunc(u8 fontId))(u16, bool32)
2017-03-28 02:30:49 +02:00
{
u32 i;
2017-09-02 00:21:11 +02:00
2021-10-30 22:47:37 +02:00
for (i = 0; i < ARRAY_COUNT(sGlyphWidthFuncs); ++i)
2017-03-28 02:30:49 +02:00
{
2021-10-30 22:47:37 +02:00
if (fontId == sGlyphWidthFuncs[i].fontId)
return sGlyphWidthFuncs[i].func;
2017-03-28 02:30:49 +02:00
}
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;
2021-10-30 22:47:37 +02:00
u32 (*func)(u16 fontId, bool32 isJapanese);
2017-03-28 02:30:49 +02:00
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 PLACEHOLDER_ID_STRING_VAR_1:
bufferPointer = gStringVar1;
break;
case PLACEHOLDER_ID_STRING_VAR_2:
bufferPointer = gStringVar2;
break;
case PLACEHOLDER_ID_STRING_VAR_3:
bufferPointer = gStringVar3;
break;
default:
return 0;
2018-11-05 21:42:12 +01:00
}
2021-03-19 23:52:37 +01:00
case CHAR_DYNAMIC:
2018-11-05 21:42:12 +01:00
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)
{
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_COLOR_HIGHLIGHT_SHADOW:
2018-11-05 21:42:12 +01:00
++str;
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_PLAY_BGM:
case EXT_CTRL_CODE_PLAY_SE:
2018-11-05 21:42:12 +01:00
++str;
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_COLOR:
case EXT_CTRL_CODE_HIGHLIGHT:
case EXT_CTRL_CODE_SHADOW:
case EXT_CTRL_CODE_PALETTE:
case EXT_CTRL_CODE_PAUSE:
case EXT_CTRL_CODE_ESCAPE:
2022-11-24 03:13:00 +01:00
case EXT_CTRL_CODE_SHIFT_RIGHT:
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_SHIFT_DOWN:
2018-11-05 21:42:12 +01:00
++str;
break;
case EXT_CTRL_CODE_FONT:
2018-11-05 21:42:12 +01:00
func = GetFontWidthFunc(*++str);
if (func == NULL)
return 0;
if (letterSpacing == -1)
localLetterSpacing = GetFontAttribute(*str, FONTATTR_LETTER_SPACING);
break;
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_CLEAR:
2018-11-05 21:42:12 +01:00
glyphWidth = *++str;
lineWidth += glyphWidth;
break;
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_SKIP:
2018-11-05 21:42:12 +01:00
lineWidth = *++str;
2017-03-28 02:30:49 +02:00
break;
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_CLEAR_TO:
2018-11-05 21:42:12 +01:00
if (*++str > lineWidth)
lineWidth = *str;
2017-03-28 02:30:49 +02:00
break;
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_MIN_LETTER_SPACING:
2018-11-05 21:42:12 +01:00
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;
2022-11-24 03:13:00 +01:00
case EXT_CTRL_CODE_RESET_FONT:
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_PAUSE_UNTIL_PRESS:
case EXT_CTRL_CODE_WAIT_SE:
case EXT_CTRL_CODE_FILL_WINDOW:
2017-03-28 02:30:49 +02:00
default:
break;
2018-11-05 21:42:12 +01:00
}
break;
2020-08-11 05:50:49 +02:00
case CHAR_KEYPAD_ICON:
case CHAR_EXTRA_SYMBOL:
if (*str == CHAR_EXTRA_SYMBOL)
2018-11-05 21:42:12 +01:00
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;
2021-03-19 23:49:19 +01:00
return width;
2017-03-28 02:30:49 +02:00
}
2021-10-31 06:44:18 +01:00
u8 RenderTextHandleBold(u8 *pixels, u8 fontId, u8 *str)
2017-03-28 02:30:49 +02:00
{
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
2020-08-11 05:50:49 +02:00
fgColor = TEXT_COLOR_WHITE;
bgColor = TEXT_COLOR_TRANSPARENT;
2021-04-10 04:39:34 +02:00
shadowColor = TEXT_COLOR_LIGHT_GRAY;
2017-09-02 00:21:11 +02:00
2021-04-10 04:39:34 +02:00
GenerateFontHalfRowLookupTable(TEXT_COLOR_WHITE, TEXT_COLOR_TRANSPARENT, TEXT_COLOR_LIGHT_GRAY);
2017-03-28 02:30:49 +02:00
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)
{
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_COLOR_HIGHLIGHT_SHADOW:
2018-11-05 21:42:12 +01:00
fgColor = strLocal[strPos++];
bgColor = strLocal[strPos++];
shadowColor = strLocal[strPos++];
GenerateFontHalfRowLookupTable(fgColor, bgColor, shadowColor);
continue;
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_COLOR:
2018-11-05 21:42:12 +01:00
fgColor = strLocal[strPos++];
GenerateFontHalfRowLookupTable(fgColor, bgColor, shadowColor);
continue;
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_HIGHLIGHT:
2018-11-05 21:42:12 +01:00
bgColor = strLocal[strPos++];
GenerateFontHalfRowLookupTable(fgColor, bgColor, shadowColor);
continue;
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_SHADOW:
2018-11-05 21:42:12 +01:00
shadowColor = strLocal[strPos++];
GenerateFontHalfRowLookupTable(fgColor, bgColor, shadowColor);
continue;
case EXT_CTRL_CODE_FONT:
2018-11-05 21:42:12 +01:00
fontId = strLocal[strPos++];
2017-03-28 02:30:49 +02:00
break;
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_PLAY_BGM:
case EXT_CTRL_CODE_PLAY_SE:
2018-11-05 21:42:12 +01:00
++strPos;
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_PALETTE:
case EXT_CTRL_CODE_PAUSE:
case EXT_CTRL_CODE_ESCAPE:
2022-11-24 03:13:00 +01:00
case EXT_CTRL_CODE_SHIFT_RIGHT:
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_SHIFT_DOWN:
case EXT_CTRL_CODE_CLEAR:
case EXT_CTRL_CODE_SKIP:
case EXT_CTRL_CODE_CLEAR_TO:
case EXT_CTRL_CODE_MIN_LETTER_SPACING:
2017-03-28 02:30:49 +02:00
++strPos;
break;
2022-11-24 03:13:00 +01:00
case EXT_CTRL_CODE_RESET_FONT:
2020-08-11 05:50:49 +02:00
case EXT_CTRL_CODE_PAUSE_UNTIL_PRESS:
case EXT_CTRL_CODE_WAIT_SE:
case EXT_CTRL_CODE_FILL_WINDOW:
case EXT_CTRL_CODE_JPN:
case EXT_CTRL_CODE_ENG:
2018-11-05 21:42:12 +01:00
default:
continue;
}
break;
2020-08-11 05:50:49 +02:00
case CHAR_DYNAMIC:
case CHAR_KEYPAD_ICON:
case CHAR_EXTRA_SYMBOL:
2018-11-05 21:42:12 +01:00
case PLACEHOLDER_BEGIN:
++strPos;
break;
case CHAR_PROMPT_SCROLL:
case CHAR_PROMPT_CLEAR:
case CHAR_NEWLINE:
case EOS:
break;
default:
switch (fontId)
{
2021-10-30 22:47:37 +02:00
case FONT_BOLD:
DecompressGlyph_Bold(temp);
2017-03-28 02:30:49 +02:00
break;
2021-10-30 22:47:37 +02:00
case FONT_NORMAL:
2017-03-28 02:30:49 +02:00
default:
2021-10-30 22:47:37 +02:00
DecompressGlyph_Normal(temp, TRUE);
2017-03-28 02:30:49 +02:00
break;
2018-11-05 21:42:12 +01:00
}
2021-03-29 18:20:00 +02:00
CpuCopy32(gCurGlyph.gfxBufferTop, pixels, 0x20);
CpuCopy32(gCurGlyph.gfxBufferBottom, pixels + 0x20, 0x20);
2018-11-05 21:42:12 +01:00
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,
2021-11-14 15:55:30 +01:00
sKeypadIconTiles + (sKeypadIcons[keypadIconId].tileOffset * 0x20),
2017-03-28 02:30:49 +02:00
0,
0,
0x80,
0x80,
x,
y,
2021-11-14 15:55:30 +01:00
sKeypadIcons[keypadIconId].width,
sKeypadIcons[keypadIconId].height);
return sKeypadIcons[keypadIconId].width;
2017-03-28 02:30:49 +02:00
}
u8 GetKeypadIconTileOffset(u8 keypadIconId)
{
2021-11-14 15:55:30 +01:00
return sKeypadIcons[keypadIconId].tileOffset;
2017-03-28 02:30:49 +02:00
}
u8 GetKeypadIconWidth(u8 keypadIconId)
{
2021-11-14 15:55:30 +01:00
return sKeypadIcons[keypadIconId].width;
2017-03-28 02:30:49 +02:00
}
u8 GetKeypadIconHeight(u8 keypadIconId)
{
2021-11-14 15:55:30 +01:00
return sKeypadIcons[keypadIconId].height;
2017-03-28 02:30:49 +02:00
}
2017-03-28 06:20:55 +02:00
void SetDefaultFontsPointer(void)
2017-03-28 02:30:49 +02:00
{
2021-10-30 22:47:37 +02:00
SetFontsPointer(sFontInfos);
2017-03-28 02:30:49 +02:00
}
u8 GetFontAttribute(u8 fontId, u8 attributeId)
{
int result = 0;
2017-03-28 02:30:49 +02:00
switch (attributeId)
{
2018-07-15 13:23:38 +02:00
case FONTATTR_MAX_LETTER_WIDTH:
2021-10-30 22:47:37 +02:00
result = sFontInfos[fontId].maxLetterWidth;
2017-03-28 02:30:49 +02:00
break;
2018-07-15 13:23:38 +02:00
case FONTATTR_MAX_LETTER_HEIGHT:
2021-10-30 22:47:37 +02:00
result = sFontInfos[fontId].maxLetterHeight;
2017-03-28 02:30:49 +02:00
break;
2018-07-15 13:23:38 +02:00
case FONTATTR_LETTER_SPACING:
2021-10-30 22:47:37 +02:00
result = sFontInfos[fontId].letterSpacing;
2017-03-28 02:30:49 +02:00
break;
2018-07-15 13:23:38 +02:00
case FONTATTR_LINE_SPACING:
2021-10-30 22:47:37 +02:00
result = sFontInfos[fontId].lineSpacing;
2017-03-28 02:30:49 +02:00
break;
case FONTATTR_UNKNOWN:
2021-10-30 22:47:37 +02:00
result = sFontInfos[fontId].unk;
2017-03-28 02:30:49 +02:00
break;
2018-07-15 13:23:38 +02:00
case FONTATTR_COLOR_FOREGROUND:
2021-10-30 22:47:37 +02:00
result = sFontInfos[fontId].fgColor;
2017-03-28 02:30:49 +02:00
break;
2018-07-15 13:23:38 +02:00
case FONTATTR_COLOR_BACKGROUND:
2021-10-30 22:47:37 +02:00
result = sFontInfos[fontId].bgColor;
2017-03-28 02:30:49 +02:00
break;
2018-07-15 13:23:38 +02:00
case FONTATTR_COLOR_SHADOW:
2021-10-30 22:47:37 +02:00
result = sFontInfos[fontId].shadowColor;
2017-03-28 02:30:49 +02:00
break;
}
return result;
}
u8 GetMenuCursorDimensionByFont(u8 fontId, u8 whichDimension)
{
2021-10-30 22:47:37 +02:00
return sMenuCursorDimensions[fontId][whichDimension];
2017-03-28 02:30:49 +02:00
}
2021-10-30 22:47:37 +02:00
static void DecompressGlyph_Small(u16 glyphId, bool32 isJapanese)
2017-03-28 02:30:49 +02:00
{
const u16 *glyphs;
2017-03-28 02:30:49 +02:00
if (isJapanese == 1)
{
2021-10-30 22:47:37 +02:00
glyphs = gFontSmallJapaneseGlyphs + (0x100 * (glyphId >> 0x4)) + (0x8 * (glyphId & 0xF));
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x80, gCurGlyph.gfxBufferBottom);
gCurGlyph.width = 8;
gCurGlyph.height = 12;
2017-03-28 02:30:49 +02:00
}
else
{
2021-10-30 22:47:37 +02:00
glyphs = gFontSmallLatinGlyphs + (0x20 * glyphId);
gCurGlyph.width = gFontSmallLatinGlyphWidths[glyphId];
2017-09-02 00:21:11 +02:00
2021-03-29 18:20:00 +02:00
if (gCurGlyph.width <= 8)
2017-03-28 02:30:49 +02:00
{
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x10, gCurGlyph.gfxBufferBottom);
2017-03-28 02:30:49 +02:00
}
else
{
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x8, gCurGlyph.gfxBufferTop + 8);
DecompressGlyphTile(glyphs + 0x10, gCurGlyph.gfxBufferBottom);
DecompressGlyphTile(glyphs + 0x18, gCurGlyph.gfxBufferBottom + 8);
2017-03-28 02:30:49 +02:00
}
2017-09-02 00:21:11 +02:00
2021-03-29 18:20:00 +02:00
gCurGlyph.height = 13;
2017-03-28 02:30:49 +02:00
}
}
2021-10-30 22:47:37 +02:00
static u32 GetGlyphWidth_Small(u16 glyphId, bool32 isJapanese)
2017-03-28 02:30:49 +02:00
{
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
return 8;
else
2021-10-30 22:47:37 +02:00
return gFontSmallLatinGlyphWidths[glyphId];
2017-03-28 02:30:49 +02:00
}
2021-10-30 22:47:37 +02:00
static void DecompressGlyph_Narrow(u16 glyphId, bool32 isJapanese)
2017-03-28 02:30:49 +02:00
{
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
{
2021-10-30 22:47:37 +02:00
glyphs = gFontNormalJapaneseGlyphs + (0x100 * (glyphId >> 0x4)) + (0x8 * (glyphId % 0x10));
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x80, gCurGlyph.gfxBufferBottom);
gCurGlyph.width = 8;
gCurGlyph.height = 15;
2017-03-28 02:30:49 +02:00
}
else
{
2021-10-30 22:47:37 +02:00
glyphs = gFontNarrowLatinGlyphs + (0x20 * glyphId);
gCurGlyph.width = gFontNarrowLatinGlyphWidths[glyphId];
2017-09-02 00:21:11 +02:00
2021-03-29 18:20:00 +02:00
if (gCurGlyph.width <= 8)
2017-03-28 02:30:49 +02:00
{
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x10, gCurGlyph.gfxBufferBottom);
2017-03-28 02:30:49 +02:00
}
else
{
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x8, gCurGlyph.gfxBufferTop + 8);
DecompressGlyphTile(glyphs + 0x10, gCurGlyph.gfxBufferBottom);
DecompressGlyphTile(glyphs + 0x18, gCurGlyph.gfxBufferBottom + 8);
2017-03-28 02:30:49 +02:00
}
2017-09-02 00:21:11 +02:00
2021-03-29 18:20:00 +02:00
gCurGlyph.height = 15;
2017-03-28 02:30:49 +02:00
}
}
2021-10-30 22:47:37 +02:00
static u32 GetGlyphWidth_Narrow(u16 glyphId, bool32 isJapanese)
2017-03-28 02:30:49 +02:00
{
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
return 8;
else
2021-10-30 22:47:37 +02:00
return gFontNarrowLatinGlyphWidths[glyphId];
2017-03-28 02:30:49 +02:00
}
2021-10-30 22:47:37 +02:00
static void DecompressGlyph_SmallNarrow(u16 glyphId, bool32 isJapanese)
2017-03-28 02:30:49 +02:00
{
const u16 *glyphs;
2017-03-28 02:30:49 +02:00
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
{
2021-10-30 22:47:37 +02:00
glyphs = gFontSmallJapaneseGlyphs + (0x100 * (glyphId >> 0x4)) + (0x8 * (glyphId & 0xF));
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x80, gCurGlyph.gfxBufferBottom);
gCurGlyph.width = 8;
gCurGlyph.height = 12;
2017-03-28 02:30:49 +02:00
}
else
{
2021-10-30 22:47:37 +02:00
glyphs = gFontSmallNarrowLatinGlyphs + (0x20 * glyphId);
gCurGlyph.width = gFontSmallNarrowLatinGlyphWidths[glyphId];
2017-09-02 00:21:11 +02:00
2021-03-29 18:20:00 +02:00
if (gCurGlyph.width <= 8)
2017-03-28 02:30:49 +02:00
{
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x10, gCurGlyph.gfxBufferBottom);
2017-03-28 02:30:49 +02:00
}
else
{
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x8, gCurGlyph.gfxBufferTop + 8);
DecompressGlyphTile(glyphs + 0x10, gCurGlyph.gfxBufferBottom);
DecompressGlyphTile(glyphs + 0x18, gCurGlyph.gfxBufferBottom + 8);
2017-03-28 02:30:49 +02:00
}
2017-09-02 00:21:11 +02:00
2021-03-29 18:20:00 +02:00
gCurGlyph.height = 12;
2017-03-28 02:30:49 +02:00
}
}
2021-10-30 22:47:37 +02:00
static u32 GetGlyphWidth_SmallNarrow(u16 glyphId, bool32 isJapanese)
2017-03-28 02:30:49 +02:00
{
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
return 8;
else
2021-10-30 22:47:37 +02:00
return gFontSmallNarrowLatinGlyphWidths[glyphId];
2017-03-28 02:30:49 +02:00
}
2021-10-30 22:47:37 +02:00
static void DecompressGlyph_Short(u16 glyphId, bool32 isJapanese)
2017-03-28 02:30:49 +02:00
{
const u16 *glyphs;
2017-03-28 02:30:49 +02:00
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
{
2021-10-30 22:47:37 +02:00
glyphs = gFontShortJapaneseGlyphs + (0x100 * (glyphId >> 0x3)) + (0x10 * (glyphId & 0x7));
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x8, gCurGlyph.gfxBufferTop + 8);
DecompressGlyphTile(glyphs + 0x80, gCurGlyph.gfxBufferBottom); // gCurGlyph + 0x20
DecompressGlyphTile(glyphs + 0x88, gCurGlyph.gfxBufferBottom + 8); // gCurGlyph + 0x60
2021-10-30 22:47:37 +02:00
gCurGlyph.width = gFontShortJapaneseGlyphWidths[glyphId];
2021-03-29 18:20:00 +02:00
gCurGlyph.height = 14;
2017-03-28 02:30:49 +02:00
}
else
{
2021-10-30 22:47:37 +02:00
glyphs = gFontShortLatinGlyphs + (0x20 * glyphId);
gCurGlyph.width = gFontShortLatinGlyphWidths[glyphId];
2017-09-02 00:21:11 +02:00
2021-03-29 18:20:00 +02:00
if (gCurGlyph.width <= 8)
2017-03-28 02:30:49 +02:00
{
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x10, gCurGlyph.gfxBufferBottom);
2017-03-28 02:30:49 +02:00
}
else
{
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x8, gCurGlyph.gfxBufferTop + 8);
DecompressGlyphTile(glyphs + 0x10, gCurGlyph.gfxBufferBottom);
DecompressGlyphTile(glyphs + 0x18, gCurGlyph.gfxBufferBottom + 8);
2017-03-28 02:30:49 +02:00
}
2017-09-02 00:21:11 +02:00
2021-03-29 18:20:00 +02:00
gCurGlyph.height = 14;
2017-03-28 02:30:49 +02:00
}
}
2021-10-30 22:47:37 +02:00
static u32 GetGlyphWidth_Short(u16 glyphId, bool32 isJapanese)
2017-03-28 02:30:49 +02:00
{
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2021-10-30 22:47:37 +02:00
return gFontShortJapaneseGlyphWidths[glyphId];
2017-03-28 02:30:49 +02:00
else
2021-10-30 22:47:37 +02:00
return gFontShortLatinGlyphWidths[glyphId];
2017-03-28 02:30:49 +02:00
}
2021-10-30 22:47:37 +02:00
static void DecompressGlyph_Normal(u16 glyphId, bool32 isJapanese)
2017-03-28 02:30:49 +02:00
{
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
{
2021-10-30 22:47:37 +02:00
glyphs = gFontNormalJapaneseGlyphs + (0x100 * (glyphId >> 0x4)) + (0x8 * (glyphId % 0x10));
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x80, gCurGlyph.gfxBufferBottom);
gCurGlyph.width = 8;
gCurGlyph.height = 15;
2017-03-28 02:30:49 +02:00
}
else
{
2021-10-30 22:47:37 +02:00
glyphs = gFontNormalLatinGlyphs + (0x20 * glyphId);
gCurGlyph.width = gFontNormalLatinGlyphWidths[glyphId];
2017-09-02 00:21:11 +02:00
2021-03-29 18:20:00 +02:00
if (gCurGlyph.width <= 8)
2017-03-28 02:30:49 +02:00
{
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x10, gCurGlyph.gfxBufferBottom);
2017-03-28 02:30:49 +02:00
}
else
{
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x8, gCurGlyph.gfxBufferTop + 8);
DecompressGlyphTile(glyphs + 0x10, gCurGlyph.gfxBufferBottom);
DecompressGlyphTile(glyphs + 0x18, gCurGlyph.gfxBufferBottom + 8);
2017-03-28 02:30:49 +02:00
}
2017-09-02 00:21:11 +02:00
2021-03-29 18:20:00 +02:00
gCurGlyph.height = 15;
2017-03-28 02:30:49 +02:00
}
}
2021-10-30 22:47:37 +02:00
static u32 GetGlyphWidth_Normal(u16 glyphId, bool32 isJapanese)
2017-03-28 02:30:49 +02:00
{
2017-03-28 06:20:55 +02:00
if (isJapanese == TRUE)
2017-03-28 02:30:49 +02:00
return 8;
else
2021-10-30 22:47:37 +02:00
return gFontNormalLatinGlyphWidths[glyphId];
2017-03-28 02:30:49 +02:00
}
2021-10-30 22:47:37 +02:00
static void DecompressGlyph_Bold(u16 glyphId)
2017-03-28 02:30:49 +02:00
{
const u16 *glyphs;
2017-03-28 02:30:49 +02:00
2021-11-14 15:55:30 +01:00
glyphs = sFontBoldJapaneseGlyphs + (0x100 * (glyphId >> 4)) + (0x8 * (glyphId & 0xF));
2021-03-29 18:20:00 +02:00
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
DecompressGlyphTile(glyphs + 0x80, gCurGlyph.gfxBufferBottom);
gCurGlyph.width = 8;
gCurGlyph.height = 12;
2017-03-28 02:30:49 +02:00
}