Task: Add Missiles to Player-Missile Graphics in BASIC
Time: 30-60 minutes
I have previously demonstrated how to implement player-missile graphics (PMG) in BASIC, and how to combine a player with a background or playfield using redefined character sets. The latter post includes a demo program that allows you fly Darth Vader’s tie fighter around a playfield that features the Death Star. It occurred to me while coding this example that I should turn this into a mini-game. So, I started looking into adding missiles to the demo. This turned out to be a little more challenging than I thought.
The key problem with learning about missiles is that very few books and other sources cover this. Most sources that teach PMG programming in BASIC stop with adding players, or only briefly mention missiles. Fortunately, I was able to track down a source that provides a nice example of programming missiles. This example is in part two of a two-part series on PMG by Robert Powell in Compute! from 1985 (Part 1 & Part 2).
There are two relatively simple steps to getting missiles on the screen, and a few tricks to making them work the way you want. The first step is to write the missile graphics to the PMG memory area. If you are using single-line resolution, this is in PMG memory location 768 to 1024. If you are using double-line resolution, the missiles are stored in locations 384 to 512. The Vader demo uses single-line resolution. Note that there are 256 bytes of PMG memory allocated to missiles. Like players, missiles span the top of the screen (byte 768) to the bottom of the screen (byte 1023). Unlike players, each byte holds the information for whether the pixel on that line of the screen is shown for ALL four missiles. So, 00000011 (i.e. decimal 3) would light up missile 0 while 11000011 (i.e. decimal 195) would light up both missiles 0 and 3. This would be implemented as POKE PMBASE+768+M0Y,3 to place missile 0 on the screen where M0Y is the Y location of the missile. This is how I implemented it in the Vader demo below. Note that there are two bits for each missile. Each can be on or off giving you some very limited ability make some simple shapes that are two bits wide and up to 256 bits high. Moving the missiles in the Y direction requires writing new memory locations and clearing out the others.
The second step is tell ANTIC where the horizontal (X) location of the missile is. This is much easier than setting the Y location and only involves writing X to memory locations 53252, 53253, 53254, and 53255 for missiles 0 to 3, respectively. You would set the X position of missile 0 to 100 with POKE 53232,100. Easy! To move the missile across the screen from left to right you would simply set up an X=X+1 loop followed by a POKE 53232,X.
A few things to keep in mind. First, moving missiles horizontally is easy and fast with a simple POKE to the horizontal movement register. However, moving in the Y direction (up and down) requires re-writing the missile bits to the PMG memory locations which is slower. This can be done with machine code. I will cover this at a later time. There are some good examples online. Second, missiles take on the colors of their respective players. They can not be set independently. In the demo I use player 0 as Vader’s tie fighter (green) and set player 1’s color to orange so that missile 1 is also orange. Player 1 is not used. This allows me to have one player and one missile of different colors on the screen. Third, it is important to set the player colors AFTER you initialize the PMG. I found if you try to set them before the missiles show up as black even the player color works just fine. I don’t recall reading this anywhere. Just one of those weird trial and error things. Finally, as is noted in the Powell piece in Compute!, the horizontal registers are write (POKE) only. For some reason, the can’t be reliably read with PEEKs. So, the X location of the missile has be tracked in a variable and not by reading the register. Finally, you can control the width of missiles (single, double, or quadruple) with a POKE to the missile width register at 53260. This is clearly explained toward the end of Chapter 8 of the Atari Player Missile Graphics book.
The demo below adds the missile capability to the Vader demo from before. Here, I simply have missiles entering from the left or right side of the screen at random Y coordinates as if X-wings were firing at Vader. I am imaging a mini-game where you, as Vader, have to survive the X-wing firing as long as possible. I will flesh this out in later posts.
The following instructions are for running the example PM code in the Altirra emulator. You can of course type the code in by hand and run it on original hardware with BASIC or boot the ATR file and load the BASIC file using SIO2PC. You could also load it from a flash device. Here is the text file. Here is a zip with the ATR file. Here is a heavily commented version of the BASIC code. Note that it runs much better on original hardware. There is a slight delay for the drawing of the playfield and then again for the player to show up.
Open Altirra and load BASIC. I used Turbo BASIC XL. You can also load the built-in BASIC from Altirra from the File->Attach special cartridge menu.
Open the BASIC code in your PC text editor or web browser and copy the text to your clipboard. Click on the View tab of Altirra and choose the paste text option from the bottom of the list. Altirra will slowly paste the text into the BASIC command line. It is important to keep focus on the Altirra window or the paste will stop and it will lose some characters.
My idea for a Vader’s last stand game is starting to take shape. The next step is to add player-missile collisions and a tie fighter explosion of some kind. I will also need to add a custom display list to put in some text at the top for a score. To make this a real game there will need to be timed rounds with increasing difficulty (more missiles, faster missiles). I have also thought of adding power ups like shields for Vader’s ship. The power ups will add some complexity to the game play that is otherwise just moving up and down to avoid the missiles. I can use players 1-3 for powerups. I could add vertical missiles as well but that would require a machine language routine for fast vertical movement. Would be good to do this for completeness. The game will definitely need some sound. I don’t want to go too crazy with this because the goal of the project is to help those that have never done this before see some easy examples.
Note that I added a faster joystick routine and also rewrote some of the IF-THEN statements to streamline the code and improve performance.