AS MANY OF YOU are probably aware, I have been working on the AA Holiday Cart for the past month or so. I was keeping this a secret up until I was positive that I was going to get it done; but here's a condensed history of its development.
The new game is titled Reindeer Rescue, and it is based on the demo I wrote about a year ago called Running Man.
As I mentioned to Manuel a couple of days ago, it has been interesting going back to the very first thing I ever wrote for the 2600 - I think if I was starting from scratch to write Reindeer Rescue today, I would quickly abandon the project because I would not believe that I could write a kernel to do what I want.
Specifically, the scrolling part of the kernel. First, let me explain briefly:
The bottom half of the play area of the screen has 8 bands of horizontally scrolling playfield and two sprites. One sprite (Santa) can move freely throughout this area and is a multicolored sprite; every line of this sprite can be a different color.
The other sprite is restricted to fitting inside the bottom band and is a single color.Each scrolling playfield band can be a different height.
At the time, I had no qualms about writing a separate minikernel for each scrolling band - which means that this section of the kernel, about 60 scanlines, is 1K of code!
If I were writing it now I would try very very hard to get the whole 60 scanlines in a single loop - and I think, ultimately, would decide that it couldn't be done without some kind of compromise (striping playfield, flicker, something).
Anyway. I don't know if that makes any sense, but it was very interesting to look back at my first 2600 code.
I ended up rewriting just about everything except the kernel, actually. The only major changes I made to the kernel were to rewrite the sprite-drawing code to use illegal opcodes (dcp), and to squeeze in line-by-line color changes of Santa all the way to the floor (previously, the runner's color couldn't change during the bottom band). This allowed Santa to have black boots, instead of running in his socks.
This was an extremely rushed development! I didn't really start modifying the original demo until I heard back from Al that he wanted me to go ahead with this; after the Philly vgXpo. So I pretty much wrote all of it in a month
Which explains why I was still making changes and testing things this morning.
Also explains why the code is so sloppy and why I never got any other sound effects in except for Santa running and jumping. And when you get points. I really wanted to get a couple of squawks, roars, and zzzzaps in there (the code for playing sound effects is in there, but never gets called and there is no sound effects data to play if it did get called). Oh well. Maybe someone can hack some stuff in there someday.
By far the trickiest part was handling collisions. There were a couple of big issues:
1) When I began development (mid-November) it was possible to back into the scrolling playfield. This was a problem because I didn't have an easy way to tell if you hit playfield from the front or the back, so I always moved you backwards if you touched playfield. This meant, though, that if you backed into the playfield it sucked you backwards and through whatever you touched! Not good. Eventual solution was to check the RAM locations where I stored the playfield data to see if there was a block of playfield behind you before I let you move backwards.
2) Because Santa leaves the ground completely in his running animation, it is possible, though difficult, to move Santa so that he ends up sticking his boots into middle of a playfield block. The picture below will hopefully help explain what I'm talking about: on the left, Santa is in a frame of animation where his feet would normally be off the ground, but his feet are flat on the ground. The right side shows what happens when his frame of animation changes to one where normally his feet would be flat on the ground: they are drawn below the ground.
This is a problem because it looks really weird to make a jump and it looks like you cleared it when suddenly the game behaves like you hit a playfield block and pushes you way back. This was very tricky to fix. In a brilliant move, since I hadn't seen the problem crop up at all since I changed from the running man animation to the running santa animation, I assumed/pretended that it had magically fixed itself. Well, what do you know, Nathan discovered that it did, indeed happen. And he discovered it last Saturday. So I was up very late on Sunday fixing this problem; what I ended up doing was changing the sprite images of Santa with his feet off the ground - I added a horizontal bar on the lowest line, so that even when his boots were off the ground, there was still a piece of sprite to collide with the playfield and prevent Santa from sticking his boots into the ground. The real trick was that I didn't want this bar to show up on screen, so it needed to be the same color as the background. That would be easy, except that there are 4 different background colors throughout the game, there isn't time to change colors dynamically during the kernel, which necessitated 9 new color tables for Santa! And each of these 23-byte tables needed to be a certain distance from the front and back of a page, plus I had already used up all the open spots for graphics data in the bank with the kernel. Fortunately, there was room in the bank to stick pieces of the kernel, so now the kernel jumps from place to place inside bank 1 like a crazed frog. Those were the biggest pain in the neck to solve but there were plenty more just like it. Alrighty; this post has gone on long enough. I'll close with an overview of where things are in the ROM:
Bank 1: Code that runs on poweron: clears registers, RAM, and TIA, and sets stack pointer. Initial setup stuff. VSYNC and the vertical retrace portion of the display, though this mostly calls subroutines that are in other banks.The play area of the kernel. Everywhere that Santa can go is drawn in this bank. Also, the portion of the title screen that draws Santa and the reindeer is in this bank. See the diagram:
Everything inside the red line is drawn in bank 1. All the graphics that go inside there are in bank 1.
Bank 2: The routine that scrolls the playfield plus all the level data. Also all the subroutines called during the vertical retrace are in this bank: Updating Santa's energy, reading the console switches, updating the score, moving the non-player-controlled objects, the subroutine that sets up a new level, and a kernel preparation subroutine.
Bank 3: This was originally going to be a bank for just music and sound effects. It ended up with those routines, and their data, plus all of the overscan. The overscan is where I deal with collisions, move Santa, play music, and process most of the game's internal logic, like checking death conditions, doing whatever needs to be done when you beat a level, etc. The kernel for the part of the screen above the red box in the diagram above is also in this bank, and the graphics for this part of the screen are here as well.
Bank 4: All other assorted kernels and pieces of kernels are here: the title screen kernel, the game over kernel, the game-winning kernel, plus the kernel for the area below the red box in the diagram above. Since all of those kernels make heavy use of 48-pixel-wide bitmaps, all the data for those bitmaps is here as well as a subroutine to display 48-pixel-wide bitmaps.