- add loading saves from No$GBA ;)

This commit is contained in:
mtabachenko 2009-07-30 14:47:54 +00:00
parent 66b71553d0
commit 517d31bae9
2 changed files with 175 additions and 2 deletions

View File

@ -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

View File

@ -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);