• src/doors/syncdoom/syncdoom.c src/doors/syncduke/syncduke_io.c src/doo

    From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Sun Jun 28 00:21:32 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/2f2f38f559bd01dc6efc897c
    Modified Files:
    src/doors/syncdoom/syncdoom.c src/doors/syncduke/syncduke_io.c src/doors/termgfx/pace.c pace.h
    Log Message:
    termgfx: share the DSR RTT-sample update between the doors

    Second slice of the present/pace unification. Both doors fold each DSR round-trip
    into a 3/4 RTT EMA, latch rt_high at 40ms, and track a min-RTT baseline, then run
    the AIMD -- the same logic, with two small divergences: SyncDOOM also rejects a stale sample (a late reply for a reclaimed frame, rtt < EMA/3) and re-seeds the baseline after an 8s window; SyncDuke does neither.

    Extract it as termgfx_rtt_sample() parameterized by those two knobs (stale_reject,
    rtt_min_window_ms): Duke passes (0, 0), Doom passes (1, RTT_MIN_WINDOW). The function returns whether the sample was accepted so each door runs the AIMD only
    then. The DSR send-time ring + inflight + the reclaim/gate stay per-door.

    Pure refactor -- proven bit-identical to each door's old inline RTT logic across
    14160 replayed samples (spanning stale/normal/spike RTT and the 8s window), 0 mismatches. Adds a rtt_min_at to SyncDuke (written by the helper, unused there since its window is 0).

    Co-Authored-By: Claude Opus 4.8 <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 Wed Jul 22 20:38:40 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/c97cc290d65f8acac11c2964
    Modified Files:
    src/doors/syncdoom/syncdoom.c src/doors/syncduke/syncduke_io.c src/doors/syncmoo1/syncmoo1_io.c
    Log Message:
    syncduke/syncdoom/syncmoo1: subset the full-frame palette off SyncTERM

    These three doors have no dirty path, but their non-SyncTERM full
    frames were re-sending all 256 registers every changed frame. Select SIXEL_PAL_USED there so a frame carries only its used colors; SyncTERM
    keeps FULL-on-change / NONE-reuse (byte-identical). All three feed a
    fixed indexed palette, so the subset is a clean win.

    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 Windows 11)@VERT to Git commit to main/sbbs/master on Sun Jul 26 22:48:31 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/18ccff2087bc6bba561d2433
    Modified Files:
    src/doors/syncdoom/syncdoom.c src/doors/syncduke/syncduke_io.c src/doors/syncretro/syncretro_io.c src/doors/termgfx/stats.c stats.h src/doors/termgfx/test/test_stats.c
    Log Message:
    termgfx: the Ctrl-S strip has to fit the row it is drawn on

    Spelling the turn-key model out -- " kitty/nat" became " kitty turn=nat"
    in 6b95aa66c0 (2026-07-26) -- cost five columns on a strip that was
    already within a few of the margin. SyncDuke's row measures 81 columns in
    the sixel-full tier, 82 in JXL with the inline-blob and upscale fields,
    and 84 on the widest text tier, against an 80-column SyncTERM. What the
    player sees depends on the terminal: the tail lost to the margin, or the overflow wrapped onto the last row of the game view and everything
    scrolled up a line.

    Two changes buy the width back and one keeps it bought.

    The shared head spells the pipeline depth "d3/auto" rather than
    "depth 3/auto", which is what termgfx_termio's row and SyncConquer's have always called it -- the same field read two ways depending on which door
    was open. That is five columns, and dropping the trailing space each door appended is a sixth: the strip ends in an erase-to-end-of-line that paints
    the rest of the row in the bar's own colors, so the space was never
    visible. Duke's three rows come to 75, 76 and 78.

    termgfx_stats_clip() is the part that keeps it. Clamping each number, which
    is all stats.c did, bounds no total -- fields accumulate, and this row overflowed by gaining one more of them. Every door now clips the assembled strip to its own column count as the last step before painting. The cut
    lands on a field boundary so a survivor is never a half-printed value, and
    a width not yet probed (cols <= 0) leaves the strip alone.

    SyncDOOM's and SyncRetro's rows change with the head; both were inside the margin already. The stderr stats line SyncDuke logs keeps "depth" -- a log
    is grepped and plotted, and costs no columns.

    test_stats asserts the two widths a door can actually reach -- the widest
    tier name, and JXL where the blob and upscale fields appear -- fit 80, and covers the clip's boundary cut and its untouched cases.

    Built and tested under MSVC only; not yet compiled under GCC/Clang.
    Uncrustify was unavailable on this machine, so the new code was written to
    the house style by hand.

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

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