				VGA Hardware Tricks
				Part 4 of 6

Introduction:

Welcome to VGA Hardware Tricks, a six-part series written by
Trixter/Hornet.  In this series, I'll be exploring ways you can push VGA
harder to achieve new effects.  The emphasis of this series is twofold:

	- The techniques discussed will work on any *standard* VGA card.
	(No SVGA or VESA video cards are necessary, but these techniques
	will work on those cards as well.)

	- The techniques discussed require very little calculation, so
	they will work on slower computers.  (Some techniques, however,
	requires a lot of CPU *attention*, which means that while the
	effects are happening, they can't be disturbed by other
	calculations, etc.  Good Assembler programmers might be able to
	get around this, however.)

This series is for intermediate to advanced coders, so there are a
couple of prerequisites you should meet:  Example code will be given in
assembler and Pascal, so familiarity with those languages will be
helpful when looking at the example code; also, a familiarity with Mode
X (unchained VGA) is required, as procedures like changing video
resolutions will be discussed.

This series covers six topics:

	- Crossfading 16-color pictures
	- Crossfading 256-color pictures
	- More than 256 colors: 12-bit color
	- More than 256 colors: 18-bit color	(this article)
	- Copper effects in text mode
	- Displaying graphics in text mode

Description:

Yes, you read that title right--we're going to display 18-bit color on a
piece of hardware only built for 8-bit color.  Seem impossible?
Technically, it is.  But using our old friend, persistance of vision, we
can fake it convincingly--and the best part is, it's not CPU intensive
at all, just a clever arrangement of pixels.

Overview:

(Note:  This technique has been so overused in 1995 that, initially, I
thought it would need no explanation; just some example code and that
would be it.  However, there is inevitably someone, somewhere, that
doesn't really grasp how this works.  So, I feel a full explanation is
necessary.)

As I've written about many times before, our brain is a very lazy thing.
So lazy, in fact, that it tends to fill in information that our eyes
don't provide.  This is called Persistance Of Vision.  (If you need a
more detailed explanation of what that is, look at previous VGA Hardware
Tricks articles or visit your local library.)  Persistance Of Vision has
been used in many places before computers even existed, like the concept
of film and television.  It's television, in fact, that provides us with
the example we'll use to coax 18-bit (262,144) color out of out 8-bit
(256) color video card.

If you've ever gotten curious as to how your television or computer
monitor works, you might have gone right up to the screen and looked at
it closely, possibly with a magnifing glass.  If you'd had, you'd see a
small hexagonal grid of red, green, and blue dots.  They're arranged in
groups of three, like this:

   X

 X   X

This arrangement is called a "triad".  Each red, green, and blue dot in
a triad glow with a different intensity, producing one solid color.
(Well, it's not exactly a *solid* color, but the dots are so small and
close together that POV blends them into one color for us.)  The entire
screen is made up of triads.

To produce 18-bit color, all we have to do is emulate a series of
triads--that is, put a red, green, and blue pixel next to each other and
alter the intensity of all three to blend into a single color.  This
technique produces 18-bit color because the VGA hardware is capable of
producing 6-bit (64) intensities of red, green, and blue for any given
pixel.  So, 6+6+6 = 18-bit color, or to look at it another way, 
64 red values * 64 blue values * 64 green values = 262,144 possible colors.

Implementing Triads:

To emulate a triad, we're going to need to set up the palette first.
VGA is capable of 64 different intensities of red, green, and blue, so
the palette needs to have 64 reds, 64 greens, and 64 blues.  Pseudocode
for doing that would probably look like this:

for loop:=0 to 63 do begin
	set palette index "loop"     to r=loop,g=0,b=0  <-- red entries
	set palette index "loop+64"  to r=0,g=loop,b=0  <-- green entries
	set palette index "loop+128" to r=0,g=0,b=loop  <-- blue entries
end;

This leaves 64 colors left over at the end of our palette (from 192 to
255), for anything we feel like doing.

Now we get to plot the three pixels of a triad.  Since VGA lays out
pixels in a grid (as opposed to a "honeycomb" like an actual television
screen), we have to lay them out on a grid as well.  The best way is in
a line, like this:

Key:  R = red pixel, G = green pixel, B = blue pixel

   0 1 2 3 4 5 6 7 8 9
   
0  R R R R R R R R R R
1  G G G G G G G G G G
2  B B B B B B B B B B

