#!/usr/bin/env bash # Wait until screen_id.py reports , instead of sleeping a guessed number # of seconds. # # Written because `launch_mission.sh` allowed a fixed 28 s for LOAD -> READY # ROOM and neither run on 2026-08-23 was ready in time: the next press was # swallowed by the transition, which left one run in OPTIONS and the next in # BRIEFINGS, and `wait_flight.sh` then tapped A into the wrong screen for five # minutes. See docs/re/dynamic-re-state-restore.md. # # `--tap BTN` presses BTN every 6 s *until the class is first seen* — that is # what clears a dialog the caller cannot know about, such as the # "Auto-Save is active. OK?" that a freshly restored profile puts up. Tapping # STOPS at the first match, because on most screens the button that dismisses a # dialog also leaves the screen you are waiting for. # # Two consecutive matches are required, so a single frame caught mid-fade does # not count as arrival. # # Usage: wait_screen.sh [timeout_s] [--tap BTN] set -u CLASS="${1:?usage: wait_screen.sh [timeout_s] [--tap BTN]}" TIMEOUT="${2:-180}" TAP="" [ "${3:-}" = "--tap" ] && TAP="${4:-A}" export HOME=/sylph-home/re DISP="${DISPLAY:-:98}" SD="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Same liveness rule as skip_intro.sh/wait_flight.sh: a failed screenshot must # not be indistinguishable from "the screen is not there yet". alive(){ ps -o pid=,stat= -C xenia_canary 2>/dev/null | awk '$2 !~ /^Z/ {print $1}'; } DEADLINE=$(( SECONDS + TIMEOUT )) hits=0; seen=0; last_tap=0 while [ $SECONDS -lt $DEADLINE ]; do rm -f /tmp/ws.png if ! screenshot /tmp/ws.png >/dev/null 2>&1 || [ ! -s /tmp/ws.png ]; then xdpyinfo -display "$DISP" >/dev/null 2>&1 \ || { echo "DISPLAY LOST at ${SECONDS}s"; exit 3; } sleep 2; continue fi [ -n "$(alive)" ] || { echo "EMULATOR GONE at ${SECONDS}s"; exit 4; } got="$(python3 "$SD/screen_id.py" /tmp/ws.png | awk '{print $1}')" if [ "$got" = "$CLASS" ]; then seen=1; hits=$(( hits + 1 )) [ $hits -ge 2 ] && { echo "$CLASS at ${SECONDS}s"; exit 0; } else hits=0 if [ -n "$TAP" ] && [ $seen -eq 0 ] && [ $(( SECONDS - last_tap )) -ge 6 ]; then python3 "$SD/pad.py" tap "$TAP" 0.3 last_tap=$SECONDS fi fi sleep 2 done echo "NO $CLASS within ${TIMEOUT}s (last seen: ${got:-none})"; exit 1