Computer is fixed. Time to get back to blogging about NES homebrew development. In my last post I talked about monster sequences. Monster sequences are sets of monster portraits displayed near the top of the screen. These portraits tell the player which monsters to whack.

Ramses Game - Sequence Indicator Graphics

Monster portraits tell the player what monsters to whack next.

At the time of that post I hadn’t programmed any monsters into the game. That’s changed now. I have my first dummy monsters in the game. I also have a timer and a death sequence and music. It’s almost bedtime so I’m going to keep it simple and just talk about the bomb timer for now.

Bomb Timer

The premise of Ramses Game is that an earthling named Ramses is kidnapped by space pirates and sold at a slave auction to an evil overlord named Bonehammer. Later, Ramses wakes up in a cold room and finds a bomb strapped to his chest, and it’s ticking.

So I need a timer and I need it to cause a GAME OVER when it reaches zero. Pretty standard. Super Mario Brothers 1 had a timer.

For my timer I reserve a byte of RAM for each digit, tens and ones (that’s two bytes). One byte of RAM would be enough to handle the maximum timer value of 99, but it’s easier to draw to the screen if it’s stored in RAM exactly how I want to display it. No hex to decimal conversion.

I also need a frame counter variable that counts frames to determine when one second has passed. The 6502 runs at about 60 frames per second, but I want my timer to count down a little faster, so I define a second as 50 frames:

SECOND_LENGTH = 50    ;constant value defining how many frames are in one "second"

.segment "ZP": zeropage

sec_counter: .res 1       ;frame counter for determining when one "second" has passed
bomb_timer_tens: .res 1   ;tens digit for the bomb timer
bomb_timer_ones: .res 1   ;ones digit for the bomb timer

And the subroutine that is called each frame to run the bomb timer:

.proc do_bombtimer
    dec sec_counter        ;decrement the frame counter.  If it is zero, a second has passed
    bne @end               ;else nonzero, so quit
    lda #SECOND_LENGTH     ;reload the framecounter to 50.
    sta sec_counter

    dec bomb_timer_ones     ;subtract 1
    bmi @dec_tens           ;if 0->FF, decrement the tens place and stick a 9 in the ones
    bne @draw               ;else if N->nonzero, done
    lda bomb_timer_tens     ;else if 1->0, check if tens is 0 too, if so die
    beq @die
    bne @draw                ;not 00, so we are still alive

@dec_tens:
    dec bomb_timer_tens
    lda #9
    sta bomb_timer_ones

@draw:
    jsr draw_bombtimer
@end:
    rts

@die:
    jsr draw_bombtimer
    lda #BOMB_DEATH         ;set gamestate to BOMB_DEATH gamestate
    jsr gamestate::set_gamestate
    ;game over
    rts
.endproc

Using two variables for the timer complicates the math ever so slightly, but for me the tradeoff is worth it.

Adding to the timer

In Ramses Game, when the player whacks all the monsters in a sequence, a new sequence is displayed and a little bit of time is added to the timer as a reward. This makes the game more exciting. Instead of giving you 60 seconds to clear 8 sequences, I’ll give you 20. The timer will always hover close to zero, giving the player a sense of urgency for every sequence. Adding to the timer is easy:

;-----------------------------
;  add_A_to_timer will add the value in the Accumulator to the bomb timer
.proc add_A_to_timer
    clc
    adc bomb_timer_ones     ;add value in A to the ones digit

@loop:
    cmp #10                 ;if result is 10 or more, loop to subtract 10 and
                            ;increment the tens until ones digit is less than 10
    bcc @store
    sec
    sbc #10
    inc bomb_timer_tens
    bne @loop

@store:
    sta bomb_timer_ones     ;store the result, then check to make sure the
                            ;tens digit didn't overflow.  Max time = 99
    lda bomb_timer_tens
    cmp #10
    bcc @end
    lda #9
    sta bomb_timer_tens

