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"
msgstr ""
msgid "Custom Game IOS"
msgstr ""
msgid "Custom Games IOS"
msgstr ""
msgid "Custom Paths"
msgstr "Vlastní cesty"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,6 +21,7 @@ SOURCES := source \
source/Controls \
source/system \
source/libs/libwbfs \
source/libs/libruntimeiospatch \
source/language \
source/mload \
source/mload/modules \
@ -73,7 +74,7 @@ endif
#---------------------------------------------------------------------------------
LIBS := -lwolfssl -lcustomfat -lcustomntfs -lcustomext2fs -lvorbisidec -logg \
-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
# 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/ \
-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)
export OUTPUT := $(CURDIR)/$(TARGET)

View File

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

View File

@ -37,7 +37,7 @@ public:
static void DestroyInstance(void) { if(instance) delete instance; instance = NULL; }
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 *GetDol(const u64 &title, u8 *tmdBuffer, bool &isForwarder);
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->SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
versionTxt->SetPosition(20, screenheight - 20);
versionTxt->SetPosition(23, screenheight - 20);
#ifdef FULLCHANNEL
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]);
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 (atoi(ptr + strlen("-bootios=")) == 58)
Settings.LoaderIOS = 58;
Settings.BootIOS = 58;
else
Settings.LoaderIOS = LIMIT(atoi(ptr + strlen("-bootios=")), 200, 255);
Settings.UseArgumentIOS = ON;
Settings.BootIOS = Settings.LoaderIOS;
Settings.BootIOS = LIMIT(atoi(ptr + strlen("-bootios=")), 200, 255);
}
ptr = strcasestr(argv[i], "-usbport=");
@ -245,38 +252,54 @@ int StartUpProcess::Run(int argc, char *argv[])
return ret;
}
void StartUpProcess::LoadIOS(u8 ios, bool boot)
{
SetTextf("Reloading to IOS%d%s\n", ios, boot ? " requested in meta.xml" : "");
if (IosLoader::LoadAppCios(ios) < 0)
{
SetTextf("Failed to load an IOS. USB Loader GX requires a cIOS or IOS58 with AHB access. Exiting...\n");
sleep(5);
Sys_BackToLoader();
}
SetTextf("Reloaded to IOS%d r%d\n", Settings.LoaderIOS, IOS_GetRevision());
}
int StartUpProcess::Execute(bool quickGameBoot)
{
Settings.EntryIOS = IOS_GetVersion();
// Disable AHBPROT
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");
sleep(5);
Sys_BackToLoader();
}
SetTextf("Reloaded to cIOS %d\n", Settings.LoaderIOS);
gprintf("Current IOS: %d - have AHB access: %s\n", IOS_GetVersion(), AHBPROT_DISABLED ? "yes" : "no");
}
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();
// Mount the SD card
SetTextf("Initializing SD card\n");
DeviceHandler::Instance()->MountSD();
// Do not mount USB if not needed. USB is not available with WiiU WiiVC injected channel
bool USBSuccess = false;
if (Settings.USBAutoMount == ON && !isWiiVC)
{
SetTextf("Initializing USB devices\n");
USBSpinUp();
DeviceHandler::Instance()->MountAllUSB(false);
gprintf("Completed initialization of USB devices\n");
if (USBSpinUp())
{
DeviceHandler::Instance()->MountAllUSB(false);
USBSuccess = true;
gprintf("Completed initialization of USB devices\n");
}
}
SetTextf("Loading config files\n");
@ -311,7 +334,7 @@ int StartUpProcess::Execute(bool quickGameBoot)
// Now load the cIOS that was set in the settings menu
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
SetTextf("Reinitializing devices\n");
}
@ -321,10 +344,10 @@ int StartUpProcess::Execute(bool quickGameBoot)
SetupPads();
DeviceHandler::Instance()->MountSD();
if (Settings.USBAutoMount == ON)
if (Settings.USBAutoMount == ON && USBSuccess)
{
USBSpinUp();
DeviceHandler::Instance()->MountAllUSB(false);
if (USBSpinUp())
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)
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)
gprintf("Patching %sIOS%d failed!\n", IOS_GetVersion() >= 200 ? "c" : "", IOS_GetVersion());
gprintf("Patching IOS%d failed!\n", IOS_GetVersion());
else
NandTitles.Get(); // get NAND channel's titles

View File

