PROGRAMMING THE BLITTER
BY SAMUEL STREEPER
In last month's "Beginning Blitter" I discussed basic GEM blitter routines, then used them to display a bitmapped DEGAS picture within a GEM window. This month I'll carry the same idea a few steps further, using the blitter to do flicker-free animation within a window.
With single buffered animation, the user views the erasure of the old image and the construction of the new, and the result is a distracting flickering effect. In order to provide smooth animation, a trick known as double buffering is often used.
Double buffering means constructing the next animation frame in a buffer not visible to the user, and then switching quickly to the new frame, thus maintaining the illusion of motion. The blitter routines give the last switching speed needed for this trick.
Boink With A Twist
On this month's START disk is SBOINK, a variation on the classic bouncing ball theme. SBOINK uses double buffering to achieve its flicker-free animation. You'll find it useful to view the program and follow the code as I discuss double buffering in more detail.
To view SBOINK, double-click on the archive file BLITTER2.PRG and choose Extract when the dialog box appears. Select a destination disk and the files will be un-ARCed directly onto that disk. Make sure that BOINK.IM2, BOINK.IM3, BOINK.PI2 and BOINK.PI3 are in the same folder as SBOINK.PRG. To start the program, double-click on SBOINK.PRG. The C code which produced it is found in SBOINK.C.
|SBOINK loads animated graphics directly over
In SBOINK the ball bounces within the confines of a GEM window, which constantly displays the time and free memory, and allows you to change the screen colors and enable or disable the blitter chip, if present. Furthermore, SBOINK is a complete GEM application which runs either as a program or a desk accessory simply by changing its extension from .PRG to .ACC and rebooting. (See "Accessorize Your Programs" in the October 1989 issue of START.) When run as a desk accessory, the ball continues to bounce even as you perform tasks in other windows, such as typing into your word processor.
Double Buffered Animation
SBOINK maintains three off-screen graphic buffers. The first buffer, the background buffer, contains a DEGAS picture which serves as the bouncing ball's backdrop. This buffer also is used to construct the next animation frame off screen.
The second buffer, the ball array buffer, contains a bit image of the ball in six stages of rotation, plus a mask for the ball's shadow effect.
The third buffer, the save area, is used to store the region of the background buffer overlaid by the ball. I use the contents of the save area to restore the background buffer to its original state before constructing the next animation frame.
The SBOINK animation sequence is a five step process, and uses the blitter routines to move graphic blocks around.
Step 1: Blit from the save area to the background buffer, thus restoring the background buffer to its original state and erasing the last image of the ball.
Step 2: Calculate the next position of the ball and store in the save area the portion of the background buffer that will be overwritten by the ball.
Step 3: Blit the ball's mask from the ball array into the background buffer, using the blitter's logical OR mode (see "Beginning Blitter" in the August 1990 issue of START). This puts a black circle in the picture where the ball will go, as well as a 50 percent black pattern that simulates the ball's shadow.
Step 4: Select the next ball image from the rotation-simulation series stored in the ball array. Blit it into the black void left by the mask. The background buffer is now complete and ready to blit to the screen. Note that all the work we have done so far has been in off-screen buffers, invisible to the user!
Step 5: Present the user with the results of our animation. Calculate the smallest rectangular region which contains both the old and new positions of the ball. Blit this region from the background buffer to our window's position in screen memory, clipped to our window's rectangle list. Because the old ball is erased on screen at the same time the new ball is drawn, the animation is smooth and flicker free.
The GFA BASIC Example
The file BOINKGFA.LST demonstrates how to animate our bouncing ball using GFA BASIC 3.0. View the bouncing ball by double-clicking on BOINKGFA.PRG; first make sure BOINK.IM2, BOINK.IM3, BOINK.PI2 and BOINK.PI3 are in its folder. Instead of running in a GEM window, this example uses an animation technique known as page flipping, which is frequently used for programming games.
Page flipping cannot be used by GEM programs because several programs share the screen, each assuming that the area used for screen memory has not been changed. Page flipping, however, is the best technique for high-speed flicker-free animations. It requires the following steps.
Step 1: Reserve 322256 bytes of memory, the storage size for a normal screen. This is your second screen "page."
Step 2: Construct an image in the second screen "page." Since this area is not being displayed, the user does not see your image while it is under construction.
Step 3: Wait for a vertical trace interrupt so you don't switch screen "pages" until the complete screen will be drawn from top to bottom.
Step 4: Switch to the second screen "page." The user is now viewing the second screen "page," so clear the appropriate memory area of the now-hidden first screen "page" and construct your next animation frame by repeating steps 2 through 4.
Program vs. Accessory
The program version of SBOINK has a menu option to load a different background picture, but desk accessories cannot have menubars. Consequently, I duplicated the picture load function in a button in the desk accessory's information dialog box, activated by holding down [Left Shift] while selecting the SBOINK desk accessory entry. Since that function is redundant for the program version, the program modifies its information dialog box, hiding the button by modifying the button's object flags using dial [DIALLOAD].ob_flags = (LASTOB | HIDETREE).
One Last Trick...
Besides being a useful programming demonstration, I intended SBOINK to show the speedup effects of Atari's legendary blitter-chip hardware versus the standard GEM blitter-software routines. SBOINK is a perfect test vehicle for such an example because it moves around lots of graphics data.
If your machine has a blitter chip installed, SBOINK presents a vertical scroll bar that allows you to enable and disable the blitter chip. Try it and you will see that the blitter chip speeds up graphics operations significantly. The speedup you see, however, does not fully reflect the true speedup caused by the blitter chip. To understand why you first must understand the multi-windowing nature of GEM.
Whenever a GEM AES-function call is made (including evnt_multi( ) and vro_copyfm( )) the GEM task dispatcher switches control to a task (program or desk accessory) in another window. While this is fine, indeed necessary, for a well-behaved GEM application, it is not ideal for the ultimate high-speed graphics demonstration because a certain amount of the computer's processing power is given to other tasks.
What I wanted was a way to optionally devote all the computer's power to running SBOINK, giving the blitter chip a chance to strut its stuff. But how to blit without calling the AES blitter function? The answer is to go straight to the lowest-level graphics call, the line-a blitter function (which is what the AES does, after running the task dispatcher).
On your START disk is a file called SVRO.C. This file has a replacement binding for the vro_copyfm( ) library function call, and this binding sets up the line-a variables without invoking the AES. Its use is transparent. If you link with the file SVRO.O, you will get the fast binding; otherwise you get the standard AES binding. In any case, you don't have to change your source code.
There are a few other advantages. AES just sets up the line-a variables anyway, and I do it almost three times as fast. Also, a virtual workstation handle is not required, so the blit works whether or not you have a valid workstation handle.
If you run SBOINK as a program and select Fast Mode from the menu, the special binding will make SBOINK blit as fast as possible. If you have a blitter chip, you will see that the blitter chip can move graphics around faster than even pure 68000 assembly code, and blitter users get this benefit without any changes to code! The difference between the normal speed and fast mode is the overhead incurred by GEM's task dispatcher and other GEM tasks.
Watch for "Advanced Blitter" next month!
Atari network developer Samuel Streeper recently moved to Palo Alto, Calif, where he works for NeXT. His "Programming the Blitter" series began in the August 1990 issue.