Take your skills to the next level with these bite-sized tutorials!

Playing Music in SGDK

Posted July 6, 2020

Playing music in SGDK might actually be a lot easier than you think. So let’s quickly look at how it works and create ourselves a little disco, what do you say? Create a new SGDK project and let’s go!

Getting The Groove

First of all we gotta get ourselves some music to play. You can of course compose your own, using a tool like Deflemask, but for the sake of this tutorial we’ll just grab a song from another game. There are many websites out there that archive old chiptune music, including of course music for the Mega Drive. But here is the first thing that you have to watch out for.

Mega Drive music comes in different formats, like .gym and others. SGDK only supports files in VGM, XGM or XGC formats.

So go ahead and grab yourself a .vgm file (or one of the others), then stick it in the resources folder of your project. (If you don’t have .vgm files sitting around and can’t find any online, then SGDK actually comes with some. Check out the sample\xgmplayer\res folder in your main SGDK folder!)

Next we’ll import the music file by adding it to our resources file, probably called resources.res. Add the following line to import the music file:

XGM track1 "musicfile.vgm"

You’ll of course have to change musicfile.vgm to whatever the name of your music file is. You can also change track1 to whatever you want, I’m just keeping things neutral here.

Lay It On Me

Now that we’ve got the music loaded and ready, it’s time to spin up that turntable! And that’s a very quick process, as playing music in SGDK actually only takes two lines of code. Add them to your main() function:


As the name implies, XGM_setLoopNumber sets how often a track should loop. A value of -1 means “infinitely” (but actually just 255 times), a value of 0 will only play a track once. With 1 it would play the track once and then loop it one more time, 2 would play the track a total of three times, and so on.

And XGM_startPlay, well…that plays the music you specify! So if you compile and run the game now, you should be hearing your track.

Pause, Resume and Disco!

That was simple enough, but let’s go a little step further just for fun. First, add a new variable to the top of your main.c file:

bool paused = FALSE;

Then, directly below it, create an array of colors for a little disco light effect:

u16 colors[6] = {

You can of course pick any colors you want, I just went with some very simple ones.

Finally, create a joypad callback so we can control the playback of our music a little. This is what the whole thing looks like:

void myJoyHandler(u16 joy, u16 changed, u16 state){
    if(changed & state & BUTTON_START){
        if(paused == FALSE){
            paused = TRUE;
        } else{
            paused = FALSE;

The code should be rather self-explanatory. If we press START on the joypad, the music will either pause or resume, depending on whether it’s already playing or not. SGDK gives us the XGM_pausePlay() and XGM_resumePlay() functions to easily accomplish that.

Implement your joypad callback at the beginning of your main function:


And now you should be able to pause/resume the playback with a quick press of the Start button! Go ahead and try it out if you want.

Finally, let’s add a little pizazz. After setting the loop number and playing the music, draw some text on screen:

VDP_drawText("Welcome to Disco Zone!", 9,13);

Then define two variables directly below that. We’ll use them in a second:

u8 currentColor = 0;
u8 ticker = 0;

Now let’s get some colors going! Inside the game loop (that is, inside the while(1) loop) add this chunk of code:

if(paused == FALSE){
    if (ticker == 60)
        ticker = 0;
        if (currentColor < 5)
            currentColor = 0;
        VDP_setPaletteColor(15, colors[currentColor]);

Let’s step through it. First of all, this logic is only handled if the track is not paused; so the light show stops along with the music. Then we increase a ticker by 1 on each frame, and when one second has passed (because our amazing program runs at 60fps, naturally) we reset it to 0 to prevent overflows. And then the magic happens: currentColor will point to the color in our colors array that we currently want to display. We increase that value if there are still more colors in the array (we defined a total of 6 colors, so the maximum index is 5) or reset it to 0 if we’re already displaying the last color of the array.

Then we use VDP_setPaletteColor to grab the color we want from the array and apply it to the text. (If you’re not quite sure how that works, check out my tutorial on the topic of text color!) And if you want a really disorienting disco experience (and don’t suffer from epilepsy) replace the index 15 with 0.

Now compile the rom, run it and get funky! Or groovy, or rock out, or whatever you do to the music you picked.


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!

Take It to the Next Level!

Want more tutorials like this one? Want sneak peeks, early access and more? Then consider supporting me on Patreon!

Become a Patron!
Just Want to Buy Me a Coffee?

Check out the rest of this tutorial series!

  • Creating Graphics for the Mega Drive
  • How to Quickly Generate C Prototype Functions in VSCode
  • Color Swapping
  • 4 Programs For Creating Mega Drive Graphics
  • Editing the Rom Header
  • Simple Game States
  • Creating a Simple Menu
  • Changing The Text Color in SGDK
  • Playing Music in SGDK
  • Converting VGZ to VGM
  • Processing Resets
  • Drawing Tiles From Code
  • 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