u32 ProcessEntry(MenuEntry* entry) { u32 pad_state; u32 res = 0; // unlock sequence for dangerous features if (entry->dangerous) { u32 unlockSequenceEmu[] = { BUTTON_LEFT, BUTTON_RIGHT, BUTTON_DOWN, BUTTON_UP, BUTTON_A }; u32 unlockSequenceSys[] = { BUTTON_LEFT, BUTTON_UP, BUTTON_RIGHT, BUTTON_UP, BUTTON_A }; u32 unlockLvlMax = 5; u32* unlockSequence = (entry->emunand) ? unlockSequenceEmu : unlockSequenceSys; u32 unlockLvl = 0; DebugClear(); Debug("You selected \"%s\".", entry->name); Debug("This feature writes to the %s.", (entry->emunand) ? "EmuNAND" : "SysNAND"); Debug("Doing this is potentially dangerous!"); Debug(""); Debug("If you wish to proceed, enter:"); Debug((entry->emunand) ? "<Left>, <Right>, <Down>, <Up>, <A>" : "<Left>, <Up>, <Right>, <Up>, <A>"); Debug(""); Debug("(B to return, START to reboot)"); while (true) { ShowProgress(unlockLvl, unlockLvlMax); if (unlockLvl == unlockLvlMax) break; pad_state = InputWait(); if (!(pad_state & BUTTON_ANY)) continue; else if (pad_state & unlockSequence[unlockLvl]) unlockLvl++; else if (pad_state & (BUTTON_B | BUTTON_START)) break; else if (unlockLvl == 0 || !(pad_state & unlockSequence[unlockLvl-1])) unlockLvl = 0; } ShowProgress(0, 0); if (unlockLvl < unlockLvlMax) return pad_state; } // execute this entries function DebugClear(); res = (SetNand(entry->emunand) == 0) ? (*(entry->function))(entry->param) : 1; Debug("%s: %s!", entry->name, (res == 0) ? "succeeded" : "failed"); Debug(""); Debug("Press B to return, START to reboot."); while(!(pad_state = InputWait() & (BUTTON_B | BUTTON_START))); // returns the last known pad_state return pad_state; }
static _Noreturn void mainLoop() { uint32_t pad; while (true) { pad = InputWait(); if (pad & (BUTTON_DOWN | BUTTON_RIGHT | BUTTON_R1)) MenuNextSelection(); if (pad & (BUTTON_UP | BUTTON_LEFT | BUTTON_L1)) MenuPrevSelection(); if (pad & BUTTON_A) { OpenAnimation(); MenuSelect(); } if (pad & BUTTON_SELECT) { fadeOut(); ShutDown(); } MenuShow(); } }
uint_fast8_t progressSetPos(uintmax_t pos) { statusDrawStart(); uint32_t timeleft = 0; if ((pos += progress_offset) >= progress_posmax) { pos = progress_posmax; timerStop(); wcscpy(status_value, lang(S_COMPLETED)); status_features |= STATUS_FINISHED; } if (pos != progress_pos || !pos) { if ((progress_pos = pos) && pos) { timeleft = timerGet(); timeleft = progress_posmax * timeleft / progress_pos - timeleft; } DrawProgress(progress_screen, &progress_rect, progress_frame, progress_done, progress_back, progress_textcolor, progress_fontsize, progress_posmax, progress_pos, timeleft); } if (pos != progress_posmax && status_features & STATUS_CANCELABLE && GetInput() & keys[KEY_B].mask) { wcscpy(status_value, lang(S_CANCELED)); status_features |= STATUS_WAIT | STATUS_FINISHED | STATUS_FAILED; } if (status_features & STATUS_FINISHED) { wcscat(status_value, L" "); swprintf(status_value + wcslen(status_value), _MAX_LFN + 1, lang(SF2_PRESS_BUTTON_ACTION), lang(S_ANY_BUTTON), lang(S_CONTINUE)); } DrawStringRect(&bottomScreen, status_value, &style.activityStatusRect, style.activityColor, style.activityStatusAlign, 16); statusDrawFinish(); if (status_features & STATUS_WAIT && status_features & STATUS_FINISHED) InputWait(); return !(status_features & STATUS_FAILED); }
static _Noreturn void mainLoop() { uint32_t pad; while (true) { drawBottom(); pad = InputWait(); if (pad & BUTTON_A) rxMode(1); //EMUNAND if (pad & BUTTON_X) rxMode(0); //SYSNAND if (pad & BUTTON_Y) PastaMode(); //PASTAMODE if (pad & BUTTON_B) ShutDown(1); //SHUTDOWN if (pad & BUTTON_LEFT) { if(cfgs[CFG_DEFAULT].val.i == 0) cfgs[CFG_DEFAULT].val.i = 3; else cfgs[CFG_DEFAULT].val.i--; writeCfg(); } if(pad & BUTTON_RIGHT) { if(cfgs[CFG_DEFAULT].val.i == 3) cfgs[CFG_DEFAULT].val.i = 0; else cfgs[CFG_DEFAULT].val.i++; writeCfg(); } } }
void InstallConfigData(){ if(CheckInstallationData() == 0) { first_boot = false; return; } first_boot = true; trySetLangFromTheme(); writeCfg(); sprintf(str, "/rxTools/Theme/%u/cfg0TOP.bin", cfgs[CFG_THEME].val.i); DrawTopSplash(str, str, str); sprintf(str, "/rxTools/Theme/%u/cfg0.bin", cfgs[CFG_THEME].val.i); DrawBottomSplash(str); int res = InstallData("0"); //SD Card sprintf(str, "/rxTools/Theme/%u/cfg1%c.bin", cfgs[CFG_THEME].val.i, res == 0 ? 'O' : 'E'); DrawBottomSplash(str); sprintf(str, "/rxTools/Theme/%u/TOP.bin", cfgs[CFG_THEME].val.i); sprintf(strl, "/rxTools/Theme/%u/TOPL.bin", cfgs[CFG_THEME].val.i); sprintf(strr, "/rxTools/Theme/%u/TOPR.bin", cfgs[CFG_THEME].val.i); DrawTopSplash(str, strl, strr); InputWait(); }
void WaitForButton(u32 button){ while (true) { TryScreenShot(); //Maybe someone wanna take screenshots while waiting u32 pad_state = InputWait(); if (pad_state & button) return; } }
void WaitForButton(uint32_t button){ while (true) { bgWork(); uint32_t pad_state = InputWait(); if (pad_state & button) return; } }
u32 InitializeD9() { u32 errorlevel = 0; // 0 -> none, 1 -> autopause, 2 -> critical ClearScreenFull(true, true); DebugClear(); #ifndef BUILD_NAME Debug("-- Decrypt9 --"); #else Debug("-- %s --", BUILD_NAME); #endif // a little bit of information about the current menu if (sizeof(menu)) { u32 n_submenus = 0; u32 n_features = 0; for (u32 m = 0; menu[m].n_entries; m++) { n_submenus = m; for (u32 e = 0; e < menu[m].n_entries; e++) n_features += (menu[m].entries[e].function) ? 1 : 0; } Debug("Counting %u submenus and %u features", n_submenus, n_features); } Debug("Initializing, hold L+R to pause"); Debug(""); if (InitFS()) { Debug("Initializing SD card... success"); FileGetData("d9logo.bin", BOT_SCREEN0, 320 * 240 * 3, 0); memcpy(BOT_SCREEN1, BOT_SCREEN0, 320 * 240 * 3); if (SetupTwlKey0x03() != 0) // TWL KeyX / KeyY errorlevel = 2; if ((GetUnitPlatform() == PLATFORM_N3DS) && (LoadKeyFromFile(0x05, 'Y', NULL) != 0)) errorlevel = (((*(vu32*) 0x101401C0) == 0) || (errorlevel > 1)) ? 2 : 1; // N3DS CTRNAND KeyY if (LoadKeyFromFile(0x25, 'X', NULL)) // NCCH 7x KeyX errorlevel = (errorlevel < 1) ? 1 : errorlevel; if (LoadKeyFromFile(0x18, 'X', NULL)) // NCCH Secure3 KeyX errorlevel = (errorlevel < 1) ? 1 : errorlevel; if (LoadKeyFromFile(0x1B, 'X', NULL)) // NCCH Secure4 KeyX errorlevel = (errorlevel < 1) ? 1 : errorlevel; Debug("Finalizing Initialization..."); RemainingStorageSpace(); } else { Debug("Initializing SD card... failed"); errorlevel = 2; } Debug(""); Debug("Initialization: %s", (errorlevel == 0) ? "success!" : (errorlevel == 1) ? "partially failed" : "failed!"); if (((~HID_STATE & BUTTON_L1) && (~HID_STATE & BUTTON_R1)) || (errorlevel > 1)) { Debug("(A to %s)", (errorlevel > 1) ? "exit" : "continue"); while (!(InputWait() & BUTTON_A)); } return errorlevel; }
u32 ScrollOutput() { u32 log_start = LogWrite(NULL); // careful, these areas are used by other functions in Decrypt9 char** logptr = (char**) 0x20316000; char* logtext = (char*) 0x20400000; u32 log_size = 0; // log size u32 l_total = 0; // total lines u32 l_curr = 0; // current line if (!FileOpen(LOG_FILE)) return 0; log_size = FileGetSize(); if ((log_size <= log_start) || (log_size - log_start >= 1024 * 1024)) { FileClose(); return 0; // allow 1MB of text max } log_size -= log_start; if (!FileRead(logtext, log_size, log_start)) { FileClose(); return 0; } FileClose(); // read lines logtext[log_size - 1] = '\0'; logptr[l_total++] = logtext; for (char* line = strchr(logtext, '\n'); line != NULL && l_total < 4000; line = strchr(line, '\n')) { *line = '\0'; logptr[l_total++] = ++line; } if (l_total >= 4000) // allow 4000 lines of text max return 0; for (; l_total < DBG_N_CHARS_Y; logptr[l_total++] = logtext + log_size - 1); // here, the actual output starts l_curr = l_total - DBG_N_CHARS_Y ; if (l_curr > 0) l_curr--; // start at the line before the last while (true) { DebugSet((const char**) logptr + l_curr); u32 pad_state = InputWait(); if (pad_state & BUTTON_X) { Screenshot(NULL); } else if ((pad_state & BUTTON_UP) && (l_curr > 0)) { l_curr--; } else if ((pad_state & BUTTON_DOWN) && (l_curr < l_total - DBG_N_CHARS_Y)) { l_curr++; } else if (pad_state & (BUTTON_B | BUTTON_START)) { return pad_state; } } return 0; }
void AdvFileManagerMain(){ panel_t Panels[2]; int currentPanel = 0; //Reset both panels for (i = 0; i < 2; i++) { Panels[i].pointer = 0; Panels[i].beginning = 0; Panels[i].openedFolder = 0; Panels[i].enabled = 0; wcscpy(Panels[i].dir, L""); Panels[i].count = AdvFileManagerList(Panels[i].dir, &Panels[i].files); } Panels[0].enabled = 1; while (true) { //Background wchar_t str[_MAX_LFN]; swprintf(str, _MAX_LFN, L"/rxTools/Theme/%u/FM.bin", cfgs[CFG_THEME].val.i); DrawSplash(screentmp, str); AdvFileManagerShow(&Panels[0], 0); AdvFileManagerShow(&Panels[1], 155); memcpy(BOT_SCREEN, screentmp, SCREEN_SIZE); //Trick to avoid screen flickering uint32_t pad_state = InputWait(); if (pad_state & BUTTON_DOWN) AdvFileManagerNextSelection(&Panels[currentPanel]); else if (pad_state & BUTTON_UP) AdvFileManagerPrevSelection(&Panels[currentPanel]); else if (pad_state & BUTTON_A) AdvFileManagerSelect(&Panels[currentPanel]); else if (pad_state & BUTTON_B) { if (Panels[currentPanel].openedFolder == 0) break; else AdvFileManagerBack(&Panels[currentPanel]); } else if (pad_state & BUTTON_LEFT) currentPanel = 0; else if (pad_state & BUTTON_RIGHT)currentPanel = 1; //Change page if (Panels[currentPanel].pointer - Panels[currentPanel].beginning == 10)Panels[currentPanel].beginning += 10; if (Panels[currentPanel].pointer<Panels[currentPanel].beginning)Panels[currentPanel].beginning -= 10; //Set who's enabled if (!currentPanel) { Panels[0].enabled = 1; Panels[1].enabled = 0; } else { Panels[0].enabled = 0; Panels[1].enabled = 1; } } }
int NandSwitch(){ ConsoleInit(); ConsoleAddText("Choose the NAND you want to use\n"); ConsoleAddText("Press X : SysNAND"); ConsoleAddText("Press Y : EmuNAND"); ConsoleAddText("Press B : Back"); ConsoleShow(); while (true) { u32 pad_state = InputWait(); if(pad_state & BUTTON_X) return 0; if(pad_state & BUTTON_Y) return 1; if(pad_state & BUTTON_B) return -1; } }
void NandMenu(){ f_mkdir ("nand"); MenuInit(&NandOptions); MenuShow(); while (true) { u32 pad_state = InputWait(); if(pad_state & BUTTON_DOWN) MenuNextSelection(); if(pad_state & BUTTON_UP) MenuPrevSelection(); if(pad_state & BUTTON_A) MenuSelect(); if(pad_state & BUTTON_B) break; TryScreenShot(); MenuShow(); } }
void AdvFileManagerFileAction(TCHAR filePath[], TCHAR fileName[]) { int actions_idx = 0; while (true) { //DRAW GUI ConsoleInit(); ConsoleSetTitle(fileName); wchar_t* beg; for (i = 0; i < FILE_ACTIONS; i++) { if (i == actions_idx) beg = strings[STR_CURSOR]; else beg = strings[STR_NO_CURSOR]; if (i == 0)print(L"%ls Launch as firm\n", beg); if (i == 1)print(L"%ls Something...\n", beg); } ConsoleShow(); //APP CONTROLS uint32_t pad_state = InputWait(); if (pad_state & BUTTON_DOWN) { if (actions_idx != FILE_ACTIONS - 1) actions_idx++; //MOVE DOWN else actions_idx = 0; //MOVE DOWN While at bottom -> go to top } else if (pad_state & BUTTON_UP) { if (actions_idx != 0) actions_idx--; //MOVE UP else actions_idx = FILE_ACTIONS - 1; //MOVE UP While at top -> go to bottom } else if (pad_state & BUTTON_A) { switch(actions_idx) { case 0: FirmLoader(filePath); break; case 1: //Something.... break; } break; } else if (pad_state & BUTTON_B) break; } }
int NandSwitch(){ if(!checkEmuNAND()) return 0; //If No EmuNAND, we force to work on SysNAND ConsoleInit(); print(strings[STR_CHOOSE], strings[STR_NAND]); print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_X], strings[STR_SYSNAND]); print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_Y], strings[STR_EMUNAND]); print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_B], strings[STR_CANCEL]); ConsoleShow(); while (true) { uint32_t pad_state = InputWait(); if(pad_state & BUTTON_X) return SYS_NAND; if(pad_state & BUTTON_Y) return EMU_NAND; if(pad_state & BUTTON_B) return UNK_NAND; } }
u32 ScrollOutput() { u32 log_start = LogWrite(NULL); // careful, these areas are used by other functions in Decrypt9 char** logptr = (char**) 0x21100000; char* logtext = (char*) 0x21200000; u32 log_size = FileGetData(LOG_FILE, logtext, 1024 * 1024, log_start); // log size u32 l_total = 0; // total lines u32 l_curr = 0; // current line // read log file (second time) log_size = FileGetData(LOG_FILE, logtext, 1024 * 1024, log_start); // allow 1MB of text max if ((log_size == 0) || (log_size >= 1024 * 1024)) return 0; // organize lines logtext[log_size - 1] = '\0'; logptr[l_total++] = logtext; for (char* line = strchr(logtext, '\n'); line != NULL && l_total < 4000; line = strchr(line, '\n')) { *line = '\0'; logptr[l_total++] = ++line; } if (l_total >= 4000) // allow 4000 lines of text max return 0; for (; l_total < DBG_N_CHARS_Y; logptr[l_total++] = logtext + log_size - 1); // fill up with empty lines // here, the actual output starts l_curr = l_total - DBG_N_CHARS_Y; if (l_curr > 0) l_curr--; // start at the line before the last while (true) { DebugSet((const char**) logptr + l_curr); u32 pad_state = InputWait(); if (pad_state & BUTTON_X) { Screenshot(NULL); } else if ((pad_state & BUTTON_UP) && (l_curr > 0)) { l_curr--; } else if ((pad_state & BUTTON_DOWN) && (l_curr < l_total - DBG_N_CHARS_Y)) { l_curr++; } else if (pad_state & (BUTTON_B | BUTTON_START)) { return pad_state; } } return 0; }
int NandSwitch(){ if(!checkEmuNAND()) return 0; //If No EmuNAND, we force to work on SysNAND ConsoleInit(); /* freezes ConsoleSetTitle(STR_CHOOSE_NAND[language]); print(STR_PRESS_X_SYSNAND[language]); print(STR_PRESS_Y_EMUNAND[language]); print(STR_PRESS_B_BACK[language]); */ ConsoleSetTitle(L"Choose the NAND you want to use"); print(L"Ⓧ sysNAND\nⓎ emuNAND\nⒷ Cancel\n"); ConsoleShow(); while (true) { u32 pad_state = InputWait(); if(pad_state & BUTTON_X) return SYS_NAND; if(pad_state & BUTTON_Y) return EMU_NAND; if(pad_state & BUTTON_B) return UNK_NAND; } }
u32 UnmountSd() { u32 pad_state; DebugClear(); Debug("Unmounting SD card..."); DeinitFS(); Debug("SD is unmounted, you may remove it now."); Debug("Put the SD card back in before pressing B!"); Debug(""); Debug("(B to return, START to reboot)"); while (true) { pad_state = InputWait(); if (((pad_state & BUTTON_B) && InitFS()) || (pad_state & BUTTON_START)) break; } return pad_state; }
int main(){ if (Initialize()) while (1); //7.X Keys stuff File KeyFile; const char *keyfile = "/slot0x25KeyX.bin"; if(FileOpen(&KeyFile, keyfile, 0)){ uint8_t keyX[16]; FileRead(&KeyFile, keyX, 16, 0); FileClose(&KeyFile); setup_aeskeyX(0x25, keyX); }else{ if (sysver < 7) { ConsoleInit(); ConsoleSetTitle(strings[STR_WARNING]); print(strings[STR_ERROR_OPENING], keyfile); print(strings[STR_WARNING_KEYFILE]); print(strings[STR_PRESS_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); ConsoleShow(); WaitForButton(BUTTON_A); } } //That's the Main Menu initialization, easy and cool OpenAnimation(); MenuInit(&MainMenu); MenuShow(); while (true) { uint32_t pad_state = InputWait(); if (pad_state & (BUTTON_DOWN | BUTTON_RIGHT | BUTTON_R1)) MenuNextSelection(); //I try to support every theme style if (pad_state & (BUTTON_UP | BUTTON_LEFT | BUTTON_L1)) MenuPrevSelection(); if (pad_state & BUTTON_A) { OpenAnimation(); MenuSelect(); } if (pad_state & BUTTON_SELECT) { fadeOut(); ShutDown(); } if (pad_state & BUTTON_START) { fadeOut(); returnHomeMenu(); } TryScreenShot(); MenuShow(); } FSDeInit(); return 0; }
int main(){ Initialize(); DrawString(TOP_SCREEN, "SUPPORT THE ORIGINAL, NOT THE IMITATION!", 75, 240-10, GREY, BLACK); //7.X Keys stuff File KeyFile; if(FileOpen(&KeyFile, "/slot0x25KeyX.bin", 0)){ u8 keyX[16]; FileRead(&KeyFile, keyX, 16, 0); FileClose(&KeyFile); setup_aeskeyX(0x25, keyX); DrawString(TOP_SCREEN, " NewKeyX ", 0, 240-8, GREEN, BLACK); }else{ if(GetSystemVersion() < 3){ ConsoleInit(); print("WARNING:\n\nCannot find slot0x25KeyX.bin.\nSome titles decryption will fail,\nand some some EmuNANDs will not boot.\n\nPress A to continue...\n"); ConsoleShow(); WaitForButton(BUTTON_A); } DrawString(TOP_SCREEN, " NewKeyX ", 0, 240-8, RED, BLACK); } DrawString(TOP_SCREEN, " EmuNAND ", 0, 240-16, checkEmuNAND() ? GREEN : RED, BLACK); //That's the Main Menu initialization, easy and cool MenuInit(&MainMenu); MenuShow(); while (true) { DrawString(TOP_SCREEN, "[SELECT] Reboot", 349-18*8, 181-24-8, RED, BLACK); DrawString(TOP_SCREEN, "[START] Shutdown", 349-18*8, 181-24, RED, BLACK); u32 pad_state = InputWait(); if(pad_state & BUTTON_DOWN) MenuNextSelection(); if(pad_state & BUTTON_UP) MenuPrevSelection(); if(pad_state & BUTTON_A) MenuSelect(); if(pad_state & BUTTON_SELECT) returnHomeMenu(); if(pad_state & BUTTON_START) ShutDown(); TryScreenShot(); MenuShow(); } FSDeInit(); return 0; }
int main(){ Initialize(); //7.X Keys stuff File KeyFile; if(FileOpen(&KeyFile, "/slot0x25KeyX.bin", 0)){ u8 keyX[16]; FileRead(&KeyFile, keyX, 16, 0); FileClose(&KeyFile); setup_aeskeyX(0x25, keyX); }else{ if(GetSystemVersion() < 3){ ConsoleInit(); ConsoleSetTitle(" WARNING"); print("WARNING:\n\nCannot find slot0x25KeyX.bin. If\nyour firmware version is less than\n7.X, some titles decryption will\nfail, and some EmuNANDs will not\nboot.\n\nPress A to continue...\n"); ConsoleShow(); WaitForButton(BUTTON_A); } } //That's the Main Menu initialization, easy and cool MenuInit(&MainMenu); MenuShow(); while (true) { u32 pad_state = InputWait(); if (pad_state & (BUTTON_DOWN | BUTTON_RIGHT | BUTTON_R1)) MenuNextSelection(); //I try to support every theme style if (pad_state & (BUTTON_UP | BUTTON_LEFT | BUTTON_L1)) MenuPrevSelection(); if(pad_state & BUTTON_A) MenuSelect(); if(pad_state & BUTTON_SELECT) ShutDown(); if(pad_state & BUTTON_START) returnHomeMenu(); TryScreenShot(); MenuShow(); } FSDeInit(); return 0; }
void restoreCoolFiles(){ int nandtype = NandSwitch(); if(nandtype == -1){ return; } selectedFile = -1; MenuInit(&CoolFilesMenu); MenuShow(); while (true) { u32 pad_state = InputWait(); if(pad_state & BUTTON_DOWN) MenuNextSelection(); if(pad_state & BUTTON_UP) MenuPrevSelection(); if(pad_state & BUTTON_A) { MenuSelect(); break; } if(pad_state & BUTTON_B) break; TryScreenShot(); MenuShow(); } if(selectedFile == -1) return; ConsoleInit(); ConsoleSetTitle("File Inject : %s", CoolFiles[selectedFile].name); char dest[256]; sprintf(tmpstr, "rxTools/%s", CoolFiles[selectedFile].name); sprintf(dest, "%d:%s", nandtype + 1, CoolFiles[selectedFile].path); print("Injecting...\n"); ConsoleShow(); int res = FileCopy(dest, tmpstr); char* showres; switch(res){ case 1 : showres = "Success!"; break; case -1 : showres = "Cannot write to file!"; break; case -2 : showres = "Cannot read from file!"; break; default : showres = "Failure!"; break; } print(showres); print("\n"); print("\nPress A to exit\n"); ConsoleShow(); WaitForButton(BUTTON_A); }
u32 UnmountSd() { u32 pad_state; #ifdef USE_THEME LoadThemeGfx(GFX_UNMOUNT, false); DeinitFS(); #else DebugClear(); Debug("Unmounting SD card..."); DeinitFS(); Debug("SD is unmounted, you may remove it now."); Debug("Put the SD card back in before pressing B!"); Debug(""); Debug("(B to return, START to reboot)"); #endif while (true) { pad_state = InputWait(); if (((pad_state & BUTTON_B) && InitFS()) || (pad_state & BUTTON_START)) break; } return pad_state; }
u32 UnmountSd() { u32 pad_state; #ifdef USE_THEME LoadThemeGfx(GFX_UNMOUNT, false); DeinitFS(); #else DebugClear(); Debug("Desmonatando la tarjeta SD..."); DeinitFS(); Debug("La tarjeta SD ha sido desmontada, puedes removerla ahora."); Debug("¡Inserta la tarjeta SD antes de pulsar B!"); Debug(""); Debug("(B para volver, START para reiniciar)"); #endif while (true) { pad_state = InputWait(); if (((pad_state & BUTTON_B) && InitFS()) || (pad_state & BUTTON_START)) break; } return pad_state; }
void wait_key() { Debug(""); Debug("Press key to continue"); InputWait(); }
u32 ProcessMenu(MenuInfo* info, u32 n_entries_main) { MenuInfo* currMenu; MenuInfo* prevMenu[MENU_MAX_DEPTH]; u32 prevIndex[MENU_MAX_DEPTH]; u32 menuLvlMin; u32 menuLvl; u32 index = 0; u32 result = MENU_EXIT_REBOOT; #ifndef USE_THEME MenuInfo mainMenu; if (n_entries_main > 1) { // build main menu structure from submenus if (n_entries_main > MENU_MAX_ENTRIES) // limit number of entries n_entries_main = MENU_MAX_ENTRIES; memset(&mainMenu, 0x00, sizeof(MenuInfo)); for (u32 i = 0; i < n_entries_main; i++) { mainMenu.entries[i].name = info[i].name; mainMenu.entries[i].function = NULL; mainMenu.entries[i].param = i; } mainMenu.n_entries = n_entries_main; #ifndef BUILD_NAME mainMenu.name = "Decrypt9 Main Menu"; #else mainMenu.name = BUILD_NAME; #endif currMenu = &mainMenu; menuLvlMin = 0; } else { currMenu = info; menuLvlMin = 1; } DrawMenu(currMenu, 0, true, false); #else currMenu = info; menuLvlMin = 1; LoadThemeGfxLogo(); LoadThemeGfxMenu(0); #endif menuLvl = menuLvlMin; // main processing loop while (true) { bool full_draw = true; u32 pad_state = InputWait(); if ((pad_state & BUTTON_A) && (currMenu->entries[index].function == NULL)) { if (menuLvl < MENU_MAX_DEPTH) { prevMenu[menuLvl] = currMenu; prevIndex[menuLvl] = index; menuLvl++; } currMenu = info + currMenu->entries[index].param; index = 0; } else if (pad_state & BUTTON_A) { pad_state = ProcessEntry(currMenu->entries + index); } else if ((pad_state & BUTTON_B) && (menuLvl > menuLvlMin)) { menuLvl--; currMenu = prevMenu[menuLvl]; index = prevIndex[menuLvl]; } else if (pad_state & BUTTON_DOWN) { index = (index == currMenu->n_entries - 1) ? 0 : index + 1; full_draw = false; } else if (pad_state & BUTTON_UP) { index = (index == 0) ? currMenu->n_entries - 1 : index - 1; full_draw = false; } else if ((pad_state & BUTTON_R1) && (menuLvl == 1)) { if (++currMenu - info >= n_entries_main) currMenu = info; index = 0; } else if ((pad_state & BUTTON_L1) && (menuLvl == 1)) { if (--currMenu < info) currMenu = info + n_entries_main - 1; index = 0; } else if (pad_state & BUTTON_SELECT) { pad_state = UnmountSd(); } else if (pad_state & BUTTON_X) { (pad_state & (BUTTON_LEFT | BUTTON_RIGHT)) ? BatchScreenshot(info, pad_state & BUTTON_RIGHT) : Screenshot(NULL); } else { full_draw = false; } if (pad_state & BUTTON_START) { result = (pad_state & BUTTON_LEFT) ? MENU_EXIT_POWEROFF : MENU_EXIT_REBOOT; break; } #ifndef USE_THEME DrawMenu(currMenu, index, full_draw, menuLvl > menuLvlMin); #else if (full_draw) LoadThemeGfxLogo(); LoadThemeGfxMenu(((currMenu - info) * 100) + index); #endif } return result; }
void dumpCoolFiles() { int nandtype = NandSwitch(); if (nandtype == UNK_NAND) return; selectedFile = -1; MenuInit(&CoolFilesMenu); MenuShow(); while (true) { uint32_t pad_state = InputWait(); if (pad_state & BUTTON_DOWN) MenuNextSelection(); if (pad_state & BUTTON_UP) MenuPrevSelection(); if (pad_state & BUTTON_A) { MenuSelect(); break; } if (pad_state & BUTTON_B) break; TryScreenShot(); MenuShow(); } if (selectedFile == -1) return; ConsoleInit(); ConsoleSetTitle(strings[STR_DUMP], strings[STR_FILES]); char dest[256], tmpstr[sizeof(dest)]; wchar_t wsrc[sizeof(tmpstr)]; sprintf(dest, "rxTools/%s", CoolFiles[selectedFile].name); sprintf(tmpstr, "%d:%s/%s", nandtype, CoolFiles[selectedFile].path, CoolFiles[selectedFile].name); mbstowcs(wsrc, tmpstr, sizeof(tmpstr)); print(strings[STR_DUMPING], wsrc, dest); ConsoleShow(); unsigned int res = FSFileCopy(dest, tmpstr); if (res != 0 && (selectedFile == 1 || selectedFile == 2)){ if (selectedFile == 1) { /* Fix for SecureInfo_B */ sprintf(dest, "rxTools/%.11s%c", CoolFiles[selectedFile].name, 'B'); sprintf(tmpstr, "%d:%s/%.11s%c", nandtype, CoolFiles[selectedFile].path, CoolFiles[selectedFile].name, 'B'); } else if (selectedFile == 2) { /* Fix for LocalFriendCodeSeed_A */ sprintf(dest, "rxTools/%.20s%c", CoolFiles[selectedFile].name, 'A'); sprintf(tmpstr, "%d:%s/%.20s%c", nandtype, CoolFiles[selectedFile].path, CoolFiles[selectedFile].name, 'A'); } mbstowcs(wsrc, tmpstr, sizeof(tmpstr)); print(strings[STR_FAILED]); print(strings[STR_DUMPING], wsrc, dest); ConsoleShow(); res = FSFileCopy(dest, tmpstr); } switch ((res >> 8) & 0xFF) { case 0: print(strings[STR_COMPLETED]); break; case 1: print(strings[STR_ERROR_OPENING], tmpstr); break; case 2: print(strings[STR_ERROR_CREATING], dest); break; case 3: case 4: print(strings[STR_ERROR_READING], tmpstr); break; case 5: case 6: print(strings[STR_ERROR_WRITING], dest); break; default: print(strings[STR_FAILED]); break; } print(strings[STR_PRESS_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); ConsoleShow(); WaitForButton(BUTTON_A); }
__attribute__((section(".text.start"), noreturn)) void _start() { static const TCHAR fontPath[] = _T("") SYS_PATH "/" FONT_NAME; void *fontBuf; UINT btr, br; int r; FIL f; // Enable TMIO IRQ *(volatile uint32_t *)0x10001000 = 0x00010000; preloadStringsA(); if (!FSInit()) { DrawString(BOT_SCREEN, strings[STR_FAILED], BOT_SCREEN_WIDTH / 2, SCREEN_HEIGHT - FONT_HEIGHT, RED, BLACK); while (1); } set_loglevel(ll_info); log(ll_info, "Initializing rxTools..."); setConsole(); fontIsLoaded = 0; r = f_open(&f, fontPath, FA_READ); if (r == FR_OK) { btr = f_size(&f); fontBuf = __builtin_alloca(btr); r = f_read(&f, fontBuf, btr, &br); if (r == FR_OK) fontIsLoaded = 1; f_close(&f); fontaddr = fontBuf; } if (fontIsLoaded) preloadStringsU(); else warn(L"Failed to load " FONT_NAME ": %d\n", r); if (getMpInfo() == MPINFO_KTR) { r = initN3DSKeys(); if (r != FR_OK) { warn(L"Failed to load keys for N3DS\n" " Code: %d\n" " RxMode will not boot. Please\n" " include key_0x16.bin and\n" " key_0x1B.bin at the root of your\n" " SD card.\n", r); InputWait(); goto postinstall; } } install(); postinstall: readCfg(); log(ll_info, "Done..."); r = loadStrings(); if (r) warn(L"Failed to load strings: %d\n", r); drawTop(); //Default boot check if (cfgs[CFG_DEFAULT].val.i && HID_STATE & BUTTON_L1) { if(cfgs[CFG_DEFAULT].val.i == 3) PastaMode(); else rxMode(cfgs[CFG_DEFAULT].val.i - 1); } if (sysver < 7) { r = initKeyX(); if (r != FR_OK) warn(L"Failed to load key X for slot 0x25\n" " Code: %d\n" " If your firmware version is less\n" " than 7.X, some titles decryption\n" " will fail, and some EmuNANDs\n" " will not boot.\n", r); } if (warned) { warn(strings[STR_PRESS_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); WaitForButton(BUTTON_A); } OpenAnimation(); mainLoop(); }
int main() { u32 pad_state; u32 num_calls = 0; InitFS(); while (true) { ClearTop(); Debug(" ALBERTOSONIC'S CFW "); Debug(""); Debug("Getting system version..."); getSystemVersion(); Debug(""); Debug("Your system is %s", systemVersion); Debug(""); if (type == 0) { Debug("Press any key to reboot."); pad_state = InputWait(); break; } else { //Let's continue our patch Debug(""); Debug("Patching..."); if (type == 1){ u8 patch[] = { 0x00, 0x20, 0x3B, 0xE0 }; u32 *dest = 0x080549C4; memcpy(dest, patch, 4); u8 patch1[] = { 0x00, 0x20, 0x08, 0xE0 }; u32 *dest1 = 0x0804239C; memcpy(dest1, patch1, 4); } if (type == 2){ u8 patch[] = { 0x00, 0x20, 0x3B, 0xE0 }; u32 *dest = 0x080523C4; memcpy(dest, patch, 4); u8 patch1[] = { 0x00, 0x20, 0x08, 0xE0 }; u32 *dest1 = 0x08058098; memcpy(dest1, patch1, 4); } if (type == 3){ u8 patch[] = { 0x00, 0x20, 0x3B, 0xE0 }; u32 *dest = 0x0805235C; memcpy(dest, patch, 4); u8 patch1[] = { 0x00, 0x20, 0x08, 0xE0 }; u32 *dest1 = 0x08058100; memcpy(dest1, patch1, 4); } if (type == 4){ u8 patch[] = { 0x6D, 0x20, 0xCE, 0x77 }; u32 *dest = 0x08052FD8; memcpy(dest, patch, 4); u8 patch1[] = { 0x5A, 0xC5, 0x73, 0xC1 }; u32 *dest1 = 0x08058804; memcpy(dest1, patch1, 4); } break; } } // return control to FIRM ARM9 code (performs firmlaunch) return 0; }
u32 ProcessEntry(MenuEntry* entry) { bool emunand = entry->param & N_EMUNAND; bool nand_force = entry->param & N_FORCEEMU; bool warning = entry->param & N_NANDWRITE; u32 pad_state; u32 res = 0; // unlock sequence for dangerous features if (warning) { u32 unlockSequenceEmu[] = { BUTTON_LEFT, BUTTON_RIGHT, BUTTON_DOWN, BUTTON_UP, BUTTON_A }; u32 unlockSequenceSys[] = { BUTTON_LEFT, BUTTON_UP, BUTTON_RIGHT, BUTTON_UP, BUTTON_A }; u32 unlockLvlMax = ((emunand) ? sizeof(unlockSequenceEmu) : sizeof(unlockSequenceSys)) / sizeof(u32); u32* unlockSequence = (emunand) ? unlockSequenceEmu : unlockSequenceSys; u32 unlockLvl = 0; #ifdef USE_THEME LoadThemeGfx((emunand) ? GFX_DANGER_E : GFX_DANGER_S, false); #endif DebugClear(); Debug("You selected \"%s\".", entry->name); Debug("This feature writes to the %s.", (emunand) ? "EmuNAND" : "SysNAND"); Debug("Data will be overwriten, keep backups!"); Debug(""); Debug("If you wish to proceed, enter:"); Debug((emunand) ? "<Left>, <Right>, <Down>, <Up>, <A>" : "<Left>, <Up>, <Right>, <Up>, <A>"); Debug(""); Debug("(B to return, START to reboot)"); while (true) { ShowProgress(unlockLvl, unlockLvlMax); if (unlockLvl == unlockLvlMax) break; pad_state = InputWait(); if (!(pad_state & BUTTON_ANY)) continue; else if (pad_state & unlockSequence[unlockLvl]) unlockLvl++; else if (pad_state & (BUTTON_B | BUTTON_START)) break; else if (unlockLvl == 0 || !(pad_state & unlockSequence[unlockLvl-1])) unlockLvl = 0; } ShowProgress(0, 0); if (unlockLvl < unlockLvlMax) return pad_state; } // execute this entries function #ifdef USE_THEME LoadThemeGfx(GFX_PROGRESS, false); #endif DebugClear(); res = (SetNand(emunand, nand_force) == 0) ? (*(entry->function))(entry->param) : 1; Debug("%s: %s!", entry->name, (res == 0) ? "succeeded" : "failed"); Debug(""); Debug("Press B to return, START to reboot."); #ifdef USE_THEME LoadThemeGfx((res == 0) ? GFX_DONE : GFX_FAILED, false); #endif while(!((pad_state = InputWait()) & (BUTTON_B | BUTTON_START))) { if (pad_state & BUTTON_X) Screenshot(NULL); #ifdef LOG_FILE else if (pad_state & BUTTON_UP) { pad_state = ScrollOutput(); break; } #endif } // returns the last known pad_state return pad_state; }
u32 ProcessEntry(MenuEntry* entry) { bool emunand = entry->param & N_EMUNAND; bool nand_force = entry->param & N_FORCEEMU; bool nand_write = entry->param & N_NANDWRITE; bool a9lh_write = (entry->param & N_A9LHWRITE) && ((*(u32*) 0x101401C0) == 0); u32 pad_state; u32 res = 0; // unlock sequence for dangerous features if (nand_write || a9lh_write) { const u32 unlockSequences[3][5] = { { BUTTON_LEFT , BUTTON_RIGHT, BUTTON_DOWN , BUTTON_UP , BUTTON_A }, // EmuNAND { BUTTON_LEFT , BUTTON_UP , BUTTON_RIGHT, BUTTON_UP , BUTTON_A }, // SysNAND { BUTTON_RIGHT, BUTTON_DOWN , BUTTON_LEFT , BUTTON_DOWN , BUTTON_A } // A9LH }; const u32 unlockLvlMax = 5; u32* unlockSequence = (u32*) &(unlockSequences[(emunand) ? 0 : (a9lh_write) ? 2 : 1]); u32 warnColor = (emunand) ? COLOR_YELLOW : COLOR_RED; u32 unlockLvl = 0; #ifdef USE_THEME LoadThemeGfx((emunand) ? GFX_DANGER_E : GFX_DANGER_S, false); #endif DebugClear(); Debug("You selected [%s].", entry->name); Debug(""); if (!a9lh_write) { DebugColor(warnColor, "This feature writes to the %s.", (emunand) ? "EmuNAND" : "SysNAND"); DebugColor(warnColor, "This may overwrite important data!"); } else { DebugColor(warnColor, "!!! THIS WILL OVERWRITE THE A9LH !!!"); DebugColor(warnColor, "!!! INSTALLATION IN YOUR SYSNAND !!!"); } Debug(""); Debug("If you wish to proceed, enter:"); Debug((emunand) ? "<Left>, <Right>, <Down>, <Up>, <A>" : (a9lh_write) ? "<Right>, <Down>, <Left>, <Down>, <A>" : "<Left>, <Up>, <Right>, <Up>, <A>"); Debug(""); Debug("(B to return, START to reboot)"); while (true) { ShowProgress(unlockLvl, unlockLvlMax); if (unlockLvl == unlockLvlMax) break; pad_state = InputWait(); if (!(pad_state & BUTTON_ANY)) continue; else if (pad_state & unlockSequence[unlockLvl]) unlockLvl++; else if (pad_state & (BUTTON_B | BUTTON_START)) break; else if (unlockLvl == 0 || !(pad_state & unlockSequence[unlockLvl-1])) unlockLvl = 0; } ShowProgress(0, 0); if (unlockLvl < unlockLvlMax) return pad_state; } // execute this entries function #ifdef USE_THEME LoadThemeGfx(GFX_PROGRESS, false); #endif DebugClear(); Debug("Selected: [%s]", entry->name); res = (SetNand(emunand, nand_force) == 0) ? (*(entry->function))(entry->param) : 1; DebugColor((res == 0) ? COLOR_GREEN : COLOR_RED, "%s: %s!", entry->name, (res == 0) ? "succeeded" : "failed"); Debug(""); Debug("Press B to return, START to reboot."); #ifdef USE_THEME LoadThemeGfx((res == 0) ? GFX_DONE : GFX_FAILED, false); #endif while(!((pad_state = InputWait()) & (BUTTON_B | BUTTON_START))) { if (pad_state & BUTTON_X) Screenshot(NULL); #ifdef LOG_FILE else if (pad_state & BUTTON_UP) { pad_state = ScrollOutput(); break; } #endif } // returns the last known pad_state return pad_state; }