Outer Space Attack is an early Invaders game for the Atari published in SoftSide magazine. It’s noteworthy for being slightly modified and republished in ANTIC v.1, n.3, as Pac-Invaders without attribution. ANTIC issued an apology in the next issue.

SOFTSIDE #42 / MARCH 1982 / PAGE 65

Outer Space Attack

by Sheldon Leemon

Outer Space Attack is a real-time arcade game for ATARI® 400 or 800 computers. It requires 16K ROM (24K for disk), a joystick, and the BASIC cartridge.

For far too long ATARI® owners have been fed a diet of warmed-over software — programs originally developed for their microcomputer cousins and translated extremely literally for the ATARI®. Although a few Machine Language programs have appeared which take advantage of the graphics features of the ATARI®, BASIC programs which show off the brilliance of the machine are few and far between.

The program presented here is pure ATARI®. Sure, zillions of Invaders-type games have been written for microcomputers. But it is precisely because of its wide implementation that I chose this type of program to show off the power of ATARI® BASIC. On what other micro could you write any kind of a playable Invaders game in under 50 lines of BASIC? How about one that featured high-resolution graphics, seven colors on the screen at once, sound, and animation?

I don’t think we will see any takers for a BASIC translation of this program. No other computer has Player/Missile (PM) graphics, redefinable character sets, relocatable display memory, and the rest of the graphics goodies that come with the ATARI®.

Now, if I were able to do all of this with just a short BASIC program, think what you could do with a long, elaborate one. As more ATARI® owners become aware of these capabilities, we should see innovative, original software designed to utilize the full power of the machine. Until then, I hope you enjoy this newest additon to the Invaders horde.

Instructions

Unless you really have been stationed on a lunar defense base, little need be said about how the game is played: You have to shoot down all of the aliens before they get past the horizon (gray surface) and wipe out your planet. To do this, you maneuver your laser base left or right with a joystick in Port 1 and fire with the trigger button.

If you let one slip by, the game will end with the current invasion wave. If you manage to wipe out one wave, a new one will start as soon as the warning siren sounds. To make things worse, the alien menace shoots back, dropping bombs more and more frequently with each successive attack wave. If your laser base is bombed, it will be replaced by one of your two spares, but when they are gone, the game is over.

In the end, your little outpost is doomed. The best you can hope for is to make the aliens pay dearly with their losses (and maximize your score).

Variables

Numeric:
BF, SF
Flags which are set when a shell is travelling upwards or a bomb is travelling downwards.
COUNT, ATTACK
ATTACK holds the number of loop iterations which must pass before a bomb is dropped. COUNT keeps track of them, and is compared to ATTACK to see if it’s time to drop one yet.
D
Holds the direction value which tells whether the invaders are moving to the right or left.
DH, DL, L, H
DH and DL hold the location of the two-byte pointer to display memory. L and H hold the values contained in these locations. When new values are POKEd into the pointer, the computer thinks the display starts farther back in memory, and the whole display appears to move.
HITS, CHANCES, SCREENS, SCORE
HITS keeps track of the number of invaders downed on the current assault wave, while CHANCES counts the number of laser bases used up. Each time HITS increases, it adds to the SCORE. After all the invaders are hit, SCREENS is incremented and we start again.
HP, HPM, BVP, SVP
HP holds the horizontal position of the laser base, while HPM does the same thing for the missiles it fires. BVP keeps track of the vertical position of the bombs, and SVP does the same for the shells.
I, J, K
Loop variables. I and J control main program loop that moves the invaders across the screen, and then down at the end of a row.
RT
Holds the value of the top-of-RAM pointer. Used to create a safe storage area above the apparent top of memory.
TOUGH, TOUGHER
Offsets added to the joystick-checking loop. To increase the difficulty in later rounds, part of the loop is skipped. This moves your shells less often, which slows them down, and speeds up the invaders.
X, Y
Hold the x, y location of the invader hit by the last shell.
String:
D$, F$, PM$
These strings are dummies which contain no useful data. They are dimensioned to allow the strings which hold data for the ATARI® PM graphics system to begin on an even 1K boundary.
M$, P$, P1$, P2$
Contain the data for the Players and Missiles which display as the laser bases, bombs, and shells.
BL$
Contains all zeroes; used to clear out other strings.
BOMB$, SHELL$
Hold the shape data for the bombs and shells.
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$        ATARI BASIC         $
$    'OUTER SPACE ATTACK'    $
$   AUTHOR: Sheldon Leemon   $
$     (c) 1982 SoftSide      $
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
Lines 30-110: Check the joystick, and move the laser base, missiles, and bombs.
10 I=0:J=0:COUNT=0:ATTACK=0:GOSUB 280:GOTO 140
20 REM -OUTER SPACE ATTACK V.1 12/81
        By SHELDON LEEMON
        Oak Park, MI 48237
