From bba0daa23a993fa45b8290785e46d20193f39036 Mon Sep 17 00:00:00 2001 From: Pk11 Date: Thu, 12 Aug 2021 16:56:52 -0500 Subject: [PATCH] Add loading font from an FRF file --- arm9/source/file_browse.cpp | 9 ++++++ arm9/source/file_browse.h | 1 + arm9/source/font.cpp | 64 +++++++++++++++++++++++++++++-------- arm9/source/font.h | 2 ++ arm9/source/main.cpp | 18 ++--------- 5 files changed, 65 insertions(+), 29 deletions(-) diff --git a/arm9/source/file_browse.cpp b/arm9/source/file_browse.cpp index f908afa..82c1353 100644 --- a/arm9/source/file_browse.cpp +++ b/arm9/source/file_browse.cpp @@ -196,6 +196,8 @@ FileOperation fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) { operations.push_back(FileOperation::restoreSave); } else if(extension(entry->name, {"img", "sd"})) { operations.push_back(FileOperation::mountImg); + } else if(extension(entry->name, {"frf"})) { + operations.push_back(FileOperation::loadFont); } operations.push_back(FileOperation::hexEdit); @@ -261,6 +263,9 @@ FileOperation fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) { case FileOperation::calculateSHA1: font->print(3, row++, false, "Calculate SHA1 hash"); break; + case FileOperation::loadFont: + font->print(3, row++, false, "Load font"); + break; case FileOperation::none: row++; break; @@ -401,6 +406,10 @@ FileOperation fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) { } case FileOperation::hexEdit: { hexEditor(entry->name.c_str(), currentDrive); break; + } case FileOperation::loadFont: { + delete font; + font = new Font(entry->name.c_str()); + break; } case FileOperation::calculateSHA1: { u8 sha1[20] = {0}; bool ret = calculateSHA1(strcat(getcwd(path, PATH_MAX), entry->name.c_str()), sha1); diff --git a/arm9/source/file_browse.h b/arm9/source/file_browse.h index a4c83cd..33a1a97 100644 --- a/arm9/source/file_browse.h +++ b/arm9/source/file_browse.h @@ -47,6 +47,7 @@ enum class FileOperation { copyFatOut, calculateSHA1, hexEdit, + loadFont, }; bool extension(const std::string &filename, const std::vector &extensions); diff --git a/arm9/source/font.cpp b/arm9/source/font.cpp index 5c7233a..e4ab568 100644 --- a/arm9/source/font.cpp +++ b/arm9/source/font.cpp @@ -24,7 +24,7 @@ bool Font::isNumber(char16_t c) { return c >= '0' && c <= '9'; } -Font::Font(const char *path) { +bool Font::load(const char *path) { FILE *file = fopen(path, "rb"); const u8 *fileBuffer = font_default_frf; @@ -35,7 +35,7 @@ Font::Font(const char *path) { fileBuffer = new u8[size]; if(!fileBuffer) { fclose(file); - return; + return false; } fseek(file, 0, SEEK_SET); @@ -44,8 +44,12 @@ Font::Font(const char *path) { const u8 *ptr = fileBuffer; // Check header magic, then skip over - if(memcmp(ptr, "RIFF", 4) != 0) - goto cleanup; + if(memcmp(ptr, "RIFF", 4) != 0) { + if(fileBuffer != font_default_frf) + delete[] fileBuffer; + + return false; + } ptr += 8; @@ -55,21 +59,32 @@ Font::Font(const char *path) { tileHeight = ptr[9]; tonccpy(&tileCount, ptr + 10, sizeof(u16)); - if(tileWidth > TILE_MAX_WIDTH || tileHeight > TILE_MAX_HEIGHT) - goto cleanup; + if(tileWidth > TILE_MAX_WIDTH || tileHeight > TILE_MAX_HEIGHT) { + if(fileBuffer != font_default_frf) + delete[] fileBuffer; + + return false; + } u32 section_size; tonccpy(§ion_size, ptr + 4, sizeof(u32)); ptr += 8 + section_size; } else { - goto cleanup; + if(fileBuffer != font_default_frf) + delete[] fileBuffer; + + return false; } // Character data if(memcmp(ptr, "CDAT", 4) == 0) { fontTiles = new u8[tileHeight * tileCount]; - if(!fontTiles) - goto cleanup; + if(!fontTiles) { + if(fileBuffer != font_default_frf) + delete[] fileBuffer; + + return false; + } tonccpy(fontTiles, ptr + 8, tileHeight * tileCount); @@ -77,14 +92,23 @@ Font::Font(const char *path) { tonccpy(§ion_size, ptr + 4, sizeof(u32)); ptr += 8 + section_size; } else { - goto cleanup; + if(fileBuffer != font_default_frf) + delete[] fileBuffer; + + return false; } // character map if(memcmp(ptr, "CMAP", 4) == 0) { fontMap = new u16[tileCount]; - if(!fontMap) - goto cleanup; + if(!fontMap) { + if(fileBuffer != font_default_frf) + delete[] fileBuffer; + + delete[] fontTiles; + + return false; + } tonccpy(fontMap, ptr + 8, sizeof(u16) * tileCount); @@ -92,7 +116,12 @@ Font::Font(const char *path) { tonccpy(§ion_size, ptr + 4, sizeof(u32)); ptr += 8 + section_size; } else { - goto cleanup; + if(fileBuffer != font_default_frf) + delete[] fileBuffer; + + delete[] fontTiles; + + return false; } questionMark = getCharIndex('?'); @@ -103,9 +132,16 @@ Font::Font(const char *path) { tonccpy(BG_PALETTE_SUB + i * 0x10, palette[i], 4); } -cleanup: if(fileBuffer != font_default_frf) delete[] fileBuffer; + + return true; +} + +Font::Font(const char *path) { + if(!load(path)) { + load(nullptr); + } } Font::~Font(void) { diff --git a/arm9/source/font.h b/arm9/source/font.h index a9962e6..d2224f3 100644 --- a/arm9/source/font.h +++ b/arm9/source/font.h @@ -60,6 +60,8 @@ class Font { u8 *fontTiles = nullptr; u16 *fontMap = nullptr; + bool load(const char *path); + u16 getCharIndex(char16_t c); public: static std::u16string utf8to16(std::string_view text); diff --git a/arm9/source/main.cpp b/arm9/source/main.cpp index 2af687b..d479634 100644 --- a/arm9/source/main.cpp +++ b/arm9/source/main.cpp @@ -97,7 +97,7 @@ int main(int argc, char **argv) { vramSetBankI(VRAM_I_SUB_SPRITE); // Init built-in font - font = new Font("/font.frf"); + font = new Font(nullptr); // Display GM9i logo bg3 = bgInit(3, BgType_Bmp8, BgSize_B8_256x256, 0, 0); @@ -176,21 +176,9 @@ int main(int argc, char **argv) { bgHide(bg3); - // TODO: better + // Reinit font, try to load default from SD this time delete font; - font = new Font("/font.frf"); - - // Overwrite background white color - BG_PALETTE[15+(7*16)] = 0x656A; - BG_PALETTE_SUB[15+(7*16)] = 0x656A; - - // Custom yellow color - BG_PALETTE[15+(3*16)] = 0x3339; - BG_PALETTE_SUB[15+(3*16)] = 0x3339; - - // Overwrite 2nd smiley face with filled tile - dmaFillWords(0xFFFFFFFF, (void*)0x6000040, 8*8); // Top screen - dmaFillWords(0xFFFFFFFF, (void*)0x6200040, 8*8); // Bottom screen + font = new Font(sdFound() ? "sd:/gm9i/font.frf" : "fat:/gm9i/font.frf"); keysSetRepeat(25,5);