@ -11,6 +11,7 @@ public:
private:
StartUpProcess();
~StartUpProcess();
void LoadIOS(u8 ios, bool boot);
int Execute(bool quickGameBoot);
bool USBSpinUp();
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,8 +745,9 @@ void GameWindow::BootGame(struct discHdr *header)
snprintf(IDfull, sizeof(IDfull), "%s", (char *) header->id);
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;
if(header->type == TYPE_GAME_EMUNANDCHAN)
if (header->type == TYPE_GAME_EMUNANDCHAN)
gameNandEmuMode = game_cfg->NandEmuMode == INHERIT ? Settings.NandEmuChanMode : game_cfg->NandEmuMode;
if (game_cfg->loadalternatedol == 2)
@ -760,14 +761,14 @@ void GameWindow::BootGame(struct discHdr *header)
return;
}
}
else if(game_cfg->loadalternatedol == 3 && WDMMenu::Show(header) == 0)
else if (game_cfg->loadalternatedol == 3 && WDMMenu::Show(header) == 0)
{
// Canceled
return;
}
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);
}
@ -778,35 +779,38 @@ void GameWindow::BootGame(struct discHdr *header)
if (CheckFile(filepath) == false)
{
snprintf(filepath + n, sizeof(filepath) - n, " %s", tr( "does not exist! Loading game without cheats." ));
if(!WindowPrompt(tr( "Error" ), filepath, tr( "Continue" ), tr( "Cancel")))
if (!WindowPrompt(tr( "Error" ), filepath, tr( "Continue" ), tr( "Cancel")))
return;
}
}
if(header->type == TYPE_GAME_EMUNANDCHAN)
if (autoIOS == GAME_IOS_CUSTOM)
{
if(gameNandEmuMode != EMUNAND_NEEK)
if (header->type == TYPE_GAME_EMUNANDCHAN)
{
// If NandEmuPath is on root of the first FAT32 partition, allow Waninkoko's rev17-21 cIOS for EmuNAND Channels
bool NandEmu_compatible = false;
const char *NandEmuChanPath = game_cfg->NandEmuPath.size() == 0 ? Settings.NandEmuChanPath : game_cfg->NandEmuPath.c_str();
NandEmu_compatible = IosLoader::is_NandEmu_compatible(NandEmuChanPath, gameIOS);
if(!IosLoader::IsD2X(gameIOS) && !NandEmu_compatible)
if (gameNandEmuMode != EMUNAND_NEEK)
{
ShowError(tr("Launching emulated NAND channels only works on d2x cIOS! Change game IOS to a d2x cIOS first."));
return;
// If NandEmuPath is on root of the first FAT32 partition, allow Waninkoko's rev17-21 cIOS for EmuNAND Channels
bool NandEmu_compatible = false;
const char *NandEmuChanPath = game_cfg->NandEmuPath.size() == 0 ? Settings.NandEmuChanPath : game_cfg->NandEmuPath.c_str();
NandEmu_compatible = IosLoader::is_NandEmu_compatible(NandEmuChanPath, gameIOS);
if (!IosLoader::IsD2X(gameIOS) && !NandEmu_compatible)
{
ShowError(tr("Launching emulated NAND channels only works on d2x cIOS! Change game IOS to a d2x cIOS first."));
return;
}
}
}
}
// Restrict EmuNAND with Wii games only with d2x
if(header->type == TYPE_GAME_WII_IMG || header->type == TYPE_GAME_WII_DISC)
{
if(gameNandEmuMode && !IosLoader::IsD2X(gameIOS))
// Restrict EmuNAND with Wii games only with d2x
if (header->type == TYPE_GAME_WII_IMG || header->type == TYPE_GAME_WII_DISC)
{
ShowError(tr("Launching Wii games with emulated NAND only works on d2x cIOS! Change game IOS to a d2x cIOS first."));
return;
if (gameNandEmuMode && !IosLoader::IsD2X(gameIOS))
{
ShowError(tr("Launching Wii games with emulated NAND only works on d2x cIOS! Change game IOS to a d2x cIOS first."));
return;
}
}
}

View File

