Commodore's port ... a sprite editor for the Commodore 64. (column) John Michael Lane.
I have used microcomputers extensively at work, but I held off the purchase of a home computer. After a great deal of research, I decided to purchase a Commodore 64 because it seemed to offer the most performance for one on a limited budget.
One of the attractions of the Commodore is its capability for sprite graphics and the promise of creating real time games in Basic. A sprite is a user-defined movable block of pixels that can be placed anywhere on the screen with a few simple commands. On the Commodore 64, a sprite is 24 pixels wide and 21 pixels high. (Total screen resolution is 320 by 200 pixels.) To animate or move an object on the screen, it usually must be drawn pixel by pixel, erased and then drawn again in a different location. This time-consuming process has precluded the use of Basic. To move a sprite of 24 by 21 pixels your program must execute approximately 504 steps to create the original image, another 504 to erase it, and another 504 steps to redraw the image.
With sprite graphics, the image is created in 63 steps and can then be moved with a single command. On the Commodore 64, a sprite can be expanded by a factor of two in the x-direction, the y-direction, or both. (The resolution, however, stays at 24 by 21 pixels.) Sprites can be drawn over one another with either sprite having a predetermined priority so that it looks like one passes in front of the other. Sprites can have transparent windows, so the background image (or another sprite) shows through.
The Commodore, which can detect collisions between sprites, stores that information in a register. It can also detect collisions between sprites and background images and has a separate register to store these. Amazing.
Well it sounded good until it came to creating a sprite. One of the limitations of the Commodore is that its version of Basic contains no graphic commands. Everything is done with PEEKs and POKEs. Sprite data are contained in 63 bytes, each of which must be POKEd into a separate memory location. The easiest way to do this is to put the bytes into DATA statements in your program and then read and POKE them into the appropriate location as shown in Listing 1.
That kind of coding can hardly be called efficient or friendly.
But that is only a secondary problem. The primary one is that you must translate your 24 by 21 pixel image into 63 bytes.
Figure 1 represents the pixel image of my "gunsight" sprite. With proper programming, it is very useful for zapping bylons, cylons, dylons, nylons, and other menacing aliens. Each line of 24 pixels must be coverted into three 8-bit (1 byte) binary numbers. The encoding is simple. A solid square represents a binary 1, and an open square represents a binary 0. Thus the first line across is read 11111111, 11111111, 11111111 in binary or 255,255,255 in decimal. The second line is read 10000000, 00000000, 00000001 or 128,0,1. With a sheet of graph paper and a calculator, I sat at my computer table encoding sprites for my first program. As I stared at my idle computer, it occurred to me that my priorities were backward, and that my first order of business should be to write a program to simplify the coding of sprites.
The rest of this column is the result.
Listing 2 is the sprite maker program. It enables you to draw a greatly enlarged sprite on the screen using the keyboard and cursor controls. Once the sprite is complete, the image is converted to bytes and stored in a cassette file for further use. Although the sprite is converted to 63 bytes of information, my program adds a 64th byte that is always zero. This simplifies the loading of sprites into memory because the Commodore 64 reserves 64 bytes of memory for each sprite.
Lines 5-45 let the user select the method to be used in creating the sprite.
Lines 50-85 set up the screen for display of the 24 by 21 pixel image.
Lines 90-98 display the + pseudo cursor.
Lines 100-170 evaluate the keyboard input. (L is the line number of the current pixel and C is the column number of the current pixel.)
Lines 600-710 check to see that the cursor is still in ths sprite area and then POKE the appropriate character into the register for the screen memory. The expression (1024+40.sup.*.L+C) translates the position of the pseudo cursor into the corresponding register holding the screen display.
Lines 1000-1200 translate the information in the screen memory into the appropriate numeric data and then store that data on cassette.
Lines 2000-2030 contain the subroutine for extracting existing sprites from a cassette file.
Lines 2500-2580 contain the subroutine for converting sprite data (in terms of bytes) into an enlarged sprite image.
The other program, Listing 3, retrieves the sprite data from the cassette tape and converts it into DATA statements which appear on the screen. Positioning the cursor on the first line of the first DATA statement and pressing RETURN four times adds the DATA statements to whatever program is in the memory. More on that later. Program Operation
The program can be used to create new sprites by drawing an image on the screen with the keyboard and cursor controls. The user starts with a 24 by 21 field of dots (periods) outlined with solid lines. A pseudo cursor is indicated by a flashing + sign.
After you move the cursor with the cursor keys, a display appears in the upper righthand corner, showing which row and column you occupy. If you move the cursor off the display field, it reappears on the other side.
Pressing the X key causes the cursor to turn each picel "on" as it passes over it. Pressing the O key causes the cursor to turn each pixel "off" as it passes. After a few minutes of practice, you will get the hang of it.
When the sprite is complete, press the shift and E keys at the same time to terminate the input portion of the program and to start calculating the bytes from the screen memory. You are asked to supply a file name for the sprite data, and it is stored on tape.
The program also allows you to load a previously created sprite, to modify it, and to store the slightly changed image in a new file. This is particularly useful for animating sprites. Simply erase an arm or a leg and redraw it to create the effect of animation.
A third feature allows you to load a sprite from data that have already been converted to bytes. This is useful if you have a program listing and want to see how the sprite looks without keying and running the program. Sprites loaded by bytes can also be changed.
Once a sprite is created and stored on cassette, how do you get it in your program? This is done with the program Getsprite along with the screen editor on the Commodore 64.
To merge the program with any existing program, clear the screen and type in LOAD "GETSPRITE." The program with which you are merging should not use line numbers below 200. (If necessary, you can renumber Getsprite.) After Getsprite is loaded, type LIST to list the program on the screen. Next, type LOAD "PROGRAM" where PROGRAM is the name of the existing program. The Commodore loads the new program over Getsprite, but when the display returns, the listing of Getsprite will be on the screen. Placing the cursor on the program lines and hitting RETURN adds the Getsprite instructions to the program without re-keying.
To avoid running the Getsprite subprogram when you run the main program, add the line: 5 GOTO XXX where XXX is the first line number of the main program.
To add sprites at any time, type GOTO 10 instead of RUN to start the program. Getsprite clears the screen and asks for a sprite filename and a beginning line number for the DATA statements. Be careful not to use any line number that would overlap a portion of your program. There will be four DATA statements of 16 bytes each, starting with the line number that you specified and incremented by one for each new DATA statement. When the DATA statements are displayed on the screen, position and press RETURN, using the screen editor to add each statement to your program. Summary
The sprite graphics capability of the Commodore 64 opens a new dimension of animation and real time graphics to the Basic programmer. Even with sprite graphics, Basic is still too slow for complicated, fast action games. However, simpler games and animated graphics for strategic and educational games can challenge the most ambitious programmer for several months. The use of the sprite editing program should make the task of creating and coding sprites a little easier.