- add loading saves from No$GBA ;)
This commit is contained in:
parent
66b71553d0
commit
517d31bae9
|
@ -548,6 +548,176 @@ void BackupDevice::load_old_state(u32 addr_size, u8* data, u32 datasize)
|
|||
flush();
|
||||
}
|
||||
|
||||
//======================================================================= no$GBA
|
||||
//=======================================================================
|
||||
//=======================================================================
|
||||
|
||||
s32 unpackSAV(void *in_buf, u32 fsize, void *out_buf)
|
||||
{
|
||||
const char no_GBA_HEADER_ID[] = "NocashGbaBackupMediaSavDataFile";
|
||||
const char no_GBA_HEADER_SRAM_ID[] = "SRAM";
|
||||
u8 *src = (u8 *)in_buf;
|
||||
u8 *dst = (u8 *)out_buf;
|
||||
u32 src_pos = 0;
|
||||
u32 dst_pos = 0;
|
||||
u8 cc = 0;
|
||||
u32 size_unpacked = 0;
|
||||
u32 size_packed = 0;
|
||||
u32 compressMethod = 0;
|
||||
char buf[128] = { 0 };
|
||||
|
||||
if (fsize < 0x50) return (-1);
|
||||
|
||||
for (int i = 0; i < 0x1F; i++)
|
||||
{
|
||||
if (src[i] != no_GBA_HEADER_ID[i]) return (-2);
|
||||
}
|
||||
if (src[0x1F] != 0x1A) return (-3);
|
||||
for (int i = 0; i < 0x4; i++)
|
||||
{
|
||||
if (src[i+0x40] != no_GBA_HEADER_SRAM_ID[i]) return (-2);
|
||||
}
|
||||
|
||||
|
||||
compressMethod = *((u32*)(src+0x44));
|
||||
|
||||
if (compressMethod == 0) // unpacked
|
||||
{
|
||||
size_unpacked = *((u32*)(src+0x4C));
|
||||
src_pos = 0x4C;
|
||||
for (int i = 0; i < size_unpacked; i++)
|
||||
{
|
||||
dst[dst_pos++] = src[src_pos++];
|
||||
}
|
||||
return (dst_pos);
|
||||
}
|
||||
|
||||
if (compressMethod == 1) // packed (method 1)
|
||||
{
|
||||
size_packed = *((u32*)(src+0x48));
|
||||
size_unpacked = *((u32*)(src+0x4C));
|
||||
|
||||
src_pos = 0x50;
|
||||
while (true)
|
||||
{
|
||||
cc = src[src_pos++];
|
||||
|
||||
if (cc == 0) return (dst_pos);
|
||||
|
||||
if (cc == 0x80)
|
||||
{
|
||||
u16 tsize = *((u16*)(src+src_pos+1));
|
||||
for (int t = 0; t < tsize; t++)
|
||||
dst[dst_pos++] = src[src_pos];
|
||||
src_pos += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cc > 0x80) // repeat
|
||||
{
|
||||
cc -= 0x80;
|
||||
for (int t = 0; t < cc; t++)
|
||||
dst[dst_pos++] = src[src_pos];
|
||||
src_pos++;
|
||||
continue;
|
||||
}
|
||||
// copy
|
||||
for (int t = 0; t < cc; t++)
|
||||
dst[dst_pos++] = src[src_pos++];
|
||||
}
|
||||
return (dst_pos);
|
||||
}
|
||||
return (-200);
|
||||
}
|
||||
|
||||
u32 savTrim(void *buf, u32 size)
|
||||
{
|
||||
u32 rows = size / 16;
|
||||
u32 pos = (size - 16);
|
||||
u8 *src = (u8*)buf;
|
||||
|
||||
for (unsigned int i = 0; i < rows; i++, pos -= 16)
|
||||
{
|
||||
if (src[pos] == 0xFF)
|
||||
{
|
||||
for (int t = 0; t < 16; t++)
|
||||
{
|
||||
if (src[pos+t] != 0xFF) return (pos+16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return (pos+16);
|
||||
}
|
||||
}
|
||||
return (size);
|
||||
}
|
||||
|
||||
u32 fillLeft(u32 size)
|
||||
{
|
||||
for (int i = 1; i < ARRAY_SIZE(save_types); i++)
|
||||
{
|
||||
if (size < save_types[i][1])
|
||||
return (size + (save_types[i][1] - size));
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool BackupDevice::load_no_gba(const char *fname)
|
||||
{
|
||||
FILE *fsrc = fopen(fname, "rb");
|
||||
u8 *in_buf = NULL;
|
||||
u8 *out_buf = NULL;
|
||||
|
||||
if (fsrc)
|
||||
{
|
||||
u32 fsize = 0;
|
||||
fseek(fsrc, 0, SEEK_END);
|
||||
fsize = ftell(fsrc);
|
||||
fseek(fsrc, 0, SEEK_SET);
|
||||
//printf("Open %s file (size %i bytes)\n", fname, fsize);
|
||||
|
||||
in_buf = new u8 [fsize];
|
||||
|
||||
if (fread(in_buf, 1, fsize, fsrc) == fsize)
|
||||
{
|
||||
out_buf = new u8 [8 * 1024 * 1024 / 8];
|
||||
for (int jj = 0; jj < 8 * 1024 * 1024 / 8; jj++)
|
||||
{
|
||||
out_buf[jj] = 0xFF;
|
||||
}
|
||||
|
||||
s32 size = unpackSAV(in_buf, fsize, out_buf);
|
||||
if (size > 0)
|
||||
{
|
||||
//printf("New size %i byte(s)\n", size);
|
||||
size = savTrim(out_buf, size);
|
||||
//printf("--- new size after trim %i byte(s)\n", size);
|
||||
size = fillLeft(size);
|
||||
//printf("--- new size after fill %i byte(s)\n", size);
|
||||
data.resize(size);
|
||||
for (int tt = 0; tt < size; tt++)
|
||||
data[tt] = out_buf[tt];
|
||||
|
||||
//dump back out as a dsv, just to keep things sane
|
||||
flush();
|
||||
printf("Loaded no$GBA save\n");
|
||||
|
||||
if (in_buf) delete [] in_buf;
|
||||
if (out_buf) delete [] out_buf;
|
||||
return true;
|
||||
}
|
||||
if (out_buf) delete [] out_buf;
|
||||
}
|
||||
if (in_buf) delete [] in_buf;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
//======================================================================= end
|
||||
//=======================================================================
|
||||
//======================================================================= no$GBA
|
||||
|
||||
|
||||
void BackupDevice::loadfile()
|
||||
{
|
||||
|
@ -575,7 +745,8 @@ void BackupDevice::loadfile()
|
|||
}
|
||||
fclose(inf);
|
||||
|
||||
load_raw(tmp);
|
||||
if (!load_no_gba(tmp))
|
||||
load_raw(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -591,7 +762,8 @@ void BackupDevice::loadfile()
|
|||
//maybe it is a misnamed raw save file. try loading it that way
|
||||
printf("Not a DeSmuME .dsv save file. Trying to load as raw.\n");
|
||||
fclose(inf);
|
||||
load_raw(filename.c_str());
|
||||
if (!load_no_gba(filename.c_str()))
|
||||
load_raw(filename.c_str());
|
||||
return;
|
||||
}
|
||||
//desmume format
|
||||
|
|
|
@ -98,6 +98,7 @@ public:
|
|||
void raw_applyUserSettings(u32& size);
|
||||
|
||||
bool load_duc(const char* filename);
|
||||
bool load_no_gba(const char *fname);
|
||||
bool load_raw(const char* filename);
|
||||
bool save_raw(const char* filename);
|
||||
bool load_movie(std::istream* is);
|
||||
|
|
Loading…
Reference in New Issue