Input: console Vol+/- combo only before install; Joy-Con +/- exit removed
All checks were successful
Build / Build (push) Successful in 16s

- cancel_combo_pressed uses only hardware volume buttons
- After installation summary and payload-missing screen: A or Power only

Made-with: Cursor
This commit is contained in:
2026-03-31 13:18:06 +02:00
parent d1fc24dae8
commit 3f6bbc0752

View File

@@ -116,6 +116,12 @@ static void print_header(void) {
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
} }
/* Console Vol+ and Vol- together (exit / cancel where documented) */
static inline bool cancel_combo_pressed(u8 btn)
{
return (btn & (BTN_VOL_UP | BTN_VOL_DOWN)) == (BTN_VOL_UP | BTN_VOL_DOWN);
}
void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size) { void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size) {
memcpy((u8 *)payload_src, (u8 *)IPL_LOAD_ADDR, PATCHED_RELOC_SZ); memcpy((u8 *)payload_src, (u8 *)IPL_LOAD_ADDR, PATCHED_RELOC_SZ);
@@ -244,11 +250,13 @@ void ipl_main(void) {
set_color(COLOR_GREEN); set_color(COLOR_GREEN);
gfx_printf("Druecke A-Taste (rechter Joy-Con) oder Power-Taste,\n"); gfx_printf("Druecke A-Taste (rechter Joy-Con) oder Power-Taste,\n");
gfx_printf("um Hekate zu starten...\n"); gfx_printf("um Hekate zu starten...\n");
gfx_printf("Oder Vol+ und Vol- (Konsole) gleichzeitig.\n");
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
} else { } else {
set_color(COLOR_GREEN); set_color(COLOR_GREEN);
gfx_printf("Druecke A-Taste (rechter Joy-Con) oder Power-Taste,\n"); gfx_printf("Druecke A-Taste (rechter Joy-Con) oder Power-Taste,\n");
gfx_printf("um den Neustart zu starten...\n"); gfx_printf("um den Neustart zu starten...\n");
gfx_printf("Oder Vol+ und Vol- (Konsole) gleichzeitig.\n");
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
} }
@@ -275,7 +283,11 @@ void ipl_main(void) {
break; break;
} }
} }
if (cancel_combo_pressed(btn_state)) {
button_pressed = true;
break;
}
msleep(50); // Small delay to avoid busy-waiting msleep(50); // Small delay to avoid busy-waiting
} }
@@ -329,12 +341,14 @@ void ipl_main(void) {
gfx_printf("\n"); gfx_printf("\n");
set_color(COLOR_CYAN); set_color(COLOR_CYAN);
gfx_printf("D-Pad / Vol+/-: Auswahl | A oder Power: Bestaetigen\n"); gfx_printf("D-Pad / Vol+/-: Auswahl | A oder Power: Bestaetigen\n");
gfx_printf("Vol+ und Vol- gleichzeitig: Abbrechen (Hekate)\n");
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
// Edge detection: only move on press (not while held) // Edge detection: only move on press (not while held)
bool prev_up = false, prev_down = false; bool prev_up = false, prev_down = false;
bool menu_aborted = false;
while (!confirmed) { while (!confirmed && !menu_aborted) {
// On selection change: redraw only the two affected lines (no full clear) // On selection change: redraw only the two affected lines (no full clear)
if (selected != prev_selected) { if (selected != prev_selected) {
gfx_con_setpos(menu_x, menu_variant_start_y + (u32)prev_selected * 16); gfx_con_setpos(menu_x, menu_variant_start_y + (u32)prev_selected * 16);
@@ -352,6 +366,11 @@ void ipl_main(void) {
if (jc && jc->cap) if (jc && jc->cap)
take_screenshot(); take_screenshot();
if (cancel_combo_pressed(btn)) {
menu_aborted = true;
break;
}
// D-pad or Vol+ / Vol- for selection (Vol+ = up, Vol- = down) // D-pad or Vol+ / Vol- for selection (Vol+ = up, Vol- = down)
bool cur_up = false, cur_down = false; bool cur_up = false, cur_down = false;
@@ -377,6 +396,20 @@ void ipl_main(void) {
msleep(50); msleep(50);
} }
if (menu_aborted) {
gfx_printf("\n");
set_color(COLOR_YELLOW);
gfx_printf("Abgebrochen. Starte Hekate...\n");
set_color(COLOR_WHITE);
msleep(500);
if (file_exists(PAYLOAD_PATH)) {
launch_payload(PAYLOAD_PATH);
} else {
power_set_state(POWER_OFF_REBOOT);
}
return;
}
pack_variant = variants_present[selected]; pack_variant = variants_present[selected];
gfx_clear_grey(0x1B); gfx_clear_grey(0x1B);
@@ -403,20 +436,21 @@ void ipl_main(void) {
gfx_printf("mit angeschlossenem Ladegeraet durchgefuehrt werden.\n\n"); gfx_printf("mit angeschlossenem Ladegeraet durchgefuehrt werden.\n\n");
set_color(COLOR_YELLOW); set_color(COLOR_YELLOW);
gfx_printf("Stecke das Ladegeraet an und warte...\n"); gfx_printf("Stecke das Ladegeraet an und warte...\n");
gfx_printf("Oder druecke + und - zum Abbrechen.\n"); gfx_printf("Oder Vol+ und Vol- (Konsole) zum Abbrechen.\n");
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
jc_init_hw(); jc_init_hw();
while (btn_read() & BTN_POWER) { msleep(50); } while (btn_read() & BTN_POWER) { msleep(50); }
bool user_cancelled = false; bool user_cancelled = false;
while (batt_pct < BATT_LOW_THRESHOLD && !bq24193_charger_connected() && !user_cancelled) { while (batt_pct < BATT_LOW_THRESHOLD && !bq24193_charger_connected() && !user_cancelled) {
u8 pbtn = btn_read();
jc_gamepad_rpt_t *jc = joycon_poll(); jc_gamepad_rpt_t *jc = joycon_poll();
if (jc) { if (jc) {
if (jc->cap) if (jc->cap)
take_screenshot(); take_screenshot();
if (jc->plus && jc->minus) { }
user_cancelled = true; if (cancel_combo_pressed(pbtn)) {
break; user_cancelled = true;
} break;
} }
if (max17050_get_property(MAX17050_RepSOC, &batt_raw) == 0) { if (max17050_get_property(MAX17050_RepSOC, &batt_raw) == 0) {
batt_pct = batt_raw >> 8; batt_pct = batt_raw >> 8;
@@ -473,10 +507,13 @@ void ipl_main(void) {
gfx_printf("Empfohlene Karten: Samsung EVO Plus, EVO Select und PRO Plus.\n\n"); gfx_printf("Empfohlene Karten: Samsung EVO Plus, EVO Select und PRO Plus.\n\n");
set_color(COLOR_GREEN); set_color(COLOR_GREEN);
gfx_printf("Druecke A (oder Power), um trotzdem fortzufahren.\n"); gfx_printf("Druecke A (oder Power), um trotzdem fortzufahren.\n");
set_color(COLOR_CYAN);
gfx_printf("Vol+ und Vol- (Konsole) gleichzeitig: Abbrechen -> Hekate.\n");
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
while (btn_read() & BTN_POWER) { msleep(50); } while (btn_read() & BTN_POWER) { msleep(50); }
bool acknowledged = false; bool acknowledged = false;
while (!acknowledged) { bool uhs_aborted = false;
while (!acknowledged && !uhs_aborted) {
u8 btn_state = btn_read(); u8 btn_state = btn_read();
if (btn_state & BTN_POWER) acknowledged = true; if (btn_state & BTN_POWER) acknowledged = true;
jc_gamepad_rpt_t *jc = joycon_poll(); jc_gamepad_rpt_t *jc = joycon_poll();
@@ -485,8 +522,22 @@ void ipl_main(void) {
take_screenshot(); take_screenshot();
if (jc->a) acknowledged = true; if (jc->a) acknowledged = true;
} }
if (cancel_combo_pressed(btn_state)) {
uhs_aborted = true;
break;
}
msleep(50); msleep(50);
} }
if (uhs_aborted) {
gfx_printf("\nAbgebrochen. Starte Hekate...\n");
msleep(500);
if (file_exists(PAYLOAD_PATH)) {
launch_payload(PAYLOAD_PATH);
} else {
power_set_state(POWER_OFF_REBOOT);
}
return;
}
// Wait for A and Power to be released so the same press doesn't start the install // Wait for A and Power to be released so the same press doesn't start the install
while (btn_read() & BTN_POWER) { msleep(50); } while (btn_read() & BTN_POWER) { msleep(50); }
bool released = false; bool released = false;
@@ -526,7 +577,7 @@ void ipl_main(void) {
gfx_printf("um die Installation zu starten...\n"); gfx_printf("um die Installation zu starten...\n");
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
set_color(COLOR_CYAN); set_color(COLOR_CYAN);
gfx_printf("Druecke + und - gleichzeitig zum Abbrechen (zurueck zu Hekate).\n"); gfx_printf("Vol+ und Vol- (Konsole) gleichzeitig: Abbrechen -> Hekate.\n");
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
// Wait for A/Power to start, or +/- to cancel // Wait for A/Power to start, or +/- to cancel
@@ -555,11 +606,10 @@ void ipl_main(void) {
button_pressed = true; button_pressed = true;
break; break;
} }
// + and - simultaneously = cancel, return to hekate }
if (jc->plus && jc->minus) { if (cancel_combo_pressed(btn_state)) {
cancelled = true; cancelled = true;
break; break;
}
} }
msleep(50); // Small delay to avoid busy-waiting msleep(50); // Small delay to avoid busy-waiting