Commit Graph
43 Commits
Author SHA1 Message Date
simplysanatori 4b85f24bb4 toolchain: mingw container build, SEH shim, ABI rewrite, run scripts 2026-10-28 02:56:44 -04:00
simplysanatori 02a7210b4c overlay: single-pass tooltip matches always-enabled DXVK stereo 2026-10-28 02:35:02 -04:00
simplysanatori e66bcd9915 merge lane/m3-hotkey 2026-10-28 02:34:55 -04:00
simplysanatoriandClaude Sonnet 5.5 54f3467244 hotkey: Shift+F6 single-pass toggle; panel: single-pass checkbox, HUD offset sliders (M3-K)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 02:34:42 -04:00
simplysanatori 74fa70604c merge lane/m3-proxy 2026-10-28 02:34:19 -04:00
simplysanatoriandClaude Opus 5.5 e4c8f2b082 proxy: enable single-pass in DXVK whatever stereo_mode says (M3-P)
With stereo_same_frame = 1 and our DXVK present, EnableSinglePassStereo is
called at CreateDevice regardless of [vr] stereo_mode, so every vertex
shader gets the stereo variant and Shift+F6 can A/B from either start.
stereo_mode now only picks the starting path (default twopass until M5
sign-off); the enable line is followed by
"stereo: starting in two-pass (stereo_mode=twopass)" or
"stereo: starting in single-pass (stereo_mode=singlepass)".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 02:34:04 -04:00
simplysanatori a4edbaa32e Merge remote-tracking branch 'origin/lane/m3-proxy' into lane/m3-hotkey 2026-10-28 02:33:37 -04:00
simplysanatoriandClaude Opus 5.5 770ba86395 proxy: route eligible scene draws through single-pass stereo (M3-P)
dispatch_draw: a scene draw (stereo_passes() == 2) goes out once, armed
with both eyes' c0, when single-pass is active and the draw is eligible
(not the reflection pass, no per-eye textures, a vertex shader bound, no
stream instancing). Diorama hands-in-front squeezes the game viewport's
depth range around the one draw (DXVK gives both eye viewports the
current MinZ/MaxZ), so it needs no fallback. Every other draw is
disarmed first: two-pass fallback, mono, reflection pass, ImGui overlay;
EndScene, Present and Reset disarm as well.

Tracking for eligibility: own vertex-shader-bound flag (SetVertexShader)
and instance-data streams (SetStreamSourceFreq, as DXVK tracks them),
both reset by Reset. SetVertexShaderConstantF notes whether c0..c3 hold
the noted upload, for the carry-over. CreateDevice enables single-pass
right after vr_submit_init; the device destructor drops the interface.

With stereo_mode = twopass nothing armed ever exists, so the two-pass
path issues exactly the device calls it did before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 02:32:35 -04:00
simplysanatoriandClaude Opus 5.5 5f41f9e342 proxy: single-pass stereo core in stereo.cpp (M3-P, SPS-VI)
- stereo_device_created: QI IDirect3DVR9 for IDirect3DVRStereo9 and call
  EnableSinglePassStereo(1) at CreateDevice when [vr] stereo_mode =
  singlepass, with the three PLAN log lines.
