summaryrefslogtreecommitdiffstats
path: root/CONTEXT.md
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-11-04 00:16:09 +0100
committersalmonik <salmonik@tuta.io>2026-11-04 00:16:09 +0100
commit4f384f94504a2027febc8b5cc3e2b3e3034c0b23 (patch)
tree68491e9e1accbfc822e46187312d1d57a7fb66ed /CONTEXT.md
parentSkybox image: upload via procedural texture, not CreateTextureFromBits (diff)
downloadhl2h-4f384f94504a2027febc8b5cc3e2b3e3034c0b23.tar.gz
hl2h-4f384f94504a2027febc8b5cc3e2b3e3034c0b23.zip
Skybox image: decode PNG ourselves to avoid symbol interposition
client.so, engine.so and vguimatsurface.so all export their own png_create_read_struct. Loading the system libpng16 made its internal calls bind to the game's older libpng, whose png_struct layout differs, so png_safe_warning read a NULL error_ptr and crashed. Replace libpng with a small PNG reader: zlib's uncompress (dlopen'ed) plus the five PNG row filters, supporting 8-bit non-interlaced RGB/RGBA/gray/palette images with tRNS alpha for palettes. Output verified byte-identical to libpng for the skybox.png in use.
Diffstat (limited to 'CONTEXT.md')
-rw-r--r--CONTEXT.md15
1 files changed, 10 insertions, 5 deletions
diff --git a/CONTEXT.md b/CONTEXT.md
index 669c1fb..5bd0436 100644
--- a/CONTEXT.md
+++ b/CONTEXT.md
@@ -363,11 +363,16 @@ vocabulary / decisions.
363- Replaces the map skybox with `<config dir>/skybox.png` (same directory as 363- Replaces the map skybox with `<config dir>/skybox.png` (same directory as
364 the INI). Not `sv_skyname`: that did not take effect at runtime in this 364 the INI). Not `sv_skyname`: that did not take effect at runtime in this
365 build, so the skybox card now works on materials instead. 365 build, so the skybox card now works on materials instead.
366- PNG is decoded with libpng16's simplified API (`dlopen`ed, no link 366- The PNG is decoded by our own reader (`zlib`'s `uncompress` + PNG filters;
367 dependency). This build's `IMaterialSystem` interface ends at 367 8-bit non-interlaced RGB/RGBA/gray/palette). Do **not** use the system
368 `GetDisplayDeviceName` (the slots after it belong to `CMaterialSystem` 368 libpng: `client.so`, `engine.so` and `vguimatsurface.so` each export their
369 itself), so there is **no `CreateTextureFromBits`**. The pixels are uploaded 369 own `png_create_read_struct`, so libpng16's internal PLT calls bind to the
370 through `CreateProceduralTexture` (vtable 81) + an `ITextureRegenerator` 370 game's older libpng with a different `png_struct` layout and crash in
371 `png_safe_warning` (error_ptr at +0xb0 reads NULL).
372- This build's `IMaterialSystem` interface ends at `GetDisplayDeviceName`
373 (the slots after it belong to `CMaterialSystem` itself), so there is **no
374 `CreateTextureFromBits`**. The pixels are uploaded through
375 `CreateProceduralTexture` (vtable 81) + an `ITextureRegenerator`
371 (`SetTextureRegenerator` 12, `Download` 13), which fills mip 0 through 376 (`SetTextureRegenerator` 12, `Download` 13), which fills mip 0 through
372 `IVTFTexture::ImageData(frame,face,mip)` (39). `IVTFTexture`'s virtual 377 `IVTFTexture::ImageData(frame,face,mip)` (39). `IVTFTexture`'s virtual
373 destructor occupies two slots, so Width=15, Height=16, RowSizeInBytes=19. 378 destructor occupies two slots, so Width=15, Height=16, RowSizeInBytes=19.