Commit Graph
10 Commits
Author SHA1 Message Date
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
UnicronNLandClaude Opus 5.5 a37c75aec8 VrApi bridge: recenter from the head after the runtime's recenter
Holding the Frame's menu button turned 32-bit (and other VrApi bridge)
games 90-120 degrees to the side. The bridge's app space is LOCAL plus
the head's yaw at the start; the runtime's recenter moves LOCAL to the
head, so that old yaw was applied again. On a LOCAL reference space
change (and on vrapi_RecenterPose, ignored before) the origin is taken
from the head again in the first frame after the change, and VrApi's
recenter count goes up. Owner-verified with Gunjack.

The upstream patches are regenerated against OVRPort 5e7df52 (they
were missing the FOV cache changes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 15:58:03 +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
UnicronNLandClaude Opus 5.5 98b16b211a a32translator: Android bridge for 32-bit games (first game: AFFECTED The Manor)
32-bit ARM (armeabi-v7a) libraries run inside a normal 64-bit Android app on the
Steam Frame, without Android's native-bridge mechanism (no Lepton changes): each
libX.so becomes libX.a32.so plus a 64-bit stub, next to liba32bridge.so (the
translator + host glue) and liba32rt.so (a 32-bit static-PIE runtime with bionic's
libc/libm/libz/libstdc++ and a loader for the game's libraries). Guest and host
talk through hypercalls (SVC 0, r7 = 0x0a32xxxx).

Bridge (native/a32translator/bridge):
- JNI both ways: generated + hand-written JNIEnv/JavaVM, RegisterNatives and
  Java_* exports through AAPCS64 -> AAPCS32 trampolines, handles for references,
  arrays/strings shared when below 4 GiB, else copied
- NativeActivity glue, libandroid imports (weak, generated from imports.txt)
- GLES 3.2 + extensions + EGL: 996 functions generated from the NDK headers
- OpenSL ES output implemented in the guest, played through AAudio
- VrApi 1.x (Gear VR era) translated to the 64-bit VrApi -> OpenXR bridge,
  including OVRPlugin 1.12's frame layout and its wrapped (app texture) chains
- controller input as Gear VR touchpad/back/gamepad events (UnityPlayer.injectEvent)
- convert.py: prototype of the APK conversion (FramePort patch to follow)
- PC harness with a fake JVM (32 checks, qemu or native) and an on-device test APK

Translator fixes found on the way: guest signals during blocking system calls
and in host code (Boehm GC deadlock in Unity's Mono), static-PIE start files and
PT_TLS/PT_GNU_RELRO bias, host fault chaining, stderr to logcat in bridge mode.

vrapi-bridge: OVP_HEADLESS_TEST=1 skips the wait for a tracked head (automated
tests without a worn headset); upstream-patches/runtime.cpp.patch updated.

Verified on the Frame (2026-10-10): AFFECTED The Manor (Unity 5.6 + Mono,
OVRPlugin 1.12) runs in the headset with picture and sound; controls in progress.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:41:43 +02:00
Lucas-Mathieu 697e96c35f Add experimental shared foveation and Batman video/loading fixes 2026-10-13 01:50:29 +02:00
spoopyghosty0 aff939a6d8 BlazeRush native fixes (GitHub #57, Klownicle's guide): GL shim gl_int_attribs (integer vertex inputs fed as floats re-set with glVertexAttribIPointer per draw, per-context reflection dropped on link/binary/delete) and gl_highp_markers (matching vertex shaders compute in highp); VrApi bridge answers FOV properties 7/8 before any session with the live FOV saved by an earlier session (also located before tracking); FrameBridge logs the runtime's unscaled eye size 2026-10-10 23:18:41 -04:00
spoopyghosty0 2995413434 VrApi bridge: vrapi_PollEvent returns ovrSuccess_EventUnavailable (1002), vrapi_SetTrackingSpace returns an ovrResult, vrapi_CreateTextureSwapChain/2 take VrApi's 32-bit format enum (found while preparing the upstream PRs) 2026-10-06 14:31:40 -04:00
spoopyghosty0 dca2d8b762 VrApi bridge: vrapi_PollEvent, RecenterPose, SetDisplayRefreshRate, GetSystemPropertyFloatArray (BlazeRush couldn't load: cannot locate symbol vrapi_PollEvent, GitHub #57); static check 'VrApi functions resolvable', triage vrapi-symbol-missing; upstream-patches regenerated (graphics.cpp.patch was stale: the Vulkan format twin was missing from it) 2026-10-06 13:23:52 -04:00
spoopyghosty0 0470a2910a FramePort: modular Quest → Steam Frame porting app
Python core + Flet GUI + CLI that turns the manual Steam Frame porting work
into a pipeline: scan dumps, analyze, suggest patches (overport + Frame fixes,
catalog of 34 verified recipes), build, static-validate, install over SSH via
a Frame-side agent, add Steam shortcuts with artwork, headless launch test and
log triage. Includes the native sources (FrameBridge adapter, VrApi bridge
patches, GL shim), prebuilt artifacts, docs (playbook, runtime notes) and a
parity harness (34/34 games reproduce the known-good builds).
2026-09-28 21:00:29 -04:00