mirror of
https://github.com/rvtr/GodMode9i.git
synced 2025-11-02 00:11:07 -04:00
Add loading font from an FRF file
This commit is contained in:
parent
ce49d1fdf9
commit
bba0daa23a
@ -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);
|
||||
|
||||
@ -47,6 +47,7 @@ enum class FileOperation {
|
||||
copyFatOut,
|
||||
calculateSHA1,
|
||||
hexEdit,
|
||||
loadFont,
|
||||
};
|
||||
|
||||
bool extension(const std::string &filename, const std::vector<std::string> &extensions);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user