mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-25 20:56:53 +01:00
*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
This commit is contained in:
parent
00e9a9ffee
commit
96cb18d26f
@ -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>2.1 r1081</version>
|
<version>2.1 r1082</version>
|
||||||
<release_date>201103221731</release_date>
|
<release_date>201105281953</release_date>
|
||||||
<no_ios_reload/>
|
<no_ios_reload/>
|
||||||
<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.
|
||||||
|
@ -1319,7 +1319,7 @@ int GameBrowseMenu::OpenClickedGame()
|
|||||||
else if(game_cfg->loadalternatedol == 4)
|
else if(game_cfg->loadalternatedol == 4)
|
||||||
defaultDolPrompt((char *) header->id);
|
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);
|
CheckOcarina(IDfull);
|
||||||
|
|
||||||
if(RunGame)
|
if(RunGame)
|
||||||
|
@ -98,16 +98,16 @@ void ImageDownloader::FindMissingImages()
|
|||||||
|
|
||||||
if(choices & CheckedBox5)
|
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 * 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);
|
FindMissing(Settings.disc_path, downloadURL, backupURL, progressTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(choices & CheckedBox6)
|
if(choices & CheckedBox6)
|
||||||
{
|
{
|
||||||
const char * downloadURL = (Settings.discart == DISCARTS_ORIGINALS_CUSTOMS) ? serverURLCustomDiscs : serverURLOrigDiscs;
|
const char * downloadURL = (Settings.discart == DISCARTS_ORIGINALS_CUSTOMS || !(choices & CheckedBox5)) ? serverURLCustomDiscs : serverURLOrigDiscs;
|
||||||
const char * progressTitle = (Settings.discart == DISCARTS_ORIGINALS_CUSTOMS) ? tr("Downloading custom Discarts") : tr("Downloading original Discarts");
|
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);
|
FindMissing(Settings.disc_path, downloadURL, NULL, progressTitle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,103 @@
|
|||||||
|
#include <ogc/machine/processor.h>
|
||||||
#include <gccore.h>
|
#include <gccore.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "usbloader/disc.h"
|
||||||
#include "dolpatcher.h"
|
#include "dolpatcher.h"
|
||||||
#include "wip.h"
|
#include "wip.h"
|
||||||
#include "gecko.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 **/
|
/** Anti 002 fix for IOS 249 rev > 12 thanks to WiiPower **/
|
||||||
bool Anti_002_fix(u8 * Address, int Size)
|
bool Anti_002_fix(u8 * Address, int Size)
|
||||||
@ -149,20 +242,23 @@ static GXRModeObj* vmodes[] =
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static GXRModeObj* PAL2NTSC[] = { &TVMpal480IntDf, &TVNtsc480IntDf, &TVPal264Ds, &TVNtsc240Ds, &TVPal264DsAa,
|
static GXRModeObj* PAL2NTSC[] = { &TVMpal480IntDf, &TVNtsc480IntDf, &TVPal264Ds, &TVNtsc240Ds, &TVPal264DsAa,
|
||||||
&TVNtsc240DsAa, &TVPal264Int, &TVNtsc240Int, &TVPal264IntAa, &TVNtsc240IntAa, &TVPal524IntAa, &TVNtsc480IntAa,
|
&TVNtsc240DsAa, &TVPal264Int, &TVNtsc240Int, &TVPal264IntAa, &TVNtsc240IntAa, &TVPal524IntAa, &TVNtsc480IntAa,
|
||||||
&TVPal528Int, &TVNtsc480IntAa, &TVPal528IntDf, &TVNtsc480IntDf, &TVPal574IntDfScale, &TVNtsc480IntDf,
|
&TVPal528Int, &TVNtsc480IntAa, &TVPal528IntDf, &TVNtsc480IntDf, &TVPal574IntDfScale, &TVNtsc480IntDf,
|
||||||
&TVEurgb60Hz240Ds, &TVNtsc240Ds, &TVEurgb60Hz240DsAa, &TVNtsc240DsAa, &TVEurgb60Hz240Int, &TVNtsc240Int,
|
&TVEurgb60Hz240Ds, &TVNtsc240Ds, &TVEurgb60Hz240DsAa, &TVNtsc240DsAa, &TVEurgb60Hz240Int, &TVNtsc240Int,
|
||||||
&TVEurgb60Hz240IntAa, &TVNtsc240IntAa, &TVEurgb60Hz480Int, &TVNtsc480IntAa, &TVEurgb60Hz480IntDf,
|
&TVEurgb60Hz240IntAa, &TVNtsc240IntAa, &TVEurgb60Hz480Int, &TVNtsc480IntAa, &TVEurgb60Hz480IntDf,
|
||||||
&TVNtsc480IntDf, &TVEurgb60Hz480IntAa, &TVNtsc480IntAa, &TVEurgb60Hz480Prog, &TVNtsc480Prog,
|
&TVNtsc480IntDf, &TVEurgb60Hz480IntAa, &TVNtsc480IntAa, &TVEurgb60Hz480Prog, &TVNtsc480Prog,
|
||||||
&TVEurgb60Hz480ProgSoft, &TVNtsc480Prog, &TVEurgb60Hz480ProgAa, &TVNtsc480Prog, 0, 0 };
|
&TVEurgb60Hz480ProgSoft, &TVNtsc480Prog, &TVEurgb60Hz480ProgAa, &TVNtsc480Prog, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
static GXRModeObj* NTSC2PAL[] = { &TVNtsc240Ds, &TVPal264Ds, &TVNtsc240DsAa, &TVPal264DsAa, &TVNtsc240Int,
|
static GXRModeObj* NTSC2PAL[] = { &TVNtsc240Ds, &TVPal264Ds, &TVNtsc240DsAa, &TVPal264DsAa, &TVNtsc240Int,
|
||||||
&TVPal264Int, &TVNtsc240IntAa, &TVPal264IntAa, &TVNtsc480IntDf, &TVPal528IntDf, &TVNtsc480IntAa,
|
&TVPal264Int, &TVNtsc240IntAa, &TVPal264IntAa, &TVNtsc480IntDf, &TVPal528IntDf, &TVNtsc480IntAa,
|
||||||
&TVPal524IntAa, &TVNtsc480Prog, &TVPal528IntDf, 0, 0 };
|
&TVPal524IntAa, &TVNtsc480Prog, &TVPal528IntDf, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
static GXRModeObj* NTSC2PAL60[] = { &TVNtsc240Ds, &TVEurgb60Hz240Ds, &TVNtsc240DsAa, &TVEurgb60Hz240DsAa,
|
static GXRModeObj* NTSC2PAL60[] = { &TVNtsc240Ds, &TVEurgb60Hz240Ds, &TVNtsc240DsAa, &TVEurgb60Hz240DsAa,
|
||||||
&TVNtsc240Int, &TVEurgb60Hz240Int, &TVNtsc240IntAa, &TVEurgb60Hz240IntAa, &TVNtsc480IntDf,
|
&TVNtsc240Int, &TVEurgb60Hz240Int, &TVNtsc240IntAa, &TVEurgb60Hz240IntAa, &TVNtsc480IntDf,
|
||||||
&TVEurgb60Hz480IntDf, &TVNtsc480IntAa, &TVEurgb60Hz480IntAa, &TVNtsc480Prog, &TVEurgb60Hz480Prog, 0, 0 };
|
&TVEurgb60Hz480IntDf, &TVNtsc480IntAa, &TVEurgb60Hz480IntAa, &TVNtsc480Prog, &TVEurgb60Hz480Prog, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
static bool compare_videomodes(GXRModeObj* mode1, GXRModeObj* mode2)
|
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))
|
while (Size >= sizeof(GXRModeObj))
|
||||||
{
|
{
|
||||||
|
|
||||||
for (i = 0; Table[i]; i += 2)
|
for (i = 0; Table[i]; i += 2)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (compare_videomodes(Table[i], (GXRModeObj*) Addr))
|
if (compare_videomodes(Table[i], (GXRModeObj*) Addr))
|
||||||
|
|
||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
patch_videomode((GXRModeObj*) Addr, Table[i + 1]);
|
patch_videomode((GXRModeObj*) Addr, Table[i + 1]);
|
||||||
@ -282,25 +375,25 @@ void VideoModePatcher(u8 * dst, int len, u8 videoSelected)
|
|||||||
{
|
{
|
||||||
switch (CONF_GetVideo())
|
switch (CONF_GetVideo())
|
||||||
{
|
{
|
||||||
case CONF_VIDEO_PAL:
|
case CONF_VIDEO_PAL:
|
||||||
if (CONF_GetEuRGB60() > 0)
|
if (CONF_GetEuRGB60() > 0)
|
||||||
{
|
{
|
||||||
table = NTSC2PAL60;
|
table = NTSC2PAL60;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
table = NTSC2PAL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONF_VIDEO_MPAL:
|
|
||||||
|
|
||||||
table = NTSC2PAL;
|
table = NTSC2PAL;
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
case CONF_VIDEO_MPAL:
|
||||||
table = PAL2NTSC;
|
|
||||||
break;
|
table = NTSC2PAL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
table = PAL2NTSC;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Search_and_patch_Video_Modes(dst, len, table);
|
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 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 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 )
|
bool PatchReturnTo( void *Address, int Size, u32 id )
|
||||||
{
|
{
|
||||||
if( !id || patched )
|
if( !id || returnToPatched )
|
||||||
return 0;
|
return 0;
|
||||||
//gprintf("PatchReturnTo( %p, %08x, %08x )\n", Address, Size, id );
|
//gprintf("PatchReturnTo( %p, %08x, %08x )\n", Address, Size, id );
|
||||||
|
|
||||||
//new __OSLoadMenu() (SM2.0 and higher)
|
//new __OSLoadMenu() (SM2.0 and higher)
|
||||||
u8 SearchPattern[ 12 ] = { 0x38, 0x80, 0x00, 0x02, 0x38, 0x60, 0x00, 0x01, 0x38, 0xa0, 0x00, 0x00 }; //li r4,2
|
u8 SearchPattern[ 12 ] = { 0x38, 0x80, 0x00, 0x02, 0x38, 0x60, 0x00, 0x01, 0x38, 0xa0, 0x00, 0x00 }; //li r4,2
|
||||||
//li r3,1
|
//li r3,1
|
||||||
//li r5,0
|
//li r5,0
|
||||||
//old _OSLoadMenu() (used in launch games)
|
//old _OSLoadMenu() (used in launch games)
|
||||||
u8 SearchPatternB[ 12 ] = { 0x38, 0xC0, 0x00, 0x02, 0x38, 0xA0, 0x00, 0x01, 0x38, 0xE0, 0x00, 0x00 }; //li r6,2
|
u8 SearchPatternB[ 12 ] = { 0x38, 0xC0, 0x00, 0x02, 0x38, 0xA0, 0x00, 0x01, 0x38, 0xE0, 0x00, 0x00 }; //li r6,2
|
||||||
//li r5,1
|
//li r5,1
|
||||||
//li r7,0
|
//li r7,0
|
||||||
//identifier for the safe place
|
//identifier for the safe place
|
||||||
u8 SearchPattern2[ 12 ] = { 0x4D, 0x65, 0x74, 0x72, 0x6F, 0x77, 0x65, 0x72, 0x6B, 0x73, 0x20, 0x54 }; //"Metrowerks T"
|
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 = Address;
|
||||||
void *Addr_end = Address+Size;
|
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 ) {
|
//find a safe place or the patch to hang out
|
||||||
ad[ 3 ] = (u32)Addr + 0x30;
|
if ( ! ad[ 3 ] && memcmp( Addr, SearchPattern2, 12 ) == 0 )
|
||||||
}
|
{
|
||||||
//find __OSLaunchMenu() and remember some addresses in it
|
ad[ 3 ] = (u32)Addr + 0x30;
|
||||||
else if ( memcmp( Addr, SearchPattern, 12 )==0 ) {
|
}
|
||||||
ad[ found++ ] = (u32)Addr;
|
//find __OSLaunchMenu() and remember some addresses in it
|
||||||
}
|
else if ( memcmp( Addr, SearchPattern, 12 )==0 )
|
||||||
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
|
{
|
||||||
{
|
ad[ found++ ] = (u32)Addr;
|
||||||
if( !ad[ 1 ] ) ad[ found++ ] = (u32)Addr;
|
}
|
||||||
else if( !ad[ 2 ] ) 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( found >= 3 )break;
|
{
|
||||||
}
|
if( !ad[ 1 ] ) ad[ found++ ] = (u32)Addr;
|
||||||
Addr += 4;
|
else if( !ad[ 2 ] ) ad[ found++ ] = (u32)Addr;
|
||||||
|
if( found >= 3 )break;
|
||||||
|
}
|
||||||
|
Addr += 4;
|
||||||
}
|
}
|
||||||
//check for the older-ass version of the SDK
|
//check for the older-ass version of the SDK
|
||||||
if( found < 3 && ad[ 3 ] )
|
if( found < 3 && ad[ 3 ] )
|
||||||
{
|
{
|
||||||
Addr = Address;
|
Addr = Address;
|
||||||
ad[ 0 ] = 0; ad[ 1 ] = 0;
|
ad[ 0 ] = 0;
|
||||||
ad[ 2 ] = 0;
|
ad[ 1 ] = 0;
|
||||||
found = 0;
|
ad[ 2 ] = 0;
|
||||||
oldSDK = 1;
|
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 ) {
|
//find __OSLaunchMenu() and remember some addresses in it
|
||||||
ad[ found++ ] = (u32)Addr;
|
if ( memcmp( Addr, SearchPatternB, 12 )==0 )
|
||||||
}
|
{
|
||||||
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
|
ad[ found++ ] = (u32)Addr;
|
||||||
{
|
}
|
||||||
if( !ad[ 1 ] ) 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
|
||||||
else if( !ad[ 2 ] ) ad[ found++ ] = (u32)Addr;
|
{
|
||||||
if( found >= 3 )break;
|
if( !ad[ 1 ] ) ad[ found++ ] = (u32)Addr;
|
||||||
}
|
else if( !ad[ 2 ] ) ad[ found++ ] = (u32)Addr;
|
||||||
Addr += 4;
|
if( found >= 3 )break;
|
||||||
}
|
}
|
||||||
|
Addr += 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//if the function is found
|
//if the function is found
|
||||||
if( found == 3 && ad[ 3 ] )
|
if( found == 3 && ad[ 3 ] )
|
||||||
{
|
{
|
||||||
//gprintf("patch __OSLaunchMenu( 0x00010001, 0x%08x )\n", id);
|
//gprintf("patch __OSLaunchMenu( 0x00010001, 0x%08x )\n", id);
|
||||||
u32 nop = 0x60000000;
|
u32 nop = 0x60000000;
|
||||||
|
|
||||||
//the magic that writes the TID to the registers
|
//the magic that writes the TID to the registers
|
||||||
u8 jump[ 20 ] = { 0x3C, 0x60, 0x00, 0x01, //lis r3,1
|
u8 jump[ 20 ] = { 0x3C, 0x60, 0x00, 0x01, //lis r3,1
|
||||||
0x60, 0x63, 0x00, 0x01, //ori r3,r3,1
|
0x60, 0x63, 0x00, 0x01, //ori r3,r3,1
|
||||||
0x3C, 0x80, (u8)( id >> 24 ), (u8)( id >> 16 ), //lis r4,(u16)(tid >> 16)
|
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)
|
0x60, 0x84, (u8)( id >> 8 ), (u8)id, //ori r4,r4,(u16)(tid)
|
||||||
0x4E, 0x80, 0x00, 0x20 }; //blr
|
0x4E, 0x80, 0x00, 0x20
|
||||||
|
}; //blr
|
||||||
|
|
||||||
if( oldSDK )
|
if( oldSDK )
|
||||||
{
|
{
|
||||||
jump[ 1 ] = 0xA0; //3CA00001 //lis r5,1
|
jump[ 1 ] = 0xA0; //3CA00001 //lis r5,1
|
||||||
jump[ 5 ] = 0xA5; //60A50001 //ori r5,r5,1
|
jump[ 5 ] = 0xA5; //60A50001 //ori r5,r5,1
|
||||||
jump[ 9 ] = 0xC0; //3CC0AF1B //lis r6,(u16)(tid >> 16)
|
jump[ 9 ] = 0xC0; //3CC0AF1B //lis r6,(u16)(tid >> 16)
|
||||||
jump[ 13 ] = 0xC6;//60C6F516 //ori r6,r6,(u16)(tid)
|
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
|
//write new stuff to in a unused part of the main.dol
|
||||||
memcpy( addr, jump, sizeof( jump ) );
|
memcpy( addr, jump, sizeof( jump ) );
|
||||||
|
|
||||||
//ES_GetTicketViews()
|
//ES_GetTicketViews()
|
||||||
u32 newval = ( ad[ 3 ] - ad[ 0 ] );
|
u32 newval = ( ad[ 3 ] - ad[ 0 ] );
|
||||||
newval &= 0x03FFFFFC;
|
newval &= 0x03FFFFFC;
|
||||||
newval |= 0x48000001;
|
newval |= 0x48000001;
|
||||||
addr = (u32*)ad[ 0 ];
|
addr = (u32*)ad[ 0 ];
|
||||||
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
|
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
|
||||||
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
|
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
|
||||||
//gprintf("\t%08x -> %08x\n", addr, newval );
|
//gprintf("\t%08x -> %08x\n", addr, newval );
|
||||||
|
|
||||||
//ES_GetTicketViews() again
|
//ES_GetTicketViews() again
|
||||||
newval = ( ad[ 3 ] - ad[ 1 ] );
|
newval = ( ad[ 3 ] - ad[ 1 ] );
|
||||||
newval &= 0x03FFFFFC;
|
newval &= 0x03FFFFFC;
|
||||||
newval |= 0x48000001;
|
newval |= 0x48000001;
|
||||||
addr = (u32*)ad[ 1 ];
|
addr = (u32*)ad[ 1 ];
|
||||||
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
|
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
|
||||||
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
|
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
|
||||||
//gprintf("\t%08x -> %08x\n", addr, newval );
|
//gprintf("\t%08x -> %08x\n", addr, newval );
|
||||||
|
|
||||||
//ES_LaunchTitle()
|
//ES_LaunchTitle()
|
||||||
newval = ( ad[ 3 ] - ad[ 2 ] );
|
newval = ( ad[ 3 ] - ad[ 2 ] );
|
||||||
newval &= 0x03FFFFFC;
|
newval &= 0x03FFFFFC;
|
||||||
newval |= 0x48000001;
|
newval |= 0x48000001;
|
||||||
addr = (u32*)ad[ 2 ];
|
addr = (u32*)ad[ 2 ];
|
||||||
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
|
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
|
||||||
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
|
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
|
||||||
//gprintf("\t%08x -> %08x\n", addr, newval );
|
//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 returnToPatched;
|
||||||
return patched;
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,16 @@ extern "C" {
|
|||||||
|
|
||||||
#include <gccore.h>
|
#include <gccore.h>
|
||||||
|
|
||||||
|
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 Anti_002_fix(u8 * Address, int Size);
|
||||||
bool NSMBPatch();
|
bool NSMBPatch();
|
||||||
bool PoPPatch();
|
bool PoPPatch();
|
||||||
bool Search_and_patch_Video_Modes(u8 * Address, u32 Size, GXRModeObj* Table[]);
|
|
||||||
void VideoModePatcher(u8 * dst, int len, u8 videoSelected);
|
void VideoModePatcher(u8 * dst, int len, u8 videoSelected);
|
||||||
bool PatchReturnTo(void *Address, int Size, u32 id);
|
bool PatchReturnTo(void *Address, int Size, u32 id);
|
||||||
|
int PatchNewReturnTo(u64 title);
|
||||||
|
bool BlockIOSReload(u8 blockiosreloadselect);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
//#include "fwrite_patch_slota.h"
|
//#include "fwrite_patch_slota.h"
|
||||||
//#include "main.h"
|
//#include "main.h"
|
||||||
|
|
||||||
|
u32 hooktype = 0;
|
||||||
|
|
||||||
extern const char * CheatFilepath;
|
extern const char * CheatFilepath;
|
||||||
|
|
||||||
extern void patchhook(u32 address, u32 len);
|
extern void patchhook(u32 address, u32 len);
|
||||||
|
@ -27,10 +27,7 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
// Globals
|
// Globals
|
||||||
u32 hooktype;
|
extern u32 hooktype;
|
||||||
int patched;
|
|
||||||
//u8 configbytes[2];
|
|
||||||
//u32 regionfree;
|
|
||||||
|
|
||||||
// Function prototypes
|
// Function prototypes
|
||||||
bool dogamehooks(void *addr, u32 len);
|
bool dogamehooks(void *addr, u32 len);
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "usbloader/AlternateDOLOffsets.h"
|
#include "usbloader/AlternateDOLOffsets.h"
|
||||||
#include "language/gettext.h"
|
#include "language/gettext.h"
|
||||||
#include "wad/nandtitle.h"
|
#include "wad/nandtitle.h"
|
||||||
|
#include "system/IosLoader.h"
|
||||||
#include "GameLoadSM.hpp"
|
#include "GameLoadSM.hpp"
|
||||||
|
|
||||||
static const char * OnOffText[] =
|
static const char * OnOffText[] =
|
||||||
@ -90,6 +91,13 @@ static const char * AlternateDOLText[] =
|
|||||||
trNOOP( "Default" ),
|
trNOOP( "Default" ),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char * IOSReloadBlockText[] =
|
||||||
|
{
|
||||||
|
trNOOP( "OFF" ),
|
||||||
|
trNOOP( "Method 1" ),
|
||||||
|
trNOOP( "Method 2" ),
|
||||||
|
};
|
||||||
|
|
||||||
GameLoadSM::GameLoadSM(const char * GameID)
|
GameLoadSM::GameLoadSM(const char * GameID)
|
||||||
: SettingsMenu(tr("Game Load"), &GuiOptions, MENU_NONE)
|
: SettingsMenu(tr("Game Load"), &GuiOptions, MENU_NONE)
|
||||||
{
|
{
|
||||||
@ -160,37 +168,37 @@ void GameLoadSM::SetOptionValues()
|
|||||||
int Idx = 0;
|
int Idx = 0;
|
||||||
|
|
||||||
//! Settings: Video Mode
|
//! Settings: Video Mode
|
||||||
if(GameConfig.video == -1)
|
if(GameConfig.video == INHERIT)
|
||||||
Options->SetValue(Idx++, tr("Use global"));
|
Options->SetValue(Idx++, tr("Use global"));
|
||||||
else
|
else
|
||||||
Options->SetValue(Idx++, "%s", tr(VideoModeText[GameConfig.video]));
|
Options->SetValue(Idx++, "%s", tr(VideoModeText[GameConfig.video]));
|
||||||
|
|
||||||
//! Settings: VIDTV Patch
|
//! Settings: VIDTV Patch
|
||||||
if(GameConfig.vipatch == -1)
|
if(GameConfig.vipatch == INHERIT)
|
||||||
Options->SetValue(Idx++, tr("Use global"));
|
Options->SetValue(Idx++, tr("Use global"));
|
||||||
else
|
else
|
||||||
Options->SetValue(Idx++, "%s", tr(OnOffText[GameConfig.vipatch]));
|
Options->SetValue(Idx++, "%s", tr(OnOffText[GameConfig.vipatch]));
|
||||||
|
|
||||||
//! Settings: Game Language
|
//! Settings: Game Language
|
||||||
if(GameConfig.language == -1)
|
if(GameConfig.language == INHERIT)
|
||||||
Options->SetValue(Idx++, tr("Use global"));
|
Options->SetValue(Idx++, tr("Use global"));
|
||||||
else
|
else
|
||||||
Options->SetValue(Idx++, "%s", tr(LanguageText[GameConfig.language]));
|
Options->SetValue(Idx++, "%s", tr(LanguageText[GameConfig.language]));
|
||||||
|
|
||||||
//! Settings: Patch Country Strings
|
//! Settings: Patch Country Strings
|
||||||
if(GameConfig.patchcountrystrings == -1)
|
if(GameConfig.patchcountrystrings == INHERIT)
|
||||||
Options->SetValue(Idx++, tr("Use global"));
|
Options->SetValue(Idx++, tr("Use global"));
|
||||||
else
|
else
|
||||||
Options->SetValue(Idx++, "%s", tr(OnOffText[GameConfig.patchcountrystrings]));
|
Options->SetValue(Idx++, "%s", tr(OnOffText[GameConfig.patchcountrystrings]));
|
||||||
|
|
||||||
//! Settings: Ocarina
|
//! Settings: Ocarina
|
||||||
if(GameConfig.ocarina == -1)
|
if(GameConfig.ocarina == INHERIT)
|
||||||
Options->SetValue(Idx++, tr("Use global"));
|
Options->SetValue(Idx++, tr("Use global"));
|
||||||
else
|
else
|
||||||
Options->SetValue(Idx++, "%s", tr(OnOffText[GameConfig.ocarina]));
|
Options->SetValue(Idx++, "%s", tr(OnOffText[GameConfig.ocarina]));
|
||||||
|
|
||||||
//! Settings: Game IOS
|
//! Settings: Game IOS
|
||||||
if(GameConfig.ios == -1)
|
if(GameConfig.ios == INHERIT)
|
||||||
Options->SetValue(Idx++, tr("Use global"));
|
Options->SetValue(Idx++, tr("Use global"));
|
||||||
else
|
else
|
||||||
Options->SetValue(Idx++, "%i", GameConfig.ios);
|
Options->SetValue(Idx++, "%i", GameConfig.ios);
|
||||||
@ -199,7 +207,7 @@ void GameLoadSM::SetOptionValues()
|
|||||||
Options->SetValue(Idx++, "%s", tr(ParentalText[GameConfig.parentalcontrol]));
|
Options->SetValue(Idx++, "%s", tr(ParentalText[GameConfig.parentalcontrol]));
|
||||||
|
|
||||||
//! Settings: Error 002 fix
|
//! Settings: Error 002 fix
|
||||||
if(GameConfig.errorfix002 == -1)
|
if(GameConfig.errorfix002 == INHERIT)
|
||||||
Options->SetValue(Idx++, tr("Use global"));
|
Options->SetValue(Idx++, tr("Use global"));
|
||||||
else
|
else
|
||||||
Options->SetValue(Idx++, "%s", tr(Error002Text[GameConfig.errorfix002]));
|
Options->SetValue(Idx++, "%s", tr(Error002Text[GameConfig.errorfix002]));
|
||||||
@ -234,7 +242,12 @@ void GameLoadSM::SetOptionValues()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Settings: Block IOS Reload
|
//! 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
|
//! Settings: Game Lock
|
||||||
Options->SetValue(Idx++, "%s", tr( OnOffText[GameConfig.Locked] ));
|
Options->SetValue(Idx++, "%s", tr( OnOffText[GameConfig.Locked] ));
|
||||||
@ -376,7 +389,11 @@ int GameLoadSM::GetMenuInternal()
|
|||||||
//! Settings: Block IOS Reload
|
//! Settings: Block IOS Reload
|
||||||
else if (ret == ++Idx)
|
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
|
//! Settings: Game Lock
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#include <ogc/machine/processor.h>
|
|
||||||
#include "menu/menus.h"
|
#include "menu/menus.h"
|
||||||
#include "menu/WDMMenu.hpp"
|
#include "menu/WDMMenu.hpp"
|
||||||
#include "mload/mload.h"
|
#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,
|
u32 GameBooter::BootPartition(char * dolpath, u8 videoselected, u8 alternatedol, u32 alternatedoloffset)
|
||||||
u8 alternatedol, u32 alternatedoloffset, u32 returnTo, u8 fix002)
|
|
||||||
{
|
{
|
||||||
gprintf("booting partition IOS %u r%u\n", IOS_GetVersion(), IOS_GetRevision());
|
gprintf("booting partition IOS %u r%u\n", IOS_GetVersion(), IOS_GetRevision());
|
||||||
entry_point p_entry;
|
entry_point p_entry;
|
||||||
@ -76,8 +74,7 @@ u32 GameBooter::BootPartition(char * dolpath, u8 videoselected, u8 languageChoic
|
|||||||
Disc_SelectVMode(videoselected);
|
Disc_SelectVMode(videoselected);
|
||||||
|
|
||||||
/* Run apploader */
|
/* Run apploader */
|
||||||
ret = Apploader_Run(&p_entry, dolpath, cheat, videoselected, languageChoice, vipatch, patchcountrystring,
|
ret = Apploader_Run(&p_entry, dolpath, alternatedol, alternatedoloffset);
|
||||||
alternatedol, alternatedoloffset, returnTo, fix002);
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -205,40 +202,11 @@ int GameBooter::BootGame(const char * gameID)
|
|||||||
u8 alternatedol = game_cfg->loadalternatedol;
|
u8 alternatedol = game_cfg->loadalternatedol;
|
||||||
u32 alternatedoloffset = game_cfg->alternatedolstart;
|
u32 alternatedoloffset = game_cfg->alternatedolstart;
|
||||||
u8 reloadblock = game_cfg->iosreloadblock;
|
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
|
//! Prepare alternate dol settings
|
||||||
SetupAltDOL(gameHeader.id, alternatedol, alternatedoloffset);
|
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
|
//! This is temporary - C <-> C++ transfer
|
||||||
SetCheatFilepath(Settings.Cheatcodespath);
|
SetCheatFilepath(Settings.Cheatcodespath);
|
||||||
SetBCAFilepath(Settings.BcaCodepath);
|
SetBCAFilepath(Settings.BcaCodepath);
|
||||||
@ -263,11 +231,13 @@ int GameBooter::BootGame(const char * gameID)
|
|||||||
gprintf("%d\n", ret);
|
gprintf("%d\n", ret);
|
||||||
|
|
||||||
//! Setup IOS reload block - only possible on Hermes cIOS
|
//! Setup IOS reload block - only possible on Hermes cIOS
|
||||||
if (reloadblock == ON && IosLoader::IsHermesIOS())
|
if (reloadblock && IosLoader::IsHermesIOS())
|
||||||
{
|
{
|
||||||
enable_ES_ioctlv_vector();
|
enable_ES_ioctlv_vector();
|
||||||
if (gameList.GetGameFS(gameHeader.id) == PART_FS_WBFS)
|
if (gameList.GetGameFS(gameHeader.id) == PART_FS_WBFS)
|
||||||
mload_close();
|
mload_close();
|
||||||
|
|
||||||
|
reloadblock = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Now we can free up the memory used by the game list
|
//! 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
|
//! Load main.dol or alternative dol into memory, start the game apploader and get game entrypoint
|
||||||
gprintf("\tDisc_wiiBoot\n");
|
gprintf("\tDisc_wiiBoot\n");
|
||||||
AppEntrypoint = BootPartition(Settings.dolpath, videoChoice, languageChoice, ocarinaChoice, viChoice, countrystrings,
|
AppEntrypoint = BootPartition(Settings.dolpath, videoChoice, alternatedol, alternatedoloffset);
|
||||||
alternatedol, alternatedoloffset, channel, fix002);
|
|
||||||
|
|
||||||
//! No entrypoint found...back to HBC/SystemMenu
|
//! No entrypoint found...back to HBC/SystemMenu
|
||||||
if(AppEntrypoint == 0)
|
if(AppEntrypoint == 0)
|
||||||
@ -285,6 +254,9 @@ int GameBooter::BootGame(const char * gameID)
|
|||||||
Sys_BackToLoader();
|
Sys_BackToLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Do all the game patches
|
||||||
|
gamepatches(videoChoice, languageChoice, countrystrings, viChoice, ocarinaChoice, fix002, reloadblock, returnToChoice);
|
||||||
|
|
||||||
//! Load Ocarina codes
|
//! Load Ocarina codes
|
||||||
bool enablecheat = false;
|
bool enablecheat = false;
|
||||||
if (ocarinaChoice)
|
if (ocarinaChoice)
|
||||||
|
@ -13,8 +13,7 @@ class GameBooter
|
|||||||
static void SetupAltDOL(u8 * gameID, u8 &alternatedol, u32 &alternatedoloffset);
|
static void SetupAltDOL(u8 * gameID, u8 &alternatedol, u32 &alternatedoloffset);
|
||||||
static int SetupDisc(u8 *gameID);
|
static int SetupDisc(u8 *gameID);
|
||||||
static bool LoadOcarina(u8 *gameID);
|
static bool LoadOcarina(u8 *gameID);
|
||||||
static u32 BootPartition(char * dolpath, u8 videoselected, u8 languageChoice, u8 cheat, u8 vipatch,
|
static u32 BootPartition(char * dolpath, u8 videoselected, u8 alternatedol, u32 alternatedoloffset);
|
||||||
u8 patchcountrystring, u8 alternatedol, u32 alternatedoloffset, u32 returnTo, u8 fix002);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
|
#include "patches/gamepatches.h"
|
||||||
#include "apploader.h"
|
#include "apploader.h"
|
||||||
#include "wdvd.h"
|
#include "wdvd.h"
|
||||||
#include "fstfile.h"
|
#include "fstfile.h"
|
||||||
@ -85,7 +86,7 @@ bool Load_Dol(void **buffer, int* dollen, const char * filepath)
|
|||||||
return true;
|
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)
|
if (!dolstart)
|
||||||
return 0;
|
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;
|
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]);
|
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,
|
RegisterDOL((u8 *) dolfile->text_start[i], dolfile->text_size[i]);
|
||||||
vipatch, cheat, returnTo, fix002);
|
|
||||||
Remove_001_Protection((void *) 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]);
|
DCFlushRange((void *) dolfile->data_start[i], dolfile->data_size[i]);
|
||||||
ICInvalidateRange((void *) dolfile->text_start[i], dolfile->text_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;
|
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]);
|
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,
|
RegisterDOL((u8 *) dolfile->data_start[i], dolfile->data_size[i]);
|
||||||
vipatch, cheat, returnTo, fix002);
|
|
||||||
Remove_001_Protection((void *) 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]);
|
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;
|
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;
|
s32 ret;
|
||||||
dolheader * dolfile;
|
dolheader * dolfile;
|
||||||
@ -164,7 +163,7 @@ u32 Load_Dol_from_disc(u32 offset, u8 videoSelected, u8 languageChoice, u8 patch
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gamepatches(buffer, size, videoSelected, languageChoice, patchcountrystring, vipatch, cheat, returnTo, fix002);
|
RegisterDOL((u8 *) buffer, size);
|
||||||
Remove_001_Protection(buffer, size);
|
Remove_001_Protection(buffer, size);
|
||||||
DCFlushRange(buffer, size);
|
DCFlushRange(buffer, size);
|
||||||
ICInvalidateRange(buffer, size);
|
ICInvalidateRange(buffer, size);
|
||||||
@ -185,7 +184,7 @@ u32 Load_Dol_from_disc(u32 offset, u8 videoSelected, u8 languageChoice, u8 patch
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gamepatches(buffer, size, videoSelected, languageChoice, patchcountrystring, vipatch, cheat, returnTo, fix002);
|
RegisterDOL((u8 *) buffer, size);
|
||||||
Remove_001_Protection(buffer, size);
|
Remove_001_Protection(buffer, size);
|
||||||
DCFlushRange(buffer, size);
|
DCFlushRange(buffer, size);
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,8 @@ extern "C"
|
|||||||
|
|
||||||
/* not the full path is needed here, the path where the dol is */
|
/* not the full path is needed here, the path where the dol is */
|
||||||
bool Load_Dol(void **buffer, int* dollen, const char * filepath);
|
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_image(void *dolstart);
|
||||||
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);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
#include "patches/patchcode.h"
|
|
||||||
#include "apploader.h"
|
#include "apploader.h"
|
||||||
#include "wdvd.h"
|
#include "wdvd.h"
|
||||||
#include "wpad.h"
|
#include "wpad.h"
|
||||||
@ -11,8 +10,6 @@
|
|||||||
#include "alternatedol.h"
|
#include "alternatedol.h"
|
||||||
#include "fstfile.h"
|
#include "fstfile.h"
|
||||||
#include "gecko.h"
|
#include "gecko.h"
|
||||||
#include "patches/wip.h"
|
|
||||||
#include "patches/dolpatcher.h"
|
|
||||||
#include "patches/gamepatches.h"
|
#include "patches/gamepatches.h"
|
||||||
#include "settings/SettingsEnums.h"
|
#include "settings/SettingsEnums.h"
|
||||||
|
|
||||||
@ -33,33 +30,7 @@ static u8 *appldr = (u8 *) 0x81200000;
|
|||||||
/* Variables */
|
/* Variables */
|
||||||
static u32 buffer[0x20] ATTRIBUTE_ALIGN( 32 );
|
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 )
|
s32 Apploader_Run(entry_point *entry, char * dolpath, u8 alternatedol, u32 alternatedoloffset)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
app_entry appldr_entry;
|
app_entry appldr_entry;
|
||||||
app_init appldr_init;
|
app_init appldr_init;
|
||||||
@ -90,12 +61,6 @@ s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected
|
|||||||
/* Initialize apploader */
|
/* Initialize apploader */
|
||||||
appldr_init(gprintf);
|
appldr_init(gprintf);
|
||||||
|
|
||||||
if (fix002 != 0)
|
|
||||||
{
|
|
||||||
/* ERROR 002 fix (thanks to WiiPower for sharing this)*/
|
|
||||||
*(u32 *) 0x80003188 = *(u32 *) 0x80003140;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
void *dst = NULL;
|
void *dst = NULL;
|
||||||
@ -108,8 +73,7 @@ s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected
|
|||||||
/* Read data from DVD */
|
/* Read data from DVD */
|
||||||
WDVD_Read(dst, len, (u64) (offset << 2));
|
WDVD_Read(dst, len, (u64) (offset << 2));
|
||||||
|
|
||||||
if( !alternatedol )
|
RegisterDOL((u8 *) dst, len);
|
||||||
gamepatches(dst, len, videoSelected, languageChoice, patchcountrystring, vipatch, cheat, returnTo, fix002 );
|
|
||||||
|
|
||||||
DCFlushRange(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 **/
|
/** Load alternate dol if set **/
|
||||||
if (alternatedol == ALT_DOL_FROM_SD_USB)
|
if (alternatedol == ALT_DOL_FROM_SD_USB)
|
||||||
{
|
{
|
||||||
wip_reset_counter();
|
ClearDOLList();
|
||||||
void *dolbuffer = NULL;
|
void *dolbuffer = NULL;
|
||||||
int dollen = 0;
|
int dollen = 0;
|
||||||
|
|
||||||
bool dolloaded = Load_Dol(&dolbuffer, &dollen, dolpath);
|
bool dolloaded = Load_Dol(&dolbuffer, &dollen, dolpath);
|
||||||
if (dolloaded)
|
if (dolloaded)
|
||||||
{
|
*entry = (entry_point) load_dol_image(dolbuffer);
|
||||||
*entry = (entry_point) load_dol_image(dolbuffer, videoSelected, languageChoice, patchcountrystring, vipatch, cheat, fix002, returnTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dolbuffer) free(dolbuffer);
|
if (dolbuffer) free(dolbuffer);
|
||||||
}
|
}
|
||||||
else if (alternatedol == ALT_DOL_FROM_GAME && alternatedoloffset != 0)
|
else if (alternatedol == ALT_DOL_FROM_GAME && alternatedoloffset != 0)
|
||||||
{
|
{
|
||||||
wip_reset_counter();
|
ClearDOLList();
|
||||||
FST_ENTRY *fst = (FST_ENTRY *) *(u32 *) 0x80000038;
|
FST_ENTRY *fst = (FST_ENTRY *) *(u32 *) 0x80000038;
|
||||||
|
|
||||||
//! Check if it's inside the limits
|
//! Check if it's inside the limits
|
||||||
if(alternatedoloffset >= fst[0].filelen)
|
if(alternatedoloffset >= fst[0].filelen)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
*entry = (entry_point) Load_Dol_from_disc(fst[alternatedoloffset].fileoffset, videoSelected, languageChoice,
|
*entry = (entry_point) Load_Dol_from_disc(fst[alternatedoloffset].fileoffset);
|
||||||
patchcountrystring, vipatch, cheat, fix002, returnTo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -10,9 +10,7 @@ extern "C"
|
|||||||
typedef void (*entry_point)(void);
|
typedef void (*entry_point)(void);
|
||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected, u8 languageChoice, u8 vipatch,
|
s32 Apploader_Run(entry_point *entry, char * dolpath, u8 alternatedol, u32 alternatedoloffset);
|
||||||
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 );
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -246,14 +246,14 @@ bool NandTitle::Exists(u64 tid)
|
|||||||
|
|
||||||
bool NandTitle::ExistsFromIndex(u32 i)
|
bool NandTitle::ExistsFromIndex(u32 i)
|
||||||
{
|
{
|
||||||
if (i > titleIds.size()) return false;
|
if (i >= titleIds.size()) return false;
|
||||||
|
|
||||||
return Exists(titleIds.at(i));
|
return Exists(titleIds.at(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NandTitle::At(u32 i)
|
u64 NandTitle::At(u32 i)
|
||||||
{
|
{
|
||||||
if (i > titleIds.size()) return 0;
|
if (i >= titleIds.size()) return 0;
|
||||||
|
|
||||||
return titleIds.at(i);
|
return titleIds.at(i);
|
||||||
}
|
}
|
||||||
@ -278,7 +278,7 @@ const char* NandTitle::NameOf(u64 tid)
|
|||||||
|
|
||||||
const char* NandTitle::NameFromIndex(u32 i)
|
const char* NandTitle::NameFromIndex(u32 i)
|
||||||
{
|
{
|
||||||
if (i > titleIds.size()) return NULL;
|
if (i >= titleIds.size()) return NULL;
|
||||||
|
|
||||||
map<u64, string>::iterator itr = NameList.find(titleIds.at(i));
|
map<u64, string>::iterator itr = NameList.find(titleIds.at(i));
|
||||||
if (itr != NameList.end()) return itr->second.c_str();
|
if (itr != NameList.end()) return itr->second.c_str();
|
||||||
@ -304,7 +304,7 @@ u16 NandTitle::VersionOf(u64 tid)
|
|||||||
|
|
||||||
u16 NandTitle::VersionFromIndex(u32 i)
|
u16 NandTitle::VersionFromIndex(u32 i)
|
||||||
{
|
{
|
||||||
if (i > titleIds.size()) return 0;
|
if (i >= titleIds.size()) return 0;
|
||||||
|
|
||||||
tmd* Tmd = GetTMD(titleIds.at(i));
|
tmd* Tmd = GetTMD(titleIds.at(i));
|
||||||
if (!Tmd) return 0;
|
if (!Tmd) return 0;
|
||||||
@ -377,7 +377,7 @@ void NandTitle::AsciiTID(u64 tid, char* out)
|
|||||||
|
|
||||||
void NandTitle::AsciiFromIndex(u32 i, char* out)
|
void NandTitle::AsciiFromIndex(u32 i, char* out)
|
||||||
{
|
{
|
||||||
if (i > titleIds.size())
|
if (i >= titleIds.size())
|
||||||
{
|
{
|
||||||
out[0] = 0;
|
out[0] = 0;
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user