- stereo_single_begin/_end: both eyes' c0 from vr_substitute_c0_for_eye,
  left then right (sky-pinning call count and zoom EMA unchanged), with
  the two-pass carry-over (a failed eye keeps what c0 held: left the
  register before the draw, right the left's). Sticky SetStereoDraw:
  skipped when both matrices and the eye size are bitwise unchanged.
  After the draw c0 ends as two-pass leaves it.
- stereo_single_pass_eligible: eye textures, fixed-function, instancing,
  counted by reason.
- stereo_disarm / stereo_end_scene: ClearStereoDraw when leaving stereo
  draws; 5 s "stereo stats:" line with [vr] stereo_stats = 1.
- stereo_set_single_pass / stereo_single_pass_active implemented (live
  toggle logs "stereo: live toggle -> single-pass|two-pass (Shift+F6)").
- stereo_begin_pass split into viewport and c0 helpers (same calls, same
  order) so a failed arm can fall back to two-pass with the matrices
  already made.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 02:32:35 -04:00
simplysanatoriandClaude Opus 5.5 00af0726ad proxy: reflection_stereo_draw_needs_eye_textures predicate (M3-P)
True when reflection_stereo_eye_textures would swap a texture for the draw
about to be issued: a stage holds the reflection while its twin is drawn
per eye, or the WaterFX screen copy while it is split by eye. Same tests,
no side effects. Such draws need a texture per eye and stay two-pass under
single-pass stereo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 02:32:35 -04:00
simplysanatoriandClaude Opus 5.5 db86c56d96 proxy: stereo_mode / stereo_stats keys and the single-pass toggle API (M3-P)
[vr] stereo_mode = twopass|singlepass (default twopass until M5 sign-off)
and [vr] stereo_stats = 0|1, with ini comments and migration defaults.
The vr_runtime comment notes that the Steam Frame uses openvr.

Agreed with lane M3-K (hotkey/panel), declared in src/vr/stereo.h:
  void stereo_set_single_pass(bool on);
  bool stereo_single_pass_active();
Stubbed here; the single-pass path follows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 02:27:22 -04:00
simplysanatori 3bf17b3bbc merge lane/m2-harness 2026-10-28 02:22:45 -04:00
simplysanatori 6e89007015 merge lane/m2-shader 2026-10-28 02:22:45 -04:00
simplysanatori 09cc4c86ae merge lane/m2-device 2026-10-28 02:22:45 -04:00
simplysanatoriandClaude Opus 5.5 520f7939bd dxvk: stereo VS push flag as a scalar push data member; one-call failure log
A one-member struct is not a struct type in the IR, so the stereo flags
push data is declared and loaded as a plain u32 (spirv-val rejected the
extra access chain index). The lowering-failure warning and its reason
are emitted in one Logger call so they stay together across compiler
threads.

Validated with the M2-C harness (all cases maxdiff 0) and spirv-val on
the dumped _sps1 shaders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 02:22:05 -04:00
simplysanatori 19cff33e14 Merge remote-tracking branch 'origin/lane/m2-device' into lane/m2-shader 2026-10-28 02:17:28 -04:00
simplysanatoriandClaude Opus 5.5 8c6a7d2b02 dxvk: single-pass stereo VS lowering (SPS-VI, M2-A)
D3D9ShaderOptions::stereoMode selects the stereo variant for vertex
shaders: cache name gets the _sps1 suffix, the static CBV always uses the
uvec4 array layout with the 8-vec4 bank appended, every c0..c3 read
(static and relative) becomes armed ? bank[view*4+i] : c[i], and a
prologue writes ViewportIndex = armed ? (InstanceId & 1) : 0. Lowering
failure falls back to the mono variant and is logged once; the device
asks D3D9CommonShader::IsStereoCapable().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 02:17:28 -04:00
simplysanatoriandClaude Opus 5.5 806a996581 dxvk: single-pass stereo device side (SPS-VI, M2-B)
IDirect3DVRStereo9 is implemented on the existing D3D9VR object (one
refcount, QueryInterface returns either interface; IUnknown identity is the
IDirect3DVR9 pointer). Device side, per DESIGN 5.1:

- EnableSinglePassStereo: needs multiViewport + shaderOutputViewportIndex,
  the shader-side D3D9ShaderOptions::stereoMode (detected at compile time,
  so this branch builds and stays off without M2-A), d3d9.trlvrSinglePass,
  and no vertex shader created yet. From then on every VS is created with
  stereoMode = 1 (PS options and keys unchanged). Mode 0 = caps query.
- SetStereoDraw is sticky: a bitwise-identical bank and eye size cost no
  upload; ClearStereoDraw disarms; Reset (ResetState) disarms.
- UpdateShaderConstants<VS>: once enabled every VS static CBV gets 128 B
  more at 16 * (Fs + I + ceil(B/4)); the bank (L c0..c3, R c0..c3) is
  written there while armed.
- BindViewportAndScissor: viewport building factored into BuildViewport;
  armed draws bind 2 viewports {eye*w, 0, w, h} with the game's MinZ/MaxZ,
  the 0.5 offset and the scissor clip per eye, as two SetViewport calls do.
- Draw, DrawIndexed, DrawUP, DrawIndexedUP: instanceCount 2 while active;
  VS push flags at offset 20 (PushDataStereo dirty flag).
- An armed draw that cannot be single-pass (fixed-function VS, stream
  instancing, or a VS whose lowering failed per IsStereoCapable) is counted
  as rejected, logged once, and drawn by DXVK per eye (eye viewport and
  that eye's c0..c3, then c0..c3 restored), i.e. the two-pass result
  instead of a missing right eye.
- GetStereoStats: stereo draws and rejections since device creation.

Log lines: "D3D9VR: single-pass stereo enabled (viewport index, bank 8
vec4, key _sps1)", "D3D9VR: stereo draw rejected (instanced) -- reported
once". Mono draws while not armed: one viewport, flag 0, instance 1; the
only difference once enabled is the 128 B CBV tail. TransferSurface and
the submit paths are untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 02:12:39 -04:00
simplysanatoriandClaude Opus 5.5 9f380e3c7d dxvk: d3d9.trlvrSinglePass kill switch (default True)
New D3D9Options::trlvrSinglePass, read from d3d9.trlvrSinglePass, and
stated explicitly in the trl_vr.exe profile. False makes
IDirect3DVRStereo9::EnableSinglePassStereo fail with D3DERR_NOTAVAILABLE
and log "D3D9VR: single-pass disabled by d3d9.trlvrSinglePass", so the
proxy stays on two-pass (PLAN rollback level 3, via DXVK_CONFIG/dxvk.conf).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 02:12:39 -04:00
simplysanatori ba275f2f83 merge lane/m2-device (frozen stereo header) into harness 2026-10-28 02:03:38 -04:00
simplysanatoriandClaude Sonnet 5.5 5b40400bba test: stereotest harness for single-pass stereo (M2-C)
stereotest.exe loads d3d9_dxvk.dll directly, renders a clipped, perspective
coloured scene into a 2W x H RT two-pass and single-pass (IDirect3DVRStereo9),
and compares readbacks. Cases: static c0, relative a0, call/ret, MSAA 2x,
scissor, mono after ClearStereoDraw, instanced rejection. shaders are emitted
by an in-file token builder (no d3dx). toolchain/stereotest.sh builds in the
legendframe-mingw image and runs headless under Proton 11 ARM64.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 02:03:31 -04:00
simplysanatoriandClaude Opus 5.5 da69654f1b dxvk: freeze the single-pass stereo contract (IDirect3DVRStereo9 v1)
d3d9_vr.h: IDirect3DVRStereo9 (IID d77445fd-6e00-4860-9a84-4020d143004c),
reached by QueryInterface on the IDirect3DVR9 object: EnableSinglePassStereo
(Mode 1 = viewport index, Mode 0 = caps query), SetStereoDraw(c0L[16],
c0R[16], eyeW, eyeH) sticky, ClearStereoDraw, GetStereoStats; caps struct
with Version 1. Constants for the shader and harness lanes: VS push flags at
offset 20 (bit 0 = armed), bank of 8 vec4 (L c0..c3, R c0..c3) appended to
the VS static CBV at 16 * (Fs + I + ceil(B/4)), key suffix "_sps1",
D3D9ShaderOptions.stereoMode.

d3d9_state.h: D3D9StereoPushData at sizeof(D3D9VsPushData) +
sizeof(D3D9FfvsPushData) = 20, inside the 40 B VS push block.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 02:00:34 -04:00
simplysanatori 3104624571 docs: single-pass stereo design and milestone plan 2026-10-28 01:56:07 -04:00
simplysanatori 8c5332bcdc merge lane/frame-install 2026-10-28 01:53:36 -04:00
simplysanatori 40a635cab7 merge lane/frame-controller-type 2026-10-28 01:53:36 -04:00
simplysanatori 893c2c4852 merge lane/frame-bindings 2026-10-28 01:53:36 -04:00
simplysanatori c2eec8da95 merge lane/hud-offset 2026-10-28 01:53:36 -04:00
simplysanatoriandClaude Sonnet 5.5 c29c0f7ac1 docs: LegendFrame README and Steam Frame install and tuning guide
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 01:53:11 -04:00
simplysanatoriandClaude Sonnet 5.5 828a275e48 frame: Steam Frame installer, uninstaller and shortcut scripts
install.sh backs up and copies the payload with a manifest, seeds trlvr.ini,
the game registry and SteamVR per-app settings, and queues the Steam shortcut
through a self-deleting steam.service drop-in. uninstall.sh reverses it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 01:53:11 -04:00
simplysanatoriandClaude Sonnet 5.5 c45ac51e8f docs: keep upstream README as docs/UPSTREAM-README.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 01:53:11 -04:00
simplysanatoriandClaude Sonnet 5.5 b6ca75f37f vr: treat frame_controller as a Touch-class controller
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 01:50:18 -04:00
simplysanatoriandClaude Sonnet 5.5 39a42ebb42 Add native Steam Frame controller binding (frame_controller)
bindings_frame_controller.json is derived from bindings_oculus_touch.json via
SteamVR's oculus_touch -> frame_controller remapping rules, validated against
the Frame input profile; registered in actions.json default_bindings. Left
menu is the Frame's /input/view button. Other headsets are unaffected.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 01:48:41 -04:00
simplysanatoriandClaude Sonnet 5.5 238e7d2faa vr: add hud_offset_x/y ini keys for the gameplay HUD
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 01:47:49 -04:00
simplysanatoriandClaude Sonnet 5.5 aabf06d110 steam-frame: start LegendFrame fork scaffolding
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 01:42:36 -04:00
RototRobot e3657d0fe5 1.1.0: OpenXR with OpenVR fallback, settings panel, god mode, body physics
- OpenXR by default (openxr_loader.dll, Khronos 1.1.63), falling back to
  OpenVR / SteamVR; [vr] vr_runtime = auto|openxr|openvr. OpenXR grip poses
  converted to the OpenVR grip so the hands sit the same under both.
- Settings panel in the headset (both sticks held, or the Touch menu
  button), worked with a main-hand pointer; TR7-Menu-Hook's options built
  in when it is installed.
- God mode pick-up, carry and throw; third-person chest and rear physics;
  body push.
- Smooth view transitions; picture brightness and contrast; 4:3 movies;
  version and runtime on the main menu.
- Palm sliders: third "side" slider, per-preset scale/zoom/side, notches
  at the defaults, index-fingertip grab from Lara's drawn finger.
- Per-model caching of the body measurements (stutter with some player
  model mods).
- Docs, release notes and notices for 1.1.0.
2026-10-28 05:10:54 +00:00
RototRobot 2e745fb89c 1.0.0 release mod support 2026-10-18 02:47:32 +01:00
RototRobot f5006595f2 Build 5 2026-10-13 01:02:55 +01:00
RototRobot b9e3b88a41 Preview 4 hotfix 2026-10-12 04:12:25 +01:00
RototRobot 9e1def16cf preview release 4 2026-10-11 04:04:17 +01:00
RototRobot be3ceb4653 Preview Build 3 2026-10-07 06:24:51 +01:00
RototRobot c502f45084 Preview 2 build
Switch view any time: with immersive controls on, long-press the right stick (or press \) in gameplay to swap between first and third person. Set third_person_mode = all to cycle classic → shoulder → board → first person instead.
Hand Calibration (Pause → VR Settings → Hand Calibration): Lara holds her hands out with guns drawn, wire boxes show your real controllers, and you squeeze each grip to lock your hands in. Fixes hands not lining up with your controllers (common on Quest).
PDA is now on the right stick double-click, and tutorial prompts show it.
One crosshair everywhere: the game's flat lock-on rings are replaced by the VR crosshair. First person aims straight from your controller; third person puts it on the game's auto-target.
One-hand catches: a clear yellow GRIP pill fixed in your view (higher for swing bars), and about 6 seconds to grab instead of 1.5 (catch_extra_time). auto_secure_catch now takes off, bars or all.

Quest and other headsets with an uneven vertical field of view: fixed the world warping with head movement.
Ledge pull-ups in first person always use the quick animation.
The shoulder camera now turns like classic (follows camera_auto_center).
The pause menu's Display page is now VR Settings; holster setup has more reliable menu entries and on-screen messages when it can't start.
Pausing no longer leaves your pistols floating beside your hands.
Fixed a black slab that could appear in front of you in third person.
Holster setup is cancelled with the menu button (left stick click).
2026-10-06 04:22:16 +01:00
RototRobot 2db029fbff Cat :( 2026-10-05 04:18:36 +01:00
RototRobot 94c59f8a0b First Preview build 2026-10-05 03:43:10 +01:00