Thursday, 31 March 2016

Eating, breathing and sleeping Knight Lore!

Since 17th August 2015, I've worked on Knight Lore almost daily, throughout reverse-engineering the original in its entirety, reassembling it to run on the TRS-80 Model 4/4P, porting it to C on the PC, then Amiga and then Neo Geo, then adding the Amstrad CPC graphics to each of the aforementioned C ports and then - finally - re-writing it all in 6809 assembler for the Coco3.

It's fair to say that I've lived, breathed and slept Knight Lore over that period and I'm sure it won't surprise some at all, particularly the programmers amongst you, that I often think about it when trying to get to sleep, or shortly after waking up. And this morning was no exception. In particular, this graphics corruption on the cauldron screen.

I guess it's testament to my familiarity with the code that I was able to pinpoint the likely culprit whilst lying in bed without reference to the listing. In short, it's (another) bug in the original code, one that I've since verified in the ZX Spectrum emulator under MESS. This bug has reared its ugly head before (writing to ROM address space), just under slightly different circumstances and in another section of code; the Coco3 port has video memory where the ZX Spectrum ROM resides, hence the graphics corruption. Simple fix, all done.

I can absolutely guarantee, without a shadow of a doubt, that there are now zero (or more) bugs remaining in the Coco3 port.

Tonight's exercise will be to get it running on real hardware. I'd like to see it running from a cartridge, at least initially, but I also have Drivewire and CocoSDC options as well. Would especially like to see it running from CocoSDC too. Now to find that Coco3 of mine...

One last bug! Famous last words!

Tonight I debugged and tweaked the cauldron room; the end of game animation, game percentage complete calculations (which had a bug - doesn't come much easier than transcribing 16-bit hex constants, but I still got that wrong) and the routine to wait for a key press which was, up until tonight, labelled and working as a routine to wait for key release! Hmm...

Anyway, as far as bugs go, that just leaves the spurious graphics at the top of the screen when exiting the cauldron room which I noticed tonight, also happens if/when you die in that room. I'm yet to investigate any further, but hopefully having two triggers will make it easier to track down. Then I can tentatively consider it bug free!

Bugs aside, that just leaves performance, or more specifically, the slow-down in busy rooms. But after more play testing and comparison against the ZX Spectrum version, I'd have to say that even as-is, the Coco3 isn't actually noticeably slower at all! And the speed-up / slow-down within rooms, which I thought was limited to the Coco3 port, occurs on the original as well.

So this all begs the question - do I optimise it until its actually faster - or perhaps more accurately, less slow - than the original? Is there a point where I cross the line between improving it, and changing the game play? I'd say definitely yes, but I still think it could do with a bit of a speed boost on the slowest sections. I'll have to play around with it.

Once I've fixed the remaining glitch though, I'm going to haul out the Coco3 and burn an EPROM. Can't wait to see it running on real hardware! Worst case, that'll be the image I send to CocoFEST.

Tuesday, 29 March 2016

More play and less work...

Just enough time tonight to set the build for (almost) invincibility, set the start location two screens to the east of the cauldron room, run under the spiked balls, jump over the fire, and enter the cauldron room. I watched the wizard head west, turn north, take a few steps, and then the screen filled up with garbage. At least it's consistent!

The C port doesn't have the same issue, but it also doesn't have bubbles in the cauldron. Bug #4 for that port. Time for some serious play testing.

UPDATE: Fixed the bug in the Coco port with the screen filling with garbage. However I noticed an issue with some rubbish on the top few lines of the display whenever you exit the cauldron room. That can wait until I finish testing the rest of the cauldron room; next is to drop a special item into the cauldron.

UPDATE #2: The cauldron room is all-but-complete. There were a few bugs, thankfully easy to find and fix. You can add objects to the cauldron, and adding the last object triggers the end-of-game animation (I won't spoil it for you) and the game ends. Some nigglies; still the rubbish at the top of the screen, the animation isn't quite right, and the end of game screens don't wait for key press. But it's very, very close now.

I also borrowed an EPROM programmer today, so I'll be able to test the cartridge image on real hardware - looking forward to seeing that!

Monday, 28 March 2016

Lode Runner update complete!

I've fixed the issues introduced with the new architecture/build. I've also added an amber monitor mode to the monochrome builds, and with RGB/composite selected on the splash screen now, I've removed the in-game option to toggle.

The Project List & Downloads page has a link to the new beta demo, which includes the fix to the monochrome versions of the GAME OVER rotating banner. I've only uploaded the cartridge images this time, purely to save myself some work and they're easier and quicker to boot in an emulator. If anyone specifically wants to run from floppy on a real system, contact me.

So it's back to the Coco3 port of Knight Lore tomorrow, or whenever I get time next. Either play testing for the cauldron screen, optimising the performance, or perhaps even starting on the Amstrad CPC graphics. I should probably tackle them in the order I've mentioned them here... but I know which is the most fun...

Lode Runner revisited.

Tonight I revisited my Coco3 port of Lode Runner, bringing the build mechanism into line with Knight Lore. Again, this means a single build for cart/disk and I also added a splash screen to the game code rather than patching from a BASIC loader. On the down side, mono and colour variants are now different builds and different images - but the pros outweigh the cons.

I still need to fix some very minor issues, all introduced with the new build mechanism, and then I'll release the latest beta demo; I fixed the GAME OVER graphics in the monochrome build many many months ago.

I should probably get the cart designed and built once Knight Lore is complete so I can actually release the full game, before starting on the next port! ;) After all, no point developing it and have it sit on my hard disk unable to be enjoyed by anyone else, especially since Lode Runner is such an awesome game!

