mirror of
https://github.com/Toastconcern/FrameStudio.git
synced 2026-10-29 00:02:23 +01:00
Headset programs rebuilt from the current source; releases can't ship them stale
The committed frame/payload still had Frame Home from Oct 21, which opens baked scenes up to v13, while Studio has saved v14 since wall spots were removed: every environment saved and sent from a release failed on the headset with "baked scene from a different Frame Studio version". - frame/payload: frame-home and fenv-tool rebuilt on the Frame from this source (byte-identical to what is installed there now). - frame/payload/SOURCE + scripts/frame-payload.sh: records the source the headset programs were built from; CI checks it in the installer job and in the release job, so nothing is published beside an outdated headset build. - fenv-tool version prints the newest baked scene it opens; Studio asks before Send to Frame and Calculate Best Settings and says to update Frame Home instead of sending a file the headset can't open. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fedadd5ae3
commit
5e2b42d487
8 files changed
+72
-3
No files matched your search
@@ -104,6 +104,8 @@ jobs:
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Headset programs match the source
|
||||
run: sh scripts/frame-payload.sh check
|
||||
- name: Package
|
||||
run: sh scripts/build-studio.sh frame-home
|
||||
- uses: actions/upload-artifact@v4
|
||||
@@ -134,6 +136,10 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: src
|
||||
# Every download carries frame/payload: none is published beside headset programs older than the source
|
||||
# (Studio would save environments the headset can't open).
|
||||
- name: Headset programs match the source
|
||||
run: sh src/scripts/frame-payload.sh check
|
||||
# What Frame Studio (studio/updater.h) and the headset's Environments panel check for updates: this commit,
|
||||
# Frame Home's identity (a hash of the headset programs, the same one the panel works out for what's installed)
|
||||
# and the files in this release.
|
||||
|
||||
+11
-2
@@ -173,8 +173,17 @@ headset, copy the results into it:
|
||||
|
||||
`frame/payload/install.sh` is the installer itself; it lives in the repository and needs no build.
|
||||
|
||||
Commit the new payload together with the code that changed. Otherwise Studio's **Install on Steam Frame** would
|
||||
install an older Frame Home than the code says.
|
||||
Then record which source they were built from, and commit the new payload together with the code that changed:
|
||||
|
||||
```sh
|
||||
sh scripts/frame-payload.sh stamp
|
||||
```
|
||||
|
||||
`frame/payload/SOURCE` holds a hash of everything the headset side is built from (`src/`, `third_party/`, `layer/`,
|
||||
`CMakeLists.txt`). `sh scripts/frame-payload.sh check` tells you whether the payload is still current. The release
|
||||
build runs it too and publishes nothing while the payload is older than the source: a Studio beside an older Frame
|
||||
Home saves environments the headset can't open. Studio also asks the headset (`fenv-tool version`) before
|
||||
**Send to Frame** and says when its Frame Home needs updating.
|
||||
|
||||
## Repository layout
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ed589d9db53c920be66e9334cc86e88e2893c2d410437d538477109cbf2fc02d
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
# The Steam Frame programs in frame/payload are built on the headset (arm64 SteamOS, its compositor's Vulkan driver)
|
||||
# and committed; every Frame Studio download and the Frame Home installer ship them. frame/payload/SOURCE records the
|
||||
# source they were built from, so Studio is never released beside an older headset build (Studio would save
|
||||
# environments the headset can't open).
|
||||
#
|
||||
# scripts/frame-payload.sh stamp after copying freshly built programs into frame/payload
|
||||
# scripts/frame-payload.sh check fails when the headset's source changed since (CI runs it before releasing)
|
||||
set -eu
|
||||
ROOT=$(cd "$(dirname "$0")/.." && pwd)
|
||||
STAMP="$ROOT/frame/payload/SOURCE"
|
||||
|
||||
# What the headset programs are built from (studio/ is Studio's alone), as the files are now: committed or not.
|
||||
source_hash() {
|
||||
list=$(mktemp)
|
||||
(cd "$ROOT" && git -c core.quotepath=off ls-files -- src third_party layer CMakeLists.txt > "$list" &&
|
||||
git hash-object --stdin-paths < "$list" | paste -d ' ' - "$list" | sha256sum | cut -c1-64)
|
||||
rm -f "$list"
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
stamp) source_hash > "$STAMP"
|
||||
echo "frame/payload/SOURCE: $(cat "$STAMP")" ;;
|
||||
check) want=$(source_hash)
|
||||
have=$(cat "$STAMP" 2>/dev/null || true)
|
||||
if [ "$want" != "$have" ]; then
|
||||
echo "frame/payload is out of date: the headset's source changed since its programs were built." >&2
|
||||
echo "Rebuild frame-home, frame-switcher and fenv-tool on the Frame, copy them into frame/payload/bin," >&2
|
||||
echo "then run scripts/frame-payload.sh stamp (docs/building.md)." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "frame/payload matches the source ($want)" ;;
|
||||
*) sed -n '2,8p' "$0"; exit 2 ;;
|
||||
esac
|
||||
+4
-1
@@ -435,6 +435,8 @@ int tune(const std::string& home, const std::string& benchArg, int seconds, doub
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// The newest baked scene this build opens: Frame Studio asks before sending (an older headset can't open a newer one).
|
||||
if (argc == 2 && !std::strcmp(argv[1], "version")) { std::printf("scene %u\n", kSceneBakeVersion); return 0; }
|
||||
if (argc >= 3 && !std::strcmp(argv[1], "info")) return info(argv[2]);
|
||||
if (argc >= 4 && !std::strcmp(argv[1], "bundle")) {
|
||||
std::string name;
|
||||
@@ -529,6 +531,7 @@ int main(int argc, char** argv) {
|
||||
" fenv-tool upgrade file.fenv... re-bake with this build (keeps world, edits, sound, picture)\n"
|
||||
" fenv-tool report [--json] <home.apk | home.fenv | footprint.apk+vista.apk>... what it costs and what's wrong with it\n"
|
||||
" fenv-tool settings <home.fenv | home.apk> [JSON | --clear] a world's own settings, shown or set\n"
|
||||
" fenv-tool tune [--seconds 30] [--late 0.01] [--cool 80] [--dry-run] <home.fenv | home.apk> its best settings on this headset, stored in it\n");
|
||||
" fenv-tool tune [--seconds 30] [--late 0.01] [--cool 80] [--dry-run] <home.fenv | home.apk> its best settings on this headset, stored in it\n"
|
||||
" fenv-tool version the newest baked scene this build opens\n");
|
||||
return 2;
|
||||
}
|
||||
@@ -2234,6 +2234,7 @@ struct Studio {
|
||||
setTuneStatus("Copying it to the headset\u2026");
|
||||
int rc = run(ssh + L"\"mkdir -p /tmp/frame-tune && rm -f /tmp/frame-tune/log\"", L"", out);
|
||||
if (rc != 0) { setTuneStatus("Can't reach the headset (" + host8 + "): " + lastLine(out)); tuning = false; return; }
|
||||
if (const std::string why = headsetCantOpen(host8); !why.empty()) { fs::remove(f, ec); setTuneStatus("Not measured. " + why); tuning = false; return; }
|
||||
out.clear();
|
||||
rc = run(scp + L"\"" + f.filename().wstring() + L"\" " + widen(host8) + L":/tmp/frame-tune/tune.fenv", f.parent_path().wstring(), out);
|
||||
fs::remove(f, ec);
|
||||
@@ -2382,6 +2383,20 @@ struct Studio {
|
||||
return png;
|
||||
}
|
||||
|
||||
// Why the headset's Frame Home can't open what this Studio saves, or "" when it can: its fenv-tool names the newest
|
||||
// baked scene it opens ("scene N"; a build from before that question prints its usage instead).
|
||||
std::string headsetCantOpen(const std::string& host8) {
|
||||
std::string out;
|
||||
const int rc = run(sshTool(L"ssh") + L"-o BatchMode=yes -o ConnectTimeout=8 " + widen(host8) + L" \"frame-home/bin/fenv-tool version\"", L"", out);
|
||||
if (rc == 127 || out.find("not found") != std::string::npos)
|
||||
return "Frame Home isn't installed on the headset: Headset > Install on Steam Frame first.";
|
||||
const size_t at = out.find("scene ");
|
||||
const long reads = at == std::string::npos ? 0 : std::strtol(out.c_str() + at + 6, nullptr, 10);
|
||||
if (reads >= static_cast<long>(kSceneBakeVersion)) return {};
|
||||
return "The headset's Frame Home is older than this Frame Studio and can't open what it saves: "
|
||||
"Headset > Install on Steam Frame updates it.";
|
||||
}
|
||||
|
||||
// A footprint with its vista goes to the Frame as one home in one file: the pair baked into a .fenv with the
|
||||
// edits, world layer and background sound (what Save Environment writes). The pair's separate copies an earlier
|
||||
// Send left there go, so the headset lists it once.
|
||||
@@ -2411,6 +2426,7 @@ struct Studio {
|
||||
setStatus("Connecting to the Frame\u2026");
|
||||
int rc = run(ssh + host + L" \"mkdir -p " + dir + L"\"", L"", out);
|
||||
if (rc != 0) { setStatus("Can't reach the Frame: " + lastLine(out)); sending = false; return; }
|
||||
if (const std::string why = headsetCantOpen(host8); !why.empty()) { setStatus("Not sent. " + why); sending = false; return; }
|
||||
std::error_code ec2;
|
||||
char msg[200];
|
||||
std::snprintf(msg, sizeof msg, "Copying %s (%.0f MB)\u2026", name.c_str(), fs::file_size(f, ec2) / 1048576.0);
|
||||
|
||||
Reference in new issue
Block a user