mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-22 11:19:17 +01:00
* 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:
parent
ac56e5ec10
commit
74fa0a40be
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -16,7 +16,7 @@ extern char headlessID[8];
|
||||
***************************************************************************/
|
||||
int MenuCheck()
|
||||
{
|
||||
gprintf("\nMenuCheck()");
|
||||
gprintf("MenuCheck()\n");
|
||||
int menu = MENU_NONE;
|
||||
int i = 0;
|
||||
int choice;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#define ALIGNED(x) __attribute__((aligned(x)))
|
||||
|
||||
#define DEBUG_MLOAD
|
||||
//#define DEBUG_MLOAD
|
||||
|
||||
/* Used for Hermes NAND emulation */
|
||||
int global_mount;
|
||||
|
@ -267,44 +267,45 @@ void VideoModePatcher(u8 * dst, int len, u8 videoSelected)
|
||||
}
|
||||
|
||||
//giantpune's magic super patch to return to channels
|
||||
|
||||
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;
|
||||
|
||||
while (Addr <= Addr_end - 12)
|
||||
{
|
||||
while (Addr <= Addr_end - 12 ) {
|
||||
//find a safe place or the patch to hang out
|
||||
if (!ad[3] && memcmp(Addr, SearchPattern2, 12) == 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if( !ad[ 1 ] ) ad[ found++ ] = (u32)Addr;
|
||||
else if( !ad[ 2 ] ) ad[ found++ ] = (u32)Addr;
|
||||
if( found >= 3 )break;
|
||||
}
|
||||
@ -314,23 +315,19 @@ bool PatchReturnTo(void *Address, int Size, u32 id)
|
||||
if( found < 3 && ad[ 3 ] )
|
||||
{
|
||||
Addr = Address;
|
||||
ad[0] = 0;
|
||||
ad[1] = 0;
|
||||
ad[ 0 ] = 0; ad[ 1 ] = 0;
|
||||
ad[ 2 ] = 0;
|
||||
found = 0;
|
||||
oldSDK = 1;
|
||||
|
||||
while (Addr <= Addr_end - 12)
|
||||
{
|
||||
while (Addr <= Addr_end - 12 ) {
|
||||
//find __OSLaunchMenu() and remember some addresses in it
|
||||
if (memcmp(Addr, SearchPatternB, 12) == 0)
|
||||
{
|
||||
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;
|
||||
if( !ad[ 1 ] ) ad[ found++ ] = (u32)Addr;
|
||||
else if( !ad[ 2 ] ) ad[ found++ ] = (u32)Addr;
|
||||
if( found >= 3 )break;
|
||||
}
|
||||
@ -338,31 +335,30 @@ bool PatchReturnTo(void *Address, int Size, u32 id)
|
||||
}
|
||||
}
|
||||
|
||||
//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;
|
||||
|
||||
//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 };
|
||||
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
|
||||
|
||||
if( oldSDK )
|
||||
{
|
||||
jump[1] = 0xA0; //3CA00001 60A50001
|
||||
jump[5] = 0xA5; //3CC04A4F 60C64449
|
||||
jump[9] = 0xC0;
|
||||
jump[13] = 0xC6;
|
||||
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)
|
||||
}
|
||||
//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;
|
||||
|
||||
void* addr = (u32*)ad[ 3 ];
|
||||
|
||||
//write new stuff to memory main.dol in a unused part of the main.dol
|
||||
//write new stuff to in a unused part of the main.dol
|
||||
memcpy( addr, jump, sizeof( jump ) );
|
||||
|
||||
//ES_GetTicketViews()
|
||||
@ -370,31 +366,31 @@ bool PatchReturnTo(void *Address, int Size, u32 id)
|
||||
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 );
|
||||
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
|
||||
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
|
||||
//gprintf("\t%08x -> %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));
|
||||
memcpy(addr + 4, &nop, sizeof(u32));
|
||||
//gprintf("\t%p -> %08x\n", addr, newval );
|
||||
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 );
|
||||
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);
|
||||
@ -403,6 +399,6 @@ bool PatchReturnTo(void *Address, int Size, u32 id)
|
||||
gprintf("ad[ %d ]: %08x\n", i, ad[ i ] );
|
||||
gprintf("offset : %08x\n", ad[ 2 ] - ad[ 3 ] );
|
||||
|
||||
}
|
||||
}*/
|
||||
return patched;
|
||||
}
|
||||
|
@ -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, ';');
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -33,13 +33,15 @@ 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 );
|
||||
|
||||
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 );
|
||||
@ -51,7 +53,10 @@ void gamepatches(u8 * dst, int len, u8 videoSelected, u8 patchcountrystring, u8
|
||||
|
||||
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);
|
||||
if( !alternatedol )
|
||||
gamepatches(dst, len, videoSelected, patchcountrystring, vipatch, cheat, returnTo, fix002 );
|
||||
|
||||
DCFlushRange(dst, len);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
*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);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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"));
|
||||
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "gecko.h"
|
||||
|
||||
Wbfs *current = NULL;
|
||||
#define DEBUG_WBFS
|
||||
//#define DEBUG_WBFS
|
||||
|
||||
/* WBFS device */
|
||||
s32 wbfsDev = WBFS_MIN_DEVICE;
|
||||
|
Loading…
Reference in New Issue
Block a user