Checking the Region
NOTE:
This tutorial is most likely not compatible with versions of SGDK above 1.70.
Unfortunately, I simply do not have the capacity or ability to update them right now. Read more about it here. Sorry.
Implementing a region check into your game can have many uses. You could censor content depending on the region, or just block people in a certain country from playing your game outright!
But of course there are also less evil and stupid uses for it. For example, you could load the game in a specific language, or you could compensate for PAL slowdown. So, how do we check the region of the Mega Drive our game is running on?
Bits and Bytes
As far as I know, SGDK doesn’t have a native function to check a console’s region, but it’s not really needed anyway. Every Mega Drive has the info saved at a certain address in its Version Register, which we can just look up by looking at the appropriate byte. The byte we want is stored at $A10001
. To grab it, we use:
u8 vers = *(u8 *)0xA10001;
This will store the hex value with all the info we need in vers
. Let’s print it on the screen!
First, we create a variable out
to hold our string, then we use sprintf
and VDP_drawText
to display it:
char out[12] = "";
sprintf(out,"HEX VALUE: %X",vers);
VDP_drawText(out,2,4);
If you compile and load the game now, it might look a little something like this:
But what does it mean, and how can we figure out the console’s region and video system from it?
Here’s how it works. All the info we need is saved in two bits in the byte at $A10001
that we just grabbed. Bit 7 tells us whether the system is Japanese (0
) or non-Japanese (1
). Bit 6 tells us whether we’re dealing with NTSC (0
) or PAL (1
).
This gives us four possible combinations:
Japan - NTSC
Japan - PAL
Non-Japan - NTSC
Non-Japan - PAL
If you know how to work with hex numbers, you can of course now just infer all the information from the value in vers
. But to make this whole thing a bit clearer, let’s take an example.
In my screenshot above, you can see the hex value is C0
. If we convert this to binary (maybe using a converter like this) we get 11000000
. As you can see, both bit 6 and bit 7 (the left-most ones) are set…meaning I’m in a non-Japanese PAL territory. And sure enough, my emulator is set to Europe!
Checking the Bits
For educational purposes, let’s check the bits individually.
To check if the n-th bit in a byte num
is set (or not), we can use this syntax:
num & (1 << n)
So, for example, if we wanted to check whether the console is non-Japanese (meaning bit 7 would be set), we’d check:
vers & (1 << 7)
If you’re not sure why this works, I recommend reading up on bits and bitshift operators in C.
Anyway, now that we know how to check a specific bit, let’s cover all cases and print out some info on the screen:
// Check the region bit (7)
if(vers & (1 << 7))
{
VDP_drawText("REGION: NOT JAPAN",2,5);
} else
{
VDP_drawText("REGION: JAPAN",2,5);
}
// Check the video bit (6)
if(vers & (1 << 6))
{
VDP_drawText("VIDEO: PAL",2,6);
} else
{
VDP_drawText("REGION: NTSC",2,6);
}
So, if we compile our game now, we’ll be looking at something like this:
And if we change the region of our emulator and reset it, the info on screen changes accordingly!
And thus we have a pretty neat way of checking the region and video system, so that we can adapt our game in whatever way we want!
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!
Want To Buy Me a Coffee?
Coffee rules, and it keeps me going! I'll take beer too, though.
Check out the rest of this tutorial series!
Comments
By using the Disqus service you confirm that you have read and agreed to the privacy policy.
comments powered by Disqus