Trimming functionality for GBA cart dumps

This commit is contained in:
d0k3 2021-02-22 16:41:21 +01:00
parent ee43fe328f
commit 71e3b6f73c
2 changed files with 44 additions and 2 deletions

View File

@ -61,7 +61,7 @@
#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_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))
#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))
#define FTYPE_NCSDFIXABLE(tp) (tp&(HDR_NAND|NOIMG_NAND))
#define FTYPE_HASCODE(tp) (((u64) (tp&(GAME_NCCH|FLAG_CXI)) == (u64) (GAME_NCCH|FLAG_CXI))|(tp&GAME_NCSD))

View File

@ -3048,11 +3048,53 @@ u32 CompressCode(const char* path, const char* path_out) {
return 0;
}
u64 GetAnyFileTrimmedSize(const char* path) {
u64 fsize = 0;
u64 trimsize = 0;
u8 pad_byte = 0x7F;
FIL fp;
UINT br;
if (fvx_open(&fp, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)
return 0;
fsize = fvx_size(&fp);
u32 bufsize = min(STD_BUFFER_SIZE, fsize);
u8* buffer = (u8*) malloc(bufsize);
if (!buffer) return 0;
for (s64 pos = align(fsize, bufsize) - bufsize; (pos >= 0) && !trimsize; pos -= bufsize) {
if ((fvx_lseek(&fp, (UINT) pos) != FR_OK) ||
(fvx_read(&fp, buffer, bufsize, &br) != FR_OK) || !br) break;
if (pad_byte == 0x7F) { // start value
pad_byte = buffer[br-1];
if ((pad_byte != 0x00) && (pad_byte != 0xFF)) break;
}
for (u8* b = buffer + (br-1); b >= buffer; b--) {
if (*b != pad_byte) {
trimsize = pos + (b-buffer) + 1;
break;
}
}
}
fvx_close(&fp);
free(buffer);
// 4 byte forced alignment
// 512 byte trimming minimum
trimsize = align(trimsize, 4);
if ((trimsize > fsize) || (fsize - trimsize < 0x200)) return 0;
return trimsize;
}
u64 GetGameFileTrimmedSize(const char* path) {
u64 filetype = IdentifyFileType(path);
u64 trimsize = 0;
if (filetype & GAME_NDS) {
if (filetype & GAME_GBA) {
trimsize = GetAnyFileTrimmedSize(path);
} else if (filetype & GAME_NDS) {
TwlHeader hdr;
if (fvx_qread(path, &hdr, 0, sizeof(TwlHeader), NULL) != FR_OK)
return 0;