Added debug logging functionality (#548)

This commit is contained in:
Bilel MEDIMEGH 2025-06-23 15:41:08 -04:00 committed by GitHub
parent 278894baa5
commit 038b78ca41
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 151 additions and 5 deletions

View File

@ -138,10 +138,10 @@ update: meson skrewup
$(MESON) subprojects update || true
setup_release: $(BUILD)/build.ninja
$(MESON) configure build -Dgdb_debugging=false
$(MESON) configure build -Dgdb_debugging=false -Dlogging_enabled=false
setup_debug: $(BUILD)/build.ninja
$(MESON) configure build -Dgdb_debugging=true
$(MESON) configure build -Dgdb_debugging=true -Dlogging_enabled=true
configure: $(BUILD)/build.ninja

View File

@ -16,3 +16,7 @@ For more detailed information about the project as a whole, please refer to its
- [2D Graphics](2d_rendering.md)
- [3D Graphics](3d_rendering.md)
## Utilities
- [Logging](logging.md)

26
docs/logging.md Normal file
View File

@ -0,0 +1,26 @@
# Logging
The repository includes a basic logger, that works with emulators such as MelonDS and No$GBA.
To enable it, compile with `make debug` (or the `logging_enabled` meson option).
## Usage
Wherever you want to log something, just include the `debug.h` file, and call the `EmulatorLog` function.
### Example
```c
#include "debug.h"
void someFunction(){
EmulatorLog("This will get printed on your emulator's standard output");
int aNumber = 5;
EmulatorLog("The function works just like printf, here's an integer : %d",aNumber);
}
```
## List of logging functions
- EmulatorLog : Prints the message with printf formatting but adds `[GAME_LOG] ` to the front and a newline at the end.
- EmulatorPrintf : Just prints it's arguments to the emulator's output, with printf formatting.

23
include/debug.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef DEBUGGING_H
#define DEBUGGING_H
#ifdef LOGGING_ENABLED
#define LOG_MESSAGE_MAX_LENGTH 1024
#include "charcode.h"
#include "strbuf.h"
// Prints to the emulator's standard output, with printf formatting
__attribute__((format(printf, 1, 2))) void EmulatorPrintf(const char *text, ...);
// Prints to the emulator's standard output, with printf formatting, but adds a marker prefix and a newline at the end
__attribute__((format(printf, 1, 2))) void EmulatorLog(const char *text, ...);
#else
#define EmulatorPrintf(text, ...)
#define EmulatorLog(text, ...)
#endif
#endif

View File

@ -40,7 +40,7 @@ c_args = [
if get_option('gdb_debugging')
c_args += [
'-O1,p',
'-inline', 'off'
# '-inline', 'off' todo: figure out why this makes the rom crash after the copyright screen
]
else
c_args += '-O4,p'
@ -61,6 +61,12 @@ if get_option('gdb_debugging')
pokeplatinum_args += '-DGDB_DEBUGGING'
endif
if get_option('logging_enabled')
pokeplatinum_args += [
'-DLOGGING_ENABLED',
]
endif
asm_args = [
'-proc', 'arm5TE',
'-16',

View File

@ -1 +1,2 @@
option('gdb_debugging', type : 'boolean', value : false)
option('gdb_debugging', type : 'boolean', value : false)
option('logging_enabled', type: 'boolean', value: false)

View File

@ -16,6 +16,7 @@ Static main
Library libcps.a (.version)
Library libssl.a (.version)
Object main.nef.p/src_main.c.o
Object main.nef.p/src_debug.c.o
Object main.nef.p/src_list_menu.c.o
Object main.nef.p/src_game_version.c.o
Object main.nef.p/src_menu.c.o

55
src/debug.c Normal file
View File

@ -0,0 +1,55 @@
#ifdef LOGGING_ENABLED
#include "debug.h"
#include "charcode.h"
#include "charmap.h"
#include "strbuf.h"
#define NOCASHGBAIDADDR 0x04FFFA00
#define NOCASHGBAPRINTADDR1 0x04FFFA14 // does not automatically add the newline
#define NOCASHGBAPRINTADDR2 0x04FFFA18 // does automatically add the newline
#define MELONDS_PRINT_MAX_LEN 120
volatile const char **noCashPrint = (volatile const char **)NOCASHGBAPRINTADDR1;
static void EmulatorRawPrint(const char *fmt)
{
*noCashPrint = fmt;
}
char formattingBuffer[LOG_MESSAGE_MAX_LENGTH];
void EmulatorVPrintf(const char *text, va_list ap)
{
const int res = vsnprintf(formattingBuffer, LOG_MESSAGE_MAX_LENGTH, text, ap);
int toprint = res >= LOG_MESSAGE_MAX_LENGTH - 1 ? LOG_MESSAGE_MAX_LENGTH - 1 : res;
const char *nextPrintStart = formattingBuffer;
while (toprint > 0) {
EmulatorRawPrint(nextPrintStart);
toprint -= MELONDS_PRINT_MAX_LEN;
nextPrintStart += MELONDS_PRINT_MAX_LEN;
}
if (res >= LOG_MESSAGE_MAX_LENGTH - 1) {
EmulatorRawPrint("\nlog truncated\n");
}
}
void EmulatorPrintf(const char *text, ...)
{
va_list args;
va_start(args, text);
EmulatorVPrintf(text, args);
va_end(args);
}
void EmulatorLog(const char *text, ...)
{
EmulatorPrintf("[GAME_LOG] ");
va_list args;
va_start(args, text);
EmulatorVPrintf(text, args);
va_end(args);
EmulatorPrintf("\n");
}
#endif

View File

@ -1017,5 +1017,6 @@ pokeplatinum_c = files(
'overlay119/ov119_021D0D80.c',
'overlay119/ov119_021D191C.c',
'library_tv/library_tv.c',
'dw_warp/dw_warp.c'
'dw_warp/dw_warp.c',
'debug.c'
)

View File

@ -5,9 +5,12 @@ import pathlib
homedir = pathlib.Path(__file__).resolve().parent.parent.parent
builddir = homedir / "build"
generateddir = builddir / "generated"
meson_options_file = builddir / "meson-info" / "intro-buildoptions.json"
cwsdkdir = homedir / "subprojects" / "metroskrew" / "lib" / "metroskrew" / "sdk" / "ds" / "2.0" / "sp2"
cwlibcdir = cwsdkdir / "msl" / "MSL_C" / "MSL_Common" / "Include"
cwlibcarmdir = cwsdkdir / "msl" / "MSL_C" / "MSL_ARM" / "Include"
cwextrasdir = cwsdkdir / "msl" / "MSL_Extras" / "MSL_Common" / "Include"
arm7_c_flags = [
@ -19,6 +22,7 @@ arm7_c_flags = [
"-mfloat-abi=soft",
"-nostdinc",
"-D_NITRO",
"-D__arm",
"-DSDK_4M",
"-DSDK_ARM7",
"-DSDK_CODE_ARM",
@ -37,6 +41,7 @@ arm9_c_flags = [
"-mfloat-abi=soft",
"-nostdinc",
"-D_NITRO",
"-D__arm",
"-DLINK_PPWLOBBY",
"-DNNS_FINALROM",
"-DSDK_4M",
@ -52,6 +57,21 @@ arm9_c_flags = [
"-DGAME_LANGUAGE=ENGLISH",
]
with open(meson_options_file, 'r') as optf:
meson_options = json.load(optf)
def find_option(opt: str):
return [o["value"] for o in meson_options if o["name"] == opt][0]
gdb_debugging = find_option("gdb_debugging")
logging_enabled = find_option("logging_enabled")
if gdb_debugging:
arm9_c_flags.append("-DGDB_DEBUGGING")
if logging_enabled:
arm9_c_flags.append("-DLOGGING_ENABLED")
asm_commands = [
{
"directory": builddir,
@ -74,6 +94,7 @@ nitrosdk_c_commands = [
+ [
f"-I{cwlibcdir}",
f"-I{cwextrasdir}",
f"-I{cwlibcarmdir}",
f"-I{homedir}/subprojects/NitroSDK-4.2.30001/include",
f"-I{builddir}/subprojects/NitroSDK-4.2.30001/gen",
"-o",
@ -92,6 +113,7 @@ nitrosystem_c_commands = [
+ [
f"-I{cwlibcdir}",
f"-I{cwextrasdir}",
f"-I{cwlibcarmdir}",
f"-I{homedir}/subprojects/NitroSDK-4.2.30001/include",
f"-I{builddir}/subprojects/NitroSDK-4.2.30001/gen",
f"-I{homedir}/subprojects/NitroSystem-071126.1/include",
@ -111,6 +133,7 @@ nitrowifi_c_commands = [
+ [
f"-I{cwlibcdir}",
f"-I{cwextrasdir}",
f"-I{cwlibcarmdir}",
f"-I{homedir}/subprojects/NitroSDK-4.2.30001/include",
f"-I{builddir}/subprojects/NitroSDK-4.2.30001/gen",
f"-I{homedir}/subprojects/NitroSystem-071126.1/include",
@ -131,6 +154,7 @@ nitrodwc_c_commands = [
+ [
f"-I{cwlibcdir}",
f"-I{cwextrasdir}",
f"-I{cwlibcarmdir}",
f"-I{homedir}/subprojects/NitroSDK-4.2.30001/include",
f"-I{builddir}/subprojects/NitroSDK-4.2.30001/gen",
f"-I{homedir}/subprojects/NitroSystem-071126.1/include",
@ -152,6 +176,7 @@ libvct_c_commands = [
+ [
f"-I{cwlibcdir}",
f"-I{cwextrasdir}",
f"-I{cwlibcarmdir}",
f"-I{homedir}/subprojects/NitroSDK-4.2.30001/include",
f"-I{builddir}/subprojects/NitroSDK-4.2.30001/gen",
f"-I{homedir}/subprojects/NitroSystem-071126.1/include",
@ -174,6 +199,7 @@ libcrypto_c_commands = [
+ [
f"-I{cwlibcdir}",
f"-I{cwextrasdir}",
f"-I{cwlibcarmdir}",
f"-I{homedir}/subprojects/NitroSDK-4.2.30001/include",
f"-I{builddir}/subprojects/NitroSDK-4.2.30001/gen",
f"-I{homedir}/subprojects/NitroSystem-071126.1/include",
@ -197,6 +223,7 @@ ppwlobby_c_commands = [
+ [
f"-I{cwlibcdir}",
f"-I{cwextrasdir}",
f"-I{cwlibcarmdir}",
f"-I{homedir}/subprojects/NitroSDK-4.2.30001/include",
f"-I{builddir}/subprojects/NitroSDK-4.2.30001/gen",
f"-I{homedir}/subprojects/NitroSystem-071126.1/include",
@ -221,6 +248,8 @@ c_commands = [
+ [
f"-I{cwlibcdir}",
f"-I{cwextrasdir}",
f"-I{cwlibcarmdir}",
f"-I{generateddir}",
f"-I{homedir}/subprojects/NitroSDK-4.2.30001/include",
f"-I{builddir}/subprojects/NitroSDK-4.2.30001/gen",
f"-I{homedir}/subprojects/NitroSystem-071126.1/include",