Thursday 4 February 2016

Neo Geo

I've managed to build the sprites for the Neo Geo port.

Knight Lore Neo Geo tiles showing mask


I thought I'd blog a bit (more) about the process I use when converting graphics for various ports. As I've stressed a few times now, the goal is always to preserve the original pixels but of course porting to different platforms often requires converting those pixel to different formats, and the Neo Geo is one of the more extreme examples.

I always like to roll my own tools (not that I've seen many ZX Spectrum Filmation Engine-to-Neo Geo conversion utilities out there) and my weapons of choice are C and the Allegro graphics library on the PC. And after using these to develop tools for many of my own little projects, I find I'm cutting-and-pasting more code than I'm writing for each new project - which is a good thing - and this latest tool was no exception.

Now although the ZX Spectrum is a purely bit-mapped system, and the Neo Geo is little more than a sprite engine, Knight Lore (the filmation engine) renders all graphics as "sprites" and this is the only reason that a Neo Geo port is even possible. Even then I'll need to make special allowances in the core for the Neo Geo (or more generically, hardware sprites) but at this point, given my past experience with Neo Geo development, I do believe it can be done.

First order of business is converting all the "sprites" from the Knight Lore sprite table into Neo Geo (MVS) tiles. For reasons I won't go into at this point, the most efficient way to organise the Neo Geo sprite tiles is to assume all "sprites" are the same size. It transpires that the largest sprite in Knight Lore is 5 bytes by 64 lines (40x64 pixels) so I've made each Neo Geo equivalent 4x4 tiles (64x64 pixels).

You might also notice that there are duplicate sprites. These are due to different objects having the same graphical representation. Not surprisingly, Knight Lore uses a lookup table to avoid such a waste of memory. However on the Neo Geo, we have a ridiculous number of tiles available and duplicating the tiles means one less level of indirection (better performance) in the sprite rendering. For those curious, this increases the number of distinct sprites from 103 to 188. That translates to no less than 3,008 tiles.

For simplicity, I've simply mapped the sprite mask to bit-plane 0, and the sprite pixels to bit-plane 1. That results in 4 colours; 0 (transparent), 1 is the mask which I will set to black, and 2 & 3 which need to be set to the same colour (eg. white) to show the correct result.

The filmation engine supports horizontal and vertical flipping of sprites. The Neo Geo also supports the same, in hardware. At first glance it seems a no-brainer, but given that the sizes of Knight Lore sprites vary, and those of the Neo Geo are fixed, it's not that simple. One solution is to keep a table of sprite dimensions and offset the sprite if flipped. A more efficient solution - on the Neo Geo at least - is to create versions of each sprite (tile) in all combinations of flip. So there'll be four (4) copies of each sprite, and now we're talking 12,032 tiles (and that doesn't include tiles required for the Neo geo BIOS, nor the Knight Lore font)! On any other system that'd be out of the question, but on the Neo Geo, it's chump-change.

So right now I have a tool that converts Knight Lore sprites to Neo Geo sprite tiles (the C ROMs). The tool then re-reads the resultant files and displays the tiles on the PC using Allegro. This code was lifted directly from a previous tool so I do actually know that the tile format is correct.

As I eluded to above, there are still two (2) fonts to extract from Knight Lore, used on the main menu and the panel (status) display. These are modest in comparison and will use only a handful of tiles.

In the mean-time, I should be able to use what I have and get a crude rendering of the main display happening. It will require some modifications to core engine, but I've done similar for the Lode Runner port some time back.

No comments:

Post a Comment