sigil-os 585a58e ships three cc0 modules that close the Mode 1 SRDX loop for 4-player arcade: proc_super.sg (browser process supervisor with crash detection and auto-restart), srdx_input.sg (remote controller input routing — viewer Pi sends button state to host), and srdx_relay_bcast.sg (N-viewer broadcast relay, up to 15 viewers, encode-once/send-all). Together they enable four players on separate Pis to play TMNT, Simpsons, X-Men arcade — each viewer's frame is broadcast from one encode, and each viewer's controller input flows back to the host.
Section 1: proc_super.sg — browser process supervisor
cap_spawn + 16-slot process table
0x800000. Each slot: pid:i32 + tab_id:i32 + alive:i32 (12B/slot).cap_spawn(cap, 0, 0) (syscall 54) to spawn a renderer process; records returned PID in the slot for tab_id.tab_id, calls cap_kill(pid), zeroes the slot.proc_alive polling + auto-restart
cap_proc_status(pid) (syscall 55); returns 1 if alive, 0 if dead.alive=1: calls proc_alive(pid). If dead: logs the crash, increments restart counter, calls proc_super_spawn(tab_id, tab_cap[tab_id]) to restart. If the restart counter for a tab exceeds 3, the tab is marked as failed (no further restart attempts). T1-T6 QEMU PASS: init, spawn, kill, crash-detect, restart, no-restart-after-3.Section 2: srdx_input.sg — remote controller input routing
Wire format: 4B LE u32 button bitmask
buttons bitmask to the SRDX connection conn via srdx_wire_raw_send. The bitmask is masked to 15 valid bits (matches the sigilOS normalized gamepad ABI — same as local sys3(44, port, 0, 0) output).conn; returns the masked u32.srdx_input_recv_all + P2/P3/P4 routing
n viewer connections per frame. For each active connection i (0-indexed), reads the 4-byte input bitmask and stores in inputs[i]. The first viewer (i=0) maps to P2; second (i=1) to P3; third (i=2) to P4. The host P1 remains the local controller. Up to 15 viewers → up to 15 remote players (the broadcast relay supports up to 15 simultaneous viewers).Section 3: srdx_relay_bcast.sg — N-viewer broadcast relay
BCAST_BASE=0xA60000: 15-viewer table
BCAST_BASE (each slot: conn:i32 + active:i32 = 8B); stores conn, marks active.conn.srdx_relay_broadcast — encode-once, send-all
srdx_encode_frame(fb, pitch, fw, fh) once to produce the encoded frame + header. Then walks the 15-viewer table: for each active viewer slot, calls srdx_wire_raw_send(conn, hdr, enc_len). Encode overhead is fixed regardless of viewer count — 1 encode per frame, not N. This is the efficiency property: 15 viewers = same CPU cost as 1 viewer for the encode step.srdx_relay_recv_inputs + srdx_bcast_tick
srdx_input_recv(conn) for all active viewer connections; fills inputs[0..n-1] (P2=viewer 0, P3=viewer 1, P4=viewer 2).srdx_relay_broadcast (encode+send) then srdx_relay_recv_inputs (collect P2/P3/P4 inputs). One call per frame from the arcade emulator main loop.Section 4: 4-player arcade — TMNT / Simpsons / X-Men
What this closes: CPS-1/2 and MAME arcade cores that support 4-player co-op (TMNT, Simpsons, X-Men, Captain Commando, The Punisher) can now run across a LAN with one host Pi and up to 3 viewer Pis. The host runs the emulator core + SRDX relay broadcaster. Each viewer Pi runs the SRDX viewer (viewer.sg IS_SCENE), renders the broadcast frame, and sends its controller input back via srdx_input_send. srdx_bcast_tick gives the host one call per frame that handles everything: encode, broadcast to all viewers, collect P2/P3/P4 inputs.
Frame flow:
- Host: emulator core renders frame →
srdx_bcast_tick(fb,...)→ SRDX encode (once) → broadcast to all active viewers → P2/P3/P4 inputs collected - Each viewer Pi: receives SRDX frame →
srdx_decode_inline→ Lumen chrome composite → display; sends button state back viasrdx_input_send