Personal Computer News


Sprite Handling

 
Published in Personal Computer News #095

Put an extra spring into the movement of your C64's sprites with this sprite-handling program from Barry Thomas.

Sprite Gymnastics

Put an extra spring into the movement of your C64's sprites with this sprite-handling program from Barry Thomas

The Commodore 64 is famous for its sprites and although Commodore Basic has no commands to give you control over them, they are fairly simple to set up and use. Just make a design on a 24 x 21 grid, convert the binary patterns to decimal numbers, and they can be poked into position at a suitable place in memory, ready for use. So far, so fine and dandy, but these sprites can appear a little pedestrian if all they can be made to do is scuttle to and fro across the screen. What's needed is a little more athleticism.

The program shown here supplies that extra something. It enables you to change sprite colours at the drop of a hat; toggle any of them on or off with a simple command; turn any sprite upside down or reverse it or even get a whole new block of data for a new sprite.

The bulk of the program comprises five Basic loaders, which poke machine code instructions into a 4K block of memory high up in memory where they will be safe from Basic. Once there, they can be called by the SYS command whenever needed.

So the large subroutine between lines 1000 and 1610 contains these five loaders, all clearly labelled. If your particular application just needs sprites that can turn upside down, you can hijack the relevant section from that subroutine, the sprite inverter at lines 1360-1470. The subroutine from line 2000 onwards simply sets up a sprite to contain pictures of Glob and Blob.

This data is stored at addresses 832 to 894, block 13 in the memory map. (That is, 13 blocks of 64 bytes up from address 0, because 13 x 64 = 832). As this area of memory is used by the system only when loading from or saving to cassette, it's usually quite safe. However, if you are using the datasette during your program you must put your data somewhere else.

The rest of the program, between lines 10 and 150 sets up a menu on the screen and prompts you to select from six courses of action. These are the five machine code routines and the option to quit the program. All the routines run independently. Using Each Routine ------------------ Choice 1 on the menu enables you to change the colour of a sprite. First, specify the sprite number, and the colour number. The sprite number in this program is always 0 since only one sprite is set up for action. The colours are from the usual Commodore selection where 0 = Black, 1 = White and so on. To use this machine code routine, we must type, or include in a program, the instruction:

SYS 50265,SN,CN

where SN is the Sprite Number (from 0-7), and CN is the Colour Number (from 0-15).

The instruction may be typed in with real numbers for the SN and CN, or as above with variables. The commas must be included or the routine jumps to the error message table in ROM. The working of the routine is quite simple: it looks for the first comma, then checks that the sprite number is not greater than seven. This being so, the next comma is checked for. The colour number must be in the appropriate range, and provided all is in order, with the operands supplied along with the SYS address, the Colour Number is placed in the appropriate place in the registers of the VIC II chip.

Choice 2 on the menu is to reverse the sprite. This process just turns the data in the sprite about-face, so if your sprite contained, e.g. a train facing right, it would be facing left after the sprite had been reversed. Simple, innit?

The workings of the routine are a little more complex than the first. No sprite number is specified when you use the routine - instead, the address of the start of the data for the sprite to be reversed must be poked into two addresses in page 0 memory. These will act as a pointer which the routine can refer to.

So, in this program, the data for sprite 0 is located in addresses 832 onwards, and the low and high bytes of this number must be poked into locations 253 and 254 respectively. In hexadecimal, 832 is $0340. The low byte, $40, converts into decimal 64 and can be poked into location 253. The high byte is $03 which, of course, remains the same in decimal and can be poked into location 254. This occurs in the main program on line 110. Once this is done, the SYS instruction can be used thus: SYS 49770.

The sprites are, of course, three bytes wide, and the routine works by taking the first byte on a row and reversing it. This byte is then put into temporary storage on the stack in page 1 memory. The second byte on the row is then reversed in the same way, and put back just where it came from in the middle position in the row. Next, the third byte is reversed and placed in the position where the first byte was taken from. This leaves just the original byte 1 to be taken from the stack and put in the right most position on the row.

In fact, this isn't as complex as it sounds. Try it out with a pictorial view of three bytes in a row on a piece of paper. That's how each row of three bytes is treated, but there are 21 rows, and each must be done in turn. If that sounds like a lengthy number crunch, the routine does, in fact, work so fast it all seems to happen at once. Pretty effective it is too.

Number three on the menu is the matching pair to the last routine because it turns the contents of the sprite upside down. This one works by taking the top row of three bytes, putting them into storage and replacing them with the three bytes that form the bottom row of the sprite. This done, the original three bytes can be put into position on the bottom row. The next step is to take the second row down and the second row up and swap them around in exactly the same way, and so on. When the middle row is reached, row 11, it is left exactly as it is.

The syntax for using the routine is simply SYS 49840.

As with the last routine, the address of the start of the sprite data must be put into addresses 253 and 254 in page 0 to act as a pointer. Both routines use that pointer in a non-destructive way, i.e. when the routine has done its job, the pointer is still where you put it, so the routine can be used again without having to put the two numbers in position again.

The only problem is that since page 0 memory is at such a premium, due to the system using almost all of it, the other routines use the same two bytes as pointers too. So, if you put your pointer into page 0, use the reverser routine and then the colour change routine on a different sprite. Don't expect your pointer to be safe and sound later on - it won't.

The third item on our menu is the sprite toggler. This lets you switch a sprite on or off, without even knowing which state it is in when you start. If the sprite is off, it will be turned on, and vice versa. It operates on the sprite switch location in the VIC II chip in exactly the same way as can be done from Basic. The difference is that you must remember one address, that is the start of the routine, and know which sprite you want to toggle. To use the routine, just type: SYS 50215,SN. As usual, the comma must be present, and SN is either a real number or a variable designating the number of the sprite to be toggled.

Last on the list is a routine to grab 63 bytes of data from anywhere in memory and put them into the space alloted for any particular sprite. This comes in handy when your particular application means using several different sprites. As the VIC II chip can only 'see' 16K of memory at once, all eight sprites in use at any one time must be in the particular 16K bank of memory currently in use.

Finding room for all these sprites can be a problem. It makes sense to put the sprite data out of the way in high memory, and just grab the data for a new sprite as and when it's needed. The sprite data can be stored safely in the 4K block of memory where I have put these five routines (Between $C000 and $CFFF). That's enough storage space for another 64 sprites. The routine is accessed with the instruction: SYS 501315,SA,SN where SA is again a real number or a variable for the start address of the new data, wherever you have chosen to store it. SN is of course the Sprite Number.

As usual, the commas are checked for, and all the routine does is transfer a block of 63 bytes, one by one, from the address specified to the address allocated to contain the data for the selected sprite. Hence, a grand total of 271 bytes of machine code can give that extra bit of pizzazz to ordinary sprites.

These routines remain the copyright of Barry Thomas 1984. All, and more, feature in Barry's new book Supercharge Your Commodore 64 published at £6.95 by Melbourne House.

Barry Thomas