*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">
<name> USB Loader GX</name>
<coder>USB Loader GX Team</coder>
<version>1.0 r931</version>
<release_date>201005290726</release_date>
<version>1.0 r932</version>
<release_date>201005290827</release_date>
<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.
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

@ -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);
}

View File

@ -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;

View File

@ -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();

View File

@ -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);
}
/****************************************************************************

View File

@ -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

View File

@ -1,128 +1,134 @@
#include <gccore.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#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 <gccore.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#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;
}

View File

@ -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__

View File

@ -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);
}
/****************************************************************************

View File

@ -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);

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);
}
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);

View File

@ -6,6 +6,7 @@
#include <wiiuse/wpad.h>
#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)
{