@end:
    jsr draw_bombtimer
    rts
.endproc

Conclusion

That’s it for the bomb timer. At least for now. There are a couple features I still want to add to the bomb timer. One is a visual cue of how much time is added to the timer upon completion of a sequence. Like a sprite that says “+8″ that floats from the sequence indicator panel to the timer. Another is palette cycling the timer display when it gets close to zero, to highlight the urgency and add to the tension.

If you have any ideas or comments, leave a comment!

I wasn’t planning to post an update so soon, but this morning when I came into work I was told that my classes were cancelled for the day. This happens occasionally at the end of the school year and generally means that I have a full day at my desk to do whatever I want. I was up late last night writing my last post, so NES programming was on my mind when I woke up in the morning.

Sequences

Today’s mission was to get Sequences up and running. A Sequence is a series of monster images at the top of the screen that indicates to the player what they should whack next. I want the Sequence engine done before I start work on monsters. It doesn’t make sense to do the monsters first. The Sequence engine is like the backbone of the game.

Here’s what I needed for Sequences:

  • An init routine that selects a starting Sequence based on Level/Sublevel.
  • A routine to draw a sequence to the screen
  • A routine to close an individual Slot and advance the engine to the next monster in the Sequence. This includes some helper routines to update graphics.
  • A routine to select a (random) new Sequence after all Slots in the current Sequence are closed.

Graphics

I decided to start by drawing a 16×16 metatile to represent a closed slot. I had time, so I took my time and ended up redrawing a lot of the dummy graphics for the Sequence Indicator:

Ramses Game - Sequence Indicator Graphics

new graphics for the Sequence Indicator.

I went for a metal look to start because it is the easiest for me to draw. For the final game I want to have several tilesets for different Level themes. I’ve always sucked at art, so I was quite surprised and happy that my tiles ended up looking so good (to my eyes anyway). I’m especially proud of my keyhole.

Loading Sequences

Loading a Sequence was pretty straight forward to code. I have a table of pointers to tables of pointers to tables of pointers: Levels->Sublevels->Sequences. Once I get down to the Sequences, I choose one randomly. My random number generator is extremely basic: I merely increment a variable once per frame. So far it does the job.

Each sequence is a series of bytes representing a monster ID. Since Sequences can be of variable size (4, 5 or 6 monsters), I have a terminator ($FF) to signal to the engine when the Sequence ends. Loading a sequence copies this series of bytes (including the terminator) to an array in RAM and sets an index variable to 0.

Drawing the sequence was pretty straight-forward too. I cleverly designed the game board so that each Slot location corresponds to a 16×16 square in the bottom-right quadrant of an attribute block. This means that the only thing that differs between the 6 Slots as far as drawing is concerned is the low byte of the target PPU address. Code is so much cleaner when everything lines up like this.

Closing Slots

Since there are no monsters yet, I have the game close a Slot every time a hole is whacked. On the game logic level, all I have to do is increment the sequence index variable and check for the terminator.

Graphically it is no more complicated than drawing a monster image into a Slot. At least it shouldn’t have been, but I got greedy and added a 3-frame animation. It took me all day to finish as I had never done background animation before today, but it was good to get my hands dirty and figure it out. I learned a lot. As a final touch, I added a door-slam sound effect at the end of the animation, which incidentally forced me to code pitch envelopes for the noise channel into my sound engine. Here’s the latest video:

Conclusion

There are still some things I want to add the the Sequence engine. I want to animate the Slots opening when a new Sequence is displayed. I also need to add in some mechanism to advance Levels/Sublevels after a specified number of Sequences are cleared. What I mean is if the player is on Level 1-1, and they knock off, say 8 Sequences, it sends them to level 1-2, which would have a different set of Sequences for the engine to choose from. These features can wait for another day though, as I’m all Nintendo’d out for today.

(BTW, Google is the ultimate word-usage authority: it’s “Nintendo’d out”, not “Nintendoed out”)