From 9c4455af43da34127864b09ad2a3d3e996c9dce1 Mon Sep 17 00:00:00 2001 From: salmonik Date: Tue, 3 Nov 2026 23:58:59 +0100 Subject: World: replace skybox changer with a PNG skybox image sv_skyname did not take effect at runtime in this build, so the Skybox card now replaces the skybox materials' textures with /skybox.png. The PNG is decoded through libpng16's simplified API (dlopen'ed, so no new link dependency) and uploaded with IMaterialSystem::CreateTextureFromBits as an RGBA8888 texture. IMaterialVar::SetTextureValue assigns it to $basetexture and the HDR variants for every material in the SkyBox textures group (all six faces get the same image). Original textures are recorded per material/var (texture pointer plus string fallback) and restored when the feature is off. Records survive level changes so a reused sky material is still restorable; the override is re-applied to a new map automatically. The card shows the image path and has a Reload image button; a missing/unreadable PNG raises an error toast. --- src/gui.cpp | 77 +++++++++++++------------------------------------------------ 1 file changed, 16 insertions(+), 61 deletions(-) (limited to 'src/gui.cpp') diff --git a/src/gui.cpp b/src/gui.cpp index 5fb8fa7..eb53dff 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -183,11 +183,10 @@ enum CtrlKind { CK_SECTION, CK_INFO, CK_BUTTON, - CK_COLOR, - CK_CHOICE + CK_COLOR }; -enum CtrlAction { ACT_NONE = 0, ACT_RELOAD, ACT_RESET }; +enum CtrlAction { ACT_NONE = 0, ACT_RELOAD, ACT_RESET, ACT_SKY_RELOAD }; struct Ctrl { int kind; @@ -196,8 +195,6 @@ struct Ctrl { bool *bval; // CK_TOGGLE int *ival; // CK_SLIDER int *rgb; // CK_COLOR: three ints, 0..255 - const char *const *opts; // CK_CHOICE: option labels - int nopts; int min, max; int action; // CK_BUTTON bool zero_unlimited; // slider: value 0 displays as "All" @@ -256,8 +253,6 @@ static void add_ctrl(int card, int kind, const char *label, const char *desc, c.action = action; c.zero_unlimited = false; c.rgb = nullptr; - c.opts = nullptr; - c.nopts = 0; c.hue = 0.0f; c.sat = 0.0f; c.val = 1.0f; @@ -287,19 +282,11 @@ static void add_color(int card, const char *label, const char *desc, add_ctrl(card, CK_COLOR, label, desc, 0, 255, nullptr, nullptr, ACT_NONE); g_ctrls[i].rgb = rgb; } -static void add_choice(int card, const char *label, const char *desc, - const char *const *opts, int nopts, int *value) { - int i = g_nctrl; - add_ctrl(card, CK_CHOICE, label, desc, 0, nopts > 0 ? nopts - 1 : 0, - nullptr, value, ACT_NONE); - g_ctrls[i].opts = opts; - g_ctrls[i].nopts = nopts; -} static int ctrl_val(const Ctrl &c) { if (c.kind == CK_TOGGLE && c.bval) return *c.bval ? 1 : 0; - if ((c.kind == CK_SLIDER || c.kind == CK_CHOICE) && c.ival) + if (c.kind == CK_SLIDER && c.ival) return *c.ival; return 0; } @@ -307,7 +294,7 @@ static void ctrl_set(Ctrl &c, int v) { if (c.kind == CK_TOGGLE && c.bval) { *c.bval = v != 0; config_save(); - } else if ((c.kind == CK_SLIDER || c.kind == CK_CHOICE) && c.ival) { + } else if (c.kind == CK_SLIDER && c.ival) { if (v < c.min) v = c.min; if (v > c.max) v = c.max; if (*c.ival != v) { @@ -433,12 +420,17 @@ static void build_cards() { add_toggle(fog, "Remove fog", "Disable fog entirely instead of recolouring it.", &g_fog_disable); + static char sky_label[512]; + snprintf(sky_label, sizeof(sky_label), "Image: %s", + config_file_cstr("skybox.png")); int sky = add_card(2, &g_skybox, "Skybox", - "Swap the skybox at runtime through sv_skyname. The " - "map's own sky comes back on level change.", + "Replace the map skybox with a PNG image from the " + "config directory (all six faces).", true); - add_choice(sky, "Sky", "Pick a skybox from the HL2 set.", skybox_options(), - skybox_option_count(), &g_skybox_choice); + add_info(sky, sky_label); + add_info(sky, "Edit skybox.png, then Reload image. Off restores the map sky."); + add_button(sky, "Reload image", "Re-read the PNG and apply it again.", + ACT_SKY_RELOAD); int spread = add_card(3, &g_spread, "Spread control", "Choose a server shot seed that tightens the cone.", @@ -855,8 +847,6 @@ static int header_h(const Card &c) { static int label_max_w(const Ctrl &c) { if (c.kind == CK_SLIDER) return S(214.0f); - if (c.kind == CK_CHOICE) - return card_content_w() - S(16.0f) - S(250.0f); return card_content_w() - S(16.0f) - S(110.0f); } @@ -1431,25 +1421,6 @@ static void handle_mouse_click() { } return; } - if (ct.kind == CK_CHOICE) { - int base = label_row_h(ct); - Rect box{cr.x + cr.w - S(238.0f), - by + (base - S(24.0f)) / 2, S(222.0f), S(24.0f)}; - if (box.has(mx, my)) { - int v = ctrl_val(ct); - if (mx < box.x + S(36.0f)) - v--; - else if (mx >= box.x + box.w - S(36.0f)) - v++; - if (v < 0) v = 0; - if (ct.nopts > 0 && v >= ct.nopts) v = ct.nopts - 1; - if (v != ctrl_val(ct)) { - *ct.ival = v; - config_save(); - } - } - return; - } if (ct.kind == CK_BUTTON) { int bw = button_w(ct.label); Rect b{cr.x + cr.w - S(16.0f) - bw, @@ -1469,6 +1440,9 @@ static void handle_mouse_click() { g_reset_armed = true; g_reset_armed_at = now; } + } else if (ct.action == ACT_SKY_RELOAD) { + skybox_reload_image(); + toastf(TOAST_INFO, "Reloading skybox.png"); } return; } @@ -1840,25 +1814,6 @@ static void draw_card(const Rect &clip, int index, int y) { outline(sw, picker_open_for(ct) ? C_ACCENT : C_BORDER, &clip); if (picker_open_for(ct)) draw_picker(clip, cr, ct, by); - } else if (ct.kind == CK_CHOICE) { - int v = ctrl_val(ct); - const char *name = (ct.opts && v >= 0 && v < ct.nopts) - ? ct.opts[v] - : "?"; - Rect box{cr.x + cr.w - S(238.0f), - by + (base_h - S(24.0f)) / 2, S(222.0f), S(24.0f)}; - fill(box, Col{45, 50, 60, 255}, &clip); - outline(box, C_BORDER, &clip); - int ty = box.y + (box.h - g_body_h) / 2; - text_in(clip, box.x + S(8.0f), ty, "<", g_font_body, g_body_h, 0, - C_DIM); - text_in(clip, box.x + box.w - S(16.0f), ty, ">", g_font_body, g_body_h, - 0, C_DIM); - int w = text_w(name, g_body_h); - int tx = box.x + (box.w - w) / 2; - if (tx < box.x + S(24.0f)) - tx = box.x + S(24.0f); - text_in(clip, tx, ty, name, g_font_body, g_body_h, 0, C_TEXT); } } by += rh; -- cgit v1.2.3