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 "apploader.h"
|
|
|
|
#include "wdvd.h"
|
|
|
|
#include "wpad.h"
|
|
|
|
#include "disc.h"
|
|
|
|
#include "alternatedol.h"
|
|
|
|
#include "fstfile.h"
|
2009-10-21 01:00:19 +02:00
|
|
|
#include "gecko.h"
|
2010-05-30 16:18:25 +02:00
|
|
|
#include "patches/gamepatches.h"
|
2011-06-03 22:31:09 +02:00
|
|
|
#include "patches/wip.h"
|
2011-01-21 20:43:59 +01:00
|
|
|
#include "settings/SettingsEnums.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-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
|
|
|
|
2009-05-03 20:53:31 +02:00
|
|
|
/* Apploader pointers */
|
2010-09-24 02:48:03 +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
|
|
|
|
2011-05-30 21:49:12 +02:00
|
|
|
s32 Apploader_Run(entry_point *entry, char * dolpath, u8 alternatedol, u32 alternatedoloffset)
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
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");
|
2009-11-09 22:49:28 +01:00
|
|
|
|
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;
|
2009-11-09 22:49:28 +01:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
/* 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);
|
2009-11-09 22:49:28 +01:00
|
|
|
|
2010-09-24 02:48:03 +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-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
|
|
|
|
2011-05-30 21:49:12 +02:00
|
|
|
RegisterDOL((u8 *) dst, len);
|
2010-09-19 12:53:24 +02:00
|
|
|
|
2010-11-06 16:30:14 +01:00
|
|
|
DCFlushRange(dst, len);
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
*entry = appldr_final();
|
|
|
|
|
|
|
|
/** Load alternate dol if set **/
|
2011-01-21 20:43:59 +01:00
|
|
|
if (alternatedol == ALT_DOL_FROM_SD_USB)
|
2010-05-30 16:18:25 +02:00
|
|
|
{
|
2011-05-30 21:49:12 +02:00
|
|
|
ClearDOLList();
|
2011-06-03 22:31:09 +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
|
|
|
|
2011-01-21 20:43:59 +01:00
|
|
|
bool dolloaded = Load_Dol(&dolbuffer, &dollen, dolpath);
|
2010-09-24 02:48:03 +02:00
|
|
|
if (dolloaded)
|
2011-05-30 21:49:12 +02:00
|
|
|
*entry = (entry_point) load_dol_image(dolbuffer);
|
2009-11-09 22:49:28 +01:00
|
|
|
|
2010-09-24 02:48:03 +02:00
|
|
|
if (dolbuffer) free(dolbuffer);
|
2010-05-29 17:43:19 +02:00
|
|
|
}
|
2011-01-21 20:43:59 +01:00
|
|
|
else if (alternatedol == ALT_DOL_FROM_GAME && alternatedoloffset != 0)
|
2010-05-29 17:43:19 +02:00
|
|
|
{
|
2011-05-30 21:49:12 +02:00
|
|
|
ClearDOLList();
|
2011-06-03 22:31:09 +02:00
|
|
|
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
|
|
|
|
2011-01-21 20:43:59 +01:00
|
|
|
//! Check if it's inside the limits
|
|
|
|
if(alternatedoloffset >= fst[0].filelen)
|
|
|
|
return 0;
|
|
|
|
|
2011-05-30 21:49:12 +02:00
|
|
|
*entry = (entry_point) Load_Dol_from_disc(fst[alternatedoloffset].fileoffset);
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|