Removed deferred divide from both ray-tri functions -- the det-scaled
epsilon comparisons lose precision for near-parallel rays, potentially
accepting triangles the original rejects. Downstream SetupBoxFrustum
then writes to wrong globals near 0xCE6738 (SGroupPtr), causing
ERROR #124 on exit.
inflate_hook: replaced manual FS:0x24 thread ID pool with Zig native
threadlocal. Fixes potential crash on Wine where FS segment layout
may differ.
Build: switched from GNU to MSVC ABI (4-5K smaller per DLL, no
.eh_frame unwind tables). Added setjmp.h stub for libdeflate MSVC
build. Added noperf build variant (zig build noperf).
Tail vertices V0/V1 read texture U/V from wrong addresses (no offset
from base instead of +8/+16 stride). Assembly reads 0x87D734/738 for
V0 and 0x87D73C/740 for V1, not the base 0x87D72C/730. This made both
base vertices share UVs, collapsing the texture and causing light beams
to taper to a point instead of maintaining width.
Also fix transformVec4 input: must be [4]f32 with w=0.0, not [3]f32.
The function reads all 4 components including [EDX+0xC]. Reading past
a 3-element array produced garbage w values that corrupted the velocity
transform, causing tail particles to extend wildly.
Fixed in both SSE and reference implementations.
Root cause of crashes was thread safety: libdeflate's decompressor struct
has mutable decode tables rebuilt per-block, so sharing between main thread
and FMOD audio thread caused wild writes. Fixed with a thread-local pool
keyed by Windows thread ID (FS:[0x24]).
Switched build ABI from msvc to gnu — eliminates stub headers, libdeflate
uses Zig's bundled MinGW libc. Relaxed zlib header filter from == 0x78 to
(CMF & 0x0F) == 0x08 to catch both 32K and 4K window sizes.
Benchmarked: stock=2681ms, per-call-alloc=1304ms (2.05x), tls=1194ms (2.2x)
on 84k calls. Zero errors, zero fallbacks in production.
DecompressData_WithOptions modifies the input buffer during overlap
handling. Our hook must save the input before calling the original,
then pass the saved copy to libdeflate. Also documents all compression
types, function signatures, and bugs found during integration.
libdeflate sanity test passes (hello → hello, cpu_features=0x8000001F).
All 93K decompression calls during loading are pure zlib (type 0x02).
Header bytes 78 9C confirm standard zlib-wrapped deflate. No PKWare,
bzip2, or ADPCM observed.
Volume: 170MB compressed → 380MB decompressed in 2.9s during loading,
~5K calls/period during gameplay.
Format: [0x02] [zlib_stream...] — straightforward for libdeflate.
Previous crashes were from reading out_size AFTER original modified it
and from writing to out_buf unsafely.
Hooks DecompressData_WithOptions (0x661A80) to run both the original
zlib inflate and libdeflate on the same data. Times both, logs the
comparison every ~450 frames, counts mismatches.
malloc/free provided via game's Storm memory manager (SMemAlloc/SMemFree)
since we link without libc on the msvc target.
libdeflate compiled with -g0 to avoid .debug_frame COFF section name
warning. AVX-512 disabled (32-bit), SSE2/AVX2 paths active.