summaryrefslogtreecommitdiffstats
path: root/src/ISURFACE_STATUS.md
diff options
context:
space:
mode:
Diffstat (limited to 'src/ISURFACE_STATUS.md')
-rw-r--r--src/ISURFACE_STATUS.md104
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
7Overlay drawing works in-game and in menus. Draw path: `PaintTraverseEx`
8hook (slot 114) on the copied ISurface vtable, wrapping our draws in
9`PushMakeCurrent(panel, false)` / `PopMakeCurrent(panel)` around ISurface
10slots 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
31Slot mapping rule: **binary slot = SDK-header slot + 4** (confirmed via
32CreateFont 62→66 and PaintTraverseEx 110→114). Vtable has 179 entries;
33slots 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
46Font alignment problem: `Tahoma` placeholder fontconfig-substituted to
47Noto Sans → per-glyph baseline jumps (fallback-substitution glyph metrics).
48Fixes 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
51range forces one font pass → uniform metrics, no jumping letters.
52
53fc-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
891. **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.
922. 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.
953. 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/`