diff --git a/arm9/source/filesys/filetype.h b/arm9/source/filesys/filetype.h index b93b5d9..d6d929a 100644 --- a/arm9/source/filesys/filetype.h +++ b/arm9/source/filesys/filetype.h @@ -59,7 +59,7 @@ #define FTYPE_UNINSTALL(tp) (tp&(GAME_TIE)) #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_TIE|GAME_TICKET|GAME_SMDH|GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_TMD|GAME_CDNTMD|GAME_TWLTMD|GAME_NDS|GAME_GBA|GAME_TAD|GAME_3DSX)) +#define FTYPE_TITLEINFO(tp) (tp&(GAME_TIE|GAME_CIA|GAME_TMD|GAME_CDNTMD|GAME_TWLTMD)) #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|GAME_GBA|SYS_FIRM)) #define FTYPE_TRANSFERABLE(tp) ((u64) (tp&(IMG_FAT|FLAG_CTR)) == (u64) (IMG_FAT|FLAG_CTR)) diff --git a/arm9/source/godmode.c b/arm9/source/godmode.c index 29f3df1..a46f8af 100644 --- a/arm9/source/godmode.c +++ b/arm9/source/godmode.c @@ -1077,6 +1077,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan u64 filetype = IdentifyFileType(file_path); u32 drvtype = DriveType(file_path); + u64 tid = GetGameFileTitleId(file_path); bool in_output_path = (strncasecmp(current_path, OUTPUT_PATH, 256) == 0); @@ -1143,6 +1144,9 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan char pathstr[32+1]; TruncateString(pathstr, file_path, 32, 8); + char tidstr[32] = { 0 }; + if (tid) snprintf(tidstr, 32, "\ntid: <%016llX>", tid); + u32 n_marked = 0; if ((&(current_dir->entry[*cursor]))->marked) { for (u32 i = 0; i < current_dir->n_entries; i++) @@ -1216,7 +1220,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan if (titleman > 0) optionstr[titleman-1] = "Open title folder"; int user_select = ShowSelectPrompt(n_opt, optionstr, (n_marked > 1) ? - "%s\n%(%lu files selected)" : "%s", pathstr, n_marked); + "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); if (user_select == hexviewer) { // -> show in hex viewer FileHexViewer(file_path); GetDirContents(current_dir, current_path); @@ -1235,7 +1239,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan optionstr[0] = "Check current CMAC only"; optionstr[1] = "Verify CMAC for all"; optionstr[2] = "Fix CMAC for all"; - user_select = (n_marked > 1) ? ShowSelectPrompt(3, optionstr, "%s\n%(%lu files selected)", pathstr, n_marked) : 1; + user_select = (n_marked > 1) ? ShowSelectPrompt(3, optionstr, "%s\n(%lu files selected)", pathstr, n_marked) : 1; if (user_select == 1) { CmacCalculator(file_path); return 0; @@ -1398,7 +1402,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan // auto select when there is only one option user_select = (n_opt <= 1) ? n_opt : (int) ShowSelectPrompt(n_opt, optionstr, (n_marked > 1) ? - "%s\n%(%lu files selected)" : "%s", pathstr, n_marked); + "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); if (user_select == mount) { // -> mount file as image const char* mnt_drv_paths[] = { "7:", "G:", "K:", "T:", "I:", "D:" }; // maybe move that to fsdrive.h if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_IMAGE)) @@ -1437,7 +1441,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan optionstr[0] = "Decrypt to " OUTPUT_PATH; optionstr[1] = "Decrypt inplace"; user_select = (int) ShowSelectPrompt(2, optionstr, (n_marked > 1) ? - "%s\n%(%lu files selected)" : "%s", pathstr, n_marked); + "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); } else user_select = 1; bool inplace = (user_select == 2); if (!user_select) { // do nothing when no choice is made @@ -1491,7 +1495,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan optionstr[0] = "Encrypt to " OUTPUT_PATH; optionstr[1] = "Encrypt inplace"; user_select = (int) ShowSelectPrompt(2, optionstr, (n_marked > 1) ? - "%s\n%(%lu files selected)" : "%s", pathstr, n_marked); + "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); } else user_select = 1; bool inplace = (user_select == 2); if (!user_select) { // do nothing when no choice is made @@ -1588,7 +1592,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan optionstr[0] = "Install to SysNAND"; optionstr[1] = "Install to EmuNAND"; user_select = (int) ShowSelectPrompt(2, optionstr, (n_marked > 1) ? - "%s\n%(%lu files selected)" : "%s", pathstr, n_marked); + "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); if (!user_select) return 0; else to_emunand = (user_select == 2); } @@ -1882,8 +1886,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan return 0; } else if (user_select == show_info) { // -> Show title info - if (ShowGameFileTitleInfo(file_path) != 0) - ShowPrompt(false, "Title info: not found"); + ShowGameCheckerInfo(file_path); return 0; } else if (user_select == hsinject) { // -> Inject to Health & Safety @@ -2513,7 +2516,10 @@ u32 GodMode(int entrypoint) { } } } else if ((pad_state & BUTTON_A) && (curr_entry->type == T_FILE)) { // process a file + if (!curr_entry->marked) ShowGameFileIcon(curr_entry->path, ALT_SCREEN); + DrawTopBar(current_path); FileHandlerMenu(current_path, &cursor, &scroll, &pane); // processed externally + ClearScreenF(true, true, COLOR_STD_BG); } else if (*current_path && ((pad_state & BUTTON_B) || // one level down ((pad_state & BUTTON_A) && (curr_entry->type == T_DOTDOT)))) { if (switched) { // use R+B to return to root fast diff --git a/arm9/source/utils/gameutil.c b/arm9/source/utils/gameutil.c index 2051511..5f03e70 100644 --- a/arm9/source/utils/gameutil.c +++ b/arm9/source/utils/gameutil.c @@ -2719,6 +2719,14 @@ u64 GetGameFileTitleId(const char* path) { u8 tid[8]; if (fvx_qread(path, tid, 0x18C, 8, NULL) == FR_OK) tid64 = getbe64(tid); + } else if (filetype & GAME_TICKET) { + u8 tid[8]; + if (fvx_qread(path, tid, 0x1DC, 8, NULL) == FR_OK) + tid64 = getbe64(tid); + } else if (filetype & GAME_TAD) { + TadHeader tad; + if (fvx_qread(path, &tad, TAD_HEADER_OFFSET, sizeof(TadHeader), NULL) == FR_OK) + tid64 = tad.title_id; } else if (filetype & GAME_NCCH) { NcchHeader ncch; if (LoadNcchHeaders(&ncch, NULL, NULL, path, 0) == 0) @@ -3273,7 +3281,7 @@ u32 LoadSmdhFromGameFile(const char* path, Smdh* smdh) { return 1; } -u32 ShowSmdhTitleInfo(Smdh* smdh, char* str, u16* screen) { +u32 ShowSmdhTitleInfo(Smdh* smdh, u16* screen) { static const u8 smdh_magic[] = { SMDH_MAGIC }; const u32 lwrap = 24; u16 icon[SMDH_SIZE_ICON_BIG / sizeof(u16)]; @@ -3289,11 +3297,11 @@ u32 ShowSmdhTitleInfo(Smdh* smdh, char* str, u16* screen) { WordWrapString(desc_l, lwrap); WordWrapString(desc_s, lwrap); WordWrapString(pub, lwrap); - ShowIconStringF(screen, icon, SMDH_DIM_ICON_BIG, SMDH_DIM_ICON_BIG, "%s%s\n%s\n%s", str, desc_l, desc_s, pub); + ShowIconStringF(screen, icon, SMDH_DIM_ICON_BIG, SMDH_DIM_ICON_BIG, "%s\n%s\n%s", desc_l, desc_s, pub); return 0; } -u32 ShowTwlIconTitleInfo(TwlIconData* twl_icon, char* str, u16* screen) { +u32 ShowTwlIconTitleInfo(TwlIconData* twl_icon, u16* screen) { const u32 lwrap = 24; u16 icon[TWLICON_SIZE_ICON / sizeof(u16)]; char desc[TWLICON_SIZE_DESC+1]; @@ -3301,7 +3309,7 @@ u32 ShowTwlIconTitleInfo(TwlIconData* twl_icon, char* str, u16* screen) { (GetTwlTitle(desc, twl_icon) != 0)) return 1; WordWrapString(desc, lwrap); - ShowIconStringF(screen, icon, TWLICON_DIM_ICON, TWLICON_DIM_ICON, "%s%s", str, desc); + ShowIconStringF(screen, icon, TWLICON_DIM_ICON, TWLICON_DIM_ICON, "%s", desc); return 0; } @@ -3309,11 +3317,12 @@ u32 ShowGbaFileTitleInfo(const char* path, u16* screen) { AgbHeader agb; if ((fvx_qread(path, &agb, 0, sizeof(AgbHeader), NULL) != FR_OK) || (ValidateAgbHeader(&agb) != 0)) return 1; + ClearScreen(screen, COLOR_STD_BG); ShowStringF(screen, "%.12s (AGB-%.4s)\n%s", agb.game_title, agb.game_code, AGB_DESTSTR(agb.game_code)); return 0; } -u32 ShowGameFileTitleInfoF(const char* path, u16* screen, const char* str, bool clear) { +u32 ShowGameFileIcon(const char* path, u16* screen) { char path_content[256]; u64 itype = IdentifyFileType(path); // initial type if (itype & GAME_TMD) { @@ -3331,27 +3340,19 @@ u32 ShowGameFileTitleInfoF(const char* path, u16* screen, const char* str, bool Smdh* smdh = (Smdh*) buffer; TwlIconData* twl_icon = (TwlIconData*) buffer; - char disp_str[64]; - snprintf(disp_str, 64, str ? "%s\n" : "", str); - // try loading SMDH, then try NDS / encrypted / GBA u32 ret = 1; u32 tp = 0; if (LoadSmdhFromGameFile(path, smdh) == 0) - ret = ShowSmdhTitleInfo(smdh, disp_str, screen); + ret = ShowSmdhTitleInfo(smdh, screen); else if ((LoadTwlMetaData(path, NULL, twl_icon) == 0) || ((itype & GAME_TAD) && (fvx_qread(path, twl_icon, TAD_BANNER_OFFSET, sizeof(TwlIconData), NULL) == FR_OK))) - ret = ShowTwlIconTitleInfo(twl_icon, disp_str, screen); + ret = ShowTwlIconTitleInfo(twl_icon, screen); else if ((tp = LoadEncryptedIconFromCiaTmd(path, buffer, NULL, false)) != 0) - ret = (tp == GAME_NCCH) ? ShowSmdhTitleInfo(smdh, disp_str, screen) : - (tp == GAME_NDS ) ? ShowTwlIconTitleInfo(twl_icon, disp_str, screen) : 1; + ret = (tp == GAME_NCCH) ? ShowSmdhTitleInfo(smdh, screen) : + (tp == GAME_NDS ) ? ShowTwlIconTitleInfo(twl_icon, screen) : 1; else ret = ShowGbaFileTitleInfo(path, screen); - if (!ret && clear) { - while(!(InputWait(0) & (BUTTON_A | BUTTON_B))); - ClearScreen(screen, COLOR_STD_BG); - } - free(buffer); return ret; } @@ -3487,8 +3488,6 @@ u32 ShowGameCheckerInfo(const char* path) { char conid_str[32] = { '\0' }; if (type & (GAME_CIA|GAME_TIE)) snprintf(conid_str, 64, "Console ID: %08lX\n", console_id); - // show icon on top - u32 icon_res = ShowGameFileTitleInfoF(path, ALT_SCREEN, NULL, false); // output results s32 state_verify = -1; @@ -3500,14 +3499,12 @@ u32 ShowGameCheckerInfo(const char* path) { "Contents size: %s\n" "%s\n%s \n" "Ticket/TMD: %s/%s\n" - "Icon data: %s\n" "Verification: %s", pathstr, typestr, srcstr, title_id, (title_version>>10)&0x3F, (title_version>>4)&0x3F, (title_version)&0xF, bytestr, contents_str, conid_str, (state_ticket == 0) ? "unknown" : (state_ticket == 2) ? "legit" : "illegit", (state_tmd == 0) ? "invalid" : (state_tmd == 2) ? "legit" : "illegit", - (icon_res) ? "unavailable" : "(see other screen)", (state_verify < 0) ? "pending\n \nProceed with verification?" : (state_verify == 0) ? "passed" : "failed") || (state_verify >= 0)) break; state_verify = VerifyGameFile(path); @@ -3515,23 +3512,9 @@ u32 ShowGameCheckerInfo(const char* path) { if (tmd) free(tmd); if (ticket) free(ticket); - if (!icon_res) ClearScreenF(true, true, COLOR_STD_BG); return 0; } -u32 ShowGameFileTitleInfo(const char* path) { - // try the checker tool first - if (ShowGameCheckerInfo(path) == 0) - return 0; - - // title id available? - char tidstr[32] = { '\0' }; - u64 tid = GetGameFileTitleId(path); - if (tid) snprintf(tidstr, 32, "<%016llX>", tid); - - return ShowGameFileTitleInfoF(path, MAIN_SCREEN, tidstr, true); -} - u32 BuildNcchInfoXorpads(const char* destdir, const char* path) { FIL fp_info; FIL fp_xorpad; diff --git a/arm9/source/utils/gameutil.h b/arm9/source/utils/gameutil.h index f3d14ad..9fcfa9a 100644 --- a/arm9/source/utils/gameutil.h +++ b/arm9/source/utils/gameutil.h @@ -14,8 +14,9 @@ u32 ExtractCodeFromCxiFile(const char* path, const char* path_out, char* extstr) u32 CompressCode(const char* path, const char* path_out); u64 GetGameFileTrimmedSize(const char* path); u32 TrimGameFile(const char* path); -u32 ShowGameFileTitleInfoF(const char* path, u16* screen, const char* str, bool clear); -u32 ShowGameFileTitleInfo(const char* path); +u32 ShowGameFileIcon(const char* path, u16* screen); +u32 ShowGameCheckerInfo(const char* path); +u64 GetGameFileTitleId(const char* path); u32 UninstallGameDataTie(const char* path, bool remove_tie, bool remove_ticket, bool remove_save); u32 GetTmdContentPath(char* path_content, const char* path_tmd); u32 GetTieContentPath(char* path_content, const char* path_tie); diff --git a/arm9/source/utils/scripting.c b/arm9/source/utils/scripting.c index 71b3414..46be6bf 100644 --- a/arm9/source/utils/scripting.c +++ b/arm9/source/utils/scripting.c @@ -1880,7 +1880,7 @@ bool ExecuteGM9Script(const char* path_script) { if (bitmap) { DrawBitmap(TOP_SCREEN, -1, -1, bitmap_width, bitmap_height, bitmap); free(bitmap); - } else if (ShowGameFileTitleInfoF(preview_str, TOP_SCREEN, NULL, false) != 0) { + } else if (ShowGameFileIcon(preview_str, TOP_SCREEN) != 0) { if (strncmp(preview_str, "off", _VAR_CNT_LEN) == 0) preview_str = "(preview disabled)"; DrawStringCenter(TOP_SCREEN, COLOR_STD_FONT, COLOR_STD_BG, "%s", preview_str); }