Commit Graph
25 Commits
Author SHA1 Message Date
MarcelineVQ 79d9521953 Refactor addon system: derive module list from build.zig, prune inactive prefixes at runtime
- Eliminate hardcoded module_names in addons.zig — now derived from
  build.zig via all_module_names build option
- Add module_active.zig runtime registry: main.zig registers isActive
  pointers during install(), addons.zig queries them without importing
  each module directly
- Prune embedded file prefixes at startup: after all modules claim
  mutexes, build a runtime active_prefixes table excluding modules we
  don't own. findEmbeddedFile searches only active entries — no
  per-lookup isActive check on the hot path
- Tag both addon and asset prefixes with module_name so pruning applies
  to all embedded files for a module
- Rename src/markers/ → src/worldmarkers/, src/outline/api.zig →
  src/outline/outline.zig to follow {name}/{name}.zig convention
2026-03-13 11:40:49 -07:00
MarcelineVQ 3e37b96788 Consolidate shared game offsets and accessor functions
Extract duplicated WoW 1.12.1 addresses and game accessor functions
into shared modules (src/offsets.zig, src/wow.zig), replacing 5+
copies of getObjectByGUID, isInBattleground, isValidPtr, etc.

- src/offsets.zig: shared address constants (object manager, descriptor
  fields, map/zone, core function addresses, D3D9/GX)
- src/wow.zig: shared accessor functions (pointer validation, object
  manager traversal, field reads, unit helpers, battleground detection,
  game function wrappers, raid target cache)
- Update 10 modules to import from shared instead of inline constants
- Remove outline/wow.zig (promoted to src/wow.zig)
- Trim outline/offsets.zig and markers/offsets.zig to module-specific only
2026-03-10 13:53:29 -07:00
MarcelineVQ 1a9f0c237e Add outline Idris research notes 2026-03-10 13:27:45 -07:00
MarcelineVQ 0f14213b0b Add logging module with auto-prefix, route all output through Logger
Replace console.zig with logging.zig: per-module Logger with auto
[name] prefix, optional file output, and destination routing. Convert
all modules from manual [name] prefixes and global con.print to Logger
instances. Remove redundant "Module loaded" lines. Replace
OutputDebugStringA in outline/tracker with Logger. Add dpslog module
with structured combat log events (SPELL_DMG, PERIODIC, HEAL, MELEE).
Add clickthrough module and bigcursor D3D9 cursor scaling.
2026-03-10 13:26:45 -07:00
MarcelineVQ d325c9f684 Use hook.cc.* aliases and migrate remaining hook.fastcall calls
Replace all local calling convention declarations (const fc/tc/sc)
with hook.cc.fastcall/thiscall/stdcall from zhook. Migrate remaining
17 hook.fastcall() inline asm call sites to hook.call() with typed
function pointers.
2026-03-09 11:16:52 -07:00
MarcelineVQ 9c96a94dc1 Migrate inline asm call sites to hook.call()
Replace hand-written inline asm blocks with hook.call() typed function
pointer dispatch across 10 files. Also migrates 4 D3D9 COM vtable
NULL-dispatch blocks using ?*anyopaque optional pointers.

Net removal: ~350 lines of inline asm replaced by single-line calls.
2026-03-09 10:28:55 -07:00
MarcelineVQ 08cbbb2b8e Add faction/interactability filtering to minimap icons
Filter hostile units, wrong-faction summoned NPCs, and non-interactable
game objects from minimap tracking. Dynamic checks (UnitReaction, owner
faction, GO_FLAG_NO_INTERACT) run every frame since group membership can
change. GUID cache still handles static classification (NPC flags/subname).

Also fix missing ECX clobber in outline UnitReaction inline asm.
2026-03-08 17:15:17 -07:00
MarcelineVQ d2f91fe8c2 Replace screenshot addon with screenshotQuality CVar
Remove the embedded Screenshot addon (TOC + Lua) and WeirdUtilsScreenshot()
Lua function. Compression quality is now controlled entirely via a CVar
(saved to config.wtf), read fresh on each screenshot. CVar 0 disables PNG
and falls through to original TGA.
2026-03-08 12:24:19 -07:00
MarcelineVQ 6ce091607f Rename embedded addons to WeirdUtils_<name> namespace
Prefix all addon folder names with WeirdUtils_ to avoid collisions
with real addons. Rename SavedVariables global from UI_MinimapIcons
to WeirdUtils_MinimapIconsSettings.
2026-03-08 11:30:04 -07:00
MarcelineVQ 6266d6ff10 Remove core addon, it only contained test functions
The WeirdUtils core addon only provided /wu slash commands, a version
global, and a test function. Remove it along with the WeirdUtils
dependency from all module addon TOC files -- the DLL controls addon
load order directly so the dependency was cosmetic.
2026-03-07 11:11:49 -08:00
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 4af033d01d Rename dataassets→customassets, Markers→WorldMarkers, prefix all mutexes
- dataassets module renamed to customassets everywhere (build flag,
  source, DLL variant name, docs)
- Markers addon renamed to WorldMarkers (addon path, .toc, .lua,
  Bindings.xml header, Lua globals, debug log prefix, mutex name)
