Wednesday, 16 August 2017

IIGS is no slam-dunk. Coco3 is looking good though...

Slow going on the Apple IIGS front, but I've finally figured out my half-screen issue when shadowing is enabled. After banging my head against a brick wall for a few days, I decided to look at the MAME driver source for the IIGS and immediately found the issue. Because the legacy Apple II hires screen memories overlap the SHR screen memory, you also need to disable the respective bits for those in the SHADOW register. And voila - a blank screen!

Now I've hit another snag. I was intending to use so-called PEI-slamming to update the modified areas of the SHR screen, which require that the direct page and stack are located in BANK1. However, I can't make any sense of the soft switches that control the bank for these and the current state doesn't make sense either. After putting out a call for help I've had a couple of responses but I'm still none-the-wiser.

Somewhat discouragingly, I did a quick experiment double-rendering the frame (one with shadowing disabled, the other enabled) and it's running a bit slower than the arcade game. Granted PEI-slamming will help, but it's going to be tight!

Whilst I'm struggling with IIGS technical issues I got impatient and started on the Coco3 (6809) port. Thus far I have a skeleton main loop that initialises the object table and adds the extra lives to the display list. I've coded up a skeleton rendering routine and fleshed out the CUR command and the tokenised command to display an extra life. It's far from optimal but it works!

First rendering on the Coco3

It's been mostly cut-and-paste from 6502 until this point. Again, the one thorn is the indirect indexed addressing mode of the 6502 but, unlike Lode Runner, it's not as extensively used in Asteroids. Other than that, there's endianity to be mindful of and I've actually swapped the byte order of words in the display list for more efficient rendering. I think this port is going to fall out relatively easily!

Saturday, 12 August 2017

Half the screen in shadow!?!

Not a lot of progress, or time to work on it.

I did, however, take preliminary steps towards eliminating flicker. The plan is to utilise video shadowing, as described in this article here, by one of the authors of the IIGS port of Wolfenstein 3D.

Currently, I've got shadowing permanently enabled and simply write to bank $01, which is shadowed on-the-fly to the SHR memory in bank $E1. Slow and flickering, but no trickery to implement and of course easier to debug. But now it's time to up my game.

So in preparation, I simply changed my initialisation routine to disable shadowing, rather than enable it. As expected, I now get a blank screen as writes to bank $01 are not copied to the SHR screen at all. So far so good.

Next step is to disable shadowing at the start of every frame render. Since I've never actually enabled it anywhere, I should still get a blank screen - right? However, when I run it, I now see the top half of the screen! And it happens in both MAME and GSPort, so it's not likely to be an emulation bug.

My first thought was Alternate Display Mode, which can be activated from the Control Panel. I can only access it in GSPort, but it's already turned off. Toggling the value regardless doesn't make any difference. And for good measure, I also disabled interrupts.

It has me completely stumped. I've fielded some queries out there but for now, no responses.

With a little more spare time tonight, but no path forward on the IIGS port, I returned to the C port. I fixed the object update and now the asteroids move as expected in attract mode. Next I added some inputs, so you can coin-up and start a game. The next bit will be tricky, rendering the player ship, as that's quite involved.

I don't really have to go through the exercise of emulating the DVG anymore; with my tokenised display list I can simply back-port that to the C version and it'll be sufficient for all platforms that it'll be running on. However I figured there wasn't too much more work to do, and it may help in understanding some nuance at some point (eg. exploding ship), so I'll persist for now.

Hopefully soon I'll learn of my stupid mistake and I can get back to finishing off the IIGS port...

Tuesday, 8 August 2017

Offsets!

I've been digging into Norbert's Atari 800XL Asteroids Emulator and trying to ascertain if/where offsets are used for various objects. To re-iterate; the position of an object is relative to the first point in the draw list of vectors that comprise the object. OTOH the position of a bitmap is (always) relative to one corner of the bounding rectangle. So in theory, displaying bitmaps in place of vector objects should require an offset for each object.

I had luck with the player ship and (all) shots. The ship appears to be a lot closer to its true location now, as evidenced by the much reduced incidence of asteroids merely passing close-by and destroying your ship. Shots are definitely much more accurate - if not perfect - as hitting the smaller asteroids requires you to, well, actually hit them!

In order to maintain the current performance, the offsets are coded directly into the compiled sprites, rather than simply offsetting the object's coordinates and thus requiring additional calculations. It did unfortunately necessitate one extra conditional branch in the ship rendering dispatcher because of an odd-valued X offset, but there was no avoiding it.

Characters don't appear to have any offsets applied, as far as I can see. As for asteroids & saucers - eek! There's a few tables with small values that could feasibly contain offsets (one, for example, is indexed by asteroid shape and size) but I'm not sure I'm going to be able to reverse-engineer exactly how it all works as it looks to my untrained eye that it starts to get into display lists. And those routines appear to be working directly on the vector hardware 1024x1024 coordinates as well.

To further add a spanner in the works, played against the Atari version there do still appear to be some inaccuracies between ship and shot and ship and asteroid, albeit subtle. They'll be fun to track down...

Anyway, I'm happy with the progress thus far, and to be honest, it's probably not going to be noticeable to any but the hard-core Asteroids experts out there... and they're not likely to be playing it on the IIGS I wouldn't think. I will look further into it, and perhaps it's a good excuse to crack open Norbert's C64 version which might be a little easier (for me) to follow.

However, I might actually move on now to the ship explosion and then flicker and sound before returning to this issue. I did notice tonight that with only a few small asteroids on the screen, the game is definitely running way too fast, so I'll look at throttling as well.

