Classic Computer Magazine Archive ANTIC VOL. 3, NO. 6 / OCTOBER 1984


Player/Missile graphics tutorial


This article is an edited excerpt from the book Computer Animation Primer by David Fox and Mitchell Waite, copyright 1984, published by Byte Books/ McGraw Hill Book Co. and reproduced by permission.
   The BASIC program listing, which demonstrates the ideas discussed in the article, runs on all Atari computers of all memory configurations.  No joystick is needed. Antic Disk subscribers RUN"D:EXAMPLE8.BAS"

Atari's player/missile graphics use the special ANTIC and GTIA microchips to let you move animated figures anywhere on the video screen without disturbing the background.
   A "player" is actually a section of RAM that contains an eight-bit-wide vertical bar from top to bottom of the screen.  This vertical bar can be positioned horizontally anywhere across the screen.
   Players can be created in the shapes you choose, with the same programming techniques applicable to user-defined character sets.
   Atari computers can handle a total of four players and four missiles-each of which can be moved independently in a horizontal, vertical or diagonal direction.
   Missiles are two bits wide, while the players are eight bits wide.  Therefore, if you're designing a game that doesn't require missiles you can combine your eight available missile bits to create a fifth player.
   Let's explore the applications of Player/Missile (P/M) graphics using a bouncing ball program.  You will be able to enter the speed of the ball and its elasticity coefficient-how bouncy it will be.  The ball (made out of a player) will not only bounce, but will "squash" when it hits.
   We use GRAPHICS 3 even though P/M graphics works in any graphics mode.  You may wonder, "Why GRAPHICS 3? It has such coarse resolution." That is exactly why we chose it - coarse graphics means low memory overhead.  No Atari graphics mode uses less memory than GRAPHICS 3.
   There are three POKEs which must be executed to turn on P/M graphics: first POKE address 54279 with the memory page where P/M RAM begins.

   POKE 54279,PMPAGE

   Next, ANTIC microchip must be told that it should begin grabbing information from P/M memory.
   A POKE of 42 into 559 Will leave us with a normal screen, a two-line P/M display and an enabled Player direct memory access (DMA):

   POKE 559,42

   The third POKE gives ANTIC, the go ahead to begin sending player, missile information to the GTIA microchip for display on the screen.
   Player graphics are now enabled and ready to go.

Type in the BASIC listing at the end of this article.  It's called Example 8 because it's the eighth program in the book from which this article is excerpted.  Check it with TYPO, and SAVE an extra backup copy.  RUN the program, and you'll see a ball bouncing according the initial program values for velocity (speed) and elasticity.  When the ball has finished bouncing, you'll be prompted for a new velocity.  Type in any positive number.  Next, you're asked for a value for elasticity.  This value should normally be within the range zero to one, but if you use a value higher than one, each bounce of the ball will be higher than the one before.

First look at line 70.  This is where the first entry into the variable value table is made with string variable PLRO$.  This line must be entered before entering any other line containing variables or the program will not work properly.  Later, the location of the data for this variable will be moved to match the RAM for Player 0.
   The subroutine on lines 100-130 is called when the value of a 16-bit number, X, needs to be separated into high and low bytes.  This is necessary when the HIBYTE and/or LOBYTE will be put into memory address by a POKE.
   Lines 140-330 initialize the program's variables and send the computer off into four initializing subroutines.  On line 150, three variables are DIMensioned-BLANK$ will be used to clear a temporary player buffer; PLR(n) will hold the RAM address of the four players; and HPLR(n) will be set to the address of the horizontal position registers for the four players.
   On line 160, an Atari BASIC trick is used to fill BLANK$ with 128 ATASCII 0 (Atari ASCII) characters.  After the first and last characters of BLANK$ are initialized to CHR$(0), the magic begins with the statement:

                 |       |
  Destination string    source string

BASIC copies the first character of the source string into the second character of the destination string, then the second character of the source string into the third character of the destination string, and so on.  In this way, each character of the string will be copied from the earlier one until the string is filled!
   Line 170 sets the screen to GRAPHICS 3, turns off the cursor and PRINTs a message on the screen.  Lines 180-240 call some special subroutines that we will cover next.  Lines 300-320 PRINT information on the screen and set the initial VELocity (speed) and ELASTICity values.  By elasticity, we mean the percentage of the ball's current velocity which remains when it hits the ground.  An elasticity of 0.5 (50 percent) means that the ball maintains half its current velocity and loses the other half every time it bounces.  An elasticity of 1.0 (100 percent) is a perfect bouncing ball.  It never loses any energy and will bounce forever.  The closest to perfect we have seen in real life is about 0.85 (85 percent) for a toy super ball.  An elasticity of 0 (O percent) is a ball that will not bounce at all - it just hits the ground and dies.
   The subroutine (5000-5360) reserves memory space, in the form of strings for the frame data, (frame means a single screen picture, just like in a movie).  Line 5100 reads the number of frames used in the sequence (FRAMES=3), the size of each frame in bytes (FRMSIZE=7), and the number of players used in this program (NUMPLRS=1).  The data is located on line 20060.  On line 5120, the variable PLRFRMMEM (PLayeR FRaMe MEMory) is set to the total number of bytes necessary to store the frames for each player.  Line 5130 sets FRAMEMEM (FRAME MEMory) to the total number of frame bytes needed for all players.

