• exec/load/door_deploy.js src/doors/syncretro/syncretro_io.c src/doors/

    From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Sun Jul 12 05:11:38 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/f98e9fb9909bbee7a516aec9
    Modified Files:
    exec/load/door_deploy.js src/doors/syncretro/syncretro_io.c src/doors/termgfx/geometry.c geometry.h
    Log Message:
    syncretro: erase the stale first frame, center against the real canvas

    Two separate defects, both visible in Windows Terminal as a grey slab down
    the left of the picture and an image that is not quite centered.

    THE GREY SLAB is a stale frame. The door assumes an 80x25 terminal until the probe replies come back, and a reply costs a network round-trip -- so it was painting frames during that window, then re-fitting to the real canvas and drawing a bigger image at a different column. A sixel is PIXELS, not cells: nothing about drawing the new image erases the old one, so whatever the first image painted outside the new one's rect stayed on screen for the whole session. It is grey because it is the console's power-on frame, which is what the core was still showing when those frames went out.

    The clearing repaint already existed (a forced repaint emits ESC[2J ahead of the frame). sr_io_set_aspect() called it; sr_io_set_canvas() and sr_io_set_grid() -- the two that fire on EVERY session -- did not. Move the invalidate into sr_io_recompute_geom(), where the rect is actually decided
    and no caller can forget it, and hold the first frame until the grid reply lands (or 400 ms passes, for a terminal that never answers) so there is no wrong-sized flash to erase in the first place.

    THE OFF-CENTERING is an integer truncation. A cell is canvas/grid, and 1648
    px over 164 columns is 10.05, not 10. The page was then derived as cols *
    cell -- up to `cols` pixels NARROWER THAN THE SCREEN, ~100 px on a wide terminal -- and centering inside a short page lands the image half that error to the left. On a display at 125%/150% scaling the fraction is bigger still, which is why this showed up on Windows Terminal and not here.

    Keep the cell fractional (termgfx_geom_center_ex, with the old int entry
    point kept as a wrapper so the sibling doors are bit-identical), center
    against the true canvas, and quantize once at the end, where the text cursor genuinely forces a whole cell. Residual error is now under half a cell.

    SyncTERM is deliberately excluded from that: it never answers the ESC[14t canvas probe, so its canvas is our GUESS, and centering against a guess is
    how syncmoo1's image used to land on the last row. When the canvas is not
    known the geometry keeps deriving the page from the grid, which IS real, and comes out exactly as before.

    The door now logs the geometry it settled on, which is what this needed and
    did not have: the terminal's canvas, grid, fractional cell, page, image size and cell origin, in one line.

    The same two defects are latent in syncmoo1, syncdoom, syncduke and syncconquer; they are untouched here.

    deploy.js: a running door cannot be overwritten (ETXTBSY), which on a live
    BBS is the normal case rather than an edge one. Report it as what it is and change nothing. Do NOT reach for the package-manager trick of copying
    alongside and renaming over the top: the door dir is reached over an SMB
    mount, where rename() onto a file another process is executing deletes the target and THEN fails, leaving a deleted-but-still-open phantom where the
    door binary was.

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