usbloadergx/source/main.c
dimok321 1618b4b1e0 USB Loader GX Release V2.2
New:
- Added game categories and filter games list by categories (Can be imported from WiiTDB).
- Wiinertag support.
- Supporting arguments from meta.xml on boot (--ios=xxx and --usbport=x) (Requires Homebrew Channel 1.0.7+ or 
  UNEO Forwarder v3.0).
- New ehci modules by Rodries with better drive compatibility.
- Added two new video modes to force progressive video mode, 'FORCE PAL480p' and 'FORCE NTSC480p'.
- Added Sneek Video Patch mode.
- Added new 'Inherit' setting for game settings named "Use global". If that option is set then the main loader 
  setting is used.
- Full d2x cIOS support with it's new features (Block IOS Reload, Return To, Sector Sizes > 512).
- Support for sector sizes > 512B with FAT32/NTFS (Requires d2x v6+)
- Real support for simultanious use of both USB ports without switching the 2nd drive temporary off. (Requires 
  Hermes cIOS or Rodries MOD of the Hermes cIOS (recommended))
- Added two new settings menus
- Added saving of game browser position when returning to USB Loader GX

Changes:
- Improved several GUI controls/navigations
- Changed settings menu layout and sorted the items to their correct place (HDD menu, features menu)
- Set games settings to use the global setting by default, set to "use global" to use the main loader settings.
- Use TinyXML instead of MXML (better XML support)
- Updated to new libs (libogc, libfat, libext2fs, libntfs)

Fix:  
- "Return to" option now work for all games, even problematic games like Prince of Persia. (Requires d2x v4+)
- Xflip setting fixed.
- Fix the parental lock of Individual game settings (Thanks to NJ7)
- Fix Theme downloader
- Fixed reset of the loader when loading game with IOS reload and disabled WiiTDB titles
- Fixed timeout timer on startup to count correctly.
- Fixed reversed disc image download when Custom/Original option is selected
- Fixed reload of game list after a game rename
- Fixed horizontal text scrolling
- Fixed booting games by arguments (headless id feature)
- Fixed We Dare game boot (thx oggzee)



R1099 Change Log:
    *Added IOS225 from Rodries cIOS Installer MOD to Hermes IOS types

New Forwarder V3.0 Changes:
    *added support for ext partitions
    *added support for arguments from xml
    *clean up of source
2011-06-29 20:45:40 +00:00

280 lines
6.7 KiB
C

