diff --git a/delphi/KPANSI.PAS b/delphi/KPANSI.PAS index f509ffe..1d7f482 100644 --- a/delphi/KPANSI.PAS +++ b/delphi/KPANSI.PAS @@ -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. } - 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 + { Blink counter: toggle cursor and text blink every BlinkInterval ticks } + Inc(FBlinkCount); + if FBlinkCount >= BlinkInterval 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); + FBlinkCount := 0; + FBlinkOn := not FBlinkOn; + Inc(FBlinkPhase); + if FBlinkPhase > 1 then + FBlinkPhase := 0; + NeedFlip := True; end; - ReleaseDC(Handle, DC); + if NeedFlip then + FlipToScreen; end;