diff --git a/delphi/KPANSI.PAS b/delphi/KPANSI.PAS index c3b4a02..d495e07 100644 --- a/delphi/KPANSI.PAS +++ b/delphi/KPANSI.PAS @@ -134,7 +134,6 @@ type procedure EraseLine(Mode: Integer); procedure ExecuteCSI(FinalCh: Char); procedure ExecuteMusic; - procedure FlipToScreen; procedure FreeLineList(List: TList); function GetCursorCol: Integer; function GetCursorRow: Integer; @@ -166,8 +165,10 @@ type destructor Destroy; override; procedure Clear; procedure Reset; + procedure FlipToScreen; procedure TickBlink; procedure Write(const S: string); + procedure WriteDeferred(const S: string); property CursorCol: Integer read GetCursorCol; property CursorRow: Integer read GetCursorRow; published @@ -1220,8 +1221,9 @@ procedure TKPAnsi.FlipToScreen; { screen via SetDIBitsToDevice immediately after rendering. One GDI call } { per dirty row, zero for the pixel expansion itself. } var - DC: HDC; - Row: Integer; + DC: HDC; + Row: Integer; + HasDirty: Boolean; begin if not HandleAllocated then Exit; @@ -1251,6 +1253,22 @@ begin FLastCursorRow := FCursorRow; end; + { Early exit: skip GetDC/ReleaseDC when nothing needs rendering } + if not FAllDirty then + begin + HasDirty := False; + for Row := 0 to FRows - 1 do + begin + if FDirtyRow[Row] then + begin + HasDirty := True; + Break; + end; + end; + if not HasDirty then + Exit; + end; + { Interleaved render + blast: single buffer is reused per row } DC := GetDC(Handle); for Row := 0 to FRows - 1 do @@ -1570,8 +1588,6 @@ begin FAllDirty := True; end; - { Reset cursor blink to visible on new data } - FBlinkOn := True; end; @@ -2315,7 +2331,6 @@ begin FBlinkOn := not FBlinkOn; FTextBlinkOn := not FTextBlinkOn; DirtyBlinkRows; - FlipToScreen; end; end; @@ -2371,6 +2386,13 @@ begin end; +procedure TKPAnsi.WriteDeferred(const S: string); +begin + if Length(S) > 0 then + ParseData(S); +end; + + { ----------------------------------------------------------------------- } { Component registration } { ----------------------------------------------------------------------- } diff --git a/delphi/TESTMAIN.PAS b/delphi/TESTMAIN.PAS index f3f4f70..77330b3 100644 --- a/delphi/TESTMAIN.PAS +++ b/delphi/TESTMAIN.PAS @@ -169,11 +169,12 @@ var Msg: TMsg; S: string; begin + Show; FDone := False; while not FDone do begin { Process all pending Windows messages (keyboard, paint, scrollbar) } - while PeekMessage(Msg, 0, 0, 0, pm_Remove) do + while PeekMessage(Msg, 0, 0, 0, pm_Remove or pm_NoYield) do begin if Msg.message = wm_Quit then begin @@ -187,18 +188,17 @@ begin if FDone then Break; - { Poll serial data directly -- no WM_COMMNOTIFY, no events } + { Poll serial data -- read one chunk, then yield to messages } if FComm.PortOpen then begin - repeat - S := FComm.Input; - if Length(S) > 0 then - FAnsi.Write(S); - until Length(S) = 0; + S := FComm.Input; + if Length(S) > 0 then + FAnsi.WriteDeferred(S); end; - { Tick blink state (uses GetTickCount, no WM_TIMER) } + { Tick blink (dirties rows if interval elapsed), then render } FAnsi.TickBlink; + FAnsi.FlipToScreen; end; end;