mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-25 20:56:53 +01:00
9e79c9d99b
* code cleanup
496 lines
12 KiB
C
496 lines
12 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ogcsys.h>
|
|
#include <ogc/lwp_watchdog.h>
|
|
#include <wiiuse/wpad.h>
|
|
|
|
#include "patches/fst.h"
|
|
#include "patches/gamepatches.h"
|
|
#include "patches/wip.h"
|
|
#include "apploader.h"
|
|
#include "disc.h"
|
|
#include "video.h"
|
|
#include "wdvd.h"
|
|
#include "alternatedol.h"
|
|
#include "memory.h"
|
|
#include "wbfs.h"
|
|
#include "../gecko.h"
|
|
#include "../fatmounter.h"
|
|
|
|
/* Constants */
|
|
#define PTABLE_OFFSET 0x40000
|
|
#define WII_MAGIC 0x5D1C9EA3
|
|
|
|
//appentrypoint
|
|
u32 appentrypoint;
|
|
|
|
/* Disc pointers */
|
|
static u32 *buffer = ( u32 * )0x93000000;
|
|
static u8 *diskid = ( u8 * )Disc_ID;
|
|
|
|
void __Disc_SetLowMem( void )
|
|
{
|
|
|
|
*Sys_Magic = 0x0D15EA5E; // Standard Boot Code
|
|
*Version = 0x00000001; // Version
|
|
*Arena_L = 0x00000000; // Arena Low
|
|
*BI2 = 0x817E5480; // BI2
|
|
*Bus_Speed = 0x0E7BE2C0; // Console Bus Speed
|
|
*CPU_Speed = 0x2B73A840; // Console CPU Speed
|
|
|
|
/* Setup low memory */
|
|
*Assembler = 0x38A00040; // Assembler
|
|
*( u32 * )0x800000E4 = 0x80431A80;
|
|
*Dev_Debugger = 0x81800000; // Dev Debugger Monitor Address
|
|
*Simulated_Mem = 0x01800000; // Simulated Memory Size
|
|
*( vu32 * )0xCD00643C = 0x00000000; // 32Mhz on Bus
|
|
|
|
//If the game is sam & max: season 1 put this shit in
|
|
char gameid[8];
|
|
memset( gameid, 0, 8 );
|
|
memcpy( gameid, ( char* )Disc_ID, 6 );
|
|
|
|
if ( ( strcmp( gameid, "R3XE6U" ) == 0 ) || ( strcmp( gameid, "R3XP6V" ) == 0 ) )
|
|
{
|
|
*GameID_Address = 0x80000000; // Game ID Address
|
|
}
|
|
|
|
/* Copy disc ID */
|
|
memcpy( ( void * )Online_Check, ( void * )Disc_ID, 4 );
|
|
|
|
/* Flush cache */
|
|
DCFlushRange( ( void * )Disc_ID, 0x3F00 );
|
|
}
|
|
|
|
void __Disc_SetVMode( u8 videoselected )
|
|
{
|
|
GXRModeObj *vmode = NULL;
|
|
|
|
u32 progressive, tvmode, vmode_reg = 0;
|
|
|
|
/* Get video mode configuration */
|
|
progressive = ( CONF_GetProgressiveScan() > 0 ) && VIDEO_HaveComponentCable();
|
|
tvmode = CONF_GetVideo();
|
|
|
|
/* Select video mode register */
|
|
switch ( tvmode )
|
|
{
|
|
case CONF_VIDEO_PAL:
|
|
vmode_reg = ( CONF_GetEuRGB60() > 0 ) ? 5 : 1;
|
|
break;
|
|
|
|
case CONF_VIDEO_MPAL:
|
|
vmode_reg = 4;
|
|
break;
|
|
|
|
case CONF_VIDEO_NTSC:
|
|
vmode_reg = 0;
|
|
break;
|
|
}
|
|
|
|
switch ( videoselected )
|
|
{
|
|
case 0:
|
|
|
|
/* Select video mode */
|
|
switch ( diskid[3] )
|
|
{
|
|
/* PAL */
|
|
case 'P':
|
|
case 'D':
|
|
case 'F':
|
|
case 'I':
|
|
case 'S':
|
|
case 'H':
|
|
case 'X':
|
|
case 'Y':
|
|
case 'Z':
|
|
if ( tvmode != CONF_VIDEO_PAL )
|
|
{
|
|
vmode_reg = 5;
|
|
vmode = ( progressive ) ? &TVNtsc480Prog : &TVEurgb60Hz480IntDf;
|
|
}
|
|
|
|
break;
|
|
|
|
/* NTSC or unknown */
|
|
case 'E':
|
|
case 'J':
|
|
case 'K':
|
|
case 'W':
|
|
if ( tvmode != CONF_VIDEO_NTSC )
|
|
{
|
|
vmode_reg = 0;
|
|
vmode = ( progressive ) ? &TVNtsc480Prog : &TVNtsc480IntDf;
|
|
}
|
|
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
vmode = &TVPal528IntDf;
|
|
vmode_reg = ( vmode->viTVMode ) >> 2;
|
|
break;
|
|
case 2:
|
|
progressive = ( CONF_GetProgressiveScan() > 0 ) && VIDEO_HaveComponentCable();
|
|
vmode = ( progressive ) ? &TVNtsc480Prog : &TVEurgb60Hz480IntDf;
|
|
vmode_reg = ( vmode->viTVMode ) >> 2;
|
|
break;
|
|
case 3:
|
|
progressive = ( CONF_GetProgressiveScan() > 0 ) && VIDEO_HaveComponentCable();
|
|
vmode = ( progressive ) ? &TVNtsc480Prog : &TVNtsc480IntDf;
|
|
vmode_reg = ( vmode->viTVMode ) >> 2;
|
|
break;
|
|
case 4:
|
|
// vmode = VIDEO_GetPreferredMode(NULL);
|
|
break;
|
|
}
|
|
|
|
/* Set video mode register */
|
|
*Video_Mode = vmode_reg;
|
|
|
|
/* Set video mode */
|
|
if ( vmode )
|
|
{
|
|
|
|
VIDEO_Configure( vmode );
|
|
|
|
/* Setup video */
|
|
VIDEO_SetBlack( FALSE );
|
|
VIDEO_Flush();
|
|
VIDEO_WaitVSync();
|
|
|
|
if ( vmode->viTVMode & VI_NON_INTERLACE )
|
|
VIDEO_WaitVSync();
|
|
}
|
|
gprintf( "\nVideo mode - %s", ( ( progressive ) ? "progressive" : "interlaced" ) );
|
|
|
|
}
|
|
|
|
void __Disc_SetTime( void )
|
|
{
|
|
/* Extern */
|
|
extern void settime( u64 );
|
|
|
|
/* Set proper time */
|
|
settime( secs_to_ticks( time( NULL ) - 946684800 ) );
|
|
}
|
|
|
|
s32 __Disc_FindPartition( u64 *outbuf )
|
|
{
|
|
u64 offset = 0, table_offset = 0;
|
|
|
|
u32 cnt, nb_partitions;
|
|
s32 ret;
|
|
|
|
/* Read partition info */
|
|
ret = WDVD_UnencryptedRead( buffer, 0x20, PTABLE_OFFSET );
|
|
if ( ret < 0 )
|
|
return ret;
|
|
|
|
/* Get data */
|
|
nb_partitions = buffer[0];
|
|
table_offset = buffer[1] << 2;
|
|
|
|
/* Read partition table */
|
|
ret = WDVD_UnencryptedRead( buffer, 0x20, table_offset );
|
|
if ( ret < 0 )
|
|
return ret;
|
|
|
|
/* Find game partition */
|
|
for ( cnt = 0; cnt < nb_partitions; cnt++ )
|
|
{
|
|
u32 type = buffer[cnt * 2 + 1];
|
|
|
|
/* Game partition */
|
|
if ( !type )
|
|
offset = buffer[cnt * 2] << 2;
|
|
}
|
|
|
|
/* No game partition found */
|
|
if ( !offset )
|
|
return -1;
|
|
|
|
/* Set output buffer */
|
|
*outbuf = offset;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
s32 Disc_Init( void )
|
|
{
|
|
/* Init DVD subsystem */
|
|
return WDVD_Init();
|
|
}
|
|
|
|
s32 Disc_Open( void )
|
|
{
|
|
s32 ret;
|
|
|
|
/* Reset drive */
|
|
ret = WDVD_Reset();
|
|
if ( ret < 0 )
|
|
return ret;
|
|
|
|
/* Read disc ID */
|
|
return WDVD_ReadDiskId( diskid );
|
|
}
|
|
|
|
s32 Disc_Wait( void )
|
|
{
|
|
u32 cover = 0;
|
|
s32 ret;
|
|
|
|
/* Wait for disc */
|
|
while ( !( cover & 0x2 ) )
|
|
{
|
|
/* Get cover status */
|
|
ret = WDVD_GetCoverStatus( &cover );
|
|
if ( ret < 0 )
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 Disc_SetUSB( const u8 *id )
|
|
{
|
|
u32 part = 0;
|
|
if ( wbfs_part_fs )
|
|
{
|
|
part = wbfs_part_lba;
|
|
}
|
|
else
|
|
{
|
|
part = wbfs_part_idx ? wbfs_part_idx - 1 : 0;
|
|
}
|
|
|
|
/* Set USB mode */
|
|
return WDVD_SetUSBMode( id, part );
|
|
}
|
|
|
|
s32 Disc_ReadHeader( void *outbuf )
|
|
{
|
|
/* Read disc header */
|
|
return WDVD_UnencryptedRead( outbuf, sizeof( struct discHdr ), 0 );
|
|
}
|
|
|
|
s32 Disc_IsWii( void )
|
|
{
|
|
struct discHdr *header = ( struct discHdr * )buffer;
|
|
|
|
s32 ret;
|
|
|
|
/* Read disc header */
|
|
ret = Disc_ReadHeader( header );
|
|
if ( ret < 0 )
|
|
return ret;
|
|
|
|
/* Check magic word */
|
|
if ( header->magic != WII_MAGIC )
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 Disc_BootPartition( u64 offset, u8 videoselected, u8 cheat, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol, u32 alternatedoloffset )
|
|
{
|
|
entry_point p_entry;
|
|
|
|
s32 ret;
|
|
|
|
/* Open specified partition */
|
|
ret = WDVD_OpenPartition( offset );
|
|
if ( ret < 0 )
|
|
return ret;
|
|
|
|
/* Setup low memory */
|
|
__Disc_SetLowMem();
|
|
|
|
char gameid[8];
|
|
memset( gameid, 0, 8 );
|
|
memcpy( gameid, ( char* )Disc_ID, 6 );
|
|
|
|
load_wip_code( ( u8 * ) &gameid );
|
|
|
|
/* If a wip file is loaded for this game this does nothing - Dimok */
|
|
PoPPatch();
|
|
|
|
/* Run apploader */
|
|
ret = Apploader_Run( &p_entry, cheat, videoselected, vipatch, patchcountrystring, error002fix, alternatedol, alternatedoloffset );
|
|
if ( ret < 0 )
|
|
return ret;
|
|
|
|
free_wip();
|
|
|
|
bool cheatloaded = false;
|
|
|
|
if ( cheat )
|
|
{
|
|
/* OCARINA STUFF - FISHEARS*/
|
|
if ( ocarina_load_code( ( u8 * ) gameid ) > 0 )
|
|
{
|
|
ocarina_do_code();
|
|
cheatloaded = true;
|
|
}
|
|
}
|
|
|
|
//kill the USB and SD
|
|
USBDevice_deInit();
|
|
SDCard_deInit();
|
|
|
|
/* Set an appropiate video mode */
|
|
__Disc_SetVMode( videoselected );
|
|
|
|
/* Set time */
|
|
__Disc_SetTime();
|
|
|
|
//gprintf("\n\tDe-init SD & USB");
|
|
|
|
/* Disconnect Wiimote */
|
|
WPAD_Flush( 0 );
|
|
WPAD_Disconnect( 0 );
|
|
WPAD_Shutdown();
|
|
|
|
// Anti-green screen fix
|
|
VIDEO_SetBlack( TRUE );
|
|
VIDEO_Flush();
|
|
VIDEO_WaitVSync();
|
|
gprintf( "\n\nUSB Loader GX is done.\n\n" );
|
|
|
|
/* Shutdown IOS subsystems */
|
|
// fix for PeppaPig (from NeoGamma)
|
|
extern void __exception_closeall();
|
|
IRQ_Disable();
|
|
__IOS_ShutdownSubsystems();
|
|
__exception_closeall();
|
|
|
|
appentrypoint = ( u32 ) p_entry;
|
|
|
|
if ( cheat == 1 && cheatloaded )
|
|
{
|
|
__asm__(
|
|
"lis %r3, appentrypoint@h\n"
|
|
"ori %r3, %r3, appentrypoint@l\n"
|
|
"lwz %r3, 0(%r3)\n"
|
|
"mtlr %r3\n"
|
|
"lis %r3, 0x8000\n"
|
|
"ori %r3, %r3, 0x18A8\n"
|
|
"mtctr %r3\n"
|
|
"bctr\n"
|
|
);
|
|
}
|
|
else
|
|
{
|
|
__asm__(
|
|
"lis %r3, appentrypoint@h\n"
|
|
"ori %r3, %r3, appentrypoint@l\n"
|
|
"lwz %r3, 0(%r3)\n"
|
|
"mtlr %r3\n"
|
|
"blr\n"
|
|
);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 Disc_WiiBoot( u8 videoselected, u8 cheat, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol, u32 alternatedoloffset )
|
|
{
|
|
u64 offset;
|
|
s32 ret;
|
|
|
|
/* Find game partition offset */
|
|
ret = __Disc_FindPartition( &offset );
|
|
if ( ret < 0 )
|
|
return ret;
|
|
|
|
/* Boot partition */
|
|
return Disc_BootPartition( offset, videoselected, cheat, vipatch, patchcountrystring, error002fix, alternatedol, alternatedoloffset );
|
|
}
|
|
|
|
|
|
|
|
void PatchCountryStrings( void *Address, int Size )
|
|
{
|
|
u8 SearchPattern[4] = { 0x00, 0x00, 0x00, 0x00 };
|
|
u8 PatchData[4] = { 0x00, 0x00, 0x00, 0x00 };
|
|
u8 *Addr = ( u8* )Address;
|
|
|
|
int wiiregion = CONF_GetRegion();
|
|
|
|
switch ( wiiregion )
|
|
{
|
|
case CONF_REGION_JP:
|
|
SearchPattern[0] = 0x00;
|
|
SearchPattern[1] = 0x4A; // J
|
|
SearchPattern[2] = 0x50; // P
|
|
break;
|
|
case CONF_REGION_EU:
|
|
SearchPattern[0] = 0x02;
|
|
SearchPattern[1] = 0x45; // E
|
|
SearchPattern[2] = 0x55; // U
|
|
break;
|
|
case CONF_REGION_KR:
|
|
SearchPattern[0] = 0x04;
|
|
SearchPattern[1] = 0x4B; // K
|
|
SearchPattern[2] = 0x52; // R
|
|
break;
|
|
case CONF_REGION_CN:
|
|
SearchPattern[0] = 0x05;
|
|
SearchPattern[1] = 0x43; // C
|
|
SearchPattern[2] = 0x4E; // N
|
|
break;
|
|
case CONF_REGION_US:
|
|
default:
|
|
SearchPattern[0] = 0x01;
|
|
SearchPattern[1] = 0x55; // U
|
|
SearchPattern[2] = 0x53; // S
|
|
}
|
|
|
|
switch ( diskid[3] )
|
|
{
|
|
case 'J':
|
|
PatchData[1] = 0x4A; // J
|
|
PatchData[2] = 0x50; // P
|
|
break;
|
|
|
|
case 'D':
|
|
case 'F':
|
|
case 'P':
|
|
case 'X':
|
|
case 'Y':
|
|
PatchData[1] = 0x45; // E
|
|
PatchData[2] = 0x55; // U
|
|
break;
|
|
|
|
case 'E':
|
|
default:
|
|
PatchData[1] = 0x55; // U
|
|
PatchData[2] = 0x53; // S
|
|
}
|
|
|
|
while ( Size >= 4 )
|
|
{
|
|
if ( Addr[0] == SearchPattern[0] && Addr[1] == SearchPattern[1] && Addr[2] == SearchPattern[2] && Addr[3] == SearchPattern[3] )
|
|
{
|
|
//*Addr = PatchData[0];
|
|
Addr += 1;
|
|
*Addr = PatchData[1];
|
|
Addr += 1;
|
|
*Addr = PatchData[2];
|
|
Addr += 1;
|
|
//*Addr = PatchData[3];
|
|
Addr += 1;
|
|
Size -= 4;
|
|
}
|
|
else
|
|
{
|
|
Addr += 4;
|
|
Size -= 4;
|
|
}
|
|
}
|
|
}
|