diff --git a/include/arm11/menu/menu.h b/include/arm11/menu/menu.h index cd37459..4504b08 100644 --- a/include/arm11/menu/menu.h +++ b/include/arm11/menu/menu.h @@ -31,6 +31,8 @@ #define MENU_FLAG_SLOTS 1 #define MENU_FLAG_SLOT(x) (1<. + */ + + + +// ANSI escape sequences for colors +// see: https://en.wikipedia.org/wiki/ANSI_escape_code +#define ESC_RESET "\x1b[0m" +#define ESC_BOLD "\x1b[1m" +#define ESC_FAINT "\x1b[2m" +#define ESC_UNDERLINE "\x1b[4m" +#define ESC_CROSSEDOUT "\x1b[9m" +#define ESC_INVERT "\x1b[7m" +#define ESC_FGCOLOR(x) "\x1b[3" #x "m" +#define ESC_BGCOLOR(x) "\x1b[4" #x "m" + +// colors for color scheme +#define ESC_SCHEME_STD ESC_RESET ESC_FGCOLOR(7) ESC_BGCOLOR(0) +#define ESC_SCHEME_WEAK ESC_RESET ESC_FGCOLOR(7) ESC_BGCOLOR(0) ESC_BOLD +#define ESC_SCHEME_ACCENT0 ESC_RESET ESC_FGCOLOR(4) ESC_BGCOLOR(0) ESC_BOLD +#define ESC_SCHEME_ACCENT1 ESC_RESET ESC_FGCOLOR(3) ESC_BGCOLOR(0) ESC_BOLD diff --git a/include/arm11/menu/menu_fb3ds.h b/include/arm11/menu/menu_fb3ds.h index ac15e1e..aca2378 100644 --- a/include/arm11/menu/menu_fb3ds.h +++ b/include/arm11/menu/menu_fb3ds.h @@ -24,7 +24,7 @@ #define SUBMENU_SLOT_SETUP(x) \ { \ - "Boot Slot #" #x " Setup", 3, NULL, MENU_FLAG_SLOT(x), \ + "Boot Slot #" #x " Setup", 3, &menuPresetSlotConfig##x, MENU_FLAG_SLOT(x), \ { \ { "Select [slot " #x "] firm", DESC_FIRM_SLOT(x), &menuSetupBootSlot, (x-1)&0xF }, \ { "Select [slot " #x "] buttons", DESC_KEYS_SLOT(x), &menuSetupBootKeys, (x-1)&0xF }, \ @@ -35,8 +35,8 @@ #define LOREM "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata" #define DESC_CONTINUE "Continue booting the first available boot slot.\nNo function if boot slots are not set up." -#define DESC_BOOT_MENU "Display a boot menu, allowing you to select which boot slot to boot from." -#define DESC_BOOT_FILE "Select a firmware to boot." +#define DESC_BOOT_MENU "Display a boot menu, allowing you to select which boot slot to boot from. Also includes boot slot and boot mode setup." +#define DESC_BOOT_FILE "Select a firmware file to boot." #define DESC_NAND_TOOLS "Enter NAND tools submenu, including tools for NAND backup, NAND restore and firmware flash." #define DESC_OPTIONS "Enter fastboot3ds settings submenu." #define DESC_MISC "Enter miscellaneous submenu, including the update tool and credits section." @@ -47,12 +47,12 @@ #define DESC_SLOT_SETUP(x) "Change boot settings for slot #" #x "." #define DESC_FIRM_SLOT(x) "Change the firmware in boot slot #" #x "." -#define DESC_CLEAR_SLOT(x) "Change the firmware in boot slot #" #x "." +#define DESC_CLEAR_SLOT(x) "Clear & reset boot slot #" #x "." #define DESC_KEYS_SLOT(x) "Change the keycombo used to boot slot #" #x "." -#define DESC_BOOT_NORMAL "Set normal boot mode.\nIn normal boot mode, you will be presented with the fastboot3ds menu upon boot." -#define DESC_BOOT_QUICK "Set quick boot mode.\nIn quick boot mode, splash is displayed and the boot is continued via the first available boot slot. To enter fastboot3ds menu, hold the HOME button at startup." -#define DESC_BOOT_QUIET "Set quiet boot mode.\nIn quiet boot mode, splash is not displayed and the boot is continued via the first available boot slot. To enter fastboot3ds menu, hold the HOME button at startup." +#define DESC_BOOT_NORMAL "In normal boot mode, you will be presented with the fastboot3ds menu upon boot." +#define DESC_BOOT_QUICK "In quick boot mode, splash is displayed and the boot is continued via the first available boot slot. To enter fastboot3ds menu, hold the HOME button at startup." +#define DESC_BOOT_QUIET "In quiet boot mode, splash is not displayed and the boot is continued via the first available boot slot. To enter fastboot3ds menu, hold the HOME button at startup." #define DESC_CHANGE_BOOT "Change fastboot3ds boot mode. This allows you to set up how your console boots." #define DESC_NAND_BACKUP "Backup current NAND to a file." @@ -84,7 +84,7 @@ } }, { // 1 - "Boot Menu", 5, &menuPresetBootSlot, MENU_FLAG_SLOTS, + "Boot Menu", 5, &menuPresetBootMenu, MENU_FLAG_SLOTS, { { "Boot [slot 1]", DESC_BOOT_SLOT(1), &menuLaunchFirm, 0x00 }, { "Boot [slot 2]", DESC_BOOT_SLOT(2), &menuLaunchFirm, 0x01 }, @@ -95,7 +95,7 @@ } }, { // 2 - "Boot Setup", 4, &menuPresetBootSlot, MENU_FLAG_SLOTS, + "Boot Setup", 4, &menuPresetBootConfig, MENU_FLAG_SLOTS | MENU_FLAG_BOOTMODE, { { "Setup [slot 1]...", DESC_SLOT_SETUP(1), NULL, 3 }, { "Setup [slot 2]...", DESC_SLOT_SETUP(2), NULL, 4 }, @@ -117,23 +117,24 @@ { // 7 "NAND Tools", 4, NULL, 0, { - { "Backup NAND", DESC_NAND_BACKUP, &menuDummyFunc, 3 }, - { "Restore NAND", DESC_NAND_RESTORE, &menuDummyFunc, 4 }, - { "Restore NAND (forced)", DESC_NAND_RESTORE_F, &menuDummyFunc, 4 }, - { "Flash firmware", DESC_FIRM_FLASH, &menuDummyFunc, 2 } + { "Backup NAND", DESC_NAND_BACKUP, &menuDummyFunc, 3 }, + { "Restore NAND", DESC_NAND_RESTORE, &menuDummyFunc, 4 }, + { "Restore NAND (forced)", DESC_NAND_RESTORE_F, &menuDummyFunc, 4 }, + { "Flash firmware", DESC_FIRM_FLASH, &menuDummyFunc, 2 } } }, { // 8 "Miscellaneous", 2, NULL, 0, { - { "Update fastboot3DS", DESC_UPDATE, &menuDummyFunc, 1 }, + { "Update fastboot3DS", DESC_UPDATE, &menuDummyFunc, 1 }, { "Credits", DESC_CREDITS, &menuShowCredits, 0 } } }, { // 9 - "Debug", 1, NULL, 0, // this will not show in the release version + "Debug", 2, NULL, 0, // this will not show in the release version { - { "View current settings", LOREM, &SetView, 0 } + { "View current settings", LOREM, &debugSettingsView, 0 }, + { "Escape sequence test", LOREM, &debugEscapeTest, 0 } } } }; diff --git a/include/arm11/menu/menu_func.h b/include/arm11/menu/menu_func.h index a2e4005..c97d610 100644 --- a/include/arm11/menu/menu_func.h +++ b/include/arm11/menu/menu_func.h @@ -21,14 +21,19 @@ #include "types.h" u32 menuPresetBootMode(void); -u32 menuPresetBootSlot(void); +u32 menuPresetBootMenu(void); +u32 menuPresetBootConfig(void); +u32 menuPresetSlotConfig1(void); +u32 menuPresetSlotConfig2(void); +u32 menuPresetSlotConfig3(void); -u32 menuSetBootMode(PrintConsole* con, u32 param); -u32 menuSetupBootSlot(PrintConsole* con, u32 param); -u32 menuSetupBootKeys(PrintConsole* con, u32 param); -u32 menuLaunchFirm(PrintConsole* con, u32 param); -u32 menuShowCredits(PrintConsole* con, u32 param); -u32 menuContinueBoot(PrintConsole* con, u32 param); +u32 menuSetBootMode(PrintConsole* term_con, PrintConsole* menu_con, u32 param); +u32 menuSetupBootSlot(PrintConsole* term_con, PrintConsole* menu_con, u32 param); +u32 menuSetupBootKeys(PrintConsole* term_con, PrintConsole* menu_con, u32 param); +u32 menuLaunchFirm(PrintConsole* term_con, PrintConsole* menu_con, u32 param); +u32 menuShowCredits(PrintConsole* term_con, PrintConsole* menu_con, u32 param); +u32 menuContinueBoot(PrintConsole* term_con, PrintConsole* menu_con, u32 param); -u32 menuDummyFunc(PrintConsole* con, u32 param); -u32 SetView(PrintConsole* con, u32 param); +u32 menuDummyFunc(PrintConsole* term_con, PrintConsole* menu_con, u32 param); +u32 debugSettingsView(PrintConsole* term_con, PrintConsole* menu_con, u32 param); +u32 debugEscapeTest(PrintConsole* term_con, PrintConsole* menu_con, u32 param); diff --git a/include/arm11/menu/menu_util.h b/include/arm11/menu/menu_util.h index f6c7a75..9db047b 100644 --- a/include/arm11/menu/menu_util.h +++ b/include/arm11/menu/menu_util.h @@ -22,8 +22,14 @@ char* mallocpyString(const char* str); void truncateString(char* dest, const char* orig, int nsize, int tpos); void formatBytes(char* str, u64 bytes); +void keysToString(u32 keys, char* string); +void stringWordWrap(char* str, int llen); + u32 stringGetHeight(const char* str); u32 stringGetWidth(const char* str); -void stringWordWrap(char* str, int llen); + u32 ee_printf_line_center(const char *const fmt, ...); + +void updateScreens(void); +void outputEndWait(void); void sleepmode(void); diff --git a/include/fs.h b/include/fs.h index ea95cd7..1a02568 100644 --- a/include/fs.h +++ b/include/fs.h @@ -23,7 +23,7 @@ #define FS_MAX_DEVICES (2) #define FS_MAX_DRIVES (FF_VOLUMES) -#define FS_DRIVE_NAMES FF_VOLUME_STRS +#define FS_DRIVE_NAMES "sdmc:/","twln:/","twlp:/","nand:/" #define FS_MAX_FILES (5) diff --git a/source/arm11/console.c b/source/arm11/console.c index 26a219d..9d60536 100644 --- a/source/arm11/console.c +++ b/source/arm11/console.c @@ -23,16 +23,16 @@ RGB8_to_565( 0,255,255), // bright cyan RGB8_to_565(255,255,255), // bright white - RGB8_to_565(128,128,128), // bright black + RGB8_to_565( 64, 64, 64), // almost black RGB8_to_565(255, 0, 0), // bright red RGB8_to_565( 0,255, 0), // bright green - RGB8_to_565(255,255, 0), // bright yellow - RGB8_to_565( 0, 0,255), // bright blue + RGB8_to_565(255,255, 32), // acccent yellow + RGB8_to_565( 64, 64,255), // accent blue RGB8_to_565(255, 0,255), // bright magenta RGB8_to_565( 0,255,255), // bright cyan - RGB8_to_565(255,255,255), // bright white + RGB8_to_565(192,192,192), // almost white - RGB8_to_565( 0, 0, 0), // faint black + RGB8_to_565(128,128,128), // bright black RGB8_to_565( 64, 0, 0), // faint red RGB8_to_565( 0, 64, 0), // faint green RGB8_to_565( 64, 64, 0), // faint yellow diff --git a/source/arm11/hardware/gfx.c b/source/arm11/hardware/gfx.c index 7f540d0..1105633 100644 --- a/source/arm11/hardware/gfx.c +++ b/source/arm11/hardware/gfx.c @@ -207,16 +207,13 @@ void* GFX_getFramebuffer(u8 screen) { - if(!activeFb) + static void *const framebufTable[2][2] = { - if(screen) return (void*)FRAMEBUF_TOP_A_2; - else return (void*)FRAMEBUF_SUB_A_2; - } - else - { - if(screen) return (void*)FRAMEBUF_TOP_A_1; - else return (void*)FRAMEBUF_SUB_A_1; - } + {(void*)FRAMEBUF_SUB_A_2, (void*)FRAMEBUF_SUB_A_1}, + {(void*)FRAMEBUF_TOP_A_2, (void*)FRAMEBUF_TOP_A_1} + }; + + return framebufTable[screen][activeFb]; } void GFX_swapFramebufs(void) diff --git a/source/arm11/hardware/hid.c b/source/arm11/hardware/hid.c index 2e28457..897763e 100644 --- a/source/arm11/hardware/hid.c +++ b/source/arm11/hardware/hid.c @@ -39,6 +39,9 @@ void hidInit(void) { + const u32 mcuInterruptMask = 0xFFFF1800u; // Standard bitmask at cold boot + I2C_writeRegBuf(I2C_DEV_MCU, 0x18, (const u8*)&mcuInterruptMask, 4); + IRQ_registerHandler(IRQ_MCU_HID, 14, 0, true, hidIrqHandler); GPIO_setBit(19, 9); // This enables the MCU HID IRQ } diff --git a/source/arm11/hardware/interrupt.c b/source/arm11/hardware/interrupt.c index 0c0b19e..73602d9 100644 --- a/source/arm11/hardware/interrupt.c +++ b/source/arm11/hardware/interrupt.c @@ -69,6 +69,10 @@ if(!getCpuId()) { + // Disable FIQs + REG_CFG11_FIQ_CNT = 1; + + // Disable the global interrupt distributor REG_GID_CNT = 0; @@ -123,6 +127,7 @@ REG_CPU_II_EOI = tmp; // End of interrupt } while(tmp != 1023); + leaveCriticalSection(); // Enables interrupts } diff --git a/source/arm11/main.c b/source/arm11/main.c index 047508c..cb9c0a7 100644 --- a/source/arm11/main.c +++ b/source/arm11/main.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include #include "types.h" #include "arm11/hardware/hardware.h" #include "arm11/hardware/interrupt.h" @@ -24,10 +25,12 @@ #include "arm11/hardware/i2c.h" #include "arm11/menu/menu.h" #include "arm11/menu/menu_fb3ds.h" +#include "arm11/menu/menu_util.h" #include "hardware/pxi.h" #include "hardware/gfx.h" #include "arm11/firm.h" #include "arm11/console.h" +#include "arm11/debug.h" #include "arm11/fmt.h" #include "fsutils.h" #include "arm11/config.h" @@ -40,12 +43,18 @@ int main(void) { + bool show_menu = false; + bool gfx_initialized = false; + char* err_string = NULL; + + // init hardware / filesystem / load config hardwareInit(); fsMountSdmc(); fsMountNandFilesystems(); loadConfigFile(); + // check keys held at boot hidScanInput(); u32 kHeld = hidKeysHeld(); @@ -53,6 +62,14 @@ // boot slot keycombo held? if (kHeld & 0xfff) { + err_string = (char*) malloc(512); + char* err_ptr = err_string; + if(!err_string) panicMsg("Out of memory"); + + char combo_str[0x80]; + keysToString(kHeld & 0xfff, combo_str); + err_ptr += ee_sprintf(err_ptr, "Keys held on boot: %s\n", combo_str); + for(u32 i = 0; (i < 3) && !g_startFirmLaunch; i++) { if(!configDataExist(KBootOption1 + i) || @@ -63,63 +80,138 @@ if((kHeld & 0xfff) == combo) { char* path = (char*) configGetData(KBootOption1 + i); + err_ptr += ee_sprintf(err_ptr, "Keys match boot slot #%lu.\nBoot path is %s\n", (i+1), path); g_startFirmLaunch = (loadVerifyFirm(path, false) >= 0); + err_ptr += ee_sprintf(err_ptr, "Load slot #%lu %s.\n", (i+1), g_startFirmLaunch ? "success" : "failed"); + break; } } + + if (!g_startFirmLaunch) + { + err_ptr += ee_sprintf(err_ptr, "Firmware not loaded!\nKeys may not match a boot slot.\n"); + } + else + { + free(err_string); + err_string = NULL; + } } + // get bootmode from config u32 bootmode = BootModeNormal; if(configDataExist(KBootMode)) bootmode = *(u32*) configGetData(KBootMode); - - // menu specific code - // HOME button detection may not work yet - if(!g_startFirmLaunch && ((bootmode == BootModeNormal) || hidIsHomeButtonHeldRaw())) - { - // init screens - GFX_init(); - - // init menu console - PrintConsole menu_con; - consoleInit(SCREEN_SUB, &menu_con, false); - - // init description console - PrintConsole desc_con; - consoleInit(SCREEN_TOP, &desc_con, false); - - // run menu - g_continueBootloader = false; - menuProcess(&menu_con, &desc_con, menu_fb3ds); - - // write config (if something changed) - if (configHasChanged()) writeConfigFile(); - - // deinit GFX - GFX_deinit(); - } - // search for a bootable firmware (all slots) - if (g_continueBootloader && !g_startFirmLaunch) + // show menu if either bootmode is normal or HOME is held + // ... or not if we already got a firmware waiting in line + show_menu = show_menu || + (!g_startFirmLaunch && ((bootmode == BootModeNormal) || hidIsHomeButtonHeldRaw())); + + + // main loop + PrintConsole term_con; + while(!g_startFirmLaunch) { - for(u32 i = 0; (i < 3) && !g_startFirmLaunch; i++) + // init screens (if we'll need them below) + if((show_menu || err_string) && !gfx_initialized) { - if(!configDataExist(KBootOption1 + i)) - continue; + GFX_init(); + // init and select terminal console + consoleInit(SCREEN_TOP, &term_con, true); + consoleSelect(&term_con); + gfx_initialized = true; + } + + // if there is an error, output it to screen + if (err_string) + { + ee_printf("%s\nPress B or HOME to enter menu.\n", err_string); + updateScreens(); + outputEndWait(); - char* path = (char*) configGetData(KBootOption1 + i); - g_startFirmLaunch = (loadVerifyFirm(path, false) >= 0); + show_menu = true; + free(err_string); + err_string = NULL; + + if(hidGetPowerButton(false)) break; + } + + // menu specific code + if(show_menu) + { + // init menu console + PrintConsole menu_con; + consoleInit(SCREEN_SUB, &menu_con, false); + + // run menu + g_continueBootloader = false; + menuProcess(&menu_con, &term_con, menu_fb3ds); + + // clear consoles and screen + consoleSelect(&menu_con); + consoleClear(); + consoleSelect(&term_con); + consoleClear(); + updateScreens(); + + // write config (if something changed) + if (configHasChanged()) writeConfigFile(); + + // check POWER button + if(hidGetPowerButton(false)) break; + } + + // search for a bootable firmware (all slots) + if (g_continueBootloader && !g_startFirmLaunch) + { + err_string = (char*) malloc(512); + char* err_ptr = err_string; + if(!err_string) panicMsg("Out of memory"); + + err_ptr += ee_sprintf(err_ptr, "Continuing bootloader...\n"); + for(u32 i = 0; (i < 3) && !g_startFirmLaunch; i++) + { + if(!configDataExist(KBootOption1 + i)) + continue; + + char* path = (char*) configGetData(KBootOption1 + i); + err_ptr += ee_sprintf(err_ptr, "Trying boot slot #%lu.\nBoot path is %s\n", (i+1), path); + g_startFirmLaunch = (loadVerifyFirm(path, false) >= 0); + err_ptr += ee_sprintf(err_ptr, "Load slot #%lu %s.\n", (i+1), g_startFirmLaunch ? "success" : "failed"); + break; + } + + if (!g_startFirmLaunch) + { + err_ptr += ee_sprintf(err_ptr, "Firmware not loaded!\nAre boot slots properly set up?\n"); + } + else + { + free(err_string); + err_string = NULL; + } } } + + // deinit GFX if it was initialized + if(gfx_initialized) GFX_deinit(); + // deinit filesystem fsUnmountAll(); + + // free memory (should already be free at this time) + if(err_string) free(err_string); + + // power off + if(hidGetPowerButton(true)) power_off(); // firm launch if(g_startFirmLaunch) firmLaunch(); - // power off - power_off(); + // reaching here was never intended.... return 0; } diff --git a/source/arm11/menu/menu.c b/source/arm11/menu/menu.c index 8b761e4..8ea648f 100644 --- a/source/arm11/menu/menu.c +++ b/source/arm11/menu/menu.c @@ -23,15 +23,73 @@ #include "types.h" #include "arm11/menu/menu.h" #include "arm11/menu/menu_util.h" +#include "arm11/menu/menu_color.h" #include "arm11/hardware/hid.h" #include "arm11/config.h" #include "arm11/console.h" +#include "arm11/debug.h" #include "arm11/fmt.h" #include "arm11/main.h" #include "hardware/gfx.h" +void menuBuildDescString(char* desc, u32 flags, u32 index, const char* desc_raw) +{ + char* desc_ptr = desc; + + // copy raw description + desc_ptr += ee_sprintf(desc_ptr, desc_raw); + + + // flags only concern descriptions right now + u32 slot = (flags & MENU_FLAG_SLOTS) ? index : + (flags & MENU_FLAG_SLOT(1)) ? 0 : + (flags & MENU_FLAG_SLOT(2)) ? 1 : + (flags & MENU_FLAG_SLOT(3)) ? 2 : (u32) -1; + + // boot mode description + if ((flags & MENU_FLAG_BOOTMODE) && (index == 3)) + { + if (configDataExist(KBootMode)) + { + char* modestr = (char*) configCopyText(KBootMode); + if (!modestr) panicMsg("Config error"); + desc_ptr += ee_sprintf(desc_ptr, "\n \ncurrent: %s", modestr); + free (modestr); + } + else desc_ptr += ee_sprintf(desc_ptr, "\n \ncurrent: - not set up -"); + } + // boot slot description + else if (slot < 3) + { + // get strings for path and keycombo + char slot_path_store[24+1]; + char* slot_path = NULL; + char* keycombo = NULL; + + if(configDataExist(KBootOption1 + slot)) + { + slot_path = slot_path_store; + truncateString(slot_path, (char*) configGetData(KBootOption1 + slot), 24, 8); + } + + if(configDataExist(KBootOption1Buttons + slot)) + keycombo = (char*) configCopyText(KBootOption1Buttons + slot); + + // write description to desc string + desc_ptr += ee_sprintf(desc_ptr, "\n \npath: %s\nkeys: %s", + slot_path ? slot_path : "- not set up -", + keycombo ? keycombo : "- not set up -"); + + if (keycombo) free(keycombo); + } + + + // wordwrap the whole string + stringWordWrap(desc, WORDWRAP_WIDTH); +} + void menuShowDesc(MenuInfo* curr_menu, PrintConsole* desc_con, u32 index) { // select and clear description console @@ -41,7 +99,7 @@ // print title at the top const char* title = "fastboot 3DS " VERS_STRING; consoleSetCursor(desc_con, (desc_con->consoleWidth - strlen(title)) >> 1, 1); - ee_printf(title); + ee_printf(ESC_SCHEME_ACCENT0 "%s" ESC_RESET, title); // get description, check if available MenuEntry* entry = &(curr_menu->entries[index]); @@ -53,58 +111,8 @@ return; // build description string - // also handle MENU_FLAG_SLOTS flag char desc_ww[512]; - if (curr_menu->flags & 0xF) // includes all known flags - { - // flags only concern descriptions right now - char slot_path_store[24+1]; - char* slot_path = NULL; - char* keycombo = NULL; - u32 flags = curr_menu->flags; - u32 slot = (flags & MENU_FLAG_SLOTS) ? index : - (flags & MENU_FLAG_SLOT(1)) ? 0 : - (flags & MENU_FLAG_SLOT(2)) ? 1 : - (flags & MENU_FLAG_SLOT(3)) ? 2 : (u32) -1; - - if (slot < 3) - { - if(configDataExist(KBootOption1 + slot)) - { - slot_path = slot_path_store; - truncateString(slot_path, (char*) configGetData(KBootOption1 + slot), 24, 8); - } - - if (configDataExist(KBootOption1Buttons + slot)) - keycombo = (char*) configCopyText(KBootOption1Buttons + slot); - - if (flags & MENU_FLAG_SLOTS) - { - if (slot_path && keycombo) - ee_snprintf(desc_ww, 512, "%s\nCurrent: %s\nButtons: %s", desc, slot_path, keycombo); - else if (slot_path) - ee_snprintf(desc_ww, 512, "%s\nCurrent: %s", desc, slot_path); - else strncpy(desc_ww, desc, 512); - } - else - { - if (((index == 0) || (index == 2)) && slot_path) - ee_snprintf(desc_ww, 512, "%s\nCurrent: %s", desc, slot_path); - else if ((index == 1) && keycombo) - ee_snprintf(desc_ww, 512, "%s\nCurrent: %s", desc, keycombo); - else strncpy(desc_ww, desc, 512); - } - - if (keycombo) free(keycombo); - } else strncpy(desc_ww, desc, 512); - } - else - { - strncpy(desc_ww, desc, 512); - } - - // wordwrap description string - stringWordWrap(desc_ww, WORDWRAP_WIDTH); + menuBuildDescString(desc_ww, curr_menu->flags, index, desc); // get width, height int desc_width = stringGetWidth(desc_ww); @@ -117,12 +125,14 @@ int desc_y = (desc_con->consoleHeight - 2 - desc_height); consoleSetCursor(desc_con, desc_x, desc_y++); - ee_printf("%s:", name); + ee_printf(ESC_SCHEME_ACCENT1 "%s:\n" ESC_RESET, name); + ee_printf(ESC_SCHEME_WEAK); for (char* str = strtok(desc_ww, "\n"); str != NULL; str = strtok(NULL, "\n")) { consoleSetCursor(desc_con, desc_x, desc_y++); ee_printf(str); } + ee_printf(ESC_RESET); } /** @@ -149,7 +159,7 @@ // menu title consoleSetCursor(menu_con, menu_x, menu_y++); - ee_printf(curr_menu->name); + ee_printf(ESC_SCHEME_ACCENT1 "%s" ESC_RESET, curr_menu->name); menu_y++; // menu entries @@ -160,14 +170,17 @@ bool is_selected = (i == index); consoleSetCursor(menu_con, menu_x, menu_y++); - ee_printf(is_selected ? "\x1b[47;30m%.3s %-*.*s\x1b[0m" : "%.3s %-*.*s", - ((menu_preset >> i) & 0x1) ? "[X]" : "[ ]", MENU_WIDTH-4, MENU_WIDTH-4, name); + // ee_printf(((menu_preset >> i) & 0x1) ? ESC_SCHEME_STD : ESC_SCHEME_WEAK); + ee_printf(ESC_SCHEME_STD); + if (is_selected) ee_printf(ESC_INVERT); + ee_printf("%.3s %-*.*s", ((menu_preset >> i) & 0x1) ? "[X]" : "[ ]", MENU_WIDTH-4, MENU_WIDTH-4, name); + ee_printf(ESC_RESET); } // button instructions menu_y = MENU_OFFSET_BUTTONS; consoleSetCursor(menu_con, menu_x, menu_y++); - ee_printf("%-*.*s", MENU_WIDTH, MENU_WIDTH, "[A]:Choose [B]:Back"); + ee_printf(ESC_SCHEME_WEAK "%-*.*s" ESC_RESET, MENU_WIDTH, MENU_WIDTH, "[A]:Choose [B]:Back"); } /** @@ -196,13 +209,13 @@ last_menu = curr_menu; GX_textureCopy((u64*)RENDERBUF_TOP, 0, (u64*)GFX_getFramebuffer(SCREEN_TOP), - 0, SCREEN_SIZE_TOP + SCREEN_SIZE_SUB); + 0, SCREEN_SIZE_TOP + SCREEN_SIZE_SUB); GFX_swapFramebufs(); } GFX_waitForEvent(GFX_EVENT_PDC0, true); // VBlank // handle power button - if(hidGetPowerButton(true)) + if(hidGetPowerButton(false)) break; // deinits & poweroff outside of this function hidScanInput(); @@ -230,7 +243,7 @@ { // call menu entry function MenuEntry* entry = &(curr_menu->entries[index]); - (*(entry->function))(desc_con, entry->param); + (*(entry->function))(desc_con, menu_con, entry->param); // force redraw (somewhat hacky) last_menu = NULL; } diff --git a/source/arm11/menu/menu_fsel.c b/source/arm11/menu/menu_fsel.c index 56eae9c..40882a4 100644 --- a/source/arm11/menu/menu_fsel.c +++ b/source/arm11/menu/menu_fsel.c @@ -26,6 +26,7 @@ #include "fsutils.h" #include "arm11/menu/menu_fsel.h" #include "arm11/menu/menu_util.h" +#include "arm11/menu/menu_color.h" #include "arm11/hardware/hid.h" #include "arm11/hardware/timer.h" #include "arm11/console.h" @@ -250,9 +251,8 @@ // browser title consoleSetCursor(menu_con, brws_x, brws_y++); - truncateString(temp_str, curr_path, BRWS_WIDTH, 8); - if (!*temp_str) strncpy(temp_str, "[root]", BRWS_WIDTH); - ee_printf(temp_str); + truncateString(temp_str, *curr_path ? curr_path : "root", BRWS_WIDTH, 8); + ee_printf(ESC_SCHEME_ACCENT1 "%-*s" ESC_RESET, BRWS_WIDTH, temp_str); brws_y++; // menu entries @@ -272,16 +272,20 @@ consoleSetCursor(menu_con, brws_x, brws_y++); truncateString(temp_str, entry->fname, BRWS_WIDTH-13, 8); - ee_printf(is_selected ? "\x1b[47;30m %-*.*s %10.10s \x1b[0m" : " %-*.*s %10.10s ", - BRWS_WIDTH-13, BRWS_WIDTH-13, temp_str, byte_str); + ee_printf(entry->is_dir ? ESC_SCHEME_WEAK : ESC_SCHEME_STD); + if (is_selected)ee_printf(ESC_INVERT); + ee_printf(" %-*.*s %10.10s ", BRWS_WIDTH-13, BRWS_WIDTH-13, temp_str, byte_str); + ee_printf(ESC_RESET); } // button instructions brws_y = BRWS_OFFSET_BUTTONS; + ee_printf(ESC_SCHEME_WEAK); consoleSetCursor(menu_con, brws_x, brws_y++); ee_printf("%-*.*s", BRWS_WIDTH, BRWS_WIDTH, "[A]:Choose [B]:Back"); consoleSetCursor(menu_con, brws_x, brws_y++); ee_printf("%-*.*s", BRWS_WIDTH, BRWS_WIDTH, "[HOME] to cancel"); + ee_printf(ESC_RESET); } diff --git a/source/arm11/menu/menu_func.c b/source/arm11/menu/menu_func.c index db90912..8192f96 100644 --- a/source/arm11/menu/menu_func.c +++ b/source/arm11/menu/menu_func.c @@ -22,41 +22,23 @@ #include #include #include "types.h" +#include "arm11/menu/menu_color.h" #include "arm11/menu/menu_fsel.h" #include "arm11/menu/menu_util.h" #include "arm11/hardware/hid.h" #include "arm11/console.h" #include "arm11/config.h" +#include "arm11/debug.h" #include "arm11/fmt.h" #include "arm11/firm.h" #include "arm11/main.h" -void outputEndWait(void) -{ - u32 kDown = 0; - - do - { - GFX_waitForEvent(GFX_EVENT_PDC0, true); - - if(hidGetPowerButton(false)) // handle power button - break; - - hidScanInput(); - kDown = hidKeysDown(); - if (kDown & (KEY_SHELL)) sleepmode(); - } - while (!(kDown & (KEY_B|KEY_HOME))); -} - -void updateScreens(void) -{ - GX_textureCopy((u64*)RENDERBUF_TOP, 0, (u64*)GFX_getFramebuffer(SCREEN_TOP), - 0, SCREEN_SIZE_TOP + SCREEN_SIZE_SUB); - GFX_swapFramebufs(); - GFX_waitForEvent(GFX_EVENT_PDC0, true); // VBlank +#define PRESET_SLOT_CONFIG_FUNC(x) \ +u32 menuPresetSlotConfig##x(void) \ +{ \ + return menuPresetSlotConfig((x-1)); \ } u32 menuPresetBootMode(void) @@ -69,7 +51,7 @@ return 0; } -u32 menuPresetBootSlot(void) +u32 menuPresetBootMenu(void) { u32 res = 0; @@ -84,16 +66,45 @@ return res; } -u32 menuSetBootMode(PrintConsole* con, u32 param) +u32 menuPresetBootConfig(void) { - (void) con; + u32 res = 0; + + if (configDataExist(KBootMode)) + res |= 1 << 3; + + return res | menuPresetBootMenu(); +} + +u32 menuPresetSlotConfig(u32 slot) +{ + u32 res = 0; + + if (configDataExist(KBootOption1 + slot)) + res |= (1 << 0); + + if (configDataExist(KBootOption1Buttons + slot)) + res |= (1 << 1); + + return res; +} +PRESET_SLOT_CONFIG_FUNC(1) +PRESET_SLOT_CONFIG_FUNC(2) +PRESET_SLOT_CONFIG_FUNC(3) + +u32 menuSetBootMode(PrintConsole* term_con, PrintConsole* menu_con, u32 param) +{ + (void) term_con; + (void) menu_con; u32 res = (configSetKeyData(KBootMode, ¶m)) ? 0 : 1; return res; } -u32 menuSetupBootSlot(PrintConsole* con, u32 param) +u32 menuSetupBootSlot(PrintConsole* term_con, PrintConsole* menu_con, u32 param) { + (void) term_con; + bool slot = param & 0xF; char res_path[256]; char* start = NULL; @@ -110,19 +121,16 @@ start = (char*) configGetData(KBootOption1 + slot); u32 res = 0; - if (menuFileSelector(res_path, con, start, "*.firm")) + if (menuFileSelector(res_path, menu_con, start, "*.firm")) res = (configSetKeyData(KBootOption1 + slot, res_path)) ? 0 : 1; return res; } -static const char * convTable[] = { - "A", "B", "SELECT", "START", "RIGHT", "LEFT", - "UP", "DOWN", "R", "L", "X", "Y" -}; - -u32 menuSetupBootKeys(PrintConsole* con, u32 param) +u32 menuSetupBootKeys(PrintConsole* term_con, PrintConsole* menu_con, u32 param) { + (void) menu_con; + const u32 y_center = 7; const u32 y_instr = 21; @@ -133,39 +141,34 @@ { // build button string char button_str[80]; - char* ptr = button_str; - bool first = true; - for (u32 i = 0; i < 12; i++) - { - if (kHeld & (1<cursorY = y_center; + term_con->cursorY = y_center; + ee_printf(ESC_SCHEME_WEAK); ee_printf_line_center("Hold button(s) to setup."); ee_printf_line_center("Currently held buttons:"); + ee_printf(ESC_SCHEME_STD); ee_printf_line_center(button_str); + ee_printf(ESC_RESET); // draw instructions - con->cursorY = y_instr; + term_con->cursorY = y_instr; + ee_printf(ESC_SCHEME_WEAK); if (configDataExist(KBootOption1Buttons + param)) { char* currentSetting = (char*) configCopyText(KBootOption1Buttons + param); + if (!currentSetting) panicMsg("Config error"); ee_printf_line_center("Current: %s", currentSetting); free(currentSetting); } ee_printf_line_center("[HOME] to cancel"); + ee_printf(ESC_RESET); // update screens updateScreens(); @@ -203,7 +206,7 @@ return res; } -u32 menuLaunchFirm(PrintConsole* con, u32 param) +u32 menuLaunchFirm(PrintConsole* term_con, PrintConsole* menu_con, u32 param) { char path_store[256]; char* path; @@ -211,7 +214,7 @@ if (param < 3) // loading from bootslot { // clear console - consoleSelect(con); + consoleSelect(term_con); consoleClear(); // check if bootslot exists @@ -230,14 +233,14 @@ else if (param == 0xFF) // user decision { path = path_store; - if (!menuFileSelector(path, con, NULL, "*.firm")) + if (!menuFileSelector(path, menu_con, NULL, "*.firm")) return 1; } // clear console if (param >= 3) { - consoleSelect(con); + consoleSelect(term_con); consoleClear(); } @@ -264,37 +267,79 @@ return 1; } -u32 menuContinueBoot(PrintConsole* con, u32 param) +u32 menuContinueBoot(PrintConsole* term_con, PrintConsole* menu_con, u32 param) { // all the relevant stuff handled outside - (void) con; + (void) term_con; + (void) menu_con; (void) param; g_continueBootloader = true; return 0; } -u32 menuDummyFunc(PrintConsole* con, u32 param) +u32 menuDummyFunc(PrintConsole* term_con, PrintConsole* menu_con, u32 param) { - (void) param; + (void) menu_con; // clear console - consoleSelect(con); + consoleSelect(term_con); consoleClear(); // print something - ee_printf("\nThis is not implemented yet.\nGo look elsewhere, nothing to see here.\n\nPress B or HOME to return."); + ee_printf("This is not implemented yet.\nMy parameter was %lu.\nGo look elsewhere, nothing to see here.\n\nPress B or HOME to return.", param); updateScreens(); outputEndWait(); return 0; } -u32 SetView(PrintConsole* con, u32 param) +u32 menuShowCredits(PrintConsole* term_con, PrintConsole* menu_con, u32 param) { + (void) menu_con; (void) param; // clear console - consoleSelect(con); + consoleSelect(term_con); + consoleClear(); + + // credits + term_con->cursorY = 4; + ee_printf(ESC_SCHEME_ACCENT0); + ee_printf_line_center("Fastboot3DS Credits"); + ee_printf_line_center("==================="); + ee_printf_line_center(""); + ee_printf(ESC_SCHEME_STD); + ee_printf_line_center("Main developers:"); + ee_printf(ESC_SCHEME_WEAK); + ee_printf_line_center("derrek"); + ee_printf_line_center("profi200"); + ee_printf_line_center(""); + ee_printf(ESC_SCHEME_STD); + ee_printf_line_center("Thanks to:"); + ee_printf(ESC_SCHEME_WEAK); + ee_printf_line_center("yellows8"); + ee_printf_line_center("plutoo"); + ee_printf_line_center("smea"); + ee_printf_line_center("Normmatt (for sdmmc code)"); + ee_printf_line_center("WinterMute (for console code)"); + ee_printf_line_center("d0k3 (for menu code)"); + ee_printf_line_center(""); + ee_printf_line_center("... everyone who contributed to 3dbrew.org"); + updateScreens(); + + // wait for user + outputEndWait(); + + return 0; +} + +u32 debugSettingsView(PrintConsole* term_con, PrintConsole* menu_con, u32 param) +{ + (void) menu_con; + (void) param; + + // clear console + consoleSelect(term_con); consoleClear(); ee_printf("Write config: %s\n", writeConfigFile() ? "success" : "failed"); @@ -329,36 +374,43 @@ return 0; } -u32 menuShowCredits(PrintConsole* con, u32 param) +u32 debugEscapeTest(PrintConsole* term_con, PrintConsole* menu_con, u32 param) { + (void) menu_con; (void) param; // clear console - consoleSelect(con); + consoleSelect(term_con); consoleClear(); - // credits - con->cursorY = 4; - ee_printf_line_center("Fastboot3DS Credits"); - ee_printf_line_center("==================="); - ee_printf_line_center(""); - ee_printf_line_center("Main developers:"); - ee_printf_line_center("derrek"); - ee_printf_line_center("profi200"); - ee_printf_line_center(""); - ee_printf_line_center("Thanks to:"); - ee_printf_line_center("yellows8"); - ee_printf_line_center("plutoo"); - ee_printf_line_center("smea"); - ee_printf_line_center("Normmatt (for sdmmc code)"); - ee_printf_line_center("WinterMute (for console code)"); - ee_printf_line_center("d0k3 (for menu code)"); - ee_printf_line_center(""); - ee_printf_line_center("... everyone who contributed to 3dbrew.org"); - updateScreens(); - - // wait for user - outputEndWait(); + ee_printf("\x1b[1mbold\n\x1b[0m"); + ee_printf("\x1b[2mfaint\n\x1b[0m"); + ee_printf("\x1b[3mitalic\n\x1b[0m"); + ee_printf("\x1b[4munderline\n\x1b[0m"); + ee_printf("\x1b[5mblink slow\n\x1b[0m"); + ee_printf("\x1b[6mblink fast\n\x1b[0m"); + ee_printf("\x1b[7mreverse\n\x1b[0m"); + ee_printf("\x1b[8mconceal\n\x1b[0m"); + ee_printf("\x1b[9mcrossed-out\n\x1b[0m"); + ee_printf("\n"); + + for (u32 i = 0; i < 8; i++) + { + char c[8]; + ee_snprintf(c, 8, "\x1b[%lu", 30 + i); + ee_printf("color #%lu: %smnormal\x1b[0m %s;2mfaint\x1b[0m %s;4munderline\x1b[0m %s;7mreverse\x1b[0m %s;9mcrossed-out\x1b[0m\n", i, c, c, c, c, c); + } + + // wait for B / HOME button + do + { + updateScreens(); + if(hidGetPowerButton(false)) // handle power button + return 0; + + hidScanInput(); + } + while (!(hidKeysDown() & (KEY_B|KEY_HOME))); return 0; } diff --git a/source/arm11/menu/menu_util.c b/source/arm11/menu/menu_util.c index bbe6894..1fc938d 100644 --- a/source/arm11/menu/menu_util.c +++ b/source/arm11/menu/menu_util.c @@ -20,9 +20,10 @@ #include #include "types.h" #include "arm11/hardware/hid.h" +#include "arm11/hardware/interrupt.h" +#include "arm11/menu/menu_util.h" #include "arm11/console.h" #include "arm11/fmt.h" -#include "arm11/hardware/interrupt.h" char* mallocpyString(const char* str) @@ -36,40 +37,61 @@ void truncateString(char* dest, const char* orig, int nsize, int tpos) { - int osize = strlen(orig); + int osize = strlen(orig); - if (nsize < 0) + if (nsize < 0) { - return; - } else if (nsize <= 3) + return; + } else if (nsize <= 3) { - ee_snprintf(dest, nsize, orig); - } else if (nsize >= osize) + ee_snprintf(dest, nsize, orig); + } else if (nsize >= osize) { - ee_snprintf(dest, nsize + 1, orig); - } else + ee_snprintf(dest, nsize + 1, orig); + } else { - if (tpos + 3 > nsize) tpos = nsize - 3; - ee_snprintf(dest, nsize + 1, "%-.*s...%-.*s", tpos, orig, nsize - (3 + tpos), orig + osize - (nsize - (3 + tpos))); - } + if (tpos + 3 > nsize) tpos = nsize - 3; + ee_snprintf(dest, nsize + 1, "%-.*s...%-.*s", tpos, orig, nsize - (3 + tpos), orig + osize - (nsize - (3 + tpos))); + } } void formatBytes(char* str, u64 bytes) { // str should be 32 byte in size, just to be safe - const char* units[] = {" Byte", " kiB", " MiB", " GiB"}; - - if (bytes < 1024) + const char* units[] = {" Byte", " kiB", " MiB", " GiB"}; + + if (bytes < 1024) { ee_snprintf(str, 32, "%llu%s", bytes, units[0]); } - else + else { - u32 scale = 1; - u64 bytes100 = (bytes * 100) >> 10; - for(; (bytes100 >= 1024*100) && (scale < 3); scale++, bytes100 >>= 10); - ee_snprintf(str, 32, "%llu.%llu%s", bytes100 / 100, (bytes100 % 100) / 10, units[scale]); - } + u32 scale = 1; + u64 bytes100 = (bytes * 100) >> 10; + for(; (bytes100 >= 1024*100) && (scale < 3); scale++, bytes100 >>= 10); + ee_snprintf(str, 32, "%llu.%llu%s", bytes100 / 100, (bytes100 % 100) / 10, units[scale]); + } +} + +static const char * convTable[] = { + "A", "B", "SELECT", "START", "RIGHT", "LEFT", + "UP", "DOWN", "R", "L", "X", "Y" +}; + +void keysToString(u32 keys, char* string) +{ + char* ptr = string; + bool first = true; + for (u32 i = 0; i < 12; i++) + { + if (keys & (1<read_sector(sector, 1, (void*)FIRM_LOAD_ADDR)) return -4; if(!firm_size((size_t*)&firmSize)) return -5; sector++; - if(!dev_decnand->read_sector(sector, (firmSize>>9) - 1, (void*)(FIRM_LOAD_ADDR + 0x200))) return -4; + if(!dev_decnand->read_sector(sector, (firmSize>>9) - 1, (void*)(FIRM_LOAD_ADDR + sizeof(firm_header)))) + return -4; } else { diff --git a/source/arm9/hardware/crypto.c b/source/arm9/hardware/crypto.c index 9e7af96..89a4f22 100644 --- a/source/arm9/hardware/crypto.c +++ b/source/arm9/hardware/crypto.c @@ -61,15 +61,6 @@ #define REG_AESKEYYFIFO ((vu32*)(AES_REGS_BASE + 0x108)) -/*static void deriveKey(u32 pad[4], u32 boot9Off) -{ - const u32 *pad2 = (u32*)(BOOT9_BASE + boot9Off); - - pad[0] ^= pad2[0]; - pad[1] ^= pad2[1]; - pad[2] ^= pad2[2]; - pad[3] ^= pad2[3]; -}*/ static void setupKeys(void) { diff --git a/source/arm9/partitions.c b/source/arm9/partitions.c index bc27f93..4a0fa6d 100644 --- a/source/arm9/partitions.c +++ b/source/arm9/partitions.c @@ -33,7 +33,9 @@ static inline int findPartition(const char *name) { size_t namelen = strlen(name); - + + if(namelen >= 1 && name[namelen - 1] == ':') namelen--; + for(size_t i=0; iis_active() || !dev_sdcard->initialized) stat = STA_NOINIT; + if(!dev_sdcard->is_active()) stat = STA_NOINIT; break; case FATFS_DEV_NUM_TWL_NAND: if(!dev_decnand->is_active()) stat = STA_NOINIT;