• src/doors/termgfx/termgfx_termio.c

    From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Wednesday, July 22, 2026 20:38:40
    https://gitlab.synchro.net/main/sbbs/-/commit/a69d062a745f0a2ea36b379f
    Modified Files:
    src/doors/termgfx/termgfx_termio.c
    Log Message:
    termgfx present_rgbx: subset the per-frame palette on all terminals

    present_rgbx re-quantizes and re-sends its palette every frame and has
    no dirty-box path, so nothing relies on persisted registers -- making SIXEL_PAL_USED safe on every terminal here, SyncTERM included. Each
    truecolor frame now defines only the registers its quantized image
    uses. Used by SyncRPG.

    Co-Authored-By: Claude Opus 4.8 (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 Thursday, July 23, 2026 02:18:02
    https://gitlab.synchro.net/main/sbbs/-/commit/c6d429e9400c9239371468c4
    Modified Files:
    src/doors/termgfx/termgfx_termio.c
    Log Message:
    termgfx: honor the BBS session time limit

    termio read DOOR32.SYS for its socket and DISCARDED line 9, the caller's minutes left. A door driven through it therefore ran until the player quit,
    and the BBS reclaimed the node only when the session itself ended -- every sibling door has honored this for a long time; syncscumm and syncrpg never have.

    The limit now comes from the drop file, or from an explicit -t<seconds> (Synchronet's %T) which overrides it, exactly as the siblings resolve it. -t
    is matched on an all-digit suffix and marked consumed, so it never reaches
    the engine's argv and an engine word option starting with -t passes through untouched.

    Over the last minute the remaining time appears on the shared notice row,
    then the session ends by setting g_quit -- the same clean unwind an idle timeout uses, so the engine saves whatever it saves rather than being killed mid-write.

    Two things about that notice are deliberate. It runs from the pump, not the present path, for the reason the idle poll does: this door presents only
    when the engine's dirty flag says the frame changed, so a countdown driven
    by frames would stall on a static screen. And it runs AFTER the idle poll,
    so when both want the row this one wins -- the idle countdown can be
    dismissed by pressing a key, this one cannot, and offering "press any key" against a limit no key will move would be a lie.

    Verified offline: -t fires to the millisecond, a DOOR32.SYS granting one
    minute exits at 60.0s (the field that was previously thrown away), -t
    overrides that drop file, and a session with no limit at all never fires.

    Co-Authored-By: Claude Opus 4.8 (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 Saturday, July 25, 2026 23:10:02
    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