BY SAMUEL STREEPER
|AT A GLANCE|
The blitter functions offer the programmer a convenient way to move and manipulate graphic data. These functions are built into GEM on every ST, so the following programming techniques work on every ST. Additionally, Megas have a graphics-accelerator chip, known as the blitter chip. If you take advantage of the blitter routines when writing your program, it will run much faster on a blitter-chip machine.
What Are The Blitter Routines?
The blitter routines move or combine rectangular blocks of data from one area of memory to another. Common blitter applications include scrolling the screen or the contents of a window, and animation. What makes the blitter routines so useful is they just as easily scroll a region horizontally or diagonally as up or down; all you need to change are the corners of the destination rectangle.
Note the term "rectangular" in the preceding paragraph. Although 32,000 bytes of contiguous memory (think of it as a line 32,000 bytes long) is needed to store a typical ST screen, when it comes to graphics it is much more convenient to deal with screen memory as a 640x400 pixel (or 640x200 or 320x200) rectangular region.
|By setting up the MFDB, predefined bitmaps,
like this DEGAS picture file, can become the
In order to use the blitter functions you must describe the area of memory that stores information about the rectangular region (the blit's source) and the area of memory that stores information about the rectangular region (the blit's destination). That description--starting address, length in words, size of region in pixels, number of bitplanes--is called a memory form definition block, or MFDB. The major advantage of using an MFDB is that your program will be able to blit correctly in any screen resolution.
If both the source and destination rectangle are the same, only one MFDB is necessary. This occurs frequently; often the screen serves as source and destination. Fortunately, TOS keeps track of the screen in memory, and both C and GFA BASIC provide built-in functions to help you create access the screen's MFDB information.
If you wish to blit a predefined bitmap, like a DEGAS picture file, you will need to set up its MFDB yourself since there isn't a built-in function to help you. These MFDBs are usually hardcoded. The information you need can be found within the specifications of the picture file. For example, DEGAS low-resolution pictures are 320x200 pixels with four bitplanes. That information gives you four of the five MFDB parameters. Since you must allocate a region of memory and read in the DEGAS picture, you know the fifth parameter, the starting address, is the same as the address of the first byte of the storage array.
To blit you also must set up an array of eight integers describing the subregion within the source rectangle which is to be moved and the subregion within the destination rectangle to which to move it. These subregions are measured relative to the boundaries of the rectangular region defined by the MFDB; (0, 0) is the upper righthand corner of the rectangle. Make sure the array values are positive and contained within the rectangle; unpredictable results will occur if the blitter routines are requested to blit outside the rectangle.
The Generic Algorithm
Any blitter program you write will follow this general algorithm:
1) define variables for the source and destination MFDB, and the subregion array;
2) (screen only) call the built-in routine to open a virtual workstation, which allows access to the parameters needed by the MFDB;
3) set up the MFDBS. In the general case, set up two--one each for the source and destination rectangle. Only one is needed if the source and destination are the same;
4) calculate the displacement of the blit and fill in the subregion array;
5) choose a write mode describing how the source and destination subregions will be combined;
6) call a built-in routine to do the blit.
On your START disk are two examples that demonstrate the algorithm above. These two demos, EX1GFA.PRG and EXAMPLE1.PRG, in GFA BASIC 3.0 and C respectively, move the letter A horizontally, vertically and diagonally, in five-pixel increments. To run the demos double-click on the archive file BLITTER1.PRG and choose Extract when the dialog box appears. Select a destination disk and the files will un-ARC directly onto that disk. The programs run in high or medium resolution.
The complete source code to these examples can be found in the files EXAMPLE1.C and EX1GFA.LST.
Let's analyze the examples. The C code declares the variable screen to be of type MFDB, which is a memory form definition block and is defined in the header file GEMDEFS.H. In GFA BASIC we use an array of long integers for the same function, hence the line DIM screen%(8).
Corners is an array of eight integers describing the subregions to blit from and to within the source and destination rectangles. The integers represent, in order: x and y coordinates for the upper left corner of the source region, x and y coordinates for the lower right corner of the source region, x and y coordinates for the upper left corner of the destination region, x and y coordinates for the lower right corner of the destination region.
In C, we pass the blitter call the variable write_mode which tells GEM how to combine the source and destination graphic blocks. In GFA BASIC, we do the same thing by putting write_mode as the ninth element in the corners array. Since we start counting at zero, the ninth element is corners%(8).
We set write_mode to three because we just wanted to move the source area to the destination, overwriting the previous contents of the destination. There are 16 available write modes, which are listed in the sidebar.
Finally, before we blit we must set up the memory form definition block for the screen. Make the call to init_mfdb( ) immediately after you open a virtual workstation to the screen. In C call v_opnvwk( ) to open a virtual workstation; in GFA BASIC 3.0 call ~V_OPNVWK(1).
And Now, The Main Event
You have seen how easy it is to use the blitter function to scroll an area of the screen. This month's main example program SBLIT.PRG loads a DEGAS-format picture into a buffer, and then opens a GEM window and blits the picture from the background buffer to the window on the screen. It demonstrates the use of the blitter in response to GEM messages for window drawing and redrawing.
Furthermore, it makes a good skeleton program for your own applications because it runs as either a desk accessory or a program, and it works properly on large-screen monitors. If SBLIT is run as a program, a menu item lets you select a background picture. Two are provided on disk, SBLIT.PI2 and SBLIT.PI3.
If it is run as a desk accessory, holding down [Left Shift] while selecting its menu item will pop up an information box that will let you load a picture. Otherwise, it searches for the default picture file SBLIT.PIx in the root folder. To install SBLIT as a desk accessory, rename SBLIT.PRG to SBLIT.ACC, copy SBLIT.ACC to the root directory of your disk, then reboot your computer. Warning: The desk accessory version of SBLIT interferes with nonstandard GEM programs like WordPerfect and Hotwire.
(To find out more about writing applications that can be run as either programs or desk accessories, read my Programming In C column "Accessorize Your Programs" in the October 1989 issue of START.)
A Blitter Bonus!
Some Macintosh computers replace the corner Desk menu choice with a revolving globe. I decided to do something similar with the SBLIT program. If you run it as a program, the corner Atari icon will periodically spin 360 degrees. It's a neat effect, and it hints at the next installment of Programming the Blitter, which demonstrates animation within a GEM window. Until then, happy coding!
Samuel Streeper is an Atari network developer who lives in San Luis Obispo, Calif. He wrote the dual-purpose program/accessory lesson in the October 1989 issue of START.