home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
program
/
books
/
progem
/
raster.6
< prev
next >
Wrap
Text File
|
1986-11-01
|
29KB
|
617 lines
Permission to reprint or excerpt is granted only if the following line
appears at the top of the article:
ANTIC PUBLISHING INC., COPYRIGHT 1985. REPRINTED BY PERMISSION.
Professional GEM by Tim Oren
Column #6 - Raster Operations
SEASONS GREETINGS!
This is the Yuletide installment of ST PRO GEM, devoted to
explaining the raster, or "bit-blit" portion of the Atari ST's VDI
functions.
Please note that this is NOT an attempt to show how to write
directly to the video memory, although you will be able to deduce a
great deal from the discussion.
As usual, there is a download with this column. You will find it
in ATARI16 (PCS-58) in DL3 under the name of GEMCL6.C.
DEFINING TERMS
To understand VDI raster operations, you need to understand the
jargon used to describe them. (Many programmers will be tempted to
skip this section and go directly to the code. Please don't do it
this time: Learning the jargon is the larger half of understanding the
raster operations!)
In VDI terms a raster area is simply a chunk of contiguous words of
memory, defining a bit image. This chunk is called a "form". A form
may reside in the ST's video map area or it may be in the data area of
your application. Forms are roughly analogous to "blits" or "sprites"
on other systems. (Note, however, that there is no sprite hardware on
the ST.)
Unlike other systems, there is NO predefined organization of the
raster form. Instead, you determine the internal layout of the form
with an auxiliary data structure called the MFDB, or Memory Form
Definition Block. Before going into the details of the MFDB, we need
to look at the various format options. Their distinguishing features
are monochrome vs. color, standard vs. device-specific and even-word
vs. fringed.
MONOCHROME VS. COLOR
Although these terms are standard, it might be better to say
"single-color vs. multi-color". What we are actually defining is the
number of bits which correspond to each dot, or pixel, on the screen.
In the ST, there are three possible answers. The high-resolution mode
has one bit per pixel, because there is only one "color": white.
In the medium resolution color mode, there are four possible colors
for each pixel. Therefore, it takes two bits to represent each dot on
the screen. (The actual colors which appear are determined by the
settings of the ST's pallette registers.)
In the low resolution color mode, sixteen colors are generated,
requiring four bits per pixel. Notice that as the number of bits per
pixel has been doubled for each mode, so the number of pixels on the
screen has been halved: 640 by 400 for monochrome, 640 by 200 for
medium-res, and 320 by 200 by low-res. In this way the ST always uses
the same amount of video RAM: 32K.
Now we have determined how many bits are needed for each pixel, but
not how they are laid out within the form. To find this out, we have
to see whether the form is device-dependent or not.
STANDARD VS. DEVICE-SPECIFIC FORMAT
The standard raster form format is a constant layout which is the
same for all GEM systems. A device-specific form is one which is
stored in the internal format of a particular GEM system. Just as the
ST has three different screen modes, so it has three different
device-specific form formats. We will look at standard form first,
then the ST-specific forms.
First, it's reasonable to ask why a standard format is used. Its
main function is to establish a portability method between various GEM
systems. For instance, an icon created in standard format on an IBM
PC GEM setup can be moved to the ST, or a GEM Paint picture from an
AT&T 6300 could be loaded into the ST version of Paint.
The standard format has some uses even if you only work with the
ST, because it gives a method of moving your application's icons and
images amongst the three different screen modes. To be sure, there
are limits to this. Since there are different numbers of pixels in
the different modes, an icon built in the high-resolution mode will
appear twice as large in low-res mode, and would appear oblong in
medium-res. (You can see this effect in the ST Desktop's icons.)
Also, colors defined in the lower resolutions will be useless in
monochrome.
The standard monochrome format uses a one-bit to represent black,
and uses a zero for white. It is assumed that the form begins at the
upper left of the raster area, and is written a word at a time left to
right on each row, with the rows being output top to bottom. Within
each word, the most significant bit is the left-most on the screen.
The standard color form uses a storage method called "color
planes". The high-order bits for all of the pixels are stored just as
for monochrome, followed by the next-lowest bit in another contiguous
block, and so on until all of the necessary color bits have been
stored.
For example, on a 16-color system, there would be four different
planes. The color of the upper-leftmost bit in the form would be
determined by concatenating the high-order bit in the first word of
each plane of the form.
The system dependent form for the ST's monochrome mode is very
simple: it is identical to the standard form! This occurs because the
ST uses a "reverse-video" setup in monochrome mode, with the
background set to white.
The video organization of the ST's color modes is more complicated.
It uses an "interleaved plane" system to store the bits which make up
a pixel. In the low-resolution mode, every four words define the
values of 16 pixels. The high-order bits of the four words are merged
to form the left-most pixel, followed by the next lower bit of each
word, and so on. This method is called interleaving because the
usually separate color planes described above have been shuffled
together in memory.
The organization of the ST's medium-resolution mode is similar to
low-res, except the only two words are taken at a time. These are
merged to create the two bits needed to address four colors.
You should note that the actual color produced by a particular
pixel value is NOT fixed. The ST uses a color remapping system called
a palette. The pixel value in memory is used to address a hardware
register in the palette which contains the actual RGB levels to be
sent to the display. Programs may set the palette registers with BIOS
calls, or the user may alter its settings with the Control Panel desk
accessory. Generally, palette zero (background) is left as white, and
the highest numbered palette is black.
EVEN-WORD VS. FRINGES
A form always begins on a word boundary, and is always stored with
an integral number of words per row. However, it is possible to use
only a portion of the final word. This partial word is called a
"fringe". If, for instance, you had a form 40 pixels wide, it would
be stored with four words per row: three whole words, and one word
with the eight pixel fringe in its upper byte.
MFDBs
Now we can intelligently define the elements of the MFDB. Its
exact C structure definition will be found in the download. The
fd_nplanes entry determines the color scheme: a value of one is
monochrome, more than one denotes a color form. If fd_stand is zero,
then the form is device-specific, otherwise it is in standard format.
The fd_w and fd_h fields contain the pixel width and height of the
form respectively. Fd_wdwidth is the width of a row in words. If
fd_w is not exactly equal to sixteen times fd_wdwidth, then the form
has a fringe.
Finally, fd_addr is the 32-bit memory address of the form itself.
Zero is a special value for fd_addr. It denotes that this MFDB is for
the video memory itself. In this case, the VDI substitutes the actual
address of the screen, and it ignores ALL of the other parameters.
They are replaced with the size of the whole screen and number of
planes in the current mode, and the form is (of course) in
device-specific format.
This implies that any MFDB which points at the screen can only
address the entire screen. This is not a problem, however, since the
the VDI raster calls allow you to select a rectangular region within
the form. (A note to advanced programmers: If this situation is
annoying, you can retrieve the address of the ST's video area from low
memory, add an appropriate offset, and substitute it into the MFDB
yourself to address a portion of the screen.)
LET'S OPERATE
Now we can look at the VDI raster operations themselves. There are
actually three: transform form, copy raster opaque, and copy raster
transparent. Both copy raster functions can perform a variety of
logic operatoins during the copy.
TRANSFORM FORM
The purpose of this operation is to change the format of a form:
from standard to device-specific, or vice-versa. The calling sequence
is:
vr_trnfm(vdi_handle,source,dest);
where source and dest are each pointers to MFDBs. They ARE allowed to
be the same. Transform form checks the fd_stand flag in the source
MFDB, toggles it and writes it into the destination MFDB after
rewriting the form itself. Note that transform form CANNOT change the
number of color planes in a form: fd_nplanes must be identical in the
two MFDBs.
If you are writing an application to run on the ST only, you will
probably be able to avoid transform form entirely. Images and icons
are stored within resources as standard forms, but since they are
monochrome, they will work "as is" with the ST.
If you may want to move your program or picture files to another
GEM system, then you will need transform form. Screen images can be
transformed to standard format and stored to disk. Another system
with the same number of color planes could the read the files, and
transform the image to ITS internal format with transform form.
A GEM application which will be moved to other systems needs to
contain code to transform the images and icons within its resource,
since standard and device-specific formats will not always coincide.
If you are in this situation, you will find several utilities in
the download which you can use to transform G_ICON and G_IMAGE
objects. There is also a routine which may be used with map_tree()
from the last column in order to transform all of the images and icons
in a resource tree at once.
COPY RASTER OPAQUE
This operation copies all or part of the source form into the
destination form. Both the source and destination forms must be in
device-specific form. Copy raster opaque is for moving information
between "like" forms, that is, it can copy from monochrome to
monochrome, or between color forms with the same number of planes.
The calling format is:
vro_cpyfm(vdi_handle, mode, pxy, source, dest);
As above, the source and dest parameters are pointers to MFDBs
(which in turn point to the actual forms). The two MFDBs may point to
memory areas which overlap. In this case, the VDI will perform the
move in a non-destructive order. Mode determines how the pixel values
in the source and destination areas will be combined. I will discuss
it separately later on.
The pxy parameter is a pointer to an eight-word integer array.
This array defines the area within each form which will be affected.
Pxy[0] and pxy[1] contain, respectively, the X and Y coordinates of
the upper left corner of the source rectangle. These are given as
positive pixel displacements from the upper left of the form. Pxy[2]
and pxy[3] contain the X and Y displacements for the lower right of
the source rectangle.
Pxy[4] through pxy[7] contain the destination rectangle in the same
format. Normally, the destination and source should be the same size.
If not, the size given for the source rules, and the whole are is
transferred beginning at the upper left given for the destination.
This all sounds complex, but is quite simple in many cases.
Consider an example where you want to move a 32 by 32 pixel area from
one part of the display to another. You would need to allocate only
one MFDB, with a zero in the fd_addr field. The VDI will take care of
counting color planes and so on. The upper left raster coordinates of
the source and destination rectangles go into pxy[0], pxy[1] and
pxy[4], pxy[5] respectively. You add 32 to each of these values and
insert the results in the corresponding lower right entries, then make
the copy call using the same MFDB for both source and destination.
The VDI takes care of any overlaps.
COPY RASTER TRANSPARENT
This operation is used for copying from a monochrome form to a
color form. It is called transparent because it "writes through" to
all of the color planes. Again, the forms need to be in
device-specific form. The calling format is:
vrt_cpyfm(vdi_handle, mode, pxy, source, dest, color);
All of the parameters are the same as copy opaque, except that
color has been added. Color is a pointer to a two word integer array.
Color[0] contains the color index which will be used when a one
appears in the source form, and color[1] contains the index for use
when a zero occurs.
Incidentally, copy transparent is used by the AES to draw G_ICONs
and G_IMAGEs onto the screen. This explains why you do not need to
convert them to color forms yourself.
(A note for advanced VDI programmers: The pxy parameter in both
copy opaque and transparent may be given in normalized device
coordinates (NDC) if the workstation associated with vdi_handle was
opened for NDC work.)
THE MODE PARAMETER
The mode variable used in both of the copy functions is an integer
with a value between zero and fifteen. It is used to select how the
copy function will merge the pixel values of the source and
destination forms. The complete table of functions is given in the
download. Since a number of these are of obscure or questionable
usefulness, I will only discuss the most commonly used modes.
REPLACE MODE
A mode of 3 results in a straight-forward copy: every destination
pixel is replaced with the corresponding source form value.
ERASE MODE
A mode value of 4 will erase every destination pixel which
corresponds to a one in the source form. (This mode corresponds to
the "eraser" in a Paint program.) A mode value of 1 will erase every
destination pixel which DOES NOT correspond to a one in the source.
XOR MODE
A mode value of 6 will cause the destination pixel to be toggled if
the corresponding source bit is a one. This operation is invertable,
that is, executing it again will reverse the effects. For this reason
it is often used for "software sprites" which must be shown and then
removed from the screens. There are some problems with this in color
operations, though - see below.
TRANSPARENT MODE
Don't confuse this term with the copy transparent function itself.
In this case it simply means that ONLY those destination pixels
corresponding with ones in the source form will be modified by the
operation. If a copy transparent is being performed, the value of
color[0] is substituted for each one bit in the source form. A mode
value of 7 selects transparent mode.
REVERSE TRANSPARENT MODE
This is like transparent mode except that only those destination
pixels corresponding to source ZEROS are modified. In a copy
transparent, the value of color[1] is substituted for each zero bit.
Mode 13 selects reverse transparent.
THE PROBLEM OF COLOR
I have discussed the various modes as if they deal with one and
zero pixel values only. This is exactly true when both forms are
monochrome, but is more complex when one or both are color forms.
When both forms are color, indicating that a copy opaque is being
performed, then the color planes are combined bit-by-bit using the
rule for that mode. That is, for each corresponding source and
destination pixel, the VDI extracts the top order bits and processes
them, then operates on the next lower bit, and so on, stuffing each
bit back into the destination form as the copy progresses. For
example, an XOR operation on pixels valued 7 and 10 would result in a
pixel value of 13.
In the case of a copy transparent, the situation is more complex.
The source form consists of one plane, and the destination form has
two or more. In order to match these up, the color[] array is used.
Whenever a one pixel is found, the value of color[0] is extracted and
used in the bit-by-bit merge process described in the last paragraph.
When a zero is found, the value of color[1] is merged into the
destination form.
As you can probably see, a raster copy using a mode which combines
the source and destination can be quite complex when color planes are
used! The situation is compounded on the ST, since the actual color
values may be remapped by the palette at any time. In many cases,
just using black and white in color[] may achieve the effects you
desire. If need to use full color, experimentation is the best guide
to what looks good on the screen and what is garish or illegible.
OPTIMIZING RASTER OPERATIONS
Because the VDI raster functions are extremely generalized, they
are also slower than hand-coded screen drivers which you might write
for your own special cases. If you want to speed up your
application's raster operations without writing assembly language
drivers, the following hints will help you increase the VDI's
performance.
AVOID MERGED COPIES
These are copy modes, such as XOR, which require that words be read
from the destination form. This extra memory access increases the
running time by up to fifty percent.
MOVE TO CORRESPONDING PIXELS
The bit position within a word of the destination rectangle should
correspond with the bit position of the source rectangle's left edge.
For instance, if the source's left edge is one pixel in, then the
destination's edge could be at one, seventeen, thirty-three, and so.
Copies which do not obey this rule force the VDI to shift each word of
the form as it is moved.
AVOID FRINGES
Put the left edge of the source and destination rectangles on an
even word boundary, and make their widths even multiples of sixteen.
The VDI then does not have to load and modify partial words within the
destination forms.
USE ANOTHER METHOD
Sometimes a raster operation is not the fastest way to accomplish
your task. For instance, filling a rectangle with zeros or ones may
be accomplished by using raster copy modes zero and fifteen, but it is
faster to use the VDI v_bar function instead. Likewise, inverting an
area on the screen may be done more quickly with v_bar by using BLACK
in XOR mode. Unfortunately, v_bar cannot affect memory which is not
in the video map, so these alternatives do not always work.
FEEDBACK RESULTS
The results of the poll on keeping or dropping the use of
portability macros are in. By a slim margin, you have voted to keep
them. The vote was close enough that in future columns I will try to
include ST-only versions of routines which make heavy use of the
macros. C purists and dedicated Atarians may then use the alternate
code.
THE NEXT QUESTION
This time I'd like to ask you to drop by the Feedback Section and
tell me whether the technical level of the columns has been:
A) Too hard! Who do you think we are, anyway?
B) Too easy! Don't underestimate Atarians.
C) About right, on the average.
If you have the time, it would also help to know a little about
your background, for instance, whether you are a professional
programmer, how long you have been computing, if you owned an 8-bit
Atari, and so on.
COMING UP SOON
The next column will deal with GEM menus: How they are constructed,
how to decipher menu messages, and how to change menu entries at
run-time. The following issue will contain more feedback response,
and a discussion on designing user interfaces for GEM programs.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MFDB Structure <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/* Memory Form Definition Block */
typedef struct fdbstr
{
long fd_addr; /* Form address */
int fd_w; /* Form width in pixels */
int fd_h; /* Form height in pixels */
int fd_wdwidth; /* Form width in memory words */
int fd_stand; /* Standard form flag */
int fd_nplanes; /* Number of color planes */
int fd_r1; /* Dummy locations: */
int fd_r2; /* reserved for future use */
int fd_r3;
} MFDB;
>>>>>>>>>>>>>>>>>>>>>>> Resource Transform Utilities <<<<<<<<<<<<<<<<<<<<<
/*------------------------------*/
/* vdi_fix */
/*------------------------------*/
VOID
vdi_fix(pfd, theaddr, wb, h) /* This routine loads the MFDB */
MFDB *pfd; /* Input values are the MFDB's */
LONG theaddr; /* address, the form's address, */
WORD wb, h; /* the form's width in bytes, */
{ /* and the height in pixels */
pfd->fww = wb >> 1;
pfd->fwp = wb << 3;
pfd->fh = h;
pfd->np = 1; /* Monochrome assumed */
pfd->mp = theaddr;
}
/*------------------------------*/
/* vdi_trans */
/*------------------------------*/
WORD
vdi_trans(saddr, swb, daddr, dwb, h) /* Transform the standard form */
LONG saddr; /* pointed at by saddr and */
UWORD swb; /* store in the form at daddr */
LONG daddr; /* Byte widths and pixel height */
UWORD dwb; /* are given */
UWORD h;
{
MFDB src, dst; /* These are on-the-fly MFDBs */
vdi_fix(&src, saddr, swb, h); /* Load the source MFDB */
src.ff = TRUE; /* Set it's std form flag */
vdi_fix(&dst, daddr, dwb, h); /* Load the destination MFDB */
dst.ff = FALSE; /* Clear the std flag */
vr_trnfm(vdi_handle, &src, &dst ); /* Call the VDI */
}
/*------------------------------*/
/* trans_bitblk */
/*------------------------------*/
VOID
trans_bitblk(obspec) /* Transform the image belonging */
LONG obspec; /* to the bitblk pointed to by */
{ /* obspec. This routine may also */
LONG taddr; /* be used with free images */
WORD wb, hl;
if ( (taddr = LLGET(BI_PDATA(obspec))) == -1L)
return; /* Get and validate image address */
wb = LWGET(BI_WB(obspec)); /* Extract image dimensions */
hl = LWGET(BI_HL(obspec));
vdi_trans(taddr, wb, taddr, wb, hl); /* Perform a transform */
} /* in place */
/*------------------------------*/
/* trans_obj */
/*------------------------------*/
VOID
trans_obj(tree, obj) /* Examine the input object. If */
LONG tree; /* it is an icon or image, trans- */
WORD obj; /* form the associated raster */
{ /* forms in place. */
WORD type, wb, hl; /* This routine may be used with */
LONG taddr, obspec; /* map_tree() to transform an */
/* entire resource tree */
type = LLOBT(LWGET(OB_TYPE(obj))); /* Load object type */
if ( (obspec = LLGET(OB_SPEC(obj))) == -1L) /* Load and check */
return (TRUE); /* ob_spec pointer */
switch (type) {
case G_IMAGE:
trans_bitblk(obspec); /* Transform image */
return (TRUE);
case G_ICON: /* Load icon size */
hl = LWGET(IB_HICON(obspec));
wb = (LWGET(IB_WICON(obspec)) + 7) >> 3;
/* Transform data */
if ( (taddr = LLGET(IB_PDATA(obspec))) != -1L)
vdi_trans(taddr, wb, taddr, wb, hl);
/* Transform mask */
if ( (taddr = LLGET(IB_PMASK(obspec))) != -1L)
vdi_trans(taddr, wb, taddr, wb, hl);
return (TRUE);
default:
return (TRUE);
}
}
>>>>>>>>>>>>>>>>>>> Macro definitions for the code above <<<<<<<<<<<<<<<<<<
#define BI_PDATA(x) (x)
#define BI_WB(x) (x + 4)
#define BI_HL(x) (x + 6)
#define OB_TYPE(x) (tree + (x) * sizeof(OBJECT) + 6)
#define OB_SPEC(x) (tree + (x) * sizeof(OBJECT) + 12)
#define IB_PMASK(x) (x)
#define IB_PDATA(x) (x + 4)
#define IB_WICON(x) (x + 22)
#define IB_HICON(x) (x + 24)
>>>>>>>>>>>>>>>>>>>>>>>>>>> VDI Copy Mode Table <<<<<<<<<<<<<<<<<<<<<<<<<<<<
Symbols: N = new destination pixel value (0 or 1)
D = old destination pixel value (0 or 1)
S = source pixel value (0 or 1)
~ = Boolean not (inversion)
& = Boolean and
| = Boolean or
^ = Boolean xor (exclusive-or)
Mode Number Action
----------- ------
0 N = 0 (USE V_BAR INSTEAD)
1 N = S & D
2 N = S & ~D
3 N = S (REPLACE)
4 N = ~S & D (ERASE)
5 N = D (USELESS)
6 N = S ^ D (XOR)
7 N = S | D (TRANSPARENT)
8 N = ~ (S | D)
9 N = ~ (S ^ D)
10 N = ~D (USE V_BAR INSTEAD)
11 N = S | ~D
12 N = ~S
13 N = ~S | D (REVERSE TRANSPARENT)
14 N = ~ (S & D)
15 N = 1 (USE V_BAR INSTEAD)
>>>>>>>>>>>>>>>>>>>>>>>>>>> END OF DOWNLOAD <<<<<<<<<<<<<<<<<<<<<<<<<<<<<