Commit Graph

2 Commits

Author SHA1 Message Date
Sylpheed RE agent
4f7630b750 tools: two dead flags that made every emulator boot script fail silently
Trying to read a third paint order off the running game turned up two bugs in
the capture harness, both of which fail in ways that look like the game
misbehaving rather than the script being wrong.

1. `--audio` is not a cvar in this tree, and eight boot scripts passed it.
   Xenia calls ShowSimpleMessageBox from ParseLaunchArguments, BEFORE logging is
   initialised, so the symptom is a 10x10 window, no log, no guest memory and a
   dialog that blocks on XIfEvent forever - i.e. a hang deep in the emulator.
   run-canary`s own header documents this exact trap; the scripts predate it.
   Removed from all eight.

2. `vgamepad` no longer exists - the uinput pad was replaced by the --hid=file
   driver and pad.py - but skip_intro.sh still called it. The script runs
   without `set -e`, so the call failed silently and the title branch pressed
   nothing while still exiting 0. A caller was told "TITLE -> A" with the game
   sitting on the title screen. It now presses through pad.py and exits 6 if
   that fails.

The first bug is fixed and verified: the boot now reaches the title screen with
PRESS (A) BUTTON. The second is fixed but does NOT unblock the title - see the
next commit.
2026-08-19 07:48:16 +00:00
4c8be12796 re(challenge): the part id is never persisted -- differential search says stack only
No literal 26 exists anywhere, so the GamePart id is computed. That does not stop
it being found: the id is KNOWN at each screen from the GamePart table (EXTRAS = 5,
MISSION SELECT = 7), so snapshot both and intersect. New tool diff_words.py does
the classic differential search over the sparse guest image, and find_partslot.sh
drives the two screens and runs it.

Result: 171 MB scanned, exactly 4 addresses read 5 then 7 -- 0x708FFBEC,
0x708FFCBC, 0x708FFDAC, 0x708FFE20 -- and all four are guest STACK (the same run's
log puts thread stacks at 0x709...). So the requested part id exists only as a
stack argument in flight; there is no persistent field, which is consistent with
finding no literal store, and means there is nothing stable to poke.

That closes the last memory-and-menu route to the challenge missions. Reaching
them needs either the genuine in-game unlock (an in-mission attainment, per
AVSCRIPT_COMMAND_ATTAINMENT_CHALLENGE_MISSION_CARGO_SCORE) or an emulator-side
hook that forces the transition -- a code change, not a poke.

diff_words.py is worth keeping well beyond this question: it locates any field
whose address is unknown but whose value is known at two moments.
2026-08-13 21:31:47 +00:00