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).
This commit is contained in:
niklascfw committed 2026-11-12 22:58:41 +01:00
1 parent 664216fa11
commit 5241cccbe9
6 files changed
+99 -278

No files matched your search

+91 -180
View File
@@ -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;
}
+2
View File
@@ -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);
+6 -80
View File
@@ -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");
-14
View File
@@ -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;
-2
View File
@@ -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);