Adventures in Mega Drive Coding Part 2: Tiles

Mega Drive C

Motivated by my first big success (getting Text on the screen) I decided to go all in and actually try to display some graphics this time. But first I set up an IDE to make things easier for myself. I decided to go with Code::Blocks as I had used that waaaay back in the day when I first learned programming. Yes, I started with C. No, I don’t remember much of it. One cool thing is that now the emulator automatically loads up the rom after I compile the project, which saves me some time and hassle.

Anyway, with the IDE and toolchain set up I got to work on getting some graphics on the screen. The Mega Drive uses 3 planes to display stuff: 2 scrolling playfields (called Plane A and B respectively) and 1 sprite plane. Each plane is made up of tiles (also called chars) with a size of 8x8 pixels. These tiles are the basic unit when it comes to loading and displaying graphics on the MD. Thanks to SGDK it’s not hard to get one of those on the screen: You load the data, then place it. Or, translated to code:

VDP_loadTileData( (const u32 *)tile, 1, 1, 0);
VDP_setTileMapXY(PLAN_A, 1, 6, 6);

Now, the first function is still a bit confusing to me, but from what I understand it loads the tile tile into position 1 of the VRAM. I’m not entirely sure what the second 1 is supposed to be; the ´0´ indicates that the DMA should not be used, which is still a bit advanced for me.

The second function is a lot easier: On Plane A it draws the tile stored at position 1 of the VRAM, at position 6,6. The position is given in tiles, not pixels.

And the result looks like this:


Thrilling! The tile I’m using isn’t actually a graphic I loaded by the way, but rather just a C array:

const u32 tile[8]=

Obviously drawing tiles in hex is slightly less convenient than using something like Photoshop, so we’ll take a look at how to load graphics made in a different software soon, but for now we’ll stick to our hex-tile.

As you might expect, drawing multiple tiles on the screen is as simple as just calling VDP_setTileMapXY() multiple times:

VDP_setTileMapXY(PLAN_A, 1, 6, 6);
VDP_setTileMapXY(PLAN_A, 1, 7, 6);
VDP_setTileMapXY(PLAN_A, 1, 9, 6);
VDP_setTileMapXY(PLAN_A, 1, 8, 7);

However! There is still a bit more you can do with a tile. First, you can add color. Each tile on a playfield can have one of 4 different color palettes applied to it. Secondly, you can actually draw tiles flipped (horizontally and/or vertically) without having to use any more memory, which is pretty cool.

So how do we do any of that? By passing these properties into VDP_setTileMapXY():

VDP_setTileMapXY(PLAN_A, TILE_ATTR_FULL(PAL2, 0, 1, 0, 1), 6, 6);

The first and last two arguments are the same as before: We’re drawing a tile on Plane A at position 6,6. However, instead of just specifying the position of the desired tile in VRAM we actually set more properties via TILE_ATTR_FULL(PAL2, 0, 1, 0, 1). These properties are as follows:

  1. Use Palette 2
  2. Draw the tile with low priority
  3. Flip the tile vertically
  4. Don’t flip the tile horizontally
  5. Use the tile at position 1 in VRAM

A little sidenote at this point: C doesn’t actually have boolean values, so instead of trueand false you use 1and 0 respectively. And here is the result of our added properties:


As you can see the first tile is now green and upside-down, a bit like me the morning after a bender. Palette 2 doesn’t have to be green of course, that’s just the way SGDK defines it by default. We’ll get into defining palettes next time.

Another thing we’ll cover next time is the tile priority: Simply put, it allows you to change the draw order of tiles. Usually plane A is drawn above plane B, but if you change the priority of a tile you can override this. This seems like a pretty powerful feature in the hands of someone who knows what they’re doing.

And that’s it for this installment, I hope you enjoyed it. As always, if there are any questions or things you are curious about, don’t hesitate to let me know! Either post in the comments below or hit me up on Twitter @ohsat_games.

See you next time!

Like my stuff?

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

I will not send you spam or sell/give your email address to someone else. That's not how I do things. And of course you can unsubscribe at any time.

Adventures in Mega Drive Coding Part 4 - More Tiles

February 10, 2018
Mega Drive C

Adventures in Mega Drive Coding Part 3 - Importing Graphics

February 1, 2018
Mega Drive C

Adventures in Mega Drive Coding Part 1: The Journey Begins

January 12, 2018
Mega Drive C
comments powered by Disqus