Saturday, July 11, 2015

More work on sprites

Finally got a chance to look at the sprite fixes that I have been working on now that I am next to my FPGA board again.

It is nice to see the sprite colour bug fixed, and see some of the games that are known to work without problem on the MEGA65.

This also means that I have finally been able to take a look at my work on 64-pixel wide, and variable height sprites, as well as a few other fun sprite improvements, some of which are inspired by the Amiga and abuse of sprites on that platform.

First up, I fixed a bug with normal-width sprites that was introduced when I started adding support for 64-pixel wide sprites.  The sprite data fetch logic was fetching one more byte than it needed to. With 24 bit = 3 byte wide sprites, this wasn't a problem, as the 4th byte didn't map anywhere since the byte address was using two bits, and thus has four possibilities. However, the move to 64 pixel = 8 byte sprite fetch meant that the extra byte, now being the ninth byte (byte 8), mapped back onto the first byte (byte 0) in the 3-bit sprite data address register.  This meant that the first byte of each row of a sprite was showing the byte that should be shown in the third position two rows down.  This was fairly easy to find and fix once I thought about it, and indeed fixed the problem.

However, after this I was seeing glitching on the right edge of sprites, which turned out to be an analogous problem, where a 25th (or 65th) column of pixels was being drawn.  Again, easy to find and fix once I thought about what was going on, and could look at a sprite on the screen and fiddle with its data.

There was also a bug where the variable height mode was not working properly, because I had mis-plumbed some registers, rendering it impossible to set the height of sprites to anything other than the normal 21 pixels. I have rolled that fix in to the next build as well.

Just these changes, allowing much bigger sprites, should increase the usefulness of sprites quite a bit.  A tall or wide character now only needs a single sprite, hopefully leaving more sprites free for other things.  Once the rest of the MEGA65 is implemented, I might look at adding more sprites, but for now I am concentrating on making the ones we have more useful and interesting.

Sprite/foreground collision is still not working, so I have also added an "xray mode" to the VIC-IV, where instead of showing the normal display, it shows foreground, background, border and sprites all as a single distinct colour.  This is enabled with a physical switch on the FPGA, to make it easy to debug.  This change is in the build I am currently synthesising now.

I also took the opportunity to add some new extended sprite features, based on my reading about how Amiga sprites work, and also how they were used to create a tiled 16-colour background in some games on the Amiga.  However, I have not copied the Amiga functionality directly, and instead created something that achieves the same results, plus some extra opportunities for abuse.

First up, I added a flag that causes a sprite to be tiled horizontally, instead of being drawn only once.  This is a simple kind of hardware-assisted sprite multiplexing. Combined with 64-pixel wide sprites, it will hopefully be useful.  For example, having a full-width parallax background can now be easily done using a single sprite.  Again, this should leave more sprites free for other things.

Second, I have added a flag that causes a sprite to modify one or two bits in the colour otherwise to be displayed.  That is, each sprite can now be selected to modify one bitplane (or two in multi-colour sprite mode) of the output.  This works for other sprites, providing something effectively the same as sprite-bonding on the Amiga, but allowing the combination of arbitrary numbers of sprites to yield arbitrary colour depths.  It isn't quite the same, because the "master" sprite that is being combined with the bitplane-modifying sprite(s) has its colour selected in the normal way, so a transparent pixel in that sprite will always translate to a transparent pixel when displayed.  So this part of the functionality, while implemented differently to the Amiga, is generally similar.

What I have also done, because it is trivial from a hardware perspective, is to allow sprites in bitplane mode to modify the colour of the non-sprite elements of the screen.  This is something rather different, and offers all sorts of opportunities for abuse.  You could use it to easily draw shadows or highlights on a display, just by carefully setting up the palette and using a sprite in the shape of a shadow.  But you could also use it to provide extra bits of depth to a regular bitmap display, without incurring the memory cost of making the whole display deeper.  For example you could make something that is similar to FLI or one of the other VIC-II bad-line tweaked modes, but with a completely static display.  There is ample opportunity for demo effects here as well, especially since the bitplane modification is an XOR, so you can get a bit creative with the end effect.

All these changes are in the model that I am currently synthesising now. Hopefully they will all work, and I will have a few minutes free some time soon to try them out and post some screen shots of strange looking sprites.