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);
|
operations.push_back(FileOperation::restoreSave);
|
||||||
} else if(extension(entry->name, {"img", "sd"})) {
|
} else if(extension(entry->name, {"img", "sd"})) {
|
||||||
operations.push_back(FileOperation::mountImg);
|
operations.push_back(FileOperation::mountImg);
|
||||||
|
} else if(extension(entry->name, {"frf"})) {
|
||||||
|
operations.push_back(FileOperation::loadFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
operations.push_back(FileOperation::hexEdit);
|
operations.push_back(FileOperation::hexEdit);
|
||||||
@ -261,6 +263,9 @@ FileOperation fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
|
|||||||
case FileOperation::calculateSHA1:
|
case FileOperation::calculateSHA1:
|
||||||
font->print(3, row++, false, "Calculate SHA1 hash");
|
font->print(3, row++, false, "Calculate SHA1 hash");
|
||||||
break;
|
break;
|
||||||
|
case FileOperation::loadFont:
|
||||||
|
font->print(3, row++, false, "Load font");
|
||||||
|
break;
|
||||||
case FileOperation::none:
|
case FileOperation::none:
|
||||||
row++;
|
row++;
|
||||||
break;
|
break;
|
||||||
@ -401,6 +406,10 @@ FileOperation fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
|
|||||||
} case FileOperation::hexEdit: {
|
} case FileOperation::hexEdit: {
|
||||||
hexEditor(entry->name.c_str(), currentDrive);
|
hexEditor(entry->name.c_str(), currentDrive);
|
||||||
break;
|
break;
|
||||||
|
} case FileOperation::loadFont: {
|
||||||
|
delete font;
|
||||||
|
font = new Font(entry->name.c_str());
|
||||||
|
break;
|
||||||
} case FileOperation::calculateSHA1: {
|
} case FileOperation::calculateSHA1: {
|
||||||
u8 sha1[20] = {0};
|
u8 sha1[20] = {0};
|
||||||
bool ret = calculateSHA1(strcat(getcwd(path, PATH_MAX), entry->name.c_str()), sha1);
|
bool ret = calculateSHA1(strcat(getcwd(path, PATH_MAX), entry->name.c_str()), sha1);
|
||||||
|
|||||||
@ -47,6 +47,7 @@ enum class FileOperation {
|
|||||||
copyFatOut,
|
copyFatOut,
|
||||||
calculateSHA1,
|
calculateSHA1,
|
||||||
hexEdit,
|
hexEdit,
|
||||||
|
loadFont,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool extension(const std::string &filename, const std::vector<std::string> &extensions);
|
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';
|
return c >= '0' && c <= '9';
|
||||||
}
|
}
|
||||||
|
|
||||||
Font::Font(const char *path) {
|
bool Font::load(const char *path) {
|
||||||
FILE *file = fopen(path, "rb");
|
FILE *file = fopen(path, "rb");
|
||||||
|
|
||||||
const u8 *fileBuffer = font_default_frf;
|
const u8 *fileBuffer = font_default_frf;
|
||||||
@ -35,7 +35,7 @@ Font::Font(const char *path) {
|
|||||||
fileBuffer = new u8[size];
|
fileBuffer = new u8[size];
|
||||||
if(!fileBuffer) {
|
if(!fileBuffer) {
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(file, 0, SEEK_SET);
|
fseek(file, 0, SEEK_SET);
|
||||||
@ -44,8 +44,12 @@ Font::Font(const char *path) {
|
|||||||
const u8 *ptr = fileBuffer;
|
const u8 *ptr = fileBuffer;
|
||||||
|
|
||||||
// Check header magic, then skip over
|
// Check header magic, then skip over
|
||||||
if(memcmp(ptr, "RIFF", 4) != 0)
|
if(memcmp(ptr, "RIFF", 4) != 0) {
|
||||||
goto cleanup;
|
if(fileBuffer != font_default_frf)
|
||||||
|
delete[] fileBuffer;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ptr += 8;
|
ptr += 8;
|
||||||
|
|
||||||
@ -55,21 +59,32 @@ Font::Font(const char *path) {
|
|||||||
tileHeight = ptr[9];
|
tileHeight = ptr[9];
|
||||||
tonccpy(&tileCount, ptr + 10, sizeof(u16));
|
tonccpy(&tileCount, ptr + 10, sizeof(u16));
|
||||||
|
|
||||||
if(tileWidth > TILE_MAX_WIDTH || tileHeight > TILE_MAX_HEIGHT)
|
if(tileWidth > TILE_MAX_WIDTH || tileHeight > TILE_MAX_HEIGHT) {
|
||||||
goto cleanup;
|
if(fileBuffer != font_default_frf)
|
||||||
|
delete[] fileBuffer;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
u32 section_size;
|
u32 section_size;
|
||||||
tonccpy(§ion_size, ptr + 4, sizeof(u32));
|
tonccpy(§ion_size, ptr + 4, sizeof(u32));
|
||||||
ptr += 8 + section_size;
|
ptr += 8 + section_size;
|
||||||
} else {
|
} else {
|
||||||
goto cleanup;
|
if(fileBuffer != font_default_frf)
|
||||||
|
delete[] fileBuffer;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Character data
|
// Character data
|
||||||
if(memcmp(ptr, "CDAT", 4) == 0) {
|
if(memcmp(ptr, "CDAT", 4) == 0) {
|
||||||
fontTiles = new u8[tileHeight * tileCount];
|
fontTiles = new u8[tileHeight * tileCount];
|
||||||
if(!fontTiles)
|
if(!fontTiles) {
|
||||||
goto cleanup;
|
if(fileBuffer != font_default_frf)
|
||||||
|
delete[] fileBuffer;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
tonccpy(fontTiles, ptr + 8, tileHeight * tileCount);
|
tonccpy(fontTiles, ptr + 8, tileHeight * tileCount);
|
||||||
|
|
||||||
@ -77,14 +92,23 @@ Font::Font(const char *path) {
|
|||||||
tonccpy(§ion_size, ptr + 4, sizeof(u32));
|
tonccpy(§ion_size, ptr + 4, sizeof(u32));
|
||||||
ptr += 8 + section_size;
|
ptr += 8 + section_size;
|
||||||
} else {
|
} else {
|
||||||
goto cleanup;
|
if(fileBuffer != font_default_frf)
|
||||||
|
delete[] fileBuffer;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// character map
|
// character map
|
||||||
if(memcmp(ptr, "CMAP", 4) == 0) {
|
if(memcmp(ptr, "CMAP", 4) == 0) {
|
||||||
fontMap = new u16[tileCount];
|
fontMap = new u16[tileCount];
|
||||||
if(!fontMap)
|
if(!fontMap) {
|
||||||
goto cleanup;
|
if(fileBuffer != font_default_frf)
|
||||||
|
delete[] fileBuffer;
|
||||||
|
|
||||||
|
delete[] fontTiles;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
tonccpy(fontMap, ptr + 8, sizeof(u16) * tileCount);
|
tonccpy(fontMap, ptr + 8, sizeof(u16) * tileCount);
|
||||||
|
|
||||||
@ -92,7 +116,12 @@ Font::Font(const char *path) {
|
|||||||
tonccpy(§ion_size, ptr + 4, sizeof(u32));
|
tonccpy(§ion_size, ptr + 4, sizeof(u32));
|
||||||
ptr += 8 + section_size;
|
ptr += 8 + section_size;
|
||||||
} else {
|
} else {
|
||||||
goto cleanup;
|
if(fileBuffer != font_default_frf)
|
||||||
|
delete[] fileBuffer;
|
||||||
|
|
||||||
|
delete[] fontTiles;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
questionMark = getCharIndex('?');
|
questionMark = getCharIndex('?');
|
||||||
@ -103,9 +132,16 @@ Font::Font(const char *path) {
|
|||||||
tonccpy(BG_PALETTE_SUB + i * 0x10, palette[i], 4);
|
tonccpy(BG_PALETTE_SUB + i * 0x10, palette[i], 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if(fileBuffer != font_default_frf)
|
if(fileBuffer != font_default_frf)
|
||||||
delete[] fileBuffer;
|
delete[] fileBuffer;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Font::Font(const char *path) {
|
||||||
|
if(!load(path)) {
|
||||||
|
load(nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Font::~Font(void) {
|
Font::~Font(void) {
|
||||||
|
|||||||
@ -60,6 +60,8 @@ class Font {
|
|||||||
u8 *fontTiles = nullptr;
|
u8 *fontTiles = nullptr;
|
||||||
u16 *fontMap = nullptr;
|
u16 *fontMap = nullptr;
|
||||||
|
|
||||||
|
bool load(const char *path);
|
||||||
|
|
||||||
u16 getCharIndex(char16_t c);
|
u16 getCharIndex(char16_t c);
|
||||||
public:
|
public:
|
||||||
static std::u16string utf8to16(std::string_view text);
|
static std::u16string utf8to16(std::string_view text);
|
||||||
|
|||||||
@ -97,7 +97,7 @@ int main(int argc, char **argv) {
|
|||||||
vramSetBankI(VRAM_I_SUB_SPRITE);
|
vramSetBankI(VRAM_I_SUB_SPRITE);
|
||||||
|
|
||||||
// Init built-in font
|
// Init built-in font
|
||||||
font = new Font("/font.frf");
|
font = new Font(nullptr);
|
||||||
|
|
||||||
// Display GM9i logo
|
// Display GM9i logo
|
||||||
bg3 = bgInit(3, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
|
bg3 = bgInit(3, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
|
||||||
@ -176,21 +176,9 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
bgHide(bg3);
|
bgHide(bg3);
|
||||||
|
|
||||||
// TODO: better
|
// Reinit font, try to load default from SD this time
|
||||||
delete font;
|
delete font;
|
||||||
font = new Font("/font.frf");
|
font = new Font(sdFound() ? "sd:/gm9i/font.frf" : "fat:/gm9i/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
|
|
||||||
|
|
||||||
keysSetRepeat(25,5);
|
keysSetRepeat(25,5);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user