tools: capture targets, and a Z-aware draw-order decoder
`ui_draw_capture.sh` grows three knobs the second iteration needed: * ARM=early presses F10 before the title exists, so a long window contains the frames in which a screen is BUILT (it turns out none are — the title screen submits the same 11 draws every frame and never rebuilds); * TARGET=menu taps A once on the title and arms on the main menu, skipping attract movies on the way — it does not get there, but the blocker it hits is documented rather than worked around; * EXTRA_FLAGS passes emulator cvars through (--create_profile_if_none, --mem_watch=false, --log_level). `ui_draw_order.py` follows the capture's new vertex format (x, y, z) and reports the Z it now has.
This commit is contained in:
@@ -29,7 +29,7 @@ wide(){ [ "$(identify -format '%w' "$1" 2>/dev/null || echo 0)" -gt 1000 ]; }
|
||||
xsetroot -solid black 2>/dev/null || true
|
||||
# ATTACH=1 watches an emulator that is already up instead of launching one.
|
||||
if [ "${ATTACH:-0}" != "1" ]; then
|
||||
( cd "$OUT" && nohup run-canary --log_ui_draws=true --ui_draw_capture_frames="${FRAMES:-3}" --ui_draw_capture_max="${MAXDRAWS:-20000}" >"$OUT/canary.stdout" 2>"$OUT/canary.stderr" & )
|
||||
( cd "$OUT" && nohup run-canary --log_ui_draws=true --ui_draw_capture_frames="${FRAMES:-3}" --ui_draw_capture_max="${MAXDRAWS:-20000}" ${EXTRA_FLAGS:-} >"$OUT/canary.stdout" 2>"$OUT/canary.stderr" & )
|
||||
# Grace period before the liveness check: run-canary is a shell that execs the
|
||||
# binary, and polling `ps -C xenia_canary` in the first moments reports GONE
|
||||
# for a process that is merely not exec'd yet.
|
||||
@@ -66,6 +66,33 @@ while [ $SECONDS -lt $deadline ]; do
|
||||
d=$(compare -metric RMSE /tmp/u1.png /tmp/u2.png null: 2>&1 | sed 's/ .*//' | cut -d. -f1); d=${d:-0}
|
||||
s=$(python3 "$SD/screen_id.py" /tmp/u2.png | awk '{print $1}')
|
||||
echo "t=${SECONDS}s screen=$s rmse=$d"
|
||||
# TARGET=menu walks one step further: tap A ONCE on the title, then arm on the
|
||||
# main menu. One tap, and only from a full-width grab — the run that tapped
|
||||
# repeatedly (off a 10-pixel sliver it had classified) crashed the guest in the
|
||||
# save-data probe behind that button.
|
||||
if [ "${TARGET:-title}" = "menu" ]; then
|
||||
if [ "$s" = "title" ] && [ "${tapped:-0}" = "0" ]; then
|
||||
echo "TITLE at ${SECONDS}s -> one A"; python3 "$SD/pad.py" tap A 0.25; tapped=1
|
||||
elif [ "$s" = "menu" ]; then
|
||||
cp /tmp/u2.png "$OUT/menu-before-f10.png"
|
||||
xdotool windowactivate "$win" 2>/dev/null
|
||||
xdotool key --window "$win" F10
|
||||
xdotool key F10
|
||||
sleep 3
|
||||
screenshot "$OUT/menu-after-f10.png" >/dev/null 2>&1
|
||||
if ls "$OUT"/xenia_re_ui_draws_*.log >/dev/null 2>&1; then
|
||||
echo "MENU CAPTURED at ${SECONDS}s"; break
|
||||
fi
|
||||
echo "F10 pressed on the menu; no log yet"
|
||||
elif [ "$d" -gt 1500 ]; then
|
||||
# Still in the attract loop. Without this the menu target waits forever:
|
||||
# the attract movie returns to the title and away again, and a run that
|
||||
# only ever watches never gets there.
|
||||
echo "movie (rmse $d) -> skip A"; python3 "$SD/pad.py" tap A 0.25; sleep 3
|
||||
fi
|
||||
sleep 1
|
||||
continue
|
||||
fi
|
||||
if [ "$s" = "title" ] && [ "${ARM:-title}" = "early" ]; then
|
||||
cp /tmp/u2.png "$OUT/title-reached.png"
|
||||
echo "TITLE REACHED at ${SECONDS}s (capture was armed early)"
|
||||
|
||||
@@ -19,7 +19,7 @@ import glob
|
||||
from collections import defaultdict
|
||||
|
||||
W, H = 1280, 720
|
||||
VERT = re.compile(r"\[([0-9A-F]{8}),([0-9A-F]{8})=(-?\d+\.\d+),(-?\d+\.\d+)\]")
|
||||
VERT = re.compile(r"\[(-?\d+\.\d+),(-?\d+\.\d+),z=(-?\d+\.\d+)\]")
|
||||
|
||||
|
||||
def sprite_index(texdir):
|
||||
@@ -78,7 +78,7 @@ def main():
|
||||
continue
|
||||
if "vb=0x" in line and pending:
|
||||
if want is None or frame == want or frame is None:
|
||||
verts = [(float(a), float(b)) for _, _, a, b in VERT.findall(line)]
|
||||
verts = [(float(a), float(b)) for a, b, _z in VERT.findall(line)]
|
||||
if verts:
|
||||
# Two conventions in one log: the UI sprite shader emits NDC,
|
||||
# the full-screen pass emits pixels already (-0.5 .. 1279.5).
|
||||
|
||||
Reference in New Issue
Block a user