@ -295,10 +295,12 @@ void WindowCredits()
#endif
char IosInfo[80] = "";
iosinfo_t * info = IosLoader::GetIOSInfo(IOS_GetVersion());
iosinfo_t *info = IosLoader::GetIOSInfo(IOS_GetVersion());
if(info)
{
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
char GCInfo[80] = "";
int currentMIOS = IosLoader::GetMIOSInfo();

View File

@ -194,6 +194,7 @@ bool CGameSettings::Save()
fprintf(f, "ocarina:%d; ", GameList[i].ocarina);
fprintf(f, "vipatch:%d; ", GameList[i].vipatch);
fprintf(f, "ios:%d; ", GameList[i].ios);
fprintf(f, "autoios:%d; ", GameList[i].autoios);
fprintf(f, "parentalcontrol:%d; ", GameList[i].parentalcontrol);
fprintf(f, "iosreloadblock:%d; ", GameList[i].iosreloadblock);
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);
return true;
}
else if(strcmp(name, "autoios") == 0)
{
game.autoios = atoi(value);
return true;
}
else if(strcmp(name, "parentalcontrol") == 0)
{
game.parentalcontrol = atoi(value);
@ -689,6 +695,7 @@ void CGameSettings::SetDefault(GameCFG &game)
game.ocarina = INHERIT;
game.vipatch = INHERIT;
game.ios = INHERIT;
game.autoios = INHERIT;
game.parentalcontrol = PARENTAL_LVL_EVERYONE;
game.patchcountrystrings = INHERIT;
game.loadalternatedol = ALT_DOL_DEFAULT;

View File

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

View File

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

View File

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

View File

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

View File

@ -42,6 +42,12 @@ static const char * OnOffText[] =
trNOOP( "Auto" )
};
static const char * GamesIOSText[] =
{
trNOOP( "Auto" ),
trNOOP( "Custom" )
};
static const char * VideoModeText[] =
{
trNOOP( "System Default" ),
@ -226,6 +232,10 @@ void GameLoadSM::SetOptionNames()
Options->SetName(Idx++, "%s", tr( "Hooktype" ));
Options->SetName(Idx++, "%s", tr( "Wiird Debugger" ));
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( "Block IOS Reload" ));
@ -356,10 +366,19 @@ void GameLoadSM::SetOptionValues()
Options->SetValue(Idx++, "%s", tr( OnOffText[GameConfig.WiirdDebugger] ));
//! Settings: Game IOS
if(GameConfig.ios == INHERIT)
if(GameConfig.autoios == INHERIT)
Options->SetValue(Idx++, tr("Use global"));
else
Options->SetValue(Idx++, "%i", GameConfig.ios);
Options->SetValue(Idx++, "%s", tr( GamesIOSText[GameConfig.autoios] ));
//! Settings: Custom Game IOS
if(GameConfig.autoios == GAME_IOS_CUSTOM)
{
if(GameConfig.ios == INHERIT)
Options->SetValue(Idx++, tr("Use global"));
else
Options->SetValue(Idx++, "%i", GameConfig.ios);
}
//! Settings: Return To
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
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];
snprintf(entered, sizeof(entered), "%i", GameConfig.ios);
@ -630,14 +658,15 @@ int GameLoadSM::GetMenuInternal()
//! Settings: EmuNAND Save/Channel Path
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
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);
}
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"));
else
{

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
#include <gctypes.h>
#include <ogc/machine/processor.h>
#include <algorithm>
#include "IosLoader.h"
#include "sys.h"
@ -18,27 +19,23 @@
#include "mload/modules/odip_frag.h"
#include "utils/tools.h"
#include "gecko.h"
#define MEM2_PROT 0x0D8B420A
#define ES_MODULE_START ((u16 *)0x939F0000)
#define ES_MODULE_END (ES_MODULE_START + 0x4000)
#define ES_HACK_OFFSET 4
#include "libs/libruntimeiospatch/runtimeiospatch.h"
extern u32 hdd_sector_size[2];
/*
* 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 currentDMLVersion = -1;
std::vector<struct d2x> d2x_list;
/******************************************************************************
* 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)
{
@ -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)
{
@ -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)
{
iosinfo_t *info = GetIOSInfo(ios);
if(!info)
return false;
bool res = (strncasecmp(info->name, "d2x", 3) == 0);
return res;
for (auto cios = d2x_list.begin(); cios != d2x_list.end(); ++cios)
{
if (cios->slot == ios)
return true;
}
return false;
}
/*
* 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.
* Check if the IOS is a d2x cIOS and return the base IOS.
*/
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)
{
@ -98,7 +150,7 @@ s32 IosLoader::LoadAppCios(u8 ios)
if ((ret = ReloadIosSafe(cios)) > -1)
{
// Remember working cios
// Remember working cIOS
Settings.LoaderIOS = cios;
break;
}
@ -108,8 +160,8 @@ s32 IosLoader::LoadAppCios(u8 ios)
}
/*
* Loads a CIOS before a game start.
* @return 0 if a cios has been successfully loaded. Else a value below 0 is returned.
* 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)
{
@ -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.
* @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)
{
@ -176,45 +228,11 @@ s32 IosLoader::ReloadIosSafe(s32 ios)
*/
s32 IosLoader::ReloadIosKeepingRights(s32 ios)
{
PatchAHB();
IosPatch_AHBPROT(false);
// Reload IOS. MEM2 protection is implicitly re-enabled
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.
*/
@ -565,70 +583,51 @@ void IosLoader::LoadIOSModules(s32 ios, s32 ios_rev)
mload_close();
}
}
if (info)
free(info);
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.
*/
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);
char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
u64 TicketID = ((((u64) 1) << 32) | ios);
u32 TMD_Length;
s32 ret = ES_GetStoredTMDSize(TicketID, &TMD_Length);
if (ret < 0)
if (ES_GetStoredTMDSize(TicketID, &TMD_Length) < 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)
if (ES_GetStoredTMD(TicketID, TMD, TMD_Length) < 0)
{
free(TMD);
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);
u8 *buffer = NULL;
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;
iosinfo_t *iosinfo = (iosinfo_t *) buffer;
if(iosinfo->magicword != 0x1ee7c105 || iosinfo->magicversion != 1)
if (buffer->magicword != 0x1ee7c105 || buffer->magicversion != 1)
{
free(buffer);
return NULL;
}
iosinfo = (iosinfo_t *) realloc(buffer, sizeof(iosinfo_t));
if(!iosinfo)
iosinfo = (iosinfo_t *) buffer;
currentIOSInfo = iosinfo;
return iosinfo;
return buffer;
}

