Sprite Grabber For The 64
Todd Wostrel
With this creative graphics utility, you can capture a part of any hi-res or text screen and convert it to a sprite for use in any other program.
Sprites are one of the Commodore 64's wonders. They can be moved around both hi-res and text screens without disturbing these screens. Collisions are easily detected, and these super-graphic blocks can be expanded in both the horizontal and vertical directions. On the negative side, sprites take a long time to read into memory—especially if your program contains many sprites—and there is no utility built into the 64's BASIC 2.0 to allow you to grab a part of a screen and place it in a sprite. "Sprite Grabber," the program accompanying this article, provides a solution to both of these problems, and does so without using a large amount of the 64's memory.
Because Sprite Grabber (Program 1) is written entirely in machine language, it must be entered using the "MLX" machine language entry program found frequently in COMPUTE!. Be sure to read the instructions for using MLX before you begin entering data. When you run MLX, you'll be asked for a starting and an ending address for the data you'll be entering. The correct values for Sprite
Grabber are as follows:
Starting address : C000 Ending address : C277
After you've entered all the data, be sure to save a copy before leaving MLX.
Grabbing Sprites
To enable Sprite Grabber, simply load it with
LOAD"filename", 8, 1
where filename is the name you used when you saved Sprite Grabber to disk. After the program is loaded, remember to type NEW and press RETURN to reset important memory pointers.
A new command is now available to you. The syntax of the command is
SYS 49152, blk, sx, sy (,sa) (,ca)
Blk refers to the block (the 64-byte area) where you want to store the sprite data. Legal numbers are 0–255. The sprite data is saved to the VIC video bank (0–3) where the screen resides. The usual restrictions for selecting sprite blocks apply. For example, if the screen currently resides in bank 0 (the default), then you must choose carefully to avoid overwriting important system information. In VIC bank 0, only block 11 (location 704–767) is completely unused by any ROM routine. If tape is not being used, blocks 13–15 (locations 832–1023) are also available. Blocks 32–255 lie in the normal BASIC program text area. When using these blocks, you should take steps to keep the BASIC program from corrupting the sprite data, and vice versa. Similar cautions apply to the other video banks.
Sx and sy are the x- and y- addresses, respectively, of the upper left corner of the screen area to be saved. Sx must be in the range of 0–319, and sy must be 0–199. Parts of the sprite may be off the screen if sx values greater than 296 or sy values greater than 176 are used.
The parameters in parentheses are optional. (Don't type the parentheses if you use these parameters.) Normally, Sprite Grabber will find which screen is being displayed and will take the data from that screen, but you can override this automatic operation with these two parameters. If the data is to come from a hires screen, only the first parameter—sa, the starting address of the screen—needs to be set. If the data is to come from a text screen, both this and the second parameter—ca, the starting address of the character set—must be specified. The legal range for each of these optional parameters is 0–65535
The Sprite Grabber command can be used in direct as well as program mode, parameters can be numbers, variables, or any expression that produces a number in the 64's BASIC. Giving a parameter a value outside of the legal range will yield unpredictable results.
Practical Uses
Sprite Grabber can be used to display scrolling messages that are captured from text screens. To move a message, all that you need to do is adjust the sprite's x- and y-coordinates. Text can easily be moved anywhere. You can even have your own custom characters grabbed and placed in a sprite.
Sprite Grabber also makes it possible to use hi-res pictures for computer programs such as games just by taking the data from the hi-res picture. If you don't have a sprite editor, you can use a hi-res program to draw sprites and later capture them for your use. Sprite grabber also makes long groups of DATA statements almost unnecessary because all you need to do is print a picture on the screen and grab it—you don't have to wait for the sprite to be POKEd into the computer's memory.
A Demonstration
Demo (Program 2) is a BASIC program that shows how to use Sprite Grabber. Demo prints a message on the computer's screen and sets up eight sprites that capture the message and scroll it. The demonstration program uses sprite blocks 252–255, which lie far enough above the end of this short program and far enough below the start of the string variable pool that they can be used without problems in this particular example.
The sprites in Demo show all the possibilities of horizontal and vertical sprite expansion. First, the image is copied to one block of sprites and displayed, then it is copied to another block and displayed. This is done to prevent jitters when the sprite is being copied. When the sprites are being changed, the character set—specified by the ca parameter in Sprite Grabber's SYS command—is also changed, causing the letters to alternate between upper- and lowercase. Let's take a closer look at the program.
Lines 160–190 do some initial housekeeping. They set the text screen and border colors (line 160), read in DATA statements that indicate the eight sprites' vertical and horizontal positions (line 170), set the vertical and horizontal expansion registers (line 180), and set the sprite's colors (line 190). The rest of the program is a loop that enables all the sprites (line 200), calls the Sprite Grabber routine to move a portion of the text screen into two sprite blocks (line 210), then stores these block numbers into the eight sprite pointers beginning at address 2040 (line 220). This process is repeated in lines 230–240 with a slightly different portion of the screen grabbed, and a different character set specified by the ca parameter in the SYS command. The program then returns to the FOR statement in line 190 and repeats the loop.
Program 1: Sprite Grabber
Please refer to the "MLX" article in this issue before entering the following listing.
C000 : 20 9B B7 8E 74 C2 A9 00 5A C008 : 85 FE AD 74 C2 0A 26 FE 92 C010 : 0A 26 FE 0A 26 FE 0A 26 08 C018 : FE 0A 26 FE 0A 26 FE 85 BC C020 : FD 20 0E E2 20 EB B7 8E 47 C028 : 73 C2 A6 14 8E 71 C2 A6 90 C030 : 15 8E 72 C2 C9 2C D0 1A 15 C038 : 20 0A C2 8E 77 C2 A0 00 95 C040 : B1 7A C9 2C D0 09 20 0A 2A C048 : C2 8E 78 C2 4C 98 C0 4C 9C C050 : BE C0 AD 00 DD 29 03 49 F9 C058 : 03 0A 0A 0A 0A 0A 0A 8D D9 C060 : 77 C2 8D 78 C2 AD 11 D0 47 C068 : 29 20 F0 11 AD 18 D0 29 4E C070 : 08 0A 0A 18 6D 77 C2 8D 97 C078 : 77 C2 4C BE C0 AD 18 D0 99 C080 : AA 29 F0 4A 4A 18 6D 77 69 C088 : C2 8D 77 C2 8A 29 0E 0A 09 C090 : 0A 18 6D 78 C2 8D 78 C2 52 C098 : 20 13 C2 A2 17 A0 14 8E 63 C0A0 : 75 C2 8C 76 C2 20 82 C1 E3 C0A8 : F0 03 20 E7 C1 CE 75 C2 DC C0B0 : 10 F3 A2 17 8E 75 C2 CE 9B C0B8 : 76 C2 10 E9 30 24 20 13 2C C0C0 : C2 A2 17 A0 14 8E 75 C2 C1 C0C8 : 8C 76 C2 20 4C C1 F0 03 D6 C0D0 : 20 E7 C1 CE 75 C2 10 F3 4C C0D8 : A2 17 8E 75 C2 CE 76 C2 9B C0E0 : 10 E9 A5 01 09 07 85 01 1A C0E8 : 58 A9 81 8D 0D DC 60 A9 50 C0F0 : 00 8D 7A C2 AD 75 C2 18 32 C0F8 : 6D 71 C2 8D 79 C2 90 06 BC C100 : A9 01 8D 7A C2 18 AD 76 3A C108 : C2 6D 73 C2 8D 7B C2 A8 6B C110 : AD 77 C2 85 FC 98 60 8D 91 C118 : 7D C2 A2 00 8E 80 C2 0A 65 C120 : 2E 80 C2 0A 2E 80 C2 18 E4 C128 : 6D 7D C2 AA A9 00 6D 80 6D C130 : C2 8D 80 C2 8A 0A 2E 80 0E C138 : C2 0A 2E 80 C2 0A 2E 80 88 C140 : C2 85 FB 18 AD 80 C2 65 E1 C148 : FC 85 FC 60 20 EF C0 29 BC C150 : F8 20 17 C1 98 29 07 65 34 C158 : FB 85 FB A9 00 65 FC 85 6A C160 : FC AD 79 C2 29 F8 65 FB 1D C168 : 85 FB AD 7A C2 65 FC 85 36 C170 : FC AD 79 C2 29 07 AA 20 14 C178 : 62 C2 A0 00 B1 FB 3D 69 53 C180 : C2 60 20 EF C0 4A 4A 4A 8E C188 : 20 17 C1 AD 79 C2 8D 7F 66 C190 : C2 AD 7A C2 8D 80 C2 4E 9E C198 : 80 C2 AD 7F C2 6A 4A 4A 59 C1A0 : 18 65 FB 85 FB A9 00 65 4D C1A8 : FC 85 FC 20 62 C2 A0 00 OD C1B0 : B1 FB AA A5 01 09 07 29 1F C1B8 : FB 85 01 A9 00 85 FC 8A F0 C1C0 : 0A 26 FC 0A 26 FC 0A 26 72 C1C8 : FC 85 FB 18 AD 78 C2 65 67 C1D0 : FC 85 FC AD 7B C2 29 07 EE C1D8 : A8 B1 FB AA AD 79 C2 29 49 C1E0 : 07 A8 8A 39 69 C2 60 AD BB C1E8 : 76 C2 0A 6D 76 C2 8D 7C C6 C1F0 : C2 AD 75 C2 4A 4A 4A 18 44 C1F8 : 6D 7C C2 A8 AD 75 C2 29 27 C200 : 07 AA BD 69 C2 11 FD 91 E9 C208 : FD 60 20 83 AE 20 F7 B7 7E C210 : A6 15 60 AD 77 C2 29 C0 EE C218 : 18 65 FE 85 FE A0 3E A9 DB C220 : 00 91 FD 88 10 FB AD 18 36 C228 : D0 29 0E C9 04 F0 04 C9 74 C230 : 06 D0 22 AD 00 DD 29 03 D8 C238 : C9 03 D0 0C A9 C0 18 6D 2C C240 : 78 C2 8D 78 C2 4C 55 C2 A0 C248 : C9 01 D0 09 A9 00 18 6D 88 C250 : 78 C2 8D 78 C2 A9 7F 8D 45 C258 : OD DC 78 A5 01 29 FA 85 2D C260 : 01 60 A5 01 29 F8 85 01 7C C268 : 60 80 40 20 10 08 04 02 F2 C270 : 01 00 00 00 00 00 00 00 76
Program 2: Demo
For instructions on entering the following program please refer to "COMPUTE!'s Guide to Typing in Programs" found elsewhere in this issue.
RQ 10 REM {2 SPACES}* SPRITE GR ABBER DEMO SK 20 REM COPYRIGHT 1988 COMPUTE! PUBLICATIONS, INC. {2 SPACES} ALL RIGHTS RESERVED. JQ 100 PRINT "{CLR}{RED} {10 SPACES} [< 18 @ >] BG 110 PRINT "{9 SPACES} [< M >] {RVS}* SPRITE GRABBER * {OFF} [< G >] FE 120 PRINT "{9 SPACES} [< M >]* {2 SPACES} FROM COMPUTE! *[< G >] EK 130 PRINT "{10 SPACES} [< 18 T>] PB 140 PRINT " {WHT} [< 7 >] {2 RIGHT} COPYRIGHT 1998 COMPUTE! PUBLICATIONS" XP 150 PRINT "{10 RIGHT} ALL RIGHTS RESERVED." DR 160 POKE 53280, 0 : POKE 53281, 0 CG 170 FOR X = 0 TO 15 : READA : POKE 53248 + X, A : NEXT AS 180 POKE 53277, 51 : POKE 53271, 15 SG 190 FOR X = 0 TO 7 : POKE 53287 + X, X / 2 + 1 : NEXT MH 200 FOT X = 31 TO 228 STEP 4 : POKE 53269, 255 FM 210 SYS 49152, 252, X, 4, 1024, 4096: SYS 49152, 253, X + 24, 4, 1024, 4096 GC 220 FORY = 0 T0 3 : POKE 2040 + 2 * Y, 252 : POKE 2041 + 2 * Y, 253 : NEXT RA 230 SYS 49152, 254, X + 2, 4, 1024, 6144 : SYS 49152, 255, X + 26, 4, 1024, 6144 EX 240 FOR Y = 0 T0 3: POKE 2040 + 2 * Y, 254 : POKE 2041 + 2 * Y, 255 : NEXT MB 250 NEXT CM 300 DATA 120, 100, 168, 100, 144, 150, 168, 150 XP 310 DATA 120, 200, 168, 200, 144, 225, 168, 225