Further improvements to GBA VC save injection

... taking over @TurdPooChargers proposal.
This commit is contained in:
d0k3 2019-11-10 22:40:37 +01:00
parent 23a7ea7fd3
commit 479fed35ef

View File

@ -197,27 +197,31 @@ u32 InjectGbaVcSavegameBuffered(const char* path, const char* path_vcsave, void*
// fix CMAC for NAND partition, rewrite AGBSAVE file // fix CMAC for NAND partition, rewrite AGBSAVE file
u32 data_size = sizeof(AgbSaveHeader) + agbsave->save_size; u32 data_size = sizeof(AgbSaveHeader) + agbsave->save_size;
agbsave->times_saved++; // (for compatibility with dual SD save injection)
if (FixAgbSaveCmac(agbsave, NULL, NULL) != 0) return 1; if (FixAgbSaveCmac(agbsave, NULL, NULL) != 0) return 1;
if (fvx_qwrite(path, agbsave, 0, data_size, NULL) != FR_OK) return 1; // write fail if (fvx_qwrite(path, agbsave, 0, data_size, NULL) != FR_OK) return 1; // write fail
// fix CMAC for SD partition, take it over to SD // fix CMAC for SD partition, take it over to SD
if (strncasecmp(path, "S:/agbsave.bin", 256) == 0) { if (strncasecmp(path, "S:/agbsave.bin", 256) == 0) {
AgbSaveHeader agbsave_sd;
char path_sd[64]; char path_sd[64];
u32 slot; u32 slot = 0;
// get the SD save path, check SD save size // get the SD save path, check SD save size
snprintf(path_sd, 64, "A:/title/%08lx/%08lx/data/00000001.sav", snprintf(path_sd, 64, "A:/title/%08lx/%08lx/data/00000001.sav",
getle32((u8*) &(agbsave->title_id) + 4), getle32((u8*) &(agbsave->title_id))); getle32((u8*) &(agbsave->title_id) + 4), getle32((u8*) &(agbsave->title_id)));
if ((fvx_stat(path_sd, &fno) != FR_OK) || (fno.fsize != max(AGBSAVE_MAX_SIZE, 2 * data_size))) if ((fvx_stat(path_sd, &fno) != FR_OK) || (fno.fsize != max(AGBSAVE_MAX_SIZE, 2 * data_size)))
return 1; // invalid / non-existant SD save return 1; // invalid / non-existant SD save
// inject current slot
slot = (agbsave->times_saved % 2) ? 0 : data_size; // find out which slot to inject to
if ((fvx_qread(path_sd, &agbsave_sd, 0, sizeof(AgbSaveHeader), NULL) == FR_OK) &&
(ValidateAgbSaveHeader(&agbsave_sd) == 0) &&
(agbsave->times_saved == agbsave_sd.times_saved))
slot = data_size; // proper slot is bottom slot (otherwise it's the top slot)
// inject next slot
agbsave->times_saved++; // increase # of times saved
if (FixAgbSaveCmac(agbsave, NULL, path_sd) != 0) return 1; if (FixAgbSaveCmac(agbsave, NULL, path_sd) != 0) return 1;
if (fvx_qwrite(path_sd, agbsave, slot, data_size, NULL) != FR_OK) return 1; // write fail (#0) if (fvx_qwrite(path_sd, agbsave, slot, data_size, NULL) != FR_OK) return 1; // write fail
// inject backup (previous) slot
slot = ((--(agbsave->times_saved)) % 2) ? 0 : data_size;
if (FixAgbSaveCmac(agbsave, NULL, path_sd) != 0) return 1;
if (fvx_qwrite(path_sd, agbsave, slot, data_size, NULL) != FR_OK) return 1; // write fail (#1)
} }
// set CFG_BOOTENV to 0x7 so the save is taken over (not needed anymore) // set CFG_BOOTENV to 0x7 so the save is taken over (not needed anymore)