Automatically pick the cIOS for games

To avoid unnecessary IOS reloads the following d2x cIOS setup should be used.

- Slot 249 base 56
- Slot 250 base 57
- Slot 251 base 38 (Wii) / base 58 (vWii)

Or you could use the following, which should improve game compatibility.

- Slot 248 base 38 (Wii)
- Slot 249 base 56
- Slot 250 base 57
- Slot 251 base 58
This commit is contained in:
wiidev 2023-01-01 17:00:34 +00:00
parent 83133a292b
commit ab3273f475
47 changed files with 783 additions and 173 deletions

View File

@ -555,6 +555,12 @@ msgstr "Vlastní adresa"
msgid "Custom Banners" msgid "Custom Banners"
msgstr "" msgstr ""
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Vlastní cesty" msgstr "Vlastní cesty"

View File

@ -555,6 +555,12 @@ msgstr "Brugerdefineret adresse"
msgid "Custom Banners" msgid "Custom Banners"
msgstr "Brugerdefineret bannere" msgstr "Brugerdefineret bannere"
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Sti-indstillinger" msgstr "Sti-indstillinger"

View File

@ -555,6 +555,12 @@ msgstr "Aangepaste Adres"
msgid "Custom Banners" msgid "Custom Banners"
msgstr "Aangepaste Banners" msgstr "Aangepaste Banners"
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Aangepaste Locaties" msgstr "Aangepaste Locaties"

View File

@ -555,6 +555,12 @@ msgstr ""
msgid "Custom Banners" msgid "Custom Banners"
msgstr "" msgstr ""
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "" msgstr ""

View File

@ -555,6 +555,12 @@ msgstr ""
msgid "Custom Banners" msgid "Custom Banners"
msgstr "" msgstr ""
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Omat polut" msgstr "Omat polut"

View File

@ -555,6 +555,12 @@ msgstr ""
msgid "Custom Banners" msgid "Custom Banners"
msgstr "Bannières persos" msgstr "Bannières persos"
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Personnalisation des dossiers" msgstr "Personnalisation des dossiers"

View File

@ -555,6 +555,12 @@ msgstr ""
msgid "Custom Banners" msgid "Custom Banners"
msgstr "Community Banner" msgstr "Community Banner"
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Community Pfade" msgstr "Community Pfade"

View File

@ -555,6 +555,12 @@ msgstr ""
msgid "Custom Banners" msgid "Custom Banners"
msgstr "Τροποποιημένες ταμπέλες-εικονίδια" msgstr "Τροποποιημένες ταμπέλες-εικονίδια"
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Τροποποιημένες διευθύνσεις/μονοπάτια αρχείων" msgstr "Τροποποιημένες διευθύνσεις/μονοπάτια αρχείων"

View File

@ -555,6 +555,12 @@ msgstr ""
msgid "Custom Banners" msgid "Custom Banners"
msgstr "" msgstr ""
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Egyéni útvonalak" msgstr "Egyéni útvonalak"

View File

@ -555,6 +555,12 @@ msgstr "Indirizzo personalizzati"
msgid "Custom Banners" msgid "Custom Banners"
msgstr "Banner personalizzati" msgstr "Banner personalizzati"
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Percorsi personalizzati" msgstr "Percorsi personalizzati"

View File

@ -555,6 +555,12 @@ msgstr "カスタム アドレス"
msgid "Custom Banners" msgid "Custom Banners"
msgstr "カスタムバナー" msgstr "カスタムバナー"
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "パスを変更" msgstr "パスを変更"

View File

@ -555,6 +555,12 @@ msgstr "커스텀 주소"
msgid "Custom Banners" msgid "Custom Banners"
msgstr "커스텀 배너" msgstr "커스텀 배너"
msgid "Custom Game IOS"
msgstr "커스텀 게임 IOS"
msgid "Custom Games IOS"
msgstr "커스텀 게임 IOS"
msgid "Custom Paths" msgid "Custom Paths"
msgstr "커스텀 경로" msgstr "커스텀 경로"

View File

@ -555,6 +555,12 @@ msgstr ""
msgid "Custom Banners" msgid "Custom Banners"
msgstr "" msgstr ""
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Egendefinerte stier" msgstr "Egendefinerte stier"

View File

@ -555,6 +555,12 @@ msgstr ""
msgid "Custom Banners" msgid "Custom Banners"
msgstr "" msgstr ""
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Sciezki" msgstr "Sciezki"

View File

@ -555,6 +555,12 @@ msgstr ""
msgid "Custom Banners" msgid "Custom Banners"
msgstr "Banners Modificados" msgstr "Banners Modificados"
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Caminhos" msgstr "Caminhos"

View File

@ -555,6 +555,12 @@ msgstr ""
msgid "Custom Banners" msgid "Custom Banners"
msgstr "" msgstr ""
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Caminhos Personalizados" msgstr "Caminhos Personalizados"

View File

@ -555,6 +555,12 @@ msgstr ""
msgid "Custom Banners" msgid "Custom Banners"
msgstr "" msgstr ""
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Изменение путей" msgstr "Изменение путей"

View File

@ -555,6 +555,12 @@ msgstr "自定义地址"
msgid "Custom Banners" msgid "Custom Banners"
msgstr "自定义频道动画" msgstr "自定义频道动画"
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "自定义路径" msgstr "自定义路径"

View File

@ -555,6 +555,12 @@ msgstr "Dirección custom"
msgid "Custom Banners" msgid "Custom Banners"
msgstr "Banners personalizados" msgstr "Banners personalizados"
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Rutas personalizadas" msgstr "Rutas personalizadas"

View File

@ -555,6 +555,12 @@ msgstr "Anpassad adress"
msgid "Custom Banners" msgid "Custom Banners"
msgstr "" msgstr ""
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Anpassade sökvägar" msgstr "Anpassade sökvägar"

View File

@ -555,6 +555,12 @@ msgstr "自訂地址"
msgid "Custom Banners" msgid "Custom Banners"
msgstr "自製頻道動畫" msgstr "自製頻道動畫"
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "自訂路徑" msgstr "自訂路徑"

View File

@ -555,6 +555,12 @@ msgstr ""
msgid "Custom Banners" msgid "Custom Banners"
msgstr "" msgstr ""
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "กำหนด ที่เก็บ" msgstr "กำหนด ที่เก็บ"

View File

@ -555,6 +555,12 @@ msgstr ""
msgid "Custom Banners" msgid "Custom Banners"
msgstr "" msgstr ""
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths" msgid "Custom Paths"
msgstr "Kişisel Yollar" msgstr "Kişisel Yollar"

View File

@ -21,6 +21,7 @@ SOURCES := source \
source/Controls \ source/Controls \
source/system \ source/system \
source/libs/libwbfs \ source/libs/libwbfs \
source/libs/libruntimeiospatch \
source/language \ source/language \
source/mload \ source/mload \
source/mload/modules \ source/mload/modules \
@ -73,7 +74,7 @@ endif
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBS := -lwolfssl -lcustomfat -lcustomntfs -lcustomext2fs -lvorbisidec -logg \ LIBS := -lwolfssl -lcustomfat -lcustomntfs -lcustomext2fs -lvorbisidec -logg \
-lmad -lfreetype -lgd -ljpeg -lpng -lm -lz -lwiiuse -lwiidrc \ -lmad -lfreetype -lgd -ljpeg -lpng -lm -lz -lwiiuse -lwiidrc \
-lbte -lasnd -logc -lruntimeiospatch -lbte -lasnd -logc
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing # list of directories containing libraries, this must be the top level containing
# include and lib # include and lib
@ -140,7 +141,7 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) -L$(CURDIR)/source/libs/libdrc/ \ export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) -L$(CURDIR)/source/libs/libdrc/ \
-L$(CURDIR)/source/libs/libext2fs -L$(CURDIR)/source/libs/libfat \ -L$(CURDIR)/source/libs/libext2fs -L$(CURDIR)/source/libs/libfat \
-L$(CURDIR)/source/libs/libntfs -L$(CURDIR)/source/libs/libruntimeiospatch \ -L$(CURDIR)/source/libs/libntfs \
-L$(CURDIR)/source/libs/libwolfssl -L$(LIBOGC_LIB) -L$(CURDIR)/source/libs/libwolfssl -L$(LIBOGC_LIB)
export OUTPUT := $(CURDIR)/$(TARGET) export OUTPUT := $(CURDIR)/$(TARGET)

View File