Saturday, 26 March 2016

Losing my direction... and optimisations.

Since my survey suggested that using directional controls on Knight Lore was more popular than rotational, I decided to look further into adding directional support. I fired up the ZX Spectrum version in MESS, selected directional, and started a game. The controls were still rotational.

So tonight I studied the portions of the input handler that I've previously ignored until now, and duly discovered that directional controls are only supported for joystick input. Odd, but it explains my confusion. A bit lazy on the input menu; they should have disabled selection of directional input when the keyboard is selected. Obviously these Stamper guys were complete amateurs, and likely never amounted to anything.

So for now, rotational it is. There's still just under 2KB free, so we'll see.

As for the CocoFEST demonstration, it's almost there. I do need to tweak the adaptive delay routine that is meant to temper the speed in the emptier rooms to make it more playable, and closer to the limit of the game (ie. when things get busy). I wonder how they did that back in the day - I certainly haven't decided on the most efficient course of action yet. I was thinking something along the lines of a FPS (or more likely, FPM) counter based off the GIME (slow) timer to get some idea of the effect of each object wiped and rendered.

At its worst, it probably is a tad slower than the Spectrum, though of course I haven't done a scrap of optimisation in the rendering, let-alone anywhere else in the code. There is a rather simple optimisation I can do, given the 128KB available to the Coco3, the 8KB banks of the GIME MMU, and the convenient fact that the sprite data is almost exactly 16KB and (by design) resides from $8000-$BFFF. And that is, create a second bank of sprite data that is HFLIP'd already. As you can imagine, flipping a sprite about its vertical axis (horizontally) is quite computationally expensive, and this optmisation would reduce a flip to setting a pair of bytes (or a single word) in the GIME MMU.

That aside, and play testing aside, I'm pretty happy with it. I've added a text-mode splash screen that lets the player select between RGB and composite palettes, though I might need to re-visit the choices I made for the composite palette that I cooked up in a hurry. It's pretty awesome that MESS emulates both display types!

I might spend a night with Lode Runner - sooner rather than later - and set up the build as I have done with Knight Lore, and also add the splash screen rather than using the cumbersome BASIC loader to select the display. Maybe I can talk someone into demonstrating Lode Runner at CocoFEST too?

The only additional aspect I'd like to explore, once the above are complete, is adding support for the Amstrad CPC graphics (it'll be a separate cartridge image). If the optimisations are successful and I get even a little headroom, there should be ample performance for the 2BPP graphics. Then I can finally put this to bed and release the finished product. Then retire on the proceeds.

Friday, 25 March 2016

The... castle... is alive, with the sound of music!

Very quick update - sound is fully implemented and (I think) fully working!

Details to follow...

UPDATE: Knight Lore uses the ZX Spectrum 1-bit sound output to produce, well, rather ordinary sound if we're being honest here. The sound was often criticised back in the day, but it still adds to the game play. Sound programming was never my strong suit, but it didn't take much to coax some beeps out of the Coco's 1-bit interface that sounded vaguely familiar.

I started with the music, reasoning that would be the easiest to compare playback speed. There's a table of notes in the code and each of the 4 tunes consists of an array of bytes that correspond to notes and a few bits of duration. It was straightforward to reverse-engineer and similarly trivial to re-implement in 6809. First cut sounded like music - just not a lot like Knight Lore music.

Not being able to see the issue in my code, I turned to MESS and recorded the main menu theme from both the original and my port. Loading them both up in Audacity, and aligning them approximately, I could confirm which counters were working and which weren't, as well as see the frequency difference. It wasn't too long before I spotted the bug in my code and viola - unmistakably the same tune! And as an added bonus, adding a single NOP in the inner loops slowed the speed to pretty much perfectly match the original.

With the low-level sound I/O and music done, it was a simple matter of working my way through the dozen or so sound routines, most fairly trivial and most worked first time.

There was one minor sticking point that resulted in a discussion with a few Coco gurus via FB. A couple of routines used the Z80 RLCA/RRCA instructions, an 8-bit rotate. The 6809, OTOH, only has 9-bit rotation instructions - all through the Carry bit. It wasn't too long during my aforementioned discussion that I'd hit upon a solution; if both accumulators on the 6809 have the same value, then LSLA, ROLB will effect a single RLCA. And as it happens, one routine used five (5) consecutive RRCA instructions, which I could replace with just 3 consecutive LSLA, ROLB instructions.

Although I haven't painstakingly compared all the sound effects just yet, what's there is pretty close and given the nature of the original effects, largely sufficient in any case.

Overall, I'm pretty happy that I was able to implement all the sound in a single day. I wasn't sure whether it would make the cut for the CocoFEST demo, but there it is!