diff options
| author | salmonik <salmonik@tuta.io> | 2026-09-12 19:04:22 +0200 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-09-12 19:04:22 +0200 |
| commit | 210f3a12ee1d56750d593b4c404a0683f810aa3e (patch) | |
| tree | 926a136c0366616077b03c2e48ffba5af7312d08 /src/ISURFACE_STATUS.md | |
| parent | init (diff) | |
| download | hl2h-210f3a12ee1d56750d593b4c404a0683f810aa3e.tar.gz hl2h-210f3a12ee1d56750d593b4c404a0683f810aa3e.zip | |
ISurface overlay working: PTEx draw path, -Werror, menu states, bind-driven features
Diffstat (limited to '')
| -rw-r--r-- | src/ISURFACE_STATUS.md | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/ISURFACE_STATUS.md b/src/ISURFACE_STATUS.md new file mode 100644 index 0000000..32a27bb --- /dev/null +++ b/src/ISURFACE_STATUS.md | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | # HL2hake ISurface Drawing — Status Report | ||
| 2 | |||
| 3 | ## Date: 2026-09-12 (final round) | ||
| 4 | |||
| 5 | ## Result: WORKING | ||
| 6 | |||
| 7 | Overlay drawing works in-game and in menus. Draw path: `PaintTraverseEx` | ||
| 8 | hook (slot 114) on the copied ISurface vtable, wrapping our draws in | ||
| 9 | `PushMakeCurrent(panel, false)` / `PopMakeCurrent(panel)` around ISurface | ||
| 10 | slots 6/10/12/17/18/20/22/66/67. | ||
| 11 | |||
| 12 | ## Confirmed ISurface VTable Slots (disassembly-verified, binary=SDK header+4) | ||
| 13 | |||
| 14 | | Slot | Function | Evidence | | ||
| 15 | |------|-------------------------------------------|----------| | ||
| 16 | | 6 | `GetEmbeddedPanel()` | returns VPANEL used with PushMakeCurrent | | ||
| 17 | | 8 | `PushMakeCurrent(VPANEL, bool)` | verified via disassembly | | ||
| 18 | | 9 | `PopMakeCurrent(VPANEL)` | verified via disassembly | | ||
| 19 | | 10 | `DrawSetColor(int r,g,b,a)` | stores RGBA at `this+0x24..0x27` | | ||
| 20 | | 12 | `DrawFilledRect(int x0,y0,x1,y1)` | verified via disassembly | | ||
| 21 | | 17 | `DrawSetTextFont(HFont)` | stores HFont at `this+0x290` | | ||
| 22 | | 18 | `DrawSetTextColor(int r,g,b,a)` | stores RGBA at `this+0x28..0x2b` | | ||
| 23 | | 20 | `DrawSetTextPos(int x,y)` | stores at `this+0x2c/0x30` | | ||
| 24 | | 22 | `DrawPrintText(wchar_t*, int, drawType)` | reads font `0x290`, pos `0x2c/0x30` | | ||
| 25 | | 66 | `CreateFont()` | SDK header 62; empirical (379) | | ||
| 26 | | 67 | `AddGlyphSetToFont(font,name,tall,weight,blur,scanlines,flags,rangeMin,rangeMax)` | SDK header 62+4; disassembly (slot 67 = 0x6a300, passes 9 args to FontManager) | | ||
| 27 | | 87 | `SolveTraverse` | InternalSchemeSettingsTraverse profiling strings @ 0x73240 | | ||
| 28 | | 88 | `PaintTraverse(VPANEL)` | tail-calls `ipanel->vt+0x1c8(panel,false)` @ 0x697e0 | | ||
| 29 | | 114 | `PaintTraverseEx(VPANEL, bool paintPopups)` | IsVisible check `ipanel+0x40`, popup array `this+0x250/0x25c`, "Too many popups!" assert @ 0x6dd46 | | ||
| 30 | |||
| 31 | Slot mapping rule: **binary slot = SDK-header slot + 4** (confirmed via | ||
| 32 | CreateFont 62→66 and PaintTraverseEx 110→114). Vtable has 179 entries; | ||
| 33 | slots 122–148 = second base class `IMatSystemSurface` | ||
| 34 | (AttachToWindow=122 … DrawSetTextureRGBAEx2=148). | ||
| 35 | |||
| 36 | ## Draw-Path Decision | ||
| 37 | |||
| 38 | - **Primary: PaintTraverseEx (slot 114)** — fires every frame for the root panel. | ||
| 39 | - **Fallback kept: DrawPrintText (slot 22)** — fires only when the game draws | ||
| 40 | text (menus); also used as in-draw call site for the game's own text. | ||
| 41 | - `g_in_draw` (hl2h.cpp) prevents recursion; both hooks call `outer_draw()` | ||
| 42 | (menu.cpp) guarded by it. | ||
| 43 | |||
| 44 | ## Fonts (the long fight) | ||
| 45 | |||
| 46 | Font alignment problem: `Tahoma` placeholder fontconfig-substituted to | ||
| 47 | Noto Sans → per-glyph baseline jumps (fallback-substitution glyph metrics). | ||
| 48 | Fixes tried in order: Tahoma → DejaVu Sans (+ANTIALIAS 0x10) → no AA → | ||
| 49 | **winner: "Liberation Sans" 16px, weight 400, flags 0x400 (FONTFLAG_CUSTOM), glyph range pinned 0x20–0xFF**. | ||
| 50 | `FONTFLAG_CUSTOM` disables the Asian fallback-compat glyph path; pinned | ||
| 51 | range forces one font pass → uniform metrics, no jumping letters. | ||
| 52 | |||
| 53 | fc-match findings (system fontconfig): | ||
| 54 | - `Tahoma` → NotoSans-Regular.ttf (substituted — unusable) | ||
| 55 | - `DejaVu Sans` → native, but jumping letters persisted | ||
| 56 | - `Verdana` → Noto Sans (substituted) | ||
| 57 | - `Liberation Sans` → LiberationSans-Regular.ttf (real, installed) ✓ | ||
| 58 | |||
| 59 | ## Surface Internals Observed | ||
| 60 | |||
| 61 | - Paint-stack count: `this+0x270` (nonzero while painting) | ||
| 62 | - Stack array: `this+0x264`, 0x1c-byte entries | ||
| 63 | - Popup array: `this+0x250/0x25c` | ||
| 64 | - Current font: `this+0x290`; text pos: `this+0x2c/0x30` | ||
| 65 | |||
| 66 | ## Menu | ||
| 67 | |||
| 68 | - Tree: HL2hake → Climb/Bunnyhop/ABH, children indented (`g_depth[]`, +12px/level). | ||
| 69 | - Right-aligned state at x=200: `[on]`/`[off]` for Active rows, | ||
| 70 | `[keyname]` for Bind rows, `[press key]` while binding. | ||
| 71 | - Feature gating: `feature_active(int)` (menu.cpp) — active AND | ||
| 72 | (bind==0 or key held). Called from `do_move` (hl2h.cpp) to gate | ||
| 73 | climb (middle-mouse) and bhop (jump) branches. | ||
| 74 | - Config: INI at `~/.hl2hake.ini` (climb/bhop/abh active+bind). | ||
| 75 | |||
| 76 | ## Build / Run | ||
| 77 | |||
| 78 | - `./build.sh`: g++ `-m32 -O2 -fPIC -shared`, links 5 TUs, `-ldl`, | ||
| 79 | `-Wall -Wextra -Werror` (all warnings fatal). | ||
| 80 | - `./play.sh -windowed +map d1_trainstation_01` (Steam runtime wrapper, | ||
| 81 | `LD_PRELOAD=libhl2hake.so`). | ||
| 82 | - Logs: `/tmp/hl2hake.log` (logf), `/tmp/hl2run.log` (stderr). | ||
| 83 | - Probe logging (`hook fired:`, `probe:`) removed 2026-09-12. | ||
| 84 | - `HL2H_DRAW_TEST=1` env: draws red rect + "HL2H DRAW TEST" without | ||
| 85 | opening the menu. | ||
| 86 | |||
| 87 | ## Lessons | ||
| 88 | |||
| 89 | 1. **Never pipe-mask build failures**: `./build.sh | tail` hides g++ rc. | ||
| 90 | Use `./build.sh > /tmp/build.log 2>&1; echo rc=$?`. This masked a | ||
| 91 | dropped `static bool g_in_draw` declaration for a whole session. | ||
| 92 | 2. PIC base recovery in vguimatsurface.so: string refs are | ||
| 93 | `lea -disp(%reg)` after `call thunk; add $const,%reg`; base 0x271000 | ||
| 94 | for slot-87/114 region. | ||
| 95 | 3. Check binary freshness: `strings libhl2hake.so | grep -c <newstr>` | ||
| 96 | — mtime can lie (build silently failed). | ||
| 97 | |||
| 98 | ## File Locations | ||
| 99 | |||
| 100 | - Project: `/home/salmon/Documents/rust/hl2h/` | ||
| 101 | - Hook + feature logic: `src/hl2h.cpp` | ||
| 102 | - Menu + drawing + config + input: `src/menu.cpp` | ||
| 103 | - Shared API: `src/hl2h.h` | ||
| 104 | - SDK headers: `source-sdk-2013/src/public/vgui/` | ||