- All 9 module mutexes now use WeirdUtils_ prefix to avoid
  collisions with other DLLs in the same process
2026-03-03 10:26:17 -08:00
MarcelineVQ db1243d136 Add marker persistence, respawn, group sync, and fix pushnumber ABI
Marker definitions (position + area ID) now persist across zone
transitions. Entities are destroyed on map change but respawned
automatically when the player approaches within 200y. Definitions
are cleared on logout/exit via onShutdown hook.

Group sync via addon messages (WMark prefix, colon-delimited protocol)
with permission checks (raid leader/assist, party leader). Includes
sync request/response for late joiners and roster change broadcasting.

Fix lua_pushnumber calling convention: function is __thiscall (ECX=L,
f64 on stack, ret 8), not __fastcall. The patched inreg fastcall was
placing the f64's low dword in EDX, corrupting values.

Other fixes:
- Remove Bindings.xml from .toc files (explicit binding loader needed)
- Remove remove_on_shutdown for markers (was killing hooks on logout)
- Remove diagnostic entity check code (culling behavior understood)
- New Lua APIs: SetMarkerDef, ClearMarkerDef, GetMarkerDef
- Rename binding labels to marker colors
2026-03-02 11:45:26 -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 2cca8f4b53 Add assetfix, transmogfix, minimapicons modules; fix assetfix disk-vs-MPQ priority
Assetfix: hook CheckFileExistence to serve loose Data\ files. The original
flags|1 approach failed because game paths contain backslashes, causing
CheckFileExistence to skip BuildFilePath and check the raw path (no Data\
prefix). Fix: write the correct Data\-prefixed disk path to the output buffer
directly and return 1, bypassing the original function for hash map hits.
This preserves hook chaining (filename argument is never transformed).

Also adds transmogfix (transmog update coalescing), minimapicons (stub),
new build options for all three modules, mutex-based multi-DLL safety,
embed .skin data into .m2 models, and various module improvements.
2026-02-28 14:07:53 -08:00
MarcelineVQ a8ebe21b0d Add hook 5 (loadModelFromFileAsync), combatlog stub, framecrash vtable hooks, marker assets
Hook 5 intercepts loadModelFromFileAsync (0x71d4e0) to synchronously load M2
model data for fake in-memory file contexts. processLoadedModelData returns 1
and entities are created, but file context cleanup is currently skipped (leaks
0x60 bytes per load) due to a crash in the cleanup path, and there's a later
EIP=0 crash during the game main loop that needs investigation.

Also adds: combatlog module stub, framecrash anchor vtable hooks (GetRelativeTo
and GetWidth/GetHeight crash guards), embedded Raid_UI_FX model assets with
skins and textures, WU_XYZ debug model.
2026-02-27 16:47:42 -08:00
MarcelineVQ 37d42d09c2 Add markers module, framecrash stub, debug console, build-flag wiring
Markers: client-side world object system using CreateGameObject. Places
M2 models at arbitrary world positions via Lua commands (/mark test,
/mark pos). Includes embedded addon, xyz.m2/blp assets served from DLL
memory, position helpers from unit movement struct, and object lifecycle
management (create, cleanup, reposition, alpha, animation).

Framecrash: stub module with reference to crash at 0x007A2452.

Console: debug output via AllocConsole/WriteConsoleA, compiles out
entirely in non-Debug builds. Used by markers and file serve logging.

Build: markers added to feature flag matrix and all-variants step.
Main: conditional markers import, Lua function registration, embedded
addon + asset file serving, console init/deinit lifecycle.

Outline README: added misc planned features and debug mode notes.
2026-02-26 15:30:21 -08:00
MarcelineVQ cd7e585412 Restructure modules with per-module addon subdirs
- Each module (outline, interact, screenshot) now has its own addon/
  subdir with .toc, .lua, and Bindings.xml
- Core WeirdUtils addon lives in src/core/addon/
- build.zig supports compile-time feature gating via -D options
- main.zig uses build_options for conditional imports and addon embedding
- Module addons only load when their module is compiled in
- 'zig build all-variants' produces full.dll + 3 single-module DLLs
2026-02-25 19:15:08 -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 661e1562d9 Fix game object occlusion: render outline targets last in batch order
Outline targets now render after all other M2 models instead of before,
so the depth buffer contains full scene geometry (game objects, other
characters, NPCs) when stencil marks are written. Previously only
terrain+WMO depth was available, causing outlines to show through
fences, mailboxes, lamp posts, and other game objects.
2026-02-24 19:06:10 -08:00
MarcelineVQ 89ac4ec7f3 Replace depth buffer copy with stencil-based terrain occlusion for outlines
StretchRect for depth-stencil surfaces is unsupported on DXVK, returning
D3DERR_INVALIDCALL every frame. Replace the entire DS snapshot approach
with stencil marks written during the DIP hook: outline targets already
depth-test against terrain (batch reordering ensures they draw first),
so STENCILPASS=REPLACE writes stencil=1 where visible. EndScene replay
gates silhouette drawing on STENCILFUNC=EQUAL to achieve terrain/WMO
occlusion without any depth buffer copy.
2026-02-24 17:34:04 -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