Скачать Outlaw Triad Demo Series, Part 3 - PAGE-FLIPPING

05.03.1996
Скачать файл (9,39 Кб)




Welcome to the Outlaw Triad demo-series! In these series we will be
talking about programming demo-effects in either pascal or assembler.
Theory behind the effects shall be discussed while a full sourcecode
is also provided. 
In this latest release we will be talking about the use of the
socalled virtual screens. These are very powerfull tools when coding
demos or any other graphic related program. A full sourcecode in Turbo
Pascal is provided in this package. Enjoy!

-------------------------- Theory ----------------------------------

What exactly is a virtual screen? Well, a virtual screen is nothing
more than a piece of base-memory representing the VGA screen. So, when
using standard mode 13h, the virtual screen is 64000 bytes large.
Because the vga is 320*200=64000 bytes.

Now what can you do with a virtual screen? A major advantage of using
these virtual screens is that you can avoid bad flickering on the
screen. The plan is to update the data in memory and then flip it to
the VGA. Updating the VGA memory directly can cause a lot of "snow" on
the screen. Suppose you are writing a demo in which a lot of sprites
and other things are moving on the screen. But what happens if you
want to have a picture in the background?
The picture would be erased because the sprites are drawn on top of it.
That's no good! Here we use a virtual screen.
You could do something like this:

    1. - Draw the picture on the virtual screen.
    2. - Flip (copy) the picture to the vga (old frames are erased).
    3. - Wait for a vertical retrace (to make it even smoother).
    4. - Draw your sprites on the vga (next frames).
    5. - Back to 2.

So you see? This way your picture won't be erased at all!
You constantly copy your virtual page to the VGA before you write the
next frame. You might say that this is a rather slow way of doing
things. This is true. But better use slow tricks than having bad
screen updates, right? 
You should write your pageflipping routine(s) in assembler.
Don't worry, for those of you with little experience in coding asm,
I have included my own assembler routines. Those are pretty fast
(using extended registers for fast copying).

Anyway, how do we setup a virtual screen? Our source is in Pascal.
Now, in Pascal you may not have a single variable of 64000 bytes.
That would be too large. The solution is using pointers.
Do it like this:

Type
  Virtual  = Array[1..64000] of byte; { the Virtual Screen size       }
  VirPoint = ^Virtual;                { Pointer to the virtual screen }

Var
  Virscr: VirPoint;                   { The actual virtual screen }
  Vaddr : Word;                       { Segment of our virtual screen }

Procedure SetMemory;                  { Allocates memory }
Begin
  GetMem(VirScr,64000);               { 64000 bytes }
  Vaddr := Seg(Virscr^);
End;

Procedure FreeMemory;                 { Frees the memory }
Begin
  FreeMem(VirScr,64000);
End;

Ok, when you use "SetMemory" inside your program, it would setup 64000
bytes of base-memory for you to use and "Vaddr" would be pointing to
the segment of this memory (virtual screen). When your program is done,
you use "FreeMemory" to... well... free the memory. If you don't do
that, programs you run after you executed your own program have 64000
bytes less to work with and that's no good. Now, right after you have
setup your virtual page, you must clear it from any garbage that might
still exist there. You can do that by writing 64000 zeros to that
memory. Examine the source to see what I mean.

All is fine sofar, but how do we actually access the virtual page?
Let me give you an example by plotting a pixel on the virtual page
with the "SetPixel" procedure. Here's the procedure in assembler:

Procedure SetPixel(X,Y:Integer;Color:Byte;Where:Word); Assembler;
Asm
  mov  ax,[Where]
  mov  es,ax                  { es:di => destination }
  mov  di,Y
  mov  ax,Y
  shl  di,8
  shl  ax,6
  add  di,ax                  { di = y*320 }
  mov  ax,X
  add  di,ax                  { di = (y*320)+x }
  mov  al,Color
  mov  byte ptr es:[di],al    { Place dot }
End;

Let's say you want to have a pixel right in the middle of the virtual
screen. The exact place is calculated in the same manner as on the VGA,
that is (Y*320)+X. Why? Because base-memory, like VGA-memory,
is lineair!
So, the middle of the screen would be X=160, Y=100. Let's say the
color is 1. Your total command would now be:
  SetPixel(160,100,1,Vaddr).
And that's it! Instead of pointing to the VGA's segment, you point to
the segment of the virtual screen. As you see it's very simple indeed.

Using base-memory is not the only way of using virtual screens.
You can also use plain VGA-memory for it. But in order to do that,
you must use an unchained VGA-mode. E.g, Mode Y has a resolution of
320*200*256 and has got 4 pages (screens) available in display (vga)
memory.
Read "chain4.doc" and "tweakdoc.txt" for more info on that.
These are textfiles written by me (Vulture/OT) on unchaining and
tweaking the VGA.

Ok, now examine the source to see a quick example of virtual screens.
In the sample program I setup a virtual screen, fill it with random
pixels and wait for a keypress. Then I flip all data on the virtual
screen to the VGA. It's a short program but I am sure you can now see
the use and power of virtual screens. Btw, the assembler procedures
found here are very fast. Only thing I ask in return is that you greet
me or Outlaw Triad in your productions. Is that cheap or what? ;-)
In the future I might release a pageflipping program in 100% assembler.