@ -264,12 +264,12 @@ u8 *Channels::GetDol(const u64 &title, u8 *tmdBuffer, bool &isForwarder)
return outBuf; return outBuf;
} }
u8 Channels::GetRequestedIOS(const u64 &title) u8 Channels::GetRequestedIOS(const u64 &title, const char *prefix)
{ {
u8 IOS = 0; u8 IOS = 0;
u32 tmdSize = 0; u32 tmdSize = 0;
u8 *titleTMD = GetTMD(title, &tmdSize, ""); u8 *titleTMD = GetTMD(title, &tmdSize, prefix);
if (!titleTMD) if (!titleTMD)
return 0; return 0;

View File

@ -37,7 +37,7 @@ public:
static void DestroyInstance(void) { if(instance) delete instance; instance = NULL; } static void DestroyInstance(void) { if(instance) delete instance; instance = NULL; }
static u32 LoadChannel(const u64 &chantitle); static u32 LoadChannel(const u64 &chantitle);
static u8 GetRequestedIOS(const u64 &title); static u8 GetRequestedIOS(const u64 &title, const char *prefix);
static u8 *GetTMD(const u64 &tid, u32 *size, const char *prefix); static u8 *GetTMD(const u64 &tid, u32 *size, const char *prefix);
static u8 *GetDol(const u64 &title, u8 *tmdBuffer, bool &isForwarder); static u8 *GetDol(const u64 &title, u8 *tmdBuffer, bool &isForwarder);
static u8 *GetOpeningBnr(const u64 &title, u32 *outsize, const char *pathPrefix); static u8 *GetOpeningBnr(const u64 &title, u32 *outsize, const char *pathPrefix);

View File

@ -51,7 +51,7 @@ StartUpProcess::StartUpProcess()
versionTxt = new GuiText(" ", 18, (GXColor){255, 255, 255, 255}); versionTxt = new GuiText(" ", 18, (GXColor){255, 255, 255, 255});
versionTxt->SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM); versionTxt->SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
versionTxt->SetPosition(20, screenheight - 20); versionTxt->SetPosition(23, screenheight - 20);
#ifdef FULLCHANNEL #ifdef FULLCHANNEL
versionTxt->SetTextf("v3.0c Rev. %s (%s)", GetRev(), commitID()); versionTxt->SetTextf("v3.0c Rev. %s (%s)", GetRev(), commitID());
@ -101,15 +101,22 @@ int StartUpProcess::ParseArguments(int argc, char *argv[])
gprintf("Boot argument %i: %s\n", i + 1, argv[i]); gprintf("Boot argument %i: %s\n", i + 1, argv[i]);
char *ptr = strcasestr(argv[i], "-bootios="); char *ptr = strcasestr(argv[i], "-ios=");
if(ptr)
{
if(atoi(ptr+strlen("-ios=")) == 58)
Settings.LoaderIOS = 58;
else
Settings.LoaderIOS = LIMIT(atoi(ptr+strlen("-ios=")), 200, 255);
}
ptr = strcasestr(argv[i], "-bootios=");
if (ptr) if (ptr)
{ {
if (atoi(ptr + strlen("-bootios=")) == 58) if (atoi(ptr + strlen("-bootios=")) == 58)
Settings.LoaderIOS = 58; Settings.BootIOS = 58;
else else
Settings.LoaderIOS = LIMIT(atoi(ptr + strlen("-bootios=")), 200, 255); Settings.BootIOS = LIMIT(atoi(ptr + strlen("-bootios=")), 200, 255);
Settings.UseArgumentIOS = ON;
Settings.BootIOS = Settings.LoaderIOS;
} }
ptr = strcasestr(argv[i], "-usbport="); ptr = strcasestr(argv[i], "-usbport=");
@ -245,39 +252,55 @@ int StartUpProcess::Run(int argc, char *argv[])
return ret; return ret;
} }
int StartUpProcess::Execute(bool quickGameBoot) void StartUpProcess::LoadIOS(u8 ios, bool boot)
{ {
Settings.EntryIOS = IOS_GetVersion(); SetTextf("Reloading to IOS%d%s\n", ios, boot ? " requested in meta.xml" : "");
// Disable AHBPROT if (IosLoader::LoadAppCios(ios) < 0)
IosLoader::PatchAHB();
gprintf("Current IOS: %d - have AHB access: %s\n", Settings.EntryIOS, AHBPROT_DISABLED ? "yes" : "no");
// Reload to a cIOS if required (old forwarder?) or requested
if (!AHBPROT_DISABLED || (Settings.EntryIOS != Settings.BootIOS))
{
SetTextf("Reloading to cIOS %d%s\n", Settings.LoaderIOS, Settings.UseArgumentIOS ? "requested in meta.xml" : "");
if (IosLoader::LoadAppCios(Settings.LoaderIOS) < 0)
{ {
SetTextf("Failed to load an IOS. USB Loader GX requires a cIOS or IOS58 with AHB access. Exiting...\n"); SetTextf("Failed to load an IOS. USB Loader GX requires a cIOS or IOS58 with AHB access. Exiting...\n");
sleep(5); sleep(5);
Sys_BackToLoader(); Sys_BackToLoader();
} }
SetTextf("Reloaded to cIOS %d\n", Settings.LoaderIOS); SetTextf("Reloaded to IOS%d r%d\n", Settings.LoaderIOS, IOS_GetRevision());
gprintf("Current IOS: %d - have AHB access: %s\n", IOS_GetVersion(), AHBPROT_DISABLED ? "yes" : "no");
} }
int StartUpProcess::Execute(bool quickGameBoot)
{
Settings.EntryIOS = IOS_GetVersion();
// Disable AHBPROT
IosPatch_AHBPROT(false);
// Store dx2 cIOS info
IosLoader::GetD2XInfo();
gprintf("Current IOS: %d - have AHB access: %s\n", Settings.EntryIOS, AHBPROT_DISABLED ? "yes" : "no");
// Reload to a cIOS if we're using both USB ports
if (Settings.USBPort == 2)
LoadIOS(Settings.LoaderIOS, false);
// Reload to a cIOS if required (old forwarder?) or requested
else if (!AHBPROT_DISABLED || (Settings.EntryIOS != Settings.BootIOS))
LoadIOS(Settings.BootIOS, true);
// Setup the pads
SetupPads(); SetupPads();
// Mount the SD card
SetTextf("Initializing SD card\n"); SetTextf("Initializing SD card\n");
DeviceHandler::Instance()->MountSD(); DeviceHandler::Instance()->MountSD();
// Do not mount USB if not needed. USB is not available with WiiU WiiVC injected channel // Do not mount USB if not needed. USB is not available with WiiU WiiVC injected channel
bool USBSuccess = false;
if (Settings.USBAutoMount == ON && !isWiiVC) if (Settings.USBAutoMount == ON && !isWiiVC)
{ {
SetTextf("Initializing USB devices\n"); SetTextf("Initializing USB devices\n");
USBSpinUp(); if (USBSpinUp())
{
DeviceHandler::Instance()->MountAllUSB(false); DeviceHandler::Instance()->MountAllUSB(false);
USBSuccess = true;
gprintf("Completed initialization of USB devices\n"); gprintf("Completed initialization of USB devices\n");
} }
}
SetTextf("Loading config files\n"); SetTextf("Loading config files\n");
gprintf("\tLoading config...%s\n", Settings.Load() ? "done" : "failed"); gprintf("\tLoading config...%s\n", Settings.Load() ? "done" : "failed");
@ -311,7 +334,7 @@ int StartUpProcess::Execute(bool quickGameBoot)
// Now load the cIOS that was set in the settings menu // Now load the cIOS that was set in the settings menu
if (IosLoader::LoadAppCios(Settings.LoaderIOS) > -1) if (IosLoader::LoadAppCios(Settings.LoaderIOS) > -1)
{ {
SetTextf("Reloaded to %s%d r%d\n", IOS_GetVersion() >= 200 ? "cIOS " : "IOS", Settings.LoaderIOS, IOS_GetRevision()); SetTextf("Reloaded to IOS%d r%d\n", Settings.LoaderIOS, IOS_GetRevision());
// Re-Mount devices // Re-Mount devices
SetTextf("Reinitializing devices\n"); SetTextf("Reinitializing devices\n");
} }
@ -321,9 +344,9 @@ int StartUpProcess::Execute(bool quickGameBoot)
SetupPads(); SetupPads();
DeviceHandler::Instance()->MountSD(); DeviceHandler::Instance()->MountSD();
if (Settings.USBAutoMount == ON) if (Settings.USBAutoMount == ON && USBSuccess)
{ {
USBSpinUp(); if (USBSpinUp())
DeviceHandler::Instance()->MountAllUSB(false); DeviceHandler::Instance()->MountAllUSB(false);
} }
} }
@ -353,9 +376,9 @@ int StartUpProcess::Execute(bool quickGameBoot)
// Enable isfs permission if using Hermes v4 without AHB, or WiiU WiiVC (IOS255 fw.img) // Enable isfs permission if using Hermes v4 without AHB, or WiiU WiiVC (IOS255 fw.img)
if (IOS_GetVersion() < 200 || (IosLoader::IsHermesIOS() && IOS_GetRevision() == 4) || isWiiVC) if (IOS_GetVersion() < 200 || (IosLoader::IsHermesIOS() && IOS_GetRevision() == 4) || isWiiVC)
{ {
SetTextf("Patching %s%d\n", IOS_GetVersion() >= 200 ? "cIOS " : "IOS", IOS_GetVersion()); SetTextf("Patching IOS%d\n", IOS_GetVersion());
if (IosPatch_RUNTIME(!isWiiVC, false, false, isWiiVC, false) == ERROR_PATCH) if (IosPatch_RUNTIME(!isWiiVC, false, false, isWiiVC, false) == ERROR_PATCH)
gprintf("Patching %sIOS%d failed!\n", IOS_GetVersion() >= 200 ? "c" : "", IOS_GetVersion()); gprintf("Patching IOS%d failed!\n", IOS_GetVersion());
else else
NandTitles.Get(); // get NAND channel's titles NandTitles.Get(); // get NAND channel's titles

View File

@ -11,6 +11,7 @@ public:
private: private:
StartUpProcess(); StartUpProcess();
~StartUpProcess(); ~StartUpProcess();
void LoadIOS(u8 ios, bool boot);
int Execute(bool quickGameBoot); int Execute(bool quickGameBoot);
bool USBSpinUp(); bool USBSpinUp();
void TextFade(int direction); void TextFade(int direction);

View File

@ -0,0 +1,237 @@
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// Copyright (C) 2010 Joseph Jordan <joe.ftpii@psychlaw.com.au>
// Copyright (C) 2012-2013 damysteryman
// Copyright (C) 2012-2015 Christopher Bratusek <nano@jpberlin.de>
// Copyright (C) 2013 DarkMatterCore
// Copyright (C) 2014 megazig
// Copyright (C) 2015-2017 FIX94
#include <gccore.h>
#include <ogc/machine/processor.h>
#include <stdio.h>
#include <string.h>
#include "../../gecko.h"
#include "runtimeiospatch.h"
#define MEM_REG_BASE 0xd8b4000
#define MEM_PROT (MEM_REG_BASE + 0x20a)
static inline void disable_memory_protection(void) {
write32(MEM_PROT, read32(MEM_PROT) & 0x0000FFFF);
}
static const u8 di_readlimit_old[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0A, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
0x7E, 0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08
};
static const u8 di_readlimit_patch[] = { 0x7e, 0xd4 };
static const u8 isfs_permissions_old[] = { 0x42, 0x8B, 0xD0, 0x01, 0x25, 0x66 };
static const u8 isfs_permissions_patch[] = { 0x42, 0x8B, 0xE0, 0x01, 0x25, 0x66 };
#if 1
static const u8 setuid_old[] = { 0xD1, 0x2A, 0x1C, 0x39 };
static const u8 setuid_patch[] = { 0x46, 0xC0 };
#endif
static const u8 es_identify_old[] = { 0x28, 0x03, 0xD1, 0x23 };
static const u8 es_identify_patch[] = { 0x00, 0x00 };
static const u8 hash_old[] = { 0x20, 0x07, 0x23, 0xA2 };
static const u8 hash_patch[] = { 0x00 };
static const u8 new_hash_old[] = { 0x20, 0x07, 0x4B, 0x0B };
#if 0
static const u8 addticket_vers_check[] = { 0xD2, 0x01, 0x4E, 0x56 };
static const u8 addticket_patch[] = { 0xE0 };
#endif
static const u8 es_set_ahbprot_old[] = { 0x68, 0x5B, 0x22, 0xEC, 0x00, 0x52, 0x18, 0x9B, 0x68, 0x1B, 0x46, 0x98, 0x07, 0xDB };
static const u8 es_set_ahbprot_patch[] = { 0x01 };
/* SSL patches made by FIX94 for Nintendont. Ported to libruntimeiospatch by DarkMatterCore */
static const u8 ssl_patch1_old[] = { 0xFE, 0x0E, 0xE3, 0x50, 0x00, 0x00, 0x05, 0x9F };
static const u8 ssl_patch1_new[] = { 0xFE, 0x0E, 0xE3, 0x28, 0xF1, 0x02, 0x05, 0x9F }; // Fixes SSL error -9 (wrong host)
static const u8 ssl_patch2_old[] = { 0x00, 0x00, 0x0A, 0x00, 0x00, 0x09, 0xEA, 0x00 };
static const u8 ssl_patch2_new[] = { 0x00, 0x00, 0xEA, 0x00, 0x00, 0x09, 0xEA, 0x00 }; // Fixes SSL error -10 (part 1) (wrong root cert)
static const u8 ssl_patch3_old[] = { 0x00, 0x00, 0x1A, 0x00, 0x00, 0x08, 0xE3, 0xE0 };
static const u8 ssl_patch3_new[] = { 0x00, 0x00, 0xEA, 0x00, 0x00, 0x08, 0xE3, 0xE0 }; // Fixes SSL error -10 (part 2) (wrong root cert)
static const u8 ssl_patch4_old[] = { 0x00, 0x00, 0xDA, 0x00, 0x00, 0x16, 0xE7, 0x96 };
static const u8 ssl_patch4_new[] = { 0x00, 0x00, 0xEA, 0x00, 0x00, 0x16, 0xE7, 0x96 }; // Fixes SSL error -11 (wrong client cert)
//Following patches added to iospatch.c by damysteryman, taken from sciifii v5
static const u8 MEM2_prot_old[] = { 0xB5, 0x00, 0x4B, 0x09, 0x22, 0x01, 0x80, 0x1A, 0x22, 0xF0 };
static const u8 MEM2_prot_patch[] = { 0xB5, 0x00, 0x4B, 0x09, 0x22, 0x00, 0x80, 0x1A, 0x22, 0xF0 };
static const u8 ES_OpenTitleContent1_old[] = { 0x9D, 0x05, 0x42, 0x9D, 0xD0, 0x03 };
static const u8 ES_OpenTitleContent1_patch[] = { 0x9D, 0x05, 0x42, 0x9D, 0xE0, 0x03 };
static const u8 ES_OpenTitleContent2_old[] = { 0xD4, 0x01, 0x4C, 0x36, 0xE0, 0x3B };
static const u8 ES_OpenTitleContent2_patch[] = { 0xE0, 0x01, 0x4C, 0x36, 0xE0, 0x3B };
static const u8 ES_ReadContent_old[] = { 0xFC, 0x0F, 0xB5, 0x30, 0x1C, 0x14, 0x1C, 0x1D, 0x4B,
0x0E, 0x68, 0x9B, 0x2B, 0x00, 0xD0, 0x03, 0x29, 0x00, 0xDB, 0x01,
0x29, 0x0F, 0xDD, 0x01 };
static const u8 ES_ReadContent_patch[] = { 0xFC, 0x0F, 0xB5, 0x30, 0x1C, 0x14, 0x1C, 0x1D, 0x4B,
0x0E, 0x68, 0x9B, 0x2B, 0x00, 0x46, 0xC0, 0x29, 0x00, 0x46, 0xC0,
0x29, 0x0F, 0xE0, 0x01 };
static const u8 ES_CloseContent_old[] = { 0xB5, 0x10, 0x4B, 0x10, 0x68, 0x9B, 0x2B, 0x00, 0xD0,
0x03, 0x29, 0x00, 0xDB, 0x01, 0x29, 0x0F, 0xDD, 0x01 };
static const u8 ES_CloseContent_patch[] = { 0xB5, 0x10, 0x4B, 0x10, 0x68, 0x9B, 0x2B, 0x00, 0x46,
0xC0, 0x29, 0x00, 0x46, 0xC0, 0x29, 0x0F, 0xE0, 0x01 };
static const u8 ES_TitleVersionCheck_old[] = { 0xD2, 0x01, 0x4E, 0x56 };
static const u8 ES_TitleVersionCheck_patch[] = { 0xE0, 0x01, 0x4E, 0x56 };
static const u8 ES_TitleDeleteCheck_old[] = { 0xD8, 0x00, 0x4A, 0x04 };
static const u8 ES_TitleDeleteCheck_patch[] = { 0xE0, 0x00, 0x4A, 0x04 };
//Following set of patches made by damysteryman for use with Wii U's vWii
static const u8 Kill_AntiSysTitleInstallv3_pt1_old[] = { 0x68, 0x1A, 0x2A, 0x01, 0xD0, 0x05 }; // Make sure that the pt1
static const u8 Kill_AntiSysTitleInstallv3_pt1_patch[] = { 0x68, 0x1A, 0x2A, 0x01, 0x46, 0xC0 }; // patch is applied twice. -dmm
static const u8 Kill_AntiSysTitleInstallv3_pt2_old[] = { 0xD0, 0x02, 0x33, 0x06, 0x42, 0x9A, 0xD1, 0x01 }; // Make sure that the pt2 patch
static const u8 Kill_AntiSysTitleInstallv3_pt2_patch[] = { 0x46, 0xC0, 0x33, 0x06, 0x42, 0x9A, 0xE0, 0x01 }; // is also applied twice. -dmm
static const u8 Kill_AntiSysTitleInstallv3_pt3_old[] = { 0x68, 0xFB, 0x2B, 0x00, 0xDB, 0x01 };
static const u8 Kill_AntiSysTitleInstallv3_pt3_patch[] = { 0x68, 0xFB, 0x2B, 0x00, 0xDB, 0x10 };
/* ISFS_SetAttr patches made by megazig */
#if 0
static const u8 isfs_setattr_pt1_old[] = { 0x42, 0xAB, 0xD0, 0x02, 0x20, 0x66 };
static const u8 isfs_setattr_pt1_patch[] = { 0x42, 0xAB, 0xE0, 0x02, 0x20, 0x66 };
static const u8 isfs_setattr_pt2_old[] = { 0x2D, 0x00, 0xD0, 0x02, 0x20, 0x66 };
static const u8 isfs_setattr_pt2_patch[] = { 0x2D, 0x00, 0xE0, 0x02, 0x20, 0x66 };
#endif
/* ISFS_permission for WiiU WiiVC patches made by fix94 */
static const u8 isfs_perm_wiivc_old[] = { 0x42, 0x9F, 0xD1, 0x03, 0x20, 0x00, 0xBD, 0xF0, 0x09, 0x8B, 0xE7, 0xF8, 0x20, 0x66 };
static const u8 isfs_perm_wiivc_patch[] = { 0x42, 0x9F, 0x46, 0xC0, 0x20, 0x00, 0xBD, 0xF0, 0x09, 0x8B, 0xE7, 0xF8, 0x20, 0x66 };
static u8 apply_patch(const char *name, const u8 *old, u32 old_size, const u8 *patch, size_t patch_size, u32 patch_offset, bool verbose) {
u8 *ptr_start = (u8*)*((u32*)0x80003134), *ptr_end = (u8*)0x94000000;
u8 found = 0;
if(verbose)
gprintf(" Patching %-30s", name);
u8 *location = NULL;
while (ptr_start < (ptr_end - patch_size)) {
if (!memcmp(ptr_start, old, old_size)) {
found++;
location = ptr_start + patch_offset;
u8 *start = location;
u32 i;
for (i = 0; i < patch_size; i++) {
*location++ = patch[i];
}
DCFlushRange((u8 *)(((u32)start) >> 5 << 5), (patch_size >> 5 << 5) + 64);
ICInvalidateRange((u8 *)(((u32)start) >> 5 << 5), (patch_size >> 5 << 5) + 64);
}
ptr_start++;
}
if(verbose){
if (found)
gprintf(" patched\n");
else
gprintf(" not patched\n");
}
return found;
}
s32 IosPatch_AHBPROT(bool verbose) {
if (AHBPROT_DISABLED) {
disable_memory_protection();
s32 ret = apply_patch("es_set_ahbprot", es_set_ahbprot_old, sizeof(es_set_ahbprot_old), es_set_ahbprot_patch, sizeof(es_set_ahbprot_patch), 25, verbose);
if (ret)
return ret;
else
return ERROR_PATCH;
}
return ERROR_AHBPROT;
}
s32 IosPatch_RUNTIME(bool wii, bool sciifii, bool vwii, bool wiivc, bool verbose) {
s32 count = 0;
if (AHBPROT_DISABLED) {
disable_memory_protection();
if(wii)
{
if(verbose) gprintf(">> Applying standard Wii patches:\n");
count += apply_patch("di_readlimit", di_readlimit_old, sizeof(di_readlimit_old), di_readlimit_patch, sizeof(di_readlimit_patch), 12, verbose);
count += apply_patch("isfs_permissions", isfs_permissions_old, sizeof(isfs_permissions_old), isfs_permissions_patch, sizeof(isfs_permissions_patch), 0, verbose);
//count += apply_patch("es_setuid", setuid_old, sizeof(setuid_old), setuid_patch, sizeof(setuid_patch), 0, verbose);
count += apply_patch("es_identify", es_identify_old, sizeof(es_identify_old), es_identify_patch, sizeof(es_identify_patch), 2, verbose);
count += apply_patch("hash_check", hash_old, sizeof(hash_old), hash_patch, sizeof(hash_patch), 1, verbose);
count += apply_patch("new_hash_check", new_hash_old, sizeof(new_hash_old), hash_patch, sizeof(hash_patch), 1, verbose);
//count += apply_patch("isfs_setattr_pt1", isfs_setattr_pt1_old, sizeof(isfs_setattr_pt1_old), isfs_setattr_pt1_patch, sizeof(isfs_setattr_pt1_patch), 0, verbose);
//count += apply_patch("isfs_setattr_pt2", isfs_setattr_pt2_old, sizeof(isfs_setattr_pt2_old), isfs_setattr_pt2_patch, sizeof(isfs_setattr_pt2_patch), 0, verbose);
//count += apply_patch("ssl_patch1", ssl_patch1_old, sizeof(ssl_patch1_old), ssl_patch1_new, sizeof(ssl_patch1_new), 0, verbose);
//count += apply_patch("ssl_patch2", ssl_patch2_old, sizeof(ssl_patch2_old), ssl_patch2_new, sizeof(ssl_patch2_new), 0, verbose);
//count += apply_patch("ssl_patch3", ssl_patch3_old, sizeof(ssl_patch3_old), ssl_patch3_new, sizeof(ssl_patch3_new), 0, verbose);
//count += apply_patch("ssl_patch4", ssl_patch4_old, sizeof(ssl_patch4_old), ssl_patch4_new, sizeof(ssl_patch4_new), 0, verbose);
}
if(sciifii)
{
if(verbose) gprintf(">> Applying Sciifii patches:\n");
count += apply_patch("MEM2_prot", MEM2_prot_old, sizeof(MEM2_prot_old), MEM2_prot_patch, sizeof(MEM2_prot_patch), 0, verbose);
count += apply_patch("ES_OpenTitleContent1", ES_OpenTitleContent1_old, sizeof(ES_OpenTitleContent1_old), ES_OpenTitleContent1_patch, sizeof(ES_OpenTitleContent1_patch), 0, verbose);
count += apply_patch("ES_OpenTitleContent2", ES_OpenTitleContent2_old, sizeof(ES_OpenTitleContent2_old), ES_OpenTitleContent2_patch, sizeof(ES_OpenTitleContent2_patch), 0, verbose);
count += apply_patch("ES_ReadContent_prot", ES_ReadContent_old, sizeof(ES_ReadContent_old), ES_ReadContent_patch, sizeof(ES_ReadContent_patch), 0, verbose);
count += apply_patch("ES_CloseContent", ES_CloseContent_old, sizeof(ES_CloseContent_old), ES_CloseContent_patch, sizeof(ES_CloseContent_patch), 0, verbose);
count += apply_patch("ES_TitleVersionCheck", ES_TitleVersionCheck_old, sizeof(ES_TitleVersionCheck_old), ES_TitleVersionCheck_patch, sizeof(ES_TitleVersionCheck_patch), 0, verbose);
count += apply_patch("ES_TitleDeleteCheck", ES_TitleDeleteCheck_old, sizeof(ES_TitleDeleteCheck_old), ES_TitleDeleteCheck_patch, sizeof(ES_TitleDeleteCheck_patch), 0, verbose);
}
if(vwii)
{
if(verbose) gprintf(">> Applying vWii patches:\n");
count += apply_patch("Kill_AntiSysTitleInstallv3_pt1", Kill_AntiSysTitleInstallv3_pt1_old, sizeof(Kill_AntiSysTitleInstallv3_pt1_old), Kill_AntiSysTitleInstallv3_pt1_patch, sizeof(Kill_AntiSysTitleInstallv3_pt1_patch), 0, verbose);
count += apply_patch("Kill_AntiSysTitleInstallv3_pt2", Kill_AntiSysTitleInstallv3_pt2_old, sizeof(Kill_AntiSysTitleInstallv3_pt2_old), Kill_AntiSysTitleInstallv3_pt2_patch, sizeof(Kill_AntiSysTitleInstallv3_pt2_patch), 0, verbose);
count += apply_patch("Kill_AntiSysTitleInstallv3_pt3", Kill_AntiSysTitleInstallv3_pt3_old, sizeof(Kill_AntiSysTitleInstallv3_pt3_old), Kill_AntiSysTitleInstallv3_pt3_patch, sizeof(Kill_AntiSysTitleInstallv3_pt3_patch), 0, verbose);
}
if(wiivc)
{
if(verbose) gprintf(">> Applying WiiVC patches:\n");
count += apply_patch("isfs_permissions", isfs_perm_wiivc_old, sizeof(isfs_perm_wiivc_old), isfs_perm_wiivc_patch, sizeof(isfs_perm_wiivc_patch), 0, verbose);
count += apply_patch("es_setuid", setuid_old, sizeof(setuid_old), setuid_patch, sizeof(setuid_patch), 0, verbose);
count += apply_patch("es_identify", es_identify_old, sizeof(es_identify_old), es_identify_patch, sizeof(es_identify_patch), 2, verbose);
}
return count;
}
return ERROR_AHBPROT;
}
s32 IosPatch_FULL(bool wii, bool sciifii, bool vwii, bool wiivc, bool verbose, int IOS) {
s32 ret = 0;
s32 xret = 0;
if (AHBPROT_DISABLED)
ret = IosPatch_AHBPROT(verbose);
else
return ERROR_AHBPROT;
if (ret) {
IOS_ReloadIOS(IOS);
xret = IosPatch_RUNTIME(wii, sciifii, vwii, wiivc, verbose);
} else {
xret = ERROR_PATCH;
}
return xret;
}
s32 IosPatch_SSL(bool verbose) {
s32 count = 0;
if (AHBPROT_DISABLED) {
disable_memory_protection();
if(verbose) gprintf(">> Applying SSL patches:\n");
count += apply_patch("ssl_patch1", ssl_patch1_old, sizeof(ssl_patch1_old), ssl_patch1_new, sizeof(ssl_patch1_new), 0, verbose);
count += apply_patch("ssl_patch2", ssl_patch2_old, sizeof(ssl_patch2_old), ssl_patch2_new, sizeof(ssl_patch2_new), 0, verbose);
count += apply_patch("ssl_patch3", ssl_patch3_old, sizeof(ssl_patch3_old), ssl_patch3_new, sizeof(ssl_patch3_new), 0, verbose);
count += apply_patch("ssl_patch4", ssl_patch4_old, sizeof(ssl_patch4_old), ssl_patch4_new, sizeof(ssl_patch4_new), 0, verbose);
return count;
}
return ERROR_AHBPROT;
}

View File

@ -745,6 +745,7 @@ void GameWindow::BootGame(struct discHdr *header)
snprintf(IDfull, sizeof(IDfull), "%s", (char *) header->id); snprintf(IDfull, sizeof(IDfull), "%s", (char *) header->id);
int gameIOS = game_cfg->ios == INHERIT ? Settings.cios : game_cfg->ios; int gameIOS = game_cfg->ios == INHERIT ? Settings.cios : game_cfg->ios;
int autoIOS = game_cfg->autoios == INHERIT ? Settings.AutoIOS : game_cfg->autoios;
int gameNandEmuMode = game_cfg->NandEmuMode == INHERIT ? Settings.NandEmuMode : game_cfg->NandEmuMode; int gameNandEmuMode = game_cfg->NandEmuMode == INHERIT ? Settings.NandEmuMode : game_cfg->NandEmuMode;
if (header->type == TYPE_GAME_EMUNANDCHAN) if (header->type == TYPE_GAME_EMUNANDCHAN)
gameNandEmuMode = game_cfg->NandEmuMode == INHERIT ? Settings.NandEmuChanMode : game_cfg->NandEmuMode; gameNandEmuMode = game_cfg->NandEmuMode == INHERIT ? Settings.NandEmuChanMode : game_cfg->NandEmuMode;
@ -767,7 +768,7 @@ void GameWindow::BootGame(struct discHdr *header)
} }
else if (game_cfg->loadalternatedol == 4) else if (game_cfg->loadalternatedol == 4)
{ {
if(!IosLoader::IsD2X(gameIOS)) if(autoIOS == GAME_IOS_CUSTOM && !IosLoader::IsD2X(gameIOS))
defaultDolPrompt((char *) header->id); defaultDolPrompt((char *) header->id);
} }
@ -783,6 +784,8 @@ void GameWindow::BootGame(struct discHdr *header)
} }
} }
if (autoIOS == GAME_IOS_CUSTOM)
{
if (header->type == TYPE_GAME_EMUNANDCHAN) if (header->type == TYPE_GAME_EMUNANDCHAN)
{ {
if (gameNandEmuMode != EMUNAND_NEEK) if (gameNandEmuMode != EMUNAND_NEEK)
@ -809,6 +812,7 @@ void GameWindow::BootGame(struct discHdr *header)
return; return;
} }
} }
}
GameStatistics.SetPlayCount(header->id, GameStatistics.GetPlayCount(header->id)+1); GameStatistics.SetPlayCount(header->id, GameStatistics.GetPlayCount(header->id)+1);
GameStatistics.Save(); GameStatistics.Save();

