*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
This commit is contained in:
dimok321 2010-05-29 15:43:19 +00:00
parent 8a4e192022
commit f0ca11506b
13 changed files with 195 additions and 177 deletions

View File

@ -2,8 +2,8 @@
<app version="1"> <app version="1">
<name> USB Loader GX</name> <name> USB Loader GX</name>
<coder>USB Loader GX Team</coder> <coder>USB Loader GX Team</coder>
<version>1.0 r931</version> <version>1.0 r932</version>
<release_date>201005290726</release_date> <release_date>201005290827</release_date>
<short_description>Loads games from USB-devices</short_description> <short_description>Loads games from USB-devices</short_description>
<long_description>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. <long_description>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. The interactive GUI is completely controllable with WiiMote, Classic Controller or GC Controller.

File diff suppressed because one or more lines are too long

View File

@ -103,7 +103,7 @@ static u32 GuiImageAsyncThreadInit()
CanSleep = false; CanSleep = false;
LWP_MutexInit(&ListLock, false); LWP_MutexInit(&ListLock, false);
LWP_MutexInit(&InUseLock, false); LWP_MutexInit(&InUseLock, false);
LWP_CreateThread(&Thread, GuiImageAsyncThread, NULL, NULL, 0, 75); LWP_CreateThread(&Thread, GuiImageAsyncThread, NULL, NULL, 16384, 75);
// while(!CanSleep) // while(!CanSleep)
// usleep(20); // usleep(20);
} }

View File

@ -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) 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; voice = -1;
play_buffer[0] = (u8*)memalign(32, BUFFER_SIZE*3); // tripple-buffer first is played play_buffer[0] = (u8*)memalign(32, BUFFER_SIZE*3); // tripple-buffer first is played

View File