Discussions on the IIGS FB page tonight have me interested already in another project, though I would only consider it after I've done a proper feasibility study and I have collaborators. I have to admit that I even loaded up the ROM in IDAPro and had a quick look at the start-up code in my lunch break.

But at this stage it's still only a slight possibility and I still have other plans for Asteroids before I put it to bed.

Monday, 7 August 2017

5 lines of code to fix 3 issues!

With the wife wanting some company in the lounge room tonight while she did some crochet, I turned on the TV for some background noise (Jupiter Ascending - what an absolute FX overload) and fired up the laptop to get some of the easier of the remaining tasks out of the way.

To this end I defined the bitmaps for two extra characters, period and underscore, and updated the arcade code to print those rather than render them with discrete vector commands. The period is used in the high score list display, and the underscore during high score entry. Straightforward.

Next was the 'rubbish' that is left on the screen after coining-up and starting a game. I thought I'd found the culprit and fixed it. Although the subsequent game appeared to be remedied, in later games it reappeared. Back to the drawing board on that one.

Finally, despite the dipswitches being hard-coded for 3 ships/game, the 2nd and subsequent games all start with 4 ships. Found that one rather quickly; the code does an LSR on the (read-only) hardware location, branching on a Carry condition. Unfortunately not so benign when that hardware location is emulated in RAM... loading into A and then shifting was a simple fix.

Somewhat interestingly, the game appeared to run faster on my laptop. Not sure if that was my imagination, a different version of MAME, different OS, or something else. Makes me even more interested in seeing it run on a real IIGS...

Aside from the above-mentioned rubbish, that only leaves the exploding ship and proper (accurate) alignment of the sprites before I tackle proper game speed throttling, flicker and sound. I might tackle alignment next, because that has the most detrimental effect on game play atm.

Oh and another thing I've forgotten about; 2-player mode. Trivial, but another task on the list.

Friday, 4 August 2017

VCF West Preview

I've had a kind offer to demonstrate Asteroids for the Apple IIGS at VCF West so today I added a quick text-mode splash screen.

Last-minute splash screen and loading bar (mid-load)

Datajerk's c2d utility allows you to display a text splash screen whilst the game is loading. It requires a dump of $400 bytes from text memory which of course on the Apple is a dog's breakfast. So I whipped up a quick C program that would allow me to easily layout my screen and then write out a binary dump compatible with Apple II text screen memory.

Some eye-candy from the latest build.

End of game - attract mode

High score list


Will be interesting to gauge the reaction of attendees. Unfortunately it's still pre-alpha so there's glitches and flickering, but it was a last-minute offer.

Thursday, 3 August 2017

Closer to an Alpha Release!

Quick update; all of the IIGS code is pure 16-bit now except for two routines - the DVG CUR handler and the support routine that calculates SHR addresses and is only called from there. They need a complete overhaul and merging into one routine. On reflection there might just be enough savings to be had to be noticeable...

All of the rendering is done and optimised (including the small saucer and thrust) except for the exploding ship, plus I need to add data for 'dot' and 'underscore' characters for the high score entry & display. And that's it in terms of optimisation, unless I can coax more out of the hardware by using shadowing and/or blanking to my advantage. It's still around 18% faster from my crude calculations.

For an alpha release I'll rework the CUR routine, add the last pieces of the missing rendering, fix the object alignment, and add a crude text-mode splash screen. I'll tackle the flicker & sound after the alpha is out there.

Closer...

UPDATE: The DVG CUR routine - and hence all IIGS-specific code in the main execution loop - is now 16-bit and optimised. I replaced the x160 calculation with a table look-up, whose instantiation was facilitated in no small part by CA65's .REPEAT command (nice!)

My latest crude calculation suggests it is ~28% faster with 4 large asteroids on the screen. After the alpha release I'll schedule rendering strictly to the arcade frame rate and see if it can keep up. Having said that, there's no guarantees that the arcade game maintains that frame rate either - there is leeway in the code to skip a frame or two before collapsing in a heap!

Tuesday, 1 August 2017

A shadow of a doubt!?!

I've added the last of the compiled sprites - the only outstanding graphics now are the ship's thrust and the exploding ship. The former I will probably tackle next.

Aside from fixing the saucer rendering, I've been cleaning up - and in the process optimising - the rendering and erase dispatch routines. Originally they were switching back and forth between 8- and 16-bit mode; all the rendering and erase routines themselves are now pure 16-bit code and the dispatchers are almost there. I also shaved some cycles off the asteroid render/erase dispatchers by streamlining my tokenised 'asteroid' instruction.

The DVG CUR handler does some Apple IIGS video calculations and stores values for use by subsequent render/erase routines. It needs a good overhaul - converting to pure 16-bit, doing away with a few values that aren't needed, and adding another that will enable further optimisation of the render/erase routines. However there's not a huge amount of cycles to be saved per frame.

Incidentally, I was studying some IIGS code online and found the switch to change the border colour, so it's now black and does improve the aesthetics somewhat.

Finally, I activated SHR shadowing and expected to see performance gain. Nada. I'll have to go back and study (again) what that actually does and how it is of benefit (if any) in my case.

As for remaining optimisations, there's not a lot else I can come up with atm. The so-called stack-blasting technique isn't really suited to this situation, nor is moving DP to the video memory. They're generally more suited to larger objects and opaque layers. I'd say it's not going to get significantly faster than what it is now, unless shadowing changes something.

One last task I forgot about; there appears to be a requirement for an adjustment factor for the objects rendered as bitmaps. This is due no doubt to the difference between the vector objects having arbitrary 'origins' (defined as the starting point of the beam) versus the origin of a bitmap always being one corner of the bounding rectangle. With luck I can deduce the required values from Norbert's code.

Edging closer to something suitable for an alpha release just to give people a taste of the game...