347 Commits
Author SHA1 Message Date
spoopyghosty0 8f932dfd9b Unreal OBB delivery: recognise obfuscated DownloaderActivity predicates (#159 Medal of Honor)
Medal of Honor (com.Virtuos.R6DLM) keeps Epic's DownloaderActivity and log text but renames the delivery predicates
and OBBData, so expansionFilesDelivered wasn't found and frame.unreal_skip_obb_delivery was never offered. Detection
now also matches a boolean method in the package's DownloaderActivity, called from onCreate, that carries Epic's
"Checking for file : " log and calls the expansion-downloader helpers; the patch rewrites those too. ANALYSIS_VERSION
18 -> 19. Heuristics eval unchanged (10/66); no existing recipe affected.
2026-10-15 01:54:33 -04:00
spoopyghosty0 8169574d89 Agent: merge case-variant duplicate shortcut keys instead of refusing them (#300 follow-up)
Pre-#263 agents left shortcuts.vdf entries with both appname and AppName; vdf_decode then refused the file
("duplicate VDF key") and Add to Steam library failed. Duplicates are now merged into one key: Steam's capitalized
spelling kept, the last value taken. Clean files still round-trip unchanged.
2026-10-15 00:50:33 -04:00
spoopyghosty0 aeabb3df5a Uploads: stream small-file tar batches over OpenSSH too, Paramiko fallback (Discussion #242)
Only big files (>=8 MiB) used OpenSSH; games made mostly of small files stayed on Paramiko and were slow on a fast
link. native_upload.put_tar streams the same tar batch through system ssh with the paired key and pinned host key;
on any failure the install falls back to Paramiko's put_tar and logs it, and doesn't retry OpenSSH for later batches.
The job log now names the transport for each part. upload_bench gains app-small / paramiko-small comparisons.
2026-10-15 00:46:11 -04:00
spoopyghosty0 d073541a83 Triage: name both OBB-check options (#159), Vulkan caveat for cube stand-in (#296), flag frames-that-started-then-stopped (#301)
- unreal-obb-check-stuck names frame.unreal_skip_obb_check (CRC, needs bVerifyOBBOnStartUp) and
  frame.unreal_skip_obb_delivery (the Java name/size gate), and says neither is a guaranteed fix.
- cube-swapchain-refused: the stand-in is GLES-only; a Vulkan game can't use it yet.
- A game that submitted projection frames but then logged no pacing summary for 20 s (process alive) is reported as
  frames-stopped (info), so a hang like SKYBOX's signature check isn't a false pass. Headless no-tracking ends are
  excluded.
2026-10-15 00:38:10 -04:00
spoopyghosty0 02dce78618 Library: side notes never create an entry; drop recipe-less stubs (#294)
Play on the Steam Frame tab for a game no longer in the library wrote last_played with upsert_game, which created an
entry with only that field: listed under its package name, "Update ready", and Update / Game settings failed with
KeyError 'recipe'. library.set_fields updates existing entries only (last played, test and session results, tags,
toggles); a one-time migration drops entries made of side notes alone.
2026-10-14 23:56:02 -04:00
spoopyghosty0 5910a8d3c7 Agent 91: the logcat keeper also catches a silent or failing Lepton mirror
After "Waiting for app", a failure line or 20 s without a logcat line start FramePort's own reader, from the
launcher's start (logcat -T <epoch>) when the mirror never wrote, else from just before its last line. The reader
restarts from where it ended, stops when Lepton's lines come back, the container's log buffer is 16 MiB, and every
decision goes to logcat-keeper.log.
2026-10-14 22:27:49 -04:00
spoopyghosty0 927dae5ff8 Merge main into aarch32testing; maintainer fixes for the 32-bit bridge
Merged main (agent 90, ANALYSIS_VERSION 17/18 after main's 15/16) and rebuilt the bridge, foveation and a32
libraries from source (deterministic, no local paths).

Fixes on top:
- a32 loader: apply DT_ANDROID_RELR relocations (Journey of the Gods crashed at start)
- VrApi bridge: vrapi_Get/SetTrackingTransform (floor-level tracking; Shadow Point's player was below the floor)
- a32: never submit an untracked default head pose (hold up to 100 ms, repair or drop); pose consistency per display
  time; submit/tracking counters
- VrApi bridge: wait again when xrWaitFrame gives a display time in the refresh just submitted (the runtime rejected
  the second frame with AlreadySubmitted; Journey of the Gods ran at ~120 fps on a 90 Hz display and the scene slid
  and snapped back); pacing counters
- VrApi bridge: GLES re-entry polls events before reusing the kept session (a lost or exiting session is replaced, a
  stopped one waits for READY)
- VrApi bridge: STAGE is the runtime's STAGE space (play-area centre and orientation, unchanged by recentering);
  LOCAL_FLOOR keeps the head-based origin
- signer certificate: pick the certificate the SignerInfo names, not the first in the PKCS#7 block
- flat 32-bit apps keep the bridge (it isn't a VR-only fix)
- Frida gadget loads are stripped before translation
- launcher restart test fixed; native/.cache is no longer committed
- catalog: Shadow Point and Journey of the Gods work (headset, 2026-10-14; min_app 1.1.2)
2026-10-14 20:10:10 -04:00
spoopyghosty0 57bb69f79c VrApi bridge: save the headset's FOV only when it really changes (it was rewritten every frame)
Rebuilt libvrapi.so and libvrapi_foveation.so without the local NDK paths a worktree build left in their debug info; a test checks that no artifact contains a local path.
2026-10-14 19:45:34 -04:00
coah 13a350b3bf fix: fall back to a devkit entry when Steam drops the library shortcut
On Frames whose Steam drops FramePort's shortcuts.vdf entries on every restart
(GitHub #41/#42), "Add to Steam library" restarted Steam twice and then failed
with "Steam removed the new library entry again after restarting". Play's
fallback (the devkit entry, the one Steam keeps) was never reached because
_add_then_play gave up first.

After the second loss the shortcuts worker now adds the devkit entry while
Steam runs, so the game ends up in the library as "Devkit Game: <title>" and
the job succeeds. Agent v89.
2026-10-14 12:36:53 -04:00
spoopyghosty0 df0cc6a34f Monitor: smooth the shown numbers (time-based moving average) so they don't flicker at fast intervals 2026-10-14 12:29:22 -04:00
spoopyghosty0 3b018b6976 Opt-in frame.unreal_skip_obb_delivery for Unreal games still stuck on the downloader with the CRC check off (#283) 2026-10-14 12:27:39 -04:00
spoopyghosty0 7c066b5fea Opt-in frame.asset_files_stub: answer Meta asset-file requests for DLC managers that stall without the service (#203) 2026-10-14 12:22:13 -04:00
spoopyghosty0 095281fca5 Clear errors for a moved game APK, installer-only Linux archives and intercepted HTTPS (#278, #287, #232) 2026-10-14 12:22:00 -04:00
spoopyghosty0 f5368d73ea FramePort 1.1.1
Config files written by an older FramePort are no longer kept as the user's own (their backup brought them
back when a recipe dropped them).
2026-10-14 11:14:12 -04:00
spoopyghosty0 56e122d85f Fix release blockers in the update-skip and upload changes (agent v88)
- Check the Steam shortcut on every update, also when nothing else changed: a connection lost during
  "Add to Steam" or Steam putting its old shortcuts.vdf back left games without a library entry. The
  agent restarts Steam only when the entry really changes.
- Artwork updates for installs without a recorded artwork manifest start from a clean folder again
  (an old portrait.jpg next to a new portrait.png was picked at random for the Steam grid).
- OpenSSH uploads only rename .part files that are already complete (sftp's reput refuses them, which
  sent every resume to the Paramiko fallback).
- frame.tbxr_vendor revision 2: GL4ES ports get "Update on Frame" for the #191 draw fix.
- Configuration-only updates send the library's current Steam tags.
- finalize drops fingerprints and the artwork record an older app didn't send.
- set_settings: malformed numbers are refused before anything is written; int settings keep a
  fractional value.
- Display diagnostics use Windows PowerShell 5.1 without pwsh's PSModulePath; window diagnostics and
  the instance owner file can't stop the GUI from starting.
2026-10-14 10:58:24 -04:00
spoopyghosty0 3fcb901f8c Prefer OpenSSH for bulk uploads with resumable Paramiko fallback 2026-10-14 10:28:55 -04:00
spoopyghosty0 faea99e837 Skip unnecessary game update work and add bounded parallel uploads 2026-10-14 10:09:24 -04:00
spoopyghosty0 f6ae3f7724 Fix xLua startup on Frame with full-pointer Lua engine 2026-10-14 09:19:19 -04:00
spoopyghosty0 310863900f Add lightweight Windows display diagnostics 2026-10-13 23:41:13 -04:00
spoopyghosty0 7462317dcb Fix GL4ES draw dispatch in Team Beef ports 2026-10-13 23:25:29 -04:00
spoopyghosty0 32a2694b05 Recover windowless FramePort instances when Windows hides the lock owner 2026-10-13 20:46:47 -04:00
spoopyghosty0 693e75b19a Retry OVRPort's missing application label failure (#269) 2026-10-13 20:21:57 -04:00
spoopyghosty0 bdbe9550ba Keep saved Android recipes out of empty OVRPort conversions (#271) 2026-10-13 20:12:50 -04:00
spoopyghosty0 c1653f21b1 Fix case-insensitive Steam shortcut keys (#263) 2026-10-13 19:20:39 -04:00
UnicronNLandClaude Opus 5.5 a7b5acbd14 Library migration a32_bridge_on: the 32-bit bridge for existing 32-bit games
Recipes the user edited (source "user") are never re-derived, so a 32-bit
game whose recipe was saved before the bridge existed kept OVRPort and the
64-bit fixes and no bridge. Since 95c5de9 such a recipe can't be built at
all (build.check_a32), so it needed fixing by hand.

The one-time migration a32_bridge_on (library._migrate, after
quest_binary_fixes_v2, which adds frame.vk_sanitize to every Quest recipe)
goes over every 32-bit-only game once:
- adds frame.a32_bridge with the patch's own reason, unless the game's
  catalog entry removes it (frame_remove)
- then engine.a32_recipe as for a bridge just turned on: OVRPort and the
  64-bit fixes off, device.text_input_window for Unity, a pre-bridge
  "unsupported" becomes "unknown"; the recipe stays the user's
- recipes that already have the bridge only lose what it replaces
- skips 64-bit games, PC VR / Linux entries and "install unchanged" games

It runs once per library, so a bridge the user switches off afterwards
stays off.

Tests: a user recipe from before the bridge is migrated, a catalog
frame_remove and a 64-bit game are left alone, switching the bridge off
afterwards sticks; the game page switch test now starts from a migrated
library.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:50:05 +02:00
UnicronNLandClaude Opus 5.5 a305ecc43b a32 bridge: switch off what it replaces, and win over pre-bridge catalog verdicts
Two ways a 32-bit game ended up with a recipe that couldn't work:

- Catalog entries written before the bridge existed (Journey of the Gods,
  Shadow Point: "unsupported: the Frame has no AArch32") dropped the
  heuristic bridge suggestion like any other patch the entry didn't choose.
- Turning the bridge on by hand kept OVRPort and the 64-bit-only fixes
  (e.g. frame.vk_sanitize) on; they then failed in the build.

Now:
- A catalog entry for a 32-bit game that neither names nor removes
  frame.a32_bridge counts as older than the bridge: the bridge stays in,
  "unsupported" becomes "unknown" and the note says it's untested with the
  bridge (quoting the old verdict). Entries that name the bridge keep their
  own verdict.
- engine.a32_recipe (was _a32) also runs in pipeline.set_recipe (game page,
  CLI `recipe --enable`, Game settings dialog) and before every build. When
  the bridge has just been turned on it also adds what it needs (Unity:
  device.text_input_window) and lifts a pre-bridge "unsupported"; later
  saves only remove, so a patch the user turns off stays off.
- Which patches work on the bridge is declared per patch instead of two
  lists in the engine: Patch.a32 / base.works_on_a32. OVRPort and Frame
  fixes are off unless they say a32 = True (the bridge, the adapter, the
  launcher entry); FrameBridge settings work unless they need the xrshim
  (settings.XRSHIM_SETTINGS, the same list frame.adapter's needs_xrshim
  reads now, so a new xrshim setting is excluded by itself). Such patches
  are hidden for 32-bit games, also in the Game settings dialog.
- build.check_a32 refuses a 32-bit build without the bridge, or with OVRPort
  or a 64-bit fix on, with a plain message instead of failing inside a tool
  or producing an APK the Frame rejects (INSTALL_FAILED_NO_MATCHING_ABIS).
  engine.warnings(recipe, analysis) says the same on the game page.
- The game page redraws the patch list when the bridge switch changed other
  patches; its save uses C.update (warn.update raised when not mounted).
- Parity: a bridge build whose known-good APK is from before the bridge gets
  "new build (no baseline)" (no alt check either) and is listed apart from
  the games at parity, instead of UNEXPLAINED.

Tests: catalog verdict old vs tested, bridge turned on by hand (incl. a
later switch-off staying off), the lifted status, works_on_a32 per category,
check_a32, warnings, parity baseline + report, and the game page's switch
driven headless (no browser). Not yet built for or run on the Frame with
Journey of the Gods / Shadow Point.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:49:43 +02:00
UnicronNLandClaude Opus 5.5 2acfd64f7f Sports Scramble runs: Quest builds on the a32 bridge, Unreal's self-restart
Sports Scramble (a 32-bit Santa Cruz build: UE 4.21, OVRPlugin on VrApi 1.21)
now plays in the headset with both controllers.

a32 bridge:
- AAsset_getBuffer: the host buffer lies above 4 GiB, so the guest gets a
  copy in its own memory, freed in AAsset_close (Unreal read its
  UE4CommandLine.txt this way and aborted on the NULL it got before)
- AKeyEvent_getFlags and the remaining AConfiguration getters
- Touch controllers for Quest builds: apps that require 6DoF head tracking
  (uses-feature android.hardware.vr.headtracking version 1) get
  assets/fp_a32_headset.txt = "quest" at conversion; the bridge then passes
  both Frame controllers through (input devices, caps, state, tracking,
  vibration; struct tails per VrApi minor) and sends no synthetic touchpad
  events. Gear VR / Go games keep the remote emulation. A32_TOUCH=1/0
  overrides.

Analysis: detect.requires_6dof, headset "quest" for such 32-bit apps
(ANALYSIS_VERSION 13).

Agent 82: Unreal restarts the app once after its first-run shader precompile
(the "optimizing" screen): it starts its own launcher activity and exits, and
Lepton ends the container with the first process. Skipping the restart or
turning it off (r.ProgramBinaryCache.RestartAndroidAfterPrecompile=0) left
the game on that screen for good. launch.sh now starts Lepton once more when
the system log shows the app's own LAUNCHER start right before its
System.exit(0) (_restart_requested; first run kept as
launch-before-restart.log; FRAMEPORT_NO_RESTART=1 turns it off).
upgrade_launchers adds it to existing launchers. Crashes, quitting from the
game and Steam's Exit game don't match.

Catalog: Sports Scramble works (owner, headset, 2026-10-13).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:48:53 +02:00
UnicronNLandClaude Opus 5.5 626950e52e Gunjack runs: original APK signature for UE4's check, GLES session kept across VR re-entry
Gunjack (CCP, UE 4.10, Gear VR) quit after loading because AndroidMain compares
GameActivity.AndroidThunkJava_GetSignature() with the original signing
certificate, and then crashed in the Frame's runtime when it entered VR again.

a32 bridge:
- frame.a32_bridge: original_signature() = Base64.DEFAULT(SHA-1(signing
  certificate DER)) of the original APK (META-INF/*.RSA|DSA|EC), stored as
  assets/fp_a32_signature.txt for libUE4.so games (convert(), shared with
  bridge/convert.py)
- the bridge loads it at activity creation and answers guest calls on the
  method ID of AndroidThunkJava_GetSignature()Ljava/lang/String; with it
  (replaces the unused hex/OpenSSL prototype)

VrApi bridge: after loading, Unreal leaves VR mode and enters it again on the
same GL context; the first frame of a second OpenXR session there aborted in
vrclient (CSharedSemaphoreLinux::WaitFromGPU from the GL binding's
PreBeginFrame). vrapi_LeaveVrMode now keeps a running GLES session and
vrapi_EnterVrMode reuses it for the same context (another context still gets
a new session; Vulkan unchanged). upstream-patches/runtime.cpp.patch updated,
libvrapi.so and liba32bridge.so rebuilt.

Verified on the Frame: headless launch test passes (72 fps after re-entry);
owner-verified in the headset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:45:43 +02:00
UnicronNLandClaude Opus 5.5 4be8e3be37 a32 bridge in FramePort: patch frame.a32_bridge, Spunky Dungeon, Gunjack findings
32-bit-only APKs (Gear VR / Oculus Go games) are no longer "unsupported": the
recipe engine suggests frame.a32_bridge, which converts the APK with the
translator bridge (convert() shared with bridge/convert.py) and ships
liba32bridge.so / liba32rt.so / liba32stub.so (native/build.py --only a32).

FramePort:
- engine._a32: overport off (OVRPort is 64-bit only; the patch ships OVRPort's
  loader chain + its 32-bit platform dispatcher, overport.ensure_runtime_lib),
  only frame.a32_bridge/adapter/launcher of the frame patches, 64-bit-only
  adapter settings dropped, device.text_input_window for Unity; such patches
  are hidden in the UI
- analysis extra.headset (ANALYSIS_VERSION 9): quest / go / gearvr ->
  "Gear VR" / "Oculus Go" platform + Steam tag; catalog `headset:` field
- expects_obb ignores Unreal's OBB-inside-the-APK (assets/main.obb.png)
- catalog: com.fallen.affected, net.mobilemischief.spunkydungeon

Bridge / translator:
- VrApi 1.31 + Unity 2019 (no-config EGL contexts, LOCAL_FLOOR/STAGE tracking
  space), GL buffer mappings per buffer object (fixes a ~10 MB/s guest leak and
  garbled vertices), Go controller mapped to the right Frame controller
- native_app_glue imports (ALooper/AInputQueue/AConfiguration/AAsset*) for
  UE4 NativeActivity games (Gunjack: runs, then quits on its own APK signature
  check, which FramePort doesn't defeat)
- debugging aids: A32_BREAK, A32_STRACE to logcat, lifecycle/LeaveVrMode logs

vrapi-bridge: honours LOCAL_FLOOR/STAGE, picks a window/RGBA8 ES3 config for
no-config contexts; upstream patch updated, libvrapi.so rebuilt.

Verified on the Frame: Spunky Dungeon (Unity 2019.2, OVRPlugin 1.46) plays at
72 fps; AFFECTED The Manor still runs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:45:24 +02:00
spoopyghosty0 d787abb5df Gamepads that appear after the start reach a running 2D app; D-pad buttons in the pad layout (#162)
Agent 85: the game's container gets the host's /dev/input at /dev/fp-input (Lepton's /dev/input holds its own Wayland
input pipes) and the launcher's _gamepad_links worker keeps /dev/input/eventN links to Steam Input's virtual pads in
step while the game runs: controllers switched off and on again (Steam makes a new pad) work without a restart.
Android's EventHub adds and removes the links through inotify (dev Frame, uinput stand-in pad created after boot:
New device, Device removed, added again). Older launchers get the new gamepad line through upgrade_launchers.
The key layout also maps BTN_DPAD_* (a Steam Input layout that sends the D-pad as buttons, e.g. a stick set to
D-pad; the Frame's controllers have no D-pad of their own).
2026-10-12 23:20:29 -04:00
spoopyghosty0 81e33e7a26 Game menu: Update with a newer APK… (#161)
Pick the new APK from the game's right-click or … menu: pipeline.replace_apk checks it's the same app (refuses
another package, warns when its versionCode is older), points the entry at it and analyses it again; title, art, tags
and the user's own recipe stay, the game data stays unless the new APK's folder has its own. The game page then
offers Update on Frame.
2026-10-12 23:15:07 -04:00
spoopyghosty0 2a33c218b1 Merge branch 'worktree-agent-a259646b4d1d00ab3' into worktree-merge-pr240 2026-10-12 23:04:01 -04:00
spoopyghosty0 fbdeb700d0 A changed Frame SSH key gets its own message and a Trust the new key button; uninstall gives up its own lock
- HostKeyChanged (paramiko BadHostKeyException): not treated as "can't reach" (jobs don't pause and retry); the
  Steam Frame page explains it and offers Trust the new key (forget_host_key + reconnect); CLI frameport frame trust-key.
- Uninstall from the running app: instance.release() drops gui.lock before the data folder goes, and files still in
  use are reported as left over instead of stopping the uninstall (Windows).
Both from Reddit reports (2026-10-12).
2026-10-12 22:57:54 -04:00
spoopyghosty0 26ef64ebf9 bHaptics: skip the Android 12 Bluetooth permission request (frame.bhaptics_permission, #235)
bHaptics' vest SDK asks for BLUETOOTH_CONNECT at start; on Lepton's Android 11 the permission screen takes the
foreground for a moment and the game pauses (Yupitergrad froze on its loading screen in the reporter's session).
PermissionUtils.requestBluetoothPermission returns at once (Dex.return_early). Suggested by analysis
bhaptics_permission (ANALYSIS_VERSION 14) and triage bhaptics-permission-prompt. On the dev Frame the prompt is gone;
whether it was the whole cause of the freeze is for the reporter to confirm.
2026-10-12 22:40:49 -04:00
spoopyghosty0 8fead8387d Merge PR #247 (experimental shared eye-tracked foveation, Batman video)
# Conflicts:
#	artifacts/SHA256SUMS
#	artifacts/arm64-v8a/libopenxr_loader_generic.so
#	artifacts/armeabi-v7a/libopenxr_loader_generic.so
#	catalog/triage.yaml
#	tests/test_triage.py
2026-10-12 21:56:42 -04:00
spoopyghosty0 6419295a00 Merge PR #245 (Star Wars: Tales from the Galaxy's Edge: splash bypass, multiview depth, SideQuest layout)
# Conflicts:
#	docs/PATCHES.md
#	src/frameport/sources/quest_dump.py
#	tests/test_quest_dump.py
#	tests/test_triage.py
2026-10-12 21:48:22 -04:00
spoopyghosty0 c29cef5f97 FrameBridge: fade_quad draws colour-scale fades as a black quad over the picture (#197)
Opt-in game setting (Picture -> Draw fades over the picture). Batman: Arkham Shadow fades by dimming its projection
layer with XR_KHR_composition_layer_color_scale_bias; with fade_quad=1 FrameBridge adds a black, alpha-blended quad
right after the dimmed layer (VIEW space, 1 m ahead), opacity = 1 - scale in 16 steps. One 8x8 swapchain, refilled
only when the step changes (Vulkan clear on the app's queue / GLES clear in its context); one swapchain per step hit
XR_ERROR_LIMIT_REACHED. fade_quad=2 also removes the layer's own scale. Device (headless, Batman): swapchain created,
level 16/16 on the first frame, no xrEndFrame errors, 72 fps.
2026-10-12 21:40:01 -04:00
spoopyghosty0 289d771cc9 Merge PR #244 (The Climb: CryEngine detection, VrApi frame flags) 2026-10-12 21:22:44 -04:00
spoopyghosty0 78ac1a2865 Agent: the cloud-saves line takes the package as given (the launcher template doesn't check names elsewhere); test template call updated (#240) 2026-10-12 21:21:06 -04:00
Lucas-Mathieu e1b153915e Fix Ruff formatting checks for foveation changes 2026-10-13 02:31:35 +02:00
Lucas-Mathieu 697e96c35f Add experimental shared foveation and Batman video/loading fixes 2026-10-13 01:50:29 +02:00
Nick Leach 34d00efe0a Fix The Climb CryEngine content detection and VrApi rendering 2026-10-12 16:28:22 -06:00
Nick Leach d6c8315463 Fix Aftermath backup data detection and first-launch cloud saves 2026-10-12 16:25:43 -06:00
spoopyghosty0 7202d6ae41 Vermillion 1.7.2: canvases are painted in the scene, so the hand and brush stay visible (frame.vermillion_scene_canvas, #200)
The game showed a canvas being painted as its own compositor layer, which the Frame draws in front of everything.
PaintableMesh.HasCompositorLayerAvailable and ShouldUseCompositorOverlay return false (Cpp2IL), so the game's own
fallback draws the canvas in the scene (Klownicle's finding). Catalog recipe, PLAYBOOK row, test.
2026-10-12 18:23:56 -04:00
Nick Leach 2fe932a50f Fix Tales loading stall, clipped eye rendering, and missing backup assets 2026-10-12 16:21:23 -06:00
spoopyghosty0 1c02ebe1d3 Lint: line lengths, unused import; scripts/upload_bench.py (upload speed by method, discussion #242) 2026-10-12 18:15:09 -04:00
spoopyghosty0 b8d5b3badc Cpp2IL: Unity 6.5 games use the development build (metadata v107)
No Cpp2IL release reads Unity 6.5's metadata yet ("We support 23-106, got 107"), so the text-field and MSAA
fixes were skipped for Wander 0.3570 (#198). When the release reports an unsupported metadata version, the
development branch's CI build (nightly.link, as Cpp2IL's README links it) is fetched into tools/cpp2il-nightly/
and used; cached errors of that kind get one retry with it. Checked with Wander 0.3570: it reads the v107
metadata and writes TMP_InputField, OVRDisplay and OculusLoader.
2026-10-12 18:07:00 -04:00
spoopyghosty0 375a9d9fe2 Wander 0.3570: Unity's thread keys share one real key (frame.unity_tls_key_pool, #198)
Bionic allows 128 pthread keys per process. Unity 6 takes about 40, and with Gecko, Firebase and the Frame's own
libraries Wander 0.3570 ran out: Firestore aborted at start ("cannot create thread specific key for
__cxa_get_globals()", #198, #202). Opt-in patch, suggested for Unity 6 with Firebase C++ or Gecko: libunity.so's
pthread_key_create/_delete and pthread_get/setspecific imports are renamed in place to fp_tkey_* (new
elf.rename_imports: undefined symbols only, shared names refused, versions set global) and libfp_tkeys.so
(native/tlskeys) is added to its DT_NEEDED; keys without a destructor become generation-tagged slots behind one
real key, everything else keeps real keys. Approach and the first helper by Klownicle (#198), reimplemented here.
Triage signature pthread-keys-exhausted, PLAYBOOK row, Wander's recipe updated to 0.3570.
2026-10-12 18:06:59 -04:00
spoopyghosty0 0c05f88c5e Game menu: Update app only (discussion #180)
Installs the new build and leaves the game data on the Frame as it is (the CLI's --apk-only): a normal update
re-sends every OBB whose size differs from the PC's copy, which replaced OBBs changed on the Frame (mods). Asks
first; Quest games on the Frame only. Resume after a failure keeps the kind of update.
2026-10-12 17:58:07 -04:00
spoopyghosty0 22a324764d Space check before installs uses the drive each game goes to (#205)
New games are checked against the drive chosen on the Frame page, installed ones against their own drive, from
the drive list fetched at connect and after install jobs (app.frame_drives). Internal storage's free space only
counts when no drive list is known. drives.target_drive/space_shortfalls are pure helpers with tests.
2026-10-12 17:58:06 -04:00