Files

92 lines
4.1 KiB
Python

#!/usr/bin/env python3
"""P7 visual probe, run ON the Frame: installs SRC.js as __LGS_SG_TEST with
debug tints (pop green, base red, cover blue), applies one spec, grabs the
headset view at fixed delays, destroys, grabs again. Frames show the room:
look at them, then delete them at once on both machines.
python3 sg_vis.py SRC.js OUTDIR [MODE]
MODE: pop (default: one big pop at +10 mm), t1dim (window.dim 0.4 on Steam's
real panel), yaw (test.yaw 25 deg), fc (frame controls moved 120 mm left and
shown without the laser). Run under the native and lab-vr locks.
"""
import asyncio
import json
import os
import subprocess
import sys
import time
GS = os.path.expanduser("~/.local/share/glass-shell")
sys.dont_write_bytecode = True # no __pycache__ left in the install (REQ P10->P7; like lab/lab.py)
sys.path.insert(0, os.path.join(GS, "device"))
import lgs # noqa: E402
import lgs_vr # noqa: E402
HV = os.path.join(GS, "native", "spike", "hvgrab")
G = "window.__LGS_SG_TEST"
MAIN = "valve.steam.gamepadui.main"
def grab(out, tag):
path = os.path.join(out, f"p7v_{tag}.png")
try:
# twice: the first frame after a pause can be an old one
subprocess.run([HV, path, "3"], capture_output=True, timeout=4)
time.sleep(0.3)
subprocess.run([HV, path, "3"], capture_output=True, timeout=4)
except subprocess.TimeoutExpired:
pass
return path if os.path.exists(path) else None
async def main():
src_path, out = sys.argv[1], sys.argv[2]
mode = sys.argv[3] if len(sys.argv) > 3 else "pop"
os.makedirs(out, exist_ok=True)
src = open(src_path, encoding="utf-8").read().strip().rstrip(";")
tg = next(x for x in lgs_vr.targets() if x["title"] == "systemui")
async with lgs.Session(tg["webSocketDebuggerUrl"]) as s:
async def js(e, timeout=10):
r = await s.eval(e, timeout)
return json.loads(r) if isinstance(r, str) and r[:1] in "{[" else r
async def keep(secs):
t0 = time.time()
while time.time() - t0 < secs:
await js(f"{G} && {G}.ping(), 0")
await asyncio.sleep(0.2)
opts = {"version": "p7vis", "global": "__LGS_SG_TEST", "watchdogMs": 5000, "force": True,
"debugTint": {"pop": [0.2, 1, 0.2], "base": [1, 0.3, 0.3], "cover": [0.3, 0.3, 1]}}
shots = []
try:
print(json.dumps({"install": (await js(f"({src})({json.dumps(opts)})", 20)) is not None}), flush=True)
shots.append(grab(out, "0_before"))
if mode in ("pop", "pop1"):
spec = {"seq": 1, "depthMotion": "none" if mode == "pop1" else "depth", "surfaces": [{"steamKey": MAIN, "texW": 1920, "texH": 1080, "visible": True,
"glassd": {"key": "glassd.none", "backdrop": [0, 0, 1, 1], "scale": 0.75},
"coverDz": 0.001, "baseDz": 0.002,
"popped": [{"id": "vis", "x": 300, "y": 200, "w": 1300, "h": 650, "dz": 0.0271}]}]}
r = await js(f"JSON.stringify({G}.update({json.dumps(spec)}))")
elif mode == "t1dim":
r = await js(f"JSON.stringify({G}.windowState({{dim: 0.4}}))")
elif mode == "yaw":
r = await js(f"JSON.stringify({G}.test.yaw(25, 8000))")
elif mode == "fc":
r = await js(f"JSON.stringify({G}.overrides({{rules: [{{id: 'fc', target: 'frame-controls', addMm: [-120, 0, 0]}},"
f"{{id: 'vis', select: '[id^=\"legacy-frame-controls-\"]', props: {{'only-visible-with-laser': false}}}}]}}))")
else:
r = None
print(json.dumps({"apply": r}), flush=True)
await keep(1.5)
shots.append(grab(out, "1_applied"))
print(json.dumps({"status": await js(f"JSON.stringify({G}.status())")}), flush=True)
finally:
print(json.dumps({"destroy": await js(f"{G} ? ({G}.destroy(), 'destroyed') : 'absent'")}), flush=True)
await asyncio.sleep(1.0)
shots.append(grab(out, "2_after"))
print(json.dumps({"shots": shots}), flush=True)
asyncio.run(main())