Tuesday 14 July 2015

Aren't new computers better than 8-bit computers?

And now for a few minutes fun diversion while I have a headache: I ran across this video quite by accident, which looks at some of the ways in which old computers were better than the newer generation.  

Of course it is all a bit tongue-in-cheek, but there is some truth in the simple reliability and maintainability of old computers.  Anyway, I hope you enjoyed a few minutes diversion.

Sunday 12 July 2015

Hi-res bitplane mode sprites now working!

Okay, so the last main part of my burst of sprite-enhancements is now working: bitplane mode for hires sprites.  What can be seen below is two sprites on screen, fully coloured in (all one bits for the image), overlapping each other and a character-mode checkerboard in the background.  The presence of each sprite causes one bit in the output colour to be flipped, and as this occurs in each combination, it yields a distinct colour.

For a lame piece of basic, it looks kind of interesting.  Of course it would look better with some interesting animation.  I might have some fun later finding some games where turning on bitplane mode on the sprites yields pretty results, but that will have to wait until I have more time. For now I am happy that I have implemented the main outstanding sprite functions -- although the collision detection still has some wrinkles to be worked out.

Bitplane-mode/"attached" sprites working in multi-colour mode

... but not in mono-mode.

In the last couple of posts I have written about my plan for having a bitplane mode for sprites. What this means is that a sprite can be set to modify the colour of the pixels it touches instead of just painting with its own colour(s).

This can be used to do a few different things.  First, you can set the bitplane mode on one or more sprites, and have them modify the colours of a "normal mode" sprite, so that only the appearance of the first sprite will change (assuming you make the bitplane-mode sprite(s) only have bits set inside the first sprite).  But you can also have sprites that all have the bitplane mode enabled, in which case they will modify the colour of the character/bitmap/background pixels behind them instead.  This is what I do here, but lets do things in order.

First, I enabled a couple of 64x100 pixel sprites, using $0400-$07ff as the data source. I spaced them slightly.  Because bitplane sprite mode currently only works in multi-colour mode, I have put the sprites in multi-colour mode, and so we can see the three colours in each sprite (white, red, black and pink), of which two are in common (black and pink):

Next I turn on bitplane mode for one of the sprites: Now we can see that it is modifying the colours behind it, whether those colours are from a sprite or from the rest of the display.

The extra colours are all the result of fiddling with a couple of the bits in the colour.
Now if we enable bitplane mode on both those sprites, we can see the same thing happening, but with more of the bits being fiddled, so we can see more colours where the two sprites overlap:

Okay, so using random junk for the sprites isn't really the best demonstration, so I filled the sprites with solid data, and did much the same thing:

Remember that the above display is all on a blue background, with only yellow text.  All other colours are the result of having the two bitplane mode sprites over the top modifying the colours.  One is modifying bits 0 and 1, and the other is modifying bits 2 and 3.  If I had more time I could have animated them to show the effect better. Another day.

Each sprite in bitplane mode will modify a specific bit or bits in the pixel colour. In mono mode (hires sprites), the bit is the number of the sprite. In multi-colour mode, it is a pair of bits, with sprite 0 modifying bits 0 and 1, sprite 1 bits 2 and 3, sprite 4 bits 0 and 1 again and so on.

Next step is to get it working for mono/hires sprites. I think I have found the bug, and am resynthesising it now. I was reading the wrong bit from the sprite colour data vector, which was always zero.  This came about because I use the same 128-bit vector for mono and multi-colour sprites, and just pad the upper bit of each two-bit colour select in mono/hires mode.  Hopefully in a few days I will have an updated post showing hires bitplane mode sprites, and perhaps after that I will write some simple little demo that has an animated set of bitplane mode sprites that causes an area of the screen to be dimmed or something like that.

Screen shots of debugging enhanced sprites

I have managed to fix a few more bugs with the extended size sprites, as the following shots show. Apologies for the horrible quality of the images, my usual phone is not in reach, and the one I had on hand has a terrible camera.

First, here is a sprite with extended width (64 pixels wide) mode on, and extended height mode on, with a sprite height of 100 pixels.  That's a big sprite!  Sprite data addresses are still in multiples of 64 bytes, but can span upto 1KB for big sprites -- that's enough for 128 rows of unique data.

Here is another similar shot where I have changed the contents of screen memory (which is where I have the sprite pointed to for convenience) to show that it is noticing all 1KB of it:

In the previous post I spoke about adding "xray-mode" to mark foreground, background, sprite and border elements, so that I can debug the sprites more easily. This is what it looks like for this display. Looks like everything is getting correctly classified.  A little after I took these screen shots, I realised that the sprite background/foreground priority bug seems to be fixed -- either that, or I have the sense of the flag backwards. In any case, the sprites are appearing behind the text, which proves that I can do the priority sorting.  I just checked in VICE, and confirmed that I did indeed have the sprite priority flag working backwards -- so I'll add that to the next resynthesis run.  This is a good discovery, because it means that a whole bunch of extra games should work now as well.

Here is the same sprite with horizontal tiling turned on, making it repeat across the screen every 64 pixels -- great for parallax background.

What didn't work was the bitplane modification mode, which I have poked around with a bit since, and hopefully will have working soon.

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.