mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 21:52:48 +00:00
DSiWare Export -> TAD
This commit is contained in:
parent
ec861a7bf7
commit
20d2772056
@ -129,9 +129,9 @@ u64 IdentifyFileType(const char* path) {
|
|||||||
return type;
|
return type;
|
||||||
} else if ((strncmp(path + 2, "/Nintendo DSiWare/", 18) == 0) &&
|
} else if ((strncmp(path + 2, "/Nintendo DSiWare/", 18) == 0) &&
|
||||||
(sscanf(fname, "%08lx.bin", &id) == 1) && (strncasecmp(ext, "bin", 4) == 0)) {
|
(sscanf(fname, "%08lx.bin", &id) == 1) && (strncasecmp(ext, "bin", 4) == 0)) {
|
||||||
DsiWareExpHeader hdr;
|
TadHeader hdr;
|
||||||
if ((FileGetData(path, &hdr, DSIWEXP_HEADER_LEN, DSIWEXP_HEADER_OFFSET) == DSIWEXP_HEADER_LEN) &&
|
if ((FileGetData(path, &hdr, TAD_HEADER_LEN, TAD_HEADER_OFFSET) == TAD_HEADER_LEN) &&
|
||||||
(strncmp(hdr.magic, DSIWEXP_HEADER_MAGIC, strlen(DSIWEXP_HEADER_MAGIC)) == 0))
|
(strncmp(hdr.magic, TAD_HEADER_MAGIC, strlen(TAD_HEADER_MAGIC)) == 0))
|
||||||
return GAME_TAD;
|
return GAME_TAD;
|
||||||
} else if ((strnlen(fname, 16) == 8) && (sscanf(fname, "%08lx", &id) == 1)) {
|
} else if ((strnlen(fname, 16) == 8) && (sscanf(fname, "%08lx", &id) == 1)) {
|
||||||
char path_cdn[256];
|
char path_cdn[256];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "sddata.h"
|
#include "sddata.h"
|
||||||
#include "dsiwareexp.h"
|
#include "tad.h"
|
||||||
#include "aes.h"
|
#include "aes.h"
|
||||||
#include "sha.h"
|
#include "sha.h"
|
||||||
|
|
||||||
@ -56,26 +56,26 @@ FilCryptInfo* fx_find_cryptinfo(FIL* fptr) {
|
|||||||
|
|
||||||
FRESULT fx_decrypt_dsiware (FIL* fp, void* buff, FSIZE_t ofs, UINT len) {
|
FRESULT fx_decrypt_dsiware (FIL* fp, void* buff, FSIZE_t ofs, UINT len) {
|
||||||
const u32 mode = AES_CNT_TITLEKEY_DECRYPT_MODE;
|
const u32 mode = AES_CNT_TITLEKEY_DECRYPT_MODE;
|
||||||
const u32 num_tbl = sizeof(DsiWareExpContentTable) / sizeof(u32);
|
const u32 num_tbl = sizeof(TadContentTable) / sizeof(u32);
|
||||||
const FSIZE_t ofs0 = f_tell(fp);
|
const FSIZE_t ofs0 = f_tell(fp);
|
||||||
|
|
||||||
u8 __attribute__((aligned(16))) iv[AES_BLOCK_SIZE];
|
u8 __attribute__((aligned(16))) iv[AES_BLOCK_SIZE];
|
||||||
u32 tbl[num_tbl];
|
u32 tbl[num_tbl];
|
||||||
u8 hdr[DSIWEXP_HEADER_LEN];
|
u8 hdr[TAD_HEADER_LEN];
|
||||||
|
|
||||||
FRESULT res;
|
FRESULT res;
|
||||||
UINT br;
|
UINT br;
|
||||||
|
|
||||||
|
|
||||||
// read and decrypt header
|
// read and decrypt header
|
||||||
if ((res = f_lseek(fp, DSIWEXP_HEADER_OFFSET)) != FR_OK) return res;
|
if ((res = f_lseek(fp, TAD_HEADER_OFFSET)) != FR_OK) return res;
|
||||||
if ((res = f_read(fp, hdr, DSIWEXP_HEADER_LEN, &br)) != FR_OK) return res;
|
if ((res = f_read(fp, hdr, TAD_HEADER_LEN, &br)) != FR_OK) return res;
|
||||||
if (br != DSIWEXP_HEADER_LEN) return FR_DENIED;
|
if (br != TAD_HEADER_LEN) return FR_DENIED;
|
||||||
memcpy(iv, hdr + DSIWEXP_HEADER_LEN - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
|
memcpy(iv, hdr + TAD_HEADER_LEN - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
|
||||||
cbc_decrypt(hdr, hdr, sizeof(DsiWareExpHeader) / AES_BLOCK_SIZE, mode, iv);
|
cbc_decrypt(hdr, hdr, sizeof(TadHeader) / AES_BLOCK_SIZE, mode, iv);
|
||||||
|
|
||||||
// setup the table
|
// setup the table
|
||||||
if (BuildDsiWareExportContentTable(tbl, hdr) != 0) return FR_DENIED;
|
if (BuildTadContentTable(tbl, hdr) != 0) return FR_DENIED;
|
||||||
if (tbl[num_tbl-1] > f_size(fp)) return FR_DENIED; // obviously missing data
|
if (tbl[num_tbl-1] > f_size(fp)) return FR_DENIED; // obviously missing data
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
#include "dsiwareexp.h"
|
|
||||||
|
|
||||||
|
|
||||||
u32 BuildDsiWareExportContentTable(void* table, void* header) {
|
|
||||||
DsiWareExpHeader* hdr = (DsiWareExpHeader*) header;
|
|
||||||
DsiWareExpContentTable* tbl = (DsiWareExpContentTable*) table;
|
|
||||||
|
|
||||||
if (strncmp(hdr->magic, DSIWEXP_HEADER_MAGIC, strlen(DSIWEXP_HEADER_MAGIC)) != 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
tbl->banner_end = 0 + sizeof(DsiWareExpBanner) + sizeof(DsiWareExpBlockMetaData);
|
|
||||||
tbl->header_end = tbl->banner_end + sizeof(DsiWareExpHeader) + sizeof(DsiWareExpBlockMetaData);
|
|
||||||
tbl->footer_end = tbl->header_end + sizeof(DsiWareExpFooter) + sizeof(DsiWareExpBlockMetaData);
|
|
||||||
|
|
||||||
u32 content_end_last = tbl->footer_end;
|
|
||||||
for (u32 i = 0; i < DSIWEXP_NUM_CONTENT; i++) {
|
|
||||||
tbl->content_end[i] = content_end_last;
|
|
||||||
if (!hdr->content_size[i]) continue; // non-existant section
|
|
||||||
tbl->content_end[i] += align(hdr->content_size[i], 0x10) + sizeof(DsiWareExpBlockMetaData);
|
|
||||||
content_end_last = tbl->content_end[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -11,6 +11,6 @@
|
|||||||
#include "codelzss.h"
|
#include "codelzss.h"
|
||||||
#include "nds.h"
|
#include "nds.h"
|
||||||
#include "gba.h"
|
#include "gba.h"
|
||||||
#include "dsiwareexp.h"
|
#include "tad.h"
|
||||||
#include "3dsx.h"
|
#include "3dsx.h"
|
||||||
#include "ncchinfo.h"
|
#include "ncchinfo.h"
|
||||||
|
24
arm9/source/game/tad.c
Normal file
24
arm9/source/game/tad.c
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include "tad.h"
|
||||||
|
|
||||||
|
|
||||||
|
u32 BuildTadContentTable(void* table, void* header) {
|
||||||
|
TadHeader* hdr = (TadHeader*) header;
|
||||||
|
TadContentTable* tbl = (TadContentTable*) table;
|
||||||
|
|
||||||
|
if (strncmp(hdr->magic, TAD_HEADER_MAGIC, strlen(TAD_HEADER_MAGIC)) != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
tbl->banner_end = 0 + sizeof(TadBanner) + sizeof(TadBlockMetaData);
|
||||||
|
tbl->header_end = tbl->banner_end + sizeof(TadHeader) + sizeof(TadBlockMetaData);
|
||||||
|
tbl->footer_end = tbl->header_end + sizeof(TadFooter) + sizeof(TadBlockMetaData);
|
||||||
|
|
||||||
|
u32 content_end_last = tbl->footer_end;
|
||||||
|
for (u32 i = 0; i < TAD_NUM_CONTENT; i++) {
|
||||||
|
tbl->content_end[i] = content_end_last;
|
||||||
|
if (!hdr->content_size[i]) continue; // non-existant section
|
||||||
|
tbl->content_end[i] += align(hdr->content_size[i], 0x10) + sizeof(TadBlockMetaData);
|
||||||
|
content_end_last = tbl->content_end[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -3,32 +3,32 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "nds.h"
|
#include "nds.h"
|
||||||
|
|
||||||
#define DSIWEXP_NUM_CONTENT 11
|
#define TAD_NUM_CONTENT 11
|
||||||
#define DSIWEXP_HEADER_MAGIC "3FDT"
|
#define TAD_HEADER_MAGIC "3FDT"
|
||||||
#define DSIWEXP_BANNER_OFFSET 0
|
#define TAD_BANNER_OFFSET 0
|
||||||
#define DSIWEXP_BANNER_LEN (sizeof(DsiWareExpBanner) + sizeof(DsiWareExpBlockMetaData))
|
#define TAD_BANNER_LEN (sizeof(TadBanner) + sizeof(TadBlockMetaData))
|
||||||
#define DSIWEXP_HEADER_OFFSET (DSIWEXP_BANNER_OFFSET + DSIWEXP_BANNER_LEN)
|
#define TAD_HEADER_OFFSET (TAD_BANNER_OFFSET + TAD_BANNER_LEN)
|
||||||
#define DSIWEXP_HEADER_LEN (sizeof(DsiWareExpHeader) + sizeof(DsiWareExpBlockMetaData))
|
#define TAD_HEADER_LEN (sizeof(TadHeader) + sizeof(TadBlockMetaData))
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 banner_end;
|
u32 banner_end;
|
||||||
u32 header_end;
|
u32 header_end;
|
||||||
u32 footer_end;
|
u32 footer_end;
|
||||||
u32 content_end[DSIWEXP_NUM_CONTENT];
|
u32 content_end[TAD_NUM_CONTENT];
|
||||||
} __attribute__((packed)) DsiWareExpContentTable;
|
} __attribute__((packed)) TadContentTable;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#Block_Metadata
|
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#Block_Metadata
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 cmac[16];
|
u8 cmac[16];
|
||||||
u8 iv0[16];
|
u8 iv0[16];
|
||||||
} __attribute__((packed)) DsiWareExpBlockMetaData;
|
} __attribute__((packed)) TadBlockMetaData;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#File_Structure_v2
|
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#File_Structure_v2
|
||||||
typedef struct {
|
typedef struct {
|
||||||
TwlIconData icon_data;
|
TwlIconData icon_data;
|
||||||
u8 unknown[0x4000 - sizeof(TwlIconData)];
|
u8 unknown[0x4000 - sizeof(TwlIconData)];
|
||||||
} __attribute__((packed)) DsiWareExpBanner;
|
} __attribute__((packed)) TadBanner;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#Header_2
|
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#Header_2
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -39,21 +39,21 @@ typedef struct {
|
|||||||
u8 cbc_test_block[0x10];
|
u8 cbc_test_block[0x10];
|
||||||
u64 title_id;
|
u64 title_id;
|
||||||
u64 unknown0;
|
u64 unknown0;
|
||||||
u32 content_size[DSIWEXP_NUM_CONTENT];
|
u32 content_size[TAD_NUM_CONTENT];
|
||||||
u8 unknown1[0x30];
|
u8 unknown1[0x30];
|
||||||
u8 tmd_reserved[0x3E];
|
u8 tmd_reserved[0x3E];
|
||||||
u8 padding[0x0E];
|
u8 padding[0x0E];
|
||||||
} __attribute__((packed)) DsiWareExpHeader;
|
} __attribute__((packed)) TadHeader;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#Footer
|
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#Footer
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 banner_sha256[0x20];
|
u8 banner_sha256[0x20];
|
||||||
u8 header_sha256[0x20];
|
u8 header_sha256[0x20];
|
||||||
u8 content_sha256[DSIWEXP_NUM_CONTENT][0x20];
|
u8 content_sha256[TAD_NUM_CONTENT][0x20];
|
||||||
u8 ecdsa_signature[0x3C];
|
u8 ecdsa_signature[0x3C];
|
||||||
u8 ecdsa_apcert[0x180];
|
u8 ecdsa_apcert[0x180];
|
||||||
u8 ecdsa_ctcert[0x180];
|
u8 ecdsa_ctcert[0x180];
|
||||||
u8 padding[0x4];
|
u8 padding[0x4];
|
||||||
} __attribute__((packed)) DsiWareExpFooter;
|
} __attribute__((packed)) TadFooter;
|
||||||
|
|
||||||
u32 BuildDsiWareExportContentTable(void* table, void* header);
|
u32 BuildTadContentTable(void* table, void* header);
|
@ -1548,7 +1548,7 @@ u32 ShowGameFileTitleInfo(const char* path) {
|
|||||||
if (LoadSmdhFromGameFile(path, smdh) == 0)
|
if (LoadSmdhFromGameFile(path, smdh) == 0)
|
||||||
return ShowSmdhTitleInfo(smdh);
|
return ShowSmdhTitleInfo(smdh);
|
||||||
else if ((LoadTwlMetaData(path, NULL, twl_icon) == 0) ||
|
else if ((LoadTwlMetaData(path, NULL, twl_icon) == 0) ||
|
||||||
((itype & GAME_TAD) && (fvx_qread(path, twl_icon, DSIWEXP_BANNER_OFFSET, sizeof(TwlIconData), NULL) == FR_OK)))
|
((itype & GAME_TAD) && (fvx_qread(path, twl_icon, TAD_BANNER_OFFSET, sizeof(TwlIconData), NULL) == FR_OK)))
|
||||||
return ShowTwlIconTitleInfo(twl_icon);
|
return ShowTwlIconTitleInfo(twl_icon);
|
||||||
else return ShowGbaFileTitleInfo(path);
|
else return ShowGbaFileTitleInfo(path);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "aes.h"
|
#include "aes.h"
|
||||||
|
|
||||||
#define VFLAG_NO_CRYPTO (1UL<<18)
|
#define VFLAG_NO_CRYPTO (1UL<<18)
|
||||||
#define VFLAG_DSIWARE (1UL<<19)
|
#define VFLAG_TAD (1UL<<19)
|
||||||
#define VFLAG_CIA_CONTENT (1UL<<20)
|
#define VFLAG_CIA_CONTENT (1UL<<20)
|
||||||
#define VFLAG_NDS (1UL<<21)
|
#define VFLAG_NDS (1UL<<21)
|
||||||
#define VFLAG_NITRO_DIR (1UL<<22)
|
#define VFLAG_NITRO_DIR (1UL<<22)
|
||||||
@ -17,7 +17,7 @@
|
|||||||
#define VFLAG_NCCH (1UL<<29)
|
#define VFLAG_NCCH (1UL<<29)
|
||||||
#define VFLAG_EXEFS (1UL<<30)
|
#define VFLAG_EXEFS (1UL<<30)
|
||||||
#define VFLAG_ROMFS (1UL<<31)
|
#define VFLAG_ROMFS (1UL<<31)
|
||||||
#define VFLAG_GAMEDIR (VFLAG_FIRM|VFLAG_CIA|VFLAG_NCSD|VFLAG_NCCH|VFLAG_EXEFS|VFLAG_ROMFS|VFLAG_LV3|VFLAG_NDS|VFLAG_NITRO_DIR|VFLAG_NITRO|VFLAG_DSIWARE)
|
#define VFLAG_GAMEDIR (VFLAG_FIRM|VFLAG_CIA|VFLAG_NCSD|VFLAG_NCCH|VFLAG_EXEFS|VFLAG_ROMFS|VFLAG_LV3|VFLAG_NDS|VFLAG_NITRO_DIR|VFLAG_NITRO|VFLAG_TAD)
|
||||||
#define VFLAG_NCCH_CRYPTO (VFLAG_EXEFS_FILE|VFLAG_EXTHDR|VFLAG_EXEFS|VFLAG_ROMFS|VFLAG_LV3|VFLAG_NCCH)
|
#define VFLAG_NCCH_CRYPTO (VFLAG_EXEFS_FILE|VFLAG_EXTHDR|VFLAG_EXEFS|VFLAG_ROMFS|VFLAG_LV3|VFLAG_NCCH)
|
||||||
|
|
||||||
#define NAME_FIRM_HEADER "header.bin"
|
#define NAME_FIRM_HEADER "header.bin"
|
||||||
@ -61,28 +61,28 @@
|
|||||||
#define NAME_NDS_BANNER "banner.bin"
|
#define NAME_NDS_BANNER "banner.bin"
|
||||||
#define NAME_NDS_DATADIR "data"
|
#define NAME_NDS_DATADIR "data"
|
||||||
|
|
||||||
#define NAME_DSIWE_BANNER "banner.bin"
|
#define NAME_TAD_BANNER "banner.bin"
|
||||||
#define NAME_DSIWE_HEADER "header.bin"
|
#define NAME_TAD_HEADER "header.bin"
|
||||||
#define NAME_DSIWE_FOOTER "footer.bin"
|
#define NAME_TAD_FOOTER "footer.bin"
|
||||||
#define NAME_DSIWE_TYPES "tmd", "srl", "02.unk", \
|
#define NAME_TAD_TYPES "tmd", "srl", "02.unk", \
|
||||||
"03.unk", "04.unk", "05.unk", \
|
"03.unk", "04.unk", "05.unk", \
|
||||||
"06.unk", "07.unk", "08.unk", \
|
"06.unk", "07.unk", "08.unk", \
|
||||||
"public.sav", "banner.sav", "11.unk"
|
"public.sav", "banner.sav", "11.unk"
|
||||||
#define NAME_DSIWE_CONTENT "%016llX.%s" // titleid.type
|
#define NAME_TAD_CONTENT "%016llX.%s" // titleid.type
|
||||||
|
|
||||||
|
|
||||||
static u64 vgame_type = 0;
|
static u64 vgame_type = 0;
|
||||||
static u32 base_vdir = 0;
|
static u32 base_vdir = 0;
|
||||||
|
|
||||||
static VirtualFile* templates_cia = (VirtualFile*) VGAME_BUFFER; // first 56kb reserved (enough for 1024 entries)
|
static VirtualFile* templates_cia = (VirtualFile*) VGAME_BUFFER; // first 56kb reserved (enough for 1024 entries)
|
||||||
static VirtualFile* templates_dsiwe = (VirtualFile*) (VGAME_BUFFER + 0xDC00); // 1kb reserved (enough for 18 entries)
|
static VirtualFile* templates_tad = (VirtualFile*) (VGAME_BUFFER + 0xDC00); // 1kb reserved (enough for 18 entries)
|
||||||
static VirtualFile* templates_firm = (VirtualFile*) (VGAME_BUFFER + 0xE000); // 2kb reserved (enough for 36 entries)
|
static VirtualFile* templates_firm = (VirtualFile*) (VGAME_BUFFER + 0xE000); // 2kb reserved (enough for 36 entries)
|
||||||
static VirtualFile* templates_ncsd = (VirtualFile*) (VGAME_BUFFER + 0xE800); // 2kb reserved (enough for 36 entries)
|
static VirtualFile* templates_ncsd = (VirtualFile*) (VGAME_BUFFER + 0xE800); // 2kb reserved (enough for 36 entries)
|
||||||
static VirtualFile* templates_ncch = (VirtualFile*) (VGAME_BUFFER + 0xF000); // 1kb reserved (enough for 18 entries)
|
static VirtualFile* templates_ncch = (VirtualFile*) (VGAME_BUFFER + 0xF000); // 1kb reserved (enough for 18 entries)
|
||||||
static VirtualFile* templates_nds = (VirtualFile*) (VGAME_BUFFER + 0xF400); // 1kb reserved (enough for 18 entries)
|
static VirtualFile* templates_nds = (VirtualFile*) (VGAME_BUFFER + 0xF400); // 1kb reserved (enough for 18 entries)
|
||||||
static VirtualFile* templates_exefs = (VirtualFile*) (VGAME_BUFFER + 0xF800); // 2kb reserved (enough for 36 entries)
|
static VirtualFile* templates_exefs = (VirtualFile*) (VGAME_BUFFER + 0xF800); // 2kb reserved (enough for 36 entries)
|
||||||
static int n_templates_cia = -1;
|
static int n_templates_cia = -1;
|
||||||
static int n_templates_dsiwe = -1;
|
static int n_templates_tad = -1;
|
||||||
static int n_templates_firm = -1;
|
static int n_templates_firm = -1;
|
||||||
static int n_templates_ncsd = -1;
|
static int n_templates_ncsd = -1;
|
||||||
static int n_templates_ncch = -1;
|
static int n_templates_ncch = -1;
|
||||||
@ -101,7 +101,7 @@ static u64 offset_lv3fd = (u64) -1;
|
|||||||
static u64 offset_nds = (u64) -1;
|
static u64 offset_nds = (u64) -1;
|
||||||
static u64 offset_nitro = (u64) -1;
|
static u64 offset_nitro = (u64) -1;
|
||||||
static u64 offset_ccnt = (u64) -1;
|
static u64 offset_ccnt = (u64) -1;
|
||||||
static u64 offset_dsiwe = (u64) -1;
|
static u64 offset_tad = (u64) -1;
|
||||||
static u32 index_ccnt = (u32) -1;
|
static u32 index_ccnt = (u32) -1;
|
||||||
|
|
||||||
static CiaStub* cia = (CiaStub*) (void*) (VGAME_BUFFER + 0x10000); // 61kB reserved - should be enough by far
|
static CiaStub* cia = (CiaStub*) (void*) (VGAME_BUFFER + 0x10000); // 61kB reserved - should be enough by far
|
||||||
@ -661,53 +661,53 @@ bool BuildVGameFirmDir(void) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BuildVGameDsiWareDir(void) {
|
bool BuildVGameTadDir(void) {
|
||||||
const char* name_type[] = { NAME_DSIWE_TYPES };
|
const char* name_type[] = { NAME_TAD_TYPES };
|
||||||
VirtualFile* templates = templates_dsiwe;
|
VirtualFile* templates = templates_tad;
|
||||||
u32 content_offset = 0;
|
u32 content_offset = 0;
|
||||||
u32 n = 0;
|
u32 n = 0;
|
||||||
|
|
||||||
// read header, setup table
|
// read header, setup table
|
||||||
DsiWareExpContentTable tbl;
|
TadContentTable tbl;
|
||||||
DsiWareExpHeader hdr;
|
TadHeader hdr;
|
||||||
ReadGameImageBytes(&hdr, DSIWEXP_HEADER_OFFSET, DSIWEXP_HEADER_LEN);
|
ReadGameImageBytes(&hdr, TAD_HEADER_OFFSET, TAD_HEADER_LEN);
|
||||||
if (BuildDsiWareExportContentTable(&tbl, &hdr) != 0) {
|
if (BuildTadContentTable(&tbl, &hdr) != 0) {
|
||||||
n_templates_dsiwe = 0;
|
n_templates_tad = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// banner
|
// banner
|
||||||
strncpy(templates[n].name, NAME_DSIWE_BANNER, 32);
|
strncpy(templates[n].name, NAME_TAD_BANNER, 32);
|
||||||
templates[n].offset = content_offset;
|
templates[n].offset = content_offset;
|
||||||
templates[n].size = tbl.banner_end - content_offset - sizeof(DsiWareExpBlockMetaData);
|
templates[n].size = tbl.banner_end - content_offset - sizeof(TadBlockMetaData);
|
||||||
templates[n].keyslot = 0xFF;
|
templates[n].keyslot = 0xFF;
|
||||||
templates[n].flags = 0;
|
templates[n].flags = 0;
|
||||||
content_offset = tbl.banner_end;
|
content_offset = tbl.banner_end;
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
// header
|
// header
|
||||||
strncpy(templates[n].name, NAME_DSIWE_HEADER, 32);
|
strncpy(templates[n].name, NAME_TAD_HEADER, 32);
|
||||||
templates[n].offset = content_offset;
|
templates[n].offset = content_offset;
|
||||||
templates[n].size = tbl.header_end - content_offset - sizeof(DsiWareExpBlockMetaData);
|
templates[n].size = tbl.header_end - content_offset - sizeof(TadBlockMetaData);
|
||||||
templates[n].keyslot = 0xFF;
|
templates[n].keyslot = 0xFF;
|
||||||
templates[n].flags = 0;
|
templates[n].flags = 0;
|
||||||
content_offset = tbl.header_end;
|
content_offset = tbl.header_end;
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
// footer
|
// footer
|
||||||
strncpy(templates[n].name, NAME_DSIWE_FOOTER, 32);
|
strncpy(templates[n].name, NAME_TAD_FOOTER, 32);
|
||||||
templates[n].offset = content_offset;
|
templates[n].offset = content_offset;
|
||||||
templates[n].size = tbl.footer_end - content_offset - sizeof(DsiWareExpBlockMetaData);
|
templates[n].size = tbl.footer_end - content_offset - sizeof(TadBlockMetaData);
|
||||||
templates[n].keyslot = 0xFF;
|
templates[n].keyslot = 0xFF;
|
||||||
templates[n].flags = 0;
|
templates[n].flags = 0;
|
||||||
content_offset = tbl.footer_end;
|
content_offset = tbl.footer_end;
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
// contents
|
// contents
|
||||||
for (u32 i = 0; i < DSIWEXP_NUM_CONTENT; content_offset = tbl.content_end[i++]) {
|
for (u32 i = 0; i < TAD_NUM_CONTENT; content_offset = tbl.content_end[i++]) {
|
||||||
if (!hdr.content_size[i]) continue; // nothing in section
|
if (!hdr.content_size[i]) continue; // nothing in section
|
||||||
// use proper names, fix TMD handling
|
// use proper names, fix TMD handling
|
||||||
snprintf(templates[n].name, 32, NAME_DSIWE_CONTENT, hdr.title_id, name_type[i]);
|
snprintf(templates[n].name, 32, NAME_TAD_CONTENT, hdr.title_id, name_type[i]);
|
||||||
templates[n].offset = content_offset;
|
templates[n].offset = content_offset;
|
||||||
templates[n].size = hdr.content_size[i];
|
templates[n].size = hdr.content_size[i];
|
||||||
templates[n].keyslot = 0xFF;
|
templates[n].keyslot = 0xFF;
|
||||||
@ -715,7 +715,7 @@ bool BuildVGameDsiWareDir(void) {
|
|||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
n_templates_dsiwe = n;
|
n_templates_tad = n;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,6 +734,7 @@ u64 InitVGameDrive(void) { // prerequisite: game file mounted as image
|
|||||||
offset_lv3fd = (u64) -1;
|
offset_lv3fd = (u64) -1;
|
||||||
offset_nds = (u64) -1;
|
offset_nds = (u64) -1;
|
||||||
offset_nitro = (u64) -1;
|
offset_nitro = (u64) -1;
|
||||||
|
offset_tad = (u64) -1;
|
||||||
|
|
||||||
base_vdir =
|
base_vdir =
|
||||||
(type & SYS_FIRM ) ? VFLAG_FIRM :
|
(type & SYS_FIRM ) ? VFLAG_FIRM :
|
||||||
@ -743,7 +744,7 @@ u64 InitVGameDrive(void) { // prerequisite: game file mounted as image
|
|||||||
(type & GAME_EXEFS) ? VFLAG_EXEFS :
|
(type & GAME_EXEFS) ? VFLAG_EXEFS :
|
||||||
(type & GAME_ROMFS) ? VFLAG_ROMFS :
|
(type & GAME_ROMFS) ? VFLAG_ROMFS :
|
||||||
(type & GAME_NDS ) ? VFLAG_NDS :
|
(type & GAME_NDS ) ? VFLAG_NDS :
|
||||||
(type & GAME_TAD ) ? VFLAG_DSIWARE : 0;
|
(type & GAME_TAD ) ? VFLAG_TAD : 0;
|
||||||
if (!base_vdir) return 0;
|
if (!base_vdir) return 0;
|
||||||
|
|
||||||
vgame_type = type;
|
vgame_type = type;
|
||||||
@ -790,9 +791,9 @@ bool OpenVGameDir(VirtualDir* vdir, VirtualFile* ventry) {
|
|||||||
((SetupArm9BinaryCrypto(a9l)) == 0))
|
((SetupArm9BinaryCrypto(a9l)) == 0))
|
||||||
offset_a9bin = arm9s->offset + ARM9BIN_OFFSET;
|
offset_a9bin = arm9s->offset + ARM9BIN_OFFSET;
|
||||||
if (!BuildVGameFirmDir()) return false;
|
if (!BuildVGameFirmDir()) return false;
|
||||||
} else if ((vdir->flags & VFLAG_DSIWARE) && (offset_dsiwe != vdir->offset)) {
|
} else if ((vdir->flags & VFLAG_TAD) && (offset_tad != vdir->offset)) {
|
||||||
offset_dsiwe = vdir->offset; // always zero(!)
|
offset_tad = vdir->offset; // always zero(!)
|
||||||
if (!BuildVGameDsiWareDir()) return false;
|
if (!BuildVGameTadDir()) return false;
|
||||||
} else if ((vdir->flags & VFLAG_CIA) && (offset_cia != vdir->offset)) {
|
} else if ((vdir->flags & VFLAG_CIA) && (offset_cia != vdir->offset)) {
|
||||||
CiaInfo info;
|
CiaInfo info;
|
||||||
if ((ReadImageBytes((u8*) cia, 0, 0x20) != 0) ||
|
if ((ReadImageBytes((u8*) cia, 0, 0x20) != 0) ||
|
||||||
@ -1018,9 +1019,9 @@ bool ReadVGameDir(VirtualFile* vfile, VirtualDir* vdir) {
|
|||||||
} else if (vdir->flags & VFLAG_NDS) {
|
} else if (vdir->flags & VFLAG_NDS) {
|
||||||
templates = templates_nds;
|
templates = templates_nds;
|
||||||
n = n_templates_nds;
|
n = n_templates_nds;
|
||||||
} else if (vdir->flags & VFLAG_DSIWARE) {
|
} else if (vdir->flags & VFLAG_TAD) {
|
||||||
templates = templates_dsiwe;
|
templates = templates_tad;
|
||||||
n = n_templates_dsiwe;
|
n = n_templates_tad;
|
||||||
} else if (vdir->flags & VFLAG_LV3) {
|
} else if (vdir->flags & VFLAG_LV3) {
|
||||||
return ReadVGameDirLv3(vfile, vdir);
|
return ReadVGameDirLv3(vfile, vdir);
|
||||||
} else if (vdir->flags & VFLAG_NITRO) {
|
} else if (vdir->flags & VFLAG_NITRO) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user