• xtrn/syncivision/lobby.js

    From Rob Swindell (on Debian L@VERT to Git commit to main/sbbs/m on Fri Jul 10 01:39:00 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/39afa04403c14cd01284dc51
    Added Files:
    xtrn/syncivision/lobby.js syncretro.ini
    Log Message:
    syncretro: add the launcher lobby

    One entry replaces one per cartridge. The lobby discovers what is in
    roms/, lists it alphabetically in columns whose count follows the
    terminal's width, and launches the door with the cartridge the player
    picked. Entry numbers are assigned once and never move, so typing 47
    always starts the same game whatever the board says.

    The ROM path is quoted, which is what carries a filename with spaces
    through xtrn.cpp's bare-space argv split -- the same shell path
    `-name %a` already takes on every sibling launch. A name carrying a
    quote or a backslash is refused rather than mangled.

    Missing BIOS is reported here, plainly, instead of leaving the player
    to stare at FreeIntv's own LOAD EXEC FAIL screen.

    Every play is logged when the door returns, whatever its exit status.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian L@VERT to Git commit to main/sbbs/m on Fri Jul 10 01:39:00 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/7ad4fb98b0e400a8dd09039b
    Modified Files:
    xtrn/syncivision/lobby.js syncivision_lib.js test_lobby_headless.js xtrn/syncivision/tests/test_syncivision_lib.js
    Log Message:
    syncivision: guard the loop, reject BIOS by name, quote all paths

    Four fixes from the final whole-branch review of the SyncRetro launcher:

    - lobby.js's picker loop was a bare `for (;;)`. On carrier loss
    console.getkey() returns "" immediately, so the loop busy-reads the
    SMB-shared plays.jsonl until terminate_on_disconnect aborts the
    script. Guard it with `while (!js.terminated && bbs.online)`, the
    same pattern xtrn/syncduke/lobby.js already uses.

    - sv_discover() rejected the BIOS by MD5 only, but LAUNCHER.md sec 6
    promises rejection "by name and by their known MD5s." A
    differently-dumped exec.bin/grom.bin (right size, wrong hash) could
    still show up as a junk cartridge entry. Add SV_BIOS_NAMES and skip
    a file whose lowercased basename is exec.bin or grom.bin.

    - play() said "Rescanning" when the chosen cartridge had vanished, but
    never rescanned, so the dead entry kept its number and kept failing.
    play() now returns whether a rescan is needed; main()'s picker loop
    re-runs sv_discover() and reassigns .num by position in the fresh,
    alphabetically sorted list, keeping the numbering contract intact.

    - The launch command line quoted the ROM path but not SR_BINARY or the
    -home path. Because a quote already routes the line through
    `$SHELL -c`, a space in either path (harmless on /sbbs today, a real
    hazard for "C:\Program Files\..." on the planned Windows port) would
    silently split it into extra shell words. Quote both; -name %a stays
    unquoted since cmdstr() already quotes the alias itself.

    Extends tests/test_syncivision_lib.js with a re-dumped-grom.bin case
    and test_lobby_headless.js with quoting assertions for the binary and
    -home paths (and adds bbs.online to its stub, now required by the
    loop guard).

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

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