usbloadergx/source/usbloader/apploader.c

160 lines
4.2 KiB
C
Raw Normal View History

2009-07-31 14:45:14 +02:00
#include <stdio.h>
#include <ogcsys.h>
#include <string.h>
#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"
#include "gecko.h"
#include "patches/wip.h"
#include "patches/dolpatcher.h"
#include "patches/gamepatches.h"
2009-07-31 14:45:14 +02:00
extern bool geckoinit;
2009-07-31 14:45:14 +02:00
/* Apploader function pointers */
2010-09-24 02:48:03 +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
/* Apploader pointers */
2010-09-24 02:48:03 +02:00
static u8 *appldr = (u8 *) 0x81200000;
/* Constants */
#define APPLDR_OFFSET 0x2440
/* Variables */
static u32 buffer[0x20] ATTRIBUTE_ALIGN( 32 );
2010-09-24 02:48:03 +02:00
void gamepatches(u8 * dst, int len, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat)
{
2010-09-24 02:48:03 +02:00
VideoModePatcher(dst, len, videoSelected);
2009-07-31 14:45:14 +02:00
2010-09-24 02:48:03 +02:00
if (cheat) dogamehooks(dst, len);
2009-07-31 14:45:14 +02:00
2010-09-24 02:48:03 +02:00
if (vipatch) vidolpatcher(dst, len);
2009-07-31 14:45:14 +02:00
/*LANGUAGE PATCH - FISHEARS*/
2010-09-24 02:48:03 +02:00
langpatcher(dst, len);
2009-07-31 14:45:14 +02:00
/*Thanks to WiiPower*/
2010-09-24 02:48:03 +02:00
if (patchcountrystring == 1) PatchCountryStrings(dst, len);
2009-07-31 14:45:14 +02:00
2010-09-24 02:48:03 +02:00
NSMBPatch(dst, len);
2010-09-24 02:48:03 +02:00
do_wip_code((u8 *) dst, len);
2010-09-24 02:48:03 +02:00
if (fix002 == 2) Anti_002_fix(dst, len);
2009-07-31 14:45:14 +02:00
}
2010-09-24 02:48:03 +02:00
s32 Apploader_Run(entry_point *entry, char * dolpath, u8 cheat, u8 videoSelected, u8 vipatch, u8 patchcountrystring,
u8 error002fix, u8 alternatedol, u32 alternatedoloffset, u32 returnTo)
{
2009-07-31 14:45:14 +02:00
app_entry appldr_entry;
2010-09-24 02:48:03 +02:00
app_init appldr_init;
app_main appldr_main;
2009-07-31 14:45:14 +02:00
app_final appldr_final;
u32 appldr_len;
s32 ret;
2010-09-24 02:48:03 +02:00
gprintf("\nApploader_Run() started\n");
//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-24 02:48:03 +02:00
ret = WDVD_Read(buffer, 0x20, APPLDR_OFFSET);
if (ret < 0) return ret;
2009-07-31 14:45:14 +02:00
/* Calculate apploader length */
appldr_len = buffer[5] + buffer[6];
/* Read apploader code */
2010-09-24 02:48:03 +02:00
ret = WDVD_Read(appldr, appldr_len, APPLDR_OFFSET + 0x20);
if (ret < 0) return ret;
/* Set apploader entry function */
2010-09-24 02:48:03 +02:00
appldr_entry = (app_entry) buffer[4];
2009-07-31 14:45:14 +02:00
/* Call apploader entry */
2010-09-24 02:48:03 +02:00
appldr_entry(&appldr_init, &appldr_main, &appldr_final);
2009-07-31 14:45:14 +02:00
/* Initialize apploader */
2010-09-24 02:48:03 +02:00
appldr_init(gprintf);
2010-09-24 02:48:03 +02:00
if (error002fix != 0)
{
2009-07-31 14:45:14 +02:00
/* ERROR 002 fix (thanks to WiiPower for sharing this)*/
2010-09-24 02:48:03 +02:00
*(u32 *) 0x80003188 = *(u32 *) 0x80003140;
2009-07-31 14:45:14 +02:00
}
u32 dolStart = 0x90000000;
u32 dolEnd = 0x0;
2010-09-24 02:48:03 +02:00
for (;;)
{
2009-07-31 14:45:14 +02:00
void *dst = NULL;
int len = 0, offset = 0;
/* Run apploader main function */
2010-09-24 02:48:03 +02:00
ret = appldr_main(&dst, &len, &offset);
if (!ret) break;
2009-07-31 14:45:14 +02:00
/* Read data from DVD */
2010-09-24 02:48:03 +02:00
WDVD_Read(dst, len, (u64) (offset << 2));
2009-07-31 14:45:14 +02:00
2010-09-24 02:48:03 +02:00
gamepatches(dst, len, videoSelected, patchcountrystring, vipatch, cheat);
DCFlushRange(dst, len);
2010-09-24 02:48:03 +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
2010-09-24 02:48:03 +02:00
if (!alternatedol && returnTo)
{
2010-09-24 02:48:03 +02:00
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-24 02:48:03 +02:00
if (alternatedol == 1)
{
wip_reset_counter();
void *dolbuffer = NULL;
int dollen = 0;
2009-07-31 14:45:14 +02:00
2010-09-24 02:48:03 +02:00
bool dolloaded = Load_Dol(&dolbuffer, &dollen, dolpath, videoSelected, patchcountrystring, vipatch, cheat);
if (dolloaded)
{
2010-09-24 02:48:03 +02:00
*entry = (entry_point) load_dol_image(dolbuffer);
}
2010-09-24 02:48:03 +02:00
if (dolbuffer) free(dolbuffer);
}
2010-09-24 02:48:03 +02:00
else if (alternatedol == 2)
{
wip_reset_counter();
2010-09-24 02:48:03 +02:00
FST_ENTRY *fst = (FST_ENTRY *) *(u32 *) 0x80000038;
2009-07-31 14:45:14 +02:00
2010-09-24 02:48:03 +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-24 02:48:03 +02:00
if (*entry == 0) SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
2009-07-31 14:45:14 +02:00
}
return 0;
}