diff options
| author | salmonik <salmonik@tuta.io> | 2026-10-27 18:09:19 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-10-27 18:09:19 +0100 |
| commit | 3fae02c7d342981c9910db7715305bc57b261a8b (patch) | |
| tree | f221907effb1f84dfa3e639e3c2966e432e15c10 /src/gui.cpp | |
| parent | GUI: add F2 preview shell with dummy controls (diff) | |
| download | hl2h-3fae02c7d342981c9910db7715305bc57b261a8b.tar.gz hl2h-3fae02c7d342981c9910db7715305bc57b261a8b.zip | |
GUI: allow movement while open; freeze look and block bind capture
Feedback pass on the preview shell:
- Freeze the rendered view explicitly in CreateMove and again at
FRAME_RENDER_START; CInput was still letting mouse look move the camera.
- Allow normal WASD/jump/duck movement while the GUI is open; strip
attack/use/impulse/weapon selection so GUI clicks do not fire.
- While bind capture is active, block all game input.
- Esc no longer closes the GUI; it only cancels bind capture. F2 or the
title-bar X close the preview.
- Interpose SDL_ShowCursor / SDL_SetRelativeMouseMode / warp / window grab so
the game cannot re-capture or hide the native cursor while the GUI is open.
Diffstat (limited to 'src/gui.cpp')
| -rw-r--r-- | src/gui.cpp | 96 |
1 files changed, 90 insertions, 6 deletions
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 | ||
| 1198 | bool gui_is_open() { return g_open; } | 1194 | bool gui_is_open() { return g_open; } |
| 1195 | bool gui_bind_capture_active() { return g_open && g_capture_card >= 0; } | ||
| 1199 | QAngle gui_frozen_view() { return g_frozen; } | 1196 | QAngle 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 | |||
| 1204 | static int (*real_show_cursor)(int) = nullptr; | ||
| 1205 | static int (*real_set_relative)(int) = nullptr; | ||
| 1206 | static void (*real_warp_mouse)(void *, int, int) = nullptr; | ||
| 1207 | static void (*real_set_grab)(void *, int) = nullptr; | ||
| 1208 | |||
| 1209 | extern "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 | |||
| 1220 | extern "C" __attribute__((visibility("default"))) int | ||
| 1221 | SDL_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 | |||
| 1233 | extern "C" __attribute__((visibility("default"))) void | ||
| 1234 | SDL_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 | |||
| 1244 | extern "C" __attribute__((visibility("default"))) void | ||
| 1245 | SDL_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 | |||
| 1258 | static void (*real_set_mouse_grab)(void *, int) = nullptr; | ||
| 1259 | static void (*real_warp_global)(int, int) = nullptr; | ||
| 1260 | |||
| 1261 | extern "C" __attribute__((visibility("default"))) void | ||
| 1262 | SDL_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 | |||
| 1275 | extern "C" __attribute__((visibility("default"))) void | ||
| 1276 | SDL_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 | } | ||
