/* 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 "cheat.h" #include "ui.h" #include "nds_card.h" #include "cheat_engine.h" #include "crc.h" #include "version.h" #include "read_card.h" const char TITLE_STRING[] = "Nitro Hax " VERSION_STRING "\nWritten by Chishm"; const char* defaultFiles[] = { "cheats.xml", "/DS/NitroHax/cheats.xml", "/NitroHax/cheats.xml", "/NDS/NitroHax/cheats.xml", "/data/NitroHax/cheats.xml", "/_nds/NitroHax/cheats.xml", "/cheats.xml"}; static bool ROMisDSiExclusive(const tNDSHeader* ndsHeader) { return (ndsHeader->unitCode == 0x03); } static bool ROMisDSiEnhanced(const tNDSHeader* ndsHeader) { return (ndsHeader->unitCode == 0x02); } static inline void ensure (bool condition, const char* errorMsg) { if (!condition) { ui.showMessage (errorMsg); while(1)swiWaitForVBlank(); } return; } void DoWait(int waitTime = 30){ for (int i = 0; i < waitTime; i++) swiWaitForVBlank(); }; void ResetSlot1() { if (REG_SCFG_MC == 0x11) return; disableSlot1(); DoWait(); enableSlot1(); } void DoCartCheck() { if (REG_SCFG_MC == 0x11) { do { swiWaitForVBlank(); } while (REG_SCFG_MC != 0x10); enableSlot1(); DoWait(60); } } //--------------------------------------------------------------------------------- int main(int argc, const char* argv[]) { (void)argc; (void)argv; u32 ndsHeader[0x80]; u32* cheatDest; int curCheat = 0; char gameid[4]; uint32_t headerCRC; std::string filename; int c; FILE* cheatFile; bool isTWLCart = false; ui.showMessage (UserInterface::TEXT_TITLE, TITLE_STRING); #ifdef DEMO ui.demo(); while(1); #endif ensure (fatInitDefault(), "FAT init failed"); // Read cheat file for (const char* FileName : defaultFiles) { cheatFile = fopen(FileName, "rb"); if (cheatFile)break; } if (!cheatFile) { filename = ui.fileBrowser (".xml"); ensure (filename.size() > 0, "No file specified"); cheatFile = fopen (filename.c_str(), "rb"); ensure (cheatFile, "Couldn't load cheats"); } ui.showMessage (UserInterface::TEXT_TITLE, TITLE_STRING); ui.showMessage ("Loading codes"); c = fgetc(cheatFile); ensure (c != 0xFF && c != 0xFE, "File is in an unsupported unicode encoding"); fseek (cheatFile, 0, SEEK_SET); CheatCodelist* codelist = new CheatCodelist(); ensure (codelist->load(cheatFile), "Can't read cheat list\n"); fclose (cheatFile); ui.showMessage (UserInterface::TEXT_TITLE, TITLE_STRING); sysSetCardOwner (BUS_OWNER_ARM9); // Check if on DSi with unlocked SCFG, if not, then assume standard NTR precedure. if ((REG_SCFG_EXT & BIT(31))) { ui.showMessage ("Loaded codes\nChecking if a cart is inserted"); if (REG_SCFG_MC != 0x18)ui.showMessage ("Insert Game"); while (REG_SCFG_MC != 0x18)DoCartCheck(); CardInit(); } else { ui.showMessage ("Loaded codes\nYou can remove your flash card\nRemove DS Card"); do { swiWaitForVBlank(); getHeader (ndsHeader); } while (ndsHeader[0] != 0xffffffff); ui.showMessage ("Insert Game"); do { swiWaitForVBlank(); getHeader (ndsHeader); } while (ndsHeader[0] == 0xffffffff); } // Delay half a second for the DS card to stabilise DoWait(); getHeader (ndsHeader); ui.showMessage ("Finding game"); memcpy (gameid, ((const char*)ndsHeader) + 12, 4); headerCRC = crc32((const char*)ndsHeader, sizeof(ndsHeader)); CheatFolder *gameCodes = codelist->getGame (gameid, headerCRC); if (!gameCodes)gameCodes = codelist; ensure(!ROMisDSiExclusive((const tNDSHeader*)ndsHeader), "TWL exclusive games are not supported!"); isTWLCart = ROMisDSiEnhanced((const tNDSHeader*)ndsHeader); ui.cheatMenu (gameCodes, gameCodes); cheatDest = (u32*) malloc(CHEAT_MAX_DATA_SIZE); ensure (cheatDest != NULL, "Bad malloc\n"); std::list cheatList = gameCodes->getEnabledCodeData(); for (std::list::iterator cheat = cheatList.begin(); cheat != cheatList.end(); cheat++) { cheatDest[curCheat++] = (*cheat); } ui.showMessage (UserInterface::TEXT_TITLE, TITLE_STRING); ui.showMessage ("Running game"); runCheatEngine (cheatDest, curCheat * sizeof(u32), isTWLCart); while(1)swiWaitForVBlank(); return 0; }