Compare commits

...

10 Commits

Author SHA1 Message Date
Dusk-92 eb083a0005 test: build DIP passthrough isolation 2026-08-29 18:58:31 +02:00
Dusk-92 b97c74469c test: hook DIP as pure passthrough 2026-08-29 18:58:21 +02:00
Dusk-92 3fe1509536 test: build EndScene-only isolation 2026-08-29 18:48:46 +02:00
Dusk-92 2ddbbe9fc7 test: isolate EndScene hook only 2026-08-29 18:48:37 +02:00
Dusk-92 7a959c7112 test: build V37A without Reset hook 2026-08-29 18:45:26 +02:00
Dusk-92 1508f4d8a6 test: isolate D3D9 path without Reset hook 2026-08-29 18:45:14 +02:00
Dusk-92 b812006831 test: build V37A without automatic D3D9 rehook 2026-08-29 18:32:47 +02:00
Dusk-92 163d6e6470 test: disable automatic D3D9 rehook during rendering 2026-08-29 18:32:38 +02:00
Dusk-92 4121cb6457 test: build V37A radii-only isolation 2026-08-29 18:20:50 +02:00
Dusk-92 43c4160b8d V37A test: apply only V37 outline radii 2026-08-29 18:20:40 +02:00
7 changed files with 278 additions and 78 deletions
@@ -0,0 +1,55 @@
name: V37A DIP Passthrough
on:
push:
branches:
- test/v37a-dip-passthrough
workflow_dispatch:
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: mlugg/setup-zig@v2
with:
version: '0.16.0'
- name: Build
shell: bash
run: |
set -euo pipefail
zig build all-variants -Doptimize=ReleaseSmall \
-Dweirdperformance=false \
-Doutline=true \
-Dcustomassets=true \
-Dtransmogfix=true
- name: Package
shell: bash
run: |
set -euo pipefail
rm -rf package dist
mkdir -p package/DLL package/Interface/AddOns/WeirdUtils_Outline dist
cp zig-out/variants/outline.dll package/DLL/outline.dll
cp src/outline/addon/Bindings.xml package/Interface/AddOns/WeirdUtils_Outline/
cp src/outline/addon/Outline.lua package/Interface/AddOns/WeirdUtils_Outline/
cp src/outline/addon/WeirdUtils_Outline.toc package/Interface/AddOns/WeirdUtils_Outline/
printf '%s\n' \
'V37A DIP passthrough isolation test.' \
'EndScene and DrawIndexedPrimitive vtable hooks are installed.' \
'DIP detour performs no Outline capture/state/resource work and immediately calls original DIP.' \
'Reset remains untouched.' \
'Visible outline is intentionally absent in this diagnostic build.' \
'main branch untouched; WeirdPerformance not modified.' \
> package/README_TEST.txt
(cd package && sha256sum DLL/outline.dll > SHA256SUMS.txt && zip -r ../dist/WeirdUtils_V37A_DIP_PASSTHROUGH.zip DLL Interface README_TEST.txt SHA256SUMS.txt)
- uses: actions/upload-artifact@v4
with:
name: WeirdUtils-V37A-DIP-PASSTHROUGH
path: dist/WeirdUtils_V37A_DIP_PASSTHROUGH.zip
if-no-files-found: error
@@ -0,0 +1,55 @@
name: V37A EndScene Only
on:
push:
branches:
- test/v37a-endscene-only
workflow_dispatch:
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: mlugg/setup-zig@v2
with:
version: '0.16.0'
- name: Build
shell: bash
run: |
set -euo pipefail
zig build all-variants -Doptimize=ReleaseSmall \
-Dweirdperformance=false \
-Doutline=true \
-Dcustomassets=true \
-Dtransmogfix=true
- name: Package
shell: bash
run: |
set -euo pipefail
rm -rf package dist
mkdir -p package/DLL package/Interface/AddOns/WeirdUtils_Outline dist
cp zig-out/variants/outline.dll package/DLL/outline.dll
cp src/outline/addon/Bindings.xml package/Interface/AddOns/WeirdUtils_Outline/
cp src/outline/addon/Outline.lua package/Interface/AddOns/WeirdUtils_Outline/
cp src/outline/addon/WeirdUtils_Outline.toc package/Interface/AddOns/WeirdUtils_Outline/
printf '%s\n' \
'V37A EndScene-only isolation test.' \
'Base: V37A no-Reset-hook + ExitFix.' \
'Only IDirect3DDevice9::EndScene is hooked.' \
'DrawIndexedPrimitive and Reset are untouched.' \
'Visible outline is intentionally absent in this diagnostic build.' \
'main branch untouched; WeirdPerformance not modified.' \
> package/README_TEST.txt
(cd package && sha256sum DLL/outline.dll > SHA256SUMS.txt && zip -r ../dist/WeirdUtils_V37A_ENDSCENE_ONLY.zip DLL Interface README_TEST.txt SHA256SUMS.txt)
- uses: actions/upload-artifact@v4
with:
name: WeirdUtils-V37A-ENDSCENE-ONLY
path: dist/WeirdUtils_V37A_ENDSCENE_ONLY.zip
if-no-files-found: error
@@ -0,0 +1,54 @@
name: V37A No AutoRehook
on:
push:
branches:
- test/v37a-no-autorehook
workflow_dispatch:
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: mlugg/setup-zig@v2
with:
version: '0.16.0'
- name: Build
shell: bash
run: |
set -euo pipefail
zig build all-variants -Doptimize=ReleaseSmall \
-Dweirdperformance=false \
-Doutline=true \
-Dcustomassets=true \
-Dtransmogfix=true
- name: Package
shell: bash
run: |
set -euo pipefail
rm -rf package dist
mkdir -p package/DLL package/Interface/AddOns/WeirdUtils_Outline dist
cp zig-out/variants/outline.dll package/DLL/outline.dll
cp src/outline/addon/Bindings.xml package/Interface/AddOns/WeirdUtils_Outline/
cp src/outline/addon/Outline.lua package/Interface/AddOns/WeirdUtils_Outline/
cp src/outline/addon/WeirdUtils_Outline.toc package/Interface/AddOns/WeirdUtils_Outline/
printf '%s\n' \
'V37A no-auto-rehook isolation test.' \
'Base: V37A radii-only + ExitFix.' \
'Only runtime change: automatic lateRehookIfLost() call removed from RenderDraw.' \
'Initial deferred D3D9 hook installation remains unchanged.' \
'main branch untouched; WeirdPerformance not modified.' \
> package/README_TEST.txt
(cd package && sha256sum DLL/outline.dll > SHA256SUMS.txt && zip -r ../dist/WeirdUtils_V37A_NO_AUTOREHOOK.zip DLL Interface README_TEST.txt SHA256SUMS.txt)
- uses: actions/upload-artifact@v4
with:
name: WeirdUtils-V37A-NO-AUTOREHOOK
path: dist/WeirdUtils_V37A_NO_AUTOREHOOK.zip
if-no-files-found: error
@@ -0,0 +1,55 @@
name: V37A No Reset Hook
on:
push:
branches:
- test/v37a-no-reset-hook
workflow_dispatch:
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: mlugg/setup-zig@v2
with:
version: '0.16.0'
- name: Build
shell: bash
run: |
set -euo pipefail
zig build all-variants -Doptimize=ReleaseSmall \
-Dweirdperformance=false \
-Doutline=true \
-Dcustomassets=true \
-Dtransmogfix=true
- name: Package
shell: bash
run: |
set -euo pipefail
rm -rf package dist
mkdir -p package/DLL package/Interface/AddOns/WeirdUtils_Outline dist
cp zig-out/variants/outline.dll package/DLL/outline.dll
cp src/outline/addon/Bindings.xml package/Interface/AddOns/WeirdUtils_Outline/
cp src/outline/addon/Outline.lua package/Interface/AddOns/WeirdUtils_Outline/
cp src/outline/addon/WeirdUtils_Outline.toc package/Interface/AddOns/WeirdUtils_Outline/
printf '%s\n' \
'V37A no-Reset-hook isolation test.' \
'Base: V37A no-auto-rehook + ExitFix.' \
'EndScene and DrawIndexedPrimitive hooks remain active.' \
'Reset hook is NOT installed.' \
'Visible outline rendering should still work.' \
'main branch untouched; WeirdPerformance not modified.' \
> package/README_TEST.txt
(cd package && sha256sum DLL/outline.dll > SHA256SUMS.txt && zip -r ../dist/WeirdUtils_V37A_NO_RESET_HOOK.zip DLL Interface README_TEST.txt SHA256SUMS.txt)
- uses: actions/upload-artifact@v4
with:
name: WeirdUtils-V37A-NO-RESET-HOOK
path: dist/WeirdUtils_V37A_NO_RESET_HOOK.zip
if-no-files-found: error
@@ -0,0 +1,51 @@
name: V37A Radii Only
on:
push:
branches:
- test/v37a-radii-only
workflow_dispatch:
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: mlugg/setup-zig@v2
with:
version: '0.16.0'
- name: Build
shell: bash
run: |
set -euo pipefail
zig build all-variants -Doptimize=ReleaseSmall \
-Dweirdperformance=false \
-Doutline=true \
-Dcustomassets=true \
-Dtransmogfix=true
- name: Package
shell: bash
run: |
set -euo pipefail
rm -rf package dist
mkdir -p package/DLL package/Interface/AddOns/WeirdUtils_Outline dist
cp zig-out/variants/outline.dll package/DLL/outline.dll
cp src/outline/addon/Bindings.xml package/Interface/AddOns/WeirdUtils_Outline/
cp src/outline/addon/Outline.lua package/Interface/AddOns/WeirdUtils_Outline/
cp src/outline/addon/WeirdUtils_Outline.toc package/Interface/AddOns/WeirdUtils_Outline/
printf '%s\n' \
'V37A isolation test.' \
'Base: V36 + ExitFix (stable in user test).' \
'Only runtime change: radii 1.5/3.0 -> 1.35/3.20.' \
'V36 decode shader remains unchanged.' \
'main branch untouched; WeirdPerformance not modified.' \
> package/README_TEST.txt
(cd package && sha256sum DLL/outline.dll > SHA256SUMS.txt && zip -r ../dist/WeirdUtils_V37A_RADII_ONLY.zip DLL Interface README_TEST.txt SHA256SUMS.txt)
- uses: actions/upload-artifact@v4
with:
name: WeirdUtils-V37A-RADII-ONLY
path: dist/WeirdUtils_V37A_RADII_ONLY.zip
if-no-files-found: error
+6 -74
View File
@@ -996,79 +996,10 @@ fn hkDIP(
) callconv(hook.cc.stdcall) i32 { ) callconv(hook.cc.stdcall) i32 {
debug_dip_seen = true; debug_dip_seen = true;
// Isolation test: keep the DIP vtable detour installed, but do no
// Outline state capture/resource work here. Call the original directly.
const OrigDIP = *const fn (*anyopaque, u32, i32, u32, u32, u32, u32) callconv(hook.cc.stdcall) i32; const OrigDIP = *const fn (*anyopaque, u32, i32, u32, u32, u32, u32) callconv(hook.cc.stdcall) i32;
const origFn: OrigDIP = @ptrFromInt(orig_dip); const origFn: OrigDIP = @ptrFromInt(orig_dip);
// ---- Cache outline draws for EndScene replay ----
if (model_hook.rendering_outline) {
debug_outline_dip_seen = true;
const model_ptr = model_hook.current_model;
const color = tracker.getModelColor(model_ptr) orelse
return origFn(device, prim_type, base_vtx, min_vtx, num_verts, start_idx, prim_count);
const category = tracker.getModelCategory(model_ptr);
// Ensure resources will be available for replay in EndScene
if (!shaders_attempted) ensureShaders(device);
ensureResources(device);
if (outline_ps == null or rt_silhouette_surf == null)
return origFn(device, prim_type, base_vtx, min_vtx, num_verts, start_idx, prim_count);
// Cache if room available
if (cached_draw_count < MAX_CACHED_DRAWS) {
const idx = cached_draw_count;
var draw = &cached_draws[idx];
// Draw parameters
draw.prim_type = prim_type;
draw.base_vtx = base_vtx;
draw.min_vtx = min_vtx;
draw.num_verts = num_verts;
draw.start_idx = start_idx;
draw.prim_count = prim_count;
// Outline info
draw.color = color;
draw.category = category;
// Capture current GPU state (AddRef COM objects to keep them alive)
deviceGetStreamSource(device, 0, &draw.vb, &draw.vb_offset, &draw.vb_stride);
// GetStreamSource AddRef's the VB - we keep the ref until replay
draw.ib = deviceGetIndices(device);
// GetIndices AddRef's the IB
draw.vertex_decl = deviceGetPtr(device, types.VT.GetVertexDeclaration);
// GetVertexDeclaration AddRef's
draw.vertex_shader = deviceGetPtr(device, types.VT.GetVertexShader);
// GetVertexShader AddRef's
for (0..4) |stage| {
draw.tex[stage] = deviceGetTexture(device, @intCast(stage));
draw.alpha_op[stage] = deviceGetTSS(device, @intCast(stage), types.D3DTSS.ALPHAOP);
draw.alpha_arg1[stage] = deviceGetTSS(device, @intCast(stage), types.D3DTSS.ALPHAARG1);
draw.alpha_arg2[stage] = deviceGetTSS(device, @intCast(stage), types.D3DTSS.ALPHAARG2);
}
draw.pixel_shader = deviceGetPtr(device, types.VT.GetPixelShader);
draw.state_block = deviceCreateStateBlock(device);
if (draw.state_block != null) debug_state_block_seen = true;
draw.alpha_test_enable = deviceGetRS(device, types.D3DRS.ALPHATESTENABLE);
draw.alpha_ref = deviceGetRS(device, types.D3DRS.ALPHAREF);
draw.alpha_func = deviceGetRS(device, types.D3DRS.ALPHAFUNC);
draw.alpha_blend_enable = deviceGetRS(device, types.D3DRS.ALPHABLENDENABLE);
draw.src_blend = deviceGetRS(device, types.D3DRS.SRCBLEND);
draw.dst_blend = deviceGetRS(device, types.D3DRS.DESTBLEND);
// Capture VS constants (bone matrices, world/view/proj transforms)
deviceGetVSConstF(device, 0, &draw.vs_consts, MAX_VS_CONST_REGS);
cached_draw_count = idx + 1;
frame_has_outlines = true;
debug_cached_draw_seen = true;
}
// DEBUG23: no stencil writes. Preserve WoW's D3D state and draw once.
// The cached geometry is replayed later into the silhouette RT.
return origFn(device, prim_type, base_vtx, min_vtx, num_verts, start_idx, prim_count);
}
// ---- Normal path ----
return origFn(device, prim_type, base_vtx, min_vtx, num_verts, start_idx, prim_count); return origFn(device, prim_type, base_vtx, min_vtx, num_verts, start_idx, prim_count);
} }
@@ -1414,8 +1345,8 @@ fn runJfaPipeline(device: *anyopaque) void {
if (saved_rt0) |rt| deviceSetRenderTarget(device, 0, rt); if (saved_rt0) |rt| deviceSetRenderTarget(device, 0, rt);
deviceSetTexture(device, 0, rt_jfa_a_tex); deviceSetTexture(device, 0, rt_jfa_a_tex);
deviceSetTexture(device, 1, rt_silhouette_tex); deviceSetTexture(device, 1, rt_silhouette_tex);
// V36: thin 1.5px core plus a subtle 3px halo. // V37A isolation test: V37 radii only, V36 decode shader unchanged.
c0 = [4]f32{ fw, fh, 1.5, 3.0 }; c0 = [4]f32{ fw, fh, 1.35, 3.20 };
deviceSetPSConstF(device, 0, &c0); deviceSetPSConstF(device, 0, &c0);
deviceSetPtr(device, types.VT.SetPixelShader, jfa_decode_ps.?); deviceSetPtr(device, types.VT.SetPixelShader, jfa_decode_ps.?);
deviceSetRS(device, types.D3DRS.ALPHABLENDENABLE, 1); deviceSetRS(device, types.D3DRS.ALPHABLENDENABLE, 1);
@@ -1627,9 +1558,10 @@ pub fn installHooks() bool {
const vtable_ptr = getD3D9VTable() orelse return false; const vtable_ptr = getD3D9VTable() orelse return false;
d3d9_vtable = vtable_ptr; d3d9_vtable = vtable_ptr;
// Isolation test: hook EndScene + DrawIndexedPrimitive.
// Reset remains untouched.
if (!patchVtableEntry(vtable_ptr, types.VT.EndScene, @intFromPtr(&hkEndScene), &orig_endscene)) return false; if (!patchVtableEntry(vtable_ptr, types.VT.EndScene, @intFromPtr(&hkEndScene), &orig_endscene)) return false;
if (!patchVtableEntry(vtable_ptr, types.VT.DrawIndexedPrimitive, @intFromPtr(&hkDIP), &orig_dip)) return false; if (!patchVtableEntry(vtable_ptr, types.VT.DrawIndexedPrimitive, @intFromPtr(&hkDIP), &orig_dip)) return false;
if (!patchVtableEntry(vtable_ptr, types.VT.Reset, @intFromPtr(&hkReset), &orig_reset)) return false;
hooks_installed = true; hooks_installed = true;
return true; return true;
+2 -4
View File
@@ -94,10 +94,8 @@ fn renderDrawDetour(this: u32, view_matrix: u32, batch_data: u32, batch_indices:
api.initD3D9Deferred(); api.initD3D9Deferred();
} }
// AutoFix: OutlineDebug() previously performed lateRehookIfLost() by hand. // Isolation test: keep the initial deferred D3D9 hook install, but do not
// Check periodically from this always-active native model hook instead. // repeatedly verify/rewrite the live vtable while rendering.
autoRepairD3D9Hooks();
// Skip reordering if nothing to outline or too many batches // Skip reordering if nothing to outline or too many batches
if (!tracker.enabled or !tracker.hasTargets() or batch_count == 0 or batch_count > MAX_REORDER) { if (!tracker.enabled or !tracker.hasTargets() or batch_count == 0 or batch_count > MAX_REORDER) {
render_draw_hook.callOriginal(.{ this, view_matrix, batch_data, batch_indices, batch_count }); render_draw_hook.callOriginal(.{ this, view_matrix, batch_data, batch_indices, batch_count });