Last time we left off with just a nifty title screen, but it seems kind of dull. Let’s add some music!
I will readily admit that I have very close to zero talent in the realm of music, so I knew I was going to need some help on this front.
I made a post on /r/gameDevClassifieds tagged Musician Wanted
laying out my requirements:
Despite my unusual requirements, I got quite a few replies!
I think the fact that this was [PAID]
work was a big part of that, but I was pleasantly surprised with the GDC community.
I ended up going with Mitch Foster for the job, and I highly recommend his work and professionalism.
In addition to freelancing, he’s also a sound engineer at Mega Cat Studios which has some great NES development resources on their blog.
Mitch provided me with three songs (including the Bridal Chorus for the credits) in a FamiTracker .ftm file and a handful of sound effects in another.
The next step was to open each file in FamiTracker and export to text (File→Export Text…) and NSF (File→Create NSF…), respectively.
Then, we could use the handy tools provided with Shiru’s FamiTone2 library to convert these to ca65
assembly.
I’m developing on a Macbook, so I have to run these Windows executables via Wine.
And now we should have a music.s and sfx.s, but what do we do with them?
The FamiTone2 library comes with library code for playing these data files back, but we have to modify it a bit to be able to use it in our C code. You can diff our modified famitone2.inc and famitone2.s with those provided by Shiru to see the full changes, but we’ll focus on the important parts.
There are five functions that we want to expose:
FamiToneInit
to reset the APU and initialize the libraryFamiToneSfxInit
to initialize SFX playbackFamiToneMusicPlay
to set the currently playing songFamiToneUpdate
to update FamiTone state every frameFamiToneSfxPlay
to play a sound effectFor these, let’s add new symbols with the same names (except prefixed with an underscore so that they’ll be callable from C) just above these assembly functions.
In some cases, they take arguments passed through the A, X, and Y registers.
We’ll be hardcoding some of these values and using the fastcall
calling convention to make sure calling our C functions with arguments puts the right values in the right registers.
Notice that we’re hardcoding the addresses of MUSIC_DATA
and SFX_DATA
.
We’re including the data files we generated before inside reset.s.
Now, let’s make sure to export these symbols and put them in the right memory segment.
Now, we can include the library from our reset.s, but first we’ll need to set a few options so that it will compile with the features we need.
And finally, we’ll need a C header to define these functions for the C compiler.
We’re now ready to go back and add the music to our title screen:
We now have an exciting theme to listen to while admiring our title screen! The screen very clearly instructs us to “Press Start”, so let’s play a sound effect every time we do.
Our game is really starting to come together! That’s all for now, but next time we’re going to add our level and credits screens into the mix and handle transitions between them.