In this tutorial series you will learn how to make a simple single-player Pong-like game for the Sega Mega Drive using SGDK! If you just want to see the full source code, you can get it from Github.

Megapong 4 - Palettes

Posted September 9, 2019

Update: I expanded the explanation on palettes a bit and removed a reference to PAL4, which of course doesn't exist. D'oh!

Last time we put a tile on screen, which was awesome. But the color was wrong, which wasn’t so awesome. Also, one tile doesn’t really make a background, does it? So we’ll take care of all that this time around. Let’s get started!

About Palettes

Okay, so why was our tile white instead of the color it should’ve been? Simply put: We didn’t tell SGDK what colors we actually wanted, so it went with the defaults. This might sound weird to you if you’ve done any gamedev on modern systems recently, because there just loading an image is enough; the engine will display it as is. However, older consoles like the Mega Drive were a lot more restricted in memory and general technical capability, so they used palettes to handle colors. The Mega Drive can handle 4 palettes with 16 colors each, of which a total of 61 can be displayed at once. That might not sound like a lot, but you can do a lot of amazing things with that!

By the way, Wikipedia has a nice little overview of the palettes of different game consoles.

Setting Palettes

But enough theory, how do we get our tile the correct color? We’re gonna do it first, then I’ll explain everything. Put this after loading the tile, but before putting it on screen:

VDP_setPalette(PAL1, bgtile.palette->data);

This gets the palette from our bgtile (remember, we compiled it as an IMAGE so it contains palette data) and adds it to PAL1. Now we just need to tell SGDK to use PAL1 for our tile. Modify your setTileXY call so it looks like this:


So the complete code is now:

VDP_setPalette(PAL1, bgtile.palette->data);

If you compile the game our tile should now shine in splendid color! Well it’s a bit too dark for that, but you know what I mean.


Alright, so what exactly did we do?

As I’ve explained, the Mega Drive can use up to 4 palettes. The line VDP_setPalette(PAL1, bgtile.palette->data); extracts the palette data from our tile (it’s a property called data of a struct called palette, which is saved in our bgtile) and sets it as PAL1 – in other words, the first palette we want to use in our game. Saving it globally like that allows other tiles to use the same palette, which saves on memory and is the whole point of storing it separately from the actual images in the first place.

Note: Contrary to what you might think, PAL1 is not actually the first palette the Mega Drive stores. In fact, you can choose between PAL0PAL3, there is no PAL4! Now if you’re wondering why we’re using PAL1 here and not PAL0: The reason has to do with our background color. I’ll explain this in more detail in my next tutorial, but for now just keep using PAL1 and upwards. It’s not like our current game needs more than one palette anyway!

What we did with VDP_setTileMapXY seems a bit more daunting, but it’s actually not as bad as it looks. Take a look at the previous and current versions side by side:

VDP_setTileMapXY(BG_B,1,2,2); //old
VDP_setTileMapXY(BG_B,TILE_ATTR_FULL(PAL1,0,FALSE,FALSE,1),2,2); //new

If you look closely, you’ll notice that we basically just replaced the 1 (pointing to a tile in VRAM) with a load of other stuff. So what does this stuff do? Here’s the signature:


Basically, TILE_ATTR_FULL is a way to more closely define how a tile is displayed. Let’s break it down:

pal: What palette you want the tile to use
prio: Remember background planes? This setting allows you to override the draw order, meaning that a tile on BG_B can be drawn atop of BG_A if this is set to TRUE.
flipV: When set to TRUE, this will flip the tile vertically.
flipH: When set to TRUE, this will flip the tile horizontally.
index: You know this one: The index of the tile in VRAM.

So instead of just telling SGDK “We want to use tile 1” we can tell it to “use tile 1 with these properties…”.

Drawing the Background

Alright, now we have the color sorted out. Time to draw our background! But setting each tile manually using VDP_setTileMapXY wouldn’t be exactly thrilling. Of course we could write a loop, but SGDK offers an easier solution in the form of a new function!

void VDP_fillTileMapRect(VDPPlan plan, u16 tile, u16 x, u16 y, u16 w, u16 h)

Can you guess what it does? Feel free to experiment a bit before reading on!

As the name implies, this function draws and fills a rectangle with tiles. The parameters are pretty self-explanatory too, but let’s break them down anyway:

plan: The background plane on which to draw your tiles.
tile: The tile index to use. Remember that you can use TILE_ATTR_FULL to set more parameters!
x: The x-coordinate (in tiles) of the upper-left corner of the rectangle.
y: The y-coordinate (in tiles) of the upper-left corner of the rectangle.
w: The width of the rectangle (in tiles).
h: The height of the rectangle (in tiles).

So how would you use this function to draw a rectangle to fill the screen with our tile, using the correct palette? By replacing our call to VDP_setTileMapXY with this:


For reference, this is what your main() function should look like right now:

//Load our tileset
VDP_setPalette(PAL1, bgtile.palette->data);

	//Do cool stuff in a loop!

//Stop doing cool stuff :(

And with that we have a background for our game, which should look like this:


That’s gonna wrap things up for today, but before I go one last word of advice in case you want to make your own tiles.

When creating your own tiles in Photoshop or another software, make sure to save the file in indexed mode. This will save the palette data separately, allowing SGDK to extract the information. Simply using RGB or another format won’t work!

Also: I highly recommend you finish this tutorial before attempting to create your own assets for it. The method we’re using to deal with palettes isn’t the best or most flexible one, since we’ll essentially be loading all the colors we need from one image (bgtile). My tile graphic already contains all the colors we’ll need for this project, so if you were to create your own tile now that would have to be the case as well. I’ll be covering better ways to work with palettes in the future, but for now I’d just like to keep things as simple as possible (which isn’t that simple at all, but that’s retro console programming for you).

Next time we’ll get things moving by adding a sprite to our project so it’ll start to look like a game. Thank you for reading and until next time!

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!

  • Megapong 1 - Hello Mega Drive World!
  • Megapong 2 - Setting Up The Environment
  • Megapong 3 - Importing Resources
  • Megapong 4 - Palettes
  • Megapong 5 - Sprites
  • Megapong 6 - Input and Paddles
  • Megapong 7 - Collisions
  • Megapong 8 - Score and HUD
  • Megapong 9 - Game Over
  • Megapong BONUS - Flashing!
  • 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