Recent

Author Topic: Video unit and updating the screen  (Read 1462 times)

CyberFilth

  • Jr. Member
  • **
  • Posts: 88
    • My github account
Video unit and updating the screen
« on: January 27, 2021, 10:09:32 pm »
I've been trying to find a few examples of the video unit and how it writes to the screen.

As I understand it, you lock the screen, write to a temporary buffer and then unlock the screen.
Running the UpdateScreen command will then copy the changed parts of the temporary buffer to the screen, rather than redrawing the whole thing.

I tried to test this with the following
Code: Pascal  [Select][+][-]
  1. program videotest;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   SysUtils,
  7.   video,
  8.   Keyboard;
  9.  
  10. var
  11.   vid: TVideoMode;
  12.   garbageArray: array[1..20, 1..20] of char;
  13.   r, c: integer;
  14.  
  15. begin
  16.   Randomize;
  17.   InitVideo;
  18.   InitKeyboard;
  19.   vid.Col := 40;
  20.   vid.Row := 80;
  21.   vid.Color := True;
  22.   SetVideoMode(vid);
  23.   GetKeyEvent;
  24.  
  25.   for r := 1 to 20 do
  26.   begin
  27.     for c := 1 to 20 do
  28.     begin
  29.       if (Random(2) = 1) then
  30.         garbageArray[r][c] := '#'
  31.       else
  32.         garbageArray[r][c] := '.';
  33.     end;
  34.   end;
  35.  
  36.   ClearScreen;
  37.   LockScreenUpdate;
  38.  
  39.   for r := 1 to 20 do
  40.   begin
  41.     for c := 1 to 20 do
  42.     begin
  43.       SetCursorPos(c, r);
  44.       Write(garbageArray[r][c]);
  45.     end;
  46.   end;
  47.  
  48.    SetCursorPos(3, 10);
  49.   Write('  OVERWRITE  ');
  50.  
  51.  
  52.   UnlockScreenUpdate;
  53.  
  54.   UpdateScreen(False);
  55.  
  56.   GetKeyEvent;
  57.  
  58.   DoneVideo;
  59.   DoneKeyboard;
  60. end.
  61.  

It writes out a random array of characters, and then writes the word OVERWRITE over the top. The behaviour that I expected was that when updating the screen it should write the whole lot in one pass. But when running the program, it writes out the array and then adds the word OVERWRITE afterwards.
I assumed that calling lock/unlockscreenupdate would stop this from happening. Or have I misunderstood how the unit works?
Running Windows 10 & Xubuntu 20.04 | Lazarus 2.0.12 | FPC 3.2.0

jamie

  • Hero Member
  • *****
  • Posts: 6091
Re: Video unit and updating the screen
« Reply #1 on: January 27, 2021, 11:20:40 pm »
That must be a DOS unit?

What exactly are you trying to accomplish ?
The only true wisdom is knowing you know nothing

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Video unit and updating the screen
« Reply #2 on: January 28, 2021, 12:42:33 am »
I assumed that calling lock/unlockscreenupdate would stop this from happening. Or have I misunderstood how the unit works?

Yes you misunderstood a little bit :)

What video does is to provide VideoBuf, a "buffer" where you write (by changing its elements) and move to screen with UpdateScreen(). If you want to prohibit "writing" in the screen for performance reasons then you can use synched calls to LockScreenUpdate and UnlockUpdateScreen but all they do is to prevent UpdateScreen() from doing anything.

Standard procedures like Write() and WriteLn() will still use their own method to access the screen, either through the handle, DMA, or whatever, depending mostly on whether you also use CRT, but unlike happens with this last, they won't be aware of the special methods in video.

What the video unit does is quite well explained in the documentation. What it doesn't, though, is undocumented. ;)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: Video unit and updating the screen
« Reply #3 on: January 28, 2021, 04:56:08 am »
The demo program seems to work as intended on FreeBSD (GTK2) and macOS (Cocoa). No obvious overwriting. Maybe a computer/video speed issue?

FreeBSD 12.2-STABLE on a 2011 Mac mini, i7-2620M CPU @ 2.70GHz, 16G, 256G SSD.
macOS 10.14.6 on a 2018 Mac mini, i7-8700B @ 4.2GHz, 16G, 1TB SSD.

