Commit graph

8 commits

Author SHA1 Message Date
cd55adae4f Fix cursor artifacts and WM_TIMER starvation during high-speed data
Three fixes:

1. Cursor font mismatch: cursor overlay TextOut used the default DC
   font instead of FPaintFont (OEM_CHARSET). The wrong font size left
   residual pixels that buffer BitBlt didn't fully cover. Fix: select
   FPaintFont + OPAQUE BkMode into the CS_OWNDC screen DC once in
   RecalcCellSize, and re-assert before cursor TextOut in case VCL
   Paint altered the DC state.

2. WM_TIMER starvation: on Win16, WM_TIMER is lowest-priority and
   never dispatched while WM_COMMNOTIFY floods the queue. Fix: render
   from EndUpdate using GetTickCount throttle (no timer dependency).
   The timer remains as fallback for idle blink and trailing data.

3. Scroll performance: restore deferred ScrollDC at render time (not
   during parsing) so only newly-revealed rows need PaintLine instead
   of all 25. Dirty flags shift with each DoScrollUp to track the
   correct logical line positions after scroll.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:40:58 -06:00
c565be8489 Decouple rendering from data processing with timer-based display
Data parsing (ProcessChar) is now purely memory operations. EndUpdate
and ParseData set FRenderPending instead of calling FlipToScreen.
A 55ms timer (~18 Hz, matching Win16 tick resolution) drives rendering:
dirty rows are painted and BitBlt'd to screen only on timer ticks.
Blink toggles every 9 ticks (~500ms). This prevents high-throughput
data (door games, file transfers) from saturating the CPU with GDI
calls — between timer ticks, data just accumulates in cell buffers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:28:14 -06:00
a96dbb3faa Fix scroll rendering artifacts by removing ScrollDC
ScrollDC shifted buffer pixels during parsing before dirty rows were
rendered, causing unrendered garbage to propagate into non-dirty rows
on successive scrolls. Replace with FAllDirty to repaint all rows from
cell data after any scroll. With batched TextOut this costs ~250 GDI
calls per scroll instead of the old 12,000, so the overhead is minimal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:18:15 -06:00
ca99d1d21b Optimize TKPAnsi rendering with batched TextOut and dirty row tracking
Separate parsing from rendering to eliminate per-character GDI calls.
ProcessChar now only updates cell data in memory; rendering is deferred
to FlipToScreen which batches consecutive same-color cells into single
TextOut calls (~5-10 per row instead of 80). Partial BitBlt transfers
only the dirty row band to the screen. Non-blinking rows render to one
buffer and BitBlt to the second, halving GDI work for typical content.

Also removes redundant GetCommError from KPComm receive path and adds
BeginUpdate/EndUpdate batching in the test app's CommEvent handler.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:15:51 -06:00
be566a5767 Fix OEM font rendering and terminal responsiveness in TKPAnsi
Replace TBitmap back buffer with raw GDI memory DC to prevent Delphi's
TCanvas from overriding the OEM_CHARSET font selection. Add OUT_RASTER_PRECIS
to CreateFontIndirect to ensure Windows maps to a true CP437 raster font
instead of a TrueType substitution. Optimize paint loop with fixed char
array instead of string concatenation. Restore Update call in ParseData
so WM_PAINT is not starved by WM_COMMNOTIFY. Add text blink support via
timer-driven FG/BG toggling and store blink as cell attribute instead of
mapping to bright background.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:48:20 -06:00
a3c52e0817 Add terminal query responses for BBS ANSI detection
Handle ENQ (0x05), ESC[c (Device Attributes), ESC[5n (Device Status
Report), and ESC[6n (Cursor Position Report).  Responses are sent
back through OnKeyData so BBSes can detect ANSI terminal capability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 00:06:39 -06:00
c3ae983a73 Add TKPAnsi ANSI BBS terminal emulation component for Delphi 1.0
TKPAnsi is a TCustomControl descendant providing a visual ANSI terminal
with 16-color palette, scrollback buffer, blinking cursor, and ANSI music.
Supports CSI sequences (cursor movement, erase, SGR colors/attributes,
insert/delete lines/chars, scroll), DEC private modes (wrap, cursor
visibility), and keyboard translation (arrows, function keys, etc.).

Test app (TESTMAIN.PAS) updated to wire TKPAnsi to TKPComm as a
full terminal: received data feeds the terminal display, keystrokes
are sent out the serial port.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:12:23 -06:00
dd8326d16a Add native Delphi 1.0 TKPComm serial communications component
VBX registration is non-functional in VB4 16-bit (VBRegisterModel is a
no-op, VBGetModelInfo never called). Native Delphi component avoids all
DLL/export/registration issues — compiles directly into the IDE.

TKPComm is a TComponent descendant calling the Windows 3.1 comm API
directly. Uses RegisterClass/CreateWindow for WM_COMMNOTIFY dispatch
with the component instance pointer stored in cbWndExtra. Includes a
test application (KPTEST) with send/receive UI built entirely in code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 22:04:54 -06:00