Subj : src/doors/syncretro/syncretro_io.c test_dirty.c To : Git commit to main/sbbs/master From : Rob Swindell (on Debian Linux) Date : Fri Aug 07 2026 01:29:30 https://gitlab.synchro.net/main/sbbs/-/commit/e2a4cacb378a4313c37f70d6 Modified Files: src/doors/syncretro/syncretro_io.c test_dirty.c Log Message: syncretro: size every patch in whole sixel bands, not just whole cells A dirty-rect patch was sized in whole text cells, which is what the cursor address in front of it needs. It is not what the decoder behind it needs. A sixel is read six pixel rows at a time, and SyncTERM's 8x16 cell makes patches 16, 32 and 80 rows tall -- none of them a whole number of bands, so every patch ended in a partial one. cterm did not clear its band mask between bands until d65cb83886 (2026-06-28). Below that, any column of a partial final band not covered by the band's first colour keeps the PREVIOUS band's pixels, and the band is blitted full height regardless. Each patch therefore left a stale sliver at its foot, which a sprite moving across the screen smears into a dotted trail behind it. SourceForge #258; reported against SyncArcade as GitLab #1214 once b3caee6dd4 (2026-08-04) made patches land where they were addressed and the trail became visible. Only SyncTERM was exposed. Every other terminal already took the band_align path, which snaps a rect to LCM(cell, 6) and so has always emitted whole bands; SyncTERM was passed band_align=0 on the reasoning that a cell-anchored patch is enough. Cell alignment is not band alignment, and 16 is not a multiple of 6. So band_align now applies to every sixel client. The height rounding in the geometry routine moves with it: it kept the image an exact multiple of the cell height precisely so band_align's hcell clamp could never strand a sub-cell remainder, and it was gated on the same condition. Splitting the two would trade a stale sliver under each patch for a stale strip along the bottom of the frame. Measured over a 14-second capture against a 1.327 peer: 51 of 53 sixels had a partial final band before, none after; patch heights go 16/32/80 -> 48/96, and the wire grows 26559 -> 27267 bytes, 2.7%. The added rows are unchanged background and cost almost nothing once run-length encoded. test_dirty pins the property the terminals actually depend on -- a rect height divisible by six -- across cell heights 16, 8, 13, 7, 6 and 5, rather than the LCM of one particular cell. Reported by Keyop. Co-Authored-By: Claude Opus 5 (1M context) --- SBBSecho 3.37-Linux * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705) .