3  R R R R R R R R R R
4  G G G G G G G G G G
5  B B B B B B B B B B

etc.  So, 18-bit color pixel "(0,0)" is really "red at (0,0)", "green at
(0,1)", and "blue at (0,2)".

Potential problems:

It sounds easy, doesn't it?  Just put a red, green, and blue pixel next
to each other and you've got one of those 262,144 colors.  If you were
to stop reading this article right now and jump to the compiler, you'd
probably run into a problem as soon as you entered mode 13h:  The pixels
are big.  *Way* too big.  In fact, you'd have to sit about four feet
away from the screen to ignore the fact that you're really looking at
three pixels close together instead of a new color.  Not only that, but
each "pixel" is made up of three pixels arranged vertically, which is a
really weird aspect ratio (the effective resolution is 320x66).  In
order to fix these problems, we've got to shrink the height of each
pixel.  But how can we make the pixels smaller?

One solution that's tempting is to use a 640x480x256 VESA mode, or
something similar.  That defeats the whole purpose of this, because then
a super-vga card would be required, and this series of articles is
dedicated to achieving new effects on *standard* hardware.  (Yes, not
*everyone* has a super-vga card and monitor.)  Besides, if you were
going to limit your audience to a VESA mode, you might as well go all
the way and use an actual 24-bit color mode anyway.  Finally,
640x480x256 is 300K of video memory per page, which is too slow for
animation (even on 486 machines).

The solution, as it has been in the past, is to use Mode X.  Mode X, as
you recall, is a video mode created by unchaining the video RAM, so that
you can (amongst many other things) alter the display resolution.  It is
easy to make a resolution of 320x400 (effectively 320x133) under Mode X,
which helps a little, and actually gives us 2 video pages to work with.
This is suitable for animation.  If you need more pixels and something a
little more accurate, 320x480 (effectively 320x160) comes close to the
standard 320x200 1:1.3 aspect ratio that VGA users are used to.  Because
it's 480 lines, it will work with all monitors.

Believe it or not, you can actually go higher than that, to 320x600
(effectively 320x200)!  This mode was, to my knowledge, first used by
Adam Bergstrom; in fact, his code is the code in the vgahard4.zip
package described later in this article.  Of course, this resolution is
only possible on monitors that can display 800x600, because it uses 600
screen lines.  It also uses 192k of the 256K of video ram we have access
to, so that makes it even more unsuitable for animation.  However, it's
best for displaying static pictures; I used it for Hornet's NAID Party
report (hrn-nrpt.zip on ftp.cdrom.com) to display "320x200" 24-bit color
pictures (I shifted left (SHL) each RGB component down two bits before
plotting to the screen).

Code:

Code that acheives this effect is available on ftp.cdrom.com in the
directory /pub/demos/hornet/demonews/vgahard in the file vgahard4.zip.
This article is stored there as well.  To compile the code directly,
you'll need Turbo Pascal 7.0 or later.  (The code can be compiled on
eariler compilers as well, but some slight modification might be
necessary.)

Notes:

This method is extremely useful for animation, since there's no palette
switching or page flipping required, unlike some other methods.  It
lends itself so well to this that it has become a "fad" effect for
practically every demo after X14 / Orange first used it on the PC.  The
18-bit color effect is sometimes called "Orange's 262144 color mode" as
a result.  Another demo that uses this is Just / Legend Design.  (In
fact, the entire demo is in that mode.)

Ambience and Luminati / Tran claim 21-bit color; they achieve this by
using two video pages and flipping between them rapidly, using two
flipping pixels in one location to blend into a "third" pixel, similar
to the 12-bit color technique covered in VGA Hardware Tricks #3.  Once
again, POV at work.  ;)  In order to achieve this, however, Tran has to
reprogram the VGA registers, increasing the refresh rate of the screen
so that it flips pages at nearly double it's normal rate, at 100Hz (100
times a second), giving an effect screen refresh rate of 50Hz.  This
mode is not completely compatible with all monitors, so I have not
decided to cover it in this series.  Captain Hook has written up a short
article on it, however, so I expect you'll learn how to do it from him
shortly.

Next time:

I'm not *quite* done with color, if you can believe that.  Next time,
I'll show you how to display 400 different colors at the same time--in
*text mode*.  :)  If you're familiar with the "copper" chip inside every
Amiga computer, you'll know what I'm talking about.  Have fun
experimenting until then!
