[stella] My First Atari 2600 Game

Subject: [stella] My First Atari 2600 Game
From: Christopher Tumber <christophertumber@xxxxxxxxxx>
Date: Mon, 07 Oct 2002 00:30:35 -0400

For those of you who don't know me, I've been involved in the Vectrex scene for several years and have a few carts out for that system. Recently I started working with the 2600 - Truth be told, I've never been a huge, huge 2600 fan but I've been really, really, really enjoying programming it!! Programming the 2600 is surprisingly similar to the Vectrex (real time manipulation of the graphics hardware, with the focus of the program being on hyper-optimised display code) except even more meticulous. Programming the 2600 definately appeals to us obsessive types!

Attached is My First Atari 2600 game. The title has ranged from "Space Instigators" to "Yet Another Invasion" to "Mother of all Invasions" to "Invade This!". Today I'm leaning towards YAI ("The universe never seems to run out of punk-ass aliens who think they can push the Earth around. So once again you must climb into your ship and teach them a lesson in peacefull co-inexistance!") but that could change tomorrow...

It's not QUITE done but since I'm going to be posting an announcement tomorow for a little release party next month, I thought I'd break the ice here first. (I hope to have it finished this week-end, but you know...)

- Invaders don't shoot yet
- Invaders don't land yet (Things get strange as the Invaders hit the bottom...)
- There are a couple more scan lines between rows of Invaders than I'd like
- Display of player's shots is a little dodgy as they pass through the ranks of the Invaders
- Rows of Invaders are not quite stable and occaisionally drop down a scanline (cycle count problem)
- Probably some other bugs I just haven't noticed

(I'd hold off posting this until it's finished but I'm down to 15 bytes ROM so I'm going to have to pull it apart a little and it may be a while before it's this intact again but I don't want to put off anouncing the release party...)

But really, the only big issue is making the Invaders shoot... (Which shouldn't be a huge deal since they're going to share the player's shot routine (multiplexed) though I am going to have to free up a few bytes of RAM... Sigh!)

There may be a few other cosmetic changes, like the saucer tends to come out a little too frequently but most of the essential game engine is complete. Source will follow once it's actually finished (It's a mess though, with a hideously complex display kernal, routines in RAM, very, very little stack use, no STA WSYNC on some scanlines, etc...)

What follows is a brief discussion of the game, how it works, how it came together, etc...

I've actually been working on a completely different game for some time. It's a game inspired by Mr. Driller (Great game! If you're not familiar with it, it's basically Boulder Dash + Tetris). I've already got the kernal and much of the game done to that one but started looking at using the RESP0/RESP1 trick for that game instead of what I'm currently using (background colour switching to make a grid of blocks). But RESP0/RESP1 is no good for that app due to the colour restrictions using RESP0/RESP1 - You can't really change colours between sprites except all the Player0s can be a different colour from the Player1s. But once I started fooling around with RESP0/RESP1 I got hooked on creating the ultimate 2600 version of that classic 11x5 game...

So, this started out as an 11x5, but it's not, it's 9x5. The reason it's not 11x5 is twofold:

1) (Most importantly) As mentioned the last time this came up, if you align the sprites closest together with RESP0/RESP1 then when you remove a sprite, the previous sprite is shifted out of alignment to the left. It is possible to eliminate this shifting by spacing the spites a little further apart as I have done, however if you do that then a row of 11 sprites is extremely wide and there's no room for the Invaders to move left and right (A full row could move like 2 or 3 pixels back and forth). This could be a usefull technique for some other game, one where the sprites don't need to move horizontally so much (Breakout/Arkanoid) but for this kind of game it was a serious problem.

2) With this wider configuration there aren't very many cycles per scanline to process other things (specifically the player's shot) - 4 cycles per sprite, plus any loop overhead and pushing values into GRP0 and GRP1 doesn't leave a lot left over. I'm not saying it'd be impossible but even with mine trimmed down 9 sprites it's an incredibly tight squeze.

And so I had to make the decision to go with 9x5. That was a tough, tough day! I'd really wanted to call the thing simply "11x5" and make the big splash. Ahhh Hubris!

So, IMHO Invaders21 really is probably as good as it's going to get for an 11x5 game. Again, I'm not saying it's impossible because all it would take is a solution to the shifting problem (or a completely new trick). But until that time it's just not gonna happen. (I realise this is not exactly news, I'm just setting the stage for the guy who comes along and actually does it...)

So it's a tradeoff: Invaders21 does 11x5 very nicely but doesn't look much like the original. Mine is only 9x5 but I hope you'll agree looks pretty good....

Here's another funny story - I almost abandonned the project fairly early on because I couldn't figure out how to turn OFF any of the sprites (I could do a solid row of 8 or 9 or 10 or 11 sprites, but I couldn't take out a couple sprites in the middle). At first I tried using the background as a shutter by changing the display priority but I couldn't get the alignment right - There was always a pixel sticking out or it was overlapping the next sprite. I had thought that Invaders21 and Inv3 were just static displays (proof of concept screens) so that there was no real way to turn them on and off on the fly (Here's the funny part!). I've only every used StellaX as a dev tool (Why play 2600 games on your computer when you can play them on your TV?) My two projects don't use the reset switch just the joystick button to start as I've always found having to get up off the couch to restart a game a particularly annoying. So when I ran Invaders21 and Inv30 I hit the space bar and probably the 5 and 1 keys (like Mame) and nothing happended I assumed static displays... So I spent a few days spinning my wheels trying to come up with a way to mask/hide/turn off sprites.

Heh, heh, only later did I realise that that couldn't be since Invaders21 is available from Hozer and I'd read a couple reference to how it and Inv30 run &etc. I went "Oooooooh! Dhuh!" and had to check the docs to find out which key mapped to the reset switch.... At which point I was able to check out the source for Inv30 and realise that it was possible to eliminate a sprite just by skipping the relevant RESP0 or RESP1....


There is a serious consideration if you want to use the RESP0/RESP1 trick - It doesn't handle less than 2 copies of a sprite well. Once you have 1 or 0 copies of either sprite you need an exception handler of some kind to deal with "turning off" that portion the RESP0/RESP1 trick and positioning the sprite(s) properly. That is, if Player0 only has one sprite, you still need to do the trick for Player1 but you also have to position Player0 with a "regular" RESP0 and probably an HMP0/HMOVE. Or vice versa. Or when both Player0 and Player1 need to be postioned in the "normal" way you also have to handle that. Or when either/or have no sprites to be shown, you have to handle that as well. You get the idea...

3 of the scanlines between rows of Invaders are caused by this - One scanline each (potential) single RESP0 and RESP1 and then another for the HMOVE. I hope to be able to eliminate one of those scanlines by combining both the RESP0 and RESP1 into one scanline. At the moment I'm using the sprite postioning code (HorzTable) from Inv30 to position the "single" Invaders (as well as the UFO, player's ship and the shot) but that'll be gone next in order to do both RESP0 and RESP1 in one scanline. (FWIW, I believe that's the only "borrowed" code I'm currently using) [Eliminating that table would also free up the ROM space I need...]

(Somebody's probably already dealt with this issue and posted about this but this is my monologue so there you go!)

Anyway, this is geting rather lengthy as it is, so I'll wrap it up now. Attached is the most recent bin, should run fine on any emulator that supports the RESP0/RESP1 trick and real hardware (At least it runs fine on my Supercharger, haven't tried it on a real cart ROM but no reason why it shouldn't...)


Attachment: Invasion.bin
Description: Binary data

Current Thread