My Atari 8-bit scrolling shoot ’em up Battle Eagle was released recently and came eighth in the annual ABBUC software competition, so as promised previously here’s a quick write up of how the more interesting bits work. But before I get too caught up in the “technical” stuff there’s also a little history to cover; the name is a fairly cheap play on Warhawk because Battle Eagle version 1 was attempting to be similar to Proteus Developments’ budget shooter, sticking to some fairly strict self-imposed “rules” that included deliberately limiting things to single colour in-game objects and not employing sneaky sprite engines. The early test code without any proper graphics or wave drivers looked like this…
…and was shelved because it didn’t work particularly well, suffering with some fairly nasty visibility issues. When I started thinking about writing something that used a character-based 4:1 pixel ratio mode back in 2012, that prototype donated a scroll routine before everything else was written from scratch. The name survived despite the major rewrite and a fairly fundamental change to the gameplay (the craft flies through the landscape rather than over it) just because I thought it still worked.
From a technical perspective, the final version is mostly quite simple; the backgrounds are character-based and using a 4:1 ratio pixel mode so each character has two columns of eight pixels which can each arbitrarily be one of sixteen luminances of a shared hue. The scrolling uses a 1K buffer and an LMS command on each character line (LMS commands are part of the display list and can be used to specify the mode and memory address for each character or pixel line) and, once the hardware smooth scroll shifts everything eight pixels down, the LMS addresses are rotated and the bottom line recycled to the top before it gets overwritten with the next row of graphics.
All four of the two pixel wide missiles are set to quad expansion and coloured black to mask off the the sides of the playfield (otherwise the background colour and enemies arriving or leaving horizontally would have rather messily extended out into the borders) and all of the players are set to double expansion and working in pairs to get three colour objects that loosely match those 4:1 ratio pixels of the background. The player craft takes two of the players and is just cleared and redrawn once a frame in a pretty standard way, but things start to get a bit more hairy when we get to the enemies.
There can be up to four enemy objects in motion at any time and they’re all generated from just the two remaining players. Objects each cover twenty three scanlines when drawn, which means four blocks of twenty three bytes, two written to the player definitions and the rest going to a couple of tables used to set player X position and colour for each scanline (so that’ll be around 115 bytes cleared and written per enemy each frame but it’s actually a little more). There’s a worryingly large unrolled loop running during the play area which is reading the two tables and dumping them to the player X positions each line and colour registers every second because there isn’t enough time to write all four registers on the scanlines where the machine is fetching screen data.
So objects are basically requesting the use of the hardware sprite pair for the space on screen they’re using and the problem with this is that, if there’s a conflict, whichever object requests the shared area last gets to use it, with the other occupants being partially or potentially totally invisible. The attack wave script has been arranged to prevent that happening almost completely, but for those rare occasions where it does (usually because an explosion is moving at a different speed to the object it replaced) the engine draws enemies in reverse order every second frame and two overlapping objects will flicker where they meet but remain visible.
That sprite engine means that the processor is tied up for around 192 scanlines and then the game has to clear and redraw the player object and it’s bullets, reset the X position table where the enemy objects were last frame (they don’t have to be cleared from the player data) and draw them into the work spaces at a close to rock solid fifty frames a second even when there are another sixteen bullet objects in play for the boss battles.
There’s a reason why it doesn’t have in-game music…