diff options
| author | salmonik <salmonik@tuta.io> | 2026-11-04 14:07:49 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-11-04 14:07:49 +0100 |
| commit | 5bc97393aee4124b00db3ab4fbe8d6e26ba88069 (patch) | |
| tree | 7315ee842a071d30f5e035b9a11b0a8045e26588 | |
| parent | Transitions: per-trigger targets and 3D wireframe; FOV range fixes (diff) | |
| download | hl2h-5bc97393aee4124b00db3ab4fbe8d6e26ba88069.tar.gz hl2h-5bc97393aee4124b00db3ab4fbe8d6e26ba88069.zip | |
Gamma: clamp slider to the engine's 2.6 cap, defer readback
The engine clamps mat_monitorgamma at 2.6, so the 2.8..3.0 end of the slider
did nothing. Read the value back one tick later (ClientCmd is queued) and
interpose SDL_SetWindowGammaRamp to see whether the engine pushes a ramp at
all.
| -rw-r--r-- | CONTEXT.md | 15 | ||||
| -rw-r--r-- | src/gui.cpp | 27 | ||||
| -rw-r--r-- | src/hl2h.cpp | 15 | ||||
| -rw-r--r-- | src/menu.cpp | 2 |
4 files changed, 46 insertions, 13 deletions
| @@ -239,11 +239,16 @@ vocabulary / decisions. | |||
| 239 | migrate to the stock value). | 239 | migrate to the stock value). |
| 240 | - `viewmodel_fov` and `mat_monitorgamma` are client cvars; applied through | 240 | - `viewmodel_fov` and `mat_monitorgamma` are client cvars; applied through |
| 241 | `ClientCmd` when their slider changes. Gamma is stored as x10 | 241 | `ClientCmd` when their slider changes. Gamma is stored as x10 |
| 242 | (`[view] gamma=22` = 2.2). The gamma value is read back through | 242 | (`[view] gamma=22` = 2.2) and the slider stops at 26 because the engine |
| 243 | `ICvar::FindVar` and logged (`view: gamma request ..., cvar reports ...`) | 243 | clamps `mat_monitorgamma` at 2.6. The value is read back through |
| 244 | to distinguish a rejected command from an OS gamma ramp the compositor | 244 | `ICvar::FindVar` on the next tick (ClientCmd is queued) and logged |
| 245 | ignores. Both live in the always-on `Camera / display` card | 245 | (`view: gamma request ..., cvar reports ...`) to distinguish a rejected |
| 246 | (`[view] fov/vmfov/gamma`). | 246 | command from an OS gamma ramp the compositor ignores. `SDL_SetWindowGammaRamp` |
| 247 | is also interposed (first 12 calls log `gamma: SDL_SetWindowGammaRamp | ||
| 248 | mid=...`) to see whether the engine ever pushes a ramp after the slider | ||
| 249 | moves; if it does and the screen does not change, the compositor is | ||
| 250 | discarding it. Both live in the always-on | ||
| 251 | `Camera / display` card (`[view] fov/vmfov/gamma`). | ||
| 247 | 252 | ||
| 248 | ## Map transitions | 253 | ## Map transitions |
| 249 | 254 | ||
diff --git a/src/gui.cpp b/src/gui.cpp index 88e5521..e8bcac7 100644 --- a/src/gui.cpp +++ b/src/gui.cpp | |||
| @@ -419,8 +419,9 @@ static void build_cards() { | |||
| 419 | "Weapon model field of view (20-120; stock 54).", 20, 120, | 419 | "Weapon model field of view (20-120; stock 54).", 20, 120, |
| 420 | &g_fov_viewmodel); | 420 | &g_fov_viewmodel); |
| 421 | add_slider(view, "Gamma x10", | 421 | add_slider(view, "Gamma x10", |
| 422 | "mat_monitorgamma x10: 16 = 1.6, 30 = 3.0, stock is 22.", 16, 30, | 422 | "mat_monitorgamma x10: 16 = 1.6, 26 = 2.6 (engine max), stock " |
| 423 | &g_gamma); | 423 | "is 22.", |
| 424 | 16, 26, &g_gamma); | ||
| 424 | 425 | ||
| 425 | add_card(2, &g_fullbright, "Fullbright", | 426 | add_card(2, &g_fullbright, "Fullbright", |
| 426 | "Ignore world lighting so dark areas are visible.", true); | 427 | "Ignore world lighting so dark areas are visible.", true); |
| @@ -2240,6 +2241,28 @@ SDL_WarpMouseGlobal(int x, int y) { | |||
| 2240 | real_warp_global(x, y); | 2241 | real_warp_global(x, y); |
| 2241 | } | 2242 | } |
| 2242 | 2243 | ||
| 2244 | // Diagnostic: tell whether mat_monitorgamma reaches the SDL gamma ramp at all. | ||
| 2245 | static int (*real_set_gamma_ramp)(void *, const unsigned short *, | ||
| 2246 | const unsigned short *, | ||
| 2247 | const unsigned short *) = nullptr; | ||
| 2248 | |||
| 2249 | extern "C" __attribute__((visibility("default"))) int | ||
| 2250 | SDL_SetWindowGammaRamp(void *window, const unsigned short *r, | ||
| 2251 | const unsigned short *g, const unsigned short *b) { | ||
| 2252 | if (!real_set_gamma_ramp) | ||
| 2253 | real_set_gamma_ramp = (int (*)(void *, const unsigned short *, | ||
| 2254 | const unsigned short *, | ||
| 2255 | const unsigned short *))dlsym( | ||
| 2256 | RTLD_NEXT, "SDL_SetWindowGammaRamp"); | ||
| 2257 | static int logs = 0; | ||
| 2258 | if (logs < 12) { | ||
| 2259 | logs++; | ||
| 2260 | logf("gamma: SDL_SetWindowGammaRamp mid=%u/%u/%u", r ? r[128] : 0, | ||
| 2261 | g ? g[128] : 0, b ? b[128] : 0); | ||
| 2262 | } | ||
| 2263 | return real_set_gamma_ramp ? real_set_gamma_ramp(window, r, g, b) : -1; | ||
| 2264 | } | ||
| 2265 | |||
| 2243 | static unsigned int (*real_get_rel_mouse)(int *, int *) = nullptr; | 2266 | static unsigned int (*real_get_rel_mouse)(int *, int *) = nullptr; |
| 2244 | static int (*real_poll_event)(void *) = nullptr; | 2267 | static int (*real_poll_event)(void *) = nullptr; |
| 2245 | 2268 | ||
diff --git a/src/hl2h.cpp b/src/hl2h.cpp index f7106cd..1fc7096 100644 --- a/src/hl2h.cpp +++ b/src/hl2h.cpp | |||
| @@ -674,13 +674,18 @@ static void view_settings_apply(void *ent) { | |||
| 674 | last_vm = g_fov_viewmodel; | 674 | last_vm = g_fov_viewmodel; |
| 675 | } | 675 | } |
| 676 | static int last_gamma = 22; | 676 | static int last_gamma = 22; |
| 677 | static int pending_gamma = -1; | ||
| 677 | if (g_gamma != last_gamma) { | 678 | if (g_gamma != last_gamma) { |
| 678 | char cmd[48]; | 679 | char cmd[48]; |
| 679 | snprintf(cmd, sizeof(cmd), "mat_monitorgamma %d.%d", g_gamma / 10, | 680 | snprintf(cmd, sizeof(cmd), "mat_monitorgamma %d.%d", g_gamma / 10, |
| 680 | g_gamma % 10); | 681 | g_gamma % 10); |
| 681 | console_cmd(cmd); | 682 | console_cmd(cmd); |
| 682 | // Read back through ICvar to tell an ignored command from an OS gamma | 683 | pending_gamma = g_gamma; |
| 683 | // ramp that the compositor discards. | 684 | last_gamma = g_gamma; |
| 685 | } | ||
| 686 | if (pending_gamma >= 0) { | ||
| 687 | // ClientCmd is queued, so read the cvar on the next tick to see the value | ||
| 688 | // the engine actually accepted (it clamps mat_monitorgamma at 2.6). | ||
| 684 | float got = -1.0f; | 689 | float got = -1.0f; |
| 685 | if (g_iface.cvar) { | 690 | if (g_iface.cvar) { |
| 686 | using FindFn = void *(*)(void *, const char *); | 691 | using FindFn = void *(*)(void *, const char *); |
| @@ -689,9 +694,9 @@ static void view_settings_apply(void *ent) { | |||
| 689 | if (v) | 694 | if (v) |
| 690 | got = *(float *)((uintptr_t)v + 0x2c); // ConVar m_Value.f | 695 | got = *(float *)((uintptr_t)v + 0x2c); // ConVar m_Value.f |
| 691 | } | 696 | } |
| 692 | logf("view: gamma request %d.%d, cvar reports %.2f", g_gamma / 10, | 697 | logf("view: gamma request %d.%d, cvar reports %.2f", pending_gamma / 10, |
| 693 | g_gamma % 10, got); | 698 | pending_gamma % 10, got); |
| 694 | last_gamma = g_gamma; | 699 | pending_gamma = -1; |
| 695 | } | 700 | } |
| 696 | } | 701 | } |
| 697 | 702 | ||
diff --git a/src/menu.cpp b/src/menu.cpp index ead5f2d..248aa48 100644 --- a/src/menu.cpp +++ b/src/menu.cpp | |||
| @@ -407,7 +407,7 @@ static bool config_load() { | |||
| 407 | } else if (strcmp(key, "gamma") == 0) { | 407 | } else if (strcmp(key, "gamma") == 0) { |
| 408 | dst = &g_gamma; | 408 | dst = &g_gamma; |
| 409 | lo = 16; | 409 | lo = 16; |
| 410 | hi = 30; | 410 | hi = 26; // the engine clamps mat_monitorgamma at 2.6 |
| 411 | stock = 22; | 411 | stock = 22; |
| 412 | } | 412 | } |
| 413 | if (dst) { | 413 | if (dst) { |
