2009-07-31 14:45:14 +02:00
|
|
|
#include <ogcsys.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <gccore.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <malloc.h>
|
|
|
|
|
|
|
|
#include "fatmounter.h"
|
|
|
|
#include "apploader.h"
|
|
|
|
#include "wdvd.h"
|
|
|
|
#include "fstfile.h"
|
2009-09-29 10:09:09 +02:00
|
|
|
#include "../patches/dvd_broadway.h"
|
|
|
|
|
2009-10-01 11:17:55 +02:00
|
|
|
extern u8 mountMethod;
|
2009-07-31 14:45:14 +02:00
|
|
|
|
|
|
|
/** Alternate dolloader made by WiiPower modified by dimok **/
|
2010-09-19 01:16:05 +02:00
|
|
|
bool Load_Dol( void **buffer, int* dollen, char * filepath )
|
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
int ret;
|
|
|
|
FILE* file;
|
|
|
|
void* dol_buffer;
|
|
|
|
|
|
|
|
char fullpath[200];
|
|
|
|
char gameidbuffer6[7];
|
2010-09-19 01:16:05 +02:00
|
|
|
memset( gameidbuffer6, 0, 7 );
|
|
|
|
memcpy( gameidbuffer6, ( char* )0x80000000, 6 );
|
|
|
|
snprintf( fullpath, 200, "%s%s.dol", filepath, gameidbuffer6 );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-05-29 09:38:54 +02:00
|
|
|
// SDCard_Init();
|
|
|
|
// USBDevice_Init();
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
file = fopen( fullpath, "rb" );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( file == NULL )
|
|
|
|
{
|
|
|
|
fclose( file );
|
|
|
|
// SDCard_deInit();
|
|
|
|
// USBDevice_deInit();
|
2009-07-31 14:45:14 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int filesize;
|
2010-09-19 01:16:05 +02:00
|
|
|
fseek( file, 0, SEEK_END );
|
|
|
|
filesize = ftell( file );
|
|
|
|
fseek( file, 0, SEEK_SET );
|
|
|
|
|
|
|
|
dol_buffer = malloc( filesize );
|
|
|
|
if ( dol_buffer == NULL )
|
|
|
|
{
|
|
|
|
fclose( file );
|
|
|
|
// SDCard_deInit();
|
|
|
|
// USBDevice_deInit();
|
2010-05-29 09:38:54 +02:00
|
|
|
return false;
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
2010-09-19 01:16:05 +02:00
|
|
|
ret = fread( dol_buffer, 1, filesize, file );
|
|
|
|
if ( ret != filesize )
|
|
|
|
{
|
|
|
|
free( dol_buffer );
|
|
|
|
fclose( file );
|
|
|
|
// SDCard_deInit();
|
|
|
|
// USBDevice_deInit();
|
2010-05-29 09:38:54 +02:00
|
|
|
return false;
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
2010-09-19 01:16:05 +02:00
|
|
|
fclose( file );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
// SDCard_deInit();
|
|
|
|
// USBDevice_deInit();
|
2009-07-31 14:45:14 +02:00
|
|
|
*buffer = dol_buffer;
|
|
|
|
*dollen = filesize;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
bool Remove_001_Protection( void *Address, int Size )
|
|
|
|
{
|
|
|
|
u8 SearchPattern[16] = { 0x40, 0x82, 0x00, 0x0C, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18 };
|
|
|
|
u8 PatchData[16] = { 0x40, 0x82, 0x00, 0x04, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18 };
|
2009-07-31 14:45:14 +02:00
|
|
|
|
|
|
|
void *Addr = Address;
|
2010-09-19 01:16:05 +02:00
|
|
|
void *Addr_end = Address + Size;
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
while ( Addr <= Addr_end - sizeof( SearchPattern ) )
|
|
|
|
{
|
|
|
|
if ( memcmp( Addr, SearchPattern, sizeof( SearchPattern ) ) == 0 )
|
|
|
|
{
|
|
|
|
memcpy( Addr, PatchData, sizeof( PatchData ) );
|
2009-07-31 14:45:14 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
Addr += 4;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
typedef struct _dolheader
|
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
u32 text_pos[7];
|
|
|
|
u32 data_pos[11];
|
|
|
|
u32 text_start[7];
|
|
|
|
u32 data_start[11];
|
|
|
|
u32 text_size[7];
|
|
|
|
u32 data_size[11];
|
|
|
|
u32 bss_start;
|
|
|
|
u32 bss_size;
|
|
|
|
u32 entry_point;
|
|
|
|
} dolheader;
|
|
|
|
|
|
|
|
static dolheader *dolfile;
|
|
|
|
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
u32 load_dol_image( void *dolstart, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat )
|
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
|
|
|
|
u32 i;
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( dolstart )
|
|
|
|
{
|
|
|
|
dolfile = ( dolheader * ) dolstart;
|
|
|
|
for ( i = 0; i < 7; i++ )
|
|
|
|
{
|
|
|
|
if ( ( !dolfile->text_size[i] ) || ( dolfile->text_start[i] < 0x100 ) ) continue;
|
|
|
|
|
|
|
|
ICInvalidateRange ( ( void * ) dolfile->text_start[i], dolfile->text_size[i] );
|
|
|
|
memmove ( ( void * ) dolfile->text_start[i], dolstart + dolfile->text_pos[i], dolfile->text_size[i] );
|
|
|
|
gamepatches( ( void * ) dolfile->text_start[i], dolfile->text_size[i], videoSelected, patchcountrystring, vipatch, cheat );
|
|
|
|
Remove_001_Protection( ( void * ) dolfile->data_start[i], dolfile->data_size[i] );
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
for ( i = 0; i < 11; i++ )
|
|
|
|
{
|
|
|
|
if ( ( !dolfile->data_size[i] ) || ( dolfile->data_start[i] < 0x100 ) ) continue;
|
2010-05-30 08:49:23 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
memmove ( ( void * ) dolfile->data_start[i], dolstart + dolfile->data_pos[i], dolfile->data_size[i] );
|
|
|
|
gamepatches( ( void * ) dolfile->data_start[i], dolfile->data_size[i], videoSelected, patchcountrystring, vipatch, cheat );
|
|
|
|
Remove_001_Protection( ( void * ) dolfile->data_start[i], dolfile->data_size[i] );
|
|
|
|
DCFlushRangeNoSync ( ( void * ) dolfile->data_start[i], dolfile->data_size[i] );
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
memset ((void *) dolfile->bss_start, 0, dolfile->bss_size);
|
|
|
|
DCFlushRange((void *) dolfile->bss_start, dolfile->bss_size);
|
|
|
|
*/
|
|
|
|
return dolfile->entry_point;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int i;
|
|
|
|
static int phase;
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
u32 load_dol_start( void *dolstart )
|
|
|
|
{
|
|
|
|
if ( dolstart )
|
|
|
|
{
|
|
|
|
dolfile = ( dolheader * )dolstart;
|
2009-07-31 14:45:14 +02:00
|
|
|
return dolfile->entry_point;
|
2010-09-19 01:16:05 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
memset( ( void * )dolfile->bss_start, 0, dolfile->bss_size );
|
|
|
|
DCFlushRange( ( void * )dolfile->bss_start, dolfile->bss_size );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
|
|
|
phase = 0;
|
|
|
|
i = 0;
|
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
bool load_dol_image_modified( void **offset, u32 *pos, u32 *len )
|
|
|
|
{
|
|
|
|
if ( phase == 0 )
|
|
|
|
{
|
|
|
|
if ( i == 7 )
|
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
phase = 1;
|
|
|
|
i = 0;
|
2010-09-19 01:16:05 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( ( !dolfile->text_size[i] ) || ( dolfile->text_start[i] < 0x100 ) )
|
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
*offset = 0;
|
|
|
|
*pos = 0;
|
|
|
|
*len = 0;
|
2010-09-19 01:16:05 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*offset = ( void * )dolfile->text_start[i];
|
2009-07-31 14:45:14 +02:00
|
|
|
*pos = dolfile->text_pos[i];
|
|
|
|
*len = dolfile->text_size[i];
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( phase == 1 )
|
|
|
|
{
|
|
|
|
if ( i == 11 )
|
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
phase = 2;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( ( !dolfile->data_size[i] ) || ( dolfile->data_start[i] < 0x100 ) )
|
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
*offset = 0;
|
|
|
|
*pos = 0;
|
|
|
|
*len = 0;
|
2010-09-19 01:16:05 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*offset = ( void * )dolfile->data_start[i];
|
2009-07-31 14:45:14 +02:00
|
|
|
*pos = dolfile->data_pos[i];
|
|
|
|
*len = dolfile->data_size[i];
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2009-09-29 10:09:09 +02:00
|
|
|
static vu32 dvddone = 0;
|
2010-09-19 01:16:05 +02:00
|
|
|
void __dvd_readidcb( s32 result )
|
2010-02-09 11:59:55 +01:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
dvddone = result;
|
2009-09-29 10:09:09 +02:00
|
|
|
}
|
2010-09-19 01:16:05 +02:00
|
|
|
u32 Load_Dol_from_disc( u32 doloffset, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat )
|
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
int ret;
|
|
|
|
void *dol_header;
|
|
|
|
u32 entrypoint;
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
dol_header = memalign( 32, sizeof( dolheader ) );
|
|
|
|
if ( dol_header == NULL )
|
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( !mountMethod )ret = WDVD_Read( dol_header, sizeof( dolheader ), ( doloffset << 2 ) );
|
2010-05-29 17:43:19 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
dvddone = 0;
|
|
|
|
ret = bwDVD_LowRead( dol_header, sizeof( dolheader ), doloffset, __dvd_readidcb );
|
|
|
|
while ( ret >= 0 && dvddone == 0 );
|
|
|
|
}
|
2010-05-29 17:43:19 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
entrypoint = load_dol_start( dol_header );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( entrypoint == 0 )
|
|
|
|
{
|
|
|
|
free( dol_header );
|
2009-07-31 14:45:14 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *offset;
|
|
|
|
u32 pos;
|
|
|
|
u32 len;
|
2010-05-29 17:43:19 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
while ( load_dol_image_modified( &offset, &pos, &len ) )
|
|
|
|
{
|
|
|
|
if ( len != 0 )
|
|
|
|
{
|
|
|
|
ret = WDVD_Read( offset, len, ( doloffset << 2 ) + pos );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
gamepatches( offset, len, videoSelected, patchcountrystring, vipatch, cheat );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
Remove_001_Protection( offset, len );
|
2010-05-30 08:49:23 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
DCFlushRange( offset, len );
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
}
|
2010-05-29 09:38:54 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
free( dol_header );
|
2009-07-31 14:45:14 +02:00
|
|
|
|
|
|
|
return entrypoint;
|
2009-09-29 10:09:09 +02:00
|
|
|
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|