Saturday, 23 September 2023

Holiday project - Vulgus RE

Long time no post!

Truth is I haven't had the time or the motivation to work on any Retroports projects for the last few months as work and Real Life have both ramped up significantly. The good news is that although work has been a lot busier, I have been working on FPGA design and that has me thinking more about potential projects for MiSTer. But I digress...

For now, I've brought my laptop away on holidays and needed a non-development project to fill in my down time - usually later in the evening - and have decided to RE Vulgus. Vulgus is perhaps a little lesser known title, Capcom's first arcade game in fact, and although it didn't set the world on fire, it is a sentimental favourite of mine as I played it quite a bit back in the day.

MAME screenshot

The game is a vertical shoot-em-up and (the game) runs on a single Z80; fixed foreground (character) 2bpp layer, 4-way scrolling background 3bpp layer, and 4bpp sprites. There's a 2nd Z80 for sound, and a pair of AY-3-8910 sound chips. Nothing exotic about that configuration.

I've spent about 5 nights thus far doing RE and have made reasonable but not spectacular progress. There do seem to be quite a lot of variables and I must admit I've hit the hard stuff a bit earlier than I generally do in these exercises. I've deduced the program architecture, which is remarkably similar to Galaxian and Scramble - almost to the extent that it suggest some sort of prior/shared knowledge. I haven't read the history of Capcom in any detail, but it is interesting how alike they are.

In a nutshell, the game runs from the VBLANK interrupt, queuing low-priority commands for the background to process - mostly tasks like foreground-layer output and score calculation. The background simply runs in a tight loop waiting to process commands, while the interrupt runs a hierarchy of routines called in sequence via jump tables, with variables keeping track of which routines are to execute next interrupt. Scott (Galaxin/Scramble RE) referred to them as 'scripts', they can also be thought of as 'state machines'.

After hitting routines in every state that manipulate varying amounts of yet-to-be-deciphered data variables, I decided to turn my attention to the game map. Even that appears to be more complicated than I'd hoped; possibly stored as meta-tiles and decoded on the fly one row at a time. I think I know where the data is stored, I just need to do more work to confirm it.

In order to assist with the RE of the map, I went back and created the graphics conversion tool that I do for every project, that allows me to render palettes, CLUTs, tiles and video memory. It's not 100% accurate, but close enough; in fact the one layer that is 100% is the background layer! My tool has been hacked from project to project over the years, and was becoming quite unweildy, so I also took the opportunity to tidy it all up and simplify the process a little. The next RE project will be a bit easier again now.

Next task is to return to the code and work out a way to render the entire map, as I did for Xevious (although I was far from the first to do that). I'm pretty sure I'll be the first to do it for Vulgus though.

Whether this effort ultimately results in a transcode is not clear atm. It does have the 16x16 background layer tiles though, which make it a lot easier to port to the Neo Geo, especially with the scrolling.

UPDATE: some progress with the map decoding/rendering. I think I've identified the tables and live pointers for the map meta-tile data, map tile data and map palette data. There is a distinction between 'planet' and 'area', and I think you can travserse the entire map 3 times before it resets?!?

No comments:

Post a Comment