From 96cb18d26fbb1fc12be2992acdae3f50e09f275f Mon Sep 17 00:00:00 2001 From: dimok321 <15055714+dimok789@users.noreply.github.com> Date: Mon, 30 May 2011 19:49:12 +0000 Subject: [PATCH] *fixed reversed disc image download when Custom/Original option is selected (Issue 1871) *corrected the patch for returnTo using d2x (should be working now) *added block ios reload of d2x. you can choose the methods in the game settings (same option as for hermes ios but it can be 1 or 2 on waninkoko ios, last option on screen) (not tested yet) *major restructuring of patching code for game patches inside the source --- HBC/META.XML | 4 +- source/menu/GameBrowseMenu.cpp | 2 +- source/network/ImageDownloader.cpp | 8 +- source/patches/gamepatches.c | 391 ++++++++++++++++++--------- source/patches/gamepatches.h | 6 +- source/patches/patchcode.c | 2 + source/patches/patchcode.h | 5 +- source/settings/menus/GameLoadSM.cpp | 35 ++- source/usbloader/GameBooter.cpp | 48 +--- source/usbloader/GameBooter.hpp | 3 +- source/usbloader/alternatedol.c | 15 +- source/usbloader/alternatedol.h | 4 +- source/usbloader/apploader.c | 51 +--- source/usbloader/apploader.h | 4 +- source/wad/nandtitle.cpp | 10 +- 15 files changed, 339 insertions(+), 249 deletions(-) diff --git a/HBC/META.XML b/HBC/META.XML index 41bc1c87..f20e25f7 100644 --- a/HBC/META.XML +++ b/HBC/META.XML @@ -2,8 +2,8 @@ USB Loader GX USB Loader GX Team - 2.1 r1081 - 201103221731 + 2.1 r1082 + 201105281953 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. diff --git a/source/menu/GameBrowseMenu.cpp b/source/menu/GameBrowseMenu.cpp index 657d4eda..fd20391f 100644 --- a/source/menu/GameBrowseMenu.cpp +++ b/source/menu/GameBrowseMenu.cpp @@ -1319,7 +1319,7 @@ int GameBrowseMenu::OpenClickedGame() else if(game_cfg->loadalternatedol == 4) defaultDolPrompt((char *) header->id); - if (RunGame && game_cfg->ocarina != OFF && Settings.ocarina != OFF) + if (RunGame && (game_cfg->ocarina == ON || (game_cfg->ocarina == INHERIT && Settings.ocarina == ON))) CheckOcarina(IDfull); if(RunGame) diff --git a/source/network/ImageDownloader.cpp b/source/network/ImageDownloader.cpp index bf5fecd1..04909944 100644 --- a/source/network/ImageDownloader.cpp +++ b/source/network/ImageDownloader.cpp @@ -98,16 +98,16 @@ void ImageDownloader::FindMissingImages() if(choices & CheckedBox5) { - const char * downloadURL = (Settings.discart == DISCARTS_ORIGINALS_CUSTOMS) ? serverURLOrigDiscs : serverURLCustomDiscs; + const char * downloadURL = (Settings.discart == DISCARTS_ORIGINALS_CUSTOMS || !(choices & CheckedBox6)) ? serverURLOrigDiscs : serverURLCustomDiscs; const char * backupURL = (choices & CheckedBox6) ? ((Settings.discart == DISCARTS_ORIGINALS_CUSTOMS) ? serverURLCustomDiscs : serverURLOrigDiscs) : NULL; - const char * progressTitle = (Settings.discart == DISCARTS_ORIGINALS_CUSTOMS) ? tr("Downloading original Discarts") : tr("Downloading custom Discarts"); + const char * progressTitle = (Settings.discart == DISCARTS_ORIGINALS_CUSTOMS || !(choices & CheckedBox6)) ? tr("Downloading original Discarts") : tr("Downloading custom Discarts"); FindMissing(Settings.disc_path, downloadURL, backupURL, progressTitle); } if(choices & CheckedBox6) { - const char * downloadURL = (Settings.discart == DISCARTS_ORIGINALS_CUSTOMS) ? serverURLCustomDiscs : serverURLOrigDiscs; - const char * progressTitle = (Settings.discart == DISCARTS_ORIGINALS_CUSTOMS) ? tr("Downloading custom Discarts") : tr("Downloading original Discarts"); + const char * downloadURL = (Settings.discart == DISCARTS_ORIGINALS_CUSTOMS || !(choices & CheckedBox5)) ? serverURLCustomDiscs : serverURLOrigDiscs; + const char * progressTitle = (Settings.discart == DISCARTS_ORIGINALS_CUSTOMS || !(choices & CheckedBox5)) ? tr("Downloading custom Discarts") : tr("Downloading original Discarts"); FindMissing(Settings.disc_path, downloadURL, NULL, progressTitle); } } diff --git a/source/patches/gamepatches.c b/source/patches/gamepatches.c index 48956a26..45b0f8f6 100644 --- a/source/patches/gamepatches.c +++ b/source/patches/gamepatches.c @@ -1,10 +1,103 @@ +#include #include #include #include +#include "usbloader/disc.h" #include "dolpatcher.h" #include "wip.h" #include "gecko.h" -#include "../settings/SettingsEnums.h" +#include "patchcode.h" +#include "gamepatches.h" +#include "settings/SettingsEnums.h" + +typedef struct _appDOL +{ + u8 *dst; + int len; +} appDOL; + +static appDOL *dolList = NULL; +static int dolCount = 0; + +static char es_fs[] ATTRIBUTE_ALIGN(32) = "/dev/es"; +static s32 es_fd = -1; + +void RegisterDOL(u8 *dst, int len) +{ + if(!dolList) + dolList = (appDOL *) malloc(sizeof(appDOL)); + + appDOL *tmp = (appDOL *) realloc(dolList, (dolCount+1)*sizeof(appDOL)); + if(!tmp) + { + free(dolList); + dolCount = 0; + return; + } + + dolList = tmp; + dolList[dolCount].dst = dst; + dolList[dolCount].len = len; + dolCount++; +} + +void ClearDOLList() +{ + if(dolList) + free(dolList); + dolList = NULL; + dolCount = 0; +} + +void gamepatches(u8 videoSelected, u8 languageChoice, u8 patchcountrystring, u8 vipatch, u8 cheat, u8 fix002, u8 blockiosreloadselect, u64 returnTo) +{ + int i; + int es_fd = IOS_Open(es_fs, 0); + + int returnToPatched = PatchNewReturnTo(returnTo); + + for(i = 0; i < dolCount; ++i) + { + u8 *dst = dolList[dolCount].dst; + int len = dolList[dolCount].len; + + VideoModePatcher(dst, len, videoSelected); + + if (cheat) + dogamehooks(dst, len); + + if (vipatch) + vidolpatcher(dst, len); + + /*LANGUAGE PATCH - FISHEARS*/ + langpatcher(dst, len, languageChoice); + + /*Thanks to WiiPower*/ + if (patchcountrystring == 1) + PatchCountryStrings(dst, len); + + do_wip_code(dst, len); + + if (fix002 == 2) + Anti_002_fix(dst, len); + + if(returnToPatched < 0) + PatchReturnTo(dst, len, (u32) returnTo); + + DCFlushRange(dst, len); + } + + BlockIOSReload(blockiosreloadselect); + + if(es_fd >= 0) + IOS_Close(es_fd); + + /* ERROR 002 fix (thanks to WiiPower for sharing this)*/ + if (fix002 != 0) + *(u32 *) 0x80003188 = *(u32 *) 0x80003140; + + DCFlushRange((void*) 0x80000000, 0x3f00); +} /** Anti 002 fix for IOS 249 rev > 12 thanks to WiiPower **/ bool Anti_002_fix(u8 * Address, int Size) @@ -149,20 +242,23 @@ static GXRModeObj* vmodes[] = #endif static GXRModeObj* PAL2NTSC[] = { &TVMpal480IntDf, &TVNtsc480IntDf, &TVPal264Ds, &TVNtsc240Ds, &TVPal264DsAa, - &TVNtsc240DsAa, &TVPal264Int, &TVNtsc240Int, &TVPal264IntAa, &TVNtsc240IntAa, &TVPal524IntAa, &TVNtsc480IntAa, - &TVPal528Int, &TVNtsc480IntAa, &TVPal528IntDf, &TVNtsc480IntDf, &TVPal574IntDfScale, &TVNtsc480IntDf, - &TVEurgb60Hz240Ds, &TVNtsc240Ds, &TVEurgb60Hz240DsAa, &TVNtsc240DsAa, &TVEurgb60Hz240Int, &TVNtsc240Int, - &TVEurgb60Hz240IntAa, &TVNtsc240IntAa, &TVEurgb60Hz480Int, &TVNtsc480IntAa, &TVEurgb60Hz480IntDf, - &TVNtsc480IntDf, &TVEurgb60Hz480IntAa, &TVNtsc480IntAa, &TVEurgb60Hz480Prog, &TVNtsc480Prog, - &TVEurgb60Hz480ProgSoft, &TVNtsc480Prog, &TVEurgb60Hz480ProgAa, &TVNtsc480Prog, 0, 0 }; + &TVNtsc240DsAa, &TVPal264Int, &TVNtsc240Int, &TVPal264IntAa, &TVNtsc240IntAa, &TVPal524IntAa, &TVNtsc480IntAa, + &TVPal528Int, &TVNtsc480IntAa, &TVPal528IntDf, &TVNtsc480IntDf, &TVPal574IntDfScale, &TVNtsc480IntDf, + &TVEurgb60Hz240Ds, &TVNtsc240Ds, &TVEurgb60Hz240DsAa, &TVNtsc240DsAa, &TVEurgb60Hz240Int, &TVNtsc240Int, + &TVEurgb60Hz240IntAa, &TVNtsc240IntAa, &TVEurgb60Hz480Int, &TVNtsc480IntAa, &TVEurgb60Hz480IntDf, + &TVNtsc480IntDf, &TVEurgb60Hz480IntAa, &TVNtsc480IntAa, &TVEurgb60Hz480Prog, &TVNtsc480Prog, + &TVEurgb60Hz480ProgSoft, &TVNtsc480Prog, &TVEurgb60Hz480ProgAa, &TVNtsc480Prog, 0, 0 + }; static GXRModeObj* NTSC2PAL[] = { &TVNtsc240Ds, &TVPal264Ds, &TVNtsc240DsAa, &TVPal264DsAa, &TVNtsc240Int, - &TVPal264Int, &TVNtsc240IntAa, &TVPal264IntAa, &TVNtsc480IntDf, &TVPal528IntDf, &TVNtsc480IntAa, - &TVPal524IntAa, &TVNtsc480Prog, &TVPal528IntDf, 0, 0 }; + &TVPal264Int, &TVNtsc240IntAa, &TVPal264IntAa, &TVNtsc480IntDf, &TVPal528IntDf, &TVNtsc480IntAa, + &TVPal524IntAa, &TVNtsc480Prog, &TVPal528IntDf, 0, 0 + }; static GXRModeObj* NTSC2PAL60[] = { &TVNtsc240Ds, &TVEurgb60Hz240Ds, &TVNtsc240DsAa, &TVEurgb60Hz240DsAa, - &TVNtsc240Int, &TVEurgb60Hz240Int, &TVNtsc240IntAa, &TVEurgb60Hz240IntAa, &TVNtsc480IntDf, - &TVEurgb60Hz480IntDf, &TVNtsc480IntAa, &TVEurgb60Hz480IntAa, &TVNtsc480Prog, &TVEurgb60Hz480Prog, 0, 0 }; + &TVNtsc240Int, &TVEurgb60Hz240Int, &TVNtsc240IntAa, &TVEurgb60Hz240IntAa, &TVNtsc480IntDf, + &TVEurgb60Hz480IntDf, &TVNtsc480IntAa, &TVEurgb60Hz480IntAa, &TVNtsc480Prog, &TVEurgb60Hz480Prog, 0, 0 + }; static bool compare_videomodes(GXRModeObj* mode1, GXRModeObj* mode2) { @@ -252,12 +348,9 @@ static bool Search_and_patch_Video_Modes(u8 * Address, u32 Size, GXRModeObj* Tab while (Size >= sizeof(GXRModeObj)) { - for (i = 0; Table[i]; i += 2) { - if (compare_videomodes(Table[i], (GXRModeObj*) Addr)) - { found = 1; patch_videomode((GXRModeObj*) Addr, Table[i + 1]); @@ -282,25 +375,25 @@ void VideoModePatcher(u8 * dst, int len, u8 videoSelected) { switch (CONF_GetVideo()) { - case CONF_VIDEO_PAL: - if (CONF_GetEuRGB60() > 0) - { - table = NTSC2PAL60; - } - else - { - table = NTSC2PAL; - } - break; - - case CONF_VIDEO_MPAL: - + case CONF_VIDEO_PAL: + if (CONF_GetEuRGB60() > 0) + { + table = NTSC2PAL60; + } + else + { table = NTSC2PAL; - break; + } + break; - default: - table = PAL2NTSC; - break; + case CONF_VIDEO_MPAL: + + table = NTSC2PAL; + break; + + default: + table = PAL2NTSC; + break; } Search_and_patch_Video_Modes(dst, len, table); } @@ -310,21 +403,22 @@ void VideoModePatcher(u8 * dst, int len, u8 videoSelected) 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; +static u8 returnToPatched = 0; + bool PatchReturnTo( void *Address, int Size, u32 id ) { - if( !id || patched ) - return 0; + if( !id || returnToPatched ) + 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 }; //li r4,2 - //li r3,1 - //li r5,0 + //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 }; //li r6,2 - //li r5,1 - //li r7,0 + //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 }; //"Metrowerks T" @@ -334,111 +428,158 @@ bool PatchReturnTo( void *Address, int Size, u32 id ) void *Addr = Address; 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; - } - //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 ] ) { - 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 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, //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 + //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 - 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) - } + 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) + } - void* addr = (u32*)ad[ 3 ]; + void* addr = (u32*)ad[ 3 ]; - //write new stuff to in a unused part of the main.dol - memcpy( addr, jump, sizeof( jump ) ); + //write new stuff to in a unused part of the main.dol + memcpy( addr, jump, sizeof( jump ) ); - //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_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_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 ); + //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 ); - //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 ); + //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; + returnToPatched = 1; } - /*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 ] ); - }*/ - return patched; + return returnToPatched; +} + +int PatchNewReturnTo(u64 title) +{ + if(title == 0) return -1; + + //! this is here for test purpose only and needs be moved later + static u64 sm_title_id ATTRIBUTE_ALIGN(32); + STACK_ALIGN(ioctlv, vector, 1, 32); + + sm_title_id = title; + vector[0].data = &sm_title_id; + vector[0].len = sizeof(sm_title_id); + + int result = -1; + + if(es_fd >= 0) + result = IOS_Ioctlv(es_fd, 0xA1, 1, 0, vector); + + return result; +} + +bool BlockIOSReload(u8 blockiosreloadselect) +{ + if(blockiosreloadselect == 0) + return false; + + static int mode ATTRIBUTE_ALIGN(32); + static int ios ATTRIBUTE_ALIGN(32); + STACK_ALIGN(ioctlv, vector, 2, 32); + + mode = blockiosreloadselect; + vector[0].data = &mode; + vector[0].len = 4; + + int inlen = 1; + if (mode == 2) { + inlen = 2; + ios = 249; // ios to be reloaded in place of the requested one + vector[1].data = &ios; + vector[1].len = 4; + } + + int result = -1; + + if(es_fd >= 0) + result = IOS_Ioctlv(es_fd, 0xA0, inlen, 0, vector); + + return (result >= 0); } diff --git a/source/patches/gamepatches.h b/source/patches/gamepatches.h index 4fd78b9a..22b9ba1f 100644 --- a/source/patches/gamepatches.h +++ b/source/patches/gamepatches.h @@ -7,12 +7,16 @@ extern "C" { #include +void RegisterDOL(u8 *dst, int len); +void ClearDOLList(); +void gamepatches(u8 videoSelected, u8 languageChoice, u8 patchcountrystring, u8 vipatch, u8 cheat, u8 fix002, u8 blockiosreloadselect, u64 returnTo); bool Anti_002_fix(u8 * Address, int Size); bool NSMBPatch(); bool PoPPatch(); -bool Search_and_patch_Video_Modes(u8 * Address, u32 Size, GXRModeObj* Table[]); void VideoModePatcher(u8 * dst, int len, u8 videoSelected); bool PatchReturnTo(void *Address, int Size, u32 id); +int PatchNewReturnTo(u64 title); +bool BlockIOSReload(u8 blockiosreloadselect); #ifdef __cplusplus } diff --git a/source/patches/patchcode.c b/source/patches/patchcode.c index adb599f9..a584b893 100644 --- a/source/patches/patchcode.c +++ b/source/patches/patchcode.c @@ -35,6 +35,8 @@ //#include "fwrite_patch_slota.h" //#include "main.h" +u32 hooktype = 0; + extern const char * CheatFilepath; extern void patchhook(u32 address, u32 len); diff --git a/source/patches/patchcode.h b/source/patches/patchcode.h index 98e05955..c9b32e8f 100644 --- a/source/patches/patchcode.h +++ b/source/patches/patchcode.h @@ -27,10 +27,7 @@ extern "C" { #endif // Globals - u32 hooktype; - int patched; - //u8 configbytes[2]; - //u32 regionfree; + extern u32 hooktype; // Function prototypes bool dogamehooks(void *addr, u32 len); diff --git a/source/settings/menus/GameLoadSM.cpp b/source/settings/menus/GameLoadSM.cpp index 29e4ccb9..7504955b 100644 --- a/source/settings/menus/GameLoadSM.cpp +++ b/source/settings/menus/GameLoadSM.cpp @@ -30,6 +30,7 @@ #include "usbloader/AlternateDOLOffsets.h" #include "language/gettext.h" #include "wad/nandtitle.h" +#include "system/IosLoader.h" #include "GameLoadSM.hpp" static const char * OnOffText[] = @@ -90,6 +91,13 @@ static const char * AlternateDOLText[] = trNOOP( "Default" ), }; +static const char * IOSReloadBlockText[] = +{ + trNOOP( "OFF" ), + trNOOP( "Method 1" ), + trNOOP( "Method 2" ), +}; + GameLoadSM::GameLoadSM(const char * GameID) : SettingsMenu(tr("Game Load"), &GuiOptions, MENU_NONE) { @@ -160,37 +168,37 @@ void GameLoadSM::SetOptionValues() int Idx = 0; //! Settings: Video Mode - if(GameConfig.video == -1) + if(GameConfig.video == INHERIT) Options->SetValue(Idx++, tr("Use global")); else Options->SetValue(Idx++, "%s", tr(VideoModeText[GameConfig.video])); //! Settings: VIDTV Patch - if(GameConfig.vipatch == -1) + if(GameConfig.vipatch == INHERIT) Options->SetValue(Idx++, tr("Use global")); else Options->SetValue(Idx++, "%s", tr(OnOffText[GameConfig.vipatch])); //! Settings: Game Language - if(GameConfig.language == -1) + if(GameConfig.language == INHERIT) Options->SetValue(Idx++, tr("Use global")); else Options->SetValue(Idx++, "%s", tr(LanguageText[GameConfig.language])); //! Settings: Patch Country Strings - if(GameConfig.patchcountrystrings == -1) + if(GameConfig.patchcountrystrings == INHERIT) Options->SetValue(Idx++, tr("Use global")); else Options->SetValue(Idx++, "%s", tr(OnOffText[GameConfig.patchcountrystrings])); //! Settings: Ocarina - if(GameConfig.ocarina == -1) + if(GameConfig.ocarina == INHERIT) Options->SetValue(Idx++, tr("Use global")); else Options->SetValue(Idx++, "%s", tr(OnOffText[GameConfig.ocarina])); //! Settings: Game IOS - if(GameConfig.ios == -1) + if(GameConfig.ios == INHERIT) Options->SetValue(Idx++, tr("Use global")); else Options->SetValue(Idx++, "%i", GameConfig.ios); @@ -199,7 +207,7 @@ void GameLoadSM::SetOptionValues() Options->SetValue(Idx++, "%s", tr(ParentalText[GameConfig.parentalcontrol])); //! Settings: Error 002 fix - if(GameConfig.errorfix002 == -1) + if(GameConfig.errorfix002 == INHERIT) Options->SetValue(Idx++, tr("Use global")); else Options->SetValue(Idx++, "%s", tr(Error002Text[GameConfig.errorfix002])); @@ -234,7 +242,12 @@ void GameLoadSM::SetOptionValues() } //! Settings: Block IOS Reload - Options->SetValue(Idx++, "%s", tr( OnOffText[GameConfig.iosreloadblock] )); + if(IosLoader::IsHermesIOS(GameConfig.ios == INHERIT ? Settings.cios : GameConfig.ios) && GameConfig.iosreloadblock) + Options->SetValue(Idx++, tr("ON")); + else if(GameConfig.iosreloadblock) + Options->SetValue(Idx++, "%s", tr(IOSReloadBlockText[GameConfig.iosreloadblock])); + else + Options->SetValue(Idx++, tr("OFF")); //! Settings: Game Lock Options->SetValue(Idx++, "%s", tr( OnOffText[GameConfig.Locked] )); @@ -376,7 +389,11 @@ int GameLoadSM::GetMenuInternal() //! Settings: Block IOS Reload else if (ret == ++Idx) { - if (++GameConfig.iosreloadblock >= MAX_ON_OFF) GameConfig.iosreloadblock = 0; + ++GameConfig.iosreloadblock; + if(GameConfig.iosreloadblock >= MAX_ON_OFF && IosLoader::IsHermesIOS(GameConfig.ios == INHERIT ? Settings.cios : GameConfig.ios)) + GameConfig.iosreloadblock = 0; + else if (GameConfig.iosreloadblock >= 3) + GameConfig.iosreloadblock = 0; } //! Settings: Game Lock diff --git a/source/usbloader/GameBooter.cpp b/source/usbloader/GameBooter.cpp index 6b037a63..62ecea73 100644 --- a/source/usbloader/GameBooter.cpp +++ b/source/usbloader/GameBooter.cpp @@ -1,4 +1,3 @@ -#include #include "menu/menus.h" #include "menu/WDMMenu.hpp" #include "mload/mload.h" @@ -45,8 +44,7 @@ int GameBooter::BootGCMode() } -u32 GameBooter::BootPartition(char * dolpath, u8 videoselected, u8 languageChoice, u8 cheat, u8 vipatch, u8 patchcountrystring, - u8 alternatedol, u32 alternatedoloffset, u32 returnTo, u8 fix002) +u32 GameBooter::BootPartition(char * dolpath, u8 videoselected, u8 alternatedol, u32 alternatedoloffset) { gprintf("booting partition IOS %u r%u\n", IOS_GetVersion(), IOS_GetRevision()); entry_point p_entry; @@ -76,8 +74,7 @@ u32 GameBooter::BootPartition(char * dolpath, u8 videoselected, u8 languageChoic Disc_SelectVMode(videoselected); /* Run apploader */ - ret = Apploader_Run(&p_entry, dolpath, cheat, videoselected, languageChoice, vipatch, patchcountrystring, - alternatedol, alternatedoloffset, returnTo, fix002); + ret = Apploader_Run(&p_entry, dolpath, alternatedol, alternatedoloffset); if (ret < 0) return 0; @@ -205,40 +202,11 @@ int GameBooter::BootGame(const char * gameID) u8 alternatedol = game_cfg->loadalternatedol; u32 alternatedoloffset = game_cfg->alternatedolstart; u8 reloadblock = game_cfg->iosreloadblock; - u8 returnToLoaderGV = game_cfg->returnTo; + u64 returnToChoice = game_cfg->returnTo ? NandTitles.At(NandTitles.FindU32(Settings.returnTo)) : 0; //! Prepare alternate dol settings SetupAltDOL(gameHeader.id, alternatedol, alternatedoloffset); - //! Setup the return to Loader option - u32 channel = 0; - if (returnToLoaderGV) - { - int idx = NandTitles.FindU32(Settings.returnTo); - - //! this is here for test purpose only and needs be moved later - static char es_fs[] ATTRIBUTE_ALIGN(32) = "/dev/es"; - static u64 sm_title_id ATTRIBUTE_ALIGN(32); - STACK_ALIGN(ioctlv, vector, 1, 32); - - sm_title_id = NandTitles.At(idx); - vector[0].data = &sm_title_id; - vector[0].len = sizeof(sm_title_id); - - int es_fd = IOS_Open(es_fs, 0); - int result = -1; - - if(es_fd >= 0) - result = IOS_Ioctlv(es_fd, 0xA1, 1, 0, vector); - - if(es_fd >= 0) - IOS_Close(es_fd); - - //! use old method in case of failure for other IOS versions than d2x - if (result < 0 && idx >= 0) - channel = TITLE_LOWER(NandTitles.At(idx)); - } - //! This is temporary - C <-> C++ transfer SetCheatFilepath(Settings.Cheatcodespath); SetBCAFilepath(Settings.BcaCodepath); @@ -263,11 +231,13 @@ int GameBooter::BootGame(const char * gameID) gprintf("%d\n", ret); //! Setup IOS reload block - only possible on Hermes cIOS - if (reloadblock == ON && IosLoader::IsHermesIOS()) + if (reloadblock && IosLoader::IsHermesIOS()) { enable_ES_ioctlv_vector(); if (gameList.GetGameFS(gameHeader.id) == PART_FS_WBFS) mload_close(); + + reloadblock = 0; } //! Now we can free up the memory used by the game list @@ -275,8 +245,7 @@ int GameBooter::BootGame(const char * gameID) //! Load main.dol or alternative dol into memory, start the game apploader and get game entrypoint gprintf("\tDisc_wiiBoot\n"); - AppEntrypoint = BootPartition(Settings.dolpath, videoChoice, languageChoice, ocarinaChoice, viChoice, countrystrings, - alternatedol, alternatedoloffset, channel, fix002); + AppEntrypoint = BootPartition(Settings.dolpath, videoChoice, alternatedol, alternatedoloffset); //! No entrypoint found...back to HBC/SystemMenu if(AppEntrypoint == 0) @@ -285,6 +254,9 @@ int GameBooter::BootGame(const char * gameID) Sys_BackToLoader(); } + //! Do all the game patches + gamepatches(videoChoice, languageChoice, countrystrings, viChoice, ocarinaChoice, fix002, reloadblock, returnToChoice); + //! Load Ocarina codes bool enablecheat = false; if (ocarinaChoice) diff --git a/source/usbloader/GameBooter.hpp b/source/usbloader/GameBooter.hpp index 5ecb3f8f..f04ad4ab 100644 --- a/source/usbloader/GameBooter.hpp +++ b/source/usbloader/GameBooter.hpp @@ -13,8 +13,7 @@ class GameBooter static void SetupAltDOL(u8 * gameID, u8 &alternatedol, u32 &alternatedoloffset); static int SetupDisc(u8 *gameID); static bool LoadOcarina(u8 *gameID); - static u32 BootPartition(char * dolpath, u8 videoselected, u8 languageChoice, u8 cheat, u8 vipatch, - u8 patchcountrystring, u8 alternatedol, u32 alternatedoloffset, u32 returnTo, u8 fix002); + static u32 BootPartition(char * dolpath, u8 videoselected, u8 alternatedol, u32 alternatedoloffset); }; #endif diff --git a/source/usbloader/alternatedol.c b/source/usbloader/alternatedol.c index 3022e0a7..4bbb430d 100644 --- a/source/usbloader/alternatedol.c +++ b/source/usbloader/alternatedol.c @@ -4,6 +4,7 @@ #include #include +#include "patches/gamepatches.h" #include "apploader.h" #include "wdvd.h" #include "fstfile.h" @@ -85,7 +86,7 @@ bool Load_Dol(void **buffer, int* dollen, const char * filepath) return true; } -u32 load_dol_image(void *dolstart, u8 videoSelected, u8 languageChoice, u8 patchcountrystring, u8 vipatch, u8 cheat, u8 fix002, u32 returnTo) +u32 load_dol_image(void *dolstart) { if (!dolstart) return 0; @@ -98,8 +99,7 @@ u32 load_dol_image(void *dolstart, u8 videoSelected, u8 languageChoice, u8 patch if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100)) continue; 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, languageChoice, patchcountrystring, - vipatch, cheat, returnTo, fix002); + RegisterDOL((u8 *) dolfile->text_start[i], dolfile->text_size[i]); Remove_001_Protection((void *) dolfile->data_start[i], dolfile->data_size[i]); DCFlushRange((void *) dolfile->data_start[i], dolfile->data_size[i]); ICInvalidateRange((void *) dolfile->text_start[i], dolfile->text_size[i]); @@ -110,8 +110,7 @@ u32 load_dol_image(void *dolstart, u8 videoSelected, u8 languageChoice, u8 patch if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100)) continue; 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, languageChoice, patchcountrystring, - vipatch, cheat, returnTo, fix002); + RegisterDOL((u8 *) dolfile->data_start[i], dolfile->data_size[i]); Remove_001_Protection((void *) dolfile->data_start[i], dolfile->data_size[i]); DCFlushRange((void *) dolfile->data_start[i], dolfile->data_size[i]); } @@ -119,7 +118,7 @@ u32 load_dol_image(void *dolstart, u8 videoSelected, u8 languageChoice, u8 patch return dolfile->entry_point; } -u32 Load_Dol_from_disc(u32 offset, u8 videoSelected, u8 languageChoice, u8 patchcountrystring, u8 vipatch, u8 cheat, u8 fix002, u32 returnTo) +u32 Load_Dol_from_disc(u32 offset) { s32 ret; dolheader * dolfile; @@ -164,7 +163,7 @@ u32 Load_Dol_from_disc(u32 offset, u8 videoSelected, u8 languageChoice, u8 patch return 0; } - gamepatches(buffer, size, videoSelected, languageChoice, patchcountrystring, vipatch, cheat, returnTo, fix002); + RegisterDOL((u8 *) buffer, size); Remove_001_Protection(buffer, size); DCFlushRange(buffer, size); ICInvalidateRange(buffer, size); @@ -185,7 +184,7 @@ u32 Load_Dol_from_disc(u32 offset, u8 videoSelected, u8 languageChoice, u8 patch return 0; } - gamepatches(buffer, size, videoSelected, languageChoice, patchcountrystring, vipatch, cheat, returnTo, fix002); + RegisterDOL((u8 *) buffer, size); Remove_001_Protection(buffer, size); DCFlushRange(buffer, size); } diff --git a/source/usbloader/alternatedol.h b/source/usbloader/alternatedol.h index 3c434c46..5195f3d1 100644 --- a/source/usbloader/alternatedol.h +++ b/source/usbloader/alternatedol.h @@ -8,8 +8,8 @@ extern "C" /* not the full path is needed here, the path where the dol is */ bool Load_Dol(void **buffer, int* dollen, const char * filepath); -u32 load_dol_image(void *dolstart, u8 videoSelected, u8 languageChoice, u8 patchcountrystring, u8 vipatch, u8 cheat, u8 fix002, u32 returnTo); -u32 Load_Dol_from_disc(u32 offset, u8 videoSelected, u8 languageChoice, u8 patchcountrystring, u8 vipatch, u8 cheat, u8 fix002, u32 returnTo); +u32 load_dol_image(void *dolstart); +u32 Load_Dol_from_disc(u32 offset); #ifdef __cplusplus } diff --git a/source/usbloader/apploader.c b/source/usbloader/apploader.c index 51bf6201..4dbf1167 100644 --- a/source/usbloader/apploader.c +++ b/source/usbloader/apploader.c @@ -3,7 +3,6 @@ #include #include -#include "patches/patchcode.h" #include "apploader.h" #include "wdvd.h" #include "wpad.h" @@ -11,8 +10,6 @@ #include "alternatedol.h" #include "fstfile.h" #include "gecko.h" -#include "patches/wip.h" -#include "patches/dolpatcher.h" #include "patches/gamepatches.h" #include "settings/SettingsEnums.h" @@ -33,33 +30,7 @@ static u8 *appldr = (u8 *) 0x81200000; /* Variables */ static u32 buffer[0x20] ATTRIBUTE_ALIGN( 32 ); -void gamepatches( u8 * dst, int len, u8 videoSelected, u8 languageChoice, u8 patchcountrystring, u8 vipatch, u8 cheat, u32 returnTo, u8 fix002 ) -{ - VideoModePatcher( dst, len, videoSelected ); - - if ( cheat ) - dogamehooks( dst, len ); - - if ( vipatch ) - vidolpatcher( dst, len ); - - /*LANGUAGE PATCH - FISHEARS*/ - langpatcher( dst, len, languageChoice ); - - /*Thanks to WiiPower*/ - if ( patchcountrystring == 1 ) - PatchCountryStrings( dst, len ); - - do_wip_code( ( u8 * ) 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 languageChoice, u8 vipatch, u8 patchcountrystring, - u8 alternatedol, u32 alternatedoloffset, u32 returnTo, u8 fix002) +s32 Apploader_Run(entry_point *entry, char * dolpath, u8 alternatedol, u32 alternatedoloffset) { app_entry appldr_entry; app_init appldr_init; @@ -90,12 +61,6 @@ s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected /* Initialize apploader */ appldr_init(gprintf); - if (fix002 != 0) - { - /* ERROR 002 fix (thanks to WiiPower for sharing this)*/ - *(u32 *) 0x80003188 = *(u32 *) 0x80003140; - } - for (;;) { void *dst = NULL; @@ -108,8 +73,7 @@ s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected /* Read data from DVD */ WDVD_Read(dst, len, (u64) (offset << 2)); - if( !alternatedol ) - gamepatches(dst, len, videoSelected, languageChoice, patchcountrystring, vipatch, cheat, returnTo, fix002 ); + RegisterDOL((u8 *) dst, len); DCFlushRange(dst, len); } @@ -119,29 +83,26 @@ s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected /** Load alternate dol if set **/ if (alternatedol == ALT_DOL_FROM_SD_USB) { - wip_reset_counter(); + ClearDOLList(); void *dolbuffer = NULL; int dollen = 0; bool dolloaded = Load_Dol(&dolbuffer, &dollen, dolpath); if (dolloaded) - { - *entry = (entry_point) load_dol_image(dolbuffer, videoSelected, languageChoice, patchcountrystring, vipatch, cheat, fix002, returnTo); - } + *entry = (entry_point) load_dol_image(dolbuffer); if (dolbuffer) free(dolbuffer); } else if (alternatedol == ALT_DOL_FROM_GAME && alternatedoloffset != 0) { - wip_reset_counter(); + ClearDOLList(); FST_ENTRY *fst = (FST_ENTRY *) *(u32 *) 0x80000038; //! Check if it's inside the limits if(alternatedoloffset >= fst[0].filelen) return 0; - *entry = (entry_point) Load_Dol_from_disc(fst[alternatedoloffset].fileoffset, videoSelected, languageChoice, - patchcountrystring, vipatch, cheat, fix002, returnTo); + *entry = (entry_point) Load_Dol_from_disc(fst[alternatedoloffset].fileoffset); } return 0; diff --git a/source/usbloader/apploader.h b/source/usbloader/apploader.h index 477a4884..69d936f3 100644 --- a/source/usbloader/apploader.h +++ b/source/usbloader/apploader.h @@ -10,9 +10,7 @@ extern "C" typedef void (*entry_point)(void); /* Prototypes */ - s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected, u8 languageChoice, u8 vipatch, - u8 patchcountrystring, u8 alternatedol, u32 alternatedoloffset, u32 returnTo, u8 fix002); - void gamepatches( u8 * dst, int len, u8 videoSelected, u8 languageChoice, u8 patchcountrystring, u8 vipatch, u8 cheat, u32 returnTo, u8 fix002 ); + s32 Apploader_Run(entry_point *entry, char * dolpath, u8 alternatedol, u32 alternatedoloffset); #ifdef __cplusplus } diff --git a/source/wad/nandtitle.cpp b/source/wad/nandtitle.cpp index 7cfe0f4c..cc8e8137 100644 --- a/source/wad/nandtitle.cpp +++ b/source/wad/nandtitle.cpp @@ -246,14 +246,14 @@ bool NandTitle::Exists(u64 tid) bool NandTitle::ExistsFromIndex(u32 i) { - if (i > titleIds.size()) return false; + if (i >= titleIds.size()) return false; return Exists(titleIds.at(i)); } u64 NandTitle::At(u32 i) { - if (i > titleIds.size()) return 0; + if (i >= titleIds.size()) return 0; return titleIds.at(i); } @@ -278,7 +278,7 @@ const char* NandTitle::NameOf(u64 tid) const char* NandTitle::NameFromIndex(u32 i) { - if (i > titleIds.size()) return NULL; + if (i >= titleIds.size()) return NULL; map::iterator itr = NameList.find(titleIds.at(i)); if (itr != NameList.end()) return itr->second.c_str(); @@ -304,7 +304,7 @@ u16 NandTitle::VersionOf(u64 tid) u16 NandTitle::VersionFromIndex(u32 i) { - if (i > titleIds.size()) return 0; + if (i >= titleIds.size()) return 0; tmd* Tmd = GetTMD(titleIds.at(i)); if (!Tmd) return 0; @@ -377,7 +377,7 @@ void NandTitle::AsciiTID(u64 tid, char* out) void NandTitle::AsciiFromIndex(u32 i, char* out) { - if (i > titleIds.size()) + if (i >= titleIds.size()) { out[0] = 0; return;