Monday, December 29, 2014

Worst intro cutscene ever?

It's a toss-up which is worse, the intro to Bad Dudes, or the intro to Robo-Ninja.  I'll let you decide:

Bad Dudes:


Robo-Ninja:

video

Tuesday, December 23, 2014

Condensing my room definitions

I recently realized that I was doing it wrong in my room definitions. Previously, I was storing the addresses of each section of background wall data, like:

TestRoom
    .byte #<TestRoomLineDefsA   ;background definition.
    .byte #>TestRoomLineDefsA   ; The < and > signify low and high bytes of 
    .byte #<TestRoomLineDefsB   ; the pointer address.
    .byte #>TestRoomLineDefsB
    .byte #<TestRoomLineDefsC   ; Atari backgrounds are made up of 3 chunks
    .byte #>TestRoomLineDefsC   ; of data which is why there are 3 pointers.
    .byte #ROOM_COLOR_BROWN     ;room colors
    .byte #ROOM_COLOR_GRAY
    .byte #TOP_CLOSED           ;door flags 
    .byte #<EnemyDefSlime       ;what enemies are in this room
    .byte #>EnemyDefSlime
    .byte #3                    ;number of enemies
    .byte #NO_ITEM              ;any special items in the room


That's 6 bytes for each room that are used to point to the background data. Realistically, there's no way I'm going to have more than 255 different room backgrounds. (There's just not enough ROM space for it), so an int Id seems to make a lot more sense, with the assumption that all 3 sections are always going to be used together:

TestRoom
    .byte #ROOM_STARTING
    .byte #ROOM_COLOR_BROWN
    .byte #ROOM_COLOR_GRAY
    .byte #TOP_CLOSED 
    .byte #<EnemyDefSlime
    .byte #>EnemyDefSlime
    .byte #3
    .byte #NO_ITEM

Doing so, I've cut the space required for a room definition in half. That means I can have twice as many rooms in my game before I run out of space. I think that's worth it! If I get around to it, I could cut out another byte per room by changing the Enemy Definition pointer to an ID instead of a pointer, but I'm not sure it's worth the effort just to save a byte per room. We'll see how desperate I get for space by the end, though.....

Sunday, December 21, 2014

Closed, locked, and fake doors

To be somewhat true to the GBA version, Atari Anguna needs doors: doors that open with the right colored key, doors that open when all enemies are killed, and fake walls that don't look like doors, but allow you to walk through them. Plus, since I'm reusing room wall layouts to save cartridge space, I want the ability to say "use room XYZ but seal off the left door"

This was the new challenge this month. I had to find a mechanism for dynamically drawing doors. The general idea would be just to fill in the "door" opening in the wall with more wall -- either some other color for a locked door, or with the wall color for sealed or fake walls.

The trick is dynamically doing this. The top and bottom walls/doors weren't too bad. I made a rule that no enemies will overlap those scanlines, and, by writing separate kernel code for those lines, gave me enough time to modify the background dynamically. It's easy enough to just modify the "background color" (not the color of the walls, but the backdrop) to either match the wall color or be the lock color, just for those few scanlines, then change it back.

The left and right walls are trickier. I don't have time on each scanline to fiddle with things. (And there's not enough ram to write all the room data to ram before rendering, modify it at that time, and then render from ram.)  Luckily I have one more Atari graphics object that I can use: the ball.

The Atari, which was pretty much made to play Pong and Combat, supports 2 sprites, 2 missiles (which match the sprites in color, and are little more than a dot, square, or line, depending on how many scanlines you show them), and a ball, which matches the playfield's color, and is also just a dot, square, or line.

The fact that the ball matches the playfield color makes it easy -- before the frame, I set it up for the ball to display either at the left, right, or not at all, then don't touch it -- it will keep displaying on each scanline, and make a nice looking wall on the right or left. I had to modify my collision code to check for collisions with both the ball and the walls, instead of just the walls, but that was straightforward. The only hitch I've run into so far is the ball collision always takes priority over the wall collision, so for a "fake" wall, the whole wall becomes fake (as the game detects a collision with the ball, which is determined in this case to be a non-blocking collision) instead of just the small portion where there's a hole in the wall.

So far I've got the left and right doors working, and the top doors. I just need to write the kernel code for the bottom door, and I can knock doors off my checklist.

(And I've got about 3 more blog-posts worth of content from the past month that I haven't gotten around to posting about, so maybe I'll find time to write them soon!)

Batari Basic and Fixed Point

When I'm too tired/frustrated to work on my NES game, I've been playing around with ideas for another hobby project that I've he...