From cd9bf5aded47bf757ac1c3a73980a5147da50de2 Mon Sep 17 00:00:00 2001 From: chaoskagami Date: Sat, 4 Jun 2016 02:24:13 -0400 Subject: [PATCH] Separate menu logic from menu_options to allow reuse --- source/config.h | 92 +++++++++++++++++++++++++----------- source/display.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++ source/menu.c | 112 ++++---------------------------------------- 3 files changed, 192 insertions(+), 130 deletions(-) create mode 100644 source/display.c diff --git a/source/config.h b/source/config.h index cf5dcfd..23768cd 100644 --- a/source/config.h +++ b/source/config.h @@ -19,14 +19,23 @@ struct config_file // arbitrary limit - contact me if you hit it. } __attribute__((packed)); + +struct patch_state +{ + char filename[255]; + + uint8_t state; +} __attribute__((packed)); + extern struct config_file config; enum type { - boolean_val, // Toggle - ranged_val, // N1 - N2, left and right to pick. - mask_val, // Bitmask allowed values. - not_option // Skip over this. + boolean_val = 0, // Toggle + ranged_val = 1, // N1 - N2, left and right to pick. + mask_val = 2, // Bitmask allowed values. + not_option = 3, // Skip over this. + call_fun = 4 // Call a function. Treat (a) as (void)(*)(void). }; struct range_str @@ -42,41 +51,72 @@ struct options_s uint32_t a, b; } __attribute__((packed)); -#define OPTION_SIGPATCH 0 // Use builtin signature patch. -#define OPTION_FIRMPROT 1 // Protect firmware from writes. -#define OPTION_LOADER 2 // Use builtin loader module replacer. -#define OPTION_SERVICES 3 // Inject services (including backdoor for 11) -#define OPTION_ARM9THREAD 4 // Use builtin ARM9 thread injector. +// Use builtin loader module replacer. +#define OPTION_LOADER 2 -#define OPTION_AUTOBOOT 5 // Skip menu unless L is held. -#define OPTION_SILENCE 6 // Don't print debug information. -#define OPTION_TRACE 7 // Pause for A key on each step. +// Inject services (including backdoor for 11) +#define OPTION_SERVICES 3 + +// Use builtin ARM9 thread injector. +#define OPTION_ARM9THREAD 4 + +// Skip menu unless L is held. +#define OPTION_AUTOBOOT 5 + +// Don't print debug information. +#define OPTION_SILENCE 6 + +// Pause for A key on each step. +#define OPTION_TRACE 7 + +// Background color is not drawn under text. +#define OPTION_TRANSP_BG 8 -#define OPTION_TRANSP_BG 8 // Background color is not drawn under text. -#define OPTION_NO_CLEAR_BG 9 // Framebuffer is preserved from whatever ran before us. -#define OPTION_READ_ME 10 // Remove Help/Readme from menu. +#define OPTION_NO_CLEAR_BG 9 + +// Remove Help/Readme from menu. +#define OPTION_READ_ME 10 + +// Enable L2 cache. +#define OPTION_LOADER_CPU_L2 11 + +// Enable 800Mhz mode. +#define OPTION_LOADER_CPU_800MHZ 12 -#define OPTION_LOADER_CPU_L2 11 // Enable L2 cache. -#define OPTION_LOADER_CPU_800MHZ 12 // Enable 800Mhz mode. -#define OPTION_LOADER_LANGEMU 13 // Enable 800Mhz mode. +// Enable language emulation. +#define OPTION_LOADER_LANGEMU 13 +// Force replacement of services. Normally you don't want this. #define OPTION_REPLACE_ALLOCATED_SVC 14 -// Replace allocated services. Normally you don't want this. -#define IGNORE_PATCH_DEPS 14 // Ignore patch UUID dependencies. Not recommended. +// Ignore patch UUID dependencies. Not recommended. +#define IGNORE_PATCH_DEPS 14 + +// Allow enabling patches which are marked as 'incompatible'. Chances are there's a reason. #define IGNORE_BROKEN_SHIT 15 -// Allow enabling patches which are marked as 'incompatible'. Chances are -// there's a reason. + +// Save log files during boot and from loader. +// This will slow things down a bit. +#define OPTION_SAVE_LOGS 253 + +// Output so much debugging info, it'd make your head spin. +#define OPTION_OVERLY_VERBOSE 254 + +// This is for internal use only. It's set when any patches +// change and causes caches to be regenerated. +#define OPTION_RECONFIGURED 255 + +// TODO - Every option beyond here is a patch now, so once I get listing +// implemented, these shall go. + +#define OPTION_SIGPATCH 0 // Use builtin signature patch. +#define OPTION_FIRMPROT 1 // Protect firmware from writes. #define OPTION_AADOWNGRADE 16 // Anti-anti-downgrade. #define OPTION_MEMEXEC 17 // Prevent MPU from disabling execute permissions. #define OPTION_UNITINFO 18 // Dev UNITINFO. Note that this is overkill. -#define OPTION_OVERLY_VERBOSE 254 // So much debugging info, it'd make your head spin. -#define OPTION_RECONFIGURED 255 // This is for internal use only. It's set when any options - // change and causes caches to be regenerated. - //#define HEADER_COLOR 12 // Color of header text. //#define BG_COLOR 13 // Color of background. //#define TEXT_COLOR 14 // Color of most text. diff --git a/source/display.c b/source/display.c new file mode 100644 index 0000000..729c808 --- /dev/null +++ b/source/display.c @@ -0,0 +1,118 @@ +#include "common.h" +#include "firm/firm.h" +#include "firm/headers.h" +#define MENU_MAIN 1 + +#define MENU_OPTIONS 2 +#define MENU_PATCHES 3 +#define MENU_INFO 4 +#define MENU_HELP 5 +#define MENU_RESET 6 +#define MENU_POWER 7 +#define MENU_BOOTME 8 + +void header(char *append); + +int +show_menu(struct options_s *options, uint8_t* toggles) +{ + int cursor_y = 0; + int need_redraw = 1; + int cursor_min = -1; + int cursor_max = -1; + int exit = 0; + + while(!exit) { + set_cursor(TOP_SCREEN, 0, 0); + + // Figure out the max if unset. + if (cursor_max == -1) { + cursor_max = 0; + while (options[cursor_max].index != -1) + ++cursor_max; + + while (options[cursor_max].allowed == not_option) + --cursor_max; + } + + // Figure out the max if unset. + if (cursor_min == -1) { + cursor_min = 0; + while (options[cursor_min].allowed == not_option) + ++cursor_min; + cursor_y = cursor_min; + } + + header("A:Enter B:Back DPAD:Nav"); + + int i = 0; + while (options[i].index != -1) { // -1 Sentinel. + if (options[i].allowed == boolean_val) { + if (cursor_y == i) + fprintf(TOP_SCREEN, "\x1b[32m>>\x1b[0m "); + else + fprintf(TOP_SCREEN, " "); + + if (need_redraw) + fprintf(TOP_SCREEN, "[%c] %s\n", (toggles[options[i].index] ? 'X' : ' '), options[i].name); + else { + // Yes, this is weird. printf does a large number of extra things we + // don't + // want computed at the moment; this is faster. + putc(TOP_SCREEN, '['); + putc(TOP_SCREEN, (toggles[options[i].index] ? 'X' : ' ')); + putc(TOP_SCREEN, ']'); + putc(TOP_SCREEN, '\n'); + } + } else if (options[i].allowed == not_option) { + fprintf(TOP_SCREEN, "%s\n", options[i].name); + } + ++i; + } + + need_redraw = 0; + + uint32_t key = wait_key(); + + switch (key) { + case BUTTON_UP: + cursor_y -= 1; + while (options[cursor_y].allowed == not_option && cursor_y >= cursor_min) + cursor_y--; + break; + case BUTTON_DOWN: + cursor_y += 1; + while (options[cursor_y].allowed == not_option && cursor_y < cursor_max) + cursor_y++; + break; + case BUTTON_LEFT: + cursor_y -= 5; + while (options[cursor_y].allowed == not_option && cursor_y >= cursor_min) + cursor_y--; + break; + case BUTTON_RIGHT: + cursor_y += 5; + while (options[cursor_y].allowed == not_option && cursor_y < cursor_max) + cursor_y++; + break; + case BUTTON_A: + // FIXME - This needs to be part of the patch menu. +// toggles[OPTION_RECONFIGURED] = 1; + toggles[options[cursor_y].index] = !toggles[options[cursor_y].index]; + break; + case BUTTON_B: + exit = 1; + need_redraw = 1; + clear_screen(TOP_SCREEN); + cursor_y = cursor_min; + break; + } + + if (cursor_y < cursor_min) + cursor_y = cursor_max - 1; + else if (cursor_y > cursor_max - 1) + cursor_y = cursor_min; + } + + return 0; +} diff --git a/source/menu.c b/source/menu.c index d364b7e..addcb60 100644 --- a/source/menu.c +++ b/source/menu.c @@ -11,8 +11,6 @@ #define MENU_POWER 7 #define MENU_BOOTME 8 -#define OPTION_AADOWNGRADE 16 // Anti-anti-downgrade. - static struct options_s options[] = { // space { 0, "", not_option, 0, 0 }, @@ -66,8 +64,6 @@ static struct options_s options[] = { }; static int cursor_y = 0; -static int cursor_min = -1; -static int cursor_max = -1; static int which_menu = 1; static int need_redraw = 1; @@ -106,100 +102,14 @@ menu_patches() return MENU_MAIN; } +int show_menu(struct options_s *options, uint8_t* toggles); + int menu_options() { - set_cursor(TOP_SCREEN, 0, 0); - - // Figure out the max if unset. - if (cursor_max == -1) { - cursor_max = 0; - while (options[cursor_max].index != -1) - ++cursor_max; - - while (options[cursor_max].allowed == not_option) - --cursor_max; - } - - // Figure out the max if unset. - if (cursor_min == -1) { - cursor_min = 0; - while (options[cursor_min].allowed == not_option) - ++cursor_min; - cursor_y = cursor_min; - } - - header("A:Enter B:Back DPAD:Nav"); - - int i = 0; - while (options[i].index != -1) { // -1 Sentinel. - if (options[i].allowed == boolean_val) { - if (cursor_y == i) - fprintf(TOP_SCREEN, "\x1b[32m>>\x1b[0m "); - else - fprintf(TOP_SCREEN, " "); - - if (need_redraw) - fprintf(TOP_SCREEN, "[%c] %s\n", (config.options[options[i].index] ? 'X' : ' '), options[i].name); - else { - // Yes, this is weird. printf does a large number of extra things we - // don't - // want computed at the moment; this is faster. - putc(TOP_SCREEN, '['); - putc(TOP_SCREEN, (config.options[options[i].index] ? 'X' : ' ')); - putc(TOP_SCREEN, ']'); - putc(TOP_SCREEN, '\n'); - } - } else if (options[i].allowed == not_option) { - fprintf(TOP_SCREEN, "%s\n", options[i].name); - } - ++i; - } - - need_redraw = 0; - - uint32_t key = wait_key(); + show_menu(options, config.options); - switch (key) { - case BUTTON_UP: - cursor_y -= 1; - while (options[cursor_y].allowed == not_option && cursor_y >= cursor_min) - cursor_y--; - break; - case BUTTON_DOWN: - cursor_y += 1; - while (options[cursor_y].allowed == not_option && cursor_y < cursor_max) - cursor_y++; - break; - case BUTTON_LEFT: - cursor_y -= 5; - while (options[cursor_y].allowed == not_option && cursor_y >= cursor_min) - cursor_y--; - break; - case BUTTON_RIGHT: - cursor_y += 5; - while (options[cursor_y].allowed == not_option && cursor_y < cursor_max) - cursor_y++; - break; - case BUTTON_A: - // TODO - Value options - config.options[OPTION_RECONFIGURED] = 1; - config.options[options[cursor_y].index] = !config.options[options[cursor_y].index]; - break; - case BUTTON_B: - need_redraw = 1; - clear_screen(TOP_SCREEN); - cursor_y = cursor_min; - return MENU_MAIN; - break; - } - - if (cursor_y < cursor_min) - cursor_y = cursor_max - 1; - else if (cursor_y > cursor_max - 1) - cursor_y = cursor_min; - - return 0; + return MENU_MAIN; } int @@ -224,10 +134,7 @@ menu_info() "TWL_FIRM / DSi Firmware:\n" " Version: %s (%x)\n", native->version_string, native->version, agb->version_string, agb->version, twl->version_string, twl->version); - while (1) { - if (wait_key() & BUTTON_ANY) - break; - } + wait_key(); need_redraw = 1; clear_screen(TOP_SCREEN); @@ -260,10 +167,7 @@ menu_help() " \n" "\n"); - while (1) { - if (wait_key() & BUTTON_ANY) - break; - } + wait_key(); need_redraw = 1; clear_screen(TOP_SCREEN); @@ -277,7 +181,7 @@ menu_reset() fumount(); // Unmount SD. // Reboot. - fprintf(BOTTOM_SCREEN, "Resetting system.\n"); + fprintf(BOTTOM_SCREEN, "Rebooting system.\n"); i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); while (1) ; @@ -343,7 +247,7 @@ menu_main() return MENU_BOOTME; // Boot meh, damnit! clear_screen(TOP_SCREEN); if (ret == MENU_OPTIONS) - cursor_y = cursor_min; // Fixup positions + cursor_y = 0; // Fixup positions return ret; } -- 2.39.5