-updated gamecube game installer,

images now got the same md5 as the one
compressed with discex, compresion
without force 32k align works fine too now
This commit is contained in:
fix94.1 2012-02-26 15:03:54 +00:00
parent 714047d220
commit fa7da0a437
3 changed files with 67 additions and 64 deletions

View File

@ -122,25 +122,11 @@ s32 GCDump::__DiscWrite(char * path, u32 offset, u32 length, progress_callback_t
return wrote; return wrote;
} }
s32 GCDump::__DiscWriteAligned(char * path, u32 offset, u32 length, int *alignment) s32 GCDump::__DiscWriteAligned(FILE *f, u32 offset, u32 length)
{ {
u8 *ReadBuffer = (u8 *)MEM2_alloc(gc_readsize+4); u8 *ReadBuffer = (u8 *)MEM2_alloc(gc_readsize+4);
u32 toread = 0; u32 toread = 0;
u32 wrote = 0; u32 wrote = 0;
*alignment = 32768;
FILE *f = fopen(path, "ab");
unsigned int align = 0x8000;
for(align = 0x8000; align > 2; align/=2)
{
if((offset & (align-1)) == 0)
{
break;
}
}
*alignment = (int)align;
while(length) while(length)
{ {
@ -153,23 +139,12 @@ s32 GCDump::__DiscWriteAligned(char * path, u32 offset, u32 length, int *alignme
memset(ReadBuffer, 0, gc_readsize); memset(ReadBuffer, 0, gc_readsize);
else if (ret > 1) else if (ret > 1)
return 0; return 0;
if (aligned) fwrite(ReadBuffer, 1, toread, f);
{ wrote += toread;
fwrite(ReadBuffer, 1, (toread+32767)&(~32767), f); offset += toread;
wrote += (toread+32767)&(~32767); length -= toread;
offset += toread;
length -= toread;
}
else
{
fwrite(ReadBuffer, 1, ((toread+(align-1))&(~(align-1))), f);
wrote += ((toread+(align-1))&(~(align-1)));
offset += toread;
length -= toread;
}
} }
SAFE_CLOSE(f);
MEM2_free(ReadBuffer); MEM2_free(ReadBuffer);
return wrote; return wrote;
} }
@ -177,7 +152,7 @@ s32 GCDump::__DiscWriteAligned(char * path, u32 offset, u32 length, int *alignme
s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data) s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
{ {
static gc_discHdr gcheader ATTRIBUTE_ALIGN(32); static gc_discHdr gcheader ATTRIBUTE_ALIGN(32);
u8 *ReadBuffer = (u8 *)MEM2_alloc(0x40); u8 *ReadBuffer = (u8 *)MEM2_alloc(0x40);
u8 *FSTBuffer; u8 *FSTBuffer;
u32 wrote = 0; u32 wrote = 0;
@ -191,63 +166,65 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
u32 GamePartOffset = 0; u32 GamePartOffset = 0;
u32 DataSize = 0; u32 DataSize = 0;
char *FSTNameOff = (char *)NULL; char *FSTNameOff = (char *)NULL;
char folder[MAX_FAT_PATH]; char folder[MAX_FAT_PATH];
bzero(folder, MAX_FAT_PATH); bzero(folder, MAX_FAT_PATH);
char gamepath[MAX_FAT_PATH]; char gamepath[MAX_FAT_PATH];
bzero(gamepath, MAX_FAT_PATH); bzero(gamepath, MAX_FAT_PATH);
s32 ret = Disc_ReadGCHeader(&gcheader); s32 ret = Disc_ReadGCHeader(&gcheader);
Asciify2(gcheader.title); Asciify2(gcheader.title);
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]", DeviceName[SD], gcheader.title, (char *)gcheader.id); snprintf(folder, sizeof(folder), "%s:/games/%s [%s]", DeviceName[SD], gcheader.title, (char *)gcheader.id);
makedir((char *)folder); makedir((char *)folder);
if(writeexfiles) if(writeexfiles)
{ {
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]/sys", DeviceName[SD], gcheader.title, (char *)gcheader.id); snprintf(folder, sizeof(folder), "%s:/games/%s [%s]/sys", DeviceName[SD], gcheader.title, (char *)gcheader.id);
makedir((char *)folder); makedir((char *)folder);
} }
ret = __DiscReadRaw(ReadBuffer, 0x400, 0x40); ret = __DiscReadRaw(ReadBuffer, 0x400, 0x40);
if(ret > 0) if(ret > 0)
return 0x31100; return 0x31100;
ApploaderSize = *(vu32*)(ReadBuffer); ApploaderSize = *(vu32*)(ReadBuffer);
DOLOffset = *(vu32*)(ReadBuffer+0x20); DOLOffset = *(vu32*)(ReadBuffer+0x20);
FSTOffset = *(vu32*)(ReadBuffer+0x24); FSTOffset = *(vu32*)(ReadBuffer+0x24);
FSTSize = *(vu32*)(ReadBuffer+0x28); FSTSize = *(vu32*)(ReadBuffer+0x28);
GamePartOffset = *(vu32*)(ReadBuffer+0x34); GamePartOffset = *(vu32*)(ReadBuffer+0x34);
DataSize = *(vu32*)(ReadBuffer+0x38); DataSize = *(vu32*)(ReadBuffer+0x38);
MEM2_free(ReadBuffer); MEM2_free(ReadBuffer);
DOLSize = FSTOffset - DOLOffset; DOLSize = FSTOffset - DOLOffset;
DiscSize = DataSize + GamePartOffset; DiscSize = DataSize + GamePartOffset;
FSTBuffer = (u8 *)MEM2_alloc((FSTSize+31)&(~31)); FSTBuffer = (u8 *)MEM2_alloc((FSTSize+31)&(~31));
ret = __DiscReadRaw(FSTBuffer, FSTOffset, (FSTSize+31)&(~31)); ret = __DiscReadRaw(FSTBuffer, FSTOffset, (FSTSize+31)&(~31));
if(ret > 0) if(ret > 0)
return 0x31100; return 0x31100;
FSTable = (u8*)FSTBuffer; FSTable = (u8*)FSTBuffer;
FSTEnt = *(u32*)(FSTable+0x08); FSTEnt = *(u32*)(FSTable+0x08);
FSTNameOff = (char*)(FSTable + FSTEnt * 0x0C); FSTNameOff = (char*)(FSTable + FSTEnt * 0x0C);
FST *fst = (FST *)(FSTable); FST *fst = (FST *)(FSTable);
gprintf("Dumping: %s %s\n", gcheader.title, compressed ? "compressed" : "full"); gprintf("Dumping: %s %s\n", gcheader.title, compressed ? "compressed" : "full");
gprintf("Apploader size : %d\n", ApploaderSize); gprintf("Apploader size : %d\n", ApploaderSize);
gprintf("DOL offset : 0x%08x\n", DOLOffset); gprintf("DOL offset : 0x%08x\n", DOLOffset);
gprintf("DOL size : %d\n", DOLSize); gprintf("DOL size : %d\n", DOLSize);
gprintf("FST offset : 0x%08x\n", FSTOffset); gprintf("FST offset : 0x%08x\n", FSTOffset);
gprintf("FST size : %d\n", FSTSize); gprintf("FST size : %d\n", FSTSize);
gprintf("Num FST entries: %d\n", FSTEnt); gprintf("Num FST entries: %d\n", FSTEnt);
gprintf("Data Offset : 0x%08x\n", FSTOffset+FSTSize);
gprintf("Disc size : %d\n", DiscSize); gprintf("Disc size : %d\n", DiscSize);
if(writeexfiles) if(writeexfiles)
{ {
gprintf("Writing %s/boot.bin\n", folder); gprintf("Writing %s/boot.bin\n", folder);
@ -262,19 +239,23 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
snprintf(gamepath, sizeof(gamepath), "%s/apploader.img", folder); snprintf(gamepath, sizeof(gamepath), "%s/apploader.img", folder);
__DiscWrite(gamepath, 0x2440, ApploaderSize, spinner, spinner_data); __DiscWrite(gamepath, 0x2440, ApploaderSize, spinner, spinner_data);
} }
snprintf(gamepath, sizeof(gamepath), "%s:/games/%s [%s]/game.iso", DeviceName[SD], gcheader.title, (char *)gcheader.id); snprintf(gamepath, sizeof(gamepath), "%s:/games/%s [%s]/game.iso", DeviceName[SD], gcheader.title, (char *)gcheader.id);
gprintf("Writing %s\n", gamepath); gprintf("Writing %s\n", gamepath);
if(compressed) if(compressed)
{ {
int alignment; u32 align;
u32 correction;
FILE *f;
f = fopen(gamepath, "ab");
ret = __DiscWriteAligned(gamepath, 0, GamePartOffset, &alignment); ret = __DiscWriteAligned(f, 0, (FSTOffset + FSTSize));
wrote += ret; wrote += (FSTOffset + FSTSize);
u32 i; u32 i;
for( i=1; i < FSTEnt; ++i ) for( i=1; i < FSTEnt; ++i )
{ {
if( fst[i].Type ) if( fst[i].Type )
@ -282,9 +263,29 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
continue; continue;
} }
else else
{ {
ret = __DiscWriteAligned(gamepath, fst[i].FileOffset, fst[i].FileLength, &alignment); correction = 0x00;
gprintf("Writing: %d/%d: %s from 0x%08x to 0x%08x(%i)\n", i, FSTEnt, FSTNameOff + fst[i].NameOffset, fst[i].FileOffset, wrote, alignment); for(align = 0x8000; align > 2; align/=2)
{
if((fst[i].FileOffset & (align-1)) == 0 || force_32k_align)
{
break;
}
}
while(((wrote+correction) & (align-1)) != 0)
correction++;
if(correction>0x00)
{
u32 j;
for(j=0x00;j<correction;j++)
fwrite("", 1, 1, f);
wrote += correction;
}
ret = __DiscWriteAligned(f, fst[i].FileOffset, fst[i].FileLength);
gprintf("Writing: %d/%d: %s from 0x%08x to 0x%08x(%i)\n", i, FSTEnt, FSTNameOff + fst[i].NameOffset, fst[i].FileOffset, wrote, align);
if( ret >= 0 ) if( ret >= 0 )
{ {
fst[i].FileOffset = wrote; fst[i].FileOffset = wrote;
@ -295,18 +296,20 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
{ {
spinner(FSTEnt, FSTEnt, spinner_data); spinner(FSTEnt, FSTEnt, spinner_data);
MEM2_free(FSTBuffer); MEM2_free(FSTBuffer);
SAFE_CLOSE(f);
return gc_error; return gc_error;
} }
} }
} }
SAFE_CLOSE(f);
gprintf("Updating FST\n"); gprintf("Updating FST\n");
f = fopen(gamepath, "r+");
FILE *f = fopen(gamepath, "r+");
fseek(f, FSTOffset, SEEK_SET); fseek(f, FSTOffset, SEEK_SET);
fwrite(fst, 1, FSTSize, f); fwrite(fst, 1, FSTSize, f);
SAFE_CLOSE(f); SAFE_CLOSE(f);
gprintf("Done!! Disc old size: %d, disc new size: %d, saved: %d\n", DiscSize, wrote, DiscSize - wrote); gprintf("Done!! Disc old size: %d, disc new size: %d, saved: %d\n", DiscSize, wrote, DiscSize - wrote);
} }
else else
@ -321,7 +324,7 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
} }
MEM2_free(FSTBuffer); MEM2_free(FSTBuffer);
return gc_skipped; return gc_skipped;
} }

