mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-18 17:29:17 +01:00
f8ae27c2e2
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
258 lines
6.0 KiB
C++
258 lines
6.0 KiB
C++
#include <gctypes.h>
|
|
|
|
#include "IosLoader.h"
|
|
#include "Controls/DeviceHandler.hpp"
|
|
#include "usbloader/usbstorage2.h"
|
|
#include "usbloader/disc.h"
|
|
#include "usbloader/wbfs.h"
|
|
#include "usbloader/wdvd.h"
|
|
#include "wad/nandtitle.h"
|
|
#include "mload/mload_modules.h"
|
|
#include "settings/CSettings.h"
|
|
#include "wad/nandtitle.h"
|
|
#include "mload/mload.h"
|
|
#include "mload/modules/ehcmodule_5.h"
|
|
#include "mload/modules/dip_plugin_249.h"
|
|
#include "mload/modules/odip_frag.h"
|
|
#include "utils/tools.h"
|
|
#include "gecko.h"
|
|
|
|
|
|
/*
|
|
* Buffer variables for the IOS info to avoid loading it several times
|
|
*/
|
|
static int currentIOS = -1;
|
|
static iosinfo_t *currentIOSInfo = NULL;
|
|
|
|
/******************************************************************************
|
|
* Public Methods:
|
|
******************************************************************************/
|
|
/*
|
|
* Check if the ios passed is a Hermes ios.
|
|
*/
|
|
bool IosLoader::IsHermesIOS(s32 ios)
|
|
{
|
|
return (ios == 222 || ios == 223 || ios == 224 || ios == 225 || ios == 202);
|
|
}
|
|
|
|
/*
|
|
* Check if the ios passed is a Waninkoko ios.
|
|
*/
|
|
bool IosLoader::IsWaninkokoIOS(s32 ios)
|
|
{
|
|
if(ios < 200 || ios > 255)
|
|
return false;
|
|
|
|
return !IsHermesIOS(ios);
|
|
}
|
|
|
|
/*
|
|
* Check if the ios passed is a d2x ios.
|
|
*/
|
|
bool IosLoader::IsD2X(s32 ios)
|
|
{
|
|
iosinfo_t *info = GetIOSInfo(ios);
|
|
if(!info)
|
|
return false;
|
|
|
|
bool res = (strncasecmp(info->name, "d2x", 3) == 0);
|
|
|
|
return res;
|
|
}
|
|
|
|
/*
|
|
* Loads CIOS (If possible the one from the settings file).
|
|
* @return 0 if a cios has been successfully loaded. Else a value below 0 is returned.
|
|
*/
|
|
s32 IosLoader::LoadAppCios()
|
|
{
|
|
u32 activeCios = IOS_GetVersion();
|
|
s32 ret = -1;
|
|
|
|
// We have what we need
|
|
if((int) activeCios == Settings.cios)
|
|
return 0;
|
|
|
|
u32 ciosLoadPriority[] = { Settings.cios, 222, 249, 250, 245, 246, 247, 248 }; // Ascending.
|
|
|
|
|
|
for (u32 i = 0; i < (sizeof(ciosLoadPriority)/sizeof(ciosLoadPriority[0])); ++i)
|
|
{
|
|
u32 cios = ciosLoadPriority[i];
|
|
|
|
if (activeCios == cios)
|
|
{
|
|
ret = 0;
|
|
break;
|
|
}
|
|
|
|
if ((ret = ReloadIosSafe(cios)) > -1)
|
|
{
|
|
// Remember working cios.
|
|
Settings.cios = cios;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*
|
|
* Loads a CIOS before a game start.
|
|
* @return 0 if a cios has been successfully loaded. Else a value below 0 is returned.
|
|
*/
|
|
s32 IosLoader::LoadGameCios(s32 ios)
|
|
{
|
|
if(ios == IOS_GetVersion())
|
|
return 0;
|
|
|
|
s32 ret = -1;
|
|
|
|
// Unmount fat before reloading IOS.
|
|
WBFS_CloseAll();
|
|
WDVD_Close();
|
|
DeviceHandler::DestroyInstance();
|
|
USBStorage2_Deinit();
|
|
|
|
ret = ReloadIosSafe(ios);
|
|
|
|
// Remount devices after reloading IOS.
|
|
DeviceHandler::Instance()->MountAll();
|
|
Disc_Init();
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Reloads a certain IOS under the condition, that an appropriate version of the IOS is installed.
|
|
* @return a negative value if a safe reload of the ios was not possible.
|
|
*/
|
|
s32 IosLoader::ReloadIosSafe(s32 ios)
|
|
{
|
|
if(IsHermesIOS(ios))
|
|
{
|
|
s32 iosRev = NandTitles.VersionOf(TITLE_ID(1, ios));
|
|
if((iosRev < 4 || iosRev > 6) && iosRev != 65535)
|
|
return -11;
|
|
}
|
|
else if(IsWaninkokoIOS(ios))
|
|
{
|
|
s32 iosRev = NandTitles.VersionOf(TITLE_ID(1, ios));
|
|
if((iosRev < 9 || iosRev > 30000) && iosRev != 65535) //let's see if Waninkoko actually gets to 30
|
|
return -22;
|
|
}
|
|
else
|
|
{
|
|
return -33;
|
|
}
|
|
|
|
s32 r = IOS_ReloadIOS(ios);
|
|
if (r >= 0) WII_Initialize();
|
|
|
|
IosLoader::LoadIOSModules(IOS_GetVersion(), IOS_GetRevision());
|
|
|
|
return r;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Private/Protected Methods:
|
|
******************************************************************************/
|
|
void IosLoader::LoadIOSModules(s32 ios, s32 ios_rev)
|
|
{
|
|
//! Hermes IOS
|
|
if(IsHermesIOS(ios))
|
|
{
|
|
const u8 * ech_module = NULL;
|
|
int ehc_module_size = 0;
|
|
const u8 * dip_plugin = NULL;
|
|
int dip_plugin_size = 0;
|
|
|
|
ech_module = ehcmodule_5;
|
|
ehc_module_size = size_ehcmodule_5;
|
|
dip_plugin = odip_frag;
|
|
dip_plugin_size = odip_frag_size;
|
|
gprintf("Loading ehc v5 and opendip module\n");
|
|
|
|
load_modules(ech_module, ehc_module_size, dip_plugin, dip_plugin_size);
|
|
}
|
|
//! Waninkoko IOS
|
|
else if(IsWaninkokoIOS(ios))
|
|
{
|
|
iosinfo_t *info = GetIOSInfo(ios);
|
|
if(ios_rev >= 18 && (!info || info->version < 6))
|
|
{
|
|
if(mload_init() < 0)
|
|
return;
|
|
|
|
gprintf("Loading dip module for Waninkoko's cios\n");
|
|
mload_module((u8 *) dip_plugin_249, dip_plugin_249_size);
|
|
mload_close();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Reads the ios info struct from the .app file.
|
|
* @return pointer to iosinfo_t on success else NULL. The user is responsible for freeing the buffer.
|
|
*/
|
|
iosinfo_t *IosLoader::GetIOSInfo(s32 ios)
|
|
{
|
|
if(currentIOS == ios && currentIOSInfo)
|
|
return currentIOSInfo;
|
|
|
|
if(currentIOSInfo)
|
|
{
|
|
free(currentIOSInfo);
|
|
currentIOSInfo = NULL;
|
|
}
|
|
|
|
currentIOS = ios;
|
|
char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(0x20);
|
|
u64 TicketID = ((((u64) 1) << 32) | ios);
|
|
u32 TMD_Length;
|
|
|
|
s32 ret = ES_GetStoredTMDSize(TicketID, &TMD_Length);
|
|
if (ret < 0)
|
|
return NULL;
|
|
|
|
signed_blob *TMD = (signed_blob*) memalign(32, ALIGN32(TMD_Length));
|
|
if (!TMD)
|
|
return NULL;
|
|
|
|
ret = ES_GetStoredTMD(TicketID, TMD, TMD_Length);
|
|
if (ret < 0)
|
|
{
|
|
free(TMD);
|
|
return NULL;
|
|
}
|
|
|
|
sprintf(filepath, "/title/%08x/%08x/content/%08x.app", 0x00000001, ios, *(u8 *)((u32)TMD+0x1E7));
|
|
|
|
free(TMD);
|
|
|
|
u8 *buffer = NULL;
|
|
u32 filesize = 0;
|
|
|
|
NandTitle::LoadFileFromNand(filepath, &buffer, &filesize);
|
|
|
|
if(!buffer)
|
|
return NULL;
|
|
|
|
iosinfo_t *iosinfo = (iosinfo_t *) buffer;
|
|
|
|
if(iosinfo->magicword != 0x1ee7c105 || iosinfo->magicversion != 1)
|
|
{
|
|
free(buffer);
|
|
return NULL;
|
|
}
|
|
|
|
iosinfo = (iosinfo_t *) realloc(buffer, sizeof(iosinfo_t));
|
|
if(!iosinfo)
|
|
iosinfo = (iosinfo_t *) buffer;
|
|
|
|
currentIOSInfo = iosinfo;
|
|
|
|
return iosinfo;
|
|
}
|