• src/doors/termgfx/termgfx_termio.c

    From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Sat Jul 25 23:10:02 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/980c0f8d21669d2627dd41cd
    Modified Files:
    src/doors/termgfx/termgfx_termio.c
    Log Message:
    termgfx: say WHY a dirty pass gave up, not just that it did

    termgfx_diff_coalesce() returns 0 for three unrelated reasons -- nothing changed, too much changed, or the change is too scattered to describe --
    and the trace reported all of them as "nothing". Only the first is waste:
    past TERMGFX_FALLBACK_PCT a repaint really is cheaper than patching most
    of the screen, and a scattered change really is cheaper sent whole.

    That distinction is not academic. Read as "nothing", the second case looks exactly like a bug worth chasing: letting Flight of the Amazon Queen play
    its opening sequence, 720 frames repainted under that label, and the
    obvious reading was that a quarter of the session was being thrown away. Measuring the tile diff over the same sequence offline says otherwise --
    65% of its frame pairs change more than half the tiles, against a 45% threshold. It is a full-motion cutscene. Those repaints are correct, and
    the only thing wrong was the label.

    Name them separately: nothing / toobig / frag, alongside the existing
    strand. The reason now comes from where the decision is made rather than
    being inferred from a return value at the call site, so a caller can no
    longer overwrite a specific answer with a vague one.

    NOTE for the commit before this one, which cannot be amended: it justifies itself with "645 of 2347 frames -- 27% -- repainted with the diff
    reporting nothing dirty at all". That number is this mislabelling and
    should be read as frames the diff declined to patch for ANY reason,
    mostly toobig. The change it describes is still right -- a palette move
    that touches no displayed pixel should not repaint, and the test pins it directly -- but the opening sequence is not the evidence for it.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Sun Jul 26 22:57:46 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/653e414fd1364d2f24e3fcb6
    Modified Files:
    src/doors/termgfx/termgfx_termio.c
    Log Message:
    termgfx: stop reporting the dirty-rect share as unavailable on SyncTERM

    The Ctrl-S strip showed "dr n/a" for every SyncTERM session, on every
    tier, while patching was in fact running -- so the one number that says
    whether the door is patching or repainting has never been readable on the client most callers use.

    The readout was keyed on the terminal having REPORTED a pixel cell size (ESC[16t). SyncTERM never reports one: CTerm implements no xterm window
    ops and uses CSI t as a private palette command, so the query fails its parameter-count check and is dropped. The patch path does not need that
    value in any case -- the diff runs on a fixed tile grid in framebuffer
    space, and placement derives its cell from canvas over grid -- so the
    condition described a dependency that does not exist.

    Measured against a SyncTERM-alike answering the grid CPR but no window
    ops: the strip now reads "dr 100%" where it read "dr n/a", with partial
    frames on the wire the whole time. A terminal that does report a cell
    size is unaffected.

    SyncRetro keeps its own version of this check: it derives the cell size
    itself, so the state is reachable there for a genuinely unknown geometry.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Sun Aug 9 23:03:12 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/e6742dcb3a7878ae2abfaedb
    Modified Files:
    src/doors/termgfx/termgfx_termio.c
    Log Message:
    termgfx: resolve a pending lone ESC after the read, not before

    termgfx_termio_pump() already drained the client each pump, so a sequence
    split by the 256-byte read buffer completed in the same pump and the lone-ESC timer never saw it. What it could still see was a sequence split across pumps: the ESC read while the socket was empty, its tail arriving afterwards, the
    next pump more than TERMGFX_ESC_TIMEOUT_MS later. The check ran first, so that tail was decoded as ordinary keys behind an Escape the client never sent.

    Move the check below the loop and leave the loop by break rather than return, so only the "nothing left to read" exit reaches it. The hard-error and EOF exits still return -- the peer is gone and an Escape would go nowhere.

    Behavior for a genuinely lone Escape is unchanged, which matters: SyncTERM sends a bare 0x1b for that key, and the doors on this path are driven from its menus. Affects SyncRPG, SyncSCUMM and SyncRetro.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net