* turn off some debug output

* change returnTo patch a bit.  now it can be run on dol sections instead of the whole thing at once.
* apply the patch for alt dols
* only apply patches to main.dol if we aren't booting an alt dol
This commit is contained in:
giantpune 2010-09-30 04:24:17 +00:00
parent ac56e5ec10
commit 74fa0a40be
12 changed files with 142 additions and 154 deletions

View File

@ -2,8 +2,8 @@
<app version="1">
<name> USB Loader GX</name>
<coder>USB Loader GX Team</coder>
<version>1.0 r982</version>
<release_date>201009291737</release_date>
<version>1.0 r983</version>
<release_date>201009300328</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.

View File

@ -149,7 +149,7 @@ int main(int argc, char *argv[])
SetupDefaultFont(fontPath);
free(fontPath);
gprintf("\n\tEnd of Main()");
//gprintf("\tEnd of Main()\n");
InitGUIThreads();
MainMenu( MENU_CHECK);
return 0;

View File

@ -16,7 +16,7 @@ extern char headlessID[8];
***************************************************************************/
int MenuCheck()
{
gprintf("\nMenuCheck()");
gprintf("MenuCheck()\n");
int menu = MENU_NONE;
int i = 0;
int choice;

View File

@ -4,7 +4,7 @@
#define ALIGNED(x) __attribute__((aligned(x)))
#define DEBUG_MLOAD
//#define DEBUG_MLOAD
/* Used for Hermes NAND emulation */
int global_mount;

View File

@ -267,142 +267,138 @@ void VideoModePatcher(u8 * dst, int len, u8 videoSelected)
}
//giantpune's magic super patch to return to channels
bool PatchReturnTo(void *Address, int Size, u32 id)
static u32 ad[ 4 ] = { 0, 0, 0, 0 };//these variables are global on the off chance the different parts needed
static u8 found = 0; //to find in the dol are found in different sections of the dol
static u8 patched = 0;
bool PatchReturnTo( void *Address, int Size, u32 id )
{
if (!id) return 0;
if( !id || patched )
return 0;
//gprintf("PatchReturnTo( %p, %08x, %08x )\n", Address, Size, id );
//new __OSLoadMenu() (SM2.0 and higher)
u8 SearchPattern[12] = { 0x38, 0x80, 0x00, 0x02, 0x38, 0x60, 0x00, 0x01, 0x38, 0xa0, 0x00, 0x00 };
u8 SearchPattern[ 12 ] = { 0x38, 0x80, 0x00, 0x02, 0x38, 0x60, 0x00, 0x01, 0x38, 0xa0, 0x00, 0x00 }; //li r4,2
//li r3,1
//li r5,0
//old _OSLoadMenu() (used in launch games)
u8 SearchPatternB[12] = { 0x38, 0xC0, 0x00, 0x02, 0x38, 0xA0, 0x00, 0x01, 0x38, 0xE0, 0x00, 0x00 };
u8 SearchPatternB[ 12 ] = { 0x38, 0xC0, 0x00, 0x02, 0x38, 0xA0, 0x00, 0x01, 0x38, 0xE0, 0x00, 0x00 }; //li r6,2
//li r5,1
//li r7,0
//identifier for the safe place
u8 SearchPattern2[12] = { 0x4D, 0x65, 0x74, 0x72, 0x6F, 0x77, 0x65, 0x72, 0x6B, 0x73, 0x20, 0x54 };
u8 SearchPattern2[ 12 ] = { 0x4D, 0x65, 0x74, 0x72, 0x6F, 0x77, 0x65, 0x72, 0x6B, 0x73, 0x20, 0x54 }; //"Metrowerks T"
int found = 0;
int patched = 0;
u8 oldSDK = 0;
u32 ad[4] = { 0, 0, 0, 0 };
found = 0;
void *Addr = Address;
void *Addr_end = Address + Size;
void *Addr_end = Address+Size;
while (Addr <= Addr_end - 12)
{
//find a safe place or the patch to hang out
if (!ad[3] && memcmp(Addr, SearchPattern2, 12) == 0)
{
ad[3] = (u32) Addr + 0x30;
//gprintf("found a safe place @ %08x\n", ad[ 3 ]);
//hexdump( Addr, 0x50 );
}
//find __OSLaunchMenu() and remember some addresses in it
else if (memcmp(Addr, SearchPattern, 12) == 0)
{
ad[found++] = (u32) Addr;
}
else if (ad[0] && memcmp(Addr, SearchPattern, 8) == 0) //after the first match is found, only search the first 8 bytes for the other 2
{
if (!ad[1])
ad[found++] = (u32) Addr;
else if (!ad[2]) ad[found++] = (u32) Addr;
if (found >= 3) break;
}
Addr += 4;
while (Addr <= Addr_end - 12 ) {
//find a safe place or the patch to hang out
if ( ! ad[ 3 ] && memcmp( Addr, SearchPattern2, 12 ) == 0 ) {
ad[ 3 ] = (u32)Addr + 0x30;
}
//find __OSLaunchMenu() and remember some addresses in it
else if ( memcmp( Addr, SearchPattern, 12 )==0 ) {
ad[ found++ ] = (u32)Addr;
}
else if ( ad[ 0 ] && memcmp( Addr, SearchPattern, 8 )==0 ) //after the first match is found, only search the first 8 bytes for the other 2
{
if( !ad[ 1 ] ) ad[ found++ ] = (u32)Addr;
else if( !ad[ 2 ] ) ad[ found++ ] = (u32)Addr;
if( found >= 3 )break;
}
Addr += 4;
}
//check for the older-ass version of the SDK
if (found < 3 && ad[3])
if( found < 3 && ad[ 3 ] )
{
Addr = Address;
ad[0] = 0;
ad[1] = 0;
ad[2] = 0;
found = 0;
oldSDK = 1;
Addr = Address;
ad[ 0 ] = 0; ad[ 1 ] = 0;
ad[ 2 ] = 0;
found = 0;
oldSDK = 1;
while (Addr <= Addr_end - 12)
{
//find __OSLaunchMenu() and remember some addresses in it
if (memcmp(Addr, SearchPatternB, 12) == 0)
{
ad[found++] = (u32) Addr;
}
else if (ad[0] && memcmp(Addr, SearchPatternB, 8) == 0) //after the first match is found, only search the first 8 bytes for the other 2
{
if (!ad[1])
ad[found++] = (u32) Addr;
else if (!ad[2]) ad[found++] = (u32) Addr;
if (found >= 3) break;
}
Addr += 4;
}
while (Addr <= Addr_end - 12 ) {
//find __OSLaunchMenu() and remember some addresses in it
if ( memcmp( Addr, SearchPatternB, 12 )==0 ) {
ad[ found++ ] = (u32)Addr;
}
else if ( ad[ 0 ] && memcmp( Addr, SearchPatternB, 8 ) == 0 ) //after the first match is found, only search the first 8 bytes for the other 2
{
if( !ad[ 1 ] ) ad[ found++ ] = (u32)Addr;
else if( !ad[ 2 ] ) ad[ found++ ] = (u32)Addr;
if( found >= 3 )break;
}
Addr += 4;
}
}
//if the function is found and if it is not too far into the main.dol
if (found == 3 && (ad[2] - ad[3] < 0x1000001) && ad[3])
//if the function is found
if( found == 3 && ad[ 3 ] )
{
//gprintf("patch __OSLaunchMenu( 0x00010001, 0x%08x )\n", id);
u32 nop = 0x60000000;
//gprintf("patch __OSLaunchMenu( 0x00010001, 0x%08x )\n", id);
u32 nop = 0x60000000;
//the magic that writes the TID to the registers
u8 jump[20] = { 0x3C, 0x60, 0x00, 0x01, 0x60, 0x63, 0x00, 0x01, 0x3C, 0x80, 0x4A, 0x4F, 0x60, 0x84, 0x44, 0x49,
0x4E, 0x80, 0x00, 0x20 };
if (oldSDK)
{
jump[1] = 0xA0; //3CA00001 60A50001
jump[5] = 0xA5; //3CC04A4F 60C64449
jump[9] = 0xC0;
jump[13] = 0xC6;
}
//patch the thing to use the new TID
jump[10] = (u8) (id >> 24);
jump[11] = (u8) (id >> 16);
jump[14] = (u8) (id >> 8);
jump[15] = (u8) id;
//the magic that writes the TID to the registers
u8 jump[ 20 ] = { 0x3C, 0x60, 0x00, 0x01, //lis r3,1
0x60, 0x63, 0x00, 0x01, //ori r3,r3,1
0x3C, 0x80, (u8)( id >> 24 ), (u8)( id >> 16 ), //lis r4,(u16)(tid >> 16)
0x60, 0x84, (u8)( id >> 8 ), (u8)id, //ori r4,r4,(u16)(tid)
0x4E, 0x80, 0x00, 0x20 }; //blr
void* addr = (u32*) ad[3];
if( oldSDK )
{
jump[ 1 ] = 0xA0; //3CA00001 //lis r5,1
jump[ 5 ] = 0xA5; //60A50001 //ori r5,r5,1
jump[ 9 ] = 0xC0; //3CC0AF1B //lis r6,(u16)(tid >> 16)
jump[ 13 ] = 0xC6;//60C6F516 //ori r6,r6,(u16)(tid)
}
//write new stuff to memory main.dol in a unused part of the main.dol
memcpy(addr, jump, sizeof(jump));
void* addr = (u32*)ad[ 3 ];
//ES_GetTicketViews()
u32 newval = (ad[3] - ad[0]);
newval &= 0x03FFFFFC;
newval |= 0x48000001;
addr = (u32*) ad[0];
memcpy(addr, &newval, sizeof(u32));
memcpy(addr + 4, &nop, sizeof(u32));
//gprintf("\t%p -> %08x\n", addr, newval );
//write new stuff to in a unused part of the main.dol
memcpy( addr, jump, sizeof( jump ) );
//ES_GetTicketViews() again
newval = (ad[3] - ad[1]);
newval &= 0x03FFFFFC;
newval |= 0x48000001;
addr = (u32*) ad[1];
memcpy(addr, &newval, sizeof(u32));
memcpy(addr + 4, &nop, sizeof(u32));
//gprintf("\t%p -> %08x\n", addr, newval );
//ES_GetTicketViews()
u32 newval = ( ad[ 3 ] - ad[ 0 ] );
newval &= 0x03FFFFFC;
newval |= 0x48000001;
addr = (u32*)ad[ 0 ];
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
//gprintf("\t%08x -> %08x\n", addr, newval );
//ES_LaunchTitle()
newval = (ad[3] - ad[2]);
newval &= 0x03FFFFFC;
newval |= 0x48000001;
addr = (u32*) ad[2];
memcpy(addr, &newval, sizeof(u32));
memcpy(addr + 4, &nop, sizeof(u32));
//gprintf("\t%p -> %08x\n", addr, newval );
//ES_GetTicketViews() again
newval = ( ad[ 3 ] - ad[ 1 ] );
newval &= 0x03FFFFFC;
newval |= 0x48000001;
addr = (u32*)ad[ 1 ];
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
//gprintf("\t%08x -> %08x\n", addr, newval );
patched = 1;
//ES_LaunchTitle()
newval = ( ad[ 3 ] - ad[ 2 ] );
newval &= 0x03FFFFFC;
newval |= 0x48000001;
addr = (u32*)ad[ 2 ];
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
//gprintf("\t%08x -> %08x\n", addr, newval );
patched = 1;
}
else
/*else
{
gprintf("not patched\n");
gprintf("found %d addresses\n", found);
int i;
for (i = 0; i < 4; i++)
gprintf("ad[ %d ]: %08x\n", i, ad[i]);
gprintf("offset : %08x\n", ad[2] - ad[3]);
gprintf("not patched\n");
gprintf("found %d addresses\n", found);
int i;
for( i = 0; i< 4; i++)
gprintf("ad[ %d ]: %08x\n", i, ad[ i ] );
gprintf("offset : %08x\n", ad[ 2 ] - ad[ 3 ] );
}
}*/
return patched;
}

View File

@ -215,7 +215,7 @@ void CGameStatistics::ParseLine(char *line)
this->TrimLine(name, LinePtr, sizeof(name));
this->TrimLine(value, eq + 1, sizeof(value));
gprintf("\nID: %s, Name = %s, Value = %s\n", GameID, name, value);
//gprintf("ID: %s, Name = %s, Value = %s\n", GameID, name, value);
SetSetting(NewGame, name, value);
LinePtr = strchr(LinePtr, ';');

View File

@ -106,7 +106,7 @@ typedef struct _dolheader
static dolheader *dolfile;
u32 load_dol_image(void *dolstart, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat, u8 fix002)
u32 load_dol_image(void *dolstart, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat, u32 returnTo, u8 fix002)
{
u32 i;
@ -121,7 +121,7 @@ u32 load_dol_image(void *dolstart, u8 videoSelected, u8 patchcountrystring, u8 v
ICInvalidateRange((void *) dolfile->text_start[i], dolfile->text_size[i]);
memmove((void *) dolfile->text_start[i], dolstart + dolfile->text_pos[i], dolfile->text_size[i]);
gamepatches((void *) dolfile->text_start[i], dolfile->text_size[i], videoSelected, patchcountrystring,
vipatch, cheat, fix002);
vipatch, cheat, returnTo, fix002);
Remove_001_Protection((void *) dolfile->data_start[i], dolfile->data_size[i]);
}
@ -131,7 +131,7 @@ u32 load_dol_image(void *dolstart, u8 videoSelected, u8 patchcountrystring, u8 v
memmove((void *) dolfile->data_start[i], dolstart + dolfile->data_pos[i], dolfile->data_size[i]);
gamepatches((void *) dolfile->data_start[i], dolfile->data_size[i], videoSelected, patchcountrystring,
vipatch, cheat, fix002);
vipatch, cheat, returnTo, fix002);
Remove_001_Protection((void *) dolfile->data_start[i], dolfile->data_size[i]);
DCFlushRangeNoSync((void *) dolfile->data_start[i], dolfile->data_size[i]);
}
@ -224,7 +224,7 @@ void __dvd_readidcb(s32 result)
{
dvddone = result;
}
u32 Load_Dol_from_disc(u32 doloffset, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat, u8 fix002)
u32 Load_Dol_from_disc(u32 doloffset, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat, u32 returnTo, u8 fix002)
{
int ret;
void *dol_header;
@ -265,7 +265,7 @@ u32 Load_Dol_from_disc(u32 doloffset, u8 videoSelected, u8 patchcountrystring, u
{
ret = WDVD_Read(offset, len, (doloffset << 2) + pos);
gamepatches(offset, len, videoSelected, patchcountrystring, vipatch, cheat, fix002);
gamepatches(offset, len, videoSelected, patchcountrystring, vipatch, cheat, returnTo, fix002);
Remove_001_Protection(offset, len);

View File

@ -9,10 +9,10 @@ extern "C"
/* not the full path is needed here, the path where the dol is */
bool Load_Dol(void **buffer, int* dollen, char * path, u8 videoSelected, u8 patchcountrystring, u8 vipatch,
u8 cheat);
u8 cheat, u32 returnTo);
bool Remove_001_Protection(void *Address, int Size);
u32 load_dol_image(void * dolstart);
u32 Load_Dol_from_disc(u32 doloffset, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat);
u32 Load_Dol_from_disc(u32 doloffset, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat, u32 returnTo);
#ifdef __cplusplus
}

View File

@ -33,25 +33,30 @@ static u8 *appldr = (u8 *) 0x81200000;
/* Variables */
static u32 buffer[0x20] ATTRIBUTE_ALIGN( 32 );
void gamepatches(u8 * dst, int len, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat, u8 fix002)
void gamepatches( u8 * dst, int len, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat, u32 returnTo, u8 fix002 )
{
VideoModePatcher(dst, len, videoSelected);
VideoModePatcher( dst, len, videoSelected );
if (cheat) dogamehooks(dst, len);
if ( cheat )
dogamehooks( dst, len );
if (vipatch) vidolpatcher(dst, len);
if ( vipatch )
vidolpatcher( dst, len );
/*LANGUAGE PATCH - FISHEARS*/
langpatcher(dst, len);
langpatcher( dst, len );
/*Thanks to WiiPower*/
if (patchcountrystring == 1) PatchCountryStrings(dst, len);
if ( patchcountrystring == 1 ) PatchCountryStrings( dst, len );
NSMBPatch(dst, len);
NSMBPatch( dst, len );
do_wip_code((u8 *) dst, len);
do_wip_code( ( u8 * ) dst, len );
if (fix002 == 2) Anti_002_fix(dst, len);
if ( fix002 == 2 )
Anti_002_fix( dst, len );
PatchReturnTo( dst, len, returnTo );
}
s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected, u8 vipatch, u8 patchcountrystring,
@ -96,9 +101,6 @@ s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected
*(u32 *) 0x80003188 = *(u32 *) 0x80003140;
}
u32 dolStart = 0x90000000;
u32 dolEnd = 0x0;
for (;;)
{
void *dst = NULL;
@ -111,20 +113,10 @@ s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected
/* Read data from DVD */
WDVD_Read(dst, len, (u64) (offset << 2));
gamepatches(dst, len, videoSelected, patchcountrystring, vipatch, cheat, fix002);
DCFlushRange(dst, len);
if( !alternatedol )
gamepatches(dst, len, videoSelected, patchcountrystring, vipatch, cheat, returnTo, fix002 );
if ((u32) dst < dolStart) dolStart = (u32) dst;
if ((u32) dst + len > dolEnd) dolEnd = (u32) dst + len;
}
//this patch should be run on the entire dol at 1 time
if (!alternatedol && returnTo)
{
if (PatchReturnTo((u32*) dolStart, dolEnd - dolStart, returnTo))
{
DCFlushRange((u32*) dolStart, dolEnd - dolStart);
}
DCFlushRange(dst, len);
}
*entry = appldr_final();
@ -136,7 +128,7 @@ s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected
void *dolbuffer = NULL;
int dollen = 0;
bool dolloaded = Load_Dol(&dolbuffer, &dollen, dolpath, videoSelected, patchcountrystring, vipatch, cheat);
bool dolloaded = Load_Dol(&dolbuffer, &dollen, dolpath, videoSelected, patchcountrystring, vipatch, cheat, returnTo);
if (dolloaded)
{
*entry = (entry_point) load_dol_image(dolbuffer);
@ -150,7 +142,7 @@ s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected
FST_ENTRY *fst = (FST_ENTRY *) *(u32 *) 0x80000038;
*entry = (entry_point) Load_Dol_from_disc(fst[alternatedoloffset].fileoffset, videoSelected,
patchcountrystring, vipatch, cheat);
patchcountrystring, vipatch, cheat, returnTo);
if (*entry == 0) SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}

View File

@ -12,7 +12,7 @@ extern "C"
/* Prototypes */
s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected, u8 vipatch,
u8 patchcountrystring, u8 error002fix, u8 alternatedol, u32 alternatedoloffset, u32 returnTo, u8 fix002);
void gamepatches(u8 * dst, int len, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat, u8 fix002);
void gamepatches( u8 * dst, int len, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat, u32 returnTo, u8 fix002 );
#ifdef __cplusplus
}

View File

@ -164,7 +164,7 @@ void __Disc_SetVMode(u8 videoselected)
if (vmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
}
gprintf("\nVideo mode - %s", ((progressive) ? "progressive" : "interlaced"));
gprintf("Video mode - %s\n", ((progressive) ? "progressive" : "interlaced"));
}

View File

@ -15,7 +15,7 @@
#include "gecko.h"
Wbfs *current = NULL;
#define DEBUG_WBFS
//#define DEBUG_WBFS
/* WBFS device */
s32 wbfsDev = WBFS_MIN_DEVICE;