diff --git a/include/arm11/menu.h b/include/arm11/menu.h index 66d04ab..04b2bc9 100644 --- a/include/arm11/menu.h +++ b/include/arm11/menu.h @@ -19,12 +19,14 @@ */ #include "types.h" +#include "arm11/console.h" #define MENU_MAX_ENTRIES 12 #define MENU_MAX_DEPTH 4 -#define MENU_WIDTH 34 -#define WORDWRAP_WIDTH 34 +#define MENU_DISP_Y -2 +#define MENU_WIDTH 28 +#define WORDWRAP_WIDTH 58 #define MENU_EXIT_REBOOT 0 #define MENU_EXIT_POWEROFF 1 @@ -35,7 +37,7 @@ typedef struct { char* name; ///< Displayed name of the menu entry. char* desc; ///< Description for menu entry. - u32 (*function)(u32 param); ///< Function called by menu entry. + u32 (*function)(PrintConsole *con, u32 param); ///< Function called by menu entry. u32 param; ///< Paramater for menu entry function / if function == NULL, offset to is_sub_menu. } MenuEntry; @@ -48,4 +50,4 @@ MenuEntry entries[MENU_MAX_ENTRIES]; ///< An array of menu entries. } MenuInfo; -u32 menuProcess(MenuInfo* info); +u32 menuProcess(PrintConsole* menu_con, PrintConsole* desc_con, MenuInfo* info); diff --git a/include/arm11/menu_fb3ds.h b/include/arm11/menu_fb3ds.h index 8dfa04e..72abfb2 100644 --- a/include/arm11/menu_fb3ds.h +++ b/include/arm11/menu_fb3ds.h @@ -26,59 +26,62 @@ #define DESC_CONTINUE "Continue booting the first available boot slot.\nNo function if boot slots are not set up or firmware not found." #define DESC_BOOT_MENU "Display a boot menu, allowing you to select which boot slot to boot from." -#define DESC_LAUNCH "Select a firmware to launch." #define DESC_NAND_TOOLS "Enter NAND tools submenu, including tools for NAND backup, NAND restore and firmware flash." -#define DESC_OPTIONS "Enter FastBoot3DS options submenu." -#define DESC_UPDATE "Update FastBoot3DS. Only signed updates are allowed." -#define DESC_CREDITS "Show FastBoot3DS credits." +#define DESC_OPTIONS "Enter fastboot3ds options submenu." +#define DESC_UPDATE "Update fastboot3ds. Only signed updates are allowed." +#define DESC_CREDITS "Show fastboot3ds credits." #define DESC_NAND_BACKUP "Backup current NAND to a file." -#define DESC_NAND_RESTORE "Restore current NAND from a file.\nThis option preserves your FastBoot3DS installation." -#define DESC_NAND_RESTORE_F "Restore current NAND from a file.\nWARNING: This will overwrite all of your flash memory, also overwriting FastBoot3DS installation." -#define DESC_FIRM_FLASH "Flash firmware from file.\nWARNING: This will allow you to flash unsigned firmware, overwriting FastBoot3DS. Using unsupported firmware can BRICK your console." +#define DESC_NAND_RESTORE "Restore current NAND from a file.\nThis option preserves your fastboot3ds installation." +#define DESC_NAND_RESTORE_F "Restore current NAND from a file.\nWARNING: This will overwrite all of your flash memory, also overwriting fastboot3ds installation." +#define DESC_FIRM_FLASH "Flash firmware from file.\nWARNING: This will allow you to flash unsigned firmware, overwriting fastboot3ds. Using unsupported firmware can BRICK your console." -#define DESC_CHANGE_BOOT "Change FastBoot3DS boot mode. This allows you to set up how your console boots." -#define DESC_CHANGE_SLOT "Setup FastBoot3DS boot slots." -#define DESC_CHANGE_BRIGHT "Change FastBood3DS brightness. This may also affect firmware launched from within FastBoot3DS" -#define DESC_SET_CONTIG "Enable/disable contiguous NAND backups. Contiguous NAND backups may be required on certain CFWS to be bootable from SD cards" +#define DESC_CHANGE_BOOT "Change fastboot3ds boot mode. This allows you to set up how your console boots." +#define DESC_CHANGE_SLOT "Setup fastboot3ds boot slots." +#define DESC_CHANGE_BRIGHT "Change FastBood3DS brightness. This may also affect firmware launched from within fastboot3ds" +#define DESC_SET_CONTIG "Enable/disable contiguous NAND backups.\nContiguous NAND backups may be required on certain CFWS to be bootable from SD cards." -#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 a key combo." -#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 a key combo." +#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 a key combo." +#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 a key combo." -#define DESC_SLOT_1 "Setup boot slot #1" -#define DESC_SLOT_2 "Setup boot slot #2" -#define DESC_SLOT_3 "Setup boot slot #3" +#define DESC_SET_SLOT_1 "Setup boot slot #1." +#define DESC_SET_SLOT_2 "Setup boot slot #2." +#define DESC_SET_SLOT_3 "Setup boot slot #3." -#define DESC_ENABLE_CONTIG "Enable contiguous NAND backups. Contiguous NAND backups may be required on certain CFWS to be bootable from SD cards" -#define DESC_DISABLE_CONTIG "Disable contiguous NAND backups. Contiguous NAND backups may be required on certain CFWS to be bootable from SD cards" +#define DESC_ENABLE_CONTIG "Select to enable contiguous NAND backups." +#define DESC_DISABLE_CONTIG "Select to disable contiguous NAND backups." + +#define DESC_BOOT_SLOT_1 "Boot slot #1." +#define DESC_BOOT_SLOT_2 "Boot slot #2." +#define DESC_BOOT_SLOT_3 "Boot slot #3." +#define DESC_BOOT_FILE "Select a firmware to boot." MenuInfo menu_fb3ds[] = { { - "FastBoot3DS Main Menu", 7, + "fastboot3ds Main Menu", 5, { { "Continue boot", DESC_CONTINUE, &DummyFunc, 0 }, - { "Boot menu..", DESC_BOOT_MENU, &DummyFunc, 0 }, - { "Launch firmware...", DESC_LAUNCH, &DummyFunc, 1 }, + { "Boot menu..", DESC_BOOT_MENU, NULL, 6 }, { "NAND tools...", DESC_NAND_TOOLS, NULL, 1 }, { "Options...", DESC_OPTIONS, NULL, 2 }, - { "Update...", DESC_UPDATE, &DummyFunc, 1 }, { "Credits", DESC_CREDITS, &DummyFunc, 3 } } }, { - "FastBoot3DS NAND tools", 4, + "fastboot3ds NAND tools", 5, { { "Backup NAND", DESC_NAND_BACKUP, &DummyFunc, 3 }, { "Restore NAND", DESC_NAND_RESTORE, &DummyFunc, 4 }, { "Restore NAND (forced)", DESC_NAND_RESTORE_F, &DummyFunc, 4 }, - { "Flash firmware", DESC_FIRM_FLASH, &DummyFunc, 2 } + { "Flash firmware", DESC_FIRM_FLASH, &DummyFunc, 2 }, + { "Update fastboot3DS", DESC_UPDATE, &DummyFunc, 1 } } }, { - "FastBoot3DS options", 4, + "fastboot3ds options", 4, { { "Change boot mode", DESC_CHANGE_BOOT, NULL, 3 }, { "Setup boot slot", DESC_CHANGE_SLOT, NULL, 4 }, @@ -87,7 +90,7 @@ } }, { - "FastBoot3DS boot mode", 3, + "fastboot3ds boot mode", 3, { { "Set normal boot", DESC_BOOT_NORMAL, &DummyFunc, 0 }, { "Set quick boot", DESC_BOOT_QUICK, &DummyFunc, 1 }, @@ -95,18 +98,27 @@ } }, { - "FastBoot3DS boot slots", 3, + "fastboot3ds boot slots", 3, { - { "Setup [slot 1]...", DESC_SLOT_1, &DummyFunc, 0 }, - { "Setup [slot 2]...", DESC_SLOT_2, &DummyFunc, 1 }, - { "Setup [slot 3]...", DESC_SLOT_3, &DummyFunc, 2 } + { "Setup [slot 1]...", DESC_SET_SLOT_1, &DummyFunc, 0 }, + { "Setup [slot 2]...", DESC_SET_SLOT_2, &DummyFunc, 1 }, + { "Setup [slot 3]...", DESC_SET_SLOT_3, &DummyFunc, 2 } } }, { - "FastBoot3DS backup setting", 2, + "fastboot3ds backup setting", 2, { { "Enable contiguous backups", DESC_ENABLE_CONTIG, &DummyFunc, 1 }, { "Disable contiguous backups", DESC_DISABLE_CONTIG, &DummyFunc, 0 } } + }, + { + "fastboot3ds boot menu", 4, + { + { "Boot [slot 1]", DESC_BOOT_SLOT_1, &DummyFunc, 0 }, + { "Boot [slot 2]", DESC_BOOT_SLOT_2, &DummyFunc, 1 }, + { "Boot [slot 3]", DESC_BOOT_SLOT_3, &DummyFunc, 2 }, + { "Boot from file...", DESC_BOOT_FILE, &DummyFunc, 3 } + } } }; diff --git a/include/arm11/menu_func.h b/include/arm11/menu_func.h index 8ba69ea..5397b95 100644 --- a/include/arm11/menu_func.h +++ b/include/arm11/menu_func.h @@ -20,4 +20,4 @@ #include "types.h" -u32 DummyFunc(u32 param); +u32 DummyFunc(PrintConsole* con, u32 param); diff --git a/source/arm11/main.c b/source/arm11/main.c index c01d1e4..35ad5fe 100644 --- a/source/arm11/main.c +++ b/source/arm11/main.c @@ -41,12 +41,22 @@ hardwareInit(); GFX_init(); - menuProcess(menu_fb3ds); - /* ee_puts("Hello from ARM11! aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); */ + + // 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 + menuProcess(&menu_con, &desc_con, menu_fb3ds); + + // power off + if(g_poweroffAllowed) power_off(); - while(!g_startFirmLaunch) + /*while(!g_startFirmLaunch) { waitForInterrupt(); @@ -77,7 +87,7 @@ GFX_deinit(); // TODO: Let ARM9 decide when to deinit gfx - firm_launch(); + firm_launch();*/ return 0; } diff --git a/source/arm11/menu.c b/source/arm11/menu.c index b81a32a..1806a88 100644 --- a/source/arm11/menu.c +++ b/source/arm11/menu.c @@ -22,6 +22,7 @@ #include "arm11/hardware/hid.h" #include "arm11/console.h" #include "arm11/fmt.h" +#include "arm11/power.h" #include "hardware/gfx.h" @@ -68,19 +69,27 @@ void menuShowDesc(MenuInfo* curr_menu, PrintConsole* desc_con, u32 index) { - MenuEntry* entry = &(curr_menu->entries[index]); - char* desc = entry->desc; - // select and clear description console consoleSelect(desc_con); consoleClear(); + // 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); + + // get description, check if available + MenuEntry* entry = &(curr_menu->entries[index]); + char* name = entry->name; + char* desc = entry->desc; + // done if no description available - if (!desc) + if (!name || !desc) { return; } + // word wrap description string char desc_ww[512]; strncpy(desc_ww, desc, 512); @@ -94,7 +103,11 @@ // write to console int desc_x = (desc_con->consoleWidth - desc_width) >> 1; - int desc_y = (desc_con->consoleHeight - desc_height) >> 1; + int desc_y = (desc_con->consoleHeight - 2 - desc_height); + + consoleSetCursor(desc_con, desc_x, desc_y++); + ee_printf("[%s]", name); + for (char* str = strtok(desc_ww, "\n"); str != NULL; str = strtok(NULL, "\n")) { consoleSetCursor(desc_con, desc_x, desc_y++); ee_printf(str); @@ -110,9 +123,9 @@ */ void menuDraw(MenuInfo* curr_menu, PrintConsole* menu_con, u32 index, bool is_sub_menu) { - const u32 menu_block_height = curr_menu->n_entries + 5; + const u32 menu_block_height = curr_menu->n_entries + 2; // +2 for title and separator int menu_x = (menu_con->consoleWidth - MENU_WIDTH) >> 1; - int menu_y = (menu_con->consoleHeight - menu_block_height) >> 1; + int menu_y = MENU_DISP_Y + ((menu_con->consoleHeight - menu_block_height) >> 1); // select menu console consoleSelect(menu_con); @@ -139,26 +152,27 @@ // second separator consoleSetCursor(menu_con, menu_x, menu_y++); - ee_printf("%*.*s", MENU_WIDTH, MENU_WIDTH, "============================================================"); + // ee_printf("%*.*s", MENU_WIDTH, MENU_WIDTH, "============================================================"); + // button descriptions (A/B) - consoleSetCursor(menu_con, menu_x, menu_y++); + /*consoleSetCursor(menu_con, menu_x, menu_y++); ee_printf(is_sub_menu ? "A: Choose B: Return" : "A: Choose"); // button descriptions (START) consoleSetCursor(menu_con, menu_x, menu_y++); - ee_printf("START: Reboot / [+\x1B] Poweroff"); + ee_printf("POWER for poweroff");*/ } /** * @brief Processes and displays the menu and user input. - * @param info A complete description of the menu. * @param menu_con Console that the menu is displayed on. * @param desc_con Console that the description is displayed on. + * @param info A complete description of the menu. */ -u32 menuProcess(MenuInfo* info) +u32 menuProcess(PrintConsole* menu_con, PrintConsole* desc_con, MenuInfo* info) { MenuInfo* curr_menu = info; MenuInfo* last_menu = NULL; @@ -169,20 +183,12 @@ u32 last_index = (u32) -1; u32 result = MENU_EXIT_REBOOT; - // init menu console - PrintConsole menu_con; - consoleInit(SCREEN_SUB, &menu_con, false); - - // init description console - PrintConsole desc_con; - consoleInit(SCREEN_TOP, &desc_con, false); - // main menu processing loop while (true) { // update menu and description (on demand) if ((index != last_index) || (curr_menu != last_menu)) { - menuDraw(curr_menu, &menu_con, index, menu_lvl); - menuShowDesc(curr_menu, &desc_con, index); + menuDraw(curr_menu, menu_con, index, menu_lvl); + menuShowDesc(curr_menu, desc_con, index); last_index = index; last_menu = curr_menu; @@ -192,6 +198,11 @@ } GFX_waitForEvent(GFX_EVENT_PDC0, true); // VBlank + if(hidGetPowerButton(true)) // handle power button + { + power_off(); + } + hidScanInput(); const u32 kDown = hidKeysDown(); const u32 kHeld = hidKeysHeld(); @@ -213,7 +224,7 @@ { // call menu entry function MenuEntry* entry = &(curr_menu->entries[index]); - (*(entry->function))(entry->param); + (*(entry->function))(desc_con, entry->param); // force redraw (somewhat hacky) last_menu = NULL; } diff --git a/source/arm11/menu_func.c b/source/arm11/menu_func.c index 251387d..682aa70 100644 --- a/source/arm11/menu_func.c +++ b/source/arm11/menu_func.c @@ -21,25 +21,53 @@ #include "arm11/console.h" #include "arm11/fmt.h" -u32 DummyFunc(u32 param) +// we need a better solution for this later (!!!) +void updateScreens(void) { - // init top console - PrintConsole top_con; - consoleInit(SCREEN_TOP, &top_con, true); - - // print something - ee_printf("Hello! I'm a dummy function.\nparam was %lu\n\nPress B to quit.", param); - GX_textureCopy((u64*)RENDERBUF_TOP, (240 * 2)>>4, (u64*)GFX_getFramebuffer(SCREEN_TOP), (240 * 2)>>4, SCREEN_SIZE_TOP + SCREEN_SIZE_SUB); GFX_swapFramebufs(); GFX_waitForEvent(GFX_EVENT_PDC0, true); // VBlank +} + +u32 DummyFunc(PrintConsole* con, u32 param) +{ + // clear console + consoleSelect(con); + consoleClear(); - // wait for A button - do { + // print something + ee_printf("Hello! I'm a dummy function.\nparam was %lu\n\nPress B to quit.\n\n", param); + updateScreens(); + + // wait for B button + do + { + if(hidGetPowerButton(false)) // handle power button + { + ee_printf("POWER button pressed.\nPress A to confirm cancel & poweroff.\n"); + updateScreens(); + + do + { + hidScanInput(); + } + while (!(hidKeysDown() & (KEY_A|KEY_B))); + + if (hidKeysDown() & KEY_B) + { + ee_printf("POWER off canceled, continuing...\n\n"); + updateScreens(); + hidGetPowerButton(true); + } + else + { + return 1; + } + } hidScanInput(); } - while (!(hidKeysHeld() & KEY_B)); + while (!(hidKeysDown() & KEY_B)); return 0; }