/****************************************************************************
* Copyright 2009 The Lemon Man and thanks to luccax, Wiipower, Aurelio and crediar
* Copyright 2010 Dimok
*
* Original forwarder source by
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#include <gccore.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ogc/machine/processor.h>
#include "video.h"
#include "background_image.h"
#include "dolloader.h"
#include "filelist.h"
#include "devicemounter.h"
#include "cfg.h"
void __exception_setreload(int t);
static int GetXMLArguments(const char *path, struct __argv *args)
{
char xmlpath[200];
snprintf(xmlpath, sizeof(xmlpath), "%s", path);
char *ptr = strrchr(xmlpath, '/');
if(ptr)
ptr[1] = '\0';
else
return -1; // only take full path
strncat(xmlpath, "meta.xml", sizeof(xmlpath));
FILE *fp = fopen(xmlpath, "rb");
if(!fp)
return -1;
fseek(fp, 0, SEEK_END);
int size = ftell(fp);
rewind(fp);
char *fileBuf = (char *) malloc(size+1);
if(!fileBuf)
{
fclose(fp);
return -1;
}
fread(fileBuf, 1, size, fp);
fclose(fp);
fileBuf[size] = '\0';
const int max_len = 1024;
char *entry = (char *) malloc(max_len);
ptr = fileBuf;
while(ptr)
{
char *comment = strstr(ptr, "<!--");
ptr = strstr(ptr, "<arg>");
if(!ptr)
break;
if(comment && comment < ptr)
{
ptr = strstr(ptr, "-->");
continue;
}
ptr += strlen("<arg>");
int len;
for(len = 0; *ptr != '\0' && !(ptr[0] == '<' && ptr[1] == '/') && len < max_len-1; ptr++, len++)
entry[len] = *ptr;
entry[len] = '\0';
char *tmp = (char *) realloc(args->commandLine, args->length + len + 1);
if(!tmp)
break; //out of memory, take what we got until now
args->commandLine = tmp;
strcpy(args->commandLine + args->length - 1, entry);
args->length += len + 1;
}
free(entry);
free(fileBuf);
return 0;
}
static FILE * open_file(const char * dev, char * filepath)
{
sprintf(filepath, "%s:/apps/usbloader_gx/boot.dol", dev);
FILE * exeFile = fopen(filepath ,"rb");
if (exeFile == NULL)
{
sprintf(filepath, "%s:/apps/usbloader_gx/boot.dol", dev);
exeFile = fopen(filepath ,"rb");
}
if (exeFile == NULL)
{
sprintf(filepath, "%s:/apps/usbloadergx/boot.dol", dev);
exeFile = fopen(filepath ,"rb");
}
return exeFile;
}
static bool FindConfigPath(const char * device, char *cfgpath, int maxsize)
{
bool result = false;
snprintf(cfgpath, maxsize, "%s:/config/GXGlobal.cfg", device);
result = cfg_parsefile(cfgpath, maxsize);
if(!result)
{
snprintf(cfgpath, maxsize, "%s:/apps/usbloader_gx/GXGlobal.cfg", device);
result = cfg_parsefile(cfgpath, maxsize);
}
if(!result)
{
snprintf(cfgpath, maxsize, "%s:/apps/usbloadergx/GXGlobal.cfg", device);
result = cfg_parsefile(cfgpath, maxsize);
}
return result;
}
int main(int argc, char **argv)
{
u32 cookie;
FILE *exeFile = NULL;
void * exeBuffer = (void *)EXECUTABLE_MEM_ADDR;
u32 exeSize = 0;
u32 exeEntryPointAddress = 0;
entrypoint exeEntryPoint;
__exception_setreload(0);
/* int videomod */
InitVideo();
/* get imagedata */
u8 * imgdata = GetImageData();
fadein(imgdata);
char filepath[200];
// try SD Card First
SDCard_Init();
if(FindConfigPath(DeviceName[SD], filepath, sizeof(filepath)))
{
strcat(filepath, "boot.dol");
exeFile = fopen(filepath, "rb");
}
if(!exeFile)
exeFile = open_file(DeviceName[SD], filepath);
// if app not found on SD Card try USB
if (exeFile == NULL)
{
USBDevice_Init();
int dev;
for(dev = USB1; dev < MAXDEVICES; ++dev)
{
if(FindConfigPath(DeviceName[dev], filepath, sizeof(filepath)))
{
strcat(filepath, "boot.dol");
exeFile = fopen(filepath, "rb");
}
if(!exeFile)
exeFile = open_file(DeviceName[dev], filepath);
}
}
// if nothing found exiting
if (exeFile == NULL)
{
fadeout(imgdata);
fclose (exeFile);
SDCard_deInit();
USBDevice_deInit();
StopGX();
free(imgdata);
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}
fseek (exeFile, 0, SEEK_END);
exeSize = ftell(exeFile);
rewind (exeFile);
if(fread (exeBuffer, 1, exeSize, exeFile) != exeSize)
{
fadeout(imgdata);
fclose (exeFile);
SDCard_deInit();
USBDevice_deInit();
StopGX();
free(imgdata);
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}
fclose (exeFile);
/* load entry point */
struct __argv args;
bzero(&args, sizeof(args));
args.argvMagic = ARGV_MAGIC;
args.length = strlen(filepath) + 2;
args.commandLine = (char*)malloc(args.length);
if (!args.commandLine) SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
strcpy(args.commandLine, filepath);
GetXMLArguments(filepath, &args);
args.commandLine[args.length - 1] = '\0';
args.argc = 1;
args.argv = &args.commandLine;
args.endARGV = args.argv + 1;
u8 * appboot_buff = (u8 *) malloc(app_booter_dol_size);
if(!appboot_buff)
{
fadeout(imgdata);
SDCard_deInit();
USBDevice_deInit();
StopGX();
free(imgdata);
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}
memcpy(appboot_buff, app_booter_dol, app_booter_dol_size);
exeEntryPointAddress = load_dol_image(appboot_buff, &args);
if(appboot_buff)
free(appboot_buff);
fadeout(imgdata);
SDCard_deInit();
USBDevice_deInit();
StopGX();
free(imgdata);
//! Reset HBC stub so we can leave correct from USB Loader to System Menu
memset((char *) 0x80001804, 0, 8);
DCFlushRange((char *) 0x80001804, 8);
if (exeEntryPointAddress == 0)
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
exeEntryPoint = (entrypoint) exeEntryPointAddress;
/* cleaning up and load dol */
SYS_ResetSystem(SYS_SHUTDOWN, 0, 0);
_CPU_ISR_Disable (cookie);
__exception_closeall ();
exeEntryPoint ();
_CPU_ISR_Restore (cookie);
return 0;
}