On line 5170, string memory is reserved for three variables.  BUFFER$ is the temporary buffer used in vertical player movement.  FRAME$ will hold the current frame to be displayed and FRAMEMEM$ holds all frames for every player.
   In this section 7000-7130, memory is reserved for the players, and P/M graphics are enabled.
   Line 7020 tells ANTIC where to find PM RAM by placing the starting memory page number (TEMP) in 54279 (D407 Hex).  The actual RAM address of PM RAM is calculated and stored in PMBASE in line 7030.
   In lines 7040-7070, two arrays are initialized.  PLR(I) holds the RAM address for Players 0 through 3. HPLR(I) holds the address of the horizontal position register for each player.
   In line 7080, SDMCTL, address 559, is initialized and ANTIC begins DMA from player RAM.  A POKE of 42 into 559 leaves us with a normal screen, a two-line P/M display and enabled player DMA, but no missiles.
   In line 7100, ANTIC starts sending player information to GTLA so it can be displayed on the screen when POKED with a 2.
   In lines 9000-9080, BASIC is tricked into moving a string variable to coincide with Player 0 RAM.  In lines 9010-9020 the locations of the string array area and the variable value table are calculated.  In 9030 the number of bytes from the beginning to the string/ array area to the start of Player 0 RAM is stored in OFFSET.  Line 9040 uses the HI/LO byte subroutine on OFFSET so these values can be POKED into the variable value table and the first variable in the program is now relocated!
   The loop in lines 10000-10140 and 21000-21060 reads the frame data for the bouncing ball into the string FRAMEMEM$.  Each BYTE is converted to a character with CHR$.
   The main animation loop (lines 400-570) controls the movement of the ball on the screen.
   On line 410 four constants are initialized.  BOTTOM is the lowest vertical screen position to which the ball will go and is analogous to the floor.  XPOS is the starting horizontal position of the ball (off the xcreen to the left).  TIME holds the elapsed time from the moment the ball is launched or bounced.  HORIZ holds the horizontal velocity.  This value is constant until the ball begins to roll.
   The ball is moved to the left of the screen in line 420, and the value of ELASTIC is checked in 430.  Later, when input is accepted from the keyboard, this line makes sure that if the elasticity is very low, there is at least one bouncing noise when the ball hits the ground.

Starting at line 440 is the gravity calculation.  The effect gravity has on the motion of an object can be represented by the formula


This shows the acceleration of gravity over time.  By subtracting the above value from the current velocity (VEL) multiplied by TIME, the current height of the ball off the ground is obtained:


This must be subtracted from the value of the ground (BOTTOM) to convert the number to screen coordinates:


FRM0, the number of the current frame to be displayed, is set to 1 (the round ball).
   Line 460 checks for contact with the ground.  If the ball has hit, (YPOS will be greater than or equal to BOTTOM), the ball's VELocity is recalculated by multiplying the current VELocity by EIASTIC.  With the initial ELASTICity of 0.8, 80 percent of the current velocity will be conserved and 20 percent lost.  TIME is set to 0 since as far as gravity is concerned, the ball is first starting out and was thrown by the ground.
   Line 470 checks to see if the ball is still on the screen.  If not, the animation loop is exited, and new values can be entered from the routine starting at 600.
   Now that all the values are calculated, the ball will be positioned on the screen.  The horizontal position of the player is set in line 480.  On 490 the correct frame is transferred from FRAMEMEM$ (where all three frames are kept) to FRAME$.  Lines 500-520 position FRAME$ at the proper vertical position in player RAM.  The ball is now in place.
   In line 530, the horizontal position of the ball (XPOS) is incremented.  Line 540 turns on the bounce sound if the ball has just struck bottom and the velocity is high enough.  If SNDFLAG was set in line 430 (low elasticity), the sound will be heard on the first bounce.
   In line 550, TIME is incremented by 0.15 and the loop continues at line 440 if the velocity is greater than 0.5. A different value can be substituted for the 0.15 to stimulate the ball bouncing in slow or fast motion.  Use a smaller TIME increment to make the ball move in tinier increments (slow motion).
   Finally, line 560 will be reached if the velocity of the ball is so slow that it can only roll rather than bounce.  HORIZ is decremented to simulate the effect of friction on the ball's horizontal velocity.  If the ball is still rolling (HORIZ will be greater than 0), frame 1 is selected, and the program jumps to 470 since the bouncing calculations of 440-460 are no longer needed.  If the ball has stopped rolling, the program will fall through the routine at 600.
   Lines 600-690 are executed after every ball finishes bouncing to allow you to enter your own velocity and elasticity values.  The ball is moved off the screen in line 610.  The TRAP command is used in line 640 to trap any INPUT errors which may occur.  If there are any, the program will jump to line 630 and the values can be reentered.  In line 670, after executing the "cursor off" POKE, at least one PRINT statement must be executed before the cursor vanishes.  Line 680 turns off error trapping by setting TRAP to a nonexistent line number, and the animation loop is restarted.

Try the following modifications:

1. Experiment with different velocities and elasticities.  Try a velocity of 1 and a velocity greater than 1.0. Did you ever see the Walt Disney movie, The Absent-Minded Professor, which is about an amazing substance called Flubber?  This flying rubber gained velocity every time it bounced.

2. Change the constant (16) in the gravity equation (fine 440) to simulate a ball on a different planet with stronger or weaker gravity.

3. Modify the program so there is a ceiling as well as a floor off of which the ball can bounce.  Will the ball speed up if you use an elasticity greater than or equal to 1.0?

David Fox is the Lucasfilm computer games project leader who spearheaded Rescue On Fractalus for release on the Atari.  Mitchell Waite is president of the Waite Group Inc, which has produced over 30 books on personal computing.

Listing: EXAMPLE8.BAS Download