2aaa089c76
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
85 lines
3.8 KiB
Markdown
85 lines
3.8 KiB
Markdown
# Outline Validation Checklist
|
|
|
|
## Build
|
|
|
|
- [ ] `zig build` succeeds with no errors (x86 windows-msvc target)
|
|
- [ ] Output DLL present at `zig-out/lib/weirdutils.dll`
|
|
|
|
## Existing Feature Regression
|
|
|
|
- [ ] DLL loads without crash (inject into WoW 1.12.1)
|
|
- [ ] `/wu version` responds correctly
|
|
- [ ] `/wu test` calls C function and returns string
|
|
- [ ] Screenshot hook works (`/wu ss`, PNG output)
|
|
- [ ] Interact/loot bindings work (InteractNearest, LootAllCorpses)
|
|
- [ ] Addon loads on login (green "WeirdUtils loaded" message)
|
|
|
|
## Outline Subsystem
|
|
|
|
### Commands
|
|
- [ ] `/wu outline` shows ON/OFF status
|
|
- [ ] `/wu outline on` enables outlines
|
|
- [ ] `/wu outline off` disables outlines
|
|
- [ ] `/wu` help text includes outline commands
|
|
|
|
### Dead Player Outlines
|
|
- [ ] Dead friendly players in party/raid show cyan outline
|
|
- [ ] Outline is visible through walls (no depth test)
|
|
- [ ] Outline disappears when player is resurrected
|
|
- [ ] Skeleton corpses are NOT outlined
|
|
|
|
### Raid Mark Outlines
|
|
- [ ] Units with raid icons (Star through Skull) show coloured outlines
|
|
- [ ] Each icon has a distinct colour
|
|
- [ ] Outlines update when raid marks change
|
|
- [ ] Outlines respect terrain occlusion (depth test enabled)
|
|
|
|
### Target Outline
|
|
- [ ] Current target shows golden amber outline
|
|
- [ ] Outline changes when target changes
|
|
- [ ] Outline clears when target is deselected
|
|
- [ ] Outline respects terrain occlusion
|
|
|
|
### Rendering Quality
|
|
- [ ] Outlines are clean (no jagged edges or flicker)
|
|
- [ ] Outline thickness is consistent across distances
|
|
- [ ] Normal model renders correctly on top of outline
|
|
- [ ] No visible render state leakage to other models
|
|
- [ ] Non-outlined units don't cover outline pixels (stencil test)
|
|
|
|
### Performance
|
|
- [ ] No noticeable FPS drop in normal gameplay
|
|
- [ ] No FPS drop in 40-player raid with multiple outlines
|
|
- [ ] Frame rate stable when toggling outlines on/off
|
|
|
|
### Edge Cases
|
|
- [ ] D3DX DLL not present → outlines gracefully disabled (no crash)
|
|
- [ ] No targets tracked → zero overhead (fast path)
|
|
- [ ] `/wu outline off` → DIP hook passes through immediately
|
|
- [ ] Device Reset (resolution change) → shaders recreated properly
|
|
|
|
## Hook Prologue Verification (Ghidra)
|
|
|
|
Verified 2026-02-23 using Ghidra MCP against WoW.exe 1.12.1 (build 5875, 4,907,008 bytes).
|
|
|
|
### Method
|
|
|
|
Raw bytes read from each hook target address via `get_bytes`. Instruction boundaries decoded to confirm the `prologue_size` parameter passed to `hook.prepare()` lands on a clean instruction boundary. A mid-instruction cut would corrupt the trampoline - the copied bytes would decode as a different instruction when followed by the trampoline's JMP.
|
|
|
|
### Results
|
|
|
|
| Address | Function | Prologue bytes | Decoded | Boundary | Safe | Fixups |
|
|
|---------|----------|---------------|---------|----------|------|--------|
|
|
| `0x0070b360` | `CM2SceneRenderDraw` | `55 8B EC 81 EC 80 00 00 00` | `PUSH EBP; MOV EBP,ESP; SUB ESP,0x80` | +1,+3,**+9** | 9B | none |
|
|
| `0x00710b90` | `CM2Model_ManageRenderListNode` | `55 8B EC 8B 45 08` | `PUSH EBP; MOV EBP,ESP; MOV EAX,[EBP+8]` | +1,+3,**+6** | 6B | none |
|
|
| `0x0070cb30` | `CM2Scene_DrawBatchProjected` | `55 8B EC 83 EC 10` | `PUSH EBP; MOV EBP,ESP; SUB ESP,0x10` | +1,+3,**+6** | 6B | none |
|
|
|
|
### Fix applied
|
|
|
|
`CM2SceneRenderDraw` prologue changed from 6 to **9** bytes in `src/outline/model_hook.zig`. The original 6-byte value would have split the `SUB ESP, 0x80` instruction (opcode `81 EC` + 4-byte immediate, spanning offset +3 to +9). The trampoline would have executed `81 EC 80 E9 xx xx` as `SUB ESP, <corrupted>`, leading to stack corruption and a crash.
|
|
|
|
### No other changes needed
|
|
|
|
- All three prologues contain only register/memory instructions (no `E8 CALL` or `E9 JMP`), so `rel32_fixups` remains `&.{}`.
|
|
- The 4-byte NOP padding (bytes 5-8) at `0x0070b360` after the 5-byte `E9 JMP` is harmless - it is never executed (execution jumps to the detour thunk).
|