Files
bigmak94andClaude Opus 5.5 c206232332 Every setting on the VR settings panel; language, camera turns, passthrough
The settings panel beside the pause menu held nine of the settings of
petari_vr.ini; the others needed the file edited over adb.  Players asked
for all of them in the game, for a choice of language, for the camera's
turns the other way round and for the room around the giant screen.

- One table of the numeric settings (vr::Setting in vr_game.cpp: key,
  range, default, how to read and change it) now serves the file's loader
  and the panel.  Values outside a setting's range are clamped instead of
  ignored.
- The panel (vr_settings.cpp) is drawn from tables of rows (a switch, a
  stepper or a slider) on four tabs: Screen, Diorama, Picture, Game, with
  a Defaults button for the open tab.  It writes only the lines of the
  settings changed on it, in one pass, so the rest keep following the
  defaults.  The refresh rate and the highest resolution now apply at
  once; the clock levels and the language at the next start.
- language: each disc's languages (European: English, French, German,
  Spanish, Italian; American: English, French, Spanish) with their
  folders; SCGetLanguage answers with the one asked for when the copy has
  its texts.  The European disc's EuDutch folder holds the English texts
  again and is not offered.
- invert_camera (on by default): the game moves its camera round Mario
  the way the D-pad is pressed, so the view turns the other way.  With
  the setting CameraLocalUtil's two tests swap sides (and CameraInfo's
  two arrows), and the diorama's snap turn takes the other sign: pushing
  the right stick right turns the view to the right.  Pages and menus
  keep their sides.
- passthrough (off by default): XR_FB_passthrough, with
  com.oculus.feature.PASSTHROUGH declared (not required) in the manifest.
  The feature and a reconstruction layer are made when the setting first
  asks, and paused while it does not.  While they run the passthrough
  layer goes out first and the eye layer blends by its alpha; around the
  giant screen the eye images are cleared to transparent, fading over
  0.3 s.  The diorama's eye images stay opaque.

Checked headless on the headset (every tab and control, the saved file,
the camera's direction with the setting off and on, French and Spanish
texts on the two discs) and in the app unworn (the language from the
file, passthrough started, paused and started again without an error,
the refresh rate changed from the panel).  Measured there with
passthrough: the compositor's GPU time goes from 1.9 to 3.1-4.2 ms a
refresh; worn, a player's heavy scene fell from 60 to 44 frames a second.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:25:57 +02:00

62 lines
3.3 KiB
Bash

#!/bin/bash
# Pushes the current build to the headset and boots it headless.
# tools/run_headless.sh [seconds] [--no-push]
# On a crash, prints the symbolized backtrace from the crash log buffer.
# HEADLESS_DATA: game files on the headset other than the app's own (another
# region's disc). HEADLESS_NAND: the save folder; the snapshots go to shots/
# next to it.
cd "$(dirname "$0")/.."
export MSYS_NO_PATHCONV=1
source tools/env.sh
ADB=$(find_adb) || { echo "adb not found" >&2; exit 1; }
NDKBIN=$(ndk_llvm_bin)
SECS=${1:-20}
DEV=/data/local/tmp/petari
DATA=${HEADLESS_DATA:-/sdcard/Android/data/com.galaxy.quest/files/game}
NAND=${HEADLESS_NAND:-$DEV/nand}
SHOTS=$(dirname $NAND)/shots
if [ "$2" != "--no-push" ]; then
mkdir -p out/headless
$NDKBIN/llvm-strip$EXE --strip-unneeded -o out/headless/libgame.so build-android/libgame.so
cp build-android/petari_headless out/headless/
$ADB shell mkdir -p $DEV/nand
$ADB push out/headless/libgame.so out/headless/petari_headless $DEV/ > /dev/null || exit 1
$ADB shell chmod 755 $DEV/petari_headless
fi
ENVS=""
for v in PETARI_XRSIM_MV PETARI_PERFLOG PETARI_XRSIM_FPS PETARI_AUDIOLOG PETARI_COPYDUMP PETARI_STAGE PETARI_MOVIE PETARI_CUTTEST PETARI_WANDER PETARI_XRSIM PETARI_XRHEAD PETARI_FOVEATE PETARI_NOCOPY PETARI_VRSIZE PETARI_WAV PETARI_ASYNC PETARI_VRTEST PETARI_VRHEAD PETARI_GLITEMS PETARI_GLSTEPS PETARI_INPUT PETARI_DUMP PETARI_THREADS PETARI_NERVES PETARI_GLDBG PETARI_GLSRC PETARI_GLVIS PETARI_GLEXEC PETARI_GLSTOP PETARI_SHOT_MS PETARI_SHOT_FROM PETARI_WARP PETARI_SELOG PETARI_DSPLOG PETARI_SETEST PETARI_SWITCH PETARI_STARBITS PETARI_XRSIM_STEPS PETARI_XRSIM_SMALL PETARI_XRSIM_BUDGET PETARI_RIGLOG PETARI_CAMLOG PETARI_POSLOG PETARI_VRINI PETARI_XRSIM_AIM PETARI_VRLIGHT_OFF PETARI_XRSIM_SWAPSCALE PETARI_FIXED_SCALE PETARI_XRSIM_LAYERS PETARI_XRSIM_TURN PETARI_DLCHECK PETARI_NODLCACHE PETARI_LANGUAGE PETARI_PANELLOG; do
if [ -n "${!v}" ]; then ENVS="$ENVS $v='${!v}'"; fi
done
$ADB shell "mkdir -p $NAND $SHOTS && rm -f $SHOTS/*.png"
$ADB logcat -b crash -c
$ADB shell "cd $DEV &&$ENVS LD_LIBRARY_PATH=$DEV timeout $((SECS + 10)) ./petari_headless $DATA $NAND $SECS; echo \"[exit status \$?]\"" 2>&1 | tee out/headless/last_run.txt
# Symbolize thread dumps (" g:<offset>" entries are libgame.so offsets).
if grep -q " bt:" out/headless/last_run.txt; then
echo "=== thread backtraces ==="
grep -E "^thread |^threads:| bt:" out/headless/last_run.txt | while IFS= read -r line; do
case "$line" in
*"bt:"*)
offs=$(echo "$line" | grep -oE "g:[0-9a-f]+" | sed 's/g:/0x/' | head -14)
if [ -n "$offs" ]; then
$NDKBIN/llvm-addr2line$EXE -C -f -e build-android/libgame.so $offs | sed -E "s|$(native_path "$REPO")/||" | paste - - | sed -E 's/^/ /'
fi
;;
*) echo "$line" ;;
esac
done
fi
CRASH=$($ADB logcat -b crash -d)
if echo "$CRASH" | grep -q "Fatal signal"; then
echo "=== crash ==="
echo "$CRASH" | grep -E "Fatal signal|signal [0-9]+|Abort message|x0 |x4 |x8 |x12 |x16 |x20 |x24 |x28 |lr " | head -12
PCS=$(echo "$CRASH" | grep -E "#[0-9]+ pc [0-9a-f]+ +/data/local/tmp/petari/libgame.so" | sed -E 's/.*pc ([0-9a-f]+).*/0x\1/' | head -24)
if [ -n "$PCS" ]; then
$NDKBIN/llvm-addr2line$EXE -C -f -i -e build-android/libgame.so $PCS | sed -E "s|$(native_path "$REPO")/||" | paste - - | sed -E "s/ / /"
fi
fi