• src/conio/cterm.c cterm.h

    From Deuc¿@VERT to Git commit to main/sbbs/m on Wednesday, October 01, 2025 02:23:00
    https://gitlab.synchro.net/main/sbbs/-/commit/3fa60ed10671772a3c9bc26f
    Modified Files:
    src/conio/cterm.c cterm.h src/syncterm/CHANGES
    Log Message:
    Implement OSC 10 ; ? ST and OSC 11 ; ? ST

    Yet another program (gcc) now defaults to dark blue on black for some things.

    This pisses me off.

    Apparently in the world we live in, every different program needs to use ANSI, and it all needs a special snowflake environment variable (usually PROGNAME_COLORS) to tell it to not suck on a terminal where dark blue is dark blue and the default background colour is black.

    To be fair, the default background colour is unknown to the program, so it can't not suck on some terminals without overriding the background itself, which would be quite rude, and the default default background colour in XTerm is white.

    XTerm supports OSC 10 ; ? ST and OSC 11 ; ? ST to query the RGB values of the foreground and background colours respectively. This would allow programs to actually know and as a result, and take away their excuse for sucking.

    Hopefully at least someone does this and chooses default colours based in it.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • 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