summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--CONTEXT.md16
-rw-r--r--docs/adr/0001-custom-isurface-gui.md5
-rw-r--r--src/gui.cpp96
-rw-r--r--src/hl2h.cpp38
-rw-r--r--src/hl2h.h1
5 files changed, 133 insertions, 23 deletions
diff --git a/CONTEXT.md b/CONTEXT.md
index 1c43b1f..53c662e 100644
--- a/CONTEXT.md
+++ b/CONTEXT.md
@@ -148,20 +148,24 @@ Binds use SDL scancodes; mouse buttons are pseudo-scancodes 600..604.
148- **Category**: sidebar group. Movement, Combat, Visuals, Weapons, System. 148- **Category**: sidebar group. Movement, Combat, Visuals, Weapons, System.
149- **Card**: per-feature panel. Header always shows Active + Bind; body is a 149- **Card**: per-feature panel. Header always shows Active + Bind; body is a
150 collapsible set of settings. 150 collapsible set of settings.
151- **Freeze**: while the GUI is open, the usercmd movement/buttons/impulses/view 151- **Freeze**: while the GUI is open, look/attack/use/impulse/weapon selection
152 are held and combat features are skipped; the game keeps simulating and 152 are blocked and combat features are skipped, but normal WASD/jump/duck
153 ESP/FOV circle/speed graph keep drawing. No invulnerability. 153 movement is allowed. Bind capture blocks all game input until it ends. The
154 game keeps simulating and ESP/FOV circle/speed graph keep drawing. No
155 invulnerability.
154- **Native cursor**: on open, leave SDL relative-mouse mode and show the OS 156- **Native cursor**: on open, leave SDL relative-mouse mode and show the OS
155 cursor; restore on close. Absolute mouse coordinates are used. 157 cursor; restore on close. Absolute mouse coordinates are used.
156- **Bind capture**: click Bind, press a key/button; Esc or clicking elsewhere 158- **Bind capture**: click Bind, press a key/button; Esc cancels capture but
157 cancels; Clear sets None; Insert is reserved for the GUI. 159 does not close the GUI; clicking elsewhere cancels; Clear sets None; Insert
160 is reserved for the GUI.
158- **UI scale**: `clamp(min(screen_w/1920, screen_h/1080), 0.75, 1.5)`; base 161- **UI scale**: `clamp(min(screen_w/1920, screen_h/1080), 0.75, 1.5)`; base
159 window 960x620, body/title fonts 15/20 px at scale 1. 162 window 960x620, body/title fonts 15/20 px at scale 1.
160- Every feature gets Active + Bind; bind None means always-on. 163- Every feature gets Active + Bind; bind None means always-on.
161- System page: config path/build info, Reload config, and a two-click Reset 164- System page: config path/build info, Reload config, and a two-click Reset
162 that restores feature settings/binds but keeps GUI layout. 165 that restores feature settings/binds but keeps GUI layout.
163- Window: fixed-size, draggable by title bar, clamped to screen, position, 166- Window: fixed-size, draggable by title bar, clamped to screen, position,
164 category and expanded cards persisted under `[gui]`. 167 category and expanded cards persisted under `[gui]`. Esc does not close the
168 GUI; the toggle key or title-bar X does.
165 169
166 170
167## Bones / ESP 171## Bones / ESP
diff --git a/docs/adr/0001-custom-isurface-gui.md b/docs/adr/0001-custom-isurface-gui.md
index 9da3c0c..9595ca8 100644
--- a/docs/adr/0001-custom-isurface-gui.md
+++ b/docs/adr/0001-custom-isurface-gui.md
@@ -38,8 +38,9 @@ path.
38- Left sidebar categories (Movement, Combat, Visuals, Weapons, System) and a 38- Left sidebar categories (Movement, Combat, Visuals, Weapons, System) and a
39 content pane of feature cards with collapsible settings. 39 content pane of feature cards with collapsible settings.
40- Native OS cursor by releasing SDL relative-mouse mode while the GUI is open. 40- Native OS cursor by releasing SDL relative-mouse mode while the GUI is open.
41- While open, freeze usercmd input/view and skip combat features; keep the 41- While open, freeze look/attack/use and skip combat features, but allow
42 game simulating and keep ESP/FOV circle/speed graph drawing. 42 normal movement; bind capture blocks all game input. Keep the game
43 simulating and keep ESP/FOV circle/speed graph drawing.
43- Replace the text menu with the GUI. No permanent fallback menu; git history 44- Replace the text menu with the GUI. No permanent fallback menu; git history
44 retains the old implementation. 45 retains the old implementation.
45 46
diff --git a/src/gui.cpp b/src/gui.cpp
index 74dd537..923cd4d 100644
--- a/src/gui.cpp
+++ b/src/gui.cpp
@@ -879,12 +879,8 @@ void gui_handle_input() {
879 return; 879 return;
880 } 880 }
881 881
882 if (esc_edge) { 882 if (esc_edge && g_capture_card >= 0)
883 if (g_capture_card >= 0) 883 g_capture_card = -1;
884 g_capture_card = -1;
885 else
886 close_gui();
887 }
888 884
889 // Keep the native cursor free even if the game re-grabs it. 885 // Keep the native cursor free even if the game re-grabs it.
890 if (sd_set_relative) 886 if (sd_set_relative)
@@ -1196,4 +1192,92 @@ void gui_draw() {
1196} 1192}
1197 1193
1198bool gui_is_open() { return g_open; } 1194bool gui_is_open() { return g_open; }
1195bool gui_bind_capture_active() { return g_open && g_capture_card >= 0; }
1199QAngle gui_frozen_view() { return g_frozen; } 1196QAngle gui_frozen_view() { return g_frozen; }
1197
1198// ---------------------------------------------------------------------------
1199// SDL cursor interposition
1200// ---------------------------------------------------------------------------
1201// The game re-asserts relative mouse mode / hides the cursor every frame. While
1202// the GUI is open, force the opposite so the native cursor stays usable.
1203
1204static int (*real_show_cursor)(int) = nullptr;
1205static int (*real_set_relative)(int) = nullptr;
1206static void (*real_warp_mouse)(void *, int, int) = nullptr;
1207static void (*real_set_grab)(void *, int) = nullptr;
1208
1209extern "C" __attribute__((visibility("default"))) int SDL_ShowCursor(int toggle) {
1210 if (!real_show_cursor)
1211 real_show_cursor = (int (*)(int))dlsym(RTLD_NEXT, "SDL_ShowCursor");
1212 if (g_open && toggle != -1) {
1213 if (real_show_cursor)
1214 real_show_cursor(1);
1215 return 1;
1216 }
1217 return real_show_cursor ? real_show_cursor(toggle) : 0;
1218}
1219
1220extern "C" __attribute__((visibility("default"))) int
1221SDL_SetRelativeMouseMode(int enabled) {
1222 if (!real_set_relative)
1223 real_set_relative =
1224 (int (*)(int))dlsym(RTLD_NEXT, "SDL_SetRelativeMouseMode");
1225 if (g_open) {
1226 if (real_set_relative)
1227 real_set_relative(0);
1228 return 0;
1229 }
1230 return real_set_relative ? real_set_relative(enabled) : 0;
1231}
1232
1233extern "C" __attribute__((visibility("default"))) void
1234SDL_WarpMouseInWindow(void *window, int x, int y) {
1235 if (!real_warp_mouse)
1236 real_warp_mouse =
1237 (void (*)(void *, int, int))dlsym(RTLD_NEXT, "SDL_WarpMouseInWindow");
1238 if (g_open)
1239 return;
1240 if (real_warp_mouse)
1241 real_warp_mouse(window, x, y);
1242}
1243
1244extern "C" __attribute__((visibility("default"))) void
1245SDL_SetWindowGrab(void *window, int grabbed) {
1246 if (!real_set_grab)
1247 real_set_grab =
1248 (void (*)(void *, int))dlsym(RTLD_NEXT, "SDL_SetWindowGrab");
1249 if (g_open) {
1250 if (real_set_grab)
1251 real_set_grab(window, 0);
1252 return;
1253 }
1254 if (real_set_grab)
1255 real_set_grab(window, grabbed);
1256}
1257
1258static void (*real_set_mouse_grab)(void *, int) = nullptr;
1259static void (*real_warp_global)(int, int) = nullptr;
1260
1261extern "C" __attribute__((visibility("default"))) void
1262SDL_SetWindowMouseGrab(void *window, int grabbed) {
1263 if (!real_set_mouse_grab)
1264 real_set_mouse_grab =
1265 (void (*)(void *, int))dlsym(RTLD_NEXT, "SDL_SetWindowMouseGrab");
1266 if (g_open) {
1267 if (real_set_mouse_grab)
1268 real_set_mouse_grab(window, 0);
1269 return;
1270 }
1271 if (real_set_mouse_grab)
1272 real_set_mouse_grab(window, grabbed);
1273}
1274
1275extern "C" __attribute__((visibility("default"))) void
1276SDL_WarpMouseGlobal(int x, int y) {
1277 if (!real_warp_global)
1278 real_warp_global = (void (*)(int, int))dlsym(RTLD_NEXT, "SDL_WarpMouseGlobal");
1279 if (g_open)
1280 return;
1281 if (real_warp_global)
1282 real_warp_global(x, y);
1283}
diff --git a/src/hl2h.cpp b/src/hl2h.cpp
index c0c27af..a0e6b53 100644
--- a/src/hl2h.cpp
+++ b/src/hl2h.cpp
@@ -546,10 +546,23 @@ static void do_move(int seq, float frametime) {
546 cmd->viewangles[0] = f.x; 546 cmd->viewangles[0] = f.x;
547 cmd->viewangles[1] = f.y; 547 cmd->viewangles[1] = f.y;
548 cmd->viewangles[2] = f.z; 548 cmd->viewangles[2] = f.z;
549 cmd->forwardmove = 0.0f; 549 // Freeze the rendered view explicitly: CInput may not push the modified
550 cmd->sidemove = 0.0f; 550 // command view back to the engine if the client mode returns false.
551 cmd->upmove = 0.0f; 551 if (g_iface.engine) {
552 cmd->buttons = 0; 552 QAngle set = f;
553 using SetViewFn = void (*)(void *, QAngle *);
554 vfunc<SetViewFn>(g_iface.engine, 20)(g_iface.engine, &set);
555 }
556 if (gui_bind_capture_active()) {
557 // Bind capture must not move/act in the game while keys are sampled.
558 cmd->forwardmove = 0.0f;
559 cmd->sidemove = 0.0f;
560 cmd->upmove = 0.0f;
561 cmd->buttons = 0;
562 } else {
563 // Movement is allowed while the GUI is open, but not look/attack/use.
564 cmd->buttons &= (IN_JUMP | IN_DUCK);
565 }
553 cmd->impulse = 0; 566 cmd->impulse = 0;
554 cmd->weaponselect = 0; 567 cmd->weaponselect = 0;
555 cmd->weaponsubtype = 0; 568 cmd->weaponsubtype = 0;
@@ -670,12 +683,19 @@ void set_silent_restore(const QAngle &angles) {
670static void hkdFrameStageNotify(void *self, int stage) { 683static void hkdFrameStageNotify(void *self, int stage) {
671 if (oFrameStageNotify) 684 if (oFrameStageNotify)
672 oFrameStageNotify(self, stage); 685 oFrameStageNotify(self, stage);
673 if (stage == 5 && g_silent_restore_pending) { 686 if (stage == 5) {
674 g_silent_restore_pending = false; 687 if (g_silent_restore_pending) {
675 if (g_iface.engine) { 688 g_silent_restore_pending = false;
676 QAngle a = g_silent_restore_angles; 689 if (g_iface.engine) {
690 QAngle a = g_silent_restore_angles;
691 using SetViewFn = void (*)(void *, QAngle *);
692 vfunc<SetViewFn>(g_iface.engine, 20)(g_iface.engine, &a);
693 }
694 }
695 if (gui_is_open() && g_iface.engine) {
696 QAngle f = gui_frozen_view();
677 using SetViewFn = void (*)(void *, QAngle *); 697 using SetViewFn = void (*)(void *, QAngle *);
678 vfunc<SetViewFn>(g_iface.engine, 20)(g_iface.engine, &a); 698 vfunc<SetViewFn>(g_iface.engine, 20)(g_iface.engine, &f);
679 } 699 }
680 } 700 }
681} 701}
diff --git a/src/hl2h.h b/src/hl2h.h
index 11b9014..8a81439 100644
--- a/src/hl2h.h
+++ b/src/hl2h.h
@@ -234,6 +234,7 @@ void menu_force_close();
234void gui_handle_input(); 234void gui_handle_input();
235void gui_draw(); 235void gui_draw();
236bool gui_is_open(); 236bool gui_is_open();
237bool gui_bind_capture_active();
237QAngle gui_frozen_view(); 238QAngle gui_frozen_view();
238// ISurface pointer (defined in menu.cpp, used for drawing tests) 239// ISurface pointer (defined in menu.cpp, used for drawing tests)
239struct ISurface; 240struct ISurface;