92 lines
No EOL
4.8 KiB
Markdown
92 lines
No EOL
4.8 KiB
Markdown
---
|
||
title: Michael Abrash's Graphics Programming Black Book, Special Edition
|
||
author: Michael Abrash
|
||
date: '1997-07-01'
|
||
isbn: '1576101746'
|
||
publisher: The Coriolis Group
|
||
category: 'Web and Software Development: Game Development,Web and Software Development:
|
||
Graphics and Multimedia Development'
|
||
chapter: '48'
|
||
pages: 903-905
|
||
---
|
||
|
||
Four-pixel-wide patterns are more useful than you might imagine. There
|
||
are actually 2128 possible patterns (16 pixels, each with 28 possible
|
||
colors); that set is certainly large enough for most color-dithering
|
||
purposes, and includes many often-used patterns, such as halftones,
|
||
diagonal stripes, and crosshatches.
|
||
|
||
Furthermore, eight-wide patterns, which are widely used, can be drawn
|
||
with two passes, one for each half of the pattern. This principle can in
|
||
fact be extended to patterns of arbitrary multiple-of-four widths.
|
||
(Widths that aren't multiples of four are considerably more difficult to
|
||
handle, because the latches are four pixels wide; one possible solution
|
||
is expanding such patterns via repetition until they are
|
||
multiple-of-four widths.)
|
||
|
||
### Allocating Memory in Mode X {#Heading3}
|
||
|
||
Listing 48.2 raises some interesting questions about the allocation of
|
||
display memory in Mode X. In Listing 48.2, whenever a pattern is to be
|
||
drawn, that pattern is first drawn in its entirety at the very end of
|
||
display memory; the latches are then loaded from that copy of the
|
||
pattern before each scan line of the actual fill is drawn. Why this
|
||
double copying process, and why is the pattern stored in that particular
|
||
area of display memory?
|
||
|
||
The double copying process is used because it's the easiest way to load
|
||
the latches. Remember, there's no way to get information directly from
|
||
the CPU to the latches; the information must first be written to some
|
||
location in display memory, because the latches can be loaded *only*
|
||
from display memory. By writing the pattern to off-screen memory, we
|
||
don't have to worry about interfering with whatever is currently
|
||
displayed on the screen.
|
||
|
||
As for why the pattern is stored exactly where it is, that's part of a
|
||
master memory allocation plan that will come to fruition in the next
|
||
chapter, when I implement a Mode X animation program. Figure 48.3 shows
|
||
this master plan; the first two pages of memory (each 76,800 pixels
|
||
long, spanning 19,200 addresses—that is, 19,200 pixel quadruplets—in
|
||
display memory) are reserved for page flipping, the next page of memory
|
||
(also 76,800 pixels long) is reserved for storing the background (which
|
||
is used to restore the holes left after images move), the last 16 pixels
|
||
(four addresses) of display memory are reserved for the pattern buffer,
|
||
and the remaining 31,728 pixels (7,932 addresses) of display memory are
|
||
free for storage of icons, images, temporary buffers, or whatever.
|
||
|
||

|
||
|
||
This is an efficient organization for animation, but there are certainly
|
||
many other possible setups. For example, you might choose to have a
|
||
solid-colored background, in which case you could dispense with the
|
||
background page (instead using the solid rectangle fill routine to
|
||
replace the background after images move), freeing up another 76,800
|
||
pixels of off-screen storage for images and buffers. You could even
|
||
eliminate page-flipping altogether if you needed to free up a great deal
|
||
of display memory. For example, with enough free display memory it is
|
||
possible in Mode X to create a virtual bitmap three times larger than
|
||
the screen, with the screen becoming a scrolling window onto that larger
|
||
bitmap. This technique has been used to good effect in a number of
|
||
animated games, with and without the use of Mode X.
|
||
|
||
### Copying Pixel Blocks within Display Memory {#Heading4}
|
||
|
||
Another fine use for the latches is copying pixels from one place in
|
||
display memory to another. Whenever both the source and the destination
|
||
share the same nibble alignment (that is, their start addresses modulo
|
||
four are the same), it is not only possible but quite easy to use the
|
||
latches to copy four pixels at a time. Listing 48.3 shows a routine that
|
||
copies via the latches. (When the source and destination do not share
|
||
the same nibble alignment, the latches cannot be used because the source
|
||
and destination planes for any given pixel differ. In that case, you can
|
||
set the Read Map register to select a source plane and the Map Mask
|
||
register to select the corresponding destination plane. Then, copy all
|
||
pixels in that plane, repeating for all four planes.)
|
||
|
||
> 
|
||
> Although copying through the latches is, in general, a speedy technique,
|
||
> especially on slower VGAs, it's not always a win. Reading video memory
|
||
> tends to be quite a bit slower than writing, and on a fast VLB or PCI
|
||
> adapter, it can be faster to copy from main memory to display memory
|
||
> than it is to copy from display memory to display memory via the
|
||
> latches. |