From 5241cccbe90bb4555d23e28287a7e29ebf450316 Mon Sep 17 00:00:00 2001 From: niklascfw Date: Thu, 12 Nov 2026 22:58:41 +0100 Subject: [PATCH] Share one selection menu; drop dead variant detection and TegraExplorer filter The variant menu in main.c and the RAM / Hekate-AMS menus in install.c were three copies of the same input loop; install_menu_select() replaces them with identical behaviour (D-pad/Vol to move, A/Power to confirm, Vol+ and Vol- to abort, Capture for screenshots). --- Makefile | 2 - source/install.c | 271 ++++++++++++++++------------------------------- source/install.h | 2 + source/main.c | 86 ++------------- source/version.c | 14 --- source/version.h | 2 - 6 files changed, 99 insertions(+), 278 deletions(-) diff --git a/Makefile b/Makefile index 53245f0..cb5f643 100644 --- a/Makefile +++ b/Makefile @@ -31,8 +31,6 @@ OBJS += $(patsubst $(BDKDIR)/%.S, $(BUILDDIR)/$(TARGET)/%.o, \ $(patsubst $(BDKDIR)/%.c, $(BUILDDIR)/$(TARGET)/%.o, \ $(call rwildcard, $(BDKDIR), *.S *.c))) -# Optional vendored tree under source/TegraExplorer/ is not part of this payload build. -OBJS := $(filter-out $(BUILDDIR)/$(TARGET)/TegraExplorer/%,$(OBJS)) GFX_INC := '"../$(SOURCEDIR)/gfx.h"' FFCFG_INC := '"../$(SOURCEDIR)/libs/fatfs/ffconf.h"' diff --git a/source/install.c b/source/install.c index e095586..fad9edf 100644 --- a/source/install.c +++ b/source/install.c @@ -582,8 +582,10 @@ static void install_joycon_reconnect(void) msleep(100); } -/* Same navigation as main.c multi-variant menu; returns false if user aborts (payload/reboot). */ -static bool install_ram_config_menu(bool *use_8gb) +/* Selection menu shared by main.c and the extras menus: draws the labels at the + * current cursor plus the key hints and returns the chosen index, or -1 when + * Vol+ and Vol- are pressed together. Only the two changed lines are redrawn. */ +int install_menu_select(const char *const *labels, int n) { jc_init_hw(); while (btn_read() & BTN_POWER) @@ -591,9 +593,86 @@ static bool install_ram_config_menu(bool *use_8gb) int selected = 0; int prev_selected = 0; - bool confirmed = false; - const int n = 2; - const char *labels[2] = { + u32 menu_x, menu_y; + gfx_con_getpos(&menu_x, &menu_y); + for (int i = 0; i < n; i++) { + install_set_color(i == selected ? COLOR_GREEN : COLOR_WHITE); + gfx_printf(i == selected ? " > %s\n" : " %s\n", labels[i]); + } + gfx_printf("\n"); + install_set_color(COLOR_CYAN); + gfx_printf("D-Pad / Vol+/-: Auswahl | A oder Power: Bestaetigen\n"); + gfx_printf("Vol+ und Vol- gleichzeitig: Abbrechen (Hekate)\n"); + install_set_color(COLOR_WHITE); + + bool prev_up = false, prev_down = false; + while (1) { + if (selected != prev_selected) { + gfx_con_setpos(menu_x, menu_y + (u32)prev_selected * 16); + install_set_color(COLOR_WHITE); + gfx_printf(" %s\n", labels[prev_selected]); + gfx_con_setpos(menu_x, menu_y + (u32)selected * 16); + install_set_color(COLOR_GREEN); + gfx_printf(" > %s\n", labels[selected]); + install_set_color(COLOR_WHITE); + prev_selected = selected; + } + + jc_gamepad_rpt_t *jc = joycon_poll(); + u8 btn = btn_read(); + + if (jc && jc->cap) + take_screenshot(); + if (cancel_combo_pressed(btn)) + return -1; + + bool cur_up = false, cur_down = false; + if (jc) { + cur_up = (jc->up != 0) && !jc->down; + cur_down = (jc->down != 0) && !jc->up; + } + if (btn & BTN_VOL_UP) + cur_up = true; + if (btn & BTN_VOL_DOWN) + cur_down = true; + + if (cur_up && !prev_up) + selected = (selected - 1 + n) % n; + else if (cur_down && !prev_down) + selected = (selected + 1) % n; + else if ((jc && jc->a) || (btn & BTN_POWER)) + return selected; + + prev_up = cur_up; + prev_down = cur_down; + msleep(50); + } +} + +/* Extras menu wrapper: abort launches Hekate. */ +static bool install_extras_choice(const char *const *labels, int n, int *choice) +{ + int sel = install_menu_select(labels, n); + if (sel < 0) { + gfx_printf("\n"); + install_set_color(COLOR_YELLOW); + gfx_printf("Abgebrochen. Starte Hekate...\n"); + install_set_color(COLOR_WHITE); + msleep(500); + installer_launch_hekate_payload(); + return false; + } + + *choice = sel; + gfx_clear_grey(0x1B); + gfx_con_setpos(0, 0); + install_print_main_header(); + return true; +} + +static bool install_ram_config_menu(bool *use_8gb) +{ + static const char *const labels[] = { "4GB Konsole (Standard)", "8GB Konsole", }; @@ -612,104 +691,16 @@ static bool install_ram_config_menu(bool *use_8gb) gfx_printf("Fall 8GB aus, da du sonst Boot Probleme bekommst!!!\n\n"); install_set_color(COLOR_WHITE); - u32 menu_x, menu_y; - gfx_con_getpos(&menu_x, &menu_y); - for (int i = 0; i < n; i++) { - if (i == selected) { - install_set_color(COLOR_GREEN); - gfx_printf(" > %s\n", labels[i]); - install_set_color(COLOR_WHITE); - } else { - gfx_printf(" %s\n", labels[i]); - } - } - gfx_printf("\n"); - install_set_color(COLOR_CYAN); - gfx_printf("D-Pad / Vol+/-: Auswahl | A oder Power: Bestaetigen\n"); - gfx_printf("Vol+ und Vol- gleichzeitig: Abbrechen (Hekate)\n"); - install_set_color(COLOR_WHITE); - - bool prev_up = false, prev_down = false; - bool menu_aborted = false; - - while (!confirmed && !menu_aborted) { - if (selected != prev_selected) { - gfx_con_setpos(menu_x, menu_y + (u32)prev_selected * 16); - install_set_color(COLOR_WHITE); - gfx_printf(" %s\n", labels[prev_selected]); - gfx_con_setpos(menu_x, menu_y + (u32)selected * 16); - install_set_color(COLOR_GREEN); - gfx_printf(" > %s\n", labels[selected]); - install_set_color(COLOR_WHITE); - prev_selected = selected; - } - - jc_gamepad_rpt_t *jc = joycon_poll(); - u8 btn = btn_read(); - - if (jc && jc->cap) - take_screenshot(); - - if (cancel_combo_pressed(btn)) { - menu_aborted = true; - break; - } - - bool cur_up = false, cur_down = false; - if (jc) { - cur_up = (jc->up != 0) && !jc->down; - cur_down = (jc->down != 0) && !jc->up; - } - if (btn & BTN_VOL_UP) - cur_up = true; - if (btn & BTN_VOL_DOWN) - cur_down = true; - - if (cur_up && !prev_up) - selected = (selected - 1 + n) % n; - else if (cur_down && !prev_down) - selected = (selected + 1) % n; - else if (jc && jc->a) - confirmed = true; - - prev_up = cur_up; - prev_down = cur_down; - - if (btn & BTN_POWER) - confirmed = true; - - msleep(50); - } - - if (menu_aborted) { - gfx_printf("\n"); - install_set_color(COLOR_YELLOW); - gfx_printf("Abgebrochen. Starte Hekate...\n"); - install_set_color(COLOR_WHITE); - msleep(500); - installer_launch_hekate_payload(); + int choice; + if (!install_extras_choice(labels, 2, &choice)) return false; - } - - *use_8gb = (selected == 1); - - gfx_clear_grey(0x1B); - gfx_con_setpos(0, 0); - install_print_main_header(); + *use_8gb = (choice == 1); return true; } static bool install_hekate_ams_menu(bool *use_pro) { - jc_init_hw(); - while (btn_read() & BTN_POWER) - msleep(50); - - int selected = 0; - int prev_selected = 0; - bool confirmed = false; - const int n = 2; - const char *labels[2] = { + static const char *const labels[] = { "Hekate / Atmosphere (Standard)", "Hekate-Pro / Atmosphere-Pro", }; @@ -724,90 +715,10 @@ static bool install_hekate_ams_menu(bool *use_pro) gfx_printf("Waehle Hekate / Atmosphere (Standard) sofern du nicht weisst, was du tust.\n\n"); install_set_color(COLOR_WHITE); - u32 menu_x, menu_y; - gfx_con_getpos(&menu_x, &menu_y); - for (int i = 0; i < n; i++) { - if (i == selected) { - install_set_color(COLOR_GREEN); - gfx_printf(" > %s\n", labels[i]); - install_set_color(COLOR_WHITE); - } else { - gfx_printf(" %s\n", labels[i]); - } - } - gfx_printf("\n"); - install_set_color(COLOR_CYAN); - gfx_printf("D-Pad / Vol+/-: Auswahl | A oder Power: Bestaetigen\n"); - gfx_printf("Vol+ und Vol- gleichzeitig: Abbrechen (Hekate)\n"); - install_set_color(COLOR_WHITE); - - bool prev_up = false, prev_down = false; - bool menu_aborted = false; - - while (!confirmed && !menu_aborted) { - if (selected != prev_selected) { - gfx_con_setpos(menu_x, menu_y + (u32)prev_selected * 16); - install_set_color(COLOR_WHITE); - gfx_printf(" %s\n", labels[prev_selected]); - gfx_con_setpos(menu_x, menu_y + (u32)selected * 16); - install_set_color(COLOR_GREEN); - gfx_printf(" > %s\n", labels[selected]); - install_set_color(COLOR_WHITE); - prev_selected = selected; - } - - jc_gamepad_rpt_t *jc = joycon_poll(); - u8 btn = btn_read(); - - if (jc && jc->cap) - take_screenshot(); - - if (cancel_combo_pressed(btn)) { - menu_aborted = true; - break; - } - - bool cur_up = false, cur_down = false; - if (jc) { - cur_up = (jc->up != 0) && !jc->down; - cur_down = (jc->down != 0) && !jc->up; - } - if (btn & BTN_VOL_UP) - cur_up = true; - if (btn & BTN_VOL_DOWN) - cur_down = true; - - if (cur_up && !prev_up) - selected = (selected - 1 + n) % n; - else if (cur_down && !prev_down) - selected = (selected + 1) % n; - else if (jc && jc->a) - confirmed = true; - - prev_up = cur_up; - prev_down = cur_down; - - if (btn & BTN_POWER) - confirmed = true; - - msleep(50); - } - - if (menu_aborted) { - gfx_printf("\n"); - install_set_color(COLOR_YELLOW); - gfx_printf("Abgebrochen. Starte Hekate...\n"); - install_set_color(COLOR_WHITE); - msleep(500); - installer_launch_hekate_payload(); + int choice; + if (!install_extras_choice(labels, 2, &choice)) return false; - } - - *use_pro = (selected == 1); - - gfx_clear_grey(0x1B); - gfx_con_setpos(0, 0); - install_print_main_header(); + *use_pro = (choice == 1); return true; } diff --git a/source/install.h b/source/install.h index 5d39790..2cc49e3 100644 --- a/source/install.h +++ b/source/install.h @@ -37,6 +37,8 @@ void install_preserve_update_cleanup_end(void); // Shared helpers (install.c) - used by install_update.c and install_clean.c void install_set_color(u32 color); +// Shared selection menu: returns index or -1 on Vol+/Vol- abort +int install_menu_select(const char *const *labels, int n); void install_check_and_clear_screen_if_needed(void); bool install_path_exists(const char *path); int install_move_staging_root_files(const char *staging, const char *dst_root); diff --git a/source/main.c b/source/main.c index 5ca7b5a..4d538de 100644 --- a/source/main.c +++ b/source/main.c @@ -312,16 +312,10 @@ void ipl_main(void) { if (num_variants == 1) { pack_variant = variants_present[0]; } else { - // Initialize joycons for menu input - jc_init_hw(); - while (btn_read() & BTN_POWER) { msleep(50); } - - // Selection menu (TegraExplorer-style: draw once, then only redraw changed lines) - int selected = 0; - int prev_selected = 0; - bool confirmed = false; - - // Draw menu once and remember start position of variant lines + const char *labels[3]; + for (int i = 0; i < num_variants; i++) + labels[i] = get_variant_name(variants_present[i]); + gfx_clear_grey(0x1B); gfx_con_setpos(0, 0); print_header(); @@ -329,77 +323,9 @@ void ipl_main(void) { gfx_printf("Mehrere OmniNX-Pakete gefunden.\n"); gfx_printf("Waehle die zu installierende Variante:\n\n"); set_color(COLOR_WHITE); - u32 menu_x, menu_variant_start_y; - gfx_con_getpos(&menu_x, &menu_variant_start_y); - for (int i = 0; i < num_variants; i++) { - if (i == selected) { - set_color(COLOR_GREEN); - gfx_printf(" > %s\n", get_variant_name(variants_present[i])); - set_color(COLOR_WHITE); - } else { - gfx_printf(" %s\n", get_variant_name(variants_present[i])); - } - } - gfx_printf("\n"); - set_color(COLOR_CYAN); - gfx_printf("D-Pad / Vol+/-: Auswahl | A oder Power: Bestaetigen\n"); - gfx_printf("Vol+ und Vol- gleichzeitig: Abbrechen (Hekate)\n"); - set_color(COLOR_WHITE); - - // Edge detection: only move on press (not while held) - bool prev_up = false, prev_down = false; - bool menu_aborted = false; - - while (!confirmed && !menu_aborted) { - // On selection change: redraw only the two affected lines (no full clear) - if (selected != prev_selected) { - gfx_con_setpos(menu_x, menu_variant_start_y + (u32)prev_selected * 16); - set_color(COLOR_WHITE); - gfx_printf(" %s\n", get_variant_name(variants_present[prev_selected])); - gfx_con_setpos(menu_x, menu_variant_start_y + (u32)selected * 16); - set_color(COLOR_GREEN); - gfx_printf(" > %s\n", get_variant_name(variants_present[selected])); - set_color(COLOR_WHITE); - prev_selected = selected; - } - - jc_gamepad_rpt_t *jc = joycon_poll(); - u8 btn = btn_read(); - - if (jc && jc->cap) - take_screenshot(); - if (cancel_combo_pressed(btn)) { - menu_aborted = true; - break; - } - - // D-pad or Vol+ / Vol- for selection (Vol+ = up, Vol- = down) - bool cur_up = false, cur_down = false; - if (jc) { - cur_up = (jc->up != 0) && !jc->down; - cur_down = (jc->down != 0) && !jc->up; - } - if (btn & BTN_VOL_UP) cur_up = true; - if (btn & BTN_VOL_DOWN) cur_down = true; - - if (cur_up && !prev_up) - selected = (selected - 1 + num_variants) % num_variants; - else if (cur_down && !prev_down) - selected = (selected + 1) % num_variants; - else if (jc && jc->a) - confirmed = true; - prev_up = cur_up; - prev_down = cur_down; - - if (btn & BTN_POWER) { - confirmed = true; - } - - msleep(50); - } - - if (menu_aborted) { + int selected = install_menu_select(labels, num_variants); + if (selected < 0) { gfx_printf("\n"); set_color(COLOR_YELLOW); gfx_printf("Abgebrochen. Starte Hekate...\n"); diff --git a/source/version.c b/source/version.c index 10c94b5..15115f6 100644 --- a/source/version.c +++ b/source/version.c @@ -146,20 +146,6 @@ omninx_status_t detect_omninx_installation(void) { return status; } -// Detect which pack variant is present on SD card -omninx_variant_t detect_pack_variant(void) { - // Check staging directories (in order of preference) - if (file_exists(STAGING_STANDARD)) { - return VARIANT_STANDARD; - } else if (file_exists(STAGING_LIGHT)) { - return VARIANT_LIGHT; - } else if (file_exists(STAGING_OC)) { - return VARIANT_OC; - } - - return VARIANT_NONE; -} - // Detect all pack variants present on SD card; returns count, fills out_variants[] int detect_present_variants(omninx_variant_t *out_variants, int max_count) { int count = 0; diff --git a/source/version.h b/source/version.h index 323933a..12bba22 100644 --- a/source/version.h +++ b/source/version.h @@ -24,8 +24,6 @@ typedef struct { // Detect current OmniNX installation status omninx_status_t detect_omninx_installation(void); -// Detect which pack variant is present on SD card (first found in fixed order) -omninx_variant_t detect_pack_variant(void); // Detect all pack variants present on SD card; returns count, fills out_variants[] (max max_count) int detect_present_variants(omninx_variant_t *out_variants, int max_count);