Friday, 20 October 2017

Code that isn't executed has no bugs!

Very brief update.

After five days away from the keyboard I decided there was only one possible reason for the erase ship routine not working... and I was right! Because I cut-and-paste the render routine and used it for the erase by replacing the video writes with CLR, it simply wasn't possible for it to fail. And it wasn't actually failing at all - I simply wasn't calling it!

I have a jump table for the (tokenised) DVG commands, and for the previous iteration without any constant offsets, the ship was erased (for now) by a call to the generic erase_chr routine, since the ship is no larger than a character. So when I added new code to the render_ship routine that moved it...

Right now I'm where I was at with the IIGS version, with the exploding ship graphics as well. In short, all the rendering is done - it's just not done at exactly the right position on the screen. The shots are coming out near the nose of the ship, but it's still offset by a pixel or two in some orientations. Why is a complete mystery to me, as both the ship and shot appear to have a constant offset applied to them.

Most of the asteroid hits seem spot-on too, but occasionally I've seen a shot pass right through the middle of a saucer.

I was hoping things would "just work" with the scaling sorted but it appears there's something still amiss. I just hope it's not buried in the Atari display list code, because that's all Greek to me...

I'm tempted to forge ahead with the Coco3 optimisations at this point, but something is nagging at me to get it exactly right this time before moving on. At least once all the offsets are deduced and coded I can back-port to any Apple version(s)!

Thursday, 12 October 2017

Size does matter

Finally, I've implemented the exploding ship routine! I had even avoided it on the Apple IIGS version which, of course, remains incomplete at this point. It's complicated, it's messy, it's slow - but I get the same results as Norbert, sans graphical bugs.

When it comes time to implement it 'properly' (optimised) on the Coco, I'll likely generate bitmaps of the pieces rather than use a table of pixel coordinates so I can use compiled sprites.

One thing that I did notice, however, on both the Apple IIGS version and the Coco version, is that the screen appears 'compressed' vertically compared to the Atari 800XL version, despite the screen resolution being similar.

Atari 800XL version by Norbert Kehrer

Note particularly the space between rows of text in the high score table.

Coco3 version (WIP) by yours truly

Although, as I said, I had noticed it before, I didn't give it much thought until now, attributing it to larger border areas on both platforms. Aside from reducing the playing area, it does cause the high score table text to overlap. In fact, on the high score entry screen, I (also) patched the message text coordinates to space them out a bit more.

I have confirmed that Norbert hasn't patched the high score display routine at all, so something is amiss. Far from being bad news though, this is actually encouraging, because on the IIGS version I did notice some subtle pixel offsets that didn't look quite right when compared to Norbert's version. I'm hoping then that fixing this issue will not only decompress the screen - and playing area - but also fix those subtle issues!

UPDATE: I've identified the issue with the screen compression, and it's both simpler and a little more complicated than I'd guessed. Asteroids world coordinates are 13 bits (0..8191) which are shifted down to 10 bits (0..1023) - with an X offset - when inserted into the display list for rendering. My rendering routine then takes the Y coordinate, for example, and scales it to (0..191). Norbert, however, doesn't scale the Y coordinate accordingly, but simply shifts it down to 0..255 and adds an offset for rendering, even though the Atari vertical resolution is also 192. That works because the visible vertical resolution on Asteroids isn't the full range 0..1023, but rather closer to 800.

Norbert also handles the objects and text slightly differently, adding a (different) Y offset for the text. It will take some further analysis before I can implement all the subtleties, and I also (now) have to add Y-axis clipping since it's now possible some objects may have a few lines off-screen. At least I've solved the mystery.

UPDATE #2: I've sorted the scaling issue, and the game now uses the full extent of the visible area, and removed my hack for the multi-line high score entry message. I've tweaked a few things to place the score at the very top, and the copyright at the very bottom, like the arcade game. It has, however, introduced a new bug with objects rendered near the bottom of the screen...

Re-scaled Coco3 version, using all 192 lines

I've decided to add all the tweaks before I start optimisations, since it will likely be more difficult to debug/modify once I add things like doulbe-buffering and compiled sprites. I also started to add the ship & shot offsets, but can't for the life of me get the ship erasing properly. I don't really understand why not, since - for now - I've cut-and-paste the render routine, replacing the instructions that write bitmap data with a CLR instruction... simply shouldn't be possible to not work. :(

I'm off interstate for a few days - sans computer - so no new updates for a while...

Wednesday, 11 October 2017

Another last word on explosions

After adding the thrust (pixel) rendering, I decided to bite the bullet and implement the ship explosion to round off the port before I move on to optimisations for the Coco3.

I've ported all the original code, despite the fact that one of the routines isn't required for the Coco3 (or any other raster/bitmap platform) port. That latter routine is, of course, completely untested.

