https://gitlab.synchro.net/main/sbbs/-/commit/faa2969bcda1e1c9736e7246
Added Files:
src/doors/syncretro/syncretro_quant.c syncretro_quant.h
Modified Files:
src/doors/syncretro/CMakeLists.txt DESIGN.md README.md main.c retro_bridge.c retro_core.c retro_core.h syncretro.h syncretro_config.c syncretro_door.c syncretro_input.c syncretro_io.c
Log Message:
syncretro: fill in M1, the video-only vertical slice
The frontend now loads a core, loads a ROM, renders frames as sixel, maps terminal keys onto a RetroPad, paces on DSR-ACK, and restores the BBS
terminal on every exit path. Audio is accepted and discarded (DESIGN.md
sec 8 defers streaming console PCM to M4; it was never a launch blocker).
Two pieces have no counterpart in the sibling doors, because a libretro
core is not a fixed-format engine:
* syncretro_quant.c -- the frame is truecolor, where DOOM/Duke/1oom all
render into an 8-bit palette, and sixel is a 256-color format. With
256 or fewer distinct colors -- every legacy console -- the palette IS
the frame's colors and the reduction is exact. The palette is built
sorted, so it depends only on the color SET: a frame redrawn from the
same colors yields a byte-identical palette and the sixel color
registers are sent once. Busier frames fall back to a fixed 6x6x6 cube
plus a 40-step gray ramp.
* The frame SIZE is not a compile-time constant and a core may change it
mid-session, so every buffer grows on demand and the image rect is
recomputed on a source-size change, not only on a probe reply.
Input is the interesting part. A RetroPad is a held-state device -- the
core asks "is UP down right now?" every frame -- but a terminal sends
bytes on press and nothing on release. Three paths, negotiated at connect, climbing the same ladder syncduke does for Build's scancode queue: evdev physical key reports on SyncTERM (CTDA cap 8; layout-independent, so WASD
works on AZERTY), the kitty keyboard protocol elsewhere, and an
auto-release timer where neither exists. Whichever mode is negotiated is
undone on exit, as in the sibling doors.
Resolve the core and ROM paths against the launch directory before sr_config_apply() chdir's into the per-user sandbox, and search a roms/ subdirectory for cartridges. Without the absolutize, a relative ROM path
was looked up inside the sandbox and never found; cores also keep the
directory pointers they are handed for the whole session.
Verified end to end against FreeIntv: with no BIOS the core still loads
the cartridge, halts, and draws its own "PUT GROM/EXEC IN SYSTEM
DIRECTORY" screen, which decodes cleanly out of a SYNCRETRO_SIXELOUT
capture -- so the BIOS gates playing a game, not exercising the frontend. Pacing, backpressure, the carrier drop and all three key paths are
covered by a synthetic core and a fake terminal on a socketpair (~/tmp/syncretro_probes). Builds warning-free under gcc and clang.
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net