summaryrefslogtreecommitdiffstats
path: root/src/menu.cpp
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-11-03 23:21:13 +0100
committersalmonik <salmonik@tuta.io>2026-11-03 23:21:13 +0100
commit1f7c91905f69baba0aca8265c84deaba2ddac98a (patch)
tree9014a7e63e5531a05ff96c80a07ecccda927a533 /src/menu.cpp
parentRemove temporary crash-stage markers (diff)
downloadhl2h-1f7c91905f69baba0aca8265c84deaba2ddac98a.tar.gz
hl2h-1f7c91905f69baba0aca8265c84deaba2ddac98a.zip
World: add world/sky material colour modulation
Port Amalgam's modulation approach: obtain IMaterialSystem from the already loaded materialsystem.so (VMaterialSystem080) and walk materials with FirstMaterial/NextMaterial/GetMaterial. ColorModulate the "World textures" group (sky names excluded) and the "SkyBox textures"/sky-named group. The walk runs only when the enabled groups or colours change, restores white when disabled, and re-applies after level changes. Before touching materials, GetNumMaterials() and the first material's name/group are sanity-checked so a wrong vtable slot logs and aborts instead of walking garbage. GUI: "World tint" card with world/sky toggles and RGB sliders; config section [worldtint].
Diffstat (limited to 'src/menu.cpp')
-rw-r--r--src/menu.cpp45
1 files changed, 43 insertions, 2 deletions
diff --git a/src/menu.cpp b/src/menu.cpp
index 9a249f8..6a7ffe5 100644
--- a/src/menu.cpp
+++ b/src/menu.cpp
@@ -46,6 +46,11 @@ FeatureState g_triggerbot{true, 603}; // default Mouse4
46FeatureState g_silentaim{true, 602}; // default Mouse3 46FeatureState g_silentaim{true, 602}; // default Mouse3
47FeatureState g_item_esp{true, 0}; // valuable item tags, always-on by default 47FeatureState g_item_esp{true, 0}; // valuable item tags, always-on by default
48FeatureState g_fullbright{false, 0}; // mat_fullbright world lighting 48FeatureState g_fullbright{false, 0}; // mat_fullbright world lighting
49FeatureState g_world_tint{false, 0}; // material colour modulation
50bool g_tint_world_on = true;
51bool g_tint_sky_on = true;
52int g_tint_world_rgb[3] = {255, 255, 255};
53int g_tint_sky_rgb[3] = {255, 255, 255};
49bool g_item_health = true; 54bool g_item_health = true;
50bool g_item_ammo = true; 55bool g_item_ammo = true;
51bool g_item_armor = true; 56bool g_item_armor = true;
@@ -187,6 +192,12 @@ void config_save() {
187 g_silentaim.bind, g_silent_fov); 192 g_silentaim.bind, g_silent_fov);
188 fprintf(f, "[fullbright]\nactive=%d\nbind=%d\n", g_fullbright.active, 193 fprintf(f, "[fullbright]\nactive=%d\nbind=%d\n", g_fullbright.active,
189 g_fullbright.bind); 194 g_fullbright.bind);
195 fprintf(f, "[worldtint]\nactive=%d\nbind=%d\nworld=%d\nsky=%d\n"
196 "wr=%d\nwg=%d\nwb=%d\nsr=%d\nsg=%d\nsb=%d\n",
197 g_world_tint.active, g_world_tint.bind, (int)g_tint_world_on,
198 (int)g_tint_sky_on, g_tint_world_rgb[0], g_tint_world_rgb[1],
199 g_tint_world_rgb[2], g_tint_sky_rgb[0], g_tint_sky_rgb[1],
200 g_tint_sky_rgb[2]);
190 fprintf(f, "[items]\nactive=%d\nbind=%d\nhealth=%d\nammo=%d\n" 201 fprintf(f, "[items]\nactive=%d\nbind=%d\nhealth=%d\nammo=%d\n"
191 "armor=%d\nweapons=%d\ncrates=%d\ndistance=%d\nmax_dist=%d\n", 202 "armor=%d\nweapons=%d\ncrates=%d\ndistance=%d\nmax_dist=%d\n",
192 g_item_esp.active, g_item_esp.bind, (int)g_item_health, 203 g_item_esp.active, g_item_esp.bind, (int)g_item_health,
@@ -220,7 +231,8 @@ static bool config_load() {
220 char line[256]; 231 char line[256];
221 FeatureState *cur = nullptr; 232 FeatureState *cur = nullptr;
222 bool in_esp = false, in_bhop = false, in_aim = false, in_silent = false, 233 bool in_esp = false, in_bhop = false, in_aim = false, in_silent = false,
223 in_jumpbug = false, in_spread = false, in_items = false; 234 in_jumpbug = false, in_spread = false, in_items = false,
235 in_tint = false;
224 while (fgets(line, sizeof(line), f)) { 236 while (fgets(line, sizeof(line), f)) {
225 line[strcspn(line, "\r\n")] = 0; 237 line[strcspn(line, "\r\n")] = 0;
226 if (line[0] == '[') { 238 if (line[0] == '[') {
@@ -240,6 +252,8 @@ static bool config_load() {
240 cur = &g_item_esp; 252 cur = &g_item_esp;
241 else if (strstr(line, "[fullbright]")) 253 else if (strstr(line, "[fullbright]"))
242 cur = &g_fullbright; 254 cur = &g_fullbright;
255 else if (strstr(line, "[worldtint]"))
256 cur = &g_world_tint;
243 else if (strstr(line, "[aimbot]")) 257 else if (strstr(line, "[aimbot]"))
244 cur = &g_aimbot; 258 cur = &g_aimbot;
245 else if (strstr(line, "[triggerbot]")) 259 else if (strstr(line, "[triggerbot]"))
@@ -255,6 +269,7 @@ static bool config_load() {
255 in_jumpbug = (cur == &g_jumpbug); 269 in_jumpbug = (cur == &g_jumpbug);
256 in_spread = (cur == &g_spread); 270 in_spread = (cur == &g_spread);
257 in_items = (cur == &g_item_esp); 271 in_items = (cur == &g_item_esp);
272 in_tint = (cur == &g_world_tint);
258 } else if (cur) { 273 } else if (cur) {
259 char *eq = strchr(line, '='); 274 char *eq = strchr(line, '=');
260 if (!eq) 275 if (!eq)
@@ -325,6 +340,25 @@ static bool config_load() {
325 if (v > 180) v = 180; 340 if (v > 180) v = 180;
326 g_silent_fov = v; 341 g_silent_fov = v;
327 } 342 }
343 if (in_tint) {
344 if (strcmp(key, "world") == 0)
345 g_tint_world_on = atoi(val) != 0;
346 else if (strcmp(key, "sky") == 0)
347 g_tint_sky_on = atoi(val) != 0;
348 else if (strcmp(key, "wr") == 0 || strcmp(key, "wg") == 0 ||
349 strcmp(key, "wb") == 0) {
350 int v = atoi(val);
351 if (v < 0) v = 0;
352 if (v > 255) v = 255;
353 g_tint_world_rgb[key[1] == 'r' ? 0 : key[1] == 'g' ? 1 : 2] = v;
354 } else if (strcmp(key, "sr") == 0 || strcmp(key, "sg") == 0 ||
355 strcmp(key, "sb") == 0) {
356 int v = atoi(val);
357 if (v < 0) v = 0;
358 if (v > 255) v = 255;
359 g_tint_sky_rgb[key[1] == 'r' ? 0 : key[1] == 'g' ? 1 : 2] = v;
360 }
361 }
328 if (in_esp) { 362 if (in_esp) {
329 if (strcmp(key, "neutral") == 0) 363 if (strcmp(key, "neutral") == 0)
330 g_esp_opt[ESP_OPT_SHOW_NEUTRAL] = atoi(val) != 0; 364 g_esp_opt[ESP_OPT_SHOW_NEUTRAL] = atoi(val) != 0;
@@ -378,6 +412,11 @@ void config_reset_defaults() {
378 g_esp_opt[i] = true; 412 g_esp_opt[i] = true;
379 g_item_esp = {true, 0}; 413 g_item_esp = {true, 0};
380 g_fullbright = {false, 0}; 414 g_fullbright = {false, 0};
415 g_world_tint = {false, 0};
416 g_tint_world_on = true;
417 g_tint_sky_on = true;
418 g_tint_world_rgb[0] = g_tint_world_rgb[1] = g_tint_world_rgb[2] = 255;
419 g_tint_sky_rgb[0] = g_tint_sky_rgb[1] = g_tint_sky_rgb[2] = 255;
381 g_item_health = true; 420 g_item_health = true;
382 g_item_ammo = true; 421 g_item_ammo = true;
383 g_item_armor = true; 422 g_item_armor = true;
@@ -495,7 +534,7 @@ static FeatureState *feature_state(int feature) {
495 static FeatureState *feats[FEAT_COUNT] = { 534 static FeatureState *feats[FEAT_COUNT] = {
496 &g_bhop, &g_abh, &g_esp, &g_aimbot, &g_triggerbot, 535 &g_bhop, &g_abh, &g_esp, &g_aimbot, &g_triggerbot,
497 &g_silentaim, &g_jumpbug, &g_melee, &g_spread, &g_item_esp, 536 &g_silentaim, &g_jumpbug, &g_melee, &g_spread, &g_item_esp,
498 &g_fullbright}; 537 &g_fullbright, &g_world_tint};
499 if (feature < 0 || feature >= FEAT_COUNT) 538 if (feature < 0 || feature >= FEAT_COUNT)
500 return nullptr; 539 return nullptr;
501 return feats[feature]; 540 return feats[feature];
@@ -701,6 +740,7 @@ void fullbright_update() {
701void outer_draw() { 740void outer_draw() {
702 poll_keyboard(); 741 poll_keyboard();
703 fullbright_update(); 742 fullbright_update();
743 world_tint_update();
704 gui_handle_input(); 744 gui_handle_input();
705 // HL2H_DRAW_TEST=1 draws a probe rect without needing the GUI open 745 // HL2H_DRAW_TEST=1 draws a probe rect without needing the GUI open
706 static bool draw_test = getenv("HL2H_DRAW_TEST") != nullptr; 746 static bool draw_test = getenv("HL2H_DRAW_TEST") != nullptr;
@@ -721,6 +761,7 @@ void outer_draw() {
721 if (le != last_local) { 761 if (le != last_local) {
722 last_local = le; 762 last_local = le;
723 font_reset = true; 763 font_reset = true;
764 world_tint_invalidate();
724 } 765 }
725 } 766 }
726 if (font_reset && g_font) { 767 if (font_reset && g_font) {