/* NitroHax -- Cheat tool for the Nintendo DS Copyright (C) 2008 Michael "Chishm" Chisholm 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, either version 3 of the License, or (at your option) any later version. 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 for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "inifile.h" #include "bootsplash.h" #include "launch_engine.h" #include "crc.h" #include "tonccpy.h" #include "nitrofs.h" #include "nds_card.h" #include "debugConsole.h" #include "hbmenu.h" #include "launcherData.h" #include "read_card.h" #include "audio.h" #define FILECOPYBUFFER 0x02000000 ALIGN(4) struct { sNDSHeader header; char padding[0x200 - sizeof(sNDSHeader)]; } ndsHeader; static char gameTitle[13] = {0}; // static char gameCode[7] = {0}; static char gameCode[5] = {0}; static bool nitroFSMounted = false; // static ALIGN(4) sNDSHeaderExt ntrHeader; const char* PROGVERSION = "3.1"; off_t getFileSize(const char *fileName) { FILE* fp = fopen(fileName, "rb"); off_t fsize = 0; if (fp) { fseek(fp, 0, SEEK_END); fsize = ftell(fp); // Get source file's size fseek(fp, 0, SEEK_SET); } fclose(fp); return fsize; } extern void InitConsole(); extern void StartFileBrowser(tLauncherSettings launchdata); extern bool ConsoleInit; void DisplayText(const char* text, bool clear = false, bool noText = false){ if (!ConsoleInit)InitConsole(); if (clear)consoleClear(); printf("--------------------------------\n"); printf("----[NTR Launcher Debug Mode]---\n"); printf("----------[Version: 3.2]--------\n"); printf("--------------------------------\n\n"); if (!noText)printf(text); } void DoWait(int waitTime = 30){ for (int i = 0; i < waitTime; i++)swiWaitForVBlank(); }; bool MountNitroFS() { if (nitroFSMounted)return nitroFSMounted; nitroFSMounted = nitroFSInit("sd:/title/00030004/4b4b4750/content/00000000.app"); if (nitroFSMounted)return nitroFSMounted; nitroFSMounted = nitroFSInit("sd:/NTR_Launcher.nds"); if (nitroFSMounted)return nitroFSMounted; nitroFSMounted = nitroFSInit("sd:/nds/NTR_Launcher.nds"); if (nitroFSMounted)return nitroFSMounted; nitroFSMounted = nitroFSInit("sd:/homebrew/NTR_Launcher.nds"); return nitroFSMounted; } static void StartStage2Mode(tLauncherSettings Launchdata, bool nitro) { sysSetCardOwner (BUS_OWNER_ARM9); StartFileBrowser(Launchdata, nitro); } bool DoCardInit(bool DebugMode, bool fastBoot) { bool FastBoot = fastBoot; if (DebugMode){ DisplayText("CLR", true, true); DisplayText("Loading Cart details.\nPlease Wait...\n", true); } switch (REG_SCFG_MC) { case 0x10: { enableSlot1(); DoWait(15); FastBoot = false; }break; case 0x11: { enableSlot1(); DoWait(15); FastBoot = false; }break; } // Do cart init stuff to wake cart up. DLDI init may fail otherwise! /*if (FastBoot) { cardInitShort(&ntrHeader); tonccpy(gameTitle, ntrHeader.gameTitle, 12); tonccpy(gameCode, ntrHeader.gameCode, 4); } else {*/ CardReset(true); cardReadHeader((u8*)&ndsHeader); while(REG_ROMCTRL & CARD_BUSY); CardReset(false); tonccpy(gameTitle, ndsHeader.header.gameTitle, 12); tonccpy(gameCode, ndsHeader.header.gameCode, 4); /*cardInit((sNDSHeaderExt*)&ndsHeader.header); tonccpy(gameTitle, ndsHeader.header.gameTitle, 12); tonccpy(gameCode, ndsHeader.header.gameCode, 4); CardReset(false);*/ // } if (DebugMode) { DisplayText("CLR", true, true); iprintf("Detected Cart Name: %12s \n", gameTitle); iprintf("Detected Cart Game ID: %6s \n\n", gameCode); printf("Press any button to continue..."); while (keysDown()) { swiWaitForVBlank(); scanKeys(); } while (!keysDown()) { swiWaitForVBlank(); scanKeys(); } } else { DoWait(25); } return FastBoot; } bool DoSlotCheck(bool DebugMode) { bool slotReset = false; switch (REG_SCFG_MC) { case 0x11: { if(DebugMode) { DisplayText("Please insert a cartridge...\n", true); } else { if (!ConsoleInit)InitConsole(); consoleClear(); printf("\n\n\n\n\n\n\n\n\n\n\n Please insert a cartridge... "); } REDO: swiWaitForVBlank(); while (REG_SCFG_MC != 0x10)swiWaitForVBlank(); enableSlot1(); DoWait(60); if (REG_SCFG_MC != 0x18) goto REDO; slotReset = true; }break; case 0x10: { slotReset = true; enableSlot1(); }break; } return slotReset; } int main() { defaultExceptionHandler(); sysSetCardOwner(BUS_OWNER_ARM9); if (!isDSiMode()) { InitConsole(); printf("--------------------------------\n"); printf("----------[NTR Launcher]--------\n"); printf("----------[Version: 3.2]--------\n"); printf("--------------------------------\n\n"); printf("\nError has occured.!\nDSi Mode not detected.\nDS/DS Lite Unsupported!"); do { swiWaitForVBlank(); scanKeys(); } while (!keysDown()); return 0; } tLauncherSettings LaunchData = { 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFFFFFFFF }; // Create backup of Cart header (if present) saved by DSi System Menu. // It will not survive memory reallocation after dropping to NTR ram spec during bootloader. tonccpy ((u32*)CartHeaderCopy, (u32*)InitialCartHeader, 0x200); int language = -1; bool scfgunlock = true; bool twlmode = false; bool twlclk = false; bool twlram = false; bool twlvram = false; bool debugmode = false; // bool fastBoot = false; bool stage2Menu = false; bool autoBoot = true; bool useAnimatedSplash = false; bool useNTRSplash = true; bool healthAndSafety_MSG = true; bool fatInit = false; bool nitroInit = false; #ifndef _NoFATINIT fatInit = fatMountSimple("sd", get_io_dsisd()); if (fatInit) { if(access("sd:/NTR_Launcher", F_OK) != 0)mkdir("sd:/NTR_Launcher", 0777); nitroInit = MountNitroFS(); if ((access("sd:/NTR_Launcher/NTR_Launcher.ini", F_OK) != 0) && nitroInit) { FILE *src = fopen("nitro:/NTR_Launcher/NTR_Launcher.ini", "rb"); if (src) { FILE *dest = fopen("sd:/NTR_Launcher/NTR_Launcher.ini", "wb"); if (dest) { fseek(src, 0, SEEK_END); u32 fSize = ftell(src); fseek(src, 0, SEEK_SET); fread((void*)FILECOPYBUFFER, 1, fSize, src); fwrite((void*)FILECOPYBUFFER, fSize, 1, dest); fclose(src); fclose(dest); } } } if (access("sd:/NTR_Launcher/NTR_Launcher.ini", F_OK) == 0) { CIniFile ntrlauncher_config( "sd:/NTR_Launcher/NTR_Launcher.ini" ); twlclk = ntrlauncher_config.GetInt("NTRLAUNCHER","TWLCLOCK",0); twlvram = ntrlauncher_config.GetInt("NTRLAUNCHER","TWLVRAM",0); twlram = ntrlauncher_config.GetInt("NTRLAUNCHER","TWLRAM",0); twlmode = ntrlauncher_config.GetInt("NTRLAUNCHER","TWLMODE",0); scfgunlock = ntrlauncher_config.GetInt("NTRLAUNCHER","SCFGUNLOCK",0); useAnimatedSplash = ntrlauncher_config.GetInt("NTRLAUNCHER","ANIMATEDSPLASH",0); useNTRSplash = ntrlauncher_config.GetInt("NTRLAUNCHER","NTRSPLASH",0); healthAndSafety_MSG = ntrlauncher_config.GetInt("NTRLAUNCHER","HEALTHSAFETYSPLASH",0); autoBoot = ntrlauncher_config.GetInt("NTRLAUNCHER","AUTOBOOT",1); debugmode = ntrlauncher_config.GetInt("NTRLAUNCHER","DEBUGMODE",0); language = ntrlauncher_config.GetInt("NTRLAUNCHER", "LANGUAGE", -1); } } #endif scanKeys(); swiWaitForVBlank(); /*scfgunlock = true; twlmode = true; twlclk = true; twlram = true; twlvram = true; debugmode = true;*/ if (scfgunlock)LaunchData.scfgUnlock = 0x01; if (twlmode)LaunchData.twlMode = 0x01; if (twlclk)LaunchData.twlCLK = 0x01; if (twlvram)LaunchData.twlVRAM = 0x01; if (twlram)LaunchData.twlRAM = 0x01; if (!autoBoot)stage2Menu = true; // if (fastBoot)LaunchData.fastBoot = 0x01; if ((keysDown() & KEY_B) && fatInit) { if (stage2Menu) { stage2Menu = false; } else { stage2Menu = true; } } if (REG_SCFG_MC == 0x11)stage2Menu = true; if ((REG_SCFG_MC == 0x10) && !stage2Menu) { sysSetCardOwner (BUS_OWNER_ARM9); DoCardInit(false, false); } if (!fatInit)stage2Menu = false; if (!stage2Menu) { if ((keysHeld() & KEY_L) && (keysHeld() & KEY_R)) { debugmode = true; } else if (keysDown() & KEY_L) { twlclk = false; twlvram = false; scfgunlock = false; twlmode = false; } else if (keysDown() & KEY_R) { twlclk = true; twlvram = true; scfgunlock = true; twlmode = true; } } ConsoleInit = debugmode; if (stage2Menu) { ConsoleInit = false; debugmode = false; } if (debugmode)useAnimatedSplash = false; if (useAnimatedSplash || stage2Menu)InitAudio(); if (!useAnimatedSplash) { if (debugmode)InitConsole(); // fastBoot = !DoSlotCheck(debugmode); if (!stage2Menu)DoSlotCheck(debugmode); } else { char *p = (char*)PersonalData->name; for (int i = 0; i < 10; i++) { if (p[i*2] == 0x00) { p[i*2/2] = 0; } else { p[i*2/2] = p[i*2]; } } if (language == -1)language = PersonalData->language; BootSplashInit(useNTRSplash, healthAndSafety_MSG, (int)language, false); } if (language != -1)LaunchData.language = (u8)language; if (scfgunlock)LaunchData.scfgUnlock = 0x01; if (twlmode)LaunchData.twlMode = 0x01; if (twlclk)LaunchData.twlCLK = 0x01; if (twlvram)LaunchData.twlVRAM = 0x01; if (debugmode)LaunchData.debugMode = 0x01; /*if (fastBoot) { LaunchData.fastBoot = 0x01; } else { LaunchData.fastBoot = 0x00; }*/ if ((stage2Menu || (REG_SCFG_MC == 0x11)) && fatInit) { StartStage2Mode(LaunchData, nitroInit); } else { // DoCardInit(debugmode, fastBoot); DoCardInit(debugmode, false); // DS-Xtreme does not like running in TWL clock speeds. // (write function likely goes too fast and semi-bricks hidden sector region randomly when using official launcher) if (!memcmp(gameTitle, "D!S!XTREME", 9)) { LaunchData.scfgUnlock = 0x00; LaunchData.twlCLK = 0x00; LaunchData.twlVRAM = 0x00; LaunchData.twlMode = 0x00; if (!useAnimatedSplash)SimpleSplashInit(); // cardInit(&ntrHeader); } else { if (ndsHeader.header.unitCode & BIT(1))LaunchData.isTWLSRL = 0x01; } while(1) { // If SCFG_MC is returning as zero/null, this means SCFG_EXT registers are locked on arm9 or user attempted to run this while in NTR mode. if((REG_SCFG_MC == 0x00) || (REG_SCFG_MC == 0x11) || (REG_SCFG_MC == 0x10)) { if (useAnimatedSplash) { BootSplashInit(false, false, 0, true); } else { DisplayText("Error has occured.!\nEither card ejected late,\nor NTR mode detected!\nPress any button to exit...", true); do { swiWaitForVBlank(); scanKeys(); } while (!keysDown()); } break; } else { LaunchData.cachedChipID = *(u32*)InitialCartChipID; runLaunchEngine(LaunchData); break; } swiWaitForVBlank(); } } return 0; }