Masked sprites and bank switching

Mike Goldberg introduces you to the delights of masks and bank switching

Who was that masked man? To that there was never an answer but there is when adding a mask to your own sprites and then plotting them. So now let's look at how to make your sprite plotting more exciting.

Last month we created a sprite called SmallOne and plotted it from a Basic listing. We also plotted a lot of unwanted pixels too in the shape of a rectangle that outlined the extent of the sprite.

Getting rid of those pixels is easy - just make a mask the same shape as the unrequired pixels, see Figure I, then save the sprite with the mask as SmallTwo. To plot the mask along with the sprite is a matter of altering one variable only.

Figure I

Look at last month's listing DrawIt line 290 and alter the variable howplotted% to 8 and change the sprite name at line 330 to Smalltwo. By adding 8 to the normal plot codes includes the mask so no great mystery there. Simple isn't it?

Once you have plotted a sprite with its mask and assured yourself that's all there really is to it try using some of the built-in effects. Add line 325:

SYS "OS_SpriteOp",256+33,area%,"Smalltwo"
                      |
                      Flip sprite

When you run the program the sprite is plotted upside down to flip it ahout the Y axis substitute 47 instead of 33. Now it is printed back to front in layman's terms.

Now if that was not enough let's see how all this can he plotted even more speedily. If we alter the string name of our sprite to just a memory address number the computer doesn't need to search to find the right sprite so plots it quicker.

Look at the listing AddressIt. Using another OS call at line 290 selects the sprite you wish to address. Note the three commas after the TO. You can see here we are altering our string SmallTwo to an integer variable called spritetwo%.

The next line reads the sprite's width and height - again note the syntax. It is not necessary to use the variable names width% and height%, any unused variables will do. So to plot it look at line 390. The first thing to notice is that the 256 in the OS_Sprite call has changed to 512 which just means we are providing the address of the sprite not its name.

The other is that the string SmallTwo is replaced with the integer variable spritetwo%. When you run this program there will he no discernible plotting speed difference. However, when plotting lots of different sprites, rubbing them out, replotting a background and putting the sprites back in as you would in a game listing, the speed increase is quite visible.

Believe me now: You will regret writing a long listing that plots sprites by name as I first did - use memory addresses because converting it over becomes a task akin to mucking out the Aegean Stables.

Which brings me neatly round to plotting a sprite over a background, then moving it and leaving the background intact. On the old Beeb this was quite a complicated machine code process.

The background that the sprite was placed over had to be stored in memory. The new coordinates of the sprite would give you the next piece of background to store while the original background was replaced to screen. Then the sprite would be plotted in its new position.

It required a very convoluted piece of coding that I spent years perfecting, only to get an Archimedes which obviated the need for any machine code. Typical butnevertheless very handy and a thousand times easier.

Because of the phenomenal processing speed of the Arc you can actually reprint the whole of the background and then the sprites on top each time you want to move something.

As well as that you can draw on more than one screen at a time - the idea being to draw all the sprites on the screen that is not visible and only display it when the drawing is complete.

Repeat this process and you get seamless animation. Don't be put off by articles you may have read about only using 16 colour modes because they are quicker - you can do amazing things in any more so why waste all those 256 colours? Some people want jam on it!

Anyway, the procedure I'm talking about is called Bank or Screen Switching and we will use a mode that uses 40k to map the screen, Mode 9, to keep things simple.

This is because each bank or screen in Mode 9 needs 40k of memory to map it and if your machine is like mine, you will not have to alter the screen memory allocation on the Task Manager if the default is 80k (Mode 12) and you only want to use one extra bank or screen.

From that, there really is only one command you now need, in two forms and here it is:

SYS 6, 112, screenbank_number%
        |                |
        Select screen    |
                         Screen number

SYS 6, 113, screenbank_number%
        |                |
        Display screen   |
                         Screen number

SYS is a System command and SYS 6 followed by two variables allows you to select a screen bank to write to and which screen bank to actually display. This can be a bit tricky to get your brain round initially but familiarity soon sets in if not through dogged perseverence alone.

I've provided an example of how straightforward this command is to use, see listing Animate, all you have to do is create three Mode 9 sprites preferably one called Backg for the background and two more Rom0 and Rom1 and save the spritefile as ROMfile.

Looking at the listing it is always a good idea to do a CLS on both screens otherwise you can get all sorts of discarded junk on the screen.

So line 370 and 380 selects screen banks 2 and 1 and clears them in that order. This saves you selecting the default screen again which is 1. Then a couple of variables: At line 440 bank% which is the bank we are writing to or displaying and at line 450 whichROM% which of the two images of Rom we are printing.

Line 510 alternates between 1 and 2 for switching to the correct screenbank number and line 520 does similar for the Rom image. Then 550 selects the screen bank not being displayed and 580 draws the background to it, line 590 draws the sprite over that and 620 switches the display to this invisible screen and displays it.

As all this loops between lines 480 and 640 the bank switching cycles between 1 and 2, 1 and 2 and so on. The result is quite breathtaking certainly on first acquaintance.

You could always incorporate a WAIT in the listing to wait for the screen to refresh but in practice all this does is slow things down needlessly.

It is often far better to sacrifice total electron microscope proof smoothness for the increase in speed and usually the increase in speed means you don't notice much jerkiness or sprite tearing anyway.

Beeb users will remember the oft-quoted smoothness solution of *FX 19 which did exactly the same thing: Crank the animation speed down to unbearably slow.

So there you have it and it's all waiting for you on your machine. The speed is there just dying to be unleashed and the commands are there too, if you know where to look. Well look no further!

Next month we'll scale the heights (and depths) of sprite scaling and a whole slice of software scrolling - make room for your portion now.

Click here to download the example files for this article


Source: Acorn Computing - January 1993
Publication: Acorn Computing
Contributor: Mike Goldberg