diff --git a/arm9/src/main.c b/arm9/src/main.c index 58e2886..daa857f 100644 --- a/arm9/src/main.c +++ b/arm9/src/main.c @@ -12,7 +12,9 @@ static bool unlaunchFound = false; static bool hnaaUnlaunchFound = false; static bool retailLauncherTmdPresentAndToBePatched = true; static bool retailConsole = true; -static bool unlaunchInstallerFound = false; +static UNLAUNCH_VERSION foundUnlaunchInstallerVersion = false; +static bool disableAllPatches = false; +static bool enableSoundAndSplash = false; bool charging = false; u8 batteryLevel = 0; @@ -21,6 +23,8 @@ PrintConsole bottomScreen; enum { MAIN_MENU_SAFE_UNLAUNCH_UNINSTALL, + MAIN_MENU_TID_PATCHES, + MAIN_MENU_SOUND_SPLASH_PATCHES, MAIN_MENU_SAFE_UNLAUNCH_INSTALL, MAIN_MENU_EXIT }; @@ -65,10 +69,18 @@ static int mainMenu(int cursor) Menu* m = newMenu(); setMenuHeader(m, "MAIN MENU"); - char uninstallStr[32], installStr[32]; + char uninstallStr[32], installStr[32], soundPatchesStr[64], tidPatchesStr[32]; sprintf(uninstallStr, "\x1B[%02omUninstall unlaunch", unlaunchFound ? 047 : 037); - sprintf(installStr, "\x1B[%02omInstall unlaunch", unlaunchInstallerFound && !unlaunchFound ? 047 : 037); + sprintf(tidPatchesStr, "\x1B[%02omDisable all patches: %s", + (foundUnlaunchInstallerVersion == v1_9 && foundUnlaunchInstallerVersion == v2_0) ? 047 : 037, + disableAllPatches ? "On" : "Off"); + sprintf(soundPatchesStr, "\x1B[%02omEnable sound and splash: %s", + (foundUnlaunchInstallerVersion == v2_0 && !disableAllPatches) ? 047 : 037, + enableSoundAndSplash ? "On" : "Off"); + sprintf(installStr, "\x1B[%02omInstall unlaunch", (foundUnlaunchInstallerVersion != INVALID && !unlaunchFound) ? 047 : 037); addMenuItem(m, uninstallStr, NULL, 0); + addMenuItem(m, tidPatchesStr, NULL, 0); + addMenuItem(m, soundPatchesStr, NULL, 0); addMenuItem(m, installStr, NULL, 0); addMenuItem(m, "\x1B[47mExit", NULL, 0); @@ -139,8 +151,8 @@ int main(int argc, char **argv) return 0; } - unlaunchInstallerFound = loadUnlaunchInstaller("sd:/unlaunch.dsi"); - if (!unlaunchInstallerFound) + foundUnlaunchInstallerVersion = loadUnlaunchInstaller("sd:/unlaunch.dsi"); + if (foundUnlaunchInstallerVersion != INVALID) { messageBox("\x1B[41mWARNING:\x1B[47m unlaunch.dsi was not found in\n" "the root of the sd card.\n" @@ -215,13 +227,26 @@ int main(int argc, char **argv) nandio_lock_writing(); } break; + + case MAIN_MENU_TID_PATCHES: + if(foundUnlaunchInstallerVersion == v1_9 && foundUnlaunchInstallerVersion == v2_0) { + disableAllPatches = !disableAllPatches; + enableSoundAndSplash = true; + } + break; + + case MAIN_MENU_SOUND_SPLASH_PATCHES: + if(foundUnlaunchInstallerVersion == v2_0 && !disableAllPatches) { + enableSoundAndSplash = !enableSoundAndSplash; + } + break; case MAIN_MENU_SAFE_UNLAUNCH_INSTALL: - if (unlaunchInstallerFound && (choiceBox("Install unlaunch?") == YES) + if (foundUnlaunchInstallerVersion != INVALID && (choiceBox("Install unlaunch?") == YES) && (retailLauncherTmdPresentAndToBePatched || (choiceBox("There doesn't seem to be a launcher.tmd\nfile matcing the hwinfo file\nKeep installing?") == YES)) && nandio_unlock_writing()) { - if(installUnlaunch(retailConsole, retailLauncherTmdPresentAndToBePatched ? retailLauncherTmdPath : NULL)) + if(installUnlaunch(retailConsole, retailLauncherTmdPresentAndToBePatched ? retailLauncherTmdPath : NULL, disableAllPatches, enableSoundAndSplash)) { messageBox("Install successful!\n"); unlaunchFound = true; diff --git a/arm9/src/unlaunch.cpp b/arm9/src/unlaunch.cpp index 6c1e21c..ffca77b 100644 --- a/arm9/src/unlaunch.cpp +++ b/arm9/src/unlaunch.cpp @@ -13,13 +13,6 @@ static char unlaunchInstallerBuffer[0x30000]; static const char* hnaaTmdPath = "nand:/title/00030017/484e4141/content/title.tmd"; static const char* hnaaBackupTmdPath = "nand:/title/00030017/484e4141/content/title.tmd.bak"; -enum UNLAUNCH_VERSION { - v1_8, - v1_9, - v2_0, - INVALID, -}; - UNLAUNCH_VERSION installerVersion{INVALID}; size_t unlaunchInstallerSize{}; @@ -39,11 +32,16 @@ constexpr std::array knownUnlaunchHashes{ "15f4a36251d1408d71114019b2825fe8f5b4c8cc"_sha1, // v2.0 }; +constexpr std::array blockAllPatchesOffset{ + 0xae74, /* 1.9 */ + 0xae91, /* 2.0 */ +}; + static bool writeUnlaunchToHNAAFolder(); bool isValidUnlaunchInstallerSize(size_t size) { - return size == 163320 /*1.8*/ || size == 196088 /*1.9*/; + return size == 163320 /*1.8*/ || size == 196088 /*1.9, 2.0*/; } bool isLauncherTmdPatched(const char* path) @@ -351,7 +349,7 @@ static bool installUnlaunchProtoConsole(void) return true; } -bool readUnlaunchInstaller(const char* path) +static bool readUnlaunchInstaller(const char* path) { FILE* unlaunchInstaller = fopen(path, "rb"); if (!unlaunchInstaller) @@ -361,7 +359,7 @@ bool readUnlaunchInstaller(const char* path) } unlaunchInstallerSize = getFileSize(unlaunchInstaller); - if(isValidUnlaunchInstallerSize(unlaunchInstallerSize)) + if(!isValidUnlaunchInstallerSize(unlaunchInstallerSize)) { messageBox("\x1B[31mError:\x1B[33m Unlaunch installer wrong file size\n"); return false; @@ -389,7 +387,7 @@ bool readUnlaunchInstaller(const char* path) return true; } -bool verifyUnlaunchInstaller(void) +static bool verifyUnlaunchInstaller(void) { Sha1Digest digest; swiSHA1Calc(digest.data(), unlaunchInstallerBuffer + 520, unlaunchInstallerSize); @@ -404,20 +402,39 @@ bool verifyUnlaunchInstaller(void) return true; } -bool patchUnlaunchInstaller(void) +static bool patchUnlaunchInstaller(bool disableAllPatches, bool enableSoundAndSplash) { - //TODO: Apply patches + if(disableAllPatches) + { + if(installerVersion == v1_8) + { + messageBox("\x1B[31mError:\x1B[33m Unlaunch 1.8 can't be patched\n"); + return false; + } + // change launcher TID from ANH to SAN so that unlaunch doesn't realize it's booting the launcher + auto patchOffset = blockAllPatchesOffset[installerVersion - 1]; + const char newID[]{'S','A','N'}; + memcpy((unlaunchInstallerBuffer + 520) + patchOffset, newID, 3); + } + else if (enableSoundAndSplash) + { + + } return true; } -bool loadUnlaunchInstaller(const char* path) +UNLAUNCH_VERSION loadUnlaunchInstaller(const char* path) { - return readUnlaunchInstaller(path) && verifyUnlaunchInstaller(); + if(readUnlaunchInstaller(path) && verifyUnlaunchInstaller()) + { + return installerVersion; + } + return INVALID; } -bool installUnlaunch(bool retailConsole, const char* retailLauncherTmdPath) +bool installUnlaunch(bool retailConsole, const char* retailLauncherTmdPath, bool disableAllPatches, bool enableSoundAndSplash) { - if (installerVersion == INVALID || !patchUnlaunchInstaller()) + if (installerVersion == INVALID || !patchUnlaunchInstaller(disableAllPatches, enableSoundAndSplash)) return false; // Treat protos differently diff --git a/arm9/src/unlaunch.h b/arm9/src/unlaunch.h index e41eb84..1c7d53c 100644 --- a/arm9/src/unlaunch.h +++ b/arm9/src/unlaunch.h @@ -6,12 +6,19 @@ extern "C" { #endif +typedef enum UNLAUNCH_VERSION { + v1_8, + v1_9, + v2_0, + INVALID, +} UNLAUNCH_VERSION; + bool uninstallUnlaunch(bool notProto, bool hasHNAABackup, const char* retailLauncherTmdPath); -bool installUnlaunch(bool retailConsole, const char* retailLauncherTmdPath); +bool installUnlaunch(bool retailConsole, const char* retailLauncherTmdPath, bool disableAllPatches, bool enableSoundAndSplash); bool isLauncherTmdPatched(const char* path); -bool loadUnlaunchInstaller(const char* path); +UNLAUNCH_VERSION loadUnlaunchInstaller(const char* path); #ifdef __cplusplus }