Add R on the main menu to boot Swiss and leave the test app
Getting back to Swiss previously meant power-cycling the console. R boots /boot.dol from the SD card directly. It reuses netboot_boot_file(), so there is ONE DOL launcher and one set of safety checks (MEM1 entry point, section overlap against the reserved staging region, libfat unmounted before the jump) rather than a second copy to keep in step. Confirmed rather than one-touch, and main-menu only: R is an easy trigger to catch by accident, test results are not saved anywhere, and losing a full run to a stray press is worse than one extra button press. Inside a suite R would be easy to hit while navigating, so it is ignored there. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -73,6 +73,19 @@ Builds clean (no warnings) with devkitPPC 16.1.0 / GCC 16 in the devcontainer:
|
|||||||
|
|
||||||
`.gitignore` excludes the build products — run `make` to produce the `.dol`.
|
`.gitignore` excludes the build products — run `make` to produce the `.dol`.
|
||||||
|
|
||||||
|
## Boot Swiss (R button)
|
||||||
|
|
||||||
|
**R** on the main menu boots `/boot.dol` from the SD card and leaves the test
|
||||||
|
app, so you can get back to Swiss without power-cycling the console.
|
||||||
|
|
||||||
|
It asks for confirmation (A to go, B to cancel). R is an easy trigger to catch
|
||||||
|
by accident, test results are not saved anywhere, and losing a full run to a
|
||||||
|
stray press is worse than one extra button. It is also main-menu only — inside
|
||||||
|
a suite, R would be easy to hit while navigating.
|
||||||
|
|
||||||
|
It uses the same `netboot_boot_file()` path as the post-update boot, so there
|
||||||
|
is one DOL launcher and one set of safety checks rather than two.
|
||||||
|
|
||||||
## Self-update over the BBA (Z button)
|
## Self-update over the BBA (Z button)
|
||||||
|
|
||||||
Press **Z**, then on the host:
|
Press **Z**, then on the host:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
* Y clear all results
|
* Y clear all results
|
||||||
* B back
|
* B back
|
||||||
* Z self-update over the BBA, then relaunch (see netboot.c)
|
* Z self-update over the BBA, then relaunch (see netboot.c)
|
||||||
|
* R boot Swiss (/boot.dol) and leave the test app
|
||||||
*/
|
*/
|
||||||
#include <gccore.h>
|
#include <gccore.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -92,7 +93,8 @@ static void draw_main(int sel, const char *status)
|
|||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
printf("\n" C_DIM " A open X run suite START run all Y clear Z net-update\n" C_RESET);
|
printf("\n" C_DIM " A open X run suite START all Y clear "
|
||||||
|
"Z net-update R Swiss\n" C_RESET);
|
||||||
if (status && *status) printf("\n %s\n", status);
|
if (status && *status) printf("\n %s\n", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,6 +200,50 @@ static void do_netboot(char *status, size_t nstatus)
|
|||||||
"update saved, but /boot.dol would not boot (%d)", rc);
|
"update saved, but /boot.dol would not boot (%d)", rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Boot Swiss from the SD card and leave the test app.
|
||||||
|
*
|
||||||
|
* Confirmed rather than one-touch: R is an easy trigger to catch by accident,
|
||||||
|
* test results are not saved anywhere, and losing a full run to a stray press
|
||||||
|
* is worse than one extra button. */
|
||||||
|
static void do_boot_swiss(char *status, size_t nstatus)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
printf("\n" C_HEAD " Boot Swiss (/boot.dol)" C_RESET "\n\n");
|
||||||
|
printf(" A = confirm, B = cancel\n");
|
||||||
|
printf(C_DIM " Test results are not saved and will be lost.\n" C_RESET);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
u16 d;
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
PAD_ScanPads();
|
||||||
|
d = PAD_ButtonsDown(0);
|
||||||
|
if (d & PAD_BUTTON_B) {
|
||||||
|
snprintf(status, nstatus, "boot cancelled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (d & PAD_BUTTON_A)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!s_stage) {
|
||||||
|
snprintf(status, nstatus, "staging region unavailable");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n booting /boot.dol ...\n");
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
|
||||||
|
/* Same path netboot uses after an update, so there is one DOL launcher
|
||||||
|
* and one set of safety checks rather than two. */
|
||||||
|
rc = netboot_boot_file("/boot.dol", s_stage, s_stage_max, nb_status);
|
||||||
|
|
||||||
|
/* Only reached on refusal -- the launcher does not return on success. */
|
||||||
|
nb_pause("boot refused");
|
||||||
|
snprintf(status, nstatus, "/boot.dol would not boot (%d)", rc);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
int screen = 0; /* 0 = main, 1 = suite detail */
|
int screen = 0; /* 0 = main, 1 = suite detail */
|
||||||
@@ -233,6 +279,14 @@ int main(void)
|
|||||||
down = PAD_ButtonsDown(0);
|
down = PAD_ButtonsDown(0);
|
||||||
if (!down) continue;
|
if (!down) continue;
|
||||||
|
|
||||||
|
if (!screen && (down & PAD_TRIGGER_R)) {
|
||||||
|
/* Main menu only: inside a suite R would be easy to hit
|
||||||
|
* while navigating. */
|
||||||
|
do_boot_swiss(status, sizeof(status));
|
||||||
|
draw_main(sel, status);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (down & PAD_TRIGGER_Z) {
|
if (down & PAD_TRIGGER_Z) {
|
||||||
/* Self-update: pull a new .dol over the BBA and launch it.
|
/* Self-update: pull a new .dol over the BBA and launch it.
|
||||||
* Staged in a malloc'd buffer rather than written in place --
|
* Staged in a malloc'd buffer rather than written in place --
|
||||||
|
|||||||
Reference in New Issue
Block a user