Monday, 30 December 2013

Neo Kong the Movie

Firstly I wanted to know how far off the mark I was with getting the tilemap rendered every frame. So I started rendering only part of the screen and it turns out it was only missing the mark by a few lines of tiles. In fact, if I had reduced the width from 32 to the visible 28, it would have scraped in. But I wanted more headroom than that; separating the rotated and non-rotated rendering routines was the obvious start. There were also a few other very simple, very obvious optimisations.

I've no easy way to profile the rendering code that I'm running, so the next best thing is to count instructions. The original, unoptimised tilemap render routine took 20,818 instructions per frame. After the above-mentioned simple optimisations, that's now down to 11,571, an almost 50% reduction. More than enough to continue with development without further ado.

After fixing one last bug - the sprite colour for an animated Mario - I've captured a small video of the Neo Geo boot-up and straight into the game-play, with Mario running back-and-forth along the bottom girder. Even the sprite priorities are correct, as you see him run behind the oil barrel.


And so from here-on in, I'll be adding code to allow Mario to traverse the entire girder level - including jumping of course - until he can reach Pauline waiting at the top. And although I've already encountered code specifically for the girder level, I suspect when it's all said and done, I'll be able to manoeuvre Mario around all of the 4 different levels.

Slowdown

OK, so I now at least know the cause of the slowdown - the tilemap render code that is running every VBLANK (and re-renders the entire tilemap every frame), in conjunction with the sprite render code that is running every VBLANK, in conjunction with the Donkey Kong code that is running every VBLANK - takes more than 16.7ms to run!

If I eliminate the tilemap render code, it runs at the correct speed.

The tilemap render code was always a quick 'n' dirty solution; something that would ultimately be replaced by code that directly writes to the Neo Geo 'tilemap' via macros. It was also written with absolutely no regard to speed optimisation, and one option I have in the short term is to try to speed up the code just enough to get past this issue atm. I think I will have a quick go at it (I can immediately see several ways to improve it), but if it fails without too much effort I'll just bite the bullet and implement the macros that I'm using for somewhere between 50-75% of tilemap accesses. The rest I'll have to hunt down and replace with the macros one-by-one.

Sunday, 29 December 2013

There was movement at the... errr... building site

In a nutshell, Mario runs left and right now.

The areas in the other listings that tend to be completely devoid of any analysis are the 'mechanics' of game-play, such as animations - and the animation of Mario himself is certainly no exception. Tonight I managed to decode the basic left-right animation logic and now Mario can run back-and-forth along the bottom girder, and even changes height correctly.

The sprite animation logic is - interesting - to put it mildly. For some inexplicable reason, rather than a simple look-up table, animation sequences are represented by bit pairs packed into hard-coded bytes strewn amongst the code and look-up requires loops of rotations, masks, compares and register copies. The same routine also (reportedly) handles barrel sprite animation (that have their own animation cell sequences) just to further complicate matters. Hmm...

Also, it's not noticeable during game-play but Mario actually 'slides' for 2 frames between sprite changes when moving left/right.

I also tried to fix the 'slow' speed, without luck, so everything is running about 50% atm. Once I find the reason and a fix for it, I'll upload a short video of Mario running across the screen.

Friday, 27 December 2013

Your name in lights

Still trying to find 10 minutes here and there to work on the port. Managed to get name registration done, although I had to hack the score handling for the moment due to the fact that you can't actually score any points - so ignore that aspect for now...


You can also start a 2-player game and it runs right through to the end game for both now. Still a few minor issues to sort, like player 2 shows the wrong height on the "How high can you climb" screen, and those pesky ladder tops, but I'm getting closer to the point where there's only game-play code that remains to be ported.

I suspect the next few weeks won't be conducive to spending any significant amount of time on Neo Kong. I've got a week up the coast coming up but will probably leave the laptop at home in favour of the tablet and drinking with my cousin!

On a different but perhaps related note; I scored the Mega Pack for my Neo Geo X for Xmas, and I'm pretty happy that I can now play Blue's Journey on it! That'll be going up the coast with me for when my wife is playing Scrabble on her tablet! Maybe one day I'll jailbreak it and be able to play Neo Kong on it!

