• src/conio/cterm.c cterm.h

    From Deuc¿@VERT to Git commit to main/sbbs/m on Monday, March 16, 2026 12:27:00
    https://gitlab.synchro.net/main/sbbs/-/commit/8b1196b593bc5fb0d78a80c7
    Modified Files:
    src/conio/cterm.c cterm.h src/syncterm/ripper.c term.c
    Log Message:
    Preserve per-entry palette override across cterm_reset()

    Custom palettes configured per BBS entry were lost when the remote
    triggered a terminal reset (ESC c), because cterm_reset() unconditionally restored dac_default.

    Store the override palette in the cterm struct so cterm_reset() can
    reapply it after resetting defaults. Also preserve it through RIP's reinit_screen() which destroys and recreates the cterm.

    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Thursday, March 19, 2026 10:20:00
    https://gitlab.synchro.net/main/sbbs/-/commit/6160b43cb83228a4ef3d6d2a
    Modified Files:
    src/conio/cterm.c cterm.h cterm_test.c
    Log Message:
    Fix REP (CSI b) across packet boundaries, add 55 ANSI unit tests

    Move lastch from cterm_write local variable to cterm->lastch in the
    cterminal struct so REP works when the character and the CSI b sequence
    arrive in separate cterm_write calls (e.g., split across TCP packets). Previously REP would silently do nothing if the data was split.

    Add 55 ANSI-BBS tests to cterm_test (177 total): C0 controls (NUL, BS,
    HT, LF, CR, NEL, HTS, RI, RIS), cursor movement (CUU/CUD/CUF/CUB/ CNL/CPL/CUP/HVP/CHA/VPA/HPA/HPR/VPR/HPB/VPB + clamping), erase ops (ED/EL/ICH/DCH/IL/DL/ECH), SGR (reset/bold/blink/negative/fg/bg),
    margins (DECSTBM/DECSLRM), scrolling (SU/SD), modes (autowrap/nowrap/
    origin), DEC rectangular ops (DECERA/DECFRA/DECCRA), REP with split
    regression test, and save/restore cursor (SCOSC/SCORC/DECSC/DECRC).

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Sunday, April 12, 2026 19:48:00
    https://gitlab.synchro.net/main/sbbs/-/commit/60fdba3a9f61d2345c760ab1
    Modified Files:
    src/conio/cterm.c cterm.h
    Log Message:
    Add function to detect where CR would go

    Important for RIP to be able to accurately detect if it's at the
    "beginning of a line" for ! parsing to work the same as RIPterm.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Sunday, April 19, 2026 21:36:00
    https://gitlab.synchro.net/main/sbbs/-/commit/89a19762259cd61a220a6f65
    Modified Files:
    src/conio/cterm.c cterm.h cterm_dec.c cterm_ecma48.c cterm_test.c src/sbbs3/syncview/syncview.c src/sbbs3/umonitor/spyon.c src/syncterm/HACKING.md ooii.c term.c src/xpdoor/xpdoor.c
    Log Message:
    cterm: drop vestigial retbuf/retsize from cterm_write + apc_handler

    cterm_write's retbuf/retsize parameters predated the response_cb callback. Every caller passed NULL, 0. Remove them, simplify cterm_respond to drop
    the fallback branch, delete the response_buf flush in cterm_handle_sts,
    and remove response_buf/response_buf_size from struct cterminal. The apc_handler callback carried the same dead retbuf/retsize pass-through
    and is cleaned up in the same pass. cterm_test loses its retbuf-leak
    detector (unreachable once the parameters are gone).

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Sunday, April 19, 2026 23:32:00
    https://gitlab.synchro.net/main/sbbs/-/commit/50184d9e6b35956aa4e9ee77
    Modified Files:
    src/conio/cterm.c cterm.h cterm_test.c src/syncterm/term.c
    Log Message:
    cterm: move keyboard encoding from term.c into cterm_encode_key()

    The six per-emulation key-mapping tables, DECBKM backspace/delete logic, ATASCII inverse toggle, Prestel/BEEB reveal toggle, and doorway
    NUL+scancode encoding all consulted state (emulation, extattr, doorway
    mode) that already lives inside struct cterminal, yet the translation
    logic sat in syncterm/term.c. Pulling it into cterm mirrors what cterm
    already does for the inbound (cterm_write) and response (cterm_respond)
    paths, tightens the module boundary, and unblocks multi-instance conio.

    ATASCII inverse state now lives on the cterm as `bool atascii_inverse`,
    read back for the status bar via cterm_atascii_inverse(). All byte
    emission goes through cterm_respond()/response_cb, so cterm stays
    decoupled from conn.c. The doorway short-circuit is absorbed into cterm_encode_key(); term.c keeps only the Alt-Z local filter.

    Adds 18 cterm_test cases covering ANSI raw/F-keys/arrow, DECBKM on/off
    for BS and DEL, VT52 arrow+DECBKM, ATASCII inverse toggle, PETSCII
    F-keys, Prestel '#' remap, BEEB HOME, and three doorway-mode variants (scancode, Alt-Z exemption, doorway off).

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Monday, April 20, 2026 22:42:00
    https://gitlab.synchro.net/main/sbbs/-/commit/edca025fc0a6ba1a425c8c8f
    Modified Files:
    src/conio/cterm.c cterm.h cterm_cterm.c cterm_cterm.h sdl_con.c src/syncterm/CHANGES ripper.c src/xpdev/sdlfuncs.c xpbeep.c xpbeep.h
    Log Message:
    xpdev: S16 stereo 44100 audio with streaming mixer

    Phase 1: format upgrade to signed 16-bit stereo 44100 Hz across all 7
    backends (CoreAudio, PulseAudio, PortAudio, SDL, Win32 waveOut, ALSA,
    OSS). SINE/SAWTOOTH/SQUARE become ideal native S16; the noisy shapes
    (SINE_HARM / SINE_SAW / SINE_SAW_CHORD / SINE_SAW_HARM) preserve their intentional U8 numeric artifacts by computing in U8 then expanding.

    Phase 2: xp_audio_* streaming API with per-stream ring buffers,
    per-channel volume, dB-linear fade in/out, and crossfade.

    Phase 3: unified pull-based mixer. Pull-native backends (SDL,
    CoreAudio, PortAudio, PulseAudio async) drive xp_mixer_pull from
    their own callback; push-native backends (Win32 waveOut, ALSA, OSS)
    run a single device thread that pulls and writes.

    Phase 3d: ANSI music (MML) rewritten around xp_audio_append;
    note_params / tone_or_beep / cterm_playnote_thread scaffolding
    deleted from cterm.c / cterm_cterm.c.

    PortAudio: dropped v1.8 pablio support, v19 callback API only.
    PulseAudio: converted from libpulse-simple to libpulse async with pa_threaded_mainloop, now pull-native.
    Win32 waveOut: pre-allocated 4-buffer ring with CALLBACK_EVENT.
    SDL audio: sdlfuncs.c libnames now lists SDL2 first.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Tuesday, April 21, 2026 17:31:00
    https://gitlab.synchro.net/main/sbbs/-/commit/897325cdb8ee22b19b9cf91a
    Modified Files:
    src/conio/cterm.c cterm.h cterm_cterm.c sdl_con.c src/syncterm/ooii.c ripper.c src/xpdev/xpbeep.c xpbeep.h
    Log Message:
    xpbeep: node-list FIFO mixer, dB volumes, soft-clip, -12 dB stream base

    Replaces the per-stream fixed 1 s S16 ring with a head/tail linked list
    of producer-supplied frame buffers. The caller malloc()s the PCM data
    and xp_audio_append() transfers ownership; the channel free()s it once
    the mixer has fully consumed the node. Append is non-blocking in the
    steady state Ä it only waits when the per-node metadata allocation
    itself fails and we need the mixer to drop a buf to free memory. This
    unblocks the scene-music use case where queuing an arbitrarily long
    playlist must return to the terminal immediately.

    Fold xp_audio_append_faded + xp_audio_append into a single entry point
    that takes a NULLable xp_audio_opts_t carrying per-entry volume (dB,
    summed with the stream base), fade_in/fade_out frames, crossfade, and
    loop. Envelopes live on the node and are evaluated per-sample in the
    mixer, which means looping bufs rise from silence exactly once and a
    crossfade append starts the overlap immediately Ä old tail fades out
    via an overlay envelope while the new buf fades in, both mixing
    concurrently until the overlay expires. XP_AUDIO_OPTS_INIT presets
    unity dB on all fields so = {0} is equivalent.

    Rework xp_mixer_pull to accumulate all streams into an int32_t scratch
    (grown under mixer_lock, persistent) and apply tanh soft-clipping in a
    single narrow pass at the end Ä replaces the old per-add int16_t
    saturate that distorted multi-stream mixes the moment any contribution
    pushed the running sum to full scale. Volumes now compose in dB (per-
    entry + stream base  one powf per channel per buf per pull) with 0 dB
    as unity.

    Lift the -12 dB headroom reduction out of xptone_makewave (both the
    U8-wrap noisy path and the double clean path) and apply it as stream
    base dB instead: cterm->music_stream and cterm->fx_stream open at
    -12 dB, xptone opens its ephemeral stream at -12 dB, sdl_beep bakes
    -12 dB into its static wave once at generation. Synth output keeps
    its full 16-bit resolution; OOII/RIP samples now ride at the same
    level as tones instead of being 12 dB louder than the rest of the mix.

    Add cterm_play_fx/_tone/_u8 on a per-cterm fx_stream (lazy-opened,
    distinct from music_stream so MF/MB ANSI-music state doesn't interact
    with RIP/OOII SFX). Migrate ripper.c rv_sound cases (A, BE, BL, M, P,
    R) and the ~40 xp_play_sample call sites in ooii.c to the new API;
    drop background bool since the persistent fx_stream handles sequencing.

    Teach parse_rip_new to forward the 0x0E music terminator to cterm when
    the preceding CSI introducer (| unconditional, M when music_enable ==
    ENABLED, N when music_enable >= BANSI) actually arms
    cterm_accumulate_music. Previously parse_rip ate all SO/SI bytes as
    RIPterm text-window controls, which left the music accumulator stuck
    until the connection ended.

    xptone chunks and play_music notes switch to per-chunk malloc + append transfer; ripper rv_sound A/BE/BL/M/P/R go through cterm_play_fx* and
    no longer re-open the device per tone.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Thursday, April 23, 2026 18:35:00
    https://gitlab.synchro.net/main/sbbs/-/commit/0ed7cdf7e7a50d6144e45781
    Modified Files:
    src/conio/cterm.c cterm.h src/syncterm/conn.c conn.h conn_conpty.c conn_conpty.h conn_pty.c conn_pty.h rlogin.c rlogin.h ssh.c ssh.h telnet_io.c telnet_io.h term.c window.c
    Log Message:
    SyncTERM: propagate terminal resizes to the remote end

    When DECSSDT toggles the status row the cterm's text dimensions change
    live, but nothing was telling the remote BBS. Add a size-change
    callback in cterm (fired from cterm_resize_rows) that term.c wires
    through a new conn_api.send_window_change dispatcher. Per-protocol implementations:

    - Telnet/TelnetS: NAWS subnegotiation, gated on DO NAWS, with RFC
    855/1073 0xFF byte-stuffing (previously missing on the inline
    DO-NAWS reply too).
    - SSH/SSHNA: SSH2 "window-change" via dssh_chan_send_window_change.
    - RLogin: RFC 1282 0xFF 0xFF 's' 's' message. First OOB handling
    in rlogin.c Ä enables SO_OOBINLINE, detects urgent bytes via
    SIOCATMARK, and dispatches through an extensible
    rlogin_handle_control() switch (stubs for 0x02/0x10/0x20; 0x80
    latches winsize-enabled and flushes the current size).
    - Local shell: TIOCSWINSZ on the pty master (unix) and
    ResizePseudoConsole on the HPCON (win32 conpty).
    - Raw/Modem/Serial: NULL; wrapper treats NULL as no-op.

    Pixel dimensions are normalized across cterm's callback, the conn
    callers, and get_term_win_size(): per-cell size comes from runtime vstat.charwidth/charheight (not the static vparams table, which was
    wrong for EGA once the font changed), and when the terminal fills
    every row/column of the framebuffer we report vstat.scrnwidth/
    scrnheight so leftover scanlines (EGA 80x43 has 6 unused rows) aren't truncated. ssh_connect now passes real pixel dims to the initial
    pty-req instead of zeros.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Friday, June 26, 2026 10:16:00
    https://gitlab.synchro.net/main/sbbs/-/commit/3c81fcf9794689f407ffd9ed
    Modified Files:
    src/conio/cterm.c cterm.h
    Log Message:
    Add lf_expand option

    Expands an LF to CRLF pair

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