View File

@ -38,7 +38,7 @@ public:
skiponerror = skip; skiponerror = skip;
compressed = comp; compressed = comp;
writeexfiles = wexf; writeexfiles = wexf;
aligned = align; force_32k_align = align;
gc_nbrretry = nretry; gc_nbrretry = nretry;
gc_readsize = rsize; gc_readsize = rsize;
gc_skipped = 0; gc_skipped = 0;
@ -46,7 +46,7 @@ public:
s32 DumpGame(progress_callback_t spinner, void *spinner_data); s32 DumpGame(progress_callback_t spinner, void *spinner_data);
s32 CheckSpace(u32 *needed, bool comp); s32 CheckSpace(u32 *needed, bool comp);
private: private:
bool aligned; bool force_32k_align;
bool skiponerror; bool skiponerror;
bool compressed; bool compressed;
bool writeexfiles; bool writeexfiles;
@ -84,6 +84,6 @@ private:
} FST; } FST;
s32 __DiscReadRaw(void *outbuf, u32 offset, u32 length); s32 __DiscReadRaw(void *outbuf, u32 offset, u32 length);
s32 __DiscWrite(char * path, u32 offset, u32 length, progress_callback_t spinner , void *spinner_data); s32 __DiscWrite(char * path, u32 offset, u32 length, progress_callback_t spinner , void *spinner_data);
s32 __DiscWriteAligned(char * path, u32 offset, u32 length, int *alignment); s32 __DiscWriteAligned(FILE *f, u32 offset, u32 length);
}; };
#endif #endif

View File

@ -115,7 +115,7 @@ int CMenu::_GCgameInstaller(void *obj)
bool skip = m.m_cfg.getBool("DML", "skip_on_error", false); bool skip = m.m_cfg.getBool("DML", "skip_on_error", false);
bool comp = m.m_cfg.getBool("DML", "compressed_dump", false); bool comp = m.m_cfg.getBool("DML", "compressed_dump", false);
bool wexf = m.m_cfg.getBool("DML", "write_ex_files", false); bool wexf = m.m_cfg.getBool("DML", "write_ex_files", false);
bool alig = m.m_cfg.getBool("DML", "align_files", true); bool alig = m.m_cfg.getBool("DML", "force_32k_align_files", false);
u32 nretry = m.m_cfg.getUInt("DML", "num_retries", 5); u32 nretry = m.m_cfg.getUInt("DML", "num_retries", 5);
u32 rsize = 32768; u32 rsize = 32768;