Add loading font from an FRF file

This commit is contained in:
Pk11 2021-08-12 16:56:52 -05:00
parent ce49d1fdf9
commit bba0daa23a
5 changed files with 65 additions and 29 deletions

View File

@ -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);

View File

@ -47,6 +47,7 @@ enum class FileOperation {
copyFatOut,
calculateSHA1,
hexEdit,
loadFont,
};
bool extension(const std::string &filename, const std::vector<std::string> &extensions);

View File

@ -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(&section_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(&section_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(&section_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) {

View File

@ -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);

View File

@ -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);