From f0ca11506b97c8932a49846008734fb4ec232e3d Mon Sep 17 00:00:00 2001 From: dimok321 <15055714+dimok789@users.noreply.github.com> Date: Sat, 29 May 2010 15:43:19 +0000 Subject: [PATCH] *WIP Patch fix. WIP patches should work now. Tested and confirmed for PoP. WIP Patches will be only accepted in the following format (let's not invent thousands of different formats): In 3x 4 bytes columns separated by a space (no ":" allowed) offset | original address | overwrite address Example for PoP: 007AAC6A 7A6B6F6A 6F6A7A6B 007AAC75 7C7A6939 69397C7A ... The original address is compared before patching and is not patched if it doesn't match. You can see the confirmation or fail of a patch on the Gecko Output. *A few fix ups in different places --- HBC/META.XML | 4 +- gui.pnproj | 2 +- source/libwiigui/gui_image_async.cpp | 6 +- source/libwiigui/gui_sound.cpp | 20 +- source/menu.cpp | 2 +- source/network/networkops.cpp | 2 +- source/patches/patchcode.c | 12 ++ source/patches/wip.c | 262 ++++++++++++++------------- source/patches/wip.h | 15 +- source/prompts/ProgressWindow.cpp | 2 +- source/usbloader/alternatedol.c | 8 +- source/usbloader/apploader.c | 29 ++- source/usbloader/disc.c | 8 +- 13 files changed, 195 insertions(+), 177 deletions(-) diff --git a/HBC/META.XML b/HBC/META.XML index 9e6406a3..873f4500 100644 --- a/HBC/META.XML +++ b/HBC/META.XML @@ -2,8 +2,8 @@ USB Loader GX USB Loader GX Team - 1.0 r931 - 201005290726 + 1.0 r932 + 201005290827 Loads games from USB-devices USB Loader GX is a libwiigui based USB iso loader with a wii-like GUI. You can install games to your HDDs and boot them with shorter loading times. The interactive GUI is completely controllable with WiiMote, Classic Controller or GC Controller. diff --git a/gui.pnproj b/gui.pnproj index 49873f17..f3128446 100644 --- a/gui.pnproj +++ b/gui.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/source/libwiigui/gui_image_async.cpp b/source/libwiigui/gui_image_async.cpp index a16f7363..d4977193 100644 --- a/source/libwiigui/gui_image_async.cpp +++ b/source/libwiigui/gui_image_async.cpp @@ -19,7 +19,7 @@ void debug(int Line, const char* Format, ...) if(debugLock==0) LWP_MutexInit(&debugLock, false); LWP_MutexLock(debugLock); - + FILE *fp = fopen("SD:/debug.txt", "a"); if(fp) { @@ -38,7 +38,7 @@ void debug(int Line, const char* Format, ...) LWP_MutexUnlock(debugLock); } //#define DEBUG(format, ...) debug(__LINE__, format, ##__VA_ARGS__) -#define DEBUG(format, ...) +#define DEBUG(format, ...) static void *memdup(const void* src, size_t len) { @@ -103,7 +103,7 @@ static u32 GuiImageAsyncThreadInit() CanSleep = false; LWP_MutexInit(&ListLock, false); LWP_MutexInit(&InUseLock, false); - LWP_CreateThread(&Thread, GuiImageAsyncThread, NULL, NULL, 0, 75); + LWP_CreateThread(&Thread, GuiImageAsyncThread, NULL, NULL, 16384, 75); // while(!CanSleep) // usleep(20); } diff --git a/source/libwiigui/gui_sound.cpp b/source/libwiigui/gui_sound.cpp index e565296a..11151849 100644 --- a/source/libwiigui/gui_sound.cpp +++ b/source/libwiigui/gui_sound.cpp @@ -44,7 +44,7 @@ GuiSoundDecoder *GuiSoundDecoder::GetDecoder(const u8 * snd, u32 len, bool snd_i { GuiSoundDecoder *d = NULL; try{ d = de->fnc(snd, len, snd_is_allocated); } - catch(const char *error){ + catch(const char *error){ gprintf("%s", error); } catch(...){} if(d) return d; @@ -52,7 +52,7 @@ GuiSoundDecoder *GuiSoundDecoder::GetDecoder(const u8 * snd, u32 len, bool snd_i return NULL; } - + /*************************************************************** * * D E C O D E R – T H R E A D @@ -191,7 +191,7 @@ GuiSound::GuiSound(const u8 *s, int l, int v/*=100*/, bool r/*=true*/, bool a/*= { if(GuiSoundCount++ == 0 || GuiSoundDecoderThreadHandle == LWP_THREAD_NULL) { - LWP_CreateThread(&GuiSoundDecoderThreadHandle,GuiSoundDecoderThread,NULL,NULL,32*1024,80); + LWP_CreateThread(&GuiSoundDecoderThreadHandle,GuiSoundDecoderThread,NULL,NULL,32768,80); } voice = -1; play_buffer[0] = (u8*)memalign(32, BUFFER_SIZE*3); // tripple-buffer first is played @@ -247,7 +247,7 @@ bool GuiSound::Load(const char *p) { Stop(); // stop playing if(!play_buffer[0]) return false; - + bool ret = false; voice = -2; // -2 marks loading from file u32 filesize = 0; @@ -300,15 +300,15 @@ void GuiSound::Play() Stop(); // stop playing if it played if(!play_buffer[0]) return; if(!decoder) return; // no decoder or no play_buffer -> no playing - // initialize the buffer - buffer_nr = 0; // allways starts with buffer 0 + // initialize the buffer + buffer_nr = 0; // allways starts with buffer 0 buffer_pos = 0; // reset position buffer_ready = false; buffer_eof = false; decoder->Rewind(); // play from begin DecoderCallback(); // fill first buffer; if(!buffer_ready || buffer_eof) // if first buffer not ready -> no play - return; + return; voice = ASND_GetFirstUnusedVoice(); if(voice >= 0) { @@ -387,7 +387,7 @@ void GuiSound::DecoderCallback() { if(loop) decoder->Rewind(); // if loop -> rewind and fill the buffer more - else if(buffer_pos) + else if(buffer_pos) break; // has data in buffer -> play the buffer else buffer_eof = true; // no data in buffer -> return EOF @@ -420,7 +420,7 @@ void GuiSound::DecoderCallback() } void GuiSound::PlayerCallback() { - if(buffer_eof) // if EOF + if(buffer_eof) // if EOF { if(ASND_TestPointer(voice, play_buffer[(buffer_nr+2)%3])==0) // test prev. Buffer Stop(); @@ -429,7 +429,7 @@ void GuiSound::PlayerCallback() { if(ASND_AddVoice(voice, play_buffer[buffer_nr], buffer_pos)==SND_OK) // add buffer { - // next buffer + // next buffer buffer_nr = (buffer_nr+1)%3; buffer_pos = 0; buffer_ready= false; diff --git a/source/menu.cpp b/source/menu.cpp index 215bf1b8..ee849e29 100644 --- a/source/menu.cpp +++ b/source/menu.cpp @@ -182,7 +182,7 @@ static void * UpdateGUI (void *arg) { * Startup GUI threads ***************************************************************************/ void InitGUIThreads() { - LWP_CreateThread(&guithread, UpdateGUI, NULL, NULL, 0, LWP_PRIO_HIGHEST); + LWP_CreateThread(&guithread, UpdateGUI, NULL, NULL, 32768, LWP_PRIO_HIGHEST); InitProgressThread(); InitNetworkThread(); diff --git a/source/network/networkops.cpp b/source/network/networkops.cpp index a718e638..7c0837d7 100644 --- a/source/network/networkops.cpp +++ b/source/network/networkops.cpp @@ -391,7 +391,7 @@ static void * networkinitcallback(void *arg) { * InitNetworkThread with priority 0 (idle) ***************************************************************************/ void InitNetworkThread() { - LWP_CreateThread (&networkthread, networkinitcallback, NULL, NULL, 0, 0); + LWP_CreateThread (&networkthread, networkinitcallback, NULL, NULL, 16384, 0); } /**************************************************************************** diff --git a/source/patches/patchcode.c b/source/patches/patchcode.c index 9c49f322..f40ee279 100644 --- a/source/patches/patchcode.c +++ b/source/patches/patchcode.c @@ -26,6 +26,8 @@ #include "usbloader/apploader.h" #include "patchcode.h" +#include "settings/cfg.h" +#include "listfiles.h" //#include "sd.h" //#include "fwrite_patch.h" @@ -192,6 +194,16 @@ static const u32 newpatch002[3] = { bool dogamehooks(void *addr, u32 len) //--------------------------------------------------------------------------------- { + //this is temporary since the screen freezes without a file loaded + char filepath[150]; + char GameId[10]; + memcpy(GameId, (u8 *) 0x80000000, 6); + GameId[6] = 0; + sprintf(filepath, "%s%s.gct", Settings.Cheatcodespath, GameId); + + if(!checkfile(filepath)) + return false; + //TODO for oggzee: when using Ocarina check if a hook as patched hooktype = 1; // TODO for oggzee: Create an option for hooktype diff --git a/source/patches/wip.c b/source/patches/wip.c index 2ec25094..5b8702f9 100644 --- a/source/patches/wip.c +++ b/source/patches/wip.c @@ -1,128 +1,134 @@ -#include -#include -#include -#include - -#include "settings/cfg.h" - -u32 doltableoffset[64]; -u32 doltablelength[64]; -u32 doltableentries; - -void wipreset() -{ - doltableentries = 0; -} - -void wipregisteroffset(u32 dst, u32 len) -{ - doltableoffset[doltableentries] = dst; - doltablelength[doltableentries] = len; - doltableentries++; -} - -void patchu8(u32 offset, u8 value) -{ - u32 i = 0; - u32 tempoffset = 0; - - while ((doltablelength[i] <= offset-tempoffset) && (i+1 < doltableentries)) - { - tempoffset+=doltablelength[i]; - i++; - } - if (offset-tempoffset < doltablelength[i]) - { - *(u8 *)(offset-tempoffset+doltableoffset[i]) = value; - } -} - -void wipparsebuffer(u8 *buffer, u32 length) -// The buffer needs a 0 at the end to properly terminate the string functions -{ - u32 pos = 0; - u32 offset; - char buf[10]; - - while (pos < length) - { - if ( *(char *)(buffer + pos) != '#' && *(char *)(buffer + pos) != ';' && *(char *)(buffer + pos) != 10 && *(char *)(buffer + pos) != 13 && *(char *)(buffer + pos) != 32 && *(char *)(buffer + pos) != 0 ) - { - memcpy(buf, (char *)(buffer + pos), 8); - buf[8] = 0; - offset = strtol(buf,NULL,16); - - pos += (u32)strchr((char *)(buffer + pos), 32)-(u32)(buffer + pos) + 1; - pos += (u32)strchr((char *)(buffer + pos), 32)-(u32)(buffer + pos) + 1; - - while (*(char *)(buffer + pos) != 10 && *(char *)(buffer + pos) != 13 && *(char *)(buffer + pos) != 0) - { - memcpy(buf, (char *)(buffer + pos), 2); - buf[2] = 0; - - patchu8(offset, strtol(buf,NULL,16)); - offset++; - pos +=2; - } - } - if (strchr((char *)(buffer + pos), 10) == NULL) - { - return; - } else - { - pos += (u32)strchr((char *)(buffer + pos), 10)-(u32)(buffer + pos) + 1; - } - } -} - -u32 do_wip_code(u8 *gameid) -{ - FILE *fp; - u32 filesize; - char filepath[150]; - memset(filepath, 0, 150); - u8 *wipCode; - - sprintf(filepath, "%s%6s", Settings.WipCodepath, gameid); - filepath[strlen(Settings.WipCodepath)+6] = '.'; - filepath[strlen(Settings.WipCodepath)+7] = 'w'; - filepath[strlen(Settings.WipCodepath)+8] = 'i'; - filepath[strlen(Settings.WipCodepath)+9] = 'p'; - - fp = fopen(filepath, "rb"); - if (!fp) { - memset(filepath, 0, 150); - sprintf(filepath, "%s%3s", Settings.WipCodepath, gameid + 1); - filepath[strlen(Settings.WipCodepath)+3] = '.'; - filepath[strlen(Settings.WipCodepath)+4] = 'w'; - filepath[strlen(Settings.WipCodepath)+5] = 'i'; - filepath[strlen(Settings.WipCodepath)+6] = 'p'; - fp = fopen(filepath, "rb"); - - if (!fp) { - return -1; - } - } - - if (fp) { - u32 ret = 0; - - fseek(fp, 0, SEEK_END); - filesize = ftell(fp); - - wipCode = malloc(filesize + 1); - wipCode[filesize] = 0; // Wip code functions need a 0 termination - - fseek(fp, 0, SEEK_SET); - ret = fread(wipCode, 1, filesize, fp); - fclose(fp); - - if (ret == filesize) - { - // Apply wip patch - wipparsebuffer(wipCode, filesize + 1); - return 0; - } - } - return -2; -} +#include +#include +#include +#include +#include "gecko.h" + +#include "settings/cfg.h" + +typedef struct +{ + u32 offset; + u32 srcaddress; + u32 dstaddress; +} WIP_Code; + +static WIP_Code * CodeList = NULL; +static u32 CodesCount = 0; +static u32 ProcessedLength = 0; +static u32 Counter = 0; + +void do_wip_code(u8 * dst, u32 len) +{ + if(!CodeList) + return; + + if(Counter < 3) + { + Counter++; + return; + } + + int i = 0; + int n = 0; + int offset = 0; + + for(i = 0; i < CodesCount; i++) + { + for(n = 0; n < 4; n++) + { + offset = CodeList[i].offset+n-ProcessedLength; + + if(offset < 0 || offset >= len) + continue; + + if(dst[offset] == ((u8 *)&CodeList[i].srcaddress)[n]) + { + dst[offset] = ((u8 *)&CodeList[i].dstaddress)[n]; + gprintf("WIP: %08X Address Patched.\n", CodeList[i].offset+n); + } + else + { + gprintf("WIP: %08X Address does not match with WIP entrie.\n", CodeList[i].offset+n); + gprintf("Destination: %02X | Should be: %02X.\n", dst[offset], ((u8 *)&CodeList[i].srcaddress)[n]); + } + } + } + ProcessedLength += len; + Counter++; +} + +void wip_reset_counter() +{ + ProcessedLength = 0; + //alternative dols don't need a skip. only main.dol. + Counter = 3; +} + +void free_wip() +{ + if(CodeList) + free(CodeList); + CodeList = NULL; + CodesCount = 0; + ProcessedLength = 0; +} + +int load_wip_code(u8 *gameid) +{ + char filepath[150]; + char GameID[8]; + memset(GameID, 0, sizeof(GameID)); + memcpy(GameID, gameid, 6); + snprintf(filepath, sizeof(filepath), "%s%s.wip", Settings.WipCodepath, GameID); + + FILE * fp = fopen(filepath, "rb"); + if (!fp) + { + memset(GameID, 0, sizeof(GameID)); + memcpy(GameID, gameid, 3); + snprintf(filepath, sizeof(filepath), "%s%s.wip", Settings.WipCodepath, GameID); + fp = fopen(filepath, "rb"); + } + + if (!fp) + return -1; + + char line[255]; + gprintf("\nLoading WIP code from %s.\n", filepath); + + while (fgets(line, sizeof(line), fp)) + { + if (line[0] == '#') continue; + + if(strlen(line) < 26) continue; + + u32 offset = (u32) strtoul(line, NULL, 16); + u32 srcaddress = (u32) strtoul(line+9, NULL, 16); + u32 dstaddress = (u32) strtoul(line+18, NULL, 16); + + if(!CodeList) + CodeList = malloc(sizeof(WIP_Code)); + + WIP_Code * tmp = realloc(CodeList, (CodesCount+1)*sizeof(WIP_Code)); + if(!tmp) + { + if(CodeList) + free(CodeList); + CodeList = NULL; + fclose(fp); + return -1; + } + + CodeList = tmp; + + CodeList[CodesCount].offset = offset; + CodeList[CodesCount].srcaddress = srcaddress; + CodeList[CodesCount].dstaddress = dstaddress; + CodesCount++; + } + fclose(fp); + gprintf("\n"); + + return 0; +} diff --git a/source/patches/wip.h b/source/patches/wip.h index 54d82845..3788f25a 100644 --- a/source/patches/wip.h +++ b/source/patches/wip.h @@ -1,6 +1,9 @@ -#ifndef __WIP_H__ -#define __WIP_H__ - -u32 do_wip_code(u8 *gameid); - -#endif //__WIP_H__ +#ifndef __WIP_H__ +#define __WIP_H__ + +int load_wip_code(u8 *gameid); +void do_wip_code(u8 * dst, u32 len); +void wip_reset_counter(); +void free_wip(); + +#endif //__WIP_H__ diff --git a/source/prompts/ProgressWindow.cpp b/source/prompts/ProgressWindow.cpp index 9a1610a9..4733be17 100644 --- a/source/prompts/ProgressWindow.cpp +++ b/source/prompts/ProgressWindow.cpp @@ -402,7 +402,7 @@ void ShowProgress(const char *title, const char *msg1, char *dynmsg2, f32 done, * Startup Progressthread in idle prio ***************************************************************************/ void InitProgressThread() { - LWP_CreateThread(&progressthread, ProgressThread, NULL, NULL, 0, 80); + LWP_CreateThread(&progressthread, ProgressThread, NULL, NULL, 16384, 80); } /**************************************************************************** diff --git a/source/usbloader/alternatedol.c b/source/usbloader/alternatedol.c index 236eeab1..1727e393 100644 --- a/source/usbloader/alternatedol.c +++ b/source/usbloader/alternatedol.c @@ -199,13 +199,13 @@ u32 Load_Dol_from_disc(u32 doloffset, u8 videoSelected, u8 patchcountrystring, u } if (!mountMethod)ret = WDVD_Read(dol_header, sizeof(dolheader), (doloffset<<2)); - + else{ dvddone = 0; ret = bwDVD_LowRead(dol_header, sizeof(dolheader), doloffset, __dvd_readidcb); while(ret>=0 && dvddone==0); } - + entrypoint = load_dol_start(dol_header); if (entrypoint == 0) { @@ -216,13 +216,11 @@ u32 Load_Dol_from_disc(u32 doloffset, u8 videoSelected, u8 patchcountrystring, u void *offset; u32 pos; u32 len; - + while (load_dol_image_modified(&offset, &pos, &len)) { if (len != 0) { ret = WDVD_Read(offset, len, (doloffset<<2) + pos); - DCFlushRange(offset, len); - gamepatches(offset, len, videoSelected, patchcountrystring, vipatch, cheat); DCFlushRange(offset, len); diff --git a/source/usbloader/apploader.c b/source/usbloader/apploader.c index 4f7613c1..ae5e7cfc 100644 --- a/source/usbloader/apploader.c +++ b/source/usbloader/apploader.c @@ -302,14 +302,14 @@ void gamepatches(void * dst, int len, u8 videoSelected, u8 patchcountrystring, u Search_and_patch_Video_Modes(dst, len, table); } - dogamehooks(dst,len); - - //if (vipatch)//moved to degamehooks() - // vidolpatcher(dst,len); + if(cheat) + dogamehooks(dst,len); + if (vipatch) + vidolpatcher(dst,len); /*LANGUAGE PATCH - FISHEARS*/ - //langpatcher(dst,len);//moved to degamehooks() + langpatcher(dst,len); /*Thanks to WiiPower*/ if (patchcountrystring == 1) @@ -317,15 +317,10 @@ void gamepatches(void * dst, int len, u8 videoSelected, u8 patchcountrystring, u NewSuperMarioBrosPatch(dst, len); - do_wip_code((u8 *)0x80000000); + do_wip_code((u8 *) dst, len); - - //if(Settings.anti002fix == on) if (fix002 == 2) Anti_002_fix(dst, len); - - //patchdebug(dst, len); - } s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol, u32 alternatedoloffset) { @@ -383,7 +378,6 @@ s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8 WDVD_Read(dst, len, (u64)(offset << 2)); gamepatches(dst, len, videoSelected, patchcountrystring, vipatch, cheat); - DCFlushRange(dst, len); } @@ -392,6 +386,7 @@ s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8 /** Load alternate dol if set **/ if (alternatedol == 1) { // gprintf("\n\talt dol from FAT"); + wip_reset_counter(); void *dolbuffer; int dollen; @@ -399,8 +394,6 @@ s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8 if (dolloaded) { Remove_001_Protection(dolbuffer, dollen); - DCFlushRange(dolbuffer, dollen); - gamepatches(dolbuffer, dollen, videoSelected, patchcountrystring, vipatch, cheat); DCFlushRange(dolbuffer, dollen); @@ -411,10 +404,10 @@ s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8 if(dolbuffer) free(dolbuffer); - - } else if (alternatedol == 2) { -// gprintf("\n\talt dol from WBFS"); - + } + else if (alternatedol == 2) + { + wip_reset_counter(); FST_ENTRY *fst = (FST_ENTRY *)*(u32 *)0x80000038; *entry = (entry_point) Load_Dol_from_disc(fst[alternatedoloffset].fileoffset, videoSelected, patchcountrystring, vipatch, cheat); diff --git a/source/usbloader/disc.c b/source/usbloader/disc.c index 9446b441..964e76de 100644 --- a/source/usbloader/disc.c +++ b/source/usbloader/disc.c @@ -6,6 +6,7 @@ #include #include "patches/fst.h" +#include "patches/wip.h" #include "apploader.h" #include "disc.h" #include "video.h" @@ -287,6 +288,8 @@ s32 Disc_BootPartition(u64 offset, u8 videoselected, u8 cheat, u8 vipatch, u8 pa memset(gameid, 0, 8); memcpy(gameid, (char*)Disc_ID, 6); + load_wip_code((u8 *) &gameid); + /* Setup low memory */ __Disc_SetLowMem(); @@ -295,9 +298,12 @@ s32 Disc_BootPartition(u64 offset, u8 videoselected, u8 cheat, u8 vipatch, u8 pa if (ret < 0) return ret; + free_wip(); + bool cheatloaded = false; - if (cheat == 1) { + if (cheat) + { /* OCARINA STUFF - FISHEARS*/ if(ocarina_load_code((u8 *) gameid) > 0) {