Files
Daniel LynchandClaude Opus 5 1f3dc40c07 docs+build: hygiene pass — close leak risk, de-drift docs, fix build prereqs
Repo hygiene round following a full review. No shim behaviour changes.

Leak risk:
- .gitignore: ignore CLAUDE.md (personal assistant-lane config, was one
  `git add -A` away from a public commit) and scratch_obj/.

Docs vs. reality:
- shim/README.md: rewritten. It described a pre-implementation skeleton with
  "core fns are TODO stubs returning -1005", three mutually inconsistent stub
  counts, and four completed milestones listed as open. Now carries the verified
  breakdown: 438/438 exports = 371 generated stubs + 46 core + 7 layers + 2
  Vulkan queries + 12 passthru trampolines.
- TESTING.md: dropped the self-contradicting "NOT yet" block (5 of 6 items were
  done or misstated, and contradicted the same file 45 lines above). Path B now
  points at tools/desktop-harness, which exists, instead of the orphaned
  shim/tests/harness.c. Path A prereqs marked as the record they are.
- HOST.md: corrected the runtime assumption. The OpenXR runtime inside Lepton is
  SteamVR (vendor/etc/openxr/1/active_runtime.json -> vrclient.so), not Monado.
  Favourable: SteamVR emulates Oculus Touch by default and advertises the
  XR_FB_foveation family, so the existing input and foveation paths should carry
  over. The old "remaining unknowns" are resolved by Lepton's published source
  and replaced with the items to check before a first Frame boot.
- README.md: same runtime correction.
- docs/research/RECON.md: the four passages prescribing an entitlement
  NOP/stub/bypass are corrected in place rather than merely disclaimed by the
  top banner, which they contradicted.

Build correctness:
- shim/build_android.sh: missing patchelf is now fatal. It warned and exited 0,
  producing a .so that cannot resolve the OpenXR loader at runtime.
- scripts/fetch_deps.sh + packaging/build_openxr_loader.sh: pin the OpenXR and
  Vulkan header versions (were tracking `main`), overridable via OPENXR_TAG /
  VULKAN_HEADERS_TAG; require cmake for the loader build.
- packaging/steamframe_patches.sh: use the apktool.jar that fetch_deps.sh
  downloads. Its prereq check demanded an `apktool` binary on PATH that the
  documented setup never provides, so it could not run after a clean setup.
- shim/gen_stubs.sh: it reads all_exports.txt, not shim_surface.txt; comment and
  emitted banner corrected. stubs.c regenerated (banner line only).
- shim/src/core.c: split seven `if (out) ...; return ...;` one-liners. Host
  build now compiles with zero warnings, down from seven.

Verified: host build 0 warnings; gen_stubs.sh output identical on regeneration;
bash -n clean on all edited scripts; pinned header/tarball URLs return 200 and
the tag tarball extracts to the expected directory name.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 02:15:10 -04:00
..

Packaging — repack the RE4 VR APK with the shim

Produces an installable, re-signed APK with our OpenXR libOVRPlugin.so swapped in. The original libovrplatformloader.so is kept untouched, so the platform's real entitlement check runs unchanged — on Quest you own the title. Dump-your-own only; nothing here is redistributed. Entitlement handling on hardware with no Meta backend is out of scope for this project and is the user's responsibility. See ../TESTING.md for the on-device plan.

One-time setup

./build_openxr_loader.sh     # builds libopenxr_loader.so (arm64) -> libs/arm64/
./make_debug_keystore.sh     # debug.keystore for re-signing (repack.sh auto-runs it)

Also build the shim libs first: ../shim/build_android.sh.

Repack

./repack.sh [input.apk]
# example:
./repack.sh                          # ../dump/base.apk

Swaps only libOVRPlugin.so + bundles libopenxr_loader.so, and keeps the original libovrplatformloader.so so the platform's real entitlement check runs unchanged.

Output: out/re4vr-shim.apk (zipaligned, v1+v2+v3 signed with the debug key).

Off-Quest port (Pico / Steam Frame / Monado-on-Android)

./steamframe_patches.sh [in.apk] [out.apk]   # default: out/re4vr-shim.apk -> out/re4vr-steamframe.apk

Run AFTER repack.sh (which swaps in our shim). Needs apktool. Applies the Java/manifest fixes a non-Quest target needs but a real Quest doesn't: spoofs Build.MANUFACTURER/MODEL so UE takes the Oculus HMD path (else our shim is never called), neuters AndroidThunkJava_ForceQuit, and strips Meta-only <uses-(native-)library> manifest entries (keeps libopenxr.google.so). Rationale + the patches we deliberately skip: ../docs/research/related-work.md. Prepared for the bring-up; not yet hardware-validated.

⚠️ Do NOT install the output on a Quest — the manifest strip removes Meta libs the Quest needs. The script warns + prompts for confirmation; pass NOT_QUEST=1 to bypass the prompt in automation. On a Quest, install the plain repack.sh output (out/re4vr-shim.apk).

Install + run (Quest, dev mode)

adb install -r out/re4vr-shim.apk
# push the OBB you dumped (same versionCode 203):
adb push ../dump/obb/main.203.com.Armature.VR4.obb  /sdcard/Android/obb/com.Armature.VR4/
adb push ../dump/obb/patch.203.com.Armature.VR4.obb /sdcard/Android/obb/com.Armature.VR4/
adb logcat | grep -iE 'xrr|openxr|OVRPlugin|Armature'   # watch [xrr] logs

Manifest

./inspect_manifest.sh [input.apk]    # confirms VR/OpenXR declarations are present

RE4 VR is already a shipping Quest VR app, so its manifest almost certainly already has the headtracking feature + VR intent category; switching vrapi->OpenXR usually needs no manifest change. inspect_manifest.sh reports any gaps; edit the decoded manifest + rebuild with apktool only if something's missing.

Notes

  • Re-signing with our own key is unavoidable (we modify a lib). That's what risks the legit entitlement on Quest — see ../TESTING.md.
  • Libs are added stored (-0) and the APK is zipalign -p 4'd so native libs stay page-aligned (extractNativeLibs=false convention).
  • Tools used: tools/android-14 (build-tools 34: zipalign/apksigner), tools/apktool.jar, tools/jdk-21 (keytool), tools/android-ndk-r27c (loader build).