I've taken a slightly different approach to Norbert, who renders his graphics by referencing the player data directly. Norbert hooks into the arcade explosion rendering routine to build a table of piece offsets, which he uses in his end-of-frame rendering, together with the player ship position data.

Rather, my (tokenised) display list command for a ship explosion (piece) comprises the piece number and piece X,Y offsets, which together with the current beam position (the last CUR command) is sufficient to position the piece bitmap.

Right now it's WIP; I am plotting a single pixel per piece rather than rendering the entire piece as I debug the ported code. It's sort-of working but there's a bug or two to iron out before I can complete the piece rendering.

Interestingly the explosion is somewhat non-deterministic. The code (re)intialises a table of piece X,Y offsets in the first few frames of the explosion - but only the high byte. So each explosion may, in theory, be subtly different. Not sure if that was intended or not.

Hopefully I'll have another update tonight.

UPDATE: I forged ahead with the explosion rendering, and managed to get something that resembles the arcade, or at least Norbert's version of it. It's not quite there, so a little debugging to do yet. But it's certainly close.


Note that I have a .define for the number of starting lives, to make debugging easier - and for the video above, it's set to 1.

To summarise, once the explosion is debugged - aside from sound - that's the porting process complete! I just need to optimised the rendering and eliminate the flicker on the Coco3. Then perhaps I can look at a Star Wars port...

UPDATE: Ship explosion is now fully debugged!

A last word on explosions.

I've finished the RE of the exploding ship routines, both in the original and Norbert's emulator.

Norbert patches the explosion routine to call his routine to render a piece - using intermediate results from the caller - and then jumps back to the original routine. There's a decent amount of code that doesn't have to be executed on the emulator, but the game at that point doesn't need to be fast.

By necessity, Norbert grabs the player ship location and derives the explosion offsets from it again (since the vector commands are all relative to the ship position). He also maintains his own table of piece locations rather than use the original table, presumably because he requires less resolution.

In short, there's a non-trivial amount of code involved, even in Norbert's emulator. Since all the pieces follow a fixed trajectory it would be possible to replace all the calculations with simple look-up tables for either piece positions, or even simply a bitmap for each frame. At this point I'm undecided on how I'll approach it, but likely simply port Norbert's code.

Thus far I've ported the arcade explosion code up until the point where Norbert hooks it to render a piece. And in theory, that's all the original code that is required; the remainder is concerned only with moving the beam back to the ship position ready to render the next piece.

To re-iterate, the only outstanding bits of code on the Coco are: rendering the thrust pixel, rendering the ship explosion pieces, and the sound. Aside from those, the graphics display needs tweaking (pixel offsets adjusted) and the flicker is to be eliminated.

I'm undecided in which order I'll tackle the above-mentioned tasks. The ship explosion is tedious, the thrust isn't too bad since I've done it on the Apple IIGS already, and the sound will definitely be the last thing I do - so fixing the display on the Coco3 is looking tempting.

UPDATE: thrust rendering is done

This also means that the RE of the original is more-or-less complete, and fully-documented. I'll probably hold off releasing that until the 6809 version is fully ported and debugged, just in case...

Monday, 9 October 2017

High scores and exploding ships

Some progress in a couple of areas.

Firstly, the high score display/entry is now fully debugged. IIRC there were at least 5 bugs in the code; not completely unexpected since - by necessity - I ported pretty much all of the code in one go before being able to test any of it. It did take a little longer than I'd hoped, but nothing too nasty in there.

The game is, arguably, fully playable now, missing only the exploding ship graphics and subtle positioning tweaks. IOW the 6809 core is complete, aside from the aforementioned exploding ship. I still need to compare a running attract mode against the original, but it appears on the surface to be 100% faithful. Now the fun bits can begin; getting the display right on various platforms!

Secondly, I took a closer look at the exploding ship routine. There's a curious amount of code for such a seemingly minor aesthetic, but after a second look I understand most of what's happening now. I was actually tipped-off when I revisited the DVG ROM listing on Computer Archeology; I'm sure it has been updated recently with more information! The extra snippet of information that put the pieces together for me was the 'Ship explosion pieces velocity' table.

There are six (6) pieces of ship that expand, dissipate and disappear one-by-one - hence the relative complexity of the code. The first (few) times the code is visited in an explosion, it creates an array of piece data in zeropage memory. This is the data that is updated each iteration (frame) of the explosion as the code moves and scales the pieces.

