Adding High Speed Vertical Positioning To P/M Graphics
David H. Markley
By now many of you have been playing the "Aliens from Outer Space" program I described in COMPUTE! # 11, and have been able to experiment with an actual game program incorporating the advanced player/missile graphics of the Atari computer. As you may have observed, player images can be moved horizontally across the playfield quite easily just by placing the player's horizontal coordinate (0-120) into its associated horizontal position register. Vertical positioning with the P/M graphics however is somewhat more difficult. Since the player's vertical position on the playfield inversely corresponds to its position within the image buffer, it is necessary to relocate each byte of the image up or down within the buffer to produce vertical movement. For example, if we move the player's image to higher address locations within the image buffer, the player will appear to move downward on the playfield.
A BASIC routine can be written using PEEKs and POKEs to move the player within the image buffer, but for most applications this method is too slow. An alternative, however, is to use a small, general purpose vertical positioning routine written in 6502 assembly code which can be called by BASIC's USR instruction.
The vertical positioning routine shown in Program 1 is relatively simple, but provides the user with a flexible and easy method of handling P/M graphics within a BASIC program. This program not only provides a valuable tool to use with player missile graphics, but for those of you who have not used assembly language routines with BASIC, it will provide some insight into this area as well. The routine is called by a BASIC statement similar to below:
DUMMY = USR (VP,IMAGE,LAST LOCATION, NEW LOCATION)
The variable to the left of the equal sign called "DUMMY" is used by some machine language subroutines as a target for a value returned by the program. The vertical positioning routine however, does not return a usable value, but the DUMMY variable is still required to satisfy Atari's USR format requirements. Within the parentheses of the command are four arguments. The first argument, VP, is the transfer address to the VP routine which has been placed into a free area of memory. Loading of the VP routine into memory will be described later with a program application example. Following the transfer address argument (which, by the way, is also required for any USR routine called by BASIC) are three arguments which are passed to the VP routine.
These arguments are the address of the image's data structure, the address of the image's current position in the P/M image buffers, and the address of its new position. Each image requires a small data structure which provides the VP routine with a pattern of the actual image which it will vertically reposition. An example of a typical image data structure is shown in Figure 1. The first byte of data provides the VP routine with the image's size in bytes. The second and following bytes are used to form a bit map pattern of the image as it would appear in the P/M image buffers.
The next two arguments contained in the USR command tell the VP routine the image's current and new positions. These arguments are actual memory addresses into the image buffers, therefore care must be taken to assure that they do not access another area of memory by mistake.
The program operation begins with an initialization step in which the three arguments passed to it by the USR command are removed from the processor's stack and placed into an area in page zero where they can be more easily used. You may have noticed that a total of seven bytes are popped off the stack during this operation. This is because the USR command always places a one byte argument count onto the stack followed by the arguments themselves. The arguments are always two bytes in length.
Once the initialization task is complete, the routine is ready to begin its intended task of moving the player image. Basically the operation is performed in two steps. The image data is first removed from its current location and then copied to its new location. Before either step can be executed, the routine must first look at the image's data structure and get the image size parameter. This value tells the routine how large an image it must handle and thus determines the number of bytes it must remove and restore. To remove an image from its current location, the routine simply goes to the current location address and writes zeroes into an X number of memory locations indicated by the size parameter. Replacement of the image is done by copying from the image's data structure an X number of bytes, also determined by the size parameter, to the image buffer starting at the address specified by the new position argument.
In some cases it may not be desirable to have the VP routine perform both the delete and restore functions. One example would be if the player image is to be removed from the viewing field and not restored at a new location. This can be handled by using the following routine call:
DUMMY = USR(VP,IMAGE,CURRENT LOCATIONS,0)
The zero in the new location field tells the VP routine not to attempt to restore the image. Likewise, the delete function can be disabled by placing a zero in the current location field.
Let's Have Some Fun
Now that we have looked at the Player/Missile Vertical Positioner routine, let's put it to work. The following game will show you how to load the player images and VP routine into memory and how to use the routine in other way besides vertical positioning.
This game which I call "Island Jumper" involves the cooperation of two characters named Crash Coleman and Deadeye Dan. Crash is the pilot of a reliable (but not so stable) airplane, the "Leaping Lucy." Crach has only had one flying lesson, but has courageously volunteered to make this flight so that you can see the VP routine in action. Although he has successfully managed to get the Leaping Lucy off the ground, he seems to be having some trouble keeping her in level flight. Our other daredevil of the sky, Deadeye Dan, will attempt, with your help, to jump out of Crash's airplane and land on Target Island. Since the ground seems to be a bit unstable from Dan's point of view, he is having difficulty figuring out when to jump and asks that you help him by pulling back on your joystick controller when you think he's on target.
Dan will make a total of five jumps each time you play the game. He will try to land on top of a sand dune located on the left side of the island. If he makes the jump on Crash's first pass over the island and lands on the dune with both feet, you get 30 points. If you don't give Dan the signal to jump during the first pass, Crash will continue to fly over the island until a jump is made. Each additional pass will deduct eight points from Dan's maximum obtainable score.
Dan can also land in the area between the sand dune and the palm tree, but you will only receive a maximum of 15 points for the jump. At the completion of the game, the computer will give you both a final score the last game played and the highest score for all games played since the last RUN command was entered. To play another game, press the button on the joystick controller.
The data for the VP routine and the player data structures is read from data statements and POKEd into memory by lines 110 thru 310 of the program. It is loaded into memory page 6 (starting at address 1536) which is a 256 byte area in memory that Atari has reserved for user binary data and machine language routines. Once the data structures and VP routine are loaded into memory, they are referenced in the BASIC program by variable names whose values have been set to the starting address of the data structure or VP routine they represent.Figure 1: Image Data Structure for the Player/Missile Vertical Positioner Routine.
|Image Pattern||Byte Number||Byte Value|