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>
This commit is contained in:
parent
a96dbb3faa
commit
c565be8489
1 changed files with 26 additions and 37 deletions
|
|
@ -62,6 +62,8 @@ type
|
|||
FPaintFont: HFont;
|
||||
FStockFont: Boolean;
|
||||
FBlinkPhase: Integer;
|
||||
FBlinkCount: Integer;
|
||||
FRenderPending: Boolean;
|
||||
FUpdateCount: Integer;
|
||||
FDirtyRow: array[0..255] of Boolean;
|
||||
FAllDirty: Boolean;
|
||||
|
|
@ -163,7 +165,10 @@ const
|
|||
$00FFFFFF { 15 White (bright) }
|
||||
);
|
||||
|
||||
CursorBlinkMs = 500;
|
||||
{ Timer fires at ~18 Hz (Win16 tick resolution is ~55 ms). }
|
||||
{ Cursor and text blink toggle every 9 ticks (~500 ms). }
|
||||
RenderTickMs = 55;
|
||||
BlinkInterval = 9;
|
||||
|
||||
{ OUT_RASTER_PRECIS may not be defined in Delphi 1.0 WinTypes }
|
||||
OutRasterPrecis = 6;
|
||||
|
|
@ -334,6 +339,8 @@ begin
|
|||
FPaintFont := 0;
|
||||
FStockFont := False;
|
||||
FBlinkPhase := 0;
|
||||
FBlinkCount := 0;
|
||||
FRenderPending := False;
|
||||
FUpdateCount := 0;
|
||||
FAllDirty := True;
|
||||
FBufDC[0] := 0;
|
||||
|
|
@ -875,7 +882,7 @@ begin
|
|||
if FUpdateCount <= 0 then
|
||||
begin
|
||||
FUpdateCount := 0;
|
||||
FlipToScreen;
|
||||
FRenderPending := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
@ -1539,7 +1546,7 @@ begin
|
|||
FBlinkOn := True;
|
||||
|
||||
if FUpdateCount = 0 then
|
||||
FlipToScreen;
|
||||
FRenderPending := True;
|
||||
end;
|
||||
|
||||
|
||||
|
|
@ -1827,10 +1834,10 @@ begin
|
|||
CreateBuffers;
|
||||
FAllDirty := True;
|
||||
|
||||
{ Start cursor blink timer }
|
||||
{ Start render/blink timer }
|
||||
if not FTimerActive then
|
||||
begin
|
||||
SetTimer(Handle, 1, CursorBlinkMs, nil);
|
||||
SetTimer(Handle, 1, RenderTickMs, nil);
|
||||
FTimerActive := True;
|
||||
end;
|
||||
|
||||
|
|
@ -1976,43 +1983,25 @@ end;
|
|||
|
||||
procedure TKPAnsi.WMTimer(var Msg: TWMTimer);
|
||||
var
|
||||
DC: HDC;
|
||||
Line: PTermLine;
|
||||
X: Integer;
|
||||
Y: Integer;
|
||||
NeedFlip: Boolean;
|
||||
begin
|
||||
FBlinkOn := not FBlinkOn;
|
||||
NeedFlip := FRenderPending;
|
||||
FRenderPending := False;
|
||||
|
||||
{ Toggle text blink phase by swapping which buffer is displayed. }
|
||||
{ Buffers are already up-to-date; just BitBlt the other one. }
|
||||
{ Blink counter: toggle cursor and text blink every BlinkInterval ticks }
|
||||
Inc(FBlinkCount);
|
||||
if FBlinkCount >= BlinkInterval then
|
||||
begin
|
||||
FBlinkCount := 0;
|
||||
FBlinkOn := not FBlinkOn;
|
||||
Inc(FBlinkPhase);
|
||||
if FBlinkPhase > 1 then
|
||||
FBlinkPhase := 0;
|
||||
|
||||
if not HandleAllocated then
|
||||
Exit;
|
||||
if FBufDC[0] = 0 then
|
||||
Exit;
|
||||
|
||||
DC := GetDC(Handle);
|
||||
BitBlt(DC, 0, 0, FBufW, FBufH,
|
||||
FBufDC[FBlinkPhase], 0, 0, SRCCOPY);
|
||||
|
||||
{ Cursor overlay }
|
||||
if FCursorVisible and FBlinkOn and (FScrollPos = 0) and
|
||||
(FCursorRow >= 0) and (FCursorRow < FRows) and
|
||||
(FCursorRow < FScreen.Count) and
|
||||
(FCursorCol >= 0) and (FCursorCol < FCols) then
|
||||
begin
|
||||
Line := FScreen[FCursorRow];
|
||||
X := FCursorCol * FCellWidth;
|
||||
Y := FCursorRow * FCellHeight;
|
||||
SetTextColor(DC, ColorToRGB(Line^.Cells[FCursorCol].BG));
|
||||
SetBkColor(DC, ColorToRGB(Line^.Cells[FCursorCol].FG));
|
||||
WinProcs.TextOut(DC, X, Y, @Line^.Cells[FCursorCol].Ch, 1);
|
||||
NeedFlip := True;
|
||||
end;
|
||||
|
||||
ReleaseDC(Handle, DC);
|
||||
if NeedFlip then
|
||||
FlipToScreen;
|
||||
end;
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue