2009-07-31 14:45:14 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <ogcsys.h>
|
|
|
|
#include <string.h>
|
2009-07-31 22:15:55 +02:00
|
|
|
#include <malloc.h>
|
2009-07-31 14:45:14 +02:00
|
|
|
|
|
|
|
#include "patches/patchcode.h"
|
|
|
|
#include "apploader.h"
|
|
|
|
#include "wdvd.h"
|
|
|
|
#include "wpad.h"
|
|
|
|
#include "disc.h"
|
|
|
|
#include "alternatedol.h"
|
|
|
|
#include "fstfile.h"
|
|
|
|
#include "settings/cfg.h"
|
2009-10-21 01:00:19 +02:00
|
|
|
#include "gecko.h"
|
2009-12-15 07:04:14 +01:00
|
|
|
#include "patches/wip.h"
|
2010-05-30 16:18:25 +02:00
|
|
|
#include "patches/dolpatcher.h"
|
|
|
|
#include "patches/gamepatches.h"
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2009-10-20 13:46:55 +02:00
|
|
|
extern bool geckoinit;
|
|
|
|
|
2009-07-31 14:45:14 +02:00
|
|
|
/* Apploader function pointers */
|
2010-09-19 01:16:05 +02:00
|
|
|
typedef int ( *app_main )( void **dst, int *size, int *offset );
|
|
|
|
typedef void ( *app_init )( void ( *report )( const char *fmt, ... ) );
|
|
|
|
typedef void *( *app_final )();
|
|
|
|
typedef void ( *app_entry )( void ( **init )( void ( *report )( const char *fmt, ... ) ), int ( **main )(), void *( **final )() );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2009-05-03 20:53:31 +02:00
|
|
|
/* Apploader pointers */
|
2010-09-19 01:16:05 +02:00
|
|
|
static u8 *appldr = ( u8 * )0x81200000;
|
2009-05-03 20:53:31 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* Constants */
|
2010-09-19 01:16:05 +02:00
|
|
|
#define APPLDR_OFFSET 0x2440
|
2009-05-03 20:53:31 +02:00
|
|
|
|
|
|
|
/* Variables */
|
2010-09-19 01:16:05 +02:00
|
|
|
static u32 buffer[0x20] ATTRIBUTE_ALIGN( 32 );
|
2009-05-03 20:53:31 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
void gamepatches( void * dst, int len, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat )
|
2010-02-09 11:59:55 +01:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
VideoModePatcher( dst, len, videoSelected );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( cheat )
|
|
|
|
dogamehooks( dst, len );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( vipatch )
|
|
|
|
vidolpatcher( dst, len );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
|
|
|
/*LANGUAGE PATCH - FISHEARS*/
|
2010-09-19 01:16:05 +02:00
|
|
|
langpatcher( dst, len );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
|
|
|
/*Thanks to WiiPower*/
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( patchcountrystring == 1 )
|
|
|
|
PatchCountryStrings( dst, len );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
NSMBPatch( dst, len );
|
2010-02-27 19:18:01 +01:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
do_wip_code( ( u8 * ) dst, len );
|
2009-11-09 22:49:28 +01:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( fix002 == 2 )
|
|
|
|
Anti_002_fix( dst, len );
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-19 12:53:24 +02:00
|
|
|
s32 Apploader_Run( entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol, u32 alternatedoloffset, u32 returnTo )
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
app_entry appldr_entry;
|
|
|
|
app_init appldr_init;
|
|
|
|
app_main appldr_main;
|
|
|
|
app_final appldr_final;
|
|
|
|
|
|
|
|
u32 appldr_len;
|
|
|
|
s32 ret;
|
2010-09-19 01:16:05 +02:00
|
|
|
gprintf( "\nApploader_Run() started\n" );
|
2009-11-09 22:49:28 +01:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
//u32 geckoattached = usb_isgeckoalive(EXI_CHANNEL_1);
|
|
|
|
//if (geckoattached)usb_flush(EXI_CHANNEL_1);
|
|
|
|
geckoinit = InitGecko();
|
2009-07-31 14:45:14 +02:00
|
|
|
|
|
|
|
/* Read apploader header */
|
2010-09-19 01:16:05 +02:00
|
|
|
ret = WDVD_Read( buffer, 0x20, APPLDR_OFFSET );
|
|
|
|
if ( ret < 0 )
|
2009-07-31 14:45:14 +02:00
|
|
|
return ret;
|
|
|
|
|
|
|
|
/* Calculate apploader length */
|
|
|
|
appldr_len = buffer[5] + buffer[6];
|
|
|
|
|
|
|
|
/* Read apploader code */
|
2010-09-19 01:16:05 +02:00
|
|
|
ret = WDVD_Read( appldr, appldr_len, APPLDR_OFFSET + 0x20 );
|
|
|
|
if ( ret < 0 )
|
2009-07-31 14:45:14 +02:00
|
|
|
return ret;
|
2009-11-09 22:49:28 +01:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
/* Set apploader entry function */
|
|
|
|
appldr_entry = ( app_entry )buffer[4];
|
2009-07-31 14:45:14 +02:00
|
|
|
|
|
|
|
/* Call apploader entry */
|
2010-09-19 01:16:05 +02:00
|
|
|
appldr_entry( &appldr_init, &appldr_main, &appldr_final );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
|
|
|
/* Initialize apploader */
|
2010-09-19 01:04:39 +02:00
|
|
|
appldr_init( gprintf );
|
2009-11-09 22:49:28 +01:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( error002fix != 0 )
|
2010-05-30 16:18:25 +02:00
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
/* ERROR 002 fix (thanks to WiiPower for sharing this)*/
|
2010-09-19 01:16:05 +02:00
|
|
|
*( u32 * )0x80003188 = *( u32 * )0x80003140;
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-19 12:53:24 +02:00
|
|
|
u32 dolStart = 0x90000000;
|
|
|
|
u32 dolEnd = 0x0;
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
for ( ;; )
|
2010-05-30 16:18:25 +02:00
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
void *dst = NULL;
|
|
|
|
int len = 0, offset = 0;
|
|
|
|
|
|
|
|
/* Run apploader main function */
|
2010-09-19 01:16:05 +02:00
|
|
|
ret = appldr_main( &dst, &len, &offset );
|
|
|
|
if ( !ret )
|
2009-07-31 14:45:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
/* Read data from DVD */
|
2010-09-19 01:16:05 +02:00
|
|
|
WDVD_Read( dst, len, ( u64 )( offset << 2 ) );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
gamepatches( dst, len, videoSelected, patchcountrystring, vipatch, cheat );
|
|
|
|
DCFlushRange( dst, len );
|
2010-09-19 12:53:24 +02:00
|
|
|
|
|
|
|
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 );
|
|
|
|
}
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
*entry = appldr_final();
|
|
|
|
|
|
|
|
/** Load alternate dol if set **/
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( alternatedol == 1 )
|
2010-05-30 16:18:25 +02:00
|
|
|
{
|
2010-05-29 17:43:19 +02:00
|
|
|
wip_reset_counter();
|
2010-05-30 16:18:25 +02:00
|
|
|
void *dolbuffer = NULL;
|
|
|
|
int dollen = 0;
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
bool dolloaded = Load_Dol( &dolbuffer, &dollen, Settings.dolpath, videoSelected, patchcountrystring, vipatch, cheat );
|
|
|
|
if ( dolloaded )
|
2010-05-30 08:49:23 +02:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
*entry = ( entry_point ) load_dol_image( dolbuffer );
|
2009-11-09 22:49:28 +01:00
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( dolbuffer )
|
|
|
|
free( dolbuffer );
|
2010-05-29 17:43:19 +02:00
|
|
|
}
|
2010-09-19 01:16:05 +02:00
|
|
|
else if ( alternatedol == 2 )
|
2010-05-29 17:43:19 +02:00
|
|
|
{
|
|
|
|
wip_reset_counter();
|
2010-09-19 01:16:05 +02:00
|
|
|
FST_ENTRY *fst = ( FST_ENTRY * ) * ( u32 * )0x80000038;
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
*entry = ( entry_point ) Load_Dol_from_disc( fst[alternatedoloffset].fileoffset, videoSelected, patchcountrystring, vipatch, cheat );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( *entry == 0 )
|
|
|
|
SYS_ResetSystem( SYS_RETURNTOMENU, 0, 0 );
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|