• src/doors/syncretro/build.bat deploy.js syncretro_plat.c syncretro_pla

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Fri Jul 10 23:41:57 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/2d7d803ba1fe4cd34013646a
    Added Files:
    src/doors/syncretro/build.bat deploy.js syncretro_plat.c syncretro_plat.h xtrn/syncivision/.gitignore getcore.js install-xtrn.ini
    Modified Files:
    docs/v322_new.md src/doors/syncretro/.gitignore CLAUDE.md CMakeLists.txt DESIGN.md LAUNCHER.md README.md build.sh main.c retro_core.c syncretro_config.c syncretro_door.c syncretro_input.c syncretro_io.c xtrn/syncivision/lobby.js syncivision_lib.js xtrn/syncivision/tests/test_syncivision_lib.js
    Removed Files:
    src/doors/syncretro/deploy.sh
    Log Message:
    syncretro: build on Windows (MSVC, Win32), and per-platform install

    Add the Windows half of the SyncRetro build, in the spirit of the sibling
    doors (syncdoom/syncduke/syncconquer/syncmoo1). Win32 (x86) is the one supported Windows target: one Win32 binary runs on both a Win32 and a
    Win64 Synchronet host (the DOOR32.SYS handle is 32-bit-significant and
    crosses the process-bitness boundary), and a Win32 door loads a Win32
    core .dll.

    All of the door's Windows-vs-POSIX difference is confined to two files:

    - syncretro_plat.c/.h -- the whole clock / sleep / non-blocking-socket
    / console-less-stderr seam over xpdev. sockwrap.h normalizes
    WSAGetLastError() onto the POSIX errno values so ONE classify()
    covers both platforms; io.c, input.c, door.c and main.c lose their
    direct read/write/fcntl/clock_gettime/signal calls and carry no
    #ifdef. door.c/config.c move onto xpdev stricmp()/FULLPATH()/fexist()
    (MSVC has no strcasecmp/realpath/access). main.c's frame pacer, which
    used clock_nanosleep(TIMER_ABSTIME), is reframed into a monotonic-
    microsecond deadline plus a millisecond sleep.
    - retro_core.c -- the core-load seam, dlopen/dlsym/dlclose vs
    LoadLibrary/GetProcAddress/FreeLibrary. NOT routed through xpdev's
    xp_dlopen(), which mangles the name and can't load a core by the
    explicit path we hand it; the shim loads the path verbatim.

    CMakeLists.txt gains an MSVC branch (ws2_32, CRT quiets, /Zi+/MAP crash symbolication, static libjxl from an x86-windows-static-md vcpkg prefix); build.bat mirrors the sibling doors.

    Install layer (xtrn/syncivision): the binary and libretro core now live
    where the lobby looks for them per platform, so one shared install (a BBS spanning a Linux box and a Windows host on the same mount) serves several
    hosts without their same-named binaries colliding -- FLAT at the door
    root on Windows (.exe/.dll never collide with a *nix host's names), or in
    an <os>-<arch> sub-dir on *nix (linux-x64, ...), falling back to the flat
    dir for the legacy symlink-deploy layout. lobby.js, deploy.js and
    getcore.js derive that location from one sv_target() so they agree. deploy.sh/deploy.bat are replaced by deploy.js (a jsexec script, so it
    shares the token code and can't drift from the lobby). getcore.js
    downloads the FreeIntv core (GPLv2+) from the libretro buildbot, local-
    first. install-xtrn.ini registers the lobby, which passes EX_NODISPLAY to bbs.exec() to hide the door's console (diagnostics captured to data/syncretro/syncretro_n<node>.log).

    Verified on Windows (VS2022, Win32/Release via build.bat): clean build,
    4/4 C unit tests pass, and an end-to-end capture-mode run loads a real
    Win32 FreeIntv core, decodes a ROM, and renders a sixel frame. The shared
    .c files changed for both platforms but were compiled under MSVC only --
    not yet GCC/Clang.

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

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