summaryrefslogtreecommitdiffstats
path: root/src/ISURFACE_STATUS.md
blob: 53be3b02fadef6bc970d659eb7637647a50cba74 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# HL2hake ISurface Drawing — Status Report

## Date: 2026-09-12, updated 2026-10-27

## Result: WORKING

Overlay drawing works in-game and in menus. Draw path: `PaintTraverseEx`
hook (slot 114) on the copied ISurface vtable, wrapping our draws in
`PushMakeCurrent(panel, false)` / `PopMakeCurrent(panel)` around ISurface
slots 6/10/12/15/17/18/20/22/66/67.

## Confirmed ISurface VTable Slots (disassembly-verified, binary=SDK header+4)

| Slot | Function                                  | Evidence |
|------|-------------------------------------------|----------|
| 6    | `GetEmbeddedPanel()`                      | returns VPANEL used with PushMakeCurrent |
| 8    | `PushMakeCurrent(VPANEL, bool)`           | verified via disassembly |
| 9    | `PopMakeCurrent(VPANEL)`                  | verified via disassembly |
| 10   | `DrawSetColor(int r,g,b,a)`               | stores RGBA at `this+0x24..0x27` |
| 12   | `DrawFilledRect(int x0,y0,x1,y1)`         | verified via disassembly |
| 14   | `DrawOutlinedRect(int x0,y0,x1,y1)`       | SDK header 10 + 4 |
| 15   | `DrawLine(int x0,y0,x1,y1)`               | SDK header 11 + 4 (skeleton ESP) |
| 17   | `DrawSetTextFont(HFont)`                  | stores HFont at `this+0x290` |
| 18   | `DrawSetTextColor(int r,g,b,a)`           | stores RGBA at `this+0x28..0x2b` |
| 20   | `DrawSetTextPos(int x,y)`                 | stores at `this+0x2c/0x30` |
| 22   | `DrawPrintText(wchar_t*, int, drawType)`  | reads font `0x290`, pos `0x2c/0x30` |
| 66   | `CreateFont()`                            | SDK header 62; empirical (379) |
| 67   | `AddGlyphSetToFont(font,name,tall,weight,blur,scanlines,flags,rangeMin,rangeMax)` | SDK header 62+4; disassembly (slot 67 = 0x6a300, passes 9 args to FontManager) |
| 75   | `GetTextSize(HFont, const wchar_t*, int& wide, int& tall)` | SDK header 71+4; used for accurate GUI wrapping |
| 87   | `SolveTraverse`                           | InternalSchemeSettingsTraverse profiling strings @ 0x73240 |
| 88   | `PaintTraverse(VPANEL)`                   | tail-calls `ipanel->vt+0x1c8(panel,false)` @ 0x697e0 |
| 114  | `PaintTraverseEx(VPANEL, bool paintPopups)` | IsVisible check `ipanel+0x40`, popup array `this+0x250/0x25c`, "Too many popups!" assert @ 0x6dd46 |

Slot mapping rule: **binary slot = SDK-header slot + 4** (confirmed via
CreateFont 62→66 and PaintTraverseEx 110→114). Vtable has 179 entries;
slots 122–148 = second base class `IMatSystemSurface`
(AttachToWindow=122 … DrawSetTextureRGBAEx2=148).

## Draw-Path Decision

- **Primary: PaintTraverseEx (slot 114)** — fires every frame for the root panel.
- **Fallback kept: DrawPrintText (slot 22)** — fires only when the game draws
  text (menus); also used as in-draw call site for the game's own text.
- `g_in_draw` (hl2h.cpp) prevents recursion; both hooks call `outer_draw()`
  (menu.cpp) guarded by it.

## Fonts (the long fight)

Font alignment problem: `Tahoma` placeholder fontconfig-substituted to
Noto Sans → per-glyph baseline jumps (fallback-substitution glyph metrics).
Fixes tried in order: Tahoma → DejaVu Sans (+ANTIALIAS 0x10) → no AA →
**winner: "Liberation Sans" 16px, weight 400, flags 0x400 (FONTFLAG_CUSTOM), glyph range pinned 0x20–0xFF**.
`FONTFLAG_CUSTOM` disables the Asian fallback-compat glyph path; pinned
range forces one font pass → uniform metrics, no jumping letters.

fc-match findings (system fontconfig):
- `Tahoma` → NotoSans-Regular.ttf (substituted — unusable)
- `DejaVu Sans` → native, but jumping letters persisted
- `Verdana` → Noto Sans (substituted)
- `Liberation Sans` → LiberationSans-Regular.ttf (real, installed) ✓

## Surface Internals Observed

- Paint-stack count: `this+0x270` (nonzero while painting)
- Stack array: `this+0x264`, 0x1c-byte entries
- Popup array: `this+0x250/0x25c`
- Current font: `this+0x290`; text pos: `this+0x2c/0x30`

## Menu

- Custom immediate-mode GUI; `Insert` is the only toggle.
- Sidebar: Movement / Combat / Visuals / Weapons / System. Cards show
  Active + Bind and collapsible settings; System has config path, build info,
  Reload and two-click Reset.
- Feature gating: `feature_active(int)` (menu.cpp) — active AND
  (bind==0 or key held), used by `do_move` and the aim features.
- Layout (`x`, `y`, `category`, `expanded` bitmask) persists under `[gui]`.
- Config: `$XDG_CONFIG_HOME/hl2hake/config` (fallback `~/.config/hl2hake/config`);
  writes are atomic (`.tmp` + rename).
- Toasts are drawn by `gui.cpp` even when the menu is closed.

## Build / Run

- `./build.sh`: g++ `-m32 -O2 -std=c++17 -fPIC -shared`, 10 TUs
  (`hl2h modules cinput netvars menu gui esp server bones vischeck`), `-ldl`,
  `-Wall -Wextra -Werror` (all warnings fatal).
- `./play.sh -windowed +map d1_trainstation_01` (Steam runtime wrapper,
  `LD_PRELOAD=libhl2hake.so`).
- Logs: `/tmp/hl2hake.log` (logf), stderr.
- `HL2H_DRAW_TEST=1` env: draws red rect + "HL2H DRAW TEST" without
  opening the menu. `HL2H_BONE_DEBUG=1` draws head-hitbox markers.

## Lessons

1. **Never pipe-mask build failures**: `./build.sh | tail` hides g++ rc.
   Use `./build.sh > /tmp/build.log 2>&1; echo rc=$?`. This masked a
   dropped `static bool g_in_draw` declaration for a whole session.
2. PIC base recovery in vguimatsurface.so: string refs are
   `lea -disp(%reg)` after `call thunk; add $const,%reg`; base 0x271000
   for slot-87/114 region.
3. Check binary freshness: `strings libhl2hake.so | grep -c <newstr>`
   — mtime can lie (build silently failed).

## File Locations

- Project: `/home/salmon/Documents/rust/hl2h/`
- Hook + movement/feature logic: `src/hl2h.cpp`
- Menu + drawing + config + input: `src/menu.cpp`
- ESP / skeleton drawing / aimbot / silent aim: `src/esp.cpp`
- Bones + hitboxes: `src/bones.cpp`
- Server-side entity/health access: `src/server.cpp`
- World vischeck / entity trace: `src/vischeck.cpp`
- Shared API: `src/hl2h.h`
- Current project overview: `CONTEXT.md`
- SDK headers: `source-sdk-2013/src/public/vgui/`