Check the collision register for Missile 0 to see if a missile has hit an invader. If it has, flow jumps to Line 210, where the hit is scored, the invader erased, and a check is done to see if the screen has been cleared.
30 Y=PEEK(53248):IF Y>0 THEN GOSUB 210
Check to see if the shell flag (SF) has been set. If it has, the missile is moved, and a check is done to see if it has gotten past the top row of invaders. If it has, the missile is erased and the flag is turned off. Line 50 then repeats the check of Line 30 to see if the motion of the missile has caused a collision.
40 IF SF=1 THEN SVP=SVP-4:M$(SVP)=SHELL$:POKE 53278,1:IF SVP-4*K<10 THEN M$(SVP,SVP+4)=BL$:SF=0
50 Y=PEEK(53248):IF Y>0 THEN GOSUB 210
Do the same kind of check as Line 40 does, only this time move the bomb. Line 70 checks for a collision between the bomb and the laser base.
60 IF BF=1 THEN BVP=BVP+3:M$(BVP)=BOMB$:IF BVP>102 THEN M$(BVP,BVP+5)=BL$:BF=0:BVP=20
70 IF PEEK(53259)=1 THEN 250
Determine whether or not to drop a bomb (by setting the flag BF). As more screens are cleared, fewer iterations of the loop will pass before a bomb is dropped, and they will fall more frequently. The position of the bomb is determined by the position of the laser base, so they can fall out of nowhere, rather than being dropped by a particular invader.
80 IF BF=0 AND COUNT>ATTACK AND K<16 THEN BF=1:POKE 53255,HP+3:BVP=14+4*K:COUNT=0
Check the joystick for right or left motion, and move the player appropriately. No checking is done to see that the player is not moved off of the screen, because this would slow down the loop. Therefore, it is possible to crash the program by trying to move the player beyond the limits of the screen.
90 HP=HP+4*(STICK(0)=7)-4*(STICK(0)=11):POKE 53248,HP
Check the fire button, and if no missile is already in flight, set the missile flag and launch one. Line 110 merely increments the loop counter (COUNT), and returns to the main loop.
100 IF STRIG(0)=0 AND SF=0 THEN SF=1:HPM=HP+2:POKE 53252,HPM:SVP=94:M$(SVP)=SHELL$:POKE 77,0
110 COUNT=COUNT+1:RETURN 
Lines 120-160: Recurring initialization routines.
120 POKE 656,1:POKE 657,2:? "GAME OVER--PUSH BUTTON TO PLAY AGAIN";:SOUND 0,0,0,0:CHANCES=0:SCREENS=0
130 POKE 656,1:POKE 657,2:? "                                    ";:POKE 704,PEEK(710):IF STRIG(0)=1 THEN 120
Initialize the scoring routines and player positions for each screen. Also, variables are set up for the increasing game difficulty on succeeding screen. Lines 120-140 reinitialize the score total variable and “Game Over” message for the end of game.
140 POKE 656,3:POKE 657,2:? "SCORE   ";:SCORE=0:GOSUB 240:POKE 705,38:POKE 706,38:ATTACK=80:TOUGH=0:TOUGHER=0
150 POKE 704,196:M$=BL$:SF=0:BF=0:POKE 53278,1:FOR I=1 TO 3:FOR J=80 TO 150:SOUND 0,J,10,6:NEXT J:NEXT I:COUNT=80
160 POKE 77,0:ATTACK=ATTACK-SCREENS*10:IF SCREENS>1 THEN TOUGH=30:IF SCREENS>3 THEN TOUGHER=60
Main program loop. Yes friends, the main loop that moves the invaders is only three lines long! All it takes to move them is to check the pointer to screen memory, and move it up one or back one position. The whole screen (except for the PM graphics) seems to move. The only reason it takes three whole lines is that the address pointer is in two bytes, and we have to check to see that the low byte value doesn’t get under 0 or over 255. Also, the animation of the characters is accomplished by POKEing location 756 in line 180. This alternates the character sets being displayed. At several points during each iteration of the loop, the subroutine that moves the laser base, missiles and bombs is called.
170 FOR K=1 TO 20:D=-D:FOR I=0 TO 8:L=PEEK(DL)-D-20*(I=8):H=PEEK(DH)-(L<0)+(L>255):L=L+256*(L<0)-256*(L>255)
180 GOSUB 30:POKE DH,H:POKE DL,L:GOSUB 30:POKE 756,RT+4+2*(PEEK(756)=RT+4):GOSUB 30+TOUGH
190 SOUND 0,255,12,15:GOSUB 30+TOUGHER:SOUND 0,0,0,0:NEXT I:NEXT K
200 GOSUB 420:M$=BL$:SF=0:BF=0:POKE 53278,1:GOTO 120
Lines 210-270: Hit subroutines.
Contains the subroutine which erases invaders that have been hit and scores the hit. Line 210 determines which character was hit.
210 SOUND 0,20,10,6:X=HPM+8*I*(-D)-64*(D<0)-48:X=2*INT(X/16):Y=(Y=2)+3*(Y=1)+5*(Y=8)+7*(Y=4)-1
220 SCORE=SCORE+10*(10-Y):HITS=HITS+1:IF HITS=24 THEN POP:M$=BL$:SCREENS=SCREENS+1:GOSUB 420:GOTO 150
230 POSITION X,Y:? #6;"  "
240 POKE 656,3:POKE 657,8:? SCORE;"         ";:M$(SVP,SVP+2)=BL$:SF=0:POKE 53278,1:RETURN
Score hits on the laser base. A spare base is erased, and if no spare bases are left, the game ends.
250 POKE 706-CHANCES,0:POKE 704,PEEK(710):M$=BL$:FOR K=70 TO 0 STEP -1:SOUND 0,240,8,K/5:NEXT K:GOSUB 420
260 CHANCES=CHANCES+1:IF CHANCES=3 THEN CHANCES=0:SCORE=0:GOTO 120
270 GOTO 150
Lines 280 to 460: Initialization routine. After initializing some important variables, the program jumps to line 280. The order of the program was carefully planned; the initialization routines which are only used once are placed at the back of the program, out of the way. The main loop goes in the middle, while frequently-called subroutines appear at the front. This layout adds much to the program’s speed.
Check the top-of-memory pointer and reset it, so that the computer will not use the top 8 pages. This space will be used for storing two new character sets, as well as the “moving” screen display. Line 290 makes the computer think that this area is the screen display, and zeroes out the memory there with a “clear screen” command (CHR$ 125). Next, the program calls a full-screen Graphics 3 display and sets the character-set pointer to the fourth page above the ramtop pointer (RT + 4).
280 RT=PEEK(106):IF RT/2=INT(RT/2) THEN RT=RT-8
290 POKE 89,RT:POKE 88,0:? CHR$(125):POKE 89,RT+3:? CHR$(125):POKE 106,RT:GRAPHICS 18:POKE 756,RT+4
Print the title, but since there is no character-set data stored at RT+4 yet, nothing appears on the screen. Lines 310 to 340 fill in the two new character sets, mostly by reading the ROM set data, but changing the first four characters of each set with the data in lines 440-450. As this data is POKEd in, the title appears on screen.
295 ? #6;"% OUTER %":? #6:? #6;"    & space &"
300 ? #6:? #6;"        ' ATTACK '":? #6:? #6:? #6:? #6;"   BY s. leemon"
310 FOR I=8 TO 39:READ X:POKE (RT+4)*256+I+32,X:SOUND 0,I,10,6:NEXT I
320 FOR I=40 TO 71:READ X:POKE (RT+6)*256+I,X:SOUND 0,I,10,6:NEXT I
330 FOR I=72 TO 87:POKE (RT+6)*256+I-72,0:SOUND 0,I,10,10:NEXT I
340 FOR I=88 TO 511:J=PEEK(57344+I):POKE (RT+6)*256+I,J:POKE (RT+4)*256+I,J:SOUND 0,I,10,6:NEXT I
Store the address of the pointer to display memory in DH and DL. Color registers are set in line 360.
350 FOR I=0 TO 600:SOUND 0,0,0,0:NEXT I:GRAPHICS 1:POKE 559,0:DH=PEEK(560)+PEEK(561)*256+5:DL=DH-1
360 POKE 89,RT+2:POKE 88,128:POKE 752,1:? " ":POKE DH+25,6:POKE 708,52:POKE 709,132:POKE 710,8:POKE 711,84
Start the initialization routine for ATARI® PM graphics. This program uses a most helpful trick: The space where Player/Missile data is stored is DIMensioned as a series of strings. Because PM$ must start on an even 1K boundary, we DIMension F$ to fill the space between D$ and the next highest 1K boundary. Now, whatever data is contained in the strings which are DIMensioned immediately after PM$ will appear on the screen as players and missiles. Line 380 zeroes out this memory, and line 390 reads the data for the shapes of the laser cannon, the shells, and the bombs into the appropriate strings. Lines 400-410 complete the Player/Missile initialization by setting the color registers, horizontal position registers, PM base address, and enabling double-line resolution PM graphics.
370 DIM BL$(128),D$(1),F$((INT(ADR(D$)/1024)+1)*1024-ADR(D$)-1),PM$(384),M$(128),P$(128),P1$(128),P2$(128)
380 DIM BOMB$(6),SHELL$(6):BL$=CHR$(0):BL$(128)=CHR$(0):BL$(2)=BL$:M$=BL$:SVP=88
390 FOR I=1 TO 6:READ K,Y,D:P$(97+I,97+I)=CHR$(K):SHELL$(I,I)=CHR$(Y):BOMB$(I,I)=CHR$(D):NEXT I
400 P1$=BL$:P2$=BL$:P1$(12)=P$:P2$=P1$:POKE 53249,170:POKE 53250,156:POKE 704,196:POKE 707,76
410 BVP=10:POKE 53254,100:HP=128:POKE 53248,HP:POKE 54279,ADR(PM$)/256:POKE 623,1:POKE 53277,3
Set screen memory to 2½ pages above ramtop. Line 430 prints the four rows of redefined characters that make up the invaders, and sends you back to the beginning.
420 POKE DH,PEEK(89):POKE DL,128:POKE 559,46:BF=1:HITS=0:D=-1:POKE 756,RT+4
430 ? #6;CHR$(125):FOR J=0 TO 3:POSITION 0,J*2:FOR I=1 TO 6:? #6;CHR$(5+32*J+J+64*(J>1));" ";:NEXT I:NEXT J:RETURN
440 DATA 60,126,255,165,255,126,0,0
441 DATA 60,126,215,215,126,255,129,102
442 DATA 24,60,126,235,255,255,65,0
445 DATA 195,126,255,153,221,255,65,65
446 DATA 0,0,60,90,60,0,0,0
447 DATA 60,126,86,126,60,62,34,54
450 DATA 24,60,126,215,255,255,130,0
451 DATA 195,66,126,255,153,187,255,65
460 DATA 24,1,0,24,1,0,24,0,0,60,0,0,126,0,192,255,0,192
SOFTSIDE #42 / MARCH 1982 / PAGE 69

