Friday, 5 February 2016

Neo Geo MVS on MAME

Had some playing around to get Knight Lore compiling under Neo Geo again, and then duly discovered how much I've forgotten about Neo Geo development! Managed to recall just enough to get some tiles showing...

A random assortment of Knight Lore tiles - Neo Geo MVS under MAME
As interesting aside... in the SOFT DIP BIOS screen it was still showing "LODE RUNNER". After checking the makefile and all the intermediate output files, the only explanation left was MAME running an old version of the development ROM (puzzledp). Nope.

Then something came back to me. If the game has NVRAM saved, it reads the game name and the settings back from the save, and doesn't use the name in the ROM header! Since the Knight Lore cartridge currently has the same GUID in the ROM header as Lode Runner, it thought it was the same game and used an old NVRAM save. Trap for young players...

UPDATE: It's slowly coming back to me...

That looks a little more organised

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.

Amiga - done and dusted

I've taken the Amiga port as far as the PC-based Allegro port. The game is now fully playable

Original ZX Spectrum Knight Lore for the Amiga - fully playable
It's been a whirlwind exercise the last few days, and it's entirely possible (even probable) that my Amiga code is absolute rubbish. For those in the know, I create a custom screen (no window) and attach a custom bitmap and specify the palette. I also maintain another bitmap for off-screen rendering, which I access via memory pointers to the bitmap plane memory. Then I use the blit functions to move areas from the buffer to the screen. For the keyboard input, I create a message port and read the matrix.

It runs on AmigaOS 3.1 and - presumably - higher. There are still a few kinks but my goal wasn't - at least at this point - to have a polished commerical-grade product. There is still one annoying bug in the C game port that causes the player to fall through the floor... can't reproduce it reliably yet so there's not much I can do about it.

EDIT: Looks like the aforementioned bug is triggered by walking on a collapsing block!

It also requires that you click on the screen with the mouse after running the game, or key presses will be directed to the shell and pause execution whenever the game outputs to stderr. I'm still looking for a solution to that one. The Amiga developer scene is almost non-existent; the few forums I have visited today have only a handful of posts from the last few years.

The 68020-based A1200 can easily cope with the speed - there's a delay in the main loop.

And it still locks up at game end, as it does on the PC.

I might try to fix the keyboard focus issue but soon I'll move onto the Neo Geo. It is going to require a completely different approach to the graphics, as there is no bitmap, only sprites. I have been thinking about it over the last few months and I think I've worked out how to approach it. The somewhat tedious and error-prone part is converting all the graphics across.

UPDATE: Removed stderr output and uploaded AmigaOS binary

Wednesday, 3 February 2016

Amiga

Not bad for a few hours work. It's currently using the most fundamental graphics functions - SetAPen() and WritePixel() - and rendering directly to the Raster Port rather than an off-screen buffer, but at least it's looking good so far!

This screen looks familiar... just before the game exits.

It exits the main game function after rendering the room and before the player appears (i.e. it crashes) but I'm happy with the progress none-the-less. I should note that it has been at least a quarter of a century since I last wrote any Amiga software!

EDIT: It wasn't a crash, but the keyboard routines returning wrong values - the game runs and objects are animated. I've also got it rendering now to an off-screen bitmap (plane) and then it blits to the display. Can't find a function that will fill a rectangular area on a bitmap (as opposed to a RastPort). Oh and it does actually crash eventually...

UPDATE: Found a way to clear a rectangular area on a bitmap. Changed screen to LORES. I need to work out how to change the palette on my custom screen.

Animating on the Amiga LORES screen
It's not rendering the sun properly - I commented-out the routine for the moment - and it crashes when day turns to night. Could be bad coordinates in my sun/moon routine... but it's getting there. Need to add keyboard input next.

Tuesday, 2 February 2016

MSX and reverse-engineered code releases

Curiosity got the better of me at lunchtime today and I took a quick look at the official Knight Lore cartridge for the MSX computer.

The core itself is identical of course, with the main differences in the system setup and hardware interfaces, most noticeably the video access routines. I was surprised they did move a couple of routines around, and there's a few more variables for as-yet-unknown purposes, but it's unmistakably a straight adaptation of the Spectrum code.