When rendering a given piece, a VECT command is added to the display list (with Z=0) to place the beam for the start of the piece, relative to the ship position. The SVEC command is then copied from the table in the DVG ROM to render the actual piece. And here's the interesting bit. The same SVEC is then copied again, but negating the dX,dY signs to position the beam back at the start of the piece. And finally, the first VECT command is similarly copied right out of the display list itself, again negating dX,dY to put the beam back at the ship position. And then on to the next piece...

I'd like to see how Norbet rendered the explosion; it seems awfully complicated for what could be done in a few pre-rendered bitmaps. If he took some short-cuts, it may not be necessary to port this code at all. However, I will need to port it for the Star Wars port anyway, so perhaps I will tackle it regardless. It'll be a little messy as there's copious instances of shuffling data to/from index registers and zeropage memory - doesn't translate well to the 6809's 16-bit index registers of course. At least it's not absolutely critical that this code run quickly...

UPDATE: I've taken a look at Norbert's code for the exploding ship, and have identified the graphics data - stored as individual pixel offsets - for the ship explosion pieces. He uses the same mechanism and rendering routine for the thrust (which reminds me, I haven't implemented the thrust graphic on the Coco version).

I'm yet to RE his code for moving the exploding pieces... that'll have to be another time.

Interestingly I've found a bug in his emulator. He overwrites part of the ship explosion pixel data table sometime during initialisation; I've haven't RE'd that routine but I suspect it's preparing memory for the control input shadow values. Why? Because he's also using 2 of those bytes from the pixel data table for the hyperspace and fire shadow values, and they're in a different memory area than the others. So he likely moved variables around and didn't finish the job...

And when you know it's there; the bug is apparent (extraneous pixels) in the YouTube video of his Atari emulator at 0:53.

Saturday, 7 October 2017

The Universe conspires!

I've ported the remaining high score routines, which leaves just two 'core' routines remaining - those concerned with the explosion of the player ship. The high score routines are almost functional; they just need a bit of debugging but don't adversely affect anything else.

So back to the mysterious end of game issue. After the addition of the high score entry routines, the nature of the issue has changed. In retrospect, the original problem was likely the very lack of the high score routines - particularly the routine that checks for a new high score - since it does change some of the state information.

The issue then manifested itself as the high score entry screen appearing briefly, then a new game starting immediately. After an hour or so of static code review and then moving on to debugging in MAME, I'd stumbled upon something that in itself didn't appear to cause the issue, but still wasn't right - a seemingly arbitrary value in the current number of credits.

However, setting a watchpoint in MAME and running not only refused to reproduce the problem, but the game started behaving correctly on the high score entry screen! Running again without the watchpoint, and it would fail. Run it again with - all OK. Inexplicable.

And then, I finally caught it. Not part of the 'core' code, but in the Coco-specific portion, I poll the keyboard every frame and increment, amongst other things, coin counters when appropriate. FTR the arcade code does this in an NMI, but for now I'm doing it once per frame. Anyway, turns out I wasn't detecting depress properly and holding down the <5> key adds multiple credits. And whilst running the debugger and watchpoint, it's slow enough to detect just one coin if you press <5> quickly.

But the universe wasn't done with me yet. In the same portion of code, I also handle the start button. In this case I was polling the keyboard correctly, but never clearing the state of the button, so once pressed, it remained in that state permanently.

And finally, to muddy the waters even further, it turns out that pressing the start button with credits in the machine will actually abort the high score entry screen altogether and start a new game!

Here I was thinking that somewhere in the core code it was exiting the high score entry state erroneously, when in fact a combination of multiple credits and a 'stuck' start button - all in my code - were to blame! At least I finally found it...

Next, debugging high score entry (which shouldn't take long) and then the exploding player ship.

Thursday, 5 October 2017

Getting close

Today I did a quick audit of what was outstanding in the 'core':
  • 7x routines for high score display/entry
  • 2x routines to display exploding player ship

There's also a few routines not strictly necessary for game play, but will likely be implemented at some stage to round off the port:
  • 4x sound routines
  • 4x sundry routines, such as NMI

I could probably knock over the high score routines in a single session. The exploding ship was the one aspect of the Apple IIGS port I hadn't addressed, for two reasons; I don't (yet) understand the code and I don't have Norbert's graphics for it (nor do I understand - yet - how he implemented it).

UPDATE: I've done 4 of the remaining 7 high score routines; namely those that display the high score table. The remaining 3 comprise the high score initials entry.

I might finish off the high score and then have another look at the exploding ship code for the arcade. If it's still incomprehensible to me, I might move on to optimising the rendering for the Coco3 before returning to it in earnest.

Today I did manage to completely break the asteroids though when adding a few tweaks... so fixing that is first on the agenda.

UPDATE: I also fixed this, however although it detects the end of the game (and displays GAME OVER) it still doesn't actually end the game - you can still play. I had a look for this earlier, and it still eludes me.