View File

@ -297,8 +297,10 @@ void WindowCredits()
char IosInfo[80] = ""; char IosInfo[80] = "";
iosinfo_t *info = IosLoader::GetIOSInfo(IOS_GetVersion()); iosinfo_t *info = IosLoader::GetIOSInfo(IOS_GetVersion());
if(info) if(info)
{
snprintf(IosInfo, sizeof(IosInfo), "(%s v%i%s base%i)", info->name, (int)info->version, info->versionstring, (int)info->baseios); snprintf(IosInfo, sizeof(IosInfo), "(%s v%i%s base%i)", info->name, (int)info->version, info->versionstring, (int)info->baseios);
free(info);
}
// Check if DIOS MIOS (Lite) is available // Check if DIOS MIOS (Lite) is available
char GCInfo[80] = ""; char GCInfo[80] = "";
int currentMIOS = IosLoader::GetMIOSInfo(); int currentMIOS = IosLoader::GetMIOSInfo();

View File

@ -194,6 +194,7 @@ bool CGameSettings::Save()
fprintf(f, "ocarina:%d; ", GameList[i].ocarina); fprintf(f, "ocarina:%d; ", GameList[i].ocarina);
fprintf(f, "vipatch:%d; ", GameList[i].vipatch); fprintf(f, "vipatch:%d; ", GameList[i].vipatch);
fprintf(f, "ios:%d; ", GameList[i].ios); fprintf(f, "ios:%d; ", GameList[i].ios);
fprintf(f, "autoios:%d; ", GameList[i].autoios);
fprintf(f, "parentalcontrol:%d; ", GameList[i].parentalcontrol); fprintf(f, "parentalcontrol:%d; ", GameList[i].parentalcontrol);
fprintf(f, "iosreloadblock:%d; ", GameList[i].iosreloadblock); fprintf(f, "iosreloadblock:%d; ", GameList[i].iosreloadblock);
fprintf(f, "patchcountrystrings:%d; ", GameList[i].patchcountrystrings); fprintf(f, "patchcountrystrings:%d; ", GameList[i].patchcountrystrings);
@ -307,6 +308,11 @@ bool CGameSettings::SetSetting(GameCFG & game, const char *name, const char *val
game.ios = atoi(value); game.ios = atoi(value);
return true; return true;
} }
else if(strcmp(name, "autoios") == 0)
{
game.autoios = atoi(value);
return true;
}
else if(strcmp(name, "parentalcontrol") == 0) else if(strcmp(name, "parentalcontrol") == 0)
{ {
game.parentalcontrol = atoi(value); game.parentalcontrol = atoi(value);
@ -689,6 +695,7 @@ void CGameSettings::SetDefault(GameCFG &game)
game.ocarina = INHERIT; game.ocarina = INHERIT;
game.vipatch = INHERIT; game.vipatch = INHERIT;
game.ios = INHERIT; game.ios = INHERIT;
game.autoios = INHERIT;
game.parentalcontrol = PARENTAL_LVL_EVERYONE; game.parentalcontrol = PARENTAL_LVL_EVERYONE;
game.patchcountrystrings = INHERIT; game.patchcountrystrings = INHERIT;
game.loadalternatedol = ALT_DOL_DEFAULT; game.loadalternatedol = ALT_DOL_DEFAULT;

View File

@ -19,6 +19,7 @@ typedef struct _GameCFG
short ocarina; short ocarina;
short vipatch; short vipatch;
short ios; short ios;
short autoios;
short parentalcontrol; short parentalcontrol;
short iosreloadblock; short iosreloadblock;
short loadalternatedol; short loadalternatedol;
@ -87,6 +88,7 @@ typedef struct _GameCFG
this->ocarina = game.ocarina; this->ocarina = game.ocarina;
this->vipatch = game.vipatch; this->vipatch = game.vipatch;
this->ios = game.ios; this->ios = game.ios;
this->autoios = game.autoios;
this->parentalcontrol = game.parentalcontrol; this->parentalcontrol = game.parentalcontrol;
this->iosreloadblock = game.iosreloadblock; this->iosreloadblock = game.iosreloadblock;
this->loadalternatedol = game.loadalternatedol; this->loadalternatedol = game.loadalternatedol;

View File

@ -124,6 +124,7 @@ void CSettings::SetDefault()
BootIOS = 58; BootIOS = 58;
LoaderIOS = 249; LoaderIOS = 249;
cios = 249; cios = 249;
AutoIOS = GAME_IOS_AUTO;
gridRows = 3; gridRows = 3;
partition = 0; partition = 0;
discart = DISCARTS_ORIGINALS_CUSTOMS; discart = DISCARTS_ORIGINALS_CUSTOMS;
@ -345,6 +346,7 @@ bool CSettings::Save()
fprintf(file, "GameSort = %d\n", GameSort); fprintf(file, "GameSort = %d\n", GameSort);
fprintf(file, "LoaderIOS = %d\n", LoaderIOS); fprintf(file, "LoaderIOS = %d\n", LoaderIOS);
fprintf(file, "cios = %d\n", cios); fprintf(file, "cios = %d\n", cios);
fprintf(file, "autoios = %d\n", AutoIOS);
fprintf(file, "keyset = %d\n", keyset); fprintf(file, "keyset = %d\n", keyset);
fprintf(file, "xflip = %d\n", xflip); fprintf(file, "xflip = %d\n", xflip);
fprintf(file, "gridRows = %d\n", gridRows); fprintf(file, "gridRows = %d\n", gridRows);
@ -666,6 +668,11 @@ bool CSettings::SetSetting(char *name, char *value)
cios = atoi(value); cios = atoi(value);
return true; return true;
} }
else if (strcmp(name, "autoios") == 0)
{
AutoIOS = atoi(value);
return true;
}
else if (strcmp(name, "keyset") == 0) else if (strcmp(name, "keyset") == 0)
{ {
keyset = atoi(value); keyset = atoi(value);

View File

@ -124,6 +124,7 @@ class CSettings
u8 BootIOS; u8 BootIOS;
u8 LoaderIOS; u8 LoaderIOS;
u8 cios; u8 cios;
short AutoIOS;
short quickboot; short quickboot;
short wsprompt; short wsprompt;
short keyset; short keyset;
@ -171,7 +172,6 @@ class CSettings
std::vector<u32> RequiredCategories; std::vector<u32> RequiredCategories;
std::vector<u32> ForbiddenCategories; std::vector<u32> ForbiddenCategories;
u8 EntryIOS; u8 EntryIOS;
short UseArgumentIOS;
short NandEmuMode; short NandEmuMode;
short NandEmuChanMode; short NandEmuChanMode;
short UseSystemFont; short UseSystemFont;

View File

@ -409,4 +409,11 @@ enum TITLETYPE
TITLETYPE_MANUAL_OVERRIDE = 7 TITLETYPE_MANUAL_OVERRIDE = 7
}; };
enum
{
GAME_IOS_AUTO,
GAME_IOS_CUSTOM,
GAME_IOS_MAX
};
#endif #endif