View File

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

View File

@ -15,6 +15,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include <algorithm>
#include "menu/menus.h"
#include "menu/WDMMenu.hpp"
#include "mload/mload.h"
@ -57,6 +59,7 @@
#include "neek.hpp"
#include "lstub.h"
#include "xml/GameTDB.hpp"
#include "wad/nandtitle.h"
/* GCC 11 false positives */
#if __GNUC__ > 10
@ -69,6 +72,7 @@ u32 AppEntrypoint = 0;
extern bool isWiiVC; // in sys.cpp
extern u32 hdd_sector_size[2];
extern std::vector<struct d2x> d2x_list;
extern "C"
{
syssram *__SYS_LockSram();
@ -143,7 +147,8 @@ u32 GameBooter::BootPartition(char *dolpath, u8 videoselected, u8 alternatedol,
return 0;
/* Open specified partition */
ret = WDVD_OpenPartition(offset);
u32 Tmd_Buffer[0x4A00] ATTRIBUTE_ALIGN(32);
ret = WDVD_OpenPartition(offset, Tmd_Buffer);
if (ret < 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 sneekChoice = game_cfg->sneekVideoPatch == INHERIT ? Settings.sneekVideoPatch : game_cfg->sneekVideoPatch;
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 alternatedol = game_cfg->loadalternatedol;
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();
gprintf("\tSettings.partition: %d\n", Settings.partition);

View File

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

View File

@ -15,7 +15,7 @@ s32 WDVD_Seek(u64);
s32 WDVD_Offset(u64);
s32 WDVD_StopLaser(void);
s32 WDVD_StopMotor(void);
s32 WDVD_OpenPartition(u64 offset);
s32 WDVD_OpenPartition(u64 offset, u32 *tmdbuf);
s32 WDVD_ClosePartition(void);
s32 WDVD_UnencryptedRead(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>
<!-- remove this line to enable arguments
<arguments>
<arg>--ios=249</arg>
<arg>--bootios=58</arg>
<arg>--usbport=0</arg>
<arg>--mountusb=1</arg>
@ -75,11 +76,9 @@ Libwiigui: Tantric
Libogc/Devkit: Shagkur and Wintermute
FreeTypeGX: Armin Tamzarian
USB Loader GX (enhanced):
USB Loader GX:
https://github.com/wiidev/usbloadergx
USB Loader GX (official):
https://sourceforge.net/projects/usbloadergx
Support (official):
Support:
https://gbatemp.net/threads/149922
GameTDB:
https://www.gametdb.com