forked from Mirror/GodMode9
Add title info display for SMDH/NCCH/NCSD/CIA/TMD
This commit is contained in:
parent
433d79d050
commit
b9501318c5
@ -46,6 +46,21 @@ void DrawRectangle(u8* screen, int x, int y, int width, int height, int color)
|
||||
}
|
||||
}
|
||||
|
||||
void DrawBitmap(u8* screen, int x, int y, int w, int h, u8* bitmap)
|
||||
{
|
||||
u8* bitmapPos = bitmap;
|
||||
for (int yy = 0; yy < h; yy++) {
|
||||
int xDisplacement = (x * BYTES_PER_PIXEL * SCREEN_HEIGHT);
|
||||
int yDisplacement = ((SCREEN_HEIGHT - (y + yy) - 1) * BYTES_PER_PIXEL);
|
||||
u8* screenPos = screen + xDisplacement + yDisplacement;
|
||||
for (int xx = w - 1; xx >= 0; xx--) {
|
||||
memcpy(screenPos, bitmapPos, BYTES_PER_PIXEL);
|
||||
bitmapPos += BYTES_PER_PIXEL;
|
||||
screenPos += BYTES_PER_PIXEL * SCREEN_HEIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCharacter(u8* screen, int character, int x, int y, int color, int bgcolor)
|
||||
{
|
||||
for (int yy = 0; yy < FONT_HEIGHT; yy++) {
|
||||
@ -110,6 +125,27 @@ u32 GetDrawStringWidth(const char* str) {
|
||||
return width;
|
||||
}
|
||||
|
||||
void WordWrapString(char* str, int llen) {
|
||||
char* last_brk = str - 1;
|
||||
char* last_spc = str - 1;
|
||||
if (!llen) llen = (SCREEN_WIDTH_TOP / FONT_WIDTH);
|
||||
for (char* str_ptr = str;; str_ptr++) {
|
||||
if (!*str_ptr || (*str_ptr == ' ')) { // on space or string_end
|
||||
if (str_ptr - last_brk > llen) { // if maximum line lenght is exceeded
|
||||
if (last_spc > last_brk) { // put a line_brk at the last space
|
||||
*last_spc = '\n';
|
||||
last_brk = last_spc;
|
||||
last_spc = str_ptr;
|
||||
} else if (*str_ptr) { // if we have no applicable space
|
||||
*str_ptr = '\n';
|
||||
last_brk = str_ptr;
|
||||
}
|
||||
} else if (*str_ptr) last_spc = str_ptr;
|
||||
} else if (*str_ptr == '\n') last_brk = str_ptr;
|
||||
if (!*str_ptr) break;
|
||||
}
|
||||
}
|
||||
|
||||
void ResizeString(char* dest, const char* orig, int nsize, int tpos, bool align_right) {
|
||||
int osize = strnlen(orig, 256);
|
||||
if (nsize < osize) {
|
||||
@ -180,6 +216,33 @@ void ShowString(const char *format, ...)
|
||||
} else ClearScreenF(true, false, COLOR_STD_BG);
|
||||
}
|
||||
|
||||
void ShowIconString(u8* icon, int w, int h, const char *format, ...)
|
||||
{
|
||||
static const u32 icon_offset = 10;
|
||||
u32 str_width, str_height, tot_height;
|
||||
u32 x_str, y_str, x_bmp, y_bmp;
|
||||
|
||||
ClearScreenF(true, false, COLOR_STD_BG);
|
||||
if (!format || !*format) return; // only if there is something in there
|
||||
|
||||
char str[STRBUF_SIZE] = { 0 };
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
vsnprintf(str, STRBUF_SIZE, format, va);
|
||||
va_end(va);
|
||||
|
||||
str_width = GetDrawStringWidth(str);
|
||||
str_height = GetDrawStringHeight(str);
|
||||
tot_height = h + icon_offset + str_height;
|
||||
x_str = (str_width >= SCREEN_WIDTH_TOP) ? 0 : (SCREEN_WIDTH_TOP - str_width) / 2;
|
||||
y_str = (str_height >= SCREEN_HEIGHT) ? 0 : h + icon_offset + (SCREEN_HEIGHT - tot_height) / 2;
|
||||
x_bmp = (w >= SCREEN_WIDTH_TOP) ? 0 : (SCREEN_WIDTH_TOP - w) / 2;
|
||||
y_bmp = (tot_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - tot_height) / 2;
|
||||
|
||||
DrawBitmap(TOP_SCREEN, x_bmp, y_bmp, w, h, icon);
|
||||
DrawStringF(TOP_SCREEN, x_str, y_str, COLOR_STD_FONT, COLOR_STD_BG, str);
|
||||
}
|
||||
|
||||
bool ShowPrompt(bool ask, const char *format, ...)
|
||||
{
|
||||
u32 str_width, str_height;
|
||||
|
@ -58,6 +58,7 @@
|
||||
void ClearScreen(unsigned char *screen, int color);
|
||||
void ClearScreenF(bool clear_top, bool clear_bottom, int color);
|
||||
void DrawRectangle(u8* screen, int x, int y, int width, int height, int color);
|
||||
void DrawBitmap(u8* screen, int x, int y, int w, int h, u8* bitmap);
|
||||
|
||||
void DrawCharacter(unsigned char *screen, int character, int x, int y, int color, int bgcolor);
|
||||
void DrawString(unsigned char *screen, const char *str, int x, int y, int color, int bgcolor);
|
||||
@ -66,12 +67,14 @@ void DrawStringF(unsigned char *screen, int x, int y, int color, int bgcolor, co
|
||||
u32 GetDrawStringHeight(const char* str);
|
||||
u32 GetDrawStringWidth(const char* str);
|
||||
|
||||
void WordWrapString(char* str, int llen);
|
||||
void ResizeString(char* dest, const char* orig, int nsize, int tpos, bool align_right);
|
||||
void TruncateString(char* dest, const char* orig, int nsize, int tpos);
|
||||
void FormatNumber(char* str, u64 number);
|
||||
void FormatBytes(char* str, u64 bytes);
|
||||
|
||||
void ShowString(const char *format, ...);
|
||||
void ShowIconString(u8* icon, int w, int h, const char *format, ...);
|
||||
bool ShowPrompt(bool ask, const char *format, ...);
|
||||
bool ShowUnlockSequence(u32 seqlvl, const char *format, ...);
|
||||
u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...);
|
||||
|
@ -8,6 +8,7 @@
|
||||
u32 IdentifyFileType(const char* path) {
|
||||
const u8 romfs_magic[] = { ROMFS_MAGIC };
|
||||
const u8 tickdb_magic[] = { TICKDB_MAGIC };
|
||||
const u8 smdh_magic[] = { SMDH_MAGIC };
|
||||
u8 header[0x200] __attribute__((aligned(32))); // minimum required size
|
||||
void* data = (void*) header;
|
||||
size_t fsize = FileGetSize(path);
|
||||
@ -60,6 +61,8 @@ u32 IdentifyFileType(const char* path) {
|
||||
return SYS_FIRM; // FIRM file
|
||||
} else if (memcmp(header + 0x100, tickdb_magic, sizeof(tickdb_magic)) == 0) {
|
||||
return SYS_TICKDB; // ticket.db
|
||||
} else if (memcmp(header, smdh_magic, sizeof(smdh_magic)) == 0) {
|
||||
return GAME_SMDH; // SMDH file
|
||||
}
|
||||
}
|
||||
if ((fsize > sizeof(BossHeader)) &&
|
||||
|
@ -13,11 +13,12 @@
|
||||
#define GAME_BOSS (1UL<<8)
|
||||
#define GAME_NUSCDN (1UL<<9)
|
||||
#define GAME_TICKET (1UL<<10)
|
||||
#define SYS_FIRM (1UL<<11)
|
||||
#define SYS_TICKDB (1UL<<12)
|
||||
#define BIN_NCCHNFO (1UL<<13)
|
||||
#define BIN_LAUNCH (1UL<<14)
|
||||
#define BIN_SUPPORT (1UL<<15)
|
||||
#define GAME_SMDH (1UL<<11)
|
||||
#define SYS_FIRM (1UL<<12)
|
||||
#define SYS_TICKDB (1UL<<13)
|
||||
#define BIN_NCCHNFO (1UL<<14)
|
||||
#define BIN_LAUNCH (1UL<<15)
|
||||
#define BIN_SUPPORT (1UL<<16)
|
||||
#define TYPE_BASE 0x00FFFFFF // 24 bit reserved for base types
|
||||
|
||||
#define FLAG_CTR (1UL<<29)
|
||||
@ -30,6 +31,7 @@
|
||||
#define FYTPE_ENCRYPTABLE(tp) (tp&(GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_BOSS))
|
||||
#define FTYPE_BUILDABLE(tp) (tp&(GAME_NCSD|GAME_NCCH|GAME_TMD))
|
||||
#define FTYPE_BUILDABLE_L(tp) (FTYPE_BUILDABLE(tp) && (tp&(GAME_TMD)))
|
||||
#define FTYPE_TITLEINFO(tp) (tp&(GAME_SMDH|GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_TMD))
|
||||
#define FTYPE_TRANSFERABLE(tp) ((u32) (tp&(IMG_FAT|FLAG_CTR)) == (u32) (IMG_FAT|FLAG_CTR))
|
||||
#define FTYPE_HSINJECTABLE(tp) ((u32) (tp&(GAME_NCCH|FLAG_CXI)) == (u32) (GAME_NCCH|FLAG_CXI))
|
||||
#define FTYPE_RESTORABLE(tp) (tp&(IMG_NAND))
|
||||
|
@ -17,7 +17,7 @@ u32 ValidateCiaHeader(CiaHeader* header) {
|
||||
}
|
||||
|
||||
u32 GetCiaInfo(CiaInfo* info, CiaHeader* header) {
|
||||
memcpy(info, header, 0x20); // take over first 0x20 byte
|
||||
if ((u8*) info != (u8*) header) memcpy(info, header, 0x20); // take over first 0x20 byte
|
||||
|
||||
info->offset_cert = align(header->size_header, 64);
|
||||
info->offset_ticket = info->offset_cert + align(header->size_cert, 64);
|
||||
|
@ -7,4 +7,5 @@
|
||||
#include "romfs.h"
|
||||
#include "firm.h"
|
||||
#include "boss.h"
|
||||
#include "smdh.h"
|
||||
#include "ncchinfo.h"
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "gameutil.h"
|
||||
#include "game.h"
|
||||
#include "hid.h"
|
||||
#include "ui.h"
|
||||
#include "fsperm.h"
|
||||
#include "filetype.h"
|
||||
@ -191,6 +192,7 @@ u32 LoadExeFsFile(void* data, const char* path, u32 offset, const char* name, u3
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (exefile) {
|
||||
u32 size_exefile = exefile->size;
|
||||
u32 offset_exefile = (ncch.offset_exefs * NCCH_MEDIA_UNIT) + sizeof(ExeFsHeader) + exefile->offset;
|
||||
@ -1374,6 +1376,105 @@ u32 BuildCiaFromGameFile(const char* path, bool force_legit) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 ShowSmdhTitleInfo(Smdh* smdh) {
|
||||
const u32 lwrap = 24;
|
||||
u8* icon = (u8*) (TEMP_BUFFER + sizeof(Smdh));
|
||||
char* desc_l = (char*) icon + SMDH_SIZE_ICON_BIG;
|
||||
char* desc_s = (char*) desc_l + SMDH_SIZE_DESC_LONG;
|
||||
char* pub = (char*) desc_s + SMDH_SIZE_DESC_SHORT;
|
||||
if ((GetSmdhIconBig(icon, smdh) != 0) ||
|
||||
(GetSmdhDescLong(desc_l, smdh) != 0) ||
|
||||
(GetSmdhDescShort(desc_s, smdh) != 0) ||
|
||||
(GetSmdhPublisher(pub, smdh) != 0))
|
||||
return 1;
|
||||
WordWrapString(desc_l, lwrap);
|
||||
WordWrapString(desc_s, lwrap);
|
||||
WordWrapString(pub, lwrap);
|
||||
ShowIconString(icon, SMDH_DIM_ICON_BIG, SMDH_DIM_ICON_BIG, "%s\n%s\n%s", desc_l, desc_s, pub);
|
||||
InputWait();
|
||||
ClearScreenF(true, false, COLOR_STD_BG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 ShowSmdhFileTitleInfo(const char* path) {
|
||||
Smdh* smdh = (Smdh*) (void*) TEMP_BUFFER;
|
||||
UINT btr;
|
||||
if ((fvx_qread(path, smdh, 0, sizeof(Smdh), &btr) != FR_OK) || (btr != sizeof(Smdh)))
|
||||
return 1;
|
||||
return ShowSmdhTitleInfo(smdh);
|
||||
}
|
||||
|
||||
u32 ShowNcchFileTitleInfo(const char* path) {
|
||||
Smdh* smdh = (Smdh*) (void*) TEMP_BUFFER;
|
||||
if (LoadExeFsFile(smdh, path, 0, "icon", sizeof(Smdh)) != 0)
|
||||
return 1;
|
||||
return ShowSmdhTitleInfo(smdh);
|
||||
}
|
||||
|
||||
u32 ShowNcsdFileTitleInfo(const char* path) {
|
||||
Smdh* smdh = (Smdh*) (void*) TEMP_BUFFER;
|
||||
if (LoadExeFsFile(smdh, path, NCSD_CNT0_OFFSET, "icon", sizeof(Smdh)) != 0)
|
||||
return 1;
|
||||
return ShowSmdhTitleInfo(smdh);
|
||||
}
|
||||
|
||||
u32 ShowCiaFileTitleInfo(const char* path) {
|
||||
Smdh* smdh = (Smdh*) (void*) TEMP_BUFFER;
|
||||
CiaInfo info;
|
||||
UINT btr;
|
||||
|
||||
if ((fvx_qread(path, &info, 0, 0x20, &btr) != FR_OK) || (btr != 0x20) ||
|
||||
(GetCiaInfo(&info, (CiaHeader*) &info) != 0))
|
||||
return 1;
|
||||
if ((info.offset_meta) && ((fvx_qread(path, smdh, info.offset_meta + 0x400, sizeof(Smdh), &btr) != FR_OK) ||
|
||||
(btr != sizeof(Smdh)))) return 1;
|
||||
else if (LoadExeFsFile(smdh, path, info.offset_content, "icon", sizeof(Smdh)) != 0) return 1;
|
||||
|
||||
return ShowSmdhTitleInfo(smdh);
|
||||
}
|
||||
|
||||
u32 ShowTmdFileTitleInfo(const char* path) {
|
||||
const u8 dlc_tid_high[] = { DLC_TID_HIGH };
|
||||
TitleMetaData* tmd = (TitleMetaData*) TEMP_BUFFER;
|
||||
TmdContentChunk* chunk = (TmdContentChunk*) (tmd + 1);
|
||||
|
||||
// content path string
|
||||
char path_content[256];
|
||||
char* name_content;
|
||||
strncpy(path_content, path, 256);
|
||||
name_content = strrchr(path_content, '/');
|
||||
if (!name_content) return 1; // will not happen
|
||||
name_content++;
|
||||
|
||||
// load TMD file
|
||||
if ((LoadTmdFile(tmd, path) != 0) || !getbe16(tmd->content_count))
|
||||
return 1;
|
||||
snprintf(name_content, 256 - (name_content - path_content),
|
||||
(memcmp(tmd->title_id, dlc_tid_high, sizeof(dlc_tid_high)) == 0) ? "00000000/%08lx.app" : "%08lx.app", getbe32(chunk->id));
|
||||
|
||||
return ShowGameFileTitleInfo(path_content);
|
||||
}
|
||||
|
||||
u32 ShowGameFileTitleInfo(const char* path) {
|
||||
u32 filetype = IdentifyFileType(path);
|
||||
u32 ret = 1;
|
||||
|
||||
// build CIA from game file
|
||||
if (filetype & GAME_SMDH) {
|
||||
ret = ShowSmdhFileTitleInfo(path);
|
||||
} else if (filetype & GAME_NCCH) {
|
||||
ret = ShowNcchFileTitleInfo(path);
|
||||
} else if (filetype & GAME_NCSD) {
|
||||
ret = ShowNcsdFileTitleInfo(path);
|
||||
} else if (filetype & GAME_CIA) {
|
||||
ret = ShowCiaFileTitleInfo(path);
|
||||
} else if (filetype & GAME_TMD) {
|
||||
ret = ShowTmdFileTitleInfo(path);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 BuildNcchInfoXorpads(const char* destdir, const char* path) {
|
||||
FIL fp_info;
|
||||
FIL fp_xorpad;
|
||||
|
@ -8,6 +8,7 @@ u32 VerifyGameFile(const char* path);
|
||||
u32 CheckEncryptedGameFile(const char* path);
|
||||
u32 CryptGameFile(const char* path, bool inplace, bool encrypt);
|
||||
u32 BuildCiaFromGameFile(const char* path, bool force_legit);
|
||||
u32 ShowGameFileTitleInfo(const char* path);
|
||||
u32 BuildNcchInfoXorpads(const char* destdir, const char* path);
|
||||
u32 CheckHealthAndSafetyInject(const char* hsdrv);
|
||||
u32 InjectHealthAndSafety(const char* path, const char* destdrv);
|
||||
|
61
source/game/smdh.c
Normal file
61
source/game/smdh.c
Normal file
@ -0,0 +1,61 @@
|
||||
#include "smdh.h"
|
||||
|
||||
#define SMDH_STRING(str, src, len) for (u32 i = 0; i < len; i++) str[i] = src[i]
|
||||
// shamelessly stolen from bch2obj.py / 3ds_hb_menu :)
|
||||
#define SMDH_LUT 0, 1, 8, 9, 2, 3, 10, 11, 16, 17, 24, 25, 18, 19, 26, 27, \
|
||||
4, 5, 12, 13, 6, 7, 14, 15, 20, 21, 28, 29, 22, 23, 30, 31, \
|
||||
32, 33, 40, 41, 34, 35, 42, 43, 48, 49, 56, 57, 50, 51, 58, 59, \
|
||||
36, 37, 44, 45, 38, 39, 46, 47, 52, 53, 60, 61, 54, 55, 62, 63
|
||||
|
||||
u32 ConvertSmdhIcon(u8* icon, const u16* smdh_icon, u32 w, u32 h) {
|
||||
const u32 lut[8*8] = { SMDH_LUT };
|
||||
u16* pix565 = (u16*) smdh_icon;
|
||||
for (u32 y = 0; y < h; y += 8) {
|
||||
for (u32 x = 0; x < w; x += 8) {
|
||||
for (u32 i = 0; i < 8*8; i++) {
|
||||
u32 ix = x + (lut[i] & 0x7);
|
||||
u32 iy = y + (lut[i] >> 3);
|
||||
u8* pix888 = icon + ((iy * w) + ix) * 3;
|
||||
*(pix888++) = ((*pix565 >> 0) & 0x1F) << 3; // B
|
||||
*(pix888++) = ((*pix565 >> 5) & 0x3F) << 2; // G
|
||||
*(pix888++) = ((*pix565 >> 11) & 0x1F) << 3; // R
|
||||
pix565++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// short desc is max 64(+1) chars long
|
||||
u32 GetSmdhDescShort(char* desc, const Smdh* smdh) {
|
||||
const SmdhAppTitle* title = &(smdh->apptitles[1]); // english title
|
||||
memset(desc, 0, SMDH_SIZE_DESC_SHORT + 1);
|
||||
SMDH_STRING(desc, title->short_desc, SMDH_SIZE_DESC_SHORT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// long desc is max 128(+1) chars long
|
||||
u32 GetSmdhDescLong(char* desc, const Smdh* smdh) {
|
||||
const SmdhAppTitle* title = &(smdh->apptitles[1]); // english title
|
||||
memset(desc, 0, SMDH_SIZE_DESC_LONG + 1);
|
||||
SMDH_STRING(desc, title->long_desc, SMDH_SIZE_DESC_LONG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// publisher is max 64(+1) chars long
|
||||
u32 GetSmdhPublisher(char* pub, const Smdh* smdh) {
|
||||
const SmdhAppTitle* title = &(smdh->apptitles[1]); // english title
|
||||
memset(pub, 0, SMDH_SIZE_PUBLISHER + 1);
|
||||
SMDH_STRING(pub, title->publisher, SMDH_SIZE_PUBLISHER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// small icons are 24x24 => 0x6C0 byte in RGB888
|
||||
u32 GetSmdhIconSmall(u8* icon, const Smdh* smdh) {
|
||||
return ConvertSmdhIcon(icon, smdh->icon_small, SMDH_DIM_ICON_SMALL, SMDH_DIM_ICON_SMALL);
|
||||
}
|
||||
|
||||
// big icons are 48x48 => 0x1B00 byte in RGB888
|
||||
u32 GetSmdhIconBig(u8* icon, const Smdh* smdh) {
|
||||
return ConvertSmdhIcon(icon, smdh->icon_big, SMDH_DIM_ICON_BIG, SMDH_DIM_ICON_BIG);
|
||||
}
|
45
source/game/smdh.h
Normal file
45
source/game/smdh.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define SMDH_MAGIC 'S', 'M', 'D', 'H'
|
||||
#define SMDH_SIZE_DESC_SHORT 64
|
||||
#define SMDH_SIZE_DESC_LONG 128
|
||||
#define SMDH_SIZE_PUBLISHER 64
|
||||
#define SMDH_DIM_ICON_SMALL 24
|
||||
#define SMDH_DIM_ICON_BIG 48
|
||||
#define SMDH_SIZE_ICON_SMALL (SMDH_DIM_ICON_SMALL * SMDH_DIM_ICON_SMALL * 3) // w * h * bpp (rgb888)
|
||||
#define SMDH_SIZE_ICON_BIG (SMDH_DIM_ICON_BIG * SMDH_DIM_ICON_BIG * 3) // w * h * bpp (rgb888)
|
||||
|
||||
// see: https://www.3dbrew.org/wiki/SMDH#Application_Titles
|
||||
typedef struct {
|
||||
u16 short_desc[0x40];
|
||||
u16 long_desc[0x80];
|
||||
u16 publisher[0x40];
|
||||
} __attribute__((packed)) SmdhAppTitle;
|
||||
|
||||
// see: https://www.3dbrew.org/wiki/SMDH
|
||||
typedef struct {
|
||||
char magic[4];
|
||||
u16 version;
|
||||
u16 reserved0;
|
||||
SmdhAppTitle apptitles[0x10]; // 1 -> english title
|
||||
u8 game_ratings[0x10];
|
||||
u32 region_lockout;
|
||||
u32 matchmaker_id;
|
||||
u64 matchmaker_id_bit;
|
||||
u32 flags;
|
||||
u16 version_eula;
|
||||
u16 reserved1;
|
||||
u32 anim_def_frame;
|
||||
u32 cec_id;
|
||||
u64 reserved2;
|
||||
u16 icon_small[0x240]; // 24x24x16bpp / 8x8 tiles / rgb565
|
||||
u16 icon_big[0x900]; // 48x48x16bpp / 8x8 tiles / rgb565
|
||||
} __attribute__((packed)) Smdh;
|
||||
|
||||
u32 GetSmdhDescShort(char* desc, const Smdh* smdh);
|
||||
u32 GetSmdhDescLong(char* desc, const Smdh* smdh);
|
||||
u32 GetSmdhPublisher(char* pub, const Smdh* smdh);
|
||||
u32 GetSmdhIconSmall(u8* icon, const Smdh* smdh);
|
||||
u32 GetSmdhIconBig(u8* icon, const Smdh* smdh);
|
@ -653,14 +653,15 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
||||
bool cryptable_inplace = ((encryptable||decryptable) && !in_output_path && (drvtype & DRV_FAT));
|
||||
bool buildable = (FTYPE_BUILDABLE(filetype));
|
||||
bool buildable_legit = (FTYPE_BUILDABLE_L(filetype));
|
||||
bool titleinfo = (FTYPE_TITLEINFO(filetype));
|
||||
bool transferable = (FTYPE_TRANSFERABLE(filetype) && IS_A9LH && (drvtype & DRV_FAT));
|
||||
bool hsinjectable = (FTYPE_HSINJECTABLE(filetype));
|
||||
bool restorable = (FTYPE_RESTORABLE(filetype) && IS_A9LH && !(drvtype & DRV_SYSNAND));
|
||||
bool ebackupable = (FTYPE_EBACKUP(filetype));
|
||||
bool xorpadable = (FTYPE_XORPAD(filetype));
|
||||
bool launchable = ((FTYPE_PAYLOAD(filetype)) && (drvtype & DRV_FAT));
|
||||
bool special_opt = mountable || verificable || decryptable || encryptable ||
|
||||
buildable || buildable_legit || hsinjectable || restorable || xorpadable || launchable || ebackupable;
|
||||
bool special_opt = mountable || verificable || decryptable || encryptable || buildable || buildable_legit ||
|
||||
titleinfo || hsinjectable || restorable || xorpadable || launchable || ebackupable;
|
||||
|
||||
char pathstr[32+1];
|
||||
TruncateString(pathstr, curr_entry->path, 32, 8);
|
||||
@ -695,6 +696,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
||||
(filetype & GAME_TMD ) ? "TMD file options..." :
|
||||
(filetype & GAME_BOSS ) ? "BOSS file options..." :
|
||||
(filetype & GAME_NUSCDN)? "Decrypt NUS/CDN file" :
|
||||
(filetype & GAME_SMDH) ? "Show SMDH title info" :
|
||||
(filetype & SYS_FIRM ) ? "FIRM image options..." :
|
||||
(filetype & SYS_TICKDB) ? "Mount as ticket.db" :
|
||||
(filetype & BIN_NCCHNFO)? "NCCHinfo options..." :
|
||||
@ -786,6 +788,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
||||
|
||||
// stuff for special menu starts here
|
||||
n_opt = 0;
|
||||
int show_info = (titleinfo) ? ++n_opt : -1;
|
||||
int mount = (mountable) ? ++n_opt : -1;
|
||||
int restore = (restorable) ? ++n_opt : -1;
|
||||
int ebackup = (ebackupable) ? ++n_opt : -1;
|
||||
@ -802,6 +805,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
||||
if (mount > 0) optionstr[mount-1] = "Mount image to drive";
|
||||
if (restore > 0) optionstr[restore-1] = "Restore SysNAND (safe)";
|
||||
if (ebackup > 0) optionstr[ebackup-1] = "Update embedded backup";
|
||||
if (show_info > 0) optionstr[show_info-1] = "Show title info";
|
||||
if (decrypt > 0) optionstr[decrypt-1] = (cryptable_inplace) ? "Decrypt file (...)" : "Decrypt file (" OUTPUT_PATH ")";
|
||||
if (encrypt > 0) optionstr[encrypt-1] = (cryptable_inplace) ? "Encrypt file (...)" : "Encrypt file (" OUTPUT_PATH ")";
|
||||
if (build > 0) optionstr[build-1] = (build_legit < 0) ? "Build CIA from file" : "Build CIA (standard)";
|
||||
@ -993,6 +997,10 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
||||
(VerifyGameFile(curr_entry->path) == 0) ? "success" : "failed");
|
||||
}
|
||||
return 0;
|
||||
} else if (user_select == show_info) { // -> Show title info
|
||||
if (ShowGameFileTitleInfo(curr_entry->path) != 0)
|
||||
ShowPrompt(false, "Title info: not found");
|
||||
return 0;
|
||||
} else if (user_select == hsinject) { // -> Inject to Health & Safety
|
||||
char* destdrv[2] = { NULL };
|
||||
n_opt = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user