View File

@ -42,6 +42,12 @@ static const char * OnOffText[] =
trNOOP( "Auto" ) trNOOP( "Auto" )
}; };
static const char * GamesIOSText[] =
{
trNOOP( "Auto" ),
trNOOP( "Custom" )
};
static const char * VideoModeText[] = static const char * VideoModeText[] =
{ {
trNOOP( "System Default" ), trNOOP( "System Default" ),
@ -226,6 +232,10 @@ void GameLoadSM::SetOptionNames()
Options->SetName(Idx++, "%s", tr( "Hooktype" )); Options->SetName(Idx++, "%s", tr( "Hooktype" ));
Options->SetName(Idx++, "%s", tr( "Wiird Debugger" )); Options->SetName(Idx++, "%s", tr( "Wiird Debugger" ));
Options->SetName(Idx++, "%s", tr( "Game IOS" )); Options->SetName(Idx++, "%s", tr( "Game IOS" ));
if(GameConfig.autoios == GAME_IOS_CUSTOM)
{
Options->SetName(Idx++, "%s", tr( "Custom Game IOS" ));
}
Options->SetName(Idx++, "%s", tr( "Return To" )); Options->SetName(Idx++, "%s", tr( "Return To" ));
Options->SetName(Idx++, "%s", tr( "Block IOS Reload" )); Options->SetName(Idx++, "%s", tr( "Block IOS Reload" ));
@ -356,10 +366,19 @@ void GameLoadSM::SetOptionValues()
Options->SetValue(Idx++, "%s", tr( OnOffText[GameConfig.WiirdDebugger] )); Options->SetValue(Idx++, "%s", tr( OnOffText[GameConfig.WiirdDebugger] ));
//! Settings: Game IOS //! Settings: Game IOS
if(GameConfig.autoios == INHERIT)
Options->SetValue(Idx++, tr("Use global"));
else
Options->SetValue(Idx++, "%s", tr( GamesIOSText[GameConfig.autoios] ));
//! Settings: Custom Game IOS
if(GameConfig.autoios == GAME_IOS_CUSTOM)
{
if(GameConfig.ios == INHERIT) if(GameConfig.ios == INHERIT)
Options->SetValue(Idx++, tr("Use global")); Options->SetValue(Idx++, tr("Use global"));
else else
Options->SetValue(Idx++, "%i", GameConfig.ios); Options->SetValue(Idx++, "%i", GameConfig.ios);
}
//! Settings: Return To //! Settings: Return To
if(Header->type == TYPE_GAME_EMUNANDCHAN && EMUNAND_NEEK == (GameConfig.NandEmuMode == INHERIT ? Settings.NandEmuChanMode : GameConfig.NandEmuMode)) if(Header->type == TYPE_GAME_EMUNANDCHAN && EMUNAND_NEEK == (GameConfig.NandEmuMode == INHERIT ? Settings.NandEmuChanMode : GameConfig.NandEmuMode))
@ -570,6 +589,15 @@ int GameLoadSM::GetMenuInternal()
//! Settings: Game IOS //! Settings: Game IOS
else if (ret == ++Idx) else if (ret == ++Idx)
{
if (++GameConfig.autoios >= GAME_IOS_MAX) GameConfig.autoios = INHERIT;
Options->ClearList();
SetOptionNames();
SetOptionValues();
}
//! Settings: Custom Game IOS
else if (GameConfig.autoios == GAME_IOS_CUSTOM && ret == ++Idx)
{ {
char entered[8]; char entered[8];
snprintf(entered, sizeof(entered), "%i", GameConfig.ios); snprintf(entered, sizeof(entered), "%i", GameConfig.ios);
@ -630,14 +658,15 @@ int GameLoadSM::GetMenuInternal()
//! Settings: EmuNAND Save/Channel Path //! Settings: EmuNAND Save/Channel Path
else if (ret == ++Idx) else if (ret == ++Idx)
{ {
int autoIOS = GameConfig.autoios == INHERIT ? Settings.AutoIOS : GameConfig.autoios;
// If NandEmuPath is on root of the first FAT32 partition, allow rev17-21 cIOS for EmuNAND Channels // If NandEmuPath is on root of the first FAT32 partition, allow rev17-21 cIOS for EmuNAND Channels
bool NandEmu_compatible = false; bool NandEmu_compatible = false;
if(Header->type == TYPE_GAME_EMUNANDCHAN) if(!autoIOS && Header->type == TYPE_GAME_EMUNANDCHAN)
{ {
NandEmu_compatible = IosLoader::is_NandEmu_compatible(NULL, GameConfig.ios == INHERIT ? Settings.cios : GameConfig.ios); NandEmu_compatible = IosLoader::is_NandEmu_compatible(NULL, GameConfig.ios == INHERIT ? Settings.cios : GameConfig.ios);
} }
if(!IosLoader::IsD2X(GameConfig.ios == INHERIT ? Settings.cios : GameConfig.ios) && !NandEmu_compatible) if(autoIOS == GAME_IOS_CUSTOM && !IosLoader::IsD2X(GameConfig.ios == INHERIT ? Settings.cios : GameConfig.ios) && !NandEmu_compatible)
WindowPrompt(tr("Error:"), tr("NAND emulation is only available on D2X cIOS!"), tr("OK")); WindowPrompt(tr("Error:"), tr("NAND emulation is only available on D2X cIOS!"), tr("OK"));
else else
{ {

View File

@ -45,6 +45,12 @@ static const char * OnOffText[] =
trNOOP( "Auto" ) trNOOP( "Auto" )
}; };
static const char * GamesIOSText[] =
{
trNOOP( "Auto" ),
trNOOP( "Custom" )
};
static const char * AspectText[] = static const char * AspectText[] =
{ {
trNOOP( "Force 4:3" ), trNOOP( "Force 4:3" ),
@ -219,6 +225,7 @@ LoaderSettings::LoaderSettings()
oldLoaderMode = Settings.LoaderMode; oldLoaderMode = Settings.LoaderMode;
oldGameCubeSource = Settings.GameCubeSource; oldGameCubeSource = Settings.GameCubeSource;
oldLoaderIOS = Settings.LoaderIOS;
} }
LoaderSettings::~LoaderSettings() LoaderSettings::~LoaderSettings()
@ -238,6 +245,11 @@ LoaderSettings::~LoaderSettings()
{ {
GCGames::Instance()->LoadAllGames(); GCGames::Instance()->LoadAllGames();
} }
if(oldLoaderIOS != Settings.LoaderIOS)
{
editMetaArguments();
}
} }
void LoaderSettings::SetOptionNames() void LoaderSettings::SetOptionNames()
@ -262,6 +274,10 @@ void LoaderSettings::SetOptionNames()
} }
Options->SetName(Idx++, "%s", tr( "Loaders IOS" )); Options->SetName(Idx++, "%s", tr( "Loaders IOS" ));
Options->SetName(Idx++, "%s", tr( "Games IOS" )); Options->SetName(Idx++, "%s", tr( "Games IOS" ));
if(Settings.AutoIOS == GAME_IOS_CUSTOM)
{
Options->SetName(Idx++, "%s", tr( "Custom Games IOS" ));
}
Options->SetName(Idx++, "%s", tr( "Quick Boot" )); Options->SetName(Idx++, "%s", tr( "Quick Boot" ));
Options->SetName(Idx++, "%s", tr( "Block IOS Reload" )); Options->SetName(Idx++, "%s", tr( "Block IOS Reload" ));
Options->SetName(Idx++, "%s", tr( "Return To" )); Options->SetName(Idx++, "%s", tr( "Return To" ));
@ -371,16 +387,25 @@ void LoaderSettings::SetOptionValues()
//! Settings: Loaders IOS //! Settings: Loaders IOS
if (Settings.godmode) if (Settings.godmode)
Options->SetValue(Idx++, "IOS %i", Settings.LoaderIOS); Options->SetValue(Idx++, "%i", Settings.LoaderIOS);
else else
Options->SetValue(Idx++, "********"); Options->SetValue(Idx++, "********");
//! Settings: Games IOS //! Settings: Games IOS
if (Settings.godmode) if (Settings.godmode)
Options->SetValue(Idx++, "IOS %i", Settings.cios); Options->SetValue(Idx++, "%s", tr( GamesIOSText[Settings.AutoIOS] ));
else else
Options->SetValue(Idx++, "********"); Options->SetValue(Idx++, "********");
//! Settings: Custom Games IOS
if(Settings.AutoIOS == GAME_IOS_CUSTOM)
{
if (Settings.godmode)
Options->SetValue(Idx++, "%i", Settings.cios);
else
Options->SetValue(Idx++, "********");
}
//! Settings: Quick Boot //! Settings: Quick Boot
Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.quickboot] )); Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.quickboot] ));
@ -693,6 +718,17 @@ int LoaderSettings::GetMenuInternal()
//! Settings: Games IOS //! Settings: Games IOS
else if (ret == ++Idx) else if (ret == ++Idx)
{
if(!Settings.godmode)
return MENU_NONE;
if (++Settings.AutoIOS >= GAME_IOS_MAX) Settings.AutoIOS = GAME_IOS_AUTO;
Options->ClearList();
SetOptionNames();
SetOptionValues();
}
//! Settings: Custom Games IOS
else if (Settings.AutoIOS == GAME_IOS_CUSTOM && ret == ++Idx)
{ {
if(!Settings.godmode) if(!Settings.godmode)
return MENU_NONE; return MENU_NONE;
@ -738,8 +774,11 @@ int LoaderSettings::GetMenuInternal()
//! Settings: EmuNAND Save Mode //! Settings: EmuNAND Save Mode
else if (ret == ++Idx ) else if (ret == ++Idx )
{ {
if(!IosLoader::IsD2X(Settings.cios)) if (Settings.AutoIOS == GAME_IOS_CUSTOM && !IosLoader::IsD2X(Settings.cios))
WindowPrompt(tr("Error:"), tr("NAND Emulation is only available on D2X cIOS!"), tr("OK")); {
WindowPrompt(tr("Error:"), tr("NAND emulation is only available on D2X cIOS!"), tr("OK"));
Settings.NandEmuMode = EMUNAND_OFF;
}
else if (++Settings.NandEmuMode >= EMUNAND_NEEK) Settings.NandEmuMode = EMUNAND_OFF; else if (++Settings.NandEmuMode >= EMUNAND_NEEK) Settings.NandEmuMode = EMUNAND_OFF;
} }

View File

@ -38,6 +38,7 @@ class LoaderSettings : public SettingsMenu
short oldLoaderMode; short oldLoaderMode;
short oldGameCubeSource; short oldGameCubeSource;
short oldLoaderIOS;
OptionList GuiOptions; OptionList GuiOptions;
}; };

