From c8ca36600dab0f8fd334e2c6a20917afef164f6f Mon Sep 17 00:00:00 2001 From: "overjoy.psm" Date: Wed, 29 Feb 2012 00:19:50 +0000 Subject: [PATCH] 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 --- source/loader/gc_disc.cpp | 701 +++++++++++++++++++++++++++----------- source/loader/gc_disc.hpp | 20 +- source/menu/menu.hpp | 5 +- source/menu/menu_wbfs.cpp | 39 ++- 4 files changed, 565 insertions(+), 200 deletions(-) diff --git a/source/loader/gc_disc.cpp b/source/loader/gc_disc.cpp index 9a36ec1b..71f8849c 100644 --- a/source/loader/gc_disc.cpp +++ b/source/loader/gc_disc.cpp @@ -26,6 +26,7 @@ ***************************************************************************/ #include +#include #include #include @@ -138,246 +139,564 @@ s32 GCDump::__DiscWriteAligned(FILE *f, u32 offset, u32 length, u8 *ReadBuffer) 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); - u8 *ReadBuffer = (u8 *)MEM2_alloc(0x40); - u8 *FSTBuffer; - u32 wrote = 0; + u8 *ReadBuffer = (u8 *)MEM2_alloc(gc_readsize); - u32 ApploaderSize = 0; - u32 DOLOffset = 0; - u32 DOLSize = 0; - u32 FSTOffset = 0; - u32 FSTSize = 0; - u32 FSTEnt = 0; - u32 GamePartOffset = 0; - u32 DataSize = 0; + u32 j; + char *FSTNameOff = (char *)NULL; char folder[MAX_FAT_PATH]; bzero(folder, MAX_FAT_PATH); char gamepath[MAX_FAT_PATH]; - bzero(gamepath, MAX_FAT_PATH); - - s32 ret = Disc_ReadGCHeader(&gcheader); - Asciify2(gcheader.title); - - 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) + bzero(gamepath, MAX_FAT_PATH); + char minfo[74]; + + for( j=0; j<2; ++j) { - MEM2_free(ReadBuffer); - return 0x31100; - } + bool done = false; + u8 *FSTBuffer; + u32 wrote = 0; - ApploaderSize = *(vu32*)(ReadBuffer); - DOLOffset = *(vu32*)(ReadBuffer+0x20); - FSTOffset = *(vu32*)(ReadBuffer+0x24); - FSTSize = *(vu32*)(ReadBuffer+0x28); - GamePartOffset = *(vu32*)(ReadBuffer+0x34); - DataSize = *(vu32*)(ReadBuffer+0x38); + s32 ret = Disc_ReadGCHeader(&gcheader); + Asciify2(gcheader.title); - 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; - 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); + snprintf(folder, sizeof(folder), "%s:/games/", gamepartition); + if(!fsop_DirExist(folder)) + fsop_MakeFolder(folder); + snprintf(folder, sizeof(folder), "%s:/games/%s [%.06s]%s", 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 [%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 ) + ret = __DiscReadRaw(ReadBuffer, 0, 0x440); + if(ret > 0) { - 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; - } - else - { - for(align = 0x8000; align > 2; align/=2) + if( fst[i].Type ) { - if((fst[i].FileOffset & (align-1)) == 0 || force_32k_align) + continue; + } + else + { + for(align = 0x8000; align > 2; align/=2) { - correction = 0x00; - while(((wrote+correction) & (align-1)) != 0) - correction++; - wrote += correction; - fseek(f,correction,SEEK_END); + 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; + } + } + 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; } } - 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; - } } } - - 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 ) + else { - MEM2_free(ReadBuffer); - return gc_error; + break; } - gprintf("Done!! Disc size: %d\n", DiscSize); } MEM2_free(ReadBuffer); - MEM2_free(FSTBuffer); 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); - - 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); + static gc_discHdr gcheader ATTRIBUTE_ALIGN(32); + u8 *ReadBuffer = (u8 *)MEM2_alloc(0x440); u32 size = 0; + u32 j; - if(writeexfiles) - { - size += 0xa440; - size += ApploaderSize; - } + char minfo[74]; - if(!comp) + for( j=0; j<2; ++j) { - size += DiscSize; - } - else - { - u8 *FSTBuffer = (u8 *)MEM2_alloc((FSTSize+31)&(~31)); - - ret = __DiscReadRaw(FSTBuffer, FSTOffset, (FSTSize+31)&(~31)); + s32 ret = __DiscReadRaw(ReadBuffer, 0, 0x440); if(ret > 0) { - MEM2_free(FSTBuffer); + MEM2_free(ReadBuffer); 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; - } - else - { - size += (fst[i].FileLength+31)&(~31); + MEM2_free(FSTBuffer); + return 1; + } + + 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; - 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; } \ No newline at end of file diff --git a/source/loader/gc_disc.hpp b/source/loader/gc_disc.hpp index 4e938e7e..c9b0dc6c 100644 --- a/source/loader/gc_disc.hpp +++ b/source/loader/gc_disc.hpp @@ -29,6 +29,7 @@ #define GC_DISC_H_ 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 { @@ -44,19 +45,32 @@ public: gamepartition = partition; gc_skipped = 0; } - s32 DumpGame(progress_callback_t spinner, void *spinner_data); - s32 CheckSpace(u32 *needed, bool comp); + s32 DumpGame(progress_callback_t spinner, message_callback_t message, void *spinner_data); + s32 CheckSpace(u32 *needed, bool comp, message_callback_t message, void *message_data); private: bool force_32k_align; bool skiponerror; bool compressed; bool writeexfiles; const char* gamepartition; + u8 Disc; + u8 Disc2; u32 gc_nbrretry; u32 gc_error; u32 gc_retry; 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; typedef struct { diff --git a/source/menu/menu.hpp b/source/menu/menu.hpp index 82e9e301..1c426b0f 100644 --- a/source/menu/menu.hpp +++ b/source/menu/menu.hpp @@ -929,8 +929,9 @@ private: void LoadView(void); void _getGrabStatus(void); static void _addDiscProgress(int status, int total, void *user_data); - static int _gameInstaller(void *obj); - static int _GCgameInstaller(void *obj); + static void _Messenger(int message, int info, char *cinfo, void *user_data); + static int _gameInstaller(void *obj); + static int _GCgameInstaller(void *obj); static int _GCcopyGame(void *obj); wstringEx _optBoolToString(int b); void _stopSounds(void); diff --git a/source/menu/menu_wbfs.cpp b/source/menu/menu_wbfs.cpp index 8fb116eb..ffe24422 100644 --- a/source/menu/menu_wbfs.cpp +++ b/source/menu/menu_wbfs.cpp @@ -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) { CMenu &m = *(CMenu *)obj; @@ -144,7 +169,13 @@ int CMenu::_GCgameInstaller(void *obj) u64 free = (u64)stats.f_frsize * (u64)stats.f_bfree; 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; @@ -161,14 +192,14 @@ int CMenu::_GCgameInstaller(void *obj) m._setThrdMsg(L"", 0); 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); if(ret == 0) m._setThrdMsg(m._t("wbfsop8", L"Game installed"), 1.f); 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) - 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 m._setThrdMsg(m._t("wbfsop9", L"An error has occurred"), 1.f); LWP_MutexUnlock(m.m_mutex);