cappe

  • Full Member
  • ***
  • Posts: 191
Re: Video unit and updating the screen
« Reply #4 on: January 28, 2021, 09:00:00 am »
it also works me on windows

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Video unit and updating the screen
« Reply #5 on: January 28, 2021, 09:04:01 am »
That must be a DOS unit?

No, it's not a DOS unit. It's a cross platform unit for full screen text (“full screen” as in “the whole command line window”) and is also what FreeVision is based on.

CyberFilth

  • Jr. Member
  • **
  • Posts: 88
    • My github account
Re: Video unit and updating the screen
« Reply #6 on: January 28, 2021, 01:51:35 pm »
I think the confusion comes from the fact that I expected the video buffer to work the same way as a graphics buffer.
Writing text to the buffer, overwriting it, deleting parts, whatever. Then when blitting this to the screen only the final result would be written.

From running this on a slow Windows PC last night however I see the screen update each change one by one. First writing out the array of characters and then adding the text in a second pass.
This doesn't seem to be any different to how the CRT unit updates the screen and I expected the Video unit to be a little faster.

I'll check the behaviour on a different laptop later and see if it behaves the same.
Running Windows 10 & Xubuntu 20.04 | Lazarus 2.0.12 | FPC 3.2.0

CyberFilth

  • Jr. Member
  • **
  • Posts: 88
    • My github account
Re: Video unit and updating the screen
« Reply #7 on: January 29, 2021, 12:04:12 am »
Ah, thanks lucamar, I think I finally got the point!
write and writeln are not part of the video unit so they ignore the screen update command.

Switching to the TextOut procedure given in the documentation is much faster with no noticeable flicker or redrawing.
Code: Pascal  [Select][+][-]
  1. program videotest;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   SysUtils,
  7.   video,
  8.   Keyboard;
  9.  
  10. var
  11.   vid: TVideoMode;
  12.   garbageArray: array[1..20, 1..20] of char;
  13.   r, c: integer;
  14.  
  15.   procedure TextOut(X, Y: word; const S: string);
  16.   var
  17.     P, I, M: word;
  18.   begin
  19.     P := ((X - 1) + (Y - 1) * ScreenWidth);
  20.     M := Length(S);
  21.     if P + M > ScreenWidth * ScreenHeight then
  22.       M := ScreenWidth * ScreenHeight - P;
  23.     for I := 1 to M do
  24.       VideoBuf^[P + I - 1] := Ord(S[i]) + ($07 shl 8);
  25.     UpdateScreen(False);
  26.   end;
  27.  
  28. begin
  29.   Randomize;
  30.   InitVideo;
  31.   InitKeyboard;
  32.   vid.Col := 40;
  33.   vid.Row := 80;
  34.   vid.Color := True;
  35.   SetVideoMode(vid);
  36.   SetCursorPos(10, 10);
  37.   Write('Ready...');
  38.   GetKeyEvent;
  39.  
  40.   for r := 1 to 20 do
  41.   begin
  42.     for c := 1 to 20 do
  43.     begin
  44.       if (Random(2) = 1) then
  45.         garbageArray[r][c] := '#'
  46.       else
  47.         garbageArray[r][c] := '.';
  48.     end;
  49.   end;
  50.  
  51.   ClearScreen;
  52.   LockScreenUpdate;
  53.  
  54.   for r := 1 to 20 do
  55.   begin
  56.     for c := 1 to 20 do
  57.     begin
  58.       TextOut(c, r, garbageArray[r][c]);
  59.     end;
  60.   end;
  61.   TextOut(3, 10, '  OVERWRITE  ');
  62.  
  63.  
  64.   UnlockScreenUpdate;
  65.  
  66.   // only redraws the parts that have been updated
  67.   UpdateScreen(False);
  68.   GetKeyEvent;
  69.   DoneVideo;
  70.   DoneKeyboard;
  71. end.
  72.  
« Last Edit: January 29, 2021, 01:55:02 pm by CyberFilth »
Running Windows 10 & Xubuntu 20.04 | Lazarus 2.0.12 | FPC 3.2.0

 

TinyPortal © 2005-2018