View File

@ -34,6 +34,8 @@ int updateMetaXML()
return 0; return 0;
char line[50]; char line[50];
snprintf(line, sizeof(line), "--ios=%d", Settings.LoaderIOS);
MetaXML.SetArgument(line);
snprintf(line, sizeof(line), "--bootios=%d", Settings.BootIOS); snprintf(line, sizeof(line), "--bootios=%d", Settings.BootIOS);
MetaXML.SetArgument(line); MetaXML.SetArgument(line);
snprintf(line, sizeof(line), "--usbport=%d", Settings.USBPort); snprintf(line, sizeof(line), "--usbport=%d", Settings.USBPort);
@ -85,6 +87,8 @@ int editMetaArguments()
// generate argurments // generate argurments
if (strstr(line, "<arguments>") != NULL) if (strstr(line, "<arguments>") != NULL)
{ {
fputs(line, destination);
snprintf(line, max_line_size, " <arg>--ios=%d</arg>\n", Settings.LoaderIOS);
fputs(line, destination); fputs(line, destination);
snprintf(line, max_line_size, " <arg>--bootios=%d</arg>\n", Settings.BootIOS); snprintf(line, max_line_size, " <arg>--bootios=%d</arg>\n", Settings.BootIOS);
fputs(line, destination); fputs(line, destination);
@ -112,10 +116,8 @@ int editMetaArguments()
fclose(destination); fclose(destination);
delete[] line; delete[] line;
if(CopyFile(metatmppath, metapath) <0) if (RemoveFile(metapath))
return 0; RenameFile(metatmppath, metapath);
RemoveFile(metatmppath);
return 1; return 1;
} }

