diff --git a/arm9/source/filesys/filetype.c b/arm9/source/filesys/filetype.c index 14c4a70..4d7e51b 100644 --- a/arm9/source/filesys/filetype.c +++ b/arm9/source/filesys/filetype.c @@ -1,5 +1,6 @@ #include "filetype.h" #include "fsutil.h" +#include "image.h" #include "fatmbr.h" #include "nand.h" #include "game.h" @@ -112,7 +113,16 @@ u64 IdentifyFileType(const char* path) { } } - if (GetFontFromPbm(data, fsize, NULL, NULL)) { + if (fsize == sizeof(TitleInfoEntry) && (strncasecmp(path, "T:/", 3) == 0)) { + const char* mntpath = GetMountPath(); + if (mntpath && *mntpath) { + if ((strncasecmp(mntpath, "1:/dbs/title.db", 16) == 0) || + (strncasecmp(mntpath, "4:/dbs/title.db", 16) == 0) || + (strncasecmp(mntpath, "A:/dbs/title.db", 16) == 0) || + (strncasecmp(mntpath, "B:/dbs/title.db", 16) == 0)) + return GAME_TIE; + } + } else if (GetFontFromPbm(data, fsize, NULL, NULL)) { return FONT_PBM; } else if ((fsize > sizeof(AgbHeader)) && (ValidateAgbHeader((AgbHeader*) data) == 0)) { diff --git a/arm9/source/filesys/filetype.h b/arm9/source/filesys/filetype.h index 4ecefaf..1014849 100644 --- a/arm9/source/filesys/filetype.h +++ b/arm9/source/filesys/filetype.h @@ -14,27 +14,28 @@ #define GAME_BOSS (1ULL<<9) #define GAME_NUSCDN (1ULL<<10) #define GAME_TICKET (1ULL<<11) -#define GAME_SMDH (1ULL<<12) -#define GAME_3DSX (1ULL<<13) -#define GAME_NDS (1ULL<<14) -#define GAME_GBA (1ULL<<15) -#define GAME_TAD (1ULL<<16) -#define SYS_FIRM (1ULL<<17) -#define SYS_DIFF (1ULL<<18) -#define SYS_DISA (1ULL<<19) -#define SYS_AGBSAVE (1ULL<<20) -#define SYS_TICKDB (1ULL<<21) -#define BIN_NCCHNFO (1ULL<<22) -#define BIN_TIKDB (1ULL<<23) -#define BIN_KEYDB (1ULL<<24) -#define BIN_LEGKEY (1ULL<<25) -#define TXT_SCRIPT (1ULL<<26) -#define TXT_GENERIC (1ULL<<27) -#define GFX_PNG (1ULL<<28) -#define FONT_PBM (1ULL<<29) -#define NOIMG_NAND (1ULL<<30) -#define HDR_NAND (1ULL<<31) -#define TYPE_BASE 0xFFFFFFFFULL // 32 bit reserved for base types +#define GAME_TIE (1ULL<<12) +#define GAME_SMDH (1ULL<<13) +#define GAME_3DSX (1ULL<<14) +#define GAME_NDS (1ULL<<15) +#define GAME_GBA (1ULL<<16) +#define GAME_TAD (1ULL<<17) +#define SYS_FIRM (1ULL<<18) +#define SYS_DIFF (1ULL<<19) +#define SYS_DISA (1ULL<<20) +#define SYS_AGBSAVE (1ULL<<21) +#define SYS_TICKDB (1ULL<<22) +#define BIN_NCCHNFO (1ULL<<23) +#define BIN_TIKDB (1ULL<<24) +#define BIN_KEYDB (1ULL<<25) +#define BIN_LEGKEY (1ULL<<26) +#define TXT_SCRIPT (1ULL<<27) +#define TXT_GENERIC (1ULL<<28) +#define GFX_PNG (1ULL<<29) +#define FONT_PBM (1ULL<<30) +#define NOIMG_NAND (1ULL<<31) +#define HDR_NAND (1ULL<<32) +#define TYPE_BASE 0xFFFFFFFFFFULL // 40 bit reserved for base types // #define FLAG_FIRM (1ULL<<57) // <--- for CXIs containing FIRMs // #define FLAG_GBAVC (1ULL<<58) // <--- for GBAVC CXIs @@ -54,7 +55,7 @@ #define FTYPE_CXIDUMP(tp) (tp&(GAME_TMD)) #define FTYPE_TIKBUILD(tp) (tp&(GAME_TICKET|SYS_TICKDB|BIN_TIKDB)) #define FTYPE_KEYBUILD(tp) (tp&(BIN_KEYDB|BIN_LEGKEY)) -#define FTYPE_TITLEINFO(tp) (tp&(GAME_SMDH|GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_TMD|GAME_NDS|GAME_GBA|GAME_TAD|GAME_3DSX)) +#define FTYPE_TITLEINFO(tp) (tp&(GAME_TIE|GAME_SMDH|GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_TMD|GAME_NDS|GAME_GBA|GAME_TAD|GAME_3DSX)) #define FTYPE_CIACHECK(tp) (tp&GAME_CIA) #define FTYPE_RENAMABLE(tp) (tp&(GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_NDS|GAME_GBA)) #define FTYPE_TRIMABLE(tp) (tp&(IMG_NAND|GAME_NCCH|GAME_NCSD|GAME_NDS|SYS_FIRM)) diff --git a/arm9/source/godmode.c b/arm9/source/godmode.c index c5ff3ac..6a3388b 100644 --- a/arm9/source/godmode.c +++ b/arm9/source/godmode.c @@ -1165,6 +1165,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan (filetype & GAME_EXEFS) ? "Mount as EXEFS image" : (filetype & GAME_ROMFS) ? "Mount as ROMFS image" : (filetype & GAME_TMD ) ? "TMD file options..." : + (filetype & GAME_TIE ) ? "Show title info" : (filetype & GAME_BOSS ) ? "BOSS file options..." : (filetype & GAME_NUSCDN)? "Decrypt NUS/CDN file" : (filetype & GAME_SMDH) ? "Show SMDH title info" : diff --git a/arm9/source/utils/gameutil.c b/arm9/source/utils/gameutil.c index fbc8cfd..2a6c221 100644 --- a/arm9/source/utils/gameutil.c +++ b/arm9/source/utils/gameutil.c @@ -260,6 +260,40 @@ u32 GetTmdContentPath(char* path_content, const char* path_tmd) { return 0; } +u32 GetTieContentPath(char* path_content, const char* path_tie) { + char path_tmd[64]; + char* tid_str = path_tie + 3; + char drv[3] = { 0x00 }; + + // this relies on: + // 1: titleinfo entries are only loaded from mounted [1/4/A/B]:/dbs/title.db + // 2: filename starts with title id + + // basic sanity check + if (*path_tie != 'T') return 1; + + // load TitleDB entry file + TitleInfoEntry tie; + if (fvx_qread(path_tie, &tie, 0, sizeof(TitleInfoEntry), NULL) != FR_OK) + return 1; + + // determine the drive + const char* mntpath = GetMountPath(); + if (!mntpath || !*mntpath) return 1; + strncpy(drv, mntpath, 2); + if ((tid_str[3] == '4') && (tid_str[4] == '8')) { + if (*drv == '1') *drv = '2'; + if (*drv == '4') *drv = '5'; + } + + // build the path + snprintf(path_tmd, 64, "%2.2s/title/%8.8s/%8.8s/content/%08lx.tmd", + drv, tid_str, tid_str + 8, tie.tmd_content_id); + + // let the TMD content path function take over + return GetTmdContentPath(path_content, path_tmd); +} + u32 WriteCiaStub(CiaStub* stub, const char* path) { FIL file; UINT btw; @@ -2175,7 +2209,7 @@ u32 InstallGameFile(const char* path, bool to_emunand) { !fvx_qsize(to_emunand ? "4:/dbs/import.db" : "1:/dbs/import.db")) return 1; } - + // now we know the correct drive drv = to_emunand ? (to_sd ? "B:" : to_twl ? "5:" : "4:") : (to_sd ? "A:" : to_twl ? "2:" : "1:"); @@ -2429,6 +2463,10 @@ u32 LoadSmdhFromGameFile(const char* path, Smdh* smdh) { char path_content[256]; if (GetTmdContentPath(path_content, path) != 0) return 1; return LoadSmdhFromGameFile(path_content, smdh); + } else if (filetype & GAME_TIE) { + char path_content[256]; + if (GetTieContentPath(path_content, path) != 0) return 1; + return LoadSmdhFromGameFile(path_content, smdh); } else if (filetype & GAME_3DSX) { ThreedsxHeader threedsx; if ((fvx_qread(path, &threedsx, 0, sizeof(ThreedsxHeader), NULL) != FR_OK) || @@ -2487,6 +2525,9 @@ u32 ShowGameFileTitleInfoF(const char* path, u16* screen, bool clear) { if (itype & GAME_TMD) { if (GetTmdContentPath(path_content, path) != 0) return 1; path = path_content; + } else if (itype & GAME_TIE) { + if (GetTieContentPath(path_content, path) != 0) return 1; + path = path_content; } void* buffer = (void*) malloc(max(sizeof(Smdh), sizeof(TwlIconData)));