https://gitlab.synchro.net/main/sbbs/-/commit/d93658bb86ce6e576031a4d9
Modified Files:
docs/door_graphics_audio_matrix.md src/doors/syncdoom/syncdoom.c src/doors/syncduke/syncduke.h syncduke_input.c syncduke_io.c src/doors/termgfx/README.md apc.c apc.h caps.h geometry.c geometry.h
Log Message:
doors: let the terminal do the 2x upscale (graphics-APC ZX/ZY)
SyncDuke and SyncDOOM both render 320x200 natively -- doomgeneric pixel- doubles Doom's 320x200 render into its 640x400 framebuffer -- and then
upscaled the frame door-side before encoding it. CTerm 1.332 added integer ZX/ZY zoom factors to the graphics APC (SourceForge syncterm feature-request #136), so the door can ship the NATIVE frame and let the terminal replicate
the pixels instead. The picture is identical -- every upscale in that chain
was already nearest-neighbor -- and a 2x frame costs ~2.4-2.8x the bytes to encode at any quality setting, so this is the ~60% bandwidth reduction the request was filed for, at no cost in quality.
termgfx_geom_zoom() decides whether the terminal can do it: only when the fitted size is an EXACT integer multiple of the source. SyncTERM has no resampler -- its only scaling anywhere, sixel raster attributes included, is whole-pixel replication -- so any other fit still gets the door-side resample it always had. In practice that means every standard 80-column canvas whose
fit lands on 640x400 (80x25, 80x50, 80x30/80x60 letterboxed, 132-col letterboxed) gets ZX=2;ZY=2, while an awkward canvas height (640x384 with the status line left on, 640x392, EGA 640x350) falls back. The factor is always
2x: a 4x fit would need a 1280-wide canvas and SyncTERM's widest is 1056.
termgfx_apc_image_zoom() emits ZX/ZY among the APC options, and omits them at 1x, so termgfx_apc_image() is now a wrapper around it and the doors NOT
touched here (SyncConquer) emit byte-identical output -- verified by memcmp, not by eye. Gated on TERMGFX_CTERM_VER_ZOOM (1332): against an older SyncTERM every door emits exactly what it did before.
The Ctrl-S stats strip grows an "x2" token next to "blob" whenever the
terminal is actually doing the upscale, because otherwise there is no way to tell from a live session which side performed it. It reports the zoom SENT per frame, not the capability, so it cannot lie about the gate.
Also documents client-side scaling properly in the door matrix, which never covered it. The sixel raster attribute (pan;pad) is the older mechanism and support fragments three ways: SyncTERM scales BOTH axes (reading pan/pad as integer scales -- a cterm extension), foot/Contour/Windows Terminal honor only the vertical DEC pixel aspect, and xterm/WezTerm render at the encoded size. That is why the doors send pan=2 broadly but pad=2 only to SyncTERM. The SyncDuke comment claiming pan=2 is "a portable DEC 2:1 aspect every sixel terminal honors" was wrong and is corrected; Windows Terminal is added to the termgfx compat matrix.
Two traps worth knowing, both now written down: keeping the client's status line forfeits the ZX/ZY optimization entirely (640x384 is not a multiple of 200), which is a load-bearing reason for the doors to hide it rather than a cosmetic one; and the full-res sixel tier is a STICKY per-user preference that the F4 cycle persists, so a one-off test cycle silently becomes the next session's starting tier -- and a full-res encode never exercises the pan=2
path on any client, which is how the vertical-scaling question stayed
unsettled for so long.
Builds clean under GCC (zero warnings in the touched files). NOT live-tested: it needs a SyncTERM built with the 1.332 APC zoom support.
--- SBBSecho 3.37-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)