void Sys_Print(const char* message) { const char* p = message; while (*p != '\0') { if (*p == '\n') { ScrollOutput(1); } if (*p == '^') { char color; p++; color = (*p - '0'); if (color < 9 && color > 0) { wattron(outputWindow, COLOR_PAIR(color + 2)); p++; continue; } } waddch(outputWindow, *p); p++; } wattron(outputWindow, COLOR_PAIR(9)); int currentTime = GetTickCount(); if (!didWeHaveConsole) { RefreshOutput(); } else if ((currentTime - lastRefresh) > 100) { RefreshOutput(); lastRefresh = currentTime; } }
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; }
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("Has seleccionado [%s].", entry->name); Debug(""); if (!a9lh_write) { DebugColor(warnColor, "Esta operacion escribira datos en %s.", (emunand) ? "EmuNAND" : "SysNAND"); DebugColor(warnColor, "¡Esto puede sobreescribir datos importantes!"); } else { DebugColor(warnColor, "ESTO SOBREESCRIBIRA LA INSTALACION!!!"); DebugColor(warnColor, "DE A9LH EN TU SYSNAND!!!"); } Debug(""); Debug("Si decides continuar, presiona los siguientes botones:"); Debug((emunand) ? "<Izquierda>, <Derecha>, <Abajo>, <Arriba>, <A>" : (a9lh_write) ? "<Derecha>, <Abajo>, <Izquierda>, <Abajo>, <A>" : "<Izquierda>, <Arriba>, <Derecha>, <Arriba>, <A>"); Debug(""); Debug("(B para volver, START para reiniciar)"); 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("Seleccionado: [%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("B para volver, START para reiniciar."); #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; }
const char* Sys_ConsoleInput() { if (!didWeHaveConsole) { ShowConsolePrompt(); wrefresh(inputWindow); didWeHaveConsole = true; } int currentTime = GetTickCount(); if ((currentTime - lastRefresh) > 250) { RefreshOutput(); lastRefresh = currentTime; } UpdateConsoleStatus(); int c = wgetch(inputWindow); if (c == ERR) { return NULL; } switch (c) { case '\r': wattron(outputWindow, COLOR_PAIR(10) | A_BOLD); wprintw(outputWindow, "]%s\n", consoleLineBuffer); wattroff(outputWindow, A_BOLD); wclear(inputWindow); ShowConsolePrompt(); wrefresh(inputWindow); ScrollOutput(1); RefreshOutput(); if (consoleLineBufferIndex) { strcpy(consoleLineBuffer2, consoleLineBuffer); strcat(consoleLineBuffer, "\n"); consoleLineBufferIndex = 0; return consoleLineBuffer; } break; case 'c' - 'a' + 1: // ctrl-c case 27: consoleLineBuffer[0] = '\0'; consoleLineBufferIndex = 0; wclear(inputWindow); ShowConsolePrompt(); wrefresh(inputWindow); break; case 8: // backspace if (consoleLineBufferIndex > 0) { consoleLineBufferIndex--; consoleLineBuffer[consoleLineBufferIndex] = '\0'; wprintw(inputWindow, "%c %c", (char)c, (char)c); wrefresh(inputWindow); } break; case KEY_PPAGE: ScrollOutput(-1); RefreshOutput(); break; case KEY_NPAGE: ScrollOutput(1); RefreshOutput(); break; case KEY_UP: wclear(inputWindow); ShowConsolePrompt(); wprintw(inputWindow, "%s", consoleLineBuffer2); wrefresh(inputWindow); strcpy(consoleLineBuffer, consoleLineBuffer2); consoleLineBufferIndex = strlen(consoleLineBuffer); break; default: if (c <= 127 && consoleLineBufferIndex < 1022) { // temporary workaround for issue #9, find out what overwrites our index later on consoleLineBufferIndex = strlen(consoleLineBuffer); consoleLineBuffer[consoleLineBufferIndex++] = (char)c; consoleLineBuffer[consoleLineBufferIndex] = '\0'; wprintw(inputWindow, "%c", (char)c); wrefresh(inputWindow); } break; } return NULL; }