mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-23 19:59:16 +01:00
-cleaned up and optimized gamecube disc
installer, maybe it's a bit faster now ;) I want to thank stfour for his fileOps which was added in r160, it makes a very good job, without it copy game from usb to sd would have taken longer to add for me :)
This commit is contained in:
parent
f1d0386b3c
commit
5e3df23f76
@ -37,6 +37,7 @@
|
|||||||
#include "wdvd.h"
|
#include "wdvd.h"
|
||||||
#include "text.hpp"
|
#include "text.hpp"
|
||||||
#include "gecko.h"
|
#include "gecko.h"
|
||||||
|
#include "fileOps.h"
|
||||||
|
|
||||||
static u8 *FSTable ALIGNED(32);
|
static u8 *FSTable ALIGNED(32);
|
||||||
|
|
||||||
@ -87,29 +88,23 @@ s32 GCDump::__DiscReadRaw(void *outbuf, u32 offset, u32 length)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 GCDump::__DiscWrite(char * path, u32 offset, u32 length, progress_callback_t spinner, void *spinner_data)
|
s32 GCDump::__DiscWrite(char * path, u32 offset, u32 length, u8 *ReadBuffer, progress_callback_t spinner, void *spinner_data)
|
||||||
{
|
{
|
||||||
gprintf("__DiscWrite(%s, 0x%08x, %x)\n", path, offset, length);
|
gprintf("__DiscWrite(%s, 0x%08x, %x)\n", path, offset, length);
|
||||||
u8 *ReadBuffer = (u8 *)MEM2_alloc(gc_readsize);
|
|
||||||
u32 toread = 0;
|
u32 toread = 0;
|
||||||
u32 wrote = 0;
|
u32 wrote = 0;
|
||||||
FILE *f = fopen(path, "ab");
|
FILE *f = fopen(path, "wb");
|
||||||
|
|
||||||
while(length)
|
while(length)
|
||||||
{
|
{
|
||||||
toread = gc_readsize;
|
toread = gc_readsize ? gc_readsize<length : length;
|
||||||
if(toread > length)
|
|
||||||
toread = length;
|
|
||||||
|
|
||||||
s32 ret = __DiscReadRaw(ReadBuffer, offset, (toread+31)&(~31));
|
s32 ret = __DiscReadRaw(ReadBuffer, offset, (toread+31)&(~31));
|
||||||
if( ret == 1 )
|
if( ret == 1 )
|
||||||
memset(ReadBuffer, 0, gc_readsize);
|
memset(ReadBuffer, 0, gc_readsize);
|
||||||
|
|
||||||
else if( ret > 1 )
|
else if( ret > 1 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fwrite(ReadBuffer, 1, toread, f);
|
fwrite(ReadBuffer, 1, toread, f);
|
||||||
|
|
||||||
wrote += toread;
|
wrote += toread;
|
||||||
offset += toread;
|
offset += toread;
|
||||||
length -= toread;
|
length -= toread;
|
||||||
@ -122,30 +117,24 @@ s32 GCDump::__DiscWrite(char * path, u32 offset, u32 length, progress_callback_t
|
|||||||
return wrote;
|
return wrote;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 GCDump::__DiscWriteAligned(FILE *f, u32 offset, u32 length)
|
s32 GCDump::__DiscWriteAligned(FILE *f, u32 offset, u32 length, u8 *ReadBuffer)
|
||||||
{
|
{
|
||||||
u8 *ReadBuffer = (u8 *)MEM2_alloc(gc_readsize+4);
|
|
||||||
u32 toread = 0;
|
u32 toread = 0;
|
||||||
u32 wrote = 0;
|
u32 wrote = 0;
|
||||||
|
|
||||||
while(length)
|
while(length)
|
||||||
{
|
{
|
||||||
toread = gc_readsize;
|
toread = length ? gc_readsize>length : gc_readsize;
|
||||||
if (toread > length)
|
|
||||||
toread = length;
|
|
||||||
|
|
||||||
s32 ret = __DiscReadRaw(ReadBuffer, offset, (toread+31)&(~31));
|
s32 ret = __DiscReadRaw(ReadBuffer, offset, (toread+31)&(~31));
|
||||||
if (ret == 1)
|
if (ret == 1)
|
||||||
memset(ReadBuffer, 0, gc_readsize);
|
memset(ReadBuffer, 0, gc_readsize);
|
||||||
else if (ret > 1)
|
else if (ret > 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fwrite(ReadBuffer, 1, toread, f);
|
fwrite(ReadBuffer, 1, toread, f);
|
||||||
wrote += toread;
|
wrote += toread;
|
||||||
offset += toread;
|
offset += toread;
|
||||||
length -= toread;
|
length -= toread;
|
||||||
}
|
}
|
||||||
MEM2_free(ReadBuffer);
|
|
||||||
return wrote;
|
return wrote;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +142,7 @@ 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(gc_readsize);
|
||||||
u8 *FSTBuffer;
|
u8 *FSTBuffer;
|
||||||
u32 wrote = 0;
|
u32 wrote = 0;
|
||||||
|
|
||||||
@ -165,7 +154,6 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
|
|||||||
u32 FSTEnt = 0;
|
u32 FSTEnt = 0;
|
||||||
u32 GamePartOffset = 0;
|
u32 GamePartOffset = 0;
|
||||||
u32 DataSize = 0;
|
u32 DataSize = 0;
|
||||||
char *FSTNameOff = (char *)NULL;
|
|
||||||
|
|
||||||
char folder[MAX_FAT_PATH];
|
char folder[MAX_FAT_PATH];
|
||||||
bzero(folder, MAX_FAT_PATH);
|
bzero(folder, MAX_FAT_PATH);
|
||||||
@ -175,18 +163,17 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
|
|||||||
s32 ret = Disc_ReadGCHeader(&gcheader);
|
s32 ret = Disc_ReadGCHeader(&gcheader);
|
||||||
Asciify2(gcheader.title);
|
Asciify2(gcheader.title);
|
||||||
|
|
||||||
|
snprintf(folder, sizeof(folder), "%s:/games/", gamepartition);
|
||||||
|
fsop_MakeFolder(folder);
|
||||||
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]", gamepartition, gcheader.title, (char *)gcheader.id);
|
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]", gamepartition, gcheader.title, (char *)gcheader.id);
|
||||||
makedir((char *)folder);
|
fsop_MakeFolder(folder);
|
||||||
|
|
||||||
if(writeexfiles)
|
|
||||||
{
|
|
||||||
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]/sys", gamepartition, gcheader.title, (char *)gcheader.id);
|
|
||||||
makedir((char *)folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = __DiscReadRaw(ReadBuffer, 0x400, 0x40);
|
ret = __DiscReadRaw(ReadBuffer, 0x400, 0x40);
|
||||||
if(ret > 0)
|
if(ret > 0)
|
||||||
|
{
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
return 0x31100;
|
return 0x31100;
|
||||||
|
}
|
||||||
|
|
||||||
ApploaderSize = *(vu32*)(ReadBuffer);
|
ApploaderSize = *(vu32*)(ReadBuffer);
|
||||||
DOLOffset = *(vu32*)(ReadBuffer+0x20);
|
DOLOffset = *(vu32*)(ReadBuffer+0x20);
|
||||||
@ -195,8 +182,6 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
|
|||||||
GamePartOffset = *(vu32*)(ReadBuffer+0x34);
|
GamePartOffset = *(vu32*)(ReadBuffer+0x34);
|
||||||
DataSize = *(vu32*)(ReadBuffer+0x38);
|
DataSize = *(vu32*)(ReadBuffer+0x38);
|
||||||
|
|
||||||
MEM2_free(ReadBuffer);
|
|
||||||
|
|
||||||
DOLSize = FSTOffset - DOLOffset;
|
DOLSize = FSTOffset - DOLOffset;
|
||||||
DiscSize = DataSize + GamePartOffset;
|
DiscSize = DataSize + GamePartOffset;
|
||||||
|
|
||||||
@ -205,13 +190,17 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
|
|||||||
ret = __DiscReadRaw(FSTBuffer, FSTOffset, (FSTSize+31)&(~31));
|
ret = __DiscReadRaw(FSTBuffer, FSTOffset, (FSTSize+31)&(~31));
|
||||||
|
|
||||||
if(ret > 0)
|
if(ret > 0)
|
||||||
|
{
|
||||||
|
MEM2_free(FSTBuffer);
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
return 0x31100;
|
return 0x31100;
|
||||||
|
}
|
||||||
|
|
||||||
FSTable = (u8*)FSTBuffer;
|
FSTable = (u8*)FSTBuffer;
|
||||||
|
|
||||||
FSTEnt = *(u32*)(FSTable+0x08);
|
FSTEnt = *(u32*)(FSTable+0x08);
|
||||||
|
|
||||||
FSTNameOff = (char*)(FSTable + FSTEnt * 0x0C);
|
char *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");
|
||||||
@ -227,17 +216,20 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
|
|||||||
|
|
||||||
if(writeexfiles)
|
if(writeexfiles)
|
||||||
{
|
{
|
||||||
|
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]/sys", gamepartition, gcheader.title, (char *)gcheader.id);
|
||||||
|
fsop_MakeFolder(folder);
|
||||||
|
|
||||||
gprintf("Writing %s/boot.bin\n", folder);
|
gprintf("Writing %s/boot.bin\n", folder);
|
||||||
snprintf(gamepath, sizeof(gamepath), "%s/boot.bin", folder);
|
snprintf(gamepath, sizeof(gamepath), "%s/boot.bin", folder);
|
||||||
__DiscWrite(gamepath, 0, 0x440, spinner, spinner_data);
|
__DiscWrite(gamepath, 0, 0x440, ReadBuffer, spinner, spinner_data);
|
||||||
|
|
||||||
gprintf("Writing %s/bi2.bin\n", folder);
|
gprintf("Writing %s/bi2.bin\n", folder);
|
||||||
snprintf(gamepath, sizeof(gamepath), "%s/bi2.bin", folder);
|
snprintf(gamepath, sizeof(gamepath), "%s/bi2.bin", folder);
|
||||||
__DiscWrite(gamepath, 0x440, 0x2000, spinner, spinner_data);
|
__DiscWrite(gamepath, 0x440, 0x2000, ReadBuffer, spinner, spinner_data);
|
||||||
|
|
||||||
gprintf("Writing %s/apploader.img\n", folder);
|
gprintf("Writing %s/apploader.img\n", folder);
|
||||||
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, ReadBuffer, spinner, spinner_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(gamepath, sizeof(gamepath), "%s:/games/%s [%s]/game.iso", gamepartition, gcheader.title, (char *)gcheader.id);
|
snprintf(gamepath, sizeof(gamepath), "%s:/games/%s [%s]/game.iso", gamepartition, gcheader.title, (char *)gcheader.id);
|
||||||
@ -249,9 +241,9 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
|
|||||||
u32 correction;
|
u32 correction;
|
||||||
|
|
||||||
FILE *f;
|
FILE *f;
|
||||||
f = fopen(gamepath, "ab");
|
f = fopen(gamepath, "wb");
|
||||||
|
|
||||||
ret = __DiscWriteAligned(f, 0, (FSTOffset + FSTSize));
|
ret = __DiscWriteAligned(f, 0, (FSTOffset + FSTSize), ReadBuffer);
|
||||||
wrote += (FSTOffset + FSTSize);
|
wrote += (FSTOffset + FSTSize);
|
||||||
|
|
||||||
u32 i;
|
u32 i;
|
||||||
@ -264,27 +256,19 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
correction = 0x00;
|
|
||||||
for(align = 0x8000; align > 2; align/=2)
|
for(align = 0x8000; align > 2; align/=2)
|
||||||
{
|
{
|
||||||
if((fst[i].FileOffset & (align-1)) == 0 || force_32k_align)
|
if((fst[i].FileOffset & (align-1)) == 0 || force_32k_align)
|
||||||
{
|
{
|
||||||
|
correction = 0x00;
|
||||||
|
while(((wrote+correction) & (align-1)) != 0)
|
||||||
|
correction++;
|
||||||
|
wrote += correction;
|
||||||
|
fseek(f,correction,SEEK_END);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ret = __DiscWriteAligned(f, fst[i].FileOffset, fst[i].FileLength, ReadBuffer);
|
||||||
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);
|
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 )
|
||||||
{
|
{
|
||||||
@ -296,16 +280,14 @@ 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);
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
SAFE_CLOSE(f);
|
SAFE_CLOSE(f);
|
||||||
return gc_error;
|
return gc_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SAFE_CLOSE(f);
|
|
||||||
|
|
||||||
gprintf("Updating FST\n");
|
gprintf("Updating FST\n");
|
||||||
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);
|
||||||
@ -314,16 +296,18 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = __DiscWrite(gamepath, 0, DiscSize, spinner, spinner_data);
|
ret = __DiscWrite(gamepath, 0, DiscSize, ReadBuffer, spinner, spinner_data);
|
||||||
if( ret < 0 )
|
if( ret < 0 )
|
||||||
{
|
{
|
||||||
MEM2_free(FSTBuffer);
|
MEM2_free(FSTBuffer);
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
return gc_error;
|
return gc_error;
|
||||||
}
|
}
|
||||||
gprintf("Done!! Disc size: %d\n", DiscSize);
|
gprintf("Done!! Disc size: %d\n", DiscSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM2_free(FSTBuffer);
|
MEM2_free(FSTBuffer);
|
||||||
|
MEM2_free(ReadBuffer);
|
||||||
|
|
||||||
return gc_skipped;
|
return gc_skipped;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ 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, u8 *ReadBuffer, progress_callback_t spinner , void *spinner_data);
|
||||||
s32 __DiscWriteAligned(FILE *f, u32 offset, u32 length);
|
s32 __DiscWriteAligned(FILE *f, u32 offset, u32 length, u8 *ReadBuffer);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue
Block a user