Take-Apart:
Outer Space Attack

by Sheldon Leemon

Outer Space Attack uses several of ATARI®’s exclusive graphics features. The first, character redefinition, has already been treated in an earlier Take-Apart article by Alan J. Zett which explained how to change the appearance of letters in order to create custom graphics characters. For Outer Space Attack, I used a character-generator program to create two sets of redefined characters, each portraying the Invader characters in different positions.

After designing the characters, the generator program then wrote the DATA statements in lines 440-450 of the program, which determine the Invaders’ shapes. The POKE 756 command in line 180 switches back and forth between the sets, creating the illusion of animation.

The second graphics feature which the program takes advantage of is graphics indirection (modifying the display list). Other microcomputers use a fixed area of memory to hold the data being displayed on the screen, so that in order to move images on the screen, you usually have to move the screen data around within this area of memory.

The ATARI® computers, however, do not use a fixed area for display memory. Instead, two bytes of memory act as a pointer to display memory. By changing this pointer, it is possible to change the data being displayed without moving around any bytes in memory. You may think of this system as keeping a “window” on memory. Instead of moving the contents within the window, the frame is moved over the contents. In another sense, each separate line on the screen is a window.

Actually, two pointers are used to change the data being displayed. One tells the computer where to store data which is entered from the keyboard or PRINT statements (the “write pointer”), and the other tells the computer which area of memory to display (the “display pointer”). While these will usually have the same value so that the display shows what is written, it is quite possible to print words or graphics into one part of memory, while displaying another part, enabling you to flip instantly between “pages” without making the user watch the second screen being set up.