View File

@ -1,5 +1,6 @@
#include <gctypes.h> #include <gctypes.h>
#include <ogc/machine/processor.h> #include <ogc/machine/processor.h>
#include <algorithm>
#include "IosLoader.h" #include "IosLoader.h"
#include "sys.h" #include "sys.h"
@ -18,27 +19,23 @@
#include "mload/modules/odip_frag.h" #include "mload/modules/odip_frag.h"
#include "utils/tools.h" #include "utils/tools.h"
#include "gecko.h" #include "gecko.h"
#include "libs/libruntimeiospatch/runtimeiospatch.h"
#define MEM2_PROT 0x0D8B420A
#define ES_MODULE_START ((u16 *)0x939F0000)
#define ES_MODULE_END (ES_MODULE_START + 0x4000)
#define ES_HACK_OFFSET 4
extern u32 hdd_sector_size[2]; extern u32 hdd_sector_size[2];
/* /*
* Buffer variables for the IOS info to avoid loading it several times * Buffer variables for the IOS info to avoid loading it several times
*/ */
static int currentIOS = -1;
static iosinfo_t *currentIOSInfo = NULL;
static int currentMIOS = -1; static int currentMIOS = -1;
static int currentDMLVersion = -1; static int currentDMLVersion = -1;
std::vector<struct d2x> d2x_list;
/****************************************************************************** /******************************************************************************
* Public Methods: * Public Methods:
******************************************************************************/ ******************************************************************************/
/* /*
* Check if the ios passed is a Hermes ios. * Check if the IOS passed is a Hermes IOS.
*/ */
bool IosLoader::IsHermesIOS(s32 ios) bool IosLoader::IsHermesIOS(s32 ios)
{ {
@ -46,7 +43,7 @@ bool IosLoader::IsHermesIOS(s32 ios)
} }
/* /*
* Check if the ios passed is a Waninkoko ios. * Check if the IOS passed is a Waninkoko IOS.
*/ */
bool IosLoader::IsWaninkokoIOS(s32 ios) bool IosLoader::IsWaninkokoIOS(s32 ios)
{ {
@ -57,22 +54,77 @@ bool IosLoader::IsWaninkokoIOS(s32 ios)
} }
/* /*
* Check if the ios passed is a d2x ios. * Check if the IOS passed is a d2x IOS.
*/ */
bool IosLoader::IsD2X(s32 ios) bool IosLoader::IsD2X(s32 ios)
{ {
iosinfo_t *info = GetIOSInfo(ios); for (auto cios = d2x_list.begin(); cios != d2x_list.end(); ++cios)
if(!info) {
if (cios->slot == ios)
return true;
}
return false; return false;
bool res = (strncasecmp(info->name, "d2x", 3) == 0);
return res;
} }
/* /*
* Loads CIOS (If possible the one from the settings file). * Check if the IOS is a d2x cIOS and return the base IOS.
* @return 0 if a cios has been successfully loaded. Else a value below 0 is returned. */
bool IosLoader::IsD2XBase(s32 ios, s32 *base)
{
iosinfo_t *info = GetIOSInfo(ios);
if(!info)
{
*base = 0;
return 0;
}
*base = (u8)info->baseios;
bool result = (strncasecmp(info->name, "d2x", 3) == 0);
free(info);
return result;
}
/*
* Get the cIOS slot from a given base IOS.
*/
s32 IosLoader::GetD2XIOS(s32 base)
{
for (auto cios = d2x_list.begin(); cios != d2x_list.end(); ++cios)
{
if (cios->base == base)
return cios->slot;
}
return 0;
}
/*
* Check if slots 255-200 contain a d2x cIOS and store info about them.
*/
void IosLoader::GetD2XInfo()
{
s32 base = 0;
ISFS_Initialize();
for (s32 i = 255; i >= 200; i--) // Prefer higher slots e.g. 251, 250 & 249
{
if (IsD2XBase(i, &base))
{
struct d2x cios = {};
cios.slot = i;
cios.base = base;
cios.duplicate = GetD2XIOS(base) ? 1 : 0;
d2x_list.push_back(cios);
gprintf("Found d2x cIOS %d (base %d)\n", i, base);
}
}
ISFS_Deinitialize();
std::sort(d2x_list.begin(), d2x_list.end(), [](const d2x &a, const d2x &b)
{ return a.base < b.base; });
}
/*
* 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(u8 ios) s32 IosLoader::LoadAppCios(u8 ios)
{ {
@ -98,7 +150,7 @@ s32 IosLoader::LoadAppCios(u8 ios)
if ((ret = ReloadIosSafe(cios)) > -1) if ((ret = ReloadIosSafe(cios)) > -1)
{ {
// Remember working cios // Remember working cIOS
Settings.LoaderIOS = cios; Settings.LoaderIOS = cios;
break; break;
} }
@ -108,8 +160,8 @@ s32 IosLoader::LoadAppCios(u8 ios)
} }
/* /*
* Loads a CIOS before a game start. * Loads a cIOS before a game start.
* @return 0 if a cios has been successfully loaded. Else a value below 0 is returned. * @return 0 if a cIOS has been successfully loaded. Else a value below 0 is returned.
*/ */
s32 IosLoader::LoadGameCios(s32 ios) s32 IosLoader::LoadGameCios(s32 ios)
{ {
@ -136,7 +188,7 @@ s32 IosLoader::LoadGameCios(s32 ios)
/* /*
* Reloads a certain IOS under the condition, that an appropriate version of the IOS is installed. * 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. * @return a negative value if a safe reload of the IOS was not possible.
*/ */
s32 IosLoader::ReloadIosSafe(s32 ios) s32 IosLoader::ReloadIosSafe(s32 ios)
{ {
@ -176,45 +228,11 @@ s32 IosLoader::ReloadIosSafe(s32 ios)
*/ */
s32 IosLoader::ReloadIosKeepingRights(s32 ios) s32 IosLoader::ReloadIosKeepingRights(s32 ios)
{ {
PatchAHB(); IosPatch_AHBPROT(false);
// Reload IOS. MEM2 protection is implicitly re-enabled // Reload IOS. MEM2 protection is implicitly re-enabled
return IOS_ReloadIOS(ios); return IOS_ReloadIOS(ios);
} }
void IosLoader::PatchAHB()
{
if (CheckAHBPROT())
{
static const u16 ticket_check[] = {
0x685B, // ldr r3, [r3, #4] ; Get TMD pointer
0x22EC, 0x0052, // movs r2, 0x1D8 ; Set offset of access rights field in TMD
0x189B, // adds r3, r3, r2 ; Add offset to TMD pointer
0x681B, // ldr r3, [r3] ; Load access rights. We'll hack it with full access rights!!!
0x4698, // mov r8, r3 ; Store it for the DVD video bitcheck later
0x07DB // lsls r3, r3, 0x1F ; check AHBPROT bit
};
// Disable memory protection
write16(MEM2_PROT, 0);
for (u16 *patchme = ES_MODULE_START; patchme < ES_MODULE_END; patchme++)
{
if (!memcmp(patchme, ticket_check, sizeof(ticket_check)))
{
gprintf("PatchAHB: Found TMD access rights check at %p\n", patchme);
/* Apply patch */
patchme[ES_HACK_OFFSET] = 0x23FF; // li r3, 0xFF ; Set full access rights
/* Flush cache */
DCFlushRange(patchme+ES_HACK_OFFSET, 2);
break;
}
}
// Enable memory protection
write16(MEM2_PROT, 1);
}
}
/* /*
* Check if MIOS is DIOS MIOS, DIOS MIOS Lite or official MIOS. * Check if MIOS is DIOS MIOS, DIOS MIOS Lite or official MIOS.
*/ */
@ -565,70 +583,51 @@ void IosLoader::LoadIOSModules(s32 ios, s32 ios_rev)
mload_close(); mload_close();
} }
} }
if (info)
free(info);
ISFS_Deinitialize(); ISFS_Deinitialize();
} }
} }
/* /*
* Reads the ios info struct from the .app file. * 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. * @return pointer to iosinfo_t on success else NULL. The user is responsible for freeing the buffer.
*/ */
iosinfo_t *IosLoader::GetIOSInfo(s32 ios) iosinfo_t *IosLoader::GetIOSInfo(s32 ios)
{ {
if(currentIOS == ios && currentIOSInfo) char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
return currentIOSInfo;
if(currentIOSInfo)
{
free(currentIOSInfo);
currentIOSInfo = NULL;
}
currentIOS = ios;
char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(0x20);
u64 TicketID = ((((u64) 1) << 32) | ios); u64 TicketID = ((((u64) 1) << 32) | ios);
u32 TMD_Length; u32 TMD_Length;
s32 ret = ES_GetStoredTMDSize(TicketID, &TMD_Length); if (ES_GetStoredTMDSize(TicketID, &TMD_Length) < 0)
if (ret < 0)
return NULL; return NULL;
signed_blob *TMD = (signed_blob*) memalign(32, ALIGN32(TMD_Length)); signed_blob *TMD = (signed_blob*) memalign(32, ALIGN32(TMD_Length));
if (!TMD) if (!TMD)
return NULL; return NULL;
ret = ES_GetStoredTMD(TicketID, TMD, TMD_Length); if (ES_GetStoredTMD(TicketID, TMD, TMD_Length) < 0)
if (ret < 0)
{ {
free(TMD); free(TMD);
return NULL; return NULL;
} }
snprintf(filepath, sizeof(filepath), "/title/%08x/%08x/content/%08x.app", 0x00000001, (unsigned int)ios, (unsigned int)(*(u8 *)((u32)TMD+0x1E7))); snprintf(filepath, sizeof(filepath), "/title/00000001/%08x/content/%08x.app", (u8)ios, *(u8 *)((u32)TMD+0x1E7));
free(TMD); free(TMD);
u8 *buffer = NULL;
u32 filesize = 0; u32 filesize = 0;
iosinfo_t *buffer = NULL;
NandTitle::LoadFileFromNand(filepath, &buffer, &filesize); NandTitle::LoadFileFromNand(filepath, (u8**)&buffer, &filesize);
if(!buffer) if (!buffer || filesize == 0)
return NULL; return NULL;
iosinfo_t *iosinfo = (iosinfo_t *) buffer; if (buffer->magicword != 0x1ee7c105 || buffer->magicversion != 1)
if(iosinfo->magicword != 0x1ee7c105 || iosinfo->magicversion != 1)
{ {
free(buffer); free(buffer);
return NULL; return NULL;
} }
iosinfo = (iosinfo_t *) realloc(buffer, sizeof(iosinfo_t)); return buffer;
if(!iosinfo)
iosinfo = (iosinfo_t *) buffer;
currentIOSInfo = iosinfo;
return iosinfo;
} }