Thursday, 19 December 2013

Just Silly

Despite the fact that we're fast approaching the silly season, time to spend on 'silly' pursuits seems to be getting harder to find, not easier. And so in my spare 10 minutes here and there I'm still chipping away at the port...

And despite the fact that I had intentions of finishing off the non-gameplay sections of the code, I found myself looking for the code that ticks down the bonus timer. Interestingly, the timer on the barrel/girder level is handled differently and is inter-twined with the barrel deployment timers. Eventually I quickly gave up on that as I'm not ready to dive into that area of the code, but at least now I have the bonus timer ticking down... albeit it too quickly on the 1st level.

Bonus timer displayed and ticking down

And putting off the less interesting bits yet again, I wanted to see if I could make Mario at least move without much effort. But alas, although now it detects left/right movement and updates the sprite, the code to adjust the coordinates was too convoluted with too many unknown variables to hack quickly.

At least I have a starting point for the game-play, but for now I'll return to the high score update and name registration screens. Then I'll do one final audit of the non-gameplay code and then I can start to make the game playable!

Tuesday, 17 December 2013

Wading through the boring bits

Not a lot to show for it, but I've been plugging away at lunchtime again. Mario's death spin is fully animated now, and I'm slowly working my way through the sundry routines that get called during game initialisation and/or clean-up, or from the main loop. This includes the various timers and housekeeping routines that don't affect much on the display. I've still got some scoring and bonus routines to do, and the high score name registration screen. Probably a few more days before I can get into the actual game-play.

In the process of Mario's death spin I had to implement sprite flipx (I had only implemented flipy previously). That comprised about 5 extra instructions. I had previously re-ordered the sprites, thinking there'd be gaps in the sprite memory map for unused sprites, but there's a only a few. Trouble is, Mario's death routine wipes a lot of the sprite objects en masse, so I reverted all the sprites to their original indices; not too painful because I use macros to address them.

I also fixed a bug in the initialisation routines that were clobbering variables that shouldn't have been clobbered; and I haven't seen the START crash since. Fingers crossed that was the source of the issue...

Interestingly, the non-Neo Geo portion of the 68K code/data is $2B1C bytes now. Although I am optimising some of the code slightly, I suspect the end result will exceed the 16KB of the Z80 ROM. I'm loathe to estimate the percentage of code I have ported at this point, but I'm hoping by now I've hit the 50% mark. And FWIW the Neo Geo PRG ROM for Neo Kong is $3888 - a few bytes short of KOF2003!

Monday, 16 December 2013

Introductions are in order

Despite the lack of updates on this blog, I've been plugging away at Neo Kong at every opportunity.
 
I jumped the gun a bit on the game-play; I thought I'd fast-track the game initialisation and get into the actual game, but it turns out that there's too much logic dependent on the initialisation. So I stepped back and ported all the initialisation routines properly. And then I realised that I had forgotten altogether about the introduction screens...

Coin-up and watch the intro screens

So now you can coin up, start a game, watch the intro, and when the game is over (I set Mario to die immediately) it returns to the attract mode loop. All that is missing outside the game-play now is the high score registration routine - which I'll probably finish off next just to get it out of the way. Once that's complete, it should mean that the only code remaining is in-game game-play code.

I do have one intermittent bug; occasionally the Neo Geo will reset when you start a game. I suspect it's an issue with a register having non-zero high-order bits due to BIOS routines where I have forgotten to zero them first - I've already made that mistake a few times. I'll track it down at some point when it starts to get too annoying.

Although I do 99% of my testing under MAME running un-throttled, I have noticed that the game runs too slow when it is throttled. I guess that's not too surprising, given that I'm rendering the entire tilemap, plus 64 sprites, plus calling the BIOS handler every VBLANK. At some point I'll do some further analysis but right now I suspect every 2nd VBLANK is being missed and it's running at half-speed. Not an issue atm since there's plenty of display optimisation to be done.

I've also been thinking ahead about what bells 'n' whistles might be nice. I'll add a (soft) dipswitch setting to select either US/Japanese level sequence. I guess I should also look at supporting loading and saving of high scores.