Commit Graph
7 Commits
Author SHA1 Message Date
MarcelineVQ 2aaa089c76 Add module control API, bigcursor with fractional scaling, shared mutex
Module control API:
- Three cdecl exports: WeirdUtils_IsModuleActive, WeirdUtils_DisableModule, WeirdUtils_DisableAll
- C header include/weirdutils_api.h for runtime DLL discovery
- All modules gain pub module_name, isActive(), shared mutex via src/mutex.zig
- build.zig refactored to module_list array of ModuleDesc

Bigcursor:
- D3D9 vtable hooks on SetCursorProperties/ShowCursor
- Scale2x/Scale3x pixel-art upscalers in pure Zig (replaces 12K-line hqx C)
- Bilinear resampler for fractional scales (1.0-4.0, default 1.2)
- Win32 cursor via CreateIconIndirect bypasses D3D9 32x32 limit
- FNV-1a hash cache for ~16 cursor bitmaps
- Lua API: SetCursorScale(n) / GetCursorScale()
- CVar cursorScale for Config.wtf persistence (tenths)

Other:
- Add dpslog module stub
- Docs and README updates
2026-03-06 13:27:35 -08:00
MarcelineVQ 475070e910 Fix marker crash on logout and add module lifecycle table
The marker cleanup hook on CleanupWorldAndEntities was never installed —
markers.installHooks() was missing from install() in main.zig. Entities
created via WorldMarker were never cleaned up before the game's atexit
handler iterated the hash table over freed heap memory.

Key changes:
- Add markers.installHooks() call (the actual crash fix)
- Replace manual install/uninstall/shutdown lists with a single modules
  table that drives all three phases — prevents this class of bug
- Gate marker Lua functions, addon, and keybindings behind isActive()
  so they're skipped when another DLL owns the hooks
- Add world_cleanup_hook.detach() to removeHooks() (was missing)
- Migrate from vendored libs/hook to external zhook dependency
- Unify installHooks return types to void across all modules
- Add diagnostic logging to marker cleanup (temporary, for testing)
2026-03-02 07:34:18 -08:00
MarcelineVQ fbfe1cb545 Outline render order, stencil protection, JFA sentinel fix, diagnostics
Render order: 3-way M2 batch partition — game objects + local player
render first (write depth), then outline targets (stencil marks), then
other players/gear/NPCs. Outlines show through other players but are
occluded by world/WMO/game objects/local player.

Stencil protection: set STENCILWRITEMASK=0 after outline target DIPs
to prevent subsequent renders from overwriting stencil marks.

JFA sentinel: changed from (1,1) to (-1,-1) to move it outside UV
space. Did not fix banding but is correct regardless.

Debug: added DEBUG_SHOW_SILHOUETTE comptime flag to bypass JFA and
composite raw silhouette RT. Confirmed silhouette is clean — banding
is in the JFA pipeline, not stale vertex buffers.

Game object + local player tracking in tracker.zig for batch ordering.

Added project README and outline subsystem README documenting render
pipeline, architecture, known issues, and planned features.
2026-02-25 18:32:49 -08:00
MarcelineVQ 528bbf2470 Fix outline rendering: cached DIP replay, disable depth for silhouettes
Switch from double-DIP (which corrupted WoW's GxDevice state) to cached
replay in EndScene. Cache draw params + GPU state (VB, IB, vertex decl,
VS, 256 VS constant registers) during the DIP hook, replay to silhouette
RT in EndScene before the JFA pipeline.

Remove D3D9 state blocks entirely — use comprehensive manual save/restore
of all modified state (render states, sampler states, shader constants,
COM objects with proper AddRef/Release).

Disable depth testing for all silhouette replay categories. By EndScene
the depth buffer has the full scene, so LESSEQUAL testing creates holes
in the silhouette wherever other models overlap — breaking the JFA
outline for targets and raid marks. Corpses already used ZENABLE=FALSE.

Add per-frame diagnostic counters (scan/classify counts by category)
logged via OutputDebugStringA for the first 20 active frames.

Clean up unused code: comAddRef, deviceCreateStateBlock, stateBlockApply.
2026-02-24 12:27:50 -08:00
MarcelineVQ 3ec7796cc1 Fix model rendering stutter: eliminate dummy D3D9 device, defer vtable hooks
The dummy device technique (Direct3DCreate9 + CreateDevice) corrupted the
d3d9 proxy's internal state when run on the main rendering thread, causing
model rendering to update at ~10fps while camera remained smooth.

Replace dummy device with direct vtable read from the game's existing
device via GxDevice global (0xC0ED38 + 0x38A8), sourced from UnitXP_SP3.

Also defer D3D9 hook installation until first rendered frame (triggered
from renderDrawDetour) to guarantee the device exists, and add
forceD24S8IfNeeded() in EndScene to force a Reset with D24S8 stencil
format since the deferred install misses the initial device Reset.

Other changes carried from prior session:
- model_hook.zig: native thiscall/naked detours (thunks eliminated)
- tracker.zig: tracked_obj_count made pub
2026-02-24 02:28:13 -08:00
MarcelineVQ 0278097034 Replace pointer chasing with forward mapping in model classification
classifyModel no longer calls resolveModelOwner (which dereferenced
unknown memory at model+0x3C0/+0x28 and crashed on terrain/doodad
models). Instead, scanObjects stores validated object pointers from
the object manager, and classifyModel compares model back-pointer
values against that known set — no pointer dereferencing beyond the
model struct itself.
2026-02-24 00:56:31 -08:00
MarcelineVQ 25ed0b3780 Add outline rendering system ported from C++ to Zig
Port the model outline hook system (CM2SceneRenderDraw, ManageRenderListNode,
DrawBatchProjected) from the C++ idris DLL to pure Zig. Includes D3D9 vtable
hooks for stencil-based outline rendering with per-category colors and thickness.

Fix GetObjectByGUID calling convention: was using fastcall (ECX/EDX) but Ghidra
confirms it's __stdcall with stack params and RET 8. Fix lua_pushcclosure address
from 0x6F3B80 (mid-body of another function) to 0x6F3920.

Guard resolveModelOwner in DrawBatchProj with hasTargets() check and cache unit
model status during ManageRenderListNode to avoid raw pointer chasing at render
time. Add IsBadReadPtr validation in resolveModelOwner to match C++ IsValidReadPtr
pattern for page-level memory safety.
2026-02-24 00:51:33 -08:00