Allow switching fonts at runtime

This commit is contained in:
d0k3 2018-01-13 17:05:51 +01:00
parent 39a94f4442
commit 48f7f4c652
4 changed files with 26 additions and 10 deletions

View File

@ -27,11 +27,12 @@ static u8 font_bin[FONT_MAX_HEIGHT * FONT_N_SYMBOLS];
u8* GetFontFromPbm(const void* pbm, const u32 pbm_size, u32* w, u32* h) { u8* GetFontFromPbm(const void* pbm, const u32 pbm_size, u32* w, u32* h) {
char* hdr = (char*) pbm; char* hdr = (char*) pbm;
u32 hdr_max_size = min(512, pbm_size);
u32 pbm_w = 0; u32 pbm_w = 0;
u32 pbm_h = 0; u32 pbm_h = 0;
// minimum size // minimum size
if (pbm_size < 7) return NULL; if (hdr_max_size < 7) return NULL;
// check header magic, then skip over // check header magic, then skip over
if (strncmp(hdr, "P4\n", 3) != 0) return NULL; if (strncmp(hdr, "P4\n", 3) != 0) return NULL;
@ -40,30 +41,30 @@ u8* GetFontFromPbm(const void* pbm, const u32 pbm_size, u32* w, u32* h) {
u32 p = 3; u32 p = 3;
while (hdr[p] == '#') { while (hdr[p] == '#') {
while (hdr[p++] != '\n') { while (hdr[p++] != '\n') {
if (p >= pbm_size) return NULL; if (p >= hdr_max_size) return NULL;
} }
} }
// parse width // parse width
while ((hdr[p] >= '0') && (hdr[p] <= '9')) { while ((hdr[p] >= '0') && (hdr[p] <= '9')) {
if (p >= pbm_size) return NULL; if (p >= hdr_max_size) return NULL;
pbm_w *= 10; pbm_w *= 10;
pbm_w += hdr[p++] - '0'; pbm_w += hdr[p++] - '0';
} }
// whitespace // whitespace
if ((hdr[p++] != ' ') || (p >= pbm_size)) if ((hdr[p++] != ' ') || (p >= hdr_max_size))
return NULL; return NULL;
// parse height // parse height
while ((hdr[p] >= '0') && (hdr[p] <= '9')) { while ((hdr[p] >= '0') && (hdr[p] <= '9')) {
if (p >= pbm_size) return NULL; if (p >= hdr_max_size) return NULL;
pbm_h *= 10; pbm_h *= 10;
pbm_h += hdr[p++] - '0'; pbm_h += hdr[p++] - '0';
} }
// line break // line break
if ((hdr[p++] != '\n') || (p >= pbm_size)) if ((hdr[p++] != '\n') || (p >= hdr_max_size))
return NULL; return NULL;
// check sizes // check sizes

View File

@ -6,6 +6,7 @@
#include "keydb.h" #include "keydb.h"
#include "ctrtransfer.h" #include "ctrtransfer.h"
#include "scripting.h" #include "scripting.h"
#include "ui.h" // only for font file detection
u64 IdentifyFileType(const char* path) { u64 IdentifyFileType(const char* path) {
const u8 romfs_magic[] = { ROMFS_MAGIC }; const u8 romfs_magic[] = { ROMFS_MAGIC };
@ -94,7 +95,9 @@ u64 IdentifyFileType(const char* path) {
} }
} }
if ((fsize > sizeof(AgbHeader)) && if (GetFontFromPbm(data, fsize, NULL, NULL)) {
return FONT_PBM;
} else if ((fsize > sizeof(AgbHeader)) &&
(ValidateAgbHeader((AgbHeader*) data) == 0)) { (ValidateAgbHeader((AgbHeader*) data) == 0)) {
return GAME_GBA; return GAME_GBA;
} else if ((fsize > sizeof(BossHeader)) && } else if ((fsize > sizeof(BossHeader)) &&

View File

@ -27,8 +27,9 @@
#define BIN_LEGKEY (1ULL<<22) #define BIN_LEGKEY (1ULL<<22)
#define TXT_SCRIPT (1ULL<<23) #define TXT_SCRIPT (1ULL<<23)
#define TXT_GENERIC (1ULL<<24) #define TXT_GENERIC (1ULL<<24)
#define NOIMG_NAND (1ULL<<25) #define FONT_PBM (1ULL<<25)
#define HDR_NAND (1ULL<<26) #define NOIMG_NAND (1ULL<<26)
#define HDR_NAND (1ULL<<27)
#define TYPE_BASE 0xFFFFFFFFULL // 32 bit reserved for base types #define TYPE_BASE 0xFFFFFFFFULL // 32 bit reserved for base types
// #define FLAG_FIRM (1ULL<<58) // <--- for CXIs containing FIRMs // #define FLAG_FIRM (1ULL<<58) // <--- for CXIs containing FIRMs
@ -58,6 +59,7 @@
#define FTYPE_KEYINIT(tp) (tp&(BIN_KEYDB)) #define FTYPE_KEYINIT(tp) (tp&(BIN_KEYDB))
#define FTYPE_KEYINSTALL(tp) (tp&(BIN_KEYDB)) #define FTYPE_KEYINSTALL(tp) (tp&(BIN_KEYDB))
#define FTYPE_SCRIPT(tp) (tp&(TXT_SCRIPT)) #define FTYPE_SCRIPT(tp) (tp&(TXT_SCRIPT))
#define FTYPE_FONT(tp) (tp&(FONT_PBM))
#define FTYPE_BOOTABLE(tp) (tp&(SYS_FIRM)) #define FTYPE_BOOTABLE(tp) (tp&(SYS_FIRM))
#define FTYPE_INSTALLABLE(tp) (tp&(SYS_FIRM)) #define FTYPE_INSTALLABLE(tp) (tp&(SYS_FIRM))
#define FTPYE_AGBSAVE(tp) (tp&(SYS_AGBSAVE)) #define FTPYE_AGBSAVE(tp) (tp&(SYS_AGBSAVE))

View File

@ -952,6 +952,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
bool keyinitable = (FTYPE_KEYINIT(filetype)) && !((drvtype & DRV_VIRTUAL) && (drvtype & DRV_SYSNAND)); bool keyinitable = (FTYPE_KEYINIT(filetype)) && !((drvtype & DRV_VIRTUAL) && (drvtype & DRV_SYSNAND));
bool keyinstallable = (FTYPE_KEYINSTALL(filetype)) && !((drvtype & DRV_VIRTUAL) && (drvtype & DRV_SYSNAND)); bool keyinstallable = (FTYPE_KEYINSTALL(filetype)) && !((drvtype & DRV_VIRTUAL) && (drvtype & DRV_SYSNAND));
bool scriptable = (FTYPE_SCRIPT(filetype)); bool scriptable = (FTYPE_SCRIPT(filetype));
bool fontable = (FTYPE_FONT(filetype));
bool bootable = (FTYPE_BOOTABLE(filetype)); bool bootable = (FTYPE_BOOTABLE(filetype));
bool installable = (FTYPE_INSTALLABLE(filetype)); bool installable = (FTYPE_INSTALLABLE(filetype));
bool agbexportable = (FTPYE_AGBSAVE(filetype) && (drvtype & DRV_VIRTUAL) && (drvtype & DRV_SYSNAND)); bool agbexportable = (FTPYE_AGBSAVE(filetype) && (drvtype & DRV_VIRTUAL) && (drvtype & DRV_SYSNAND));
@ -966,7 +967,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
extrcodeable = (FTYPE_HASCODE(filetype_cxi)); extrcodeable = (FTYPE_HASCODE(filetype_cxi));
} }
bool special_opt = mountable || verificable || decryptable || encryptable || cia_buildable || cia_buildable_legit || cxi_dumpable || tik_buildable || key_buildable || titleinfo || renamable || transferable || hsinjectable || restorable || xorpadable || ebackupable || ncsdfixable || extrcodeable || keyinitable || keyinstallable || bootable || scriptable || installable || agbexportable || agbimportable; bool special_opt = mountable || verificable || decryptable || encryptable || cia_buildable || cia_buildable_legit || cxi_dumpable || tik_buildable || key_buildable || titleinfo || renamable || transferable || hsinjectable || restorable || xorpadable || ebackupable || ncsdfixable || extrcodeable || keyinitable || keyinstallable || bootable || scriptable || fontable || installable || agbexportable || agbimportable;
char pathstr[32+1]; char pathstr[32+1];
TruncateString(pathstr, file_path, 32, 8); TruncateString(pathstr, file_path, 32, 8);
@ -1016,6 +1017,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
(filetype & BIN_LEGKEY) ? "Build " KEYDB_NAME : (filetype & BIN_LEGKEY) ? "Build " KEYDB_NAME :
(filetype & BIN_NCCHNFO)? "NCCHinfo options..." : (filetype & BIN_NCCHNFO)? "NCCHinfo options..." :
(filetype & TXT_SCRIPT) ? "Execute GM9 script" : (filetype & TXT_SCRIPT) ? "Execute GM9 script" :
(filetype & FONT_PBM) ? "Set as active font" :
(filetype & HDR_NAND) ? "Rebuild NCSD header" : (filetype & HDR_NAND) ? "Rebuild NCSD header" :
(filetype & NOIMG_NAND) ? "Rebuild NCSD header" : "???"; (filetype & NOIMG_NAND) ? "Rebuild NCSD header" : "???";
optionstr[hexviewer-1] = "Show in Hexeditor"; optionstr[hexviewer-1] = "Show in Hexeditor";
@ -1158,6 +1160,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
int install = (installable) ? ++n_opt : -1; int install = (installable) ? ++n_opt : -1;
int boot = (bootable) ? ++n_opt : -1; int boot = (bootable) ? ++n_opt : -1;
int script = (scriptable) ? ++n_opt : -1; int script = (scriptable) ? ++n_opt : -1;
int font = (fontable) ? ++n_opt : -1;
int agbexport = (agbexportable) ? ++n_opt : -1; int agbexport = (agbexportable) ? ++n_opt : -1;
int agbimport = (agbimportable) ? ++n_opt : -1; int agbimport = (agbimportable) ? ++n_opt : -1;
if (mount > 0) optionstr[mount-1] = (filetype & GAME_TMD) ? "Mount CXI/NDS to drive" : "Mount image to drive"; if (mount > 0) optionstr[mount-1] = (filetype & GAME_TMD) ? "Mount CXI/NDS to drive" : "Mount image to drive";
@ -1185,6 +1188,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
if (install > 0) optionstr[install-1] = "Install FIRM"; if (install > 0) optionstr[install-1] = "Install FIRM";
if (boot > 0) optionstr[boot-1] = "Boot FIRM"; if (boot > 0) optionstr[boot-1] = "Boot FIRM";
if (script > 0) optionstr[script-1] = "Execute GM9 script"; if (script > 0) optionstr[script-1] = "Execute GM9 script";
if (font > 0) optionstr[font-1] = "Set as active font";
if (agbexport > 0) optionstr[agbexport-1] = "Dump GBA VC save"; if (agbexport > 0) optionstr[agbexport-1] = "Dump GBA VC save";
if (agbimport > 0) optionstr[agbimport-1] = "Inject GBA VC save"; if (agbimport > 0) optionstr[agbimport-1] = "Inject GBA VC save";
@ -1592,6 +1596,12 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
ClearScreenF(true, true, COLOR_STD_BG); ClearScreenF(true, true, COLOR_STD_BG);
return 0; return 0;
} }
else if (user_select == font) { // set font
u32 pbm_size = FileGetData(file_path, TEMP_BUFFER, TEMP_BUFFER_SIZE, 0);
if (pbm_size) SetFontFromPbm(TEMP_BUFFER, pbm_size);
ClearScreenF(true, true, COLOR_STD_BG);
return 0;
}
else if (user_select == agbexport) { // export GBA VC save else if (user_select == agbexport) { // export GBA VC save
if (DumpGbaVcSavegame(file_path) == 0) if (DumpGbaVcSavegame(file_path) == 0)
ShowPrompt(false, "Savegame dumped to " OUTPUT_PATH); ShowPrompt(false, "Savegame dumped to " OUTPUT_PATH);