mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-12-24 10:51:48 +01:00
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:
parent
83133a292b
commit
ab3273f475
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -555,6 +555,12 @@ msgstr ""
|
||||
msgid "Custom Banners"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Game IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Games IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Paths"
|
||||
msgstr ""
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -555,6 +555,12 @@ msgstr ""
|
||||
msgid "Custom Banners"
|
||||
msgstr "Τροποποιημένες ταμπέλες-εικονίδια"
|
||||
|
||||
msgid "Custom Game IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Games IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Paths"
|
||||
msgstr "Τροποποιημένες διευθύνσεις/μονοπάτια αρχείων"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -555,6 +555,12 @@ msgstr "カスタム アドレス"
|
||||
msgid "Custom Banners"
|
||||
msgstr "カスタムバナー"
|
||||
|
||||
msgid "Custom Game IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Games IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Paths"
|
||||
msgstr "パスを変更"
|
||||
|
||||
|
@ -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 "커스텀 경로"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -555,6 +555,12 @@ msgstr ""
|
||||
msgid "Custom Banners"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Game IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Games IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Paths"
|
||||
msgstr "Sciezki"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -555,6 +555,12 @@ msgstr ""
|
||||
msgid "Custom Banners"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Game IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Games IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Paths"
|
||||
msgstr "Изменение путей"
|
||||
|
||||
|
@ -555,6 +555,12 @@ msgstr "自定义地址"
|
||||
msgid "Custom Banners"
|
||||
msgstr "自定义频道动画"
|
||||
|
||||
msgid "Custom Game IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Games IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Paths"
|
||||
msgstr "自定义路径"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -555,6 +555,12 @@ msgstr "自訂地址"
|
||||
msgid "Custom Banners"
|
||||
msgstr "自製頻道動畫"
|
||||
|
||||
msgid "Custom Game IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Games IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Paths"
|
||||
msgstr "自訂路徑"
|
||||
|
||||
|
@ -555,6 +555,12 @@ msgstr ""
|
||||
msgid "Custom Banners"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Game IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Games IOS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom Paths"
|
||||
msgstr "กำหนด ที่เก็บ"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
5
Makefile
5
Makefile
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -11,6 +11,7 @@ public:
|
||||
private:
|
||||
StartUpProcess();
|
||||
~StartUpProcess();
|
||||
void LoadIOS(u8 ios, bool boot);
|
||||
int Execute(bool quickGameBoot);
|
||||
bool USBSpinUp();
|
||||
void TextFade(int direction);
|
||||
|
Binary file not shown.
237
source/libs/libruntimeiospatch/runtimeiospatch.c
Normal file
237
source/libs/libruntimeiospatch/runtimeiospatch.c
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -409,4 +409,11 @@ enum TITLETYPE
|
||||
TITLETYPE_MANUAL_OVERRIDE = 7
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GAME_IOS_AUTO,
|
||||
GAME_IOS_CUSTOM,
|
||||
GAME_IOS_MAX
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ class LoaderSettings : public SettingsMenu
|
||||
|
||||
short oldLoaderMode;
|
||||
short oldGameCubeSource;
|
||||
short oldLoaderIOS;
|
||||
OptionList GuiOptions;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user