Compare commits

..
10 changed files with 363 additions and 48 deletions
+77
View File
@@ -0,0 +1,77 @@
name: Commit V36 Retail Soft decode
on:
push:
branches:
- test/v36-retail-jfa-soft
permissions:
contents: write
jobs:
commit-v36-soft:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: test/v36-retail-jfa-soft
- name: Apply V36 decode
shell: bash
run: |
set -euo pipefail
python3 <<'PY'
from pathlib import Path
p = Path('src/outline/d3d9_hook.zig')
s = p.read_text()
if 'V36 RETAIL-SOFT' in s:
raise SystemExit(0)
start = s.index('/// V32 POLISH: hard 3px outline, no feather.')
end = s.index('/// Debug: composite silhouette RT directly.')
lines = [
'/// V36 RETAIL-SOFT: keep the proven V34 JFA, soften only final decode.',
'/// c0 = (screen_width, screen_height, core_radius_px, halo_radius_px).',
'/// Uses the same two texture reads as V34: no 17-tap full-screen morphology.',
'const jfa_decode_src =',
' "ps_3_0\\n" ++',
' "def c1, 0.0, 0.22, 0.82, -0.002\\n" ++',
' "def c2, 1.0, 0.95, 0.58, 0.0\\n" ++',
' "dcl_2d s0\\n" ++',
' "dcl_2d s1\\n" ++',
' "dcl_texcoord0 v0\\n" ++',
' "texld r0, v0, s0\\n" ++',
' "sub r1.xy, v0.xy, r0.xy\\n" ++',
' "mul r1.xy, r1.xy, c0.xy\\n" ++',
' "dp2add r1.z, r1, r1, c1.x\\n" ++',
' "mul r3.x, c0.z, c0.z\\n" ++',
' "mul r3.y, c0.w, c0.w\\n" ++',
' "sub r4.x, r1.z, r3.y\\n" ++',
' "cmp r6.w, r4.x, c1.x, c1.y\\n" ++',
' "sub r4.x, r1.z, r3.x\\n" ++',
' "cmp r6.w, r4.x, r6.w, c1.z\\n" ++',
' "texld r5, v0, s1\\n" ++',
' "add r5.x, r5.a, c1.w\\n" ++',
' "cmp r6.w, r5.x, c1.x, r6.w\\n" ++',
' "mov r6.xyz, c2.xyz\\n" ++',
' "mov oC0, r6\\n";',
'',
'',
]
s = s[:start] + '\n'.join(lines) + s[end:]
old = ' // V34: hard 3px edge unchanged; JFA seed precision is now full-float.\n c0 = [4]f32{ fw, fh, 3.0, 0.0 };'
new_cpu = ' // V36: thin 1.5px core plus a subtle 3px halo.\n c0 = [4]f32{ fw, fh, 1.5, 3.0 };'
if old not in s:
raise SystemExit('V34 CPU decode constants not found')
p.write_text(s.replace(old, new_cpu))
PY
- name: Commit source
shell: bash
run: |
set -euo pipefail
if git diff --quiet; then exit 0; fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add src/outline/d3d9_hook.zig
git commit -m "V36: soft Retail-style JFA decode"
git push origin HEAD:test/v36-retail-jfa-soft
@@ -0,0 +1,55 @@
name: V36 ExitFix Baseline
on:
push:
branches:
- test/v36-exitfix-baseline
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' \
'V36 runtime + process-exit safety only.' \
'Base runtime commit: 4bbee94388f98843b738e275fd9482576be80654.' \
'Compared with V34, only src/outline/d3d9_hook.zig changes runtime behavior.' \
'main branch is untouched.' \
'WeirdPerformance is disabled in this standalone build and not modified.' \
> package/README_TEST.txt
(cd package && sha256sum DLL/outline.dll > SHA256SUMS.txt && zip -r ../dist/WeirdUtils_V36_EXITFIX_BASELINE.zip DLL Interface README_TEST.txt SHA256SUMS.txt)
- uses: actions/upload-artifact@v4
with:
name: WeirdUtils-V36-EXITFIX-BASELINE
path: dist/WeirdUtils_V36_EXITFIX_BASELINE.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
+1 -4
View File
@@ -1053,10 +1053,7 @@ pub export fn DllMain(
switch (reason) {
1 => install(),
0 => {
// ExitFix: when lpReserved is non-null, Windows is terminating the
// whole process. Do not call into D3D9/COM or other DLLs from
// DLL_PROCESS_DETACH during global teardown; the OS will reclaim
// those resources. Keep full uninstall for explicit FreeLibrary.
// Process-exit safety only; runtime Outline behavior is unchanged.
if (reserved == null) uninstall();
},
else => {},
+12 -36
View File
@@ -57,14 +57,6 @@ var orig_reset: usize = 0;
var d3d9_vtable: ?[*]usize = null;
var hooks_installed: bool = false;
/// ExitFix: once shutdown begins, no code path may reinstall D3D9 hooks.
var shutdown_started: bool = false;
pub fn beginShutdown() void {
shutdown_started = true;
}
// Sticky diagnostics for the in-game OutlineDebug() command.
pub var debug_endscene_seen: bool = false;
pub var debug_dip_seen: bool = false;
@@ -122,7 +114,6 @@ pub var debug_late_rehook_succeeded: bool = false;
/// If the current entries are no longer ours, chain whatever is there now as
/// the new originals, then patch the three entries again.
pub fn lateRehookIfLost() bool {
if (shutdown_started) return false;
debug_late_rehook_attempted = true;
const cur = getD3D9VTable() orelse return false;
@@ -741,40 +732,26 @@ const jfa_prop_src =
"mov oC0.xy, r8.xy\n" ++
"mov oC0.zw, c1.xx\n";
/// V38 RETAIL-POLISH: keep the proven V34/V36/V37 JFA and refine only
/// the final alpha profile. Still only two texture reads.
/// V36 RETAIL-SOFT: keep the proven V34 JFA, soften only final decode.
/// c0 = (screen_width, screen_height, core_radius_px, halo_radius_px).
/// Uses the same two texture reads as V34: no 17-tap full-screen morphology.
const jfa_decode_src =
"ps_3_0\n" ++
// c1 = zero, one, halo alpha, -interior threshold
"def c1, 0.0, 1.0, 0.17, -0.002\n" ++
// pale Retail-like yellow-green
"def c2, 1.0, 0.96, 0.62, 0.0\n" ++
// core alpha
"def c3, 0.84, 0.0, 0.0, 0.0\n" ++
"def c1, 0.0, 0.22, 0.82, -0.002\n" ++
"def c2, 1.0, 0.95, 0.58, 0.0\n" ++
"dcl_2d s0\n" ++
"dcl_2d s1\n" ++
"dcl_texcoord0 v0\n" ++
// Nearest JFA seed and pixel-space squared distance.
"texld r0, v0, s0\n" ++
"sub r1.xy, v0.xy, r0.xy\n" ++
"mul r1.xy, r1.xy, c0.xy\n" ++
"dp2add r1.z, r1, r1, c1.x\n" ++
// Squared core and halo radii.
"mul r3.x, c0.z, c0.z\n" ++
"mul r3.y, c0.w, c0.w\n" ++
// Smooth halo factor = saturate((halo² - dist²) / (halo² - core²)).
"sub r3.z, r3.y, r3.x\n" ++
"rcp r3.z, r3.z\n" ++
"sub r4.x, r3.y, r1.z\n" ++
"mul r4.x, r4.x, r3.z\n" ++
"max r4.x, r4.x, c1.x\n" ++
"min r4.x, r4.x, c1.y\n" ++
"mul r6.w, r4.x, c1.z\n" ++
// Solid-but-soft core inside the inner radius.
"sub r4.y, r1.z, r3.x\n" ++
"cmp r6.w, r4.y, r6.w, c3.x\n" ++
// Never paint over the original model interior.
"sub r4.x, r1.z, r3.y\n" ++
"cmp r6.w, r4.x, c1.x, c1.y\n" ++
"sub r4.x, r1.z, r3.x\n" ++
"cmp r6.w, r4.x, r6.w, c1.z\n" ++
"texld r5, v0, s1\n" ++
"add r5.x, r5.a, c1.w\n" ++
"cmp r6.w, r5.x, c1.x, r6.w\n" ++
@@ -1437,8 +1414,8 @@ fn runJfaPipeline(device: *anyopaque) void {
if (saved_rt0) |rt| deviceSetRenderTarget(device, 0, rt);
deviceSetTexture(device, 0, rt_jfa_a_tex);
deviceSetTexture(device, 1, rt_silhouette_tex);
// V38: slightly stronger 1.5px core with a subtler 3.1px falloff.
c0 = [4]f32{ fw, fh, 1.50, 3.10 };
// V37A isolation test: V37 radii only, V36 decode shader unchanged.
c0 = [4]f32{ fw, fh, 1.35, 3.20 };
deviceSetPSConstF(device, 0, &c0);
deviceSetPtr(device, types.VT.SetPixelShader, jfa_decode_ps.?);
deviceSetRS(device, types.D3DRS.ALPHABLENDENABLE, 1);
@@ -1646,14 +1623,13 @@ fn getD3D9VTable() ?[*]usize {
pub fn installHooks() bool {
if (hooks_installed) return true;
if (shutdown_started) return false;
const vtable_ptr = getD3D9VTable() orelse return false;
d3d9_vtable = vtable_ptr;
// Isolation test: hook EndScene only.
// DrawIndexedPrimitive and Reset remain untouched.
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.Reset, @intFromPtr(&hkReset), &orig_reset)) return false;
hooks_installed = 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();
}
// AutoFix: OutlineDebug() previously performed lateRehookIfLost() by hand.
// Check periodically from this always-active native model hook instead.
autoRepairD3D9Hooks();
// Isolation test: keep the initial deferred D3D9 hook install, but do not
// repeatedly verify/rewrite the live vtable while rendering.
// 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) {
render_draw_hook.callOriginal(.{ this, view_matrix, batch_data, batch_indices, batch_count });
+1 -4
View File
@@ -109,11 +109,8 @@ pub fn initD3D9Deferred() void {
/// Remove all outline hooks. Called during DLL_PROCESS_DETACH.
pub fn cleanup() void {
if (g_is_hook_owner) {
// ExitFix: stop any future self-heal first, then detach the model hooks
// that can call lateRehookIfLost(), and only then tear down D3D9.
d3d9_hook.beginShutdown();
model_hook.removeHooks();
d3d9_hook.removeHooks();
model_hook.removeHooks();
log.close();
mod_mutex.release(&g_mutex);
}