Skip to content

Commit

Permalink
Trimming functionality for GBA cart dumps
Browse files Browse the repository at this point in the history
  • Loading branch information
d0k3 committed Feb 22, 2021
1 parent ee43fe3 commit 71e3b6f
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
2 changes: 1 addition & 1 deletion arm9/source/filesys/filetype.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
44 changes: 43 additions & 1 deletion arm9/source/utils/gameutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 71e3b6f

Please sign in to comment.