• src/doors/termgfx/test/test_termgfx_termio_palfade.csrc/doors/termgfx/

    From Rob Swindell (on Debian Linux)@1:103/705 to Git commit to main/sbbs/master on Sat Jul 25 23:10:02 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/f7b071a67065b38a52c9d738
    Added Files:
    src/doors/termgfx/test/test_termgfx_termio_palfade.c
    Modified Files:
    src/doors/termgfx/termgfx_termio.c src/doors/termgfx/test/unit_termgfx_termio.sh
    Log Message:
    termgfx: patch a palette change instead of repainting the frame

    Any change to the palette forced a whole frame on both tiers. The reasons
    were real: JXL bakes the palette into each frame's RGB pixels, so a fade
    moves every affected pixel's colour while leaving the INDEX buffer the
    diff looks at completely unchanged; and sixel colour registers are shared
    with what is already drawn, so redefining one recolours the screen under
    the parts a patch would not repaint.

    Both are about the same thing -- which pixels a moved palette entry
    actually affects -- and that is computable. Record WHICH entries moved,
    and let the tile diff treat a tile drawn with one of them as dirty even
    when its indices are identical. The gate then has nothing left to protect
    and both tiers drop it.

    What remains is telling the terminal. A SyncTERM box carries no palette by design (its registers persist) and all 256 would dwarf a small box, so the first box of such a frame carries exactly the entries that moved. Every
    other terminal resets registers per image and its used-colour subset
    already covers this; the JXL tier carries RGB pixels and needs nothing.

    Measured on a played Flight of the Amazon Queen session over Windows
    Terminal, this was the whole of what was left: 267 frames repainting for
    this reason, carrying 52.9MB of the session's 68.6MB -- 77% of every byte
    sent, after the bottom-strand fix had already halved the total.

    The new test pins the case only this can catch: a PURE fade, where not one index changes and only what an index means moves. It is deliberately local
    -- a flat background with the moving colour confined to one block -- since
    a colour spread across every tile legitimately dirties the whole frame and would prove nothing.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)