@ -182,7 +182,7 @@ static void * UpdateGUI (void *arg) {
* Startup GUI threads * Startup GUI threads
***************************************************************************/ ***************************************************************************/
void InitGUIThreads() { void InitGUIThreads() {
LWP_CreateThread(&guithread, UpdateGUI, NULL, NULL, 0, LWP_PRIO_HIGHEST); LWP_CreateThread(&guithread, UpdateGUI, NULL, NULL, 32768, LWP_PRIO_HIGHEST);
InitProgressThread(); InitProgressThread();
InitNetworkThread(); InitNetworkThread();

View File

@ -391,7 +391,7 @@ static void * networkinitcallback(void *arg) {
* InitNetworkThread with priority 0 (idle) * InitNetworkThread with priority 0 (idle)
***************************************************************************/ ***************************************************************************/
void InitNetworkThread() { void InitNetworkThread() {
LWP_CreateThread (&networkthread, networkinitcallback, NULL, NULL, 0, 0); LWP_CreateThread (&networkthread, networkinitcallback, NULL, NULL, 16384, 0);
} }
/**************************************************************************** /****************************************************************************

View File

@ -26,6 +26,8 @@
#include "usbloader/apploader.h" #include "usbloader/apploader.h"
#include "patchcode.h" #include "patchcode.h"
#include "settings/cfg.h"
#include "listfiles.h"
//#include "sd.h" //#include "sd.h"
//#include "fwrite_patch.h" //#include "fwrite_patch.h"
@ -192,6 +194,16 @@ static const u32 newpatch002[3] = {
bool dogamehooks(void *addr, u32 len) 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 //TODO for oggzee: when using Ocarina check if a hook as patched
hooktype = 1; // TODO for oggzee: Create an option for hooktype hooktype = 1; // TODO for oggzee: Create an option for hooktype

View File

@ -2,127 +2,133 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include "gecko.h"
#include "settings/cfg.h" #include "settings/cfg.h"
u32 doltableoffset[64]; typedef struct
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; u32 offset;
char buf[10]; u32 srcaddress;
u32 dstaddress;
} WIP_Code;
while (pos < length) static WIP_Code * CodeList = NULL;
{ static u32 CodesCount = 0;
if ( *(char *)(buffer + pos) != '#' && *(char *)(buffer + pos) != ';' && *(char *)(buffer + pos) != 10 && *(char *)(buffer + pos) != 13 && *(char *)(buffer + pos) != 32 && *(char *)(buffer + pos) != 0 ) static u32 ProcessedLength = 0;
{ static u32 Counter = 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; void do_wip_code(u8 * dst, u32 len)
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)
{ {
if(!CodeList)
return; return;
} else
if(Counter < 3)
{ {
pos += (u32)strchr((char *)(buffer + pos), 10)-(u32)(buffer + pos) + 1; Counter++;
} return;
}
} }
u32 do_wip_code(u8 *gameid) 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)
{ {
FILE *fp;
u32 filesize;
char filepath[150]; char filepath[150];
memset(filepath, 0, 150); char GameID[8];
u8 *wipCode; memset(GameID, 0, sizeof(GameID));
memcpy(GameID, gameid, 6);
sprintf(filepath, "%s%6s", Settings.WipCodepath, gameid); snprintf(filepath, sizeof(filepath), "%s%s.wip", 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';
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"); 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) { 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; return -1;
} }
CodeList = tmp;
CodeList[CodesCount].offset = offset;
CodeList[CodesCount].srcaddress = srcaddress;
CodeList[CodesCount].dstaddress = dstaddress;
CodesCount++;
} }
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); fclose(fp);
gprintf("\n");
if (ret == filesize)
{
// Apply wip patch
wipparsebuffer(wipCode, filesize + 1);
return 0; return 0;
} }
}
return -2;
}

View File

@ -1,6 +1,9 @@
#ifndef __WIP_H__ #ifndef __WIP_H__
#define __WIP_H__ #define __WIP_H__
u32 do_wip_code(u8 *gameid); int load_wip_code(u8 *gameid);
void do_wip_code(u8 * dst, u32 len);
void wip_reset_counter();
void free_wip();
#endif //__WIP_H__ #endif //__WIP_H__

View File

@ -402,7 +402,7 @@ void ShowProgress(const char *title, const char *msg1, char *dynmsg2, f32 done,
* Startup Progressthread in idle prio * Startup Progressthread in idle prio
***************************************************************************/ ***************************************************************************/
void InitProgressThread() { void InitProgressThread() {
LWP_CreateThread(&progressthread, ProgressThread, NULL, NULL, 0, 80); LWP_CreateThread(&progressthread, ProgressThread, NULL, NULL, 16384, 80);
} }
/**************************************************************************** /****************************************************************************

View File

@ -221,8 +221,6 @@ u32 Load_Dol_from_disc(u32 doloffset, u8 videoSelected, u8 patchcountrystring, u
if (len != 0) { if (len != 0) {
ret = WDVD_Read(offset, len, (doloffset<<2) + pos); ret = WDVD_Read(offset, len, (doloffset<<2) + pos);
DCFlushRange(offset, len);
gamepatches(offset, len, videoSelected, patchcountrystring, vipatch, cheat); gamepatches(offset, len, videoSelected, patchcountrystring, vipatch, cheat);
DCFlushRange(offset, len); DCFlushRange(offset, len);

View File

@ -302,14 +302,14 @@ void gamepatches(void * dst, int len, u8 videoSelected, u8 patchcountrystring, u
Search_and_patch_Video_Modes(dst, len, table); Search_and_patch_Video_Modes(dst, len, table);
} }
if(cheat)
dogamehooks(dst,len); dogamehooks(dst,len);
//if (vipatch)//moved to degamehooks() if (vipatch)
// vidolpatcher(dst,len); vidolpatcher(dst,len);
/*LANGUAGE PATCH - FISHEARS*/ /*LANGUAGE PATCH - FISHEARS*/
//langpatcher(dst,len);//moved to degamehooks() langpatcher(dst,len);
/*Thanks to WiiPower*/ /*Thanks to WiiPower*/
if (patchcountrystring == 1) if (patchcountrystring == 1)
@ -317,15 +317,10 @@ void gamepatches(void * dst, int len, u8 videoSelected, u8 patchcountrystring, u
NewSuperMarioBrosPatch(dst, len); NewSuperMarioBrosPatch(dst, len);
do_wip_code((u8 *)0x80000000); do_wip_code((u8 *) dst, len);
//if(Settings.anti002fix == on)
if (fix002 == 2) if (fix002 == 2)
Anti_002_fix(dst, len); 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) { 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)); WDVD_Read(dst, len, (u64)(offset << 2));
gamepatches(dst, len, videoSelected, patchcountrystring, vipatch, cheat); gamepatches(dst, len, videoSelected, patchcountrystring, vipatch, cheat);
DCFlushRange(dst, len); 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 **/ /** Load alternate dol if set **/
if (alternatedol == 1) { if (alternatedol == 1) {
// gprintf("\n\talt dol from FAT"); // gprintf("\n\talt dol from FAT");
wip_reset_counter();
void *dolbuffer; void *dolbuffer;
int dollen; int dollen;
@ -399,8 +394,6 @@ s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8
if (dolloaded) { if (dolloaded) {
Remove_001_Protection(dolbuffer, dollen); Remove_001_Protection(dolbuffer, dollen);
DCFlushRange(dolbuffer, dollen);
gamepatches(dolbuffer, dollen, videoSelected, patchcountrystring, vipatch, cheat); gamepatches(dolbuffer, dollen, videoSelected, patchcountrystring, vipatch, cheat);
DCFlushRange(dolbuffer, dollen); DCFlushRange(dolbuffer, dollen);
@ -411,10 +404,10 @@ s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8
if(dolbuffer) if(dolbuffer)
free(dolbuffer); free(dolbuffer);
}
} else if (alternatedol == 2) { else if (alternatedol == 2)
// gprintf("\n\talt dol from WBFS"); {
wip_reset_counter();
FST_ENTRY *fst = (FST_ENTRY *)*(u32 *)0x80000038; FST_ENTRY *fst = (FST_ENTRY *)*(u32 *)0x80000038;
*entry = (entry_point) Load_Dol_from_disc(fst[alternatedoloffset].fileoffset, videoSelected, patchcountrystring, vipatch, cheat); *entry = (entry_point) Load_Dol_from_disc(fst[alternatedoloffset].fileoffset, videoSelected, patchcountrystring, vipatch, cheat);

View File

@ -6,6 +6,7 @@
#include <wiiuse/wpad.h> #include <wiiuse/wpad.h>
#include "patches/fst.h" #include "patches/fst.h"
#include "patches/wip.h"
#include "apploader.h" #include "apploader.h"
#include "disc.h" #include "disc.h"
#include "video.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); memset(gameid, 0, 8);
memcpy(gameid, (char*)Disc_ID, 6); memcpy(gameid, (char*)Disc_ID, 6);
load_wip_code((u8 *) &gameid);
/* Setup low memory */ /* Setup low memory */
__Disc_SetLowMem(); __Disc_SetLowMem();
@ -295,9 +298,12 @@ s32 Disc_BootPartition(u64 offset, u8 videoselected, u8 cheat, u8 vipatch, u8 pa
if (ret < 0) if (ret < 0)
return ret; return ret;
free_wip();
bool cheatloaded = false; bool cheatloaded = false;
if (cheat == 1) { if (cheat)
{
/* OCARINA STUFF - FISHEARS*/ /* OCARINA STUFF - FISHEARS*/
if(ocarina_load_code((u8 *) gameid) > 0) if(ocarina_load_code((u8 *) gameid) > 0)
{ {