View File

@ -81,6 +81,13 @@ typedef struct _iosinfo_t
char versionstring[0x10]; // Example: beta2 char versionstring[0x10]; // Example: beta2
} __attribute__((packed)) iosinfo_t; } __attribute__((packed)) iosinfo_t;
typedef struct d2x
{
s32 slot;
s32 base;
s32 duplicate;
} d2x;
class IosLoader class IosLoader
{ {
public: public:
@ -88,10 +95,12 @@ class IosLoader
static s32 LoadGameCios(s32 ios); static s32 LoadGameCios(s32 ios);
static s32 ReloadIosSafe(s32 ios); static s32 ReloadIosSafe(s32 ios);
static s32 ReloadIosKeepingRights(s32 ios); static s32 ReloadIosKeepingRights(s32 ios);
static void PatchAHB();
static bool IsHermesIOS(s32 ios = IOS_GetVersion()); static bool IsHermesIOS(s32 ios = IOS_GetVersion());
static bool IsWaninkokoIOS(s32 ios = IOS_GetVersion()); static bool IsWaninkokoIOS(s32 ios = IOS_GetVersion());
static bool IsD2X(s32 ios = IOS_GetVersion()); static bool IsD2X(s32 ios = IOS_GetVersion());
static bool IsD2XBase(s32 ios, s32 *base);
static s32 GetD2XIOS(s32 base);
static void GetD2XInfo();
static iosinfo_t *GetIOSInfo(s32 ios); static iosinfo_t *GetIOSInfo(s32 ios);
static u8 GetMIOSInfo(); static u8 GetMIOSInfo();
static u8 GetDMLVersion(char* releaseDate = NULL); static u8 GetDMLVersion(char* releaseDate = NULL);

View File

@ -15,6 +15,8 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include <algorithm>
#include "menu/menus.h" #include "menu/menus.h"
#include "menu/WDMMenu.hpp" #include "menu/WDMMenu.hpp"
#include "mload/mload.h" #include "mload/mload.h"
@ -57,6 +59,7 @@
#include "neek.hpp" #include "neek.hpp"
#include "lstub.h" #include "lstub.h"
#include "xml/GameTDB.hpp" #include "xml/GameTDB.hpp"
#include "wad/nandtitle.h"
/* GCC 11 false positives */ /* GCC 11 false positives */
#if __GNUC__ > 10 #if __GNUC__ > 10
@ -69,6 +72,7 @@ u32 AppEntrypoint = 0;
extern bool isWiiVC; // in sys.cpp extern bool isWiiVC; // in sys.cpp
extern u32 hdd_sector_size[2]; extern u32 hdd_sector_size[2];
extern std::vector<struct d2x> d2x_list;
extern "C" extern "C"
{ {
syssram *__SYS_LockSram(); syssram *__SYS_LockSram();
@ -143,7 +147,8 @@ u32 GameBooter::BootPartition(char *dolpath, u8 videoselected, u8 alternatedol,
return 0; return 0;
/* Open specified partition */ /* Open specified partition */
ret = WDVD_OpenPartition(offset); u32 Tmd_Buffer[0x4A00] ATTRIBUTE_ALIGN(32);
ret = WDVD_OpenPartition(offset, Tmd_Buffer);
if (ret < 0) if (ret < 0)
return 0; return 0;
@ -307,6 +312,7 @@ int GameBooter::BootGame(struct discHdr *gameHdr)
u8 deflicker = game_cfg->deflicker == INHERIT ? Settings.deflicker : game_cfg->deflicker; u8 deflicker = game_cfg->deflicker == INHERIT ? Settings.deflicker : game_cfg->deflicker;
u8 sneekChoice = game_cfg->sneekVideoPatch == INHERIT ? Settings.sneekVideoPatch : game_cfg->sneekVideoPatch; u8 sneekChoice = game_cfg->sneekVideoPatch == INHERIT ? Settings.sneekVideoPatch : game_cfg->sneekVideoPatch;
s32 iosChoice = game_cfg->ios == INHERIT ? Settings.cios : game_cfg->ios; s32 iosChoice = game_cfg->ios == INHERIT ? Settings.cios : game_cfg->ios;
u8 autoIOS = game_cfg->autoios == INHERIT ? Settings.AutoIOS : game_cfg->autoios;
u8 countrystrings = game_cfg->patchcountrystrings == INHERIT ? Settings.patchcountrystrings : game_cfg->patchcountrystrings; u8 countrystrings = game_cfg->patchcountrystrings == INHERIT ? Settings.patchcountrystrings : game_cfg->patchcountrystrings;
u8 alternatedol = game_cfg->loadalternatedol; u8 alternatedol = game_cfg->loadalternatedol;
u32 alternatedoloffset = game_cfg->alternatedolstart; u32 alternatedoloffset = game_cfg->alternatedolstart;
@ -363,6 +369,104 @@ int GameBooter::BootGame(struct discHdr *gameHdr)
} }
} }
if (autoIOS == GAME_IOS_AUTO && d2x_list.size())
{
s32 requestedIOS = 0;
if (gameHeader.type == TYPE_GAME_NANDCHAN)
requestedIOS = Channels::GetRequestedIOS(gameHeader.tid, NULL);
else if (gameHeader.type == TYPE_GAME_EMUNANDCHAN)
requestedIOS = Channels::GetRequestedIOS(gameHeader.tid, NandEmuPath);
else if (gameHeader.type == TYPE_GAME_WII_IMG)
{
wbfs_disc_t *d = WBFS_OpenDisc(gameHeader.id);
if (d)
{
void *titleTMD = NULL;
int tmd_size = wbfs_extract_file(d, (char *)"TMD", &titleTMD);
if (titleTMD != NULL)
{
if (tmd_size > 0x18B)
requestedIOS = *((u8 *)titleTMD + 0x18B);
free(titleTMD);
}
WBFS_CloseDisc(d);
}
}
else if (gameHeader.type == TYPE_GAME_WII_DISC)
{
u64 offset;
if (Disc_FindPartition(&offset) >= 0)
{
u32 Tmd_Buffer[0x4A00] ATTRIBUTE_ALIGN(32);
if (WDVD_OpenPartition(offset, Tmd_Buffer) >= 0)
{
tmd *tmd_dvd = (tmd *)SIGNATURE_PAYLOAD(Tmd_Buffer);
requestedIOS = tmd_dvd->sys_version;
WDVD_ClosePartition();
}
}
}
if (requestedIOS)
{
// Remove cIOS duplicates
// This is done here so that IsD2X() always has the complete list
for (auto cios = d2x_list.begin(); cios != d2x_list.end();)
{
if (cios->duplicate)
{
gprintf("Duplicate IOS: %d in slot %d removed\n", cios->base, cios->slot);
cios = d2x_list.erase(cios);
}
else
++cios;
}
gprintf("Requested IOS: %d\n", requestedIOS);
// Workaround for SpongeBobs Boating Bash
if (memcmp(gameHeader.id, "SBV", 3) == 0)
{
// Check if we don't have a cIOS with base IOS 53
if (!IosLoader::GetD2XIOS(requestedIOS))
{
if (isWiiU())
requestedIOS = 58;
else
requestedIOS = IosLoader::GetD2XIOS(58) ? 58 : 38;
gprintf("Applied SpongeBob workaround\n");
}
}
// Check if there's any cIOS options remaining
if (d2x_list.size())
{
// Check for a D2X cIOS with the requested base IOS
int slot = IosLoader::GetD2XIOS(requestedIOS);
if (slot)
iosChoice = slot;
else
{
// Nothing found, so try the closest match
// e.g. if we've got 55, 57 & 58 and a game requests 56 we'll use 57
auto cios = std::lower_bound(d2x_list.begin(), d2x_list.end(), requestedIOS, [](const d2x &x, const int &y)
{ return x.base < y; });
// Check if the requested IOS is greater than what's available
if (cios == d2x_list.end())
{
requestedIOS = d2x_list.back().base;
iosChoice = d2x_list.back().slot;
}
else
{
requestedIOS = cios->base;
iosChoice = cios->slot;
}
gprintf("Next best IOS: %d\n", requestedIOS);
}
gprintf("Boot with IOS: %d base %d\n", iosChoice, requestedIOS);
}
}
}
AppCleanUp(); AppCleanUp();
gprintf("\tSettings.partition: %d\n", Settings.partition); gprintf("\tSettings.partition: %d\n", Settings.partition);

View File

@ -193,12 +193,11 @@ s32 WDVD_StopMotor(void)
return (ret == 1) ? 0 : -ret; return (ret == 1) ? 0 : -ret;
} }
s32 WDVD_OpenPartition(u64 offset) s32 WDVD_OpenPartition(u64 offset, u32 *tmdbuf)
{ {
if (_di_fd < 0) if (_di_fd < 0)
return _di_fd; return _di_fd;
static u8 Tmd_Buffer[0x4A00] ATTRIBUTE_ALIGN(32);
static ioctlv Vectors[5] ATTRIBUTE_ALIGN(32); static ioctlv Vectors[5] ATTRIBUTE_ALIGN(32);
s32 ret; s32 ret;
@ -214,7 +213,7 @@ s32 WDVD_OpenPartition(u64 offset)
Vectors[1].len = 0; Vectors[1].len = 0;
Vectors[2].data = 0; Vectors[2].data = 0;
Vectors[2].len = 0; Vectors[2].len = 0;
Vectors[3].data = Tmd_Buffer; Vectors[3].data = tmdbuf;
Vectors[3].len = 0x49e4; Vectors[3].len = 0x49e4;
Vectors[4].data = outbuf; Vectors[4].data = outbuf;
Vectors[4].len = 0x20; Vectors[4].len = 0x20;

View File

@ -15,7 +15,7 @@ s32 WDVD_Seek(u64);
s32 WDVD_Offset(u64); s32 WDVD_Offset(u64);
s32 WDVD_StopLaser(void); s32 WDVD_StopLaser(void);
s32 WDVD_StopMotor(void); s32 WDVD_StopMotor(void);
s32 WDVD_OpenPartition(u64 offset); s32 WDVD_OpenPartition(u64 offset, u32 *tmdbuf);
s32 WDVD_ClosePartition(void); s32 WDVD_ClosePartition(void);
s32 WDVD_UnencryptedRead(void *, u32, u64); s32 WDVD_UnencryptedRead(void *, u32, u64);
s32 WDVD_Read(void *, u32, u64); s32 WDVD_Read(void *, u32, u64);

View File

@ -49,6 +49,7 @@ cat <<EOF > ./HBC/meta.xml
<release_date>$rev_date</release_date> <release_date>$rev_date</release_date>
<!-- remove this line to enable arguments <!-- remove this line to enable arguments
<arguments> <arguments>
<arg>--ios=249</arg>
<arg>--bootios=58</arg> <arg>--bootios=58</arg>
<arg>--usbport=0</arg> <arg>--usbport=0</arg>
<arg>--mountusb=1</arg> <arg>--mountusb=1</arg>
@ -75,11 +76,9 @@ Libwiigui: Tantric
Libogc/Devkit: Shagkur and Wintermute Libogc/Devkit: Shagkur and Wintermute
FreeTypeGX: Armin Tamzarian FreeTypeGX: Armin Tamzarian
USB Loader GX (enhanced): USB Loader GX:
https://github.com/wiidev/usbloadergx https://github.com/wiidev/usbloadergx
USB Loader GX (official): Support:
https://sourceforge.net/projects/usbloadergx
Support (official):
https://gbatemp.net/threads/149922 https://gbatemp.net/threads/149922
GameTDB: GameTDB:
https://www.gametdb.com https://www.gametdb.com