Check this out. Somebody made an NES birthday card for their wife. And they used my NES sound engine tutorials to play the music. I indirectly helped make a complete stranger smile and feel happy. That’s pretty cool!
Check this out. Somebody made an NES birthday card for their wife. And they used my NES sound engine tutorials to play the music. I indirectly helped make a complete stranger smile and feel happy. That’s pretty cool!
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.
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:
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:
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 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.
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:
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”)
I mentioned in my previous post that I have started a new project. I learned a lot about code organization since the last time I worked on Explorer and I wanted to start fresh. This project isn’t as ambitious as Explorer is, so I should be able to complete it more quickly and build my nesdev skills.
The new game is tentatively titled Ramses Game. It’s a single screen action/puzzle game with a cutscene-driven storyline. I’m using ca65 to assemble and the UNROM mapper.
The story of the game goes like this:
Ramses (the hero) was kidnapped from his home by space pirates and sold at a slave auction in the Artajian system to a cruel master named Bonehammer. Now he finds himself on a monster-infested planet, trapped in a strange prison with a bomb strapped to his chest. He sees a hammer in the corner of the room. Curious, he picks up the hammer and the game for his life begins…
I got the idea to make Ramses Game while I was playing Dragon Quest V on the DS. There is a mini-game in DQV called Slime Smack, which is basically a touch-pen version of Whack-a-mole game with slimes:
Ramses Game has a very similar concept. The flow of gameplay looks like this:
There are a series of HOLES. CREATURES come out of the holes. You whack them in the SEQUENCE indicated before the TIMER runs out.
Successfully whacking all CREATURES in a SEQUENCE will add time to the TIMER and bring up a new SEQUENCE. Successfully completing a series of SEQUENCES (7-10?) will advance you to the next AREA.
If the TIMER ever reaches zero, you lose a LIFE. If you lose all your LIVES, game over.
Ramses Game will differ from Slime Smack some key areas though:
I’ve made quite a bit of progress in the few days I’ve been working on it. I have a placeholder gameboard that displays. I have input-reading routines that successfully detect button combinations. When you whack a hole on the gameboard, you get a visual and audio cue. I made some dummy monster images that display up in the sequence indicator. Everything is coming along nicely. Here is a video of current gameplay:
I’ll post some code snippets next post.
It’s been a while since I posted here. I took a break from my homebrew to write some tutorials on how to code a sound engine for the NES. You can find them here: NES Sound Tutorials.
After a long break I finally got back to some homebrew coding. I worked in 6502 for a few hours today. I didn’t work on Explorer, but rather a different game project that is less ambitious. I’ll introduce the game properly in a future post.
One thing that I needed for the new game project was a way to detect button combinations like up+A or right+B – the kind that you use to select plays in TecmoBowl. It was a little tricky to pull off. For one thing, if the player presses something like up+left+A, I need to resolve that to either up+A or left+A. I need to work that out for all possible combinations of button presses. This includes taking care of cases where A+B are pressed at the same time.
Another issue is with holding buttons. If the player holds B down and makes circles around the dpad, I only want it to catch the first combination. To do two combos in a row, they should release the B button and press it again. But what if the player hits up+B, and then while still holding B they press A+left? Does the holding of B stop the 2nd combination from being picked up or not? There are a lot of possible cases since the controller reading routine is called 60 times per second. The player can’t control their input on a frame-by-frame scale. Sliding from B to A might very well contain several frames (fraction of a second) where both buttons are held down before the B button is released. Not impossible to solve, but it wasn’t as straightforward as I had expected.
Another thing I did today was port my sound engine to ca65. I wrote my NES sound tutorials for the NESASM assembler. My tutorials are a continuation of another set of tutorials which use NESASM and I wanted to stay consistent. Plus most new nesdevers start with NESASM as it is very newbie-friendly.
My tutorial sound engine was an improvement over the one I had previously written in ca65, so I wanted to replace the old with the new. So I spent some time today porting my sound engine from NESASM to ca65. I was sure everything was going to break as soon as I got all the syntax converted. But it didn’t! Once I got it to assemble it worked perfectly on the first try! That was a relief.
ca65 lets you define scopes. Scopes enable you to keep parts of your program hidden from the other parts of your program. It’s good to separate modules, especially in large programs, so that you don’t have variable conflicts and the like. These bugs are the hardest to trace in assembly language.
I didn’t use scopes before because I didn’t really know how. But I found a great thread on nesdev about ca65 scopes that told me how to do it, so I spent some time today separating my sound and controller reading modules from the main program. Everything feels much … cleaner now. Like washing your hands after working outside on a summer day. I can physically feel how much easier things are going to be in the future for me with scopes.
I bought an NES! Ordered it on Yahoo Auctions on Saturday and it arrived at my house on Sunday! All I need now is a PowerPak and I can start testing my programs on real hardware. I can’t wait!
I’m too lazy to upload pictures here, but you can see the ones I posted to twitter here: