mirror of
https://github.com/rvtr/unlaunch-installer_dev.git
synced 2026-01-26 13:43:08 -05:00
Add key combo to uninstall unlaunch alongside the hnaa failsafe
This commit is contained in:
parent
027308e1f5
commit
593141e702
@ -22,6 +22,7 @@ static const char* splashSoundBinaryPatchPath = NULL;
|
||||
static const char* customBgPath = NULL;
|
||||
volatile bool charging = false;
|
||||
volatile u8 batteryLevel = 0;
|
||||
static bool wantsUnsafeUnlaunchUninstall = false;
|
||||
|
||||
PrintConsole topScreen;
|
||||
PrintConsole bottomScreen;
|
||||
@ -32,7 +33,8 @@ enum {
|
||||
MAIN_MENU_TID_PATCHES,
|
||||
MAIN_MENU_SOUND_SPLASH_PATCHES,
|
||||
MAIN_MENU_SAFE_UNLAUNCH_INSTALL,
|
||||
MAIN_MENU_EXIT
|
||||
MAIN_MENU_EXIT,
|
||||
MAIN_MENU_SAFE_UNLAUNCH_UNINSTALL_NO_BACKUP,
|
||||
};
|
||||
|
||||
static void setupScreens()
|
||||
@ -92,12 +94,17 @@ static int mainMenu(int cursor)
|
||||
addMenuItem(m, soundPatchesStr, NULL, foundUnlaunchInstallerVersion == v2_0 && !disableAllPatches && splashSoundBinaryPatchPath != NULL, false);
|
||||
addMenuItem(m, installUnlaunchStr, NULL, foundUnlaunchInstallerVersion != INVALID && !unlaunchFound, false);
|
||||
addMenuItem(m, "Exit", NULL, true, false);
|
||||
if(wantsUnsafeUnlaunchUninstall)
|
||||
addMenuItem(m, "Uninstall unlaunch no backup", NULL, unlaunchFound, false);
|
||||
|
||||
m->cursor = cursor;
|
||||
|
||||
//bottom screen
|
||||
printMenu(m);
|
||||
|
||||
int konamiCode = 0;
|
||||
bool konamiCodeCooldown = false;
|
||||
|
||||
while (!programEnd)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
@ -108,6 +115,29 @@ static int mainMenu(int cursor)
|
||||
|
||||
if (keysDown() & KEY_A)
|
||||
break;
|
||||
|
||||
if(wantsUnsafeUnlaunchUninstall)
|
||||
continue;
|
||||
|
||||
int held = keysHeld();
|
||||
|
||||
if ((held & (KEY_L | KEY_R | KEY_Y)) == (KEY_L | KEY_R | KEY_Y))
|
||||
{
|
||||
if(held == (KEY_L | KEY_R | KEY_Y) && !konamiCodeCooldown)
|
||||
{
|
||||
konamiCodeCooldown = true;
|
||||
++konamiCode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
konamiCodeCooldown = false;
|
||||
}
|
||||
if (konamiCode == 5)
|
||||
{
|
||||
wantsUnsafeUnlaunchUninstall = true;
|
||||
addMenuItem(m, "Uninstall unlaunch no backup", NULL, unlaunchFound, false);
|
||||
}
|
||||
}
|
||||
|
||||
int result = m->cursor;
|
||||
@ -158,22 +188,22 @@ int main(int argc, char **argv)
|
||||
messageBox("nand init \x1B[31mfailed\n\x1B[47m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
while (batteryLevel < 7 && !charging)
|
||||
{
|
||||
if (choiceBox("\x1B[47mBattery is too low!\nPlease plug in the console.\n\nContinue?") == NO)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DeviceList* deviceList = getDeviceList();
|
||||
|
||||
|
||||
const char* installerPath = (argc > 0) ? argv[0] : (deviceList ? deviceList->appname : "sd:/ntrboot.nds");
|
||||
|
||||
|
||||
if (!nitroFSInit(installerPath))
|
||||
{
|
||||
messageBox("nitroFSInit()...\x1B[31mFailed\n\x1B[47m");
|
||||
}
|
||||
|
||||
|
||||
if (fileExists("sd:/unlaunch.dsi"))
|
||||
{
|
||||
foundUnlaunchInstallerVersion = loadUnlaunchInstaller("sd:/unlaunch.dsi");
|
||||
@ -184,7 +214,7 @@ int main(int argc, char **argv)
|
||||
"Attempting to use the bundled one.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(foundUnlaunchInstallerVersion == INVALID)
|
||||
{
|
||||
foundUnlaunchInstallerVersion = loadUnlaunchInstaller("nitro:/unlaunch.dsi");
|
||||
@ -195,7 +225,7 @@ int main(int argc, char **argv)
|
||||
"Installing unlaunch won't be possible.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(fileExists("nitro:/unlaunch-patch.bin"))
|
||||
{
|
||||
splashSoundBinaryPatchPath = "nitro:/unlaunch-patch.bin";
|
||||
@ -236,11 +266,11 @@ int main(int argc, char **argv)
|
||||
}
|
||||
// HWINFO_S may not always exist (PRE_IMPORT). Fill in defaults if that happens.
|
||||
}
|
||||
|
||||
|
||||
// I own and know of many people with retail and dev prototypes
|
||||
// These can normally be identified by having the region set to ALL (0x41)
|
||||
retailConsole = (region != 0x41 && region != 0xFF);
|
||||
|
||||
|
||||
unsigned long long tmdSize = getFileSizePath(hnaaTmdPath);
|
||||
if (tmdSize > 520)
|
||||
{
|
||||
@ -260,8 +290,10 @@ int main(int argc, char **argv)
|
||||
switch (cursor)
|
||||
{
|
||||
case MAIN_MENU_SAFE_UNLAUNCH_UNINSTALL:
|
||||
case MAIN_MENU_SAFE_UNLAUNCH_UNINSTALL_NO_BACKUP:
|
||||
if(unlaunchFound && nandio_unlock_writing()) {
|
||||
if(uninstallUnlaunch(retailConsole, hnaaUnlaunchFound, retailLauncherTmdPath))
|
||||
bool unsafeUninstall = wantsUnsafeUnlaunchUninstall && cursor == MAIN_MENU_SAFE_UNLAUNCH_UNINSTALL_NO_BACKUP;
|
||||
if(uninstallUnlaunch(retailConsole, hnaaUnlaunchFound, retailLauncherTmdPath, unsafeUninstall))
|
||||
{
|
||||
messageBox("Uninstall successful!\n");
|
||||
unlaunchFound = false;
|
||||
@ -273,7 +305,7 @@ int main(int argc, char **argv)
|
||||
nandio_synchronize_fats();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case MAIN_MENU_CUSTOM_BG:
|
||||
if(foundUnlaunchInstallerVersion != INVALID) {
|
||||
const char* customBg = backgroundMenu();
|
||||
@ -289,13 +321,13 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case MAIN_MENU_TID_PATCHES:
|
||||
if(foundUnlaunchInstallerVersion == v1_9 || foundUnlaunchInstallerVersion == v2_0) {
|
||||
disableAllPatches = !disableAllPatches;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case MAIN_MENU_SOUND_SPLASH_PATCHES:
|
||||
if(foundUnlaunchInstallerVersion == v2_0 && !disableAllPatches && splashSoundBinaryPatchPath != NULL) {
|
||||
enableSoundAndSplash = !enableSoundAndSplash;
|
||||
|
||||
@ -65,7 +65,7 @@ bool isLauncherTmdPatched(const char* path)
|
||||
return c == 0x47;
|
||||
}
|
||||
|
||||
static bool restoreMainTmd(const char* path, bool hasHNAABackup)
|
||||
static bool restoreMainTmd(const char* path, bool hasHNAABackup, bool removeHNAABackup)
|
||||
{
|
||||
FILE* launcherTmd = fopen(path, "r+b");
|
||||
if(!launcherTmd)
|
||||
@ -83,6 +83,20 @@ static bool restoreMainTmd(const char* path, bool hasHNAABackup)
|
||||
fseek(launcherTmd, -1, SEEK_CUR);
|
||||
c = 0x48;
|
||||
fwrite(&c, 1, 1, launcherTmd);
|
||||
fclose(launcherTmd);
|
||||
if(removeHNAABackup && hasHNAABackup)
|
||||
{
|
||||
if(!toggleFileReadOnly(hnaaTmdPath, false))
|
||||
{
|
||||
messageBox("\x1B[31mError:\x1B[33m Failed to mark unlaunch's title.tmd as writable\nLeaving as is\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
remove(hnaaTmdPath);
|
||||
rmdir("nand:/title/00030017/484e4141/content");
|
||||
rmdir("nand:/title/00030017/484e4141");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(c != 0x47)
|
||||
{
|
||||
@ -93,7 +107,7 @@ static bool restoreMainTmd(const char* path, bool hasHNAABackup)
|
||||
// This is also a good idea to make sure the tmd is 520b.
|
||||
// You will have a much higher brick risk if something goes wrong with a tmd over 520b.
|
||||
// See: http://docs.randommeaninglesscharacters.com/unlaunch.html
|
||||
if(!hasHNAABackup)
|
||||
if(!hasHNAABackup && !removeHNAABackup)
|
||||
{
|
||||
auto choiceString = [&]{
|
||||
if(installerVersion != INVALID)
|
||||
@ -129,6 +143,19 @@ static bool restoreMainTmd(const char* path, bool hasHNAABackup)
|
||||
}
|
||||
}
|
||||
}
|
||||
if(removeHNAABackup && hasHNAABackup)
|
||||
{
|
||||
if(!toggleFileReadOnly(hnaaTmdPath, false))
|
||||
{
|
||||
messageBox("\x1B[31mError:\x1B[33m Failed to mark unlaunch's title.tmd as writable\nLeaving as is\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
remove(hnaaTmdPath);
|
||||
rmdir("nand:/title/00030017/484e4141/content");
|
||||
rmdir("nand:/title/00030017/484e4141");
|
||||
}
|
||||
}
|
||||
if (ftruncate(fileno(launcherTmd), 520) != 0) {
|
||||
messageBox("\x1B[31mError:\x1B[33m Failed to remove unlaunch\n");
|
||||
fclose(launcherTmd);
|
||||
@ -141,7 +168,6 @@ static bool restoreMainTmd(const char* path, bool hasHNAABackup)
|
||||
fclose(launcherTmd);
|
||||
return false;
|
||||
}
|
||||
fclose(launcherTmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -188,7 +214,7 @@ static bool restoreProtoTmd(const char* path)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uninstallUnlaunch(bool retailConsole, bool hasHNAABackup, const char* retailLauncherTmdPath)
|
||||
bool uninstallUnlaunch(bool retailConsole, bool hasHNAABackup, const char* retailLauncherTmdPath, bool removeHNAABackup)
|
||||
{
|
||||
// TODO: handle retailLauncherTmdPresentAndToBePatched = false on retail consoles
|
||||
if (retailConsole) {
|
||||
@ -196,7 +222,7 @@ bool uninstallUnlaunch(bool retailConsole, bool hasHNAABackup, const char* retai
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!restoreMainTmd(retailLauncherTmdPath, hasHNAABackup))
|
||||
if (!restoreMainTmd(retailLauncherTmdPath, hasHNAABackup, removeHNAABackup))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ typedef enum UNLAUNCH_VERSION {
|
||||
|
||||
const char* getUnlaunchVersionString(UNLAUNCH_VERSION);
|
||||
|
||||
bool uninstallUnlaunch(bool notProto, bool hasHNAABackup, const char* retailLauncherTmdPath);
|
||||
bool uninstallUnlaunch(bool notProto, bool hasHNAABackup, const char* retailLauncherTmdPath, bool removeHNAABackup);
|
||||
bool installUnlaunch(bool retailConsole, const char* retailLauncherTmdPath, bool disableAllPatches, const char* splashSoundBinaryPatchPath, const char* customBackgroundPath);
|
||||
|
||||
bool isLauncherTmdPatched(const char* path);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user