mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-30 15:14:18 +01:00
Again some dumper changes:
* It's now possible to dump games that come with 2 discs * Added messenger callback to interact with the thread message Todo: * Cleanup the code
This commit is contained in:
parent
fa1852bfa9
commit
c8ca36600d
@ -26,6 +26,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <ogcsys.h>
|
#include <ogcsys.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
@ -138,246 +139,564 @@ s32 GCDump::__DiscWriteAligned(FILE *f, u32 offset, u32 length, u8 *ReadBuffer)
|
|||||||
return wrote;
|
return wrote;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
|
s32 GCDump::DumpGame(progress_callback_t spinner, message_callback_t message, 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(gc_readsize);
|
||||||
u8 *FSTBuffer;
|
|
||||||
u32 wrote = 0;
|
|
||||||
|
|
||||||
u32 ApploaderSize = 0;
|
u32 j;
|
||||||
u32 DOLOffset = 0;
|
|
||||||
u32 DOLSize = 0;
|
|
||||||
u32 FSTOffset = 0;
|
|
||||||
u32 FSTSize = 0;
|
|
||||||
u32 FSTEnt = 0;
|
|
||||||
u32 GamePartOffset = 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);
|
||||||
|
char minfo[74];
|
||||||
s32 ret = Disc_ReadGCHeader(&gcheader);
|
|
||||||
Asciify2(gcheader.title);
|
for( j=0; j<2; ++j)
|
||||||
|
|
||||||
snprintf(folder, sizeof(folder), "%s:/games/", gamepartition);
|
|
||||||
if(!fsop_DirExist(folder))
|
|
||||||
fsop_MakeFolder(folder);
|
|
||||||
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]", gamepartition, gcheader.title, (char *)gcheader.id);
|
|
||||||
if(!fsop_DirExist(folder))
|
|
||||||
fsop_MakeFolder(folder);
|
|
||||||
|
|
||||||
ret = __DiscReadRaw(ReadBuffer, 0x400, 0x40);
|
|
||||||
if(ret > 0)
|
|
||||||
{
|
{
|
||||||
MEM2_free(ReadBuffer);
|
bool done = false;
|
||||||
return 0x31100;
|
u8 *FSTBuffer;
|
||||||
}
|
u32 wrote = 0;
|
||||||
|
|
||||||
ApploaderSize = *(vu32*)(ReadBuffer);
|
s32 ret = Disc_ReadGCHeader(&gcheader);
|
||||||
DOLOffset = *(vu32*)(ReadBuffer+0x20);
|
Asciify2(gcheader.title);
|
||||||
FSTOffset = *(vu32*)(ReadBuffer+0x24);
|
|
||||||
FSTSize = *(vu32*)(ReadBuffer+0x28);
|
|
||||||
GamePartOffset = *(vu32*)(ReadBuffer+0x34);
|
|
||||||
DataSize = *(vu32*)(ReadBuffer+0x38);
|
|
||||||
|
|
||||||
DOLSize = FSTOffset - DOLOffset;
|
snprintf(folder, sizeof(folder), "%s:/games/", gamepartition);
|
||||||
DiscSize = DataSize + GamePartOffset;
|
if(!fsop_DirExist(folder))
|
||||||
|
fsop_MakeFolder(folder);
|
||||||
FSTBuffer = (u8 *)MEM2_alloc((FSTSize+31)&(~31));
|
snprintf(folder, sizeof(folder), "%s:/games/%s [%.06s]%s", gamepartition, gcheader.title, (char *)gcheader.id, j ? "2" : "");
|
||||||
|
|
||||||
ret = __DiscReadRaw(FSTBuffer, FSTOffset, (FSTSize+31)&(~31));
|
|
||||||
|
|
||||||
if(ret > 0)
|
|
||||||
{
|
|
||||||
MEM2_free(FSTBuffer);
|
|
||||||
MEM2_free(ReadBuffer);
|
|
||||||
return 0x31100;
|
|
||||||
}
|
|
||||||
|
|
||||||
FSTable = (u8*)FSTBuffer;
|
|
||||||
MEM2_free(ReadBuffer);
|
|
||||||
|
|
||||||
ReadBuffer = (u8 *)MEM2_alloc(gc_readsize);
|
|
||||||
|
|
||||||
FSTEnt = *(u32*)(FSTable+0x08);
|
|
||||||
|
|
||||||
FSTNameOff = (char*)(FSTable + FSTEnt * 0x0C);
|
|
||||||
FST *fst = (FST *)(FSTable);
|
|
||||||
|
|
||||||
gprintf("Dumping: %s %s\n", gcheader.title, compressed ? "compressed" : "full");
|
|
||||||
|
|
||||||
gprintf("Apploader size : %d\n", ApploaderSize);
|
|
||||||
gprintf("DOL offset : 0x%08x\n", DOLOffset);
|
|
||||||
gprintf("DOL size : %d\n", DOLSize);
|
|
||||||
gprintf("FST offset : 0x%08x\n", FSTOffset);
|
|
||||||
gprintf("FST size : %d\n", FSTSize);
|
|
||||||
gprintf("Num FST entries: %d\n", FSTEnt);
|
|
||||||
gprintf("Data Offset : 0x%08x\n", FSTOffset+FSTSize);
|
|
||||||
gprintf("Disc size : %d\n", DiscSize);
|
|
||||||
|
|
||||||
if(writeexfiles)
|
|
||||||
{
|
|
||||||
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]/sys", gamepartition, gcheader.title, (char *)gcheader.id);
|
|
||||||
if(!fsop_DirExist(folder))
|
if(!fsop_DirExist(folder))
|
||||||
fsop_MakeFolder(folder);
|
fsop_MakeFolder(folder);
|
||||||
|
|
||||||
gprintf("Writing %s/boot.bin\n", folder);
|
ret = __DiscReadRaw(ReadBuffer, 0, 0x440);
|
||||||
snprintf(gamepath, sizeof(gamepath), "%s/boot.bin", folder);
|
if(ret > 0)
|
||||||
__DiscWrite(gamepath, 0, 0x440, ReadBuffer, spinner, spinner_data);
|
|
||||||
|
|
||||||
gprintf("Writing %s/bi2.bin\n", folder);
|
|
||||||
snprintf(gamepath, sizeof(gamepath), "%s/bi2.bin", folder);
|
|
||||||
__DiscWrite(gamepath, 0x440, 0x2000, ReadBuffer, spinner, spinner_data);
|
|
||||||
|
|
||||||
gprintf("Writing %s/apploader.img\n", folder);
|
|
||||||
snprintf(gamepath, sizeof(gamepath), "%s/apploader.img", folder);
|
|
||||||
__DiscWrite(gamepath, 0x2440, ApploaderSize, ReadBuffer, spinner, spinner_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(gamepath, sizeof(gamepath), "%s:/games/%s [%s]/game.iso", gamepartition, gcheader.title, (char *)gcheader.id);
|
|
||||||
|
|
||||||
gprintf("Writing %s\n", gamepath);
|
|
||||||
if(compressed)
|
|
||||||
{
|
|
||||||
u32 align;
|
|
||||||
u32 correction;
|
|
||||||
|
|
||||||
FILE *f;
|
|
||||||
f = fopen(gamepath, "wb");
|
|
||||||
|
|
||||||
ret = __DiscWriteAligned(f, 0, (FSTOffset + FSTSize), ReadBuffer);
|
|
||||||
wrote += (FSTOffset + FSTSize);
|
|
||||||
|
|
||||||
u32 i;
|
|
||||||
|
|
||||||
for( i=1; i < FSTEnt; ++i )
|
|
||||||
{
|
{
|
||||||
if( fst[i].Type )
|
MEM2_free(ReadBuffer);
|
||||||
|
return 0x31100;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID = *(vu32*)(ReadBuffer);
|
||||||
|
ApploaderSize = *(vu32*)(ReadBuffer+0x400);
|
||||||
|
DOLOffset = *(vu32*)(ReadBuffer+0x420);
|
||||||
|
FSTOffset = *(vu32*)(ReadBuffer+0x424);
|
||||||
|
FSTSize = *(vu32*)(ReadBuffer+0x428);
|
||||||
|
FSTTotal = *(vu32*)(ReadBuffer+0x42c);
|
||||||
|
GamePartOffset = *(vu32*)(ReadBuffer+0x434);
|
||||||
|
DataSize = *(vu32*)(ReadBuffer+0x438);
|
||||||
|
|
||||||
|
DOLSize = FSTOffset - DOLOffset;
|
||||||
|
DiscSize = DataSize + GamePartOffset;
|
||||||
|
|
||||||
|
FSTBuffer = (u8 *)MEM2_alloc((FSTSize+31)&(~31));
|
||||||
|
|
||||||
|
ret = __DiscReadRaw(FSTBuffer, FSTOffset, (FSTSize+31)&(~31));
|
||||||
|
|
||||||
|
if(ret > 0)
|
||||||
|
{
|
||||||
|
MEM2_free(FSTBuffer);
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
|
return 0x31100;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSTable = (u8*)FSTBuffer;
|
||||||
|
|
||||||
|
FSTEnt = *(u32*)(FSTable+0x08);
|
||||||
|
|
||||||
|
FSTNameOff = (char*)(FSTable + FSTEnt * 0x0C);
|
||||||
|
FST *fst = (FST *)(FSTable);
|
||||||
|
|
||||||
|
snprintf(minfo, sizeof(minfo), "[%.06s] %s", (char *)gcheader.id, gcheader.title);
|
||||||
|
|
||||||
|
if(FSTTotal > FSTSize)
|
||||||
|
message( 4, j+1, minfo, spinner_data);
|
||||||
|
else
|
||||||
|
message( 3, 0, minfo, spinner_data);
|
||||||
|
|
||||||
|
gprintf("Dumping: %s %s\n", gcheader.title, compressed ? "compressed" : "full");
|
||||||
|
|
||||||
|
gprintf("Apploader size : %d\n", ApploaderSize);
|
||||||
|
gprintf("DOL offset : 0x%08x\n", DOLOffset);
|
||||||
|
gprintf("DOL size : %d\n", DOLSize);
|
||||||
|
gprintf("FST offset : 0x%08x\n", FSTOffset);
|
||||||
|
gprintf("FST size : %d\n", FSTSize);
|
||||||
|
gprintf("Num FST entries: %d\n", FSTEnt);
|
||||||
|
gprintf("Data Offset : 0x%08x\n", FSTOffset+FSTSize);
|
||||||
|
gprintf("Disc size : %d\n", DiscSize);
|
||||||
|
|
||||||
|
if(writeexfiles)
|
||||||
|
{
|
||||||
|
snprintf(folder, sizeof(folder), "%s:/games/%s [%.06s]%s/sys", gamepartition, gcheader.title, (char *)gcheader.id, j ? "2" : "");
|
||||||
|
if(!fsop_DirExist(folder))
|
||||||
|
fsop_MakeFolder(folder);
|
||||||
|
|
||||||
|
gprintf("Writing %s/boot.bin\n", folder);
|
||||||
|
snprintf(gamepath, sizeof(gamepath), "%s/boot.bin", folder);
|
||||||
|
__DiscWrite(gamepath, 0, 0x440, ReadBuffer, spinner, spinner_data);
|
||||||
|
|
||||||
|
gprintf("Writing %s/bi2.bin\n", folder);
|
||||||
|
snprintf(gamepath, sizeof(gamepath), "%s/bi2.bin", folder);
|
||||||
|
__DiscWrite(gamepath, 0x440, 0x2000, ReadBuffer, spinner, spinner_data);
|
||||||
|
|
||||||
|
gprintf("Writing %s/apploader.img\n", folder);
|
||||||
|
snprintf(gamepath, sizeof(gamepath), "%s/apploader.img", folder);
|
||||||
|
__DiscWrite(gamepath, 0x2440, ApploaderSize, ReadBuffer, spinner, spinner_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(gamepath, sizeof(gamepath), "%s:/games/%s [%.06s]%s/game.iso", gamepartition, gcheader.title, (char *)gcheader.id, j ? "2" : "");
|
||||||
|
|
||||||
|
gprintf("Writing %s\n", gamepath);
|
||||||
|
if(compressed)
|
||||||
|
{
|
||||||
|
u32 align;
|
||||||
|
u32 correction;
|
||||||
|
|
||||||
|
FILE *f;
|
||||||
|
f = fopen(gamepath, "wb");
|
||||||
|
|
||||||
|
ret = __DiscWriteAligned(f, 0, (FSTOffset + FSTSize), ReadBuffer);
|
||||||
|
wrote += (FSTOffset + FSTSize);
|
||||||
|
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
for( i=1; i < FSTEnt; ++i )
|
||||||
{
|
{
|
||||||
continue;
|
if( fst[i].Type )
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(align = 0x8000; align > 2; align/=2)
|
|
||||||
{
|
{
|
||||||
if((fst[i].FileOffset & (align-1)) == 0 || force_32k_align)
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(align = 0x8000; align > 2; align/=2)
|
||||||
{
|
{
|
||||||
correction = 0x00;
|
if((fst[i].FileOffset & (align-1)) == 0 || force_32k_align)
|
||||||
while(((wrote+correction) & (align-1)) != 0)
|
{
|
||||||
correction++;
|
correction = 0x00;
|
||||||
wrote += correction;
|
while(((wrote+correction) & (align-1)) != 0)
|
||||||
fseek(f,correction,SEEK_END);
|
correction++;
|
||||||
|
wrote += correction;
|
||||||
|
fseek(f,correction,SEEK_END);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = __DiscWriteAligned(f, fst[i].FileOffset, fst[i].FileLength, ReadBuffer);
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
fst[i].FileOffset = wrote;
|
||||||
|
wrote += ret;
|
||||||
|
spinner(i, FSTEnt, spinner_data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spinner(FSTEnt, FSTEnt, spinner_data);
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
|
MEM2_free(FSTBuffer);
|
||||||
|
SAFE_CLOSE(f);
|
||||||
|
return gc_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gprintf("Updating FST\n");
|
||||||
|
fseek(f, FSTOffset, SEEK_SET);
|
||||||
|
fwrite(fst, 1, FSTSize, f);
|
||||||
|
SAFE_CLOSE(f);
|
||||||
|
|
||||||
|
gprintf("Done!! Disc old size: %d, disc new size: %d, saved: %d\n", DiscSize, wrote, DiscSize - wrote);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = __DiscWrite(gamepath, 0, DiscSize, ReadBuffer, spinner, spinner_data);
|
||||||
|
if( ret < 0 )
|
||||||
|
{
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
|
MEM2_free(FSTBuffer);
|
||||||
|
return gc_error;
|
||||||
|
}
|
||||||
|
gprintf("Done!! Disc size: %d\n", DiscSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM2_free(FSTBuffer);
|
||||||
|
|
||||||
|
if(FSTTotal > FSTSize && !j)
|
||||||
|
{
|
||||||
|
*(u32*)0xCD0000C0 |= 0x20;
|
||||||
|
u32 cover = 0;
|
||||||
|
message( 9, 0, minfo, spinner_data);
|
||||||
|
|
||||||
|
while(!done)
|
||||||
|
{
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
WDVD_GetCoverStatus(&cover);
|
||||||
|
if(!(cover & 0x2))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(Disc_Wait() < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(Disc_Open() < 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if(Disc_IsGC() == 0)
|
||||||
|
{
|
||||||
|
s32 ret = __DiscReadRaw(ReadBuffer, 0, 0x440);
|
||||||
|
if(ret > 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ID2 = *(vu32*)(ReadBuffer);
|
||||||
|
Disc = *(vu8*)(ReadBuffer+0x06);
|
||||||
|
|
||||||
|
if(ID == ID2 && Disc == 0x01)
|
||||||
|
{
|
||||||
|
done = true;
|
||||||
|
*(u32*)0xCD0000C0 &= ~0x20;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(ID == ID2 && Disc == 0x00)
|
||||||
|
{
|
||||||
|
message( 7, 1, NULL, spinner_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(ID != ID2)
|
||||||
|
{
|
||||||
|
message( 8, 0, NULL, spinner_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(Disc_IsWii() == 0)
|
||||||
|
{
|
||||||
|
message( 5, 0, NULL, spinner_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message( 6, 0, NULL, spinner_data);
|
||||||
|
usleep( 5000000 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = __DiscWriteAligned(f, fst[i].FileOffset, fst[i].FileLength, ReadBuffer);
|
|
||||||
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 )
|
|
||||||
{
|
|
||||||
fst[i].FileOffset = wrote;
|
|
||||||
wrote += ret;
|
|
||||||
spinner(i, FSTEnt, spinner_data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spinner(FSTEnt, FSTEnt, spinner_data);
|
|
||||||
MEM2_free(ReadBuffer);
|
|
||||||
SAFE_CLOSE(f);
|
|
||||||
return gc_error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
gprintf("Updating FST\n");
|
|
||||||
fseek(f, FSTOffset, SEEK_SET);
|
|
||||||
fwrite(fst, 1, FSTSize, f);
|
|
||||||
SAFE_CLOSE(f);
|
|
||||||
|
|
||||||
gprintf("Done!! Disc old size: %d, disc new size: %d, saved: %d\n", DiscSize, wrote, DiscSize - wrote);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = __DiscWrite(gamepath, 0, DiscSize, ReadBuffer, spinner, spinner_data);
|
|
||||||
if( ret < 0 )
|
|
||||||
{
|
{
|
||||||
MEM2_free(ReadBuffer);
|
break;
|
||||||
return gc_error;
|
|
||||||
}
|
}
|
||||||
gprintf("Done!! Disc size: %d\n", DiscSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM2_free(ReadBuffer);
|
MEM2_free(ReadBuffer);
|
||||||
MEM2_free(FSTBuffer);
|
|
||||||
|
|
||||||
return gc_skipped;
|
return gc_skipped;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 GCDump::CheckSpace(u32 *needed, bool comp)
|
s32 GCDump::CheckSpace(u32 *needed, bool comp, message_callback_t message, void *message_data)
|
||||||
{
|
{
|
||||||
u8 *ReadBuffer = (u8 *)MEM2_alloc(0x40);
|
static gc_discHdr gcheader ATTRIBUTE_ALIGN(32);
|
||||||
|
|
||||||
s32 ret = __DiscReadRaw(ReadBuffer, 0x400, 0x40);
|
|
||||||
if(ret > 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
u32 ApploaderSize = *(vu32*)(ReadBuffer);
|
|
||||||
u32 FSTOffset = *(vu32*)(ReadBuffer+0x24);
|
|
||||||
u32 FSTSize = *(vu32*)(ReadBuffer+0x28);
|
|
||||||
u32 GamePartOffset = *(vu32*)(ReadBuffer+0x34);
|
|
||||||
u32 DataSize = *(vu32*)(ReadBuffer+0x38);
|
|
||||||
|
|
||||||
u32 DiscSize = DataSize + GamePartOffset;
|
|
||||||
|
|
||||||
MEM2_free(ReadBuffer);
|
|
||||||
|
|
||||||
|
u8 *ReadBuffer = (u8 *)MEM2_alloc(0x440);
|
||||||
u32 size = 0;
|
u32 size = 0;
|
||||||
|
u32 j;
|
||||||
|
|
||||||
if(writeexfiles)
|
char minfo[74];
|
||||||
{
|
|
||||||
size += 0xa440;
|
|
||||||
size += ApploaderSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!comp)
|
for( j=0; j<2; ++j)
|
||||||
{
|
{
|
||||||
size += DiscSize;
|
s32 ret = __DiscReadRaw(ReadBuffer, 0, 0x440);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
u8 *FSTBuffer = (u8 *)MEM2_alloc((FSTSize+31)&(~31));
|
|
||||||
|
|
||||||
ret = __DiscReadRaw(FSTBuffer, FSTOffset, (FSTSize+31)&(~31));
|
|
||||||
if(ret > 0)
|
if(ret > 0)
|
||||||
{
|
{
|
||||||
MEM2_free(FSTBuffer);
|
MEM2_free(ReadBuffer);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSTable = (u8*)FSTBuffer;
|
|
||||||
u32 FSTEnt = *(u32*)(FSTable+0x08);
|
|
||||||
FST *fst = (FST *)(FSTable);
|
|
||||||
|
|
||||||
u32 i;
|
|
||||||
|
|
||||||
for( i=1; i < FSTEnt; ++i )
|
ID = *(vu32*)(ReadBuffer);
|
||||||
|
ID2 = 0;
|
||||||
|
Disc = *(vu8*)(ReadBuffer+0x06);
|
||||||
|
Disc2 = 0;
|
||||||
|
ApploaderSize = *(vu32*)(ReadBuffer+0x400);
|
||||||
|
FSTOffset = *(vu32*)(ReadBuffer+0x424);
|
||||||
|
FSTSize = *(vu32*)(ReadBuffer+0x428);
|
||||||
|
FSTTotal = *(vu32*)(ReadBuffer+0x42c);
|
||||||
|
GamePartOffset = *(vu32*)(ReadBuffer+0x434);
|
||||||
|
DataSize = *(vu32*)(ReadBuffer+0x438);
|
||||||
|
|
||||||
|
DiscSize = DataSize + GamePartOffset;
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
Disc_ReadGCHeader(&gcheader);
|
||||||
|
Asciify2(gcheader.title);
|
||||||
|
|
||||||
|
snprintf(minfo, sizeof(minfo), "[%.06s] %s", (char *)gcheader.id, gcheader.title);
|
||||||
|
|
||||||
|
message( 2, 0, minfo, message_data);
|
||||||
|
|
||||||
|
if(writeexfiles)
|
||||||
{
|
{
|
||||||
if( fst[i].Type )
|
size += 0xa440;
|
||||||
|
size += ApploaderSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!comp)
|
||||||
|
{
|
||||||
|
size += DiscSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u8 *FSTBuffer = (u8 *)MEM2_alloc((FSTSize+31)&(~31));
|
||||||
|
|
||||||
|
ret = __DiscReadRaw(FSTBuffer, FSTOffset, (FSTSize+31)&(~31));
|
||||||
|
if(ret > 0)
|
||||||
{
|
{
|
||||||
continue;
|
MEM2_free(FSTBuffer);
|
||||||
}
|
return 1;
|
||||||
else
|
}
|
||||||
{
|
|
||||||
size += (fst[i].FileLength+31)&(~31);
|
FSTable = (u8*)FSTBuffer;
|
||||||
|
u32 FSTEnt = *(u32*)(FSTable+0x08);
|
||||||
|
FST *fst = (FST *)(FSTable);
|
||||||
|
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
for( i=1; i < FSTEnt; ++i )
|
||||||
|
{
|
||||||
|
if( fst[i].Type )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size += (fst[i].FileLength+31)&(~31);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MEM2_free(FSTBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(FSTTotal > FSTSize)
|
||||||
|
{
|
||||||
|
u32 cover = 0;
|
||||||
|
if(Disc == 0x00 && j == 0)
|
||||||
|
{
|
||||||
|
while(!done)
|
||||||
|
{
|
||||||
|
message( 1, 2, minfo, message_data);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
WDVD_GetCoverStatus(&cover);
|
||||||
|
if(!(cover & 0x2))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(Disc_Wait() < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(Disc_Open() < 0)
|
||||||
|
{
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Disc_IsGC() == 0)
|
||||||
|
{
|
||||||
|
s32 ret = __DiscReadRaw(ReadBuffer, 0, 0x440);
|
||||||
|
if(ret > 0)
|
||||||
|
{
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID2 = *(vu32*)(ReadBuffer);
|
||||||
|
Disc2 = *(vu8*)(ReadBuffer+0x06);
|
||||||
|
|
||||||
|
if(ID == ID2 && Disc2 == 0x01)
|
||||||
|
{
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(ID == ID2 && Disc2 == 0x00)
|
||||||
|
{
|
||||||
|
message( 7, 1, NULL, message_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(ID != ID2)
|
||||||
|
{
|
||||||
|
message( 8, 0, NULL, message_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(Disc_IsWii() == 0)
|
||||||
|
{
|
||||||
|
message( 5, 0, NULL, message_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message( 6, 0, NULL, message_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(Disc == 0x01 && j == 0)
|
||||||
|
{
|
||||||
|
while(!done)
|
||||||
|
{
|
||||||
|
message( 1, 1, minfo, message_data);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
WDVD_GetCoverStatus(&cover);
|
||||||
|
if(!(cover & 0x2))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(Disc_Wait() < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(Disc_Open() < 0)
|
||||||
|
{
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Disc_IsGC() == 0)
|
||||||
|
{
|
||||||
|
s32 ret = __DiscReadRaw(ReadBuffer, 0, 0x440);
|
||||||
|
if(ret > 0)
|
||||||
|
{
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID2 = *(vu32*)(ReadBuffer);
|
||||||
|
Disc2 = *(vu8*)(ReadBuffer+0x06);
|
||||||
|
|
||||||
|
if(ID == ID2 && Disc2 == 0x00)
|
||||||
|
{
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(ID == ID2 && Disc2 == 0x01)
|
||||||
|
{
|
||||||
|
message( 7, 2, NULL, message_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(ID != ID2)
|
||||||
|
{
|
||||||
|
message( 8, 0, NULL, message_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(Disc_IsWii() == 0)
|
||||||
|
{
|
||||||
|
message( 5, 0, NULL, message_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message( 6, 0, NULL, message_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(j == 1)
|
||||||
|
{
|
||||||
|
if(Disc == 0x01)
|
||||||
|
{
|
||||||
|
while(!done)
|
||||||
|
{
|
||||||
|
message( 1, 1, minfo, message_data);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
WDVD_GetCoverStatus(&cover);
|
||||||
|
if(!(cover & 0x2))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(Disc_Wait() < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(Disc_Open() < 0)
|
||||||
|
{
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Disc_IsGC() == 0)
|
||||||
|
{
|
||||||
|
s32 ret = __DiscReadRaw(ReadBuffer, 0, 0x440);
|
||||||
|
if(ret > 0)
|
||||||
|
{
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID2 = *(vu32*)(ReadBuffer);
|
||||||
|
Disc2 = *(vu8*)(ReadBuffer+0x06);
|
||||||
|
|
||||||
|
if(ID == ID2 && Disc2 == 0x00)
|
||||||
|
{
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(ID == ID2 && Disc2 == 0x01)
|
||||||
|
{
|
||||||
|
message( 7, 2, NULL, message_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(ID != ID2)
|
||||||
|
{
|
||||||
|
message( 8, 0, NULL, message_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(Disc_IsWii() == 0)
|
||||||
|
{
|
||||||
|
message( 5, 0, NULL, message_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message( 6, 0, NULL, message_data);
|
||||||
|
usleep( 5000000 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MEM2_free(FSTBuffer);
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
*needed = size/0x8000;
|
*needed = size/0x8000;
|
||||||
gprintf("Free space needed: %d bytes (%x blocks)\n", size, size/0x8000);
|
gprintf("Free space needed: %d Mb (%x blocks)\n", (size/1024)/1024, size/0x8000);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -29,6 +29,7 @@
|
|||||||
#define GC_DISC_H_
|
#define GC_DISC_H_
|
||||||
|
|
||||||
typedef void (*progress_callback_t)(int status,int total,void *user_data);
|
typedef void (*progress_callback_t)(int status,int total,void *user_data);
|
||||||
|
typedef void (*message_callback_t)(int message, int info, char *cinfo, void *user_data);
|
||||||
|
|
||||||
class GCDump
|
class GCDump
|
||||||
{
|
{
|
||||||
@ -44,19 +45,32 @@ public:
|
|||||||
gamepartition = partition;
|
gamepartition = partition;
|
||||||
gc_skipped = 0;
|
gc_skipped = 0;
|
||||||
}
|
}
|
||||||
s32 DumpGame(progress_callback_t spinner, void *spinner_data);
|
s32 DumpGame(progress_callback_t spinner, message_callback_t message, void *spinner_data);
|
||||||
s32 CheckSpace(u32 *needed, bool comp);
|
s32 CheckSpace(u32 *needed, bool comp, message_callback_t message, void *message_data);
|
||||||
private:
|
private:
|
||||||
bool force_32k_align;
|
bool force_32k_align;
|
||||||
bool skiponerror;
|
bool skiponerror;
|
||||||
bool compressed;
|
bool compressed;
|
||||||
bool writeexfiles;
|
bool writeexfiles;
|
||||||
const char* gamepartition;
|
const char* gamepartition;
|
||||||
|
u8 Disc;
|
||||||
|
u8 Disc2;
|
||||||
u32 gc_nbrretry;
|
u32 gc_nbrretry;
|
||||||
u32 gc_error;
|
u32 gc_error;
|
||||||
u32 gc_retry;
|
u32 gc_retry;
|
||||||
u32 gc_skipped;
|
u32 gc_skipped;
|
||||||
u32 gc_readsize;
|
u32 gc_readsize;
|
||||||
|
u32 ID;
|
||||||
|
u32 ID2;
|
||||||
|
u32 ApploaderSize;
|
||||||
|
u32 DOLOffset;
|
||||||
|
u32 DOLSize;
|
||||||
|
u32 FSTOffset;
|
||||||
|
u32 FSTSize;
|
||||||
|
u32 FSTTotal;
|
||||||
|
u32 FSTEnt;
|
||||||
|
u32 GamePartOffset;
|
||||||
|
u32 DataSize;
|
||||||
u32 DiscSize;
|
u32 DiscSize;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -929,8 +929,9 @@ private:
|
|||||||
void LoadView(void);
|
void LoadView(void);
|
||||||
void _getGrabStatus(void);
|
void _getGrabStatus(void);
|
||||||
static void _addDiscProgress(int status, int total, void *user_data);
|
static void _addDiscProgress(int status, int total, void *user_data);
|
||||||
static int _gameInstaller(void *obj);
|
static void _Messenger(int message, int info, char *cinfo, void *user_data);
|
||||||
static int _GCgameInstaller(void *obj);
|
static int _gameInstaller(void *obj);
|
||||||
|
static int _GCgameInstaller(void *obj);
|
||||||
static int _GCcopyGame(void *obj);
|
static int _GCcopyGame(void *obj);
|
||||||
wstringEx _optBoolToString(int b);
|
wstringEx _optBoolToString(int b);
|
||||||
void _stopSounds(void);
|
void _stopSounds(void);
|
||||||
|
@ -71,6 +71,31 @@ void CMenu::_addDiscProgress(int status, int total, void *user_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMenu::_Messenger(int message, int info, char *cinfo, void *user_data)
|
||||||
|
{
|
||||||
|
CMenu &m = *(CMenu *)user_data;
|
||||||
|
LWP_MutexLock(m.m_mutex);
|
||||||
|
if(message == 1)
|
||||||
|
m._setThrdMsg(wfmt(m._fmt("wbfsop14", L"Calculating space needed for %s...\n Please insert disc %d to continue"), cinfo, info), 0.f);
|
||||||
|
if(message == 2)
|
||||||
|
m._setThrdMsg(wfmt(m._fmt("wbfsop15", L"Calculating space needed for %s"), cinfo), 0.f);
|
||||||
|
if(message == 3)
|
||||||
|
m._setThrdMsg(wfmt(m._fmt("wbfsop16", L"Installing %s"), cinfo), 0.f);
|
||||||
|
if(message == 4)
|
||||||
|
m._setThrdMsg(wfmt(m._fmt("wbfsop17", L"Installing %s disc %d/2"), cinfo, info), 0.f);
|
||||||
|
if(message == 5)
|
||||||
|
m._setThrdMsg(m._t("wbfsop18", L"Don't try to trick me with a Wii disc!!"), 0.f);
|
||||||
|
if(message == 6)
|
||||||
|
m._setThrdMsg(m._t("wbfsop19", L"This is not a GC disc!!"), 0.f);
|
||||||
|
if(message == 7)
|
||||||
|
m._setThrdMsg(wfmt(m._fmt("wbfsop20", L"You inserted disc %d again!!"), info), 0.f);
|
||||||
|
if(message == 8)
|
||||||
|
m._setThrdMsg(m._t("wbfsop21", L"This is a disc of another game!!"), 0.f);
|
||||||
|
if(message == 9)
|
||||||
|
m._setThrdMsg(wfmt(m._fmt("wbfsop22", L"Installing %s...\n Please insert disc 2 to continue"), cinfo), 1.f);
|
||||||
|
LWP_MutexUnlock(m.m_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
int CMenu::_gameInstaller(void *obj)
|
int CMenu::_gameInstaller(void *obj)
|
||||||
{
|
{
|
||||||
CMenu &m = *(CMenu *)obj;
|
CMenu &m = *(CMenu *)obj;
|
||||||
@ -144,7 +169,13 @@ int CMenu::_GCgameInstaller(void *obj)
|
|||||||
u64 free = (u64)stats.f_frsize * (u64)stats.f_bfree;
|
u64 free = (u64)stats.f_frsize * (u64)stats.f_bfree;
|
||||||
u32 needed = 0;
|
u32 needed = 0;
|
||||||
|
|
||||||
m_gcdump.CheckSpace(&needed, comp);
|
ret = m_gcdump.CheckSpace(&needed, comp, CMenu::_Messenger, obj);
|
||||||
|
if(ret != 0)
|
||||||
|
{
|
||||||
|
m._setThrdMsg(m._t("wbfsop9", L"An error has occurred"), 1.f);
|
||||||
|
m.m_thrdWorking = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
u32 blockfree = free/0x8000;
|
u32 blockfree = free/0x8000;
|
||||||
|
|
||||||
@ -161,14 +192,14 @@ int CMenu::_GCgameInstaller(void *obj)
|
|||||||
m._setThrdMsg(L"", 0);
|
m._setThrdMsg(L"", 0);
|
||||||
LWP_MutexUnlock(m.m_mutex);
|
LWP_MutexUnlock(m.m_mutex);
|
||||||
|
|
||||||
ret = m_gcdump.DumpGame(CMenu::_addDiscProgress, obj);
|
ret = m_gcdump.DumpGame(CMenu::_addDiscProgress, CMenu::_Messenger, obj);
|
||||||
LWP_MutexLock(m.m_mutex);
|
LWP_MutexLock(m.m_mutex);
|
||||||
if(ret == 0)
|
if(ret == 0)
|
||||||
m._setThrdMsg(m._t("wbfsop8", L"Game installed"), 1.f);
|
m._setThrdMsg(m._t("wbfsop8", L"Game installed"), 1.f);
|
||||||
else if( ret >= 0x30200)
|
else if( ret >= 0x30200)
|
||||||
m._setThrdMsg(wfmt(m._fmt("wbfsop12", L"DVDError(%d)"), ret), 0.f);
|
m._setThrdMsg(wfmt(m._fmt("wbfsop12", L"DVDError(%d)"), ret), 1.f);
|
||||||
else if( ret > 0)
|
else if( ret > 0)
|
||||||
m._setThrdMsg(wfmt(m._fmt("wbfsop13", L"Game installed, but disc contains errors (%d)"), ret), 0.f);
|
m._setThrdMsg(wfmt(m._fmt("wbfsop13", L"Game installed, but disc contains errors (%d)"), ret), 1.f);
|
||||||
else
|
else
|
||||||
m._setThrdMsg(m._t("wbfsop9", L"An error has occurred"), 1.f);
|
m._setThrdMsg(m._t("wbfsop9", L"An error has occurred"), 1.f);
|
||||||
LWP_MutexUnlock(m.m_mutex);
|
LWP_MutexUnlock(m.m_mutex);
|
||||||
|
Loading…
Reference in New Issue
Block a user