When programming a common tool to debug is to log strings to a terminal / log file. On a GBA we don't necessarily have that ability, but many emulators will implement extensions that allow us to write to a log from within our running game. Please note that those debugging extensions are only valid for the respective emulator and will not work on other ones or real hardware. In fact they might break on other guest devices, therefore make sure to only use debugging when developing something and turn it off for productive builds.
The code for talking to the debug loggers is already included in pokeemerald since 9b6b164aad
.
1. Enabling external Debugging
Go to include/config.h
and comment #define NDEBUG
:
-#define NDEBUG
+// #define NDEBUG
Make sure to remove the comment when you want to build without logging enabled, e.g. in a productive environment. Debug logs only work on the respective target devices and are potential hard hits on your game's performance if you do them a lot.
2. Print something
Wherever you want to use the debug log use the following syntax:
DebugPrintf(str, ...);
Like you would use printf
from the C standard library. View man 3 printf
or find a ressource online to see a list of format arguments you can provide and what they do, e.g.:
u32 a = 42;
DebugPrintf("a = %d. But also a = 0x%x", a, a);
should print the following string to the log: a = 42. But also a = 0x2a
, since %d
, %x
can be used to print unsigned decimal / hexadecimal integers respectively.
Additionally if you are using the default configuration, a custom format option %S
is added, which will print strings from the game, e.g.:
DebugPrintf("%S", gSpeciesNames[SPECIES_BULBASAUR]);
should print the following string to the log: BULBASAUR
.
3. Assertions
This implementation supports 2 versions of Assertions.
AGB_ASSERT(expression)
will print an error to the log ifexpression
is violated. It will then crash the game.AGB_WARNING(expression)
will print a warning to the log ifexpression
is violated. It will then continue to gracefully operate the program.
4. Viewing the logs
Since AGBPrintf
is not widely supported by emulators it is recommended to use mGBA. The default configuration will use the mGBA handler for printing to the log.
In order to view our logs, we'll need to use the mGBA emulator. Open the log viewer by going to the "Tools" menu and selecting "View Logs...". Make sure the log level checkboxes for INFO, WARNING, ERROR are checked and run your game until it hits a DebugPrintf
statement.
On newer versions of mgba you may want to disable some of the verbose logging to actually see your output over the rest of the log spam. Go to Tools->Settings->Logging
and disable whatever is spamming your log:
5. Configuration
Apart from enabling debugging you can also change the LOG_HANDLER
and the PRETTY_PRINT_HANDLER
. See the comments in include/config.h
. Note that when using LIBC as your PRETTY_PRINT_HANDLER
it was discovered that the devkitPro libc does not link well against it and it does not support the %S
format extension.
Screenshots from Someone Who Followed This Tutorial.
After following this tutorial, the biggest challenge found was setting up mGBA's logger correctly (either it's unintuitive or I'm dumb). Below are screenshots of how it's set up on my machine.
My mGBA version is 0.10.0. I set it up so it'll log in with the error flags.