# libOVRPlugin.so shim (OVRPlugin v1.51 ABI -> OpenXR) Drop-in replacement for RE4 VR's `libOVRPlugin.so`. It re-exports the `ovrp_*` C ABI the game calls and implements it on **OpenXR + Vulkan** instead of Meta's `libvrapi.so`. **Status: working.** RE4 VR boots and is playable on a Quest 2 through this shim on Meta's OpenXR runtime — stereo rendering, head and controller tracking, buttons, grips, haptics, and save loading. Steam Frame is the next target; see `../HOST.md`. ## Export surface The artifact exports **438/438** `ovrp_*` symbols, matching `../analysis/all_exports.txt` exactly (0 missing, 0 extra), so any `dlsym` of any `ovrp_` resolves even for the ~199 entry points RE4 never references. | Source | Exports | What | |---|---|---| | `src/stubs.c` (generated) | 371 | 103 Unsupported (-1004), 67 no-op Success (0), 201 NotYetImplemented (-1005) | | `src/core.c` | 46 | lifecycle, frame loop, poses, controller, system info | | `src/layers.c` | 7 | `SetupLayer` / `GetLayerTexture2` / stage count / eye layer desc | | `src/vk_session.c` | 2 | the Vulkan instance/device extension queries | | `src/passthru.c` | 12 | trampolines for calls the game makes that need no real impl | `gen_stubs.sh` regenerates `src/stubs.c` from `../analysis/all_exports.txt`; functions prototyped in the header are skipped there (67 of them) and implemented in `core.c`. Regeneration is deterministic — re-running it on a clean tree produces no diff. ## Layout - `include/ovrplugin_shim.h` — the `ovrp_*` C ABI: types, structs, core prototypes. Independently written against the observed ABI, with `_Static_assert`s pinning the binary-verified struct sizes so a layout mistake fails the build rather than the device. - `src/xr_runtime.{c,h}` — the OpenXR engine: instance/session lifecycle, the frame loop, swapchains, layer composition, foveation, perf levels. - `src/vk_session.c` — Vulkan graphics binding, image enumeration, the tile-memory flush. - `src/layers.c` — layer setup and eye layer geometry. - `src/xr_input.c` — action sets and controller/haptics mapping. - `src/android_init.c` — JavaVM/activity capture, `xrInitializeLoaderKHR`, Android instance create-info chaining. - `src/passthru.c` — the author-only A/B diagnostic (see below). - `src/stubs.c` — generated. Roughly 48 distinct OpenXR entry points are used. ## Build **The deployable artifact** is Android arm64 — the game runs inside Horizon OS or Lepton: ```sh ../scripts/fetch_deps.sh # OpenXR + Vulkan headers, NDK, JDK, build-tools ./build_android.sh # -> build/arm64/libOVRPlugin.so ``` Needs the NDK (r27c) and `patchelf` (to add `NEEDED libopenxr_loader.so`). Then `../packaging/repack.sh` swaps it into your own dumped APK. **Host build** is compile-validation plus the desktop OpenXR harness, not a shipping artifact: ```sh ./build_host.sh # -> ../build/host/{libOVRPlugin.so,harness} ../tools/desktop-harness/run.sh ``` Needs libvulkan and an OpenXR loader; without the loader it builds the objects and stops. ## Debug: passthru forwarding (author-only diagnostic) `debug.re4vr.passthru=1` hands the whole OVRPlugin session to a real, SONAME-patched `libOVRPlugin_real.so` if one is present in the APK — an A/B harness for diffing native runtime behaviour against the shim. **No such binary is included or distributed by this repo**; you would have to place one from your own device dump, and without it the flag is inert. All other `debug.re4vr.*` props are likewise diagnostics. ## Known gaps - Depth layer submission is gated behind `debug.re4vr.depth` and off by default; Meta's runtime accepts but does not use plain KHR depth for reprojection. - Input binds `/interaction_profiles/oculus/touch_controller` only. - Several `debug.re4vr.*` paths are documented dead ends kept for reference (copy-ring, render-ahead, submithook); see `../docs/research/` for what each one ruled out. See `../docs/research/SHIM-SCOPE.md` for how the surface was scoped, `../TESTING.md` for the test plan, and `../docs/README.md` for the research trail.