Give the almost trivial code changes I did for the TRS-80 port, I was expecting the code to more closely resemble the original. But there appears to be just a little too much MSX-specific code required for me to bother with a port of a game that already has a port. If I'm honest, I'm starting to tire of the filmation games and I need to move on to my original goal before I lose interest altogether.

On another note, I decided there was no reason not to release my reverse-engineered code listings for various projects in the past. So now you'll find disassemblies for Apple II Lode Runner, MSX Lode Runner (partial), TRS-80 Tandy Invaders, and source for the Microbee port of the same - all on my Project List page.

Enjoy!

EDIT: No luck installing the Amiga development environment on my work PC tonight...

Monday, 1 February 2016

Pentagram on the TRS-80

They say practice makes perfect, and porting filmation games to the TRS-80 is certainly no exception. The third and final installment - Pentagram - is now running, albeit slowly.

Pentagram title screen on the TRS-80

A rather busy screen on the TRS-80

Initially I was a little surprised that the game runs so noticeably slower than the previous two titles, however on reflection there is a fair bit of additional code manipulating the graphics objects that I'm yet to reverse-engineer.

I should also reiterate that the TRS-80 code is still a quick hack and far from optimal.

I also discovered the pause control (SPACEBAR) in all three games, and have updated (my copies of) the disassemblies accordingly. I have also implemented pause in the Pentagram TRS-80 port.

As was the case for Alien 8, I think there's little value in taking this disassembly too much further for the purposes of implementing Knight Lore on the Coco3 or any other platform for that matter. I don't believe the core filmation engine is any more enhanced (or even faster) than that originally coded for Knight Lore. I might check my theory on the shooting, but I'll leave the remainder of the program as an exercise for later (or others).

Preliminary alpha disassembly and TRS-80 binary available.

Next? Another Z80 port to the Australian-made Microbee (Premium) is on the cards. I'm considering then tackling the Amiga and Neo Geo ports (of my C source) - they shouldn't take a huge amount of time, and then I'll get stuck into the Coco3 6809 port of Knight Lore.

More on Pentagram

I've finished the first pass labeling the routines and formatting the data for Pentagram.

Some interesting observations. I would have to say that Pentagram was definitely based on the Alien 8 source code, but there is at least one routine that was lifted from Knight Lore rather than Alien 8. The routine in question has the same net effect - so no good reason for doing so, in fact the Alien 8 version was unrolled to (presumably) run faster - which suggests that perhaps Pentagram was started before Alien 8 was finished!?!

Seemingly for no good reason, the memory map of the game differs from the previous games. The former had variables, then font, game layout and graphic data, and then code, which included the sprite update jump table, strings etc. Pentagram starts with game layout and graphic data, followed by variables, sprite update jump table and then code. Inexplicably, the font data is right in the middle of the sprite data - I suspect the graphics data resided in multiple include files and no-one noticed the font data splitting the sprite data in two.

Knight Lore has a maximum of 40 objects at each location, Alien 8 has 56 (hence the slower rendering) and Pentagram 54. In what may be a bug in Pentagram, the list of objects to draw is only 48 bytes long (same as Knight Lore); not long enough if every object needs redrawing! Again, was that a bug fixed in Alien 8 after the source was forked for Pentagram?

I've seen no evidence (yet) that the filmation engine core itself has been enhanced. The 3D maths, including Z-ordering, all appear to be identical to the previous games.

I've yet to definitively identify the code responsible for the mechanics of re-spawning monsters and shooting, but I've got a pretty good idea of how it would be done. Rather than requiring an extension to the core per se, they should simply be implemented in the sprite update routines; at least, that's the way I would have done it. A testament to the quality and flexibility of the original design!

There are a number of routines called from the main game loop that manipulate objects that are new to Pentagram, which I would say comprise the main differences in the Pentagram source code. At this point I'm not sure what they do.

Based on the work I've done so far, I would say that producing a relocatable version and patching it for the TRS-80 wouldn't be out of the question in the near future.