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

80 lines
3.9 KiB
Markdown

# ovrplugin-openxr-shim
A from-scratch reimplementation of Meta's `libOVRPlugin.so` on top of **OpenXR**,
so legacy VrApi/OVRPlugin-based Meta Quest titles can run on standard OpenXR
runtimes — Valve's **Steam Frame** (SteamVR inside Lepton), Monado, and others.
**Status:** *Resident Evil 4 VR* boots and is playable on a Quest 2 through this
shim — stereo rendering, head + controller tracking, buttons, grips, haptics, and
save loading all work. (Developed as a preservation / interoperability experiment.)
## What it is
Quest's `libOVRPlugin.so` is the C shim Unreal/Unity games call to talk to Meta's
VR runtime. Meta deprecated the underlying VrApi in 2022 and the whole modern stack
(incl. Steam Frame's SteamVR) is OpenXR-only, so VrApi-era titles have no runtime on
non-Meta OpenXR platforms. This project re-exports the `ovrp_*` C API backed by
OpenXR instead, as a **drop-in replacement** `libOVRPlugin.so`:
```
game (libUE4.so) ──ovrp_* C API──> [THIS SHIM] ──OpenXR──> runtime (SteamVR / Meta / Monado / …)
```
It implements the OpenXR instance/session lifecycle, the Vulkan graphics binding,
the frame loop + swapchains, layer compositing, and action-based input — mapping all
of it to the `ovrp_*` ABI the game expects.
## Legal / scope
- This repo contains **only original code**. It does **not** include or redistribute
any game, the Meta runtime, Meta's headers, or Epic's UnrealEngine source. You
must build the shim yourself and apply it to a copy of a game **you legally own and
dump yourself** (patch-only, dump-your-own — like ROM-hack patches).
- Reimplementing an API for interoperability is the goal here; no proprietary binaries
or decompiled source are published.
- Entitlement/ownership checks are **out of scope**: this project ships no circumvention code
and circumvents nothing. On Quest the platform's real entitlement check runs unchanged (you
own the title). Running on hardware with no Meta backend requires a valid entitlement by
other means — that is the user's responsibility and not provided here.
- Not affiliated with or endorsed by Meta, Capcom, Epic Games, or Valve. All
trademarks belong to their owners.
- Provided as-is, no warranty. You are responsible for compliance with applicable law and
the terms of any software you use it with, in your jurisdiction.
## Build
```sh
scripts/fetch_deps.sh # OpenXR + Vulkan headers (Apache-2.0), NDK, JDK, build-tools
shim/build_android.sh # -> shim/build/arm64/libOVRPlugin.so
packaging/build_openxr_loader.sh # -> packaging/libs/arm64/libopenxr_loader.so
```
`fetch_deps.sh` pins the header versions; override with `OPENXR_TAG` / `VULKAN_HEADERS_TAG`.
From your distro you also need **`patchelf`** (the Android build fails without it — the shim
cannot resolve the OpenXR loader) and **`cmake`** (for the loader build). A host x86-64 build
is also supported for compile-validation and the desktop harness: `shim/build_host.sh`.
## Use (with your own dumped game)
```sh
packaging/repack.sh /path/to/your/base.apk # swap the shim in, re-sign
adb install -r packaging/out/<game>-shim.apk
# push your own dumped OBB, then launch on a dev-mode Quest
```
See `packaging/README.md` and `TESTING.md` for the full flow.
## Layout
- `shim/src/` — the implementation: `xr_runtime` (session/frame loop/swapchains),
`vk_session` (Vulkan binding + ext), `layers`, `xr_input` (action sets), `core`
(the ovrp_* entry points), `android_init`, generated `stubs`.
- `shim/include/ovrplugin_shim.h` — the `ovrp_*` C ABI (clean-room from observed ABI).
- `packaging/` — repack/sign tooling.
- `docs/` — research notes + session handoffs (`docs/README.md` narrates how the
frame-pacing "ghost" was solved); `TESTING.md`/`HOST.md` at root.
## Acknowledgements
Built against the [OpenXR](https://www.khronos.org/openxr/) and
[Vulkan](https://www.vulkan.org/) specs and the Khronos OpenXR loader.