https://gitlab.synchro.net/main/sbbs/-/commit/d6ab9c05fab10fa46155986f
Modified Files:
src/doors/syncmoo1/syncmoo1_io.c
Log Message:
syncmoo1: drain paced-frame acks before the sixel vscale probe
On xterm (and any terminal that draws a sixel at its encoded size rather
than honoring the raster pan), the picture intermittently rendered at
half height and the in-game mouse cursor tracked at twice the vertical
rate -- the game's idea of the pointer drifted from the hardware cursor.
Both symptoms were one cause: a wrong vertical-scaling verdict. The probe paints two thin slivers (pan=1, then pan=2), each bracketed by a cursor- position report, and infers "scales" when the pan=2 sliver advanced the
cursor further than the pan=1 one. The three reports must be the probe's
own [home, after-pan1, after-pan2].
But sm_io_vscale_probe() fires from present(), AFTER the first few frames
have already gone out and been paced -- and each paced frame is acked by a cursor report of its own. When a frame's ack was still in flight as the
probe armed, sm_input_vscale_collect() claimed that straggling pace-ack as
the probe's `home`, shifting the window by one: the true [1,3,5] (equal
two-row advances -- xterm ignores pan) was read as [1,1,3] and looked like
it had scaled. The door then sent a half-height pan=2 encode to a terminal
that draws at the encoded size, and sm_map_mouse() -- which assumes the
image fills the full fitted height -- put the cursor at 2x the Y rate. The
race made it intermittent: whether a leftover ack landed inside the three- report window depended on timing.
Fix: quiesce the pace pipeline before arming. Wait for every outstanding present()-sent DSR to be acked (draining routes those reports to sm_io_pace_ack(), since the collector is not yet armed), so the probe's
own three reports are the only cursor reports in flight once it arms. The synchronous probe that follows blocks further presents, so no new DSR can appear before the verdict. Bounded by the probe's existing grace; a silent terminal just proceeds to the safe full-size fallback.
This restores the invariant the sibling doors already hold a different way
-- SyncDOOM and SyncDuke run the probe before the first frame (SyncDuke
holds frame one for it; SyncDOOM reads its own accumulator with nothing in flight), so a stray report is inert there. syncmoo1 paints early frames,
so it drains instead. Verified on xterm -ti vt340: the probe now collects
a clean [1,3,5], the verdict is "does not scale", and frames stay pan=1 at
full height with the cursor aligned.
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net