Learn how to make a space shooter for the Sega Mega Drive using SGDK! I highly recommend working through the Megapong Tutorial first, as that explains a lot of the basics of MD coding.

Megalaga 9 - Sound

Posted April 24, 2020

In space, no one can hear you scream. But you can hear lasers, explosions and video game beeps. That’s just science.

So far our game has been rather quiet. So let’s add some sound to it to spice things up! What would a classic shmup be without beeps and bloops after all?

Sound Drivers

But first we’ll briefly have to talk about sound drivers. First of all: What is a sound driver? As the name implies, it’s basically a piece of software that deals with the audio side of a Mega Drive game. Without a sound driver there would be no sound. But it also affects the quality of the sound, the possible effects, how many sounds can be played at the same time, whether sound effects can be played over music and even how the music can be composed. Sound drivers are a big deal.

Which might make it seem surprising that companies pretty much had to create their own sound drivers… and there are a lot! You know how some Mega Drive games have amazing music like Streets of Rage while others sound like the Sonic Spinball options screen? A lot of that is due to the sound driver used. Back in the day, composing music for game hardware was as much about programming as it was about actual composing.

But anyway, let’s not get too deep into it. The fact is: Your game needs a sound driver. Luckily, SGDK comes with several you can use, so you don’t have to create your own. Which is very good, because I don’t think writing your own is easy. At all. So in this tutorial I’ll show you how to use one of the included drivers to add sound effects to our game!

Importing Sounds

Alright, let’s finally get started! We’ll begin by adding a sound for our laser. First we’ll need a sound file. I have prepared one that you can download here:

Click here to download the sound file

Create a new folder in your project’s res folder called sfx, then copy the content of the downloaded .zip file into it. You might notice that it’s nothing but a regular .wav file, not some sort of special Mega Drive format. And that’s because SGDK will handle the conversion for us! Just like with graphics, you plop in a commonly used file type and SGDK will convert it to whatever it should be. This is awesome as it saves us as lot of time and headaches.

With the sound file in place, it’s time to open up resources.res to import the file into our project. Do this by adding the following line:

WAV sfx_laser "sfx/laser.wav" 5

We’re importing the file "sfx/laser.wav" under the name sfx_laser and tell SGDK that it’s a resource of type WAV, as we want to use it as a sound effect in our game. We also specify the sound engine we want to use (in our case XGM) by passing in 5. Thanks to Christian for pointing this out! Make sure to check his featured comment below for more information.

Playing Sounds

We’ve got the sound, now what do we do with it? And what about that whole sound driver thing? Let’s find out!

As I said, SGDK supports various sound drivers. The one we will be using is the XGM driver. This driver was actually written by the creator of SGDK himself, Stephane Dallongeville, and as such is rather powerful while being easy to use. Just for fun, here are some of its features:

Now there is a lot of technical stuff in there that’s not important right now, but what is important for us is that this driver can handle multiple PCM sounds at the same time. PCM is mostly used for sound effects, which is all we’ll be dealing with right now.

But enough with the theory already, let’s make our game go pew pew. Playing sound effects is a two-step process: First we declare a sound, then we play it whenever we want. And to make things easier for us, we’ll use a define. So at the top of main.c add this define:

#define SFX_LASER 64

Sounds are identified by integers and by using defines we won’t have to memorize them all. We’re also starting at 64 because the first 64 indexes (0 - 63) are reserved for music by the sound driver, so sound effects have to start at 64. Keep that in mind!

Now to declare our sound effect. At the beginning of our main() function, where we’re doing other basic initialization stuff like JOY_init(), add the following line:

XGM_setPCM(SFX_LASER, sfx_laser, sizeof(sfx_laser));

The function XGM_setPCM declares a PCM sample to the sound driver. Without this step we couldn’t play our sound, as our driver wouldn’t even know about it. The first argument is the index of the sound (in our case 64), the second is the resource we want to use; in our case we named the sound sfx_laser in our resources.res file. The final argument is the size of the sample in bytes. Luckily C gives us the sizeof() operator, which will return exactly what we need.

Now that the sound driver knows about our sound, we can play it! We’ve got a nice laser sound, so let’s play it somewhere in shootBullet (which we probably should have named shootLaser, but oh well). Near the end of shootBullet, when we set the position of the bullet sprite and increment bulletsOnScreen, add this line:


This function does what it says, it’s starts playback of a PCM sample. We tell it the sample ID, which we must have declared first using XGM_setPCM. Then we define the priority of the sound, which can range from 0 - 15 where 0 is the lowest priority. This comes into play when a sound is supposed to play on a channel that already has a sound playing. If the new sound has a higher priority, it will override the previous sound. Finally, we tell the XGM driver which channel to play our sound on. XGM supports 4 PCM channels, the first of which is usually used for music. So we’ll just play our sound on channel 2, which we access via the define SOUND_PCM_CH2.

And…that’s it! Compile the game, shoot a bullet/laser and be amazed at the aural landscape.

As you can see, dealing with sounds has a lot of theory behind it but isn’t that hard to do when you have a tool like SGDK along with a good sound driver. Things will of course get tricky when you’re making a proper game with music and several sounds playing all at once, but it’s still a lot easier to deal with than what the original MD programmers had to deal with back in the 90s.

Now that you know how to implement sounds, you might want to add an explosion sound when you’ve blown up an enemy. So here is one that you can use for some practice:

Click here to download the sound file

Remember the 3 basics steps to playing sound effects: Import, declare, play. And once you have a second sound, you can start toying around with the priorities and channels.

This marks the end of the Megalaga tutorial! Well, at least for now. However, patrons at the $2 level or higher will receive an exclusive bonus step next week where we will add a rapid fire powerup to the game. Thank you very much for reading! If you have any comments or questions, please leave them below. Until next time and be excellent to each other!

If you've got problems or questions, join the official SGDK Discord! It's full of people a lot smarter and skilled than me. Of course you're also welcome to just hang out and have fun!

Download the Project Files!

All patrons on Patreon get the complete source code for this tutorial, as well as other perks such as early access! And Patreon support also ensures that I can keep working on tutorials like this one. Become a Patron!
Just Want to Buy Me a Coffee?

Check out the rest of this tutorial series!

  • Megalaga 1 - Space
  • Megalaga 2 - Entities
  • Megalaga 3 - Enemies
  • Megalaga 4 - Enemy Movement and Input
  • Megalaga 5 - Bullets
  • Megalaga 6 - Collision and HUD
  • Megalaga 7 - Enemy Bullets
  • Megalaga 8 - Spam Protection
  • Megalaga 9 - Sound
  • Megalaga BONUS - Powerup
  • Get Words in Your Inbox!

    Be oldschool and sign up for my newsletter to get updates! Just enter your email address, prove you're not part of Skynet and you're good to go!

    Powered by CleverReach. I will not send you spam or sell/give your email address to someone else.  You can of course unsubscribe at any time. By clicking the subscribe button above, you confirm that you have read and agreed to our privacy policy.

    By using the Disqus service you confirm that you have read and agreed to the privacy policy.

    comments powered by Disqus

    Related Posts

    HaxeFlixel Tutorials!

    If you’ve popped over to the tutorial section recently you might have noticed that I’ve added my very first HaxeFlixel tutorial! It shows how to implement a simple, pixel-perfect 2D water shader which I used for Go! Go! PogoGirl. But a few of you might be wondering what a HaxeFlixel is. Well, it’s a 2D game framework that is as powerful as it is underrated! It runs on the (also underrated) Haxe language, is extremely well documented, open source, and has built-in functions for almost anything you’d need.
    Read More

    Streets of Was

    As I’m sure many of you will remember, the original Streets of Rage for the Mega Drive had multiple endings. The real canonical ending has you beat the crap out of Mr. X, thereby ending his reign of terror forever (yeah, right). However, if you confronted Mr. X with a buddy in tow, a new possible path unlocked. A quick refresher is in order. When you confront Mr. X he will ask you to join his organization.
    Read More

    Streets of Rage 2 Design Docs

    A few years ago, Yuzo Koshiro posted a pile of old game design documents for Bare Knuckle 2 aka Streets of Rage 2 on the Ancient blog to commemorate the release of Streets of Rage 2 3D on the Nintendo 3DS. These documents gave a deep insight into the game’s inner workings, technical aspects, designs and even some cut content. They were an awesome resource for one of the most awesome games ever created.

    Read More