The write pointer is in memory locations 88 and 89. You can verify this by calculating the address pointed to with the statement WP = PEEK(88) -1-256 *PEEK(89), and then using a POKE WP,33 command to make the letter “A” appear in the upper-left corner of the screen (screen data uses Internal Character Set values, shown on page 55 of the Reference Manual).

Outer Space Attack uses the write pointer to clear memory, by changing the pointer value to the memory address of the area used for character data, and printing CHR$(125) (Line 290). The “screen clear” character causes the computer to write 1024 zeroes to that area of memory, which it thinks contains the screen display. In Outer Space Attack, the display pointer is changed frequently to give the Invaders the illusion of horizontal motion. This technique, known as coarse scrolling, is demonstrated in the following program:

10 DH=PEEK(560)+PEEK(561)*256+5:DL=DH-1

First we find the two-byte pointer to display memory.

20 FOR I=1 TO 40:POKE DL,PEEK(DL)+1:FOR J=1 TO 50:NEXT J:NEXT I

Next we add one to the low-byte value of the pointer and then POKE the new value back in. This makes the whole display appear to move to the left. The loop which uses the J index was added to slow down the motion.

30 FOR I=1 TO 40:POKE DL,PEEK(DL)-1:FOR J=1 TO 50:NEXT J:NEXT I

This line repeats the motion, this time to the right.

These three lines show the basic logic used in the main program loop of Outer Space Attack. The only real difference is that there, provision was made to carry or borrow from the high byte when the low-byte value got above 255 or below (see Line 170 of the program).

Although this explains the motion of the Invaders, why doesn’t the base, the bombs, or the shells move at the same time? Because they are not being displayed by the regular screen graphics system, but by a completely separate system known as Player/Missile graphics. This system features up to four characters called players, each of which is eight screen dots wide, and four two-dot characters known as missiles. Each character is potentially as tall as the screen. The hardware maintains collision registers to record hits between the players, missiles, and graphics objects.

The topic of Player/Missile (PM) graphics is too broad to be dealt with easily in one short article. For those unfamiliar with this system, I would recommend that you read Chris Crawford’s article in the November, 1981, issue of Byte, or the article published by Atari in their magazine The ATARI® Connection. But for those who are familiar with PM graphics, I will explain the trick used in Outer Space Attack to make them more manageable.

One problem with using PM graphics in BASIC programs is that vertical motion is usually produced by moving the player data through memory, POKEing one byte at a time. This produces slow and jerky motion. A better method exists. Normally, the user picks out an area in memory that is otherwise unused by the program in which to store data for PM graphics. But what if that area coincides with the data storage area of a string? Then, by manipulating the string data, you also will change the PM display data, at Machine Language speed.

The only obstacle to this approach is that PM data memory has to start on a 1K boundary (i.e., the first address must be an even multiple of 1024). The way that Outer Space Attack solves the problem is to dimension a string, F$, to take up space until the boundary is reached. In this way, the player data area is occupied by the string P$, and any time you change the value of P$, you change the player data.

The short example which follows demonstrates how easily PM graphics can be used in BASIC this way:

10 DIM D$(1),F$((INT(ADR(D$)/1024)+1)*1024-ADR(D$)-1),PM$(384),M$(128),P$(128)
20 PM$=CHR$(0):PM$(384)=CHR$(0):PM$(2)=PM$:M$=PM$:P$=M$
30 DIM BALL$(7):BALLS=P$:FOR I=2 TO 6:READ A:BALL$(I,I)=CHR$(A):NEXT I
40 DATA 24,24,24,255,24,24,24
50 POKE 704,14:POKE 54279,ADR(PM$)/256:POKE 559,46:POKE 53277,3:P$(60)=BALL$
60 FOR J=1 TO 5:FOR I=47 TO 200:POKE 53248,1:NEXT I:FOR I=200 TO 47 STEP -1:POKE 53248,1:NEXT I:NEXT J:P$=M$
70 POKE 53248,120
80 FOR J=1 TO 8:FOR I=16 TO 107:P$(1)=BALL$:NEXT I:FOR I=107 TO 16 STEP -1:P$(I)=BALL$:NEXT I:NEXT J:P$=M$

Line 10 takes care of setting up the strings. PMS represents a blank buffer before the start of the player memory, MS is the area of missile memory, and PS is the memory area used for Player 0. If the other three players are desired, these strings should be dimensioned right after PS. Line 20 fills PMS, MS, and PS with all-zero data.

Line 30 then dimensions BALLS, and fills it with data that represents the shape of a ball. A zero is placed in front and behind the ball shape data, so that when the data is moved, the preceding and trailing zeroes will erase the remnants of the prior character.

Line 50 takes care of normal PM housekeeping. The first POKE sets the color of the ball to white. The second one makes the string area starting with PM$ the beginning of PM graphics data memory. The third POKE enables PM memory for double-line resolution graphics, and the fourth enables the player and missile display. Finally, the statement PS(60) = BALLS sets the data at position 60 of player memory equal to the ball data, so that a ball will appear about midway down the screen.

The next two lines show how to move the ball. Line 70 demonstrates how horizontal position is changed by POKEing the horizontal position register (53248 decimal) with a value between and 255. Notice that after this demonstration is finished, the player is cleared by assigning PS the value of MS, which is all zeroes. Next, vertical motion is displayed, by sequentially changing the contents of P$. This produces smooth, fast motion without resorting to Machine Language routines.

As you can see, the techniques used in Outer Space Attack, though sophisticated, are not all that difficult to master. The small effort required to learn them will reward you with access to graphics power far beyond the reach of other micros. PM graphics alone offer effects which could not otherwise be achieved, by making four additional colors available for the screen display; allowing you to mix pictures and text on the same horizontal line; and giving you a method of creating smooth animation in BASIC, simply by defining several strings containing shape data, and alternately assigning to PS the value of each. Other PM features such as selectable priority, which allows you to choose whether the player appears to go in front of or behind other screen graphics, and collision registers, which tell you when screen objects touch one another, lend themselves to sophisticated games.

While touching on some of ATARI®’s unique features, this article in no way exhausts the possibilities. The hardware capabilities of these computers will let you go as far as you wish.

I would like to thank the Michigan ATARI® Computer Enthusiasts, and especially Marcus Watts, who described to the group the PM techniques discussed here, for their help in developing Outer Space Attack and other programs.

ANTIC v.1 n.4 / OCTOBER 1982 / PAGE 41

APOLOGY

The game PAC-INVADERS, published in this department in Issue #3, was the original work of Sheldon Leemon and not Vince Scott as we indicated. Mr. Leemon’s version, titled, Outer Space Attack, appeared in Softside Magazine, March 1982.

Mr. Leemon is the author of INSTEDIT, a character editor program from APEX, as well as an upcoming GTIA tutorial from Educational Software.

Softside is a monthly magazine featuring information and programs for users of Apple, TRS-80 and ATARI computers.

We apologize to all concerned for any misrepresentation or confusion.