From 15c7ff60f6d1809959f95ad40c496f6b70114729 Mon Sep 17 00:00:00 2001 From: trustytrojan <87675609+trustytrojan@users.noreply.github.com> Date: Sun, 3 Aug 2025 07:11:42 -0400 Subject: [PATCH 1/2] just saving my work --- .gitignore | 1 + source/arm9/console.c | 85 ++++++++++++++++++++++++++++-------------- source/arm9/keyboard.c | 14 +------ 3 files changed, 59 insertions(+), 41 deletions(-) diff --git a/.gitignore b/.gitignore index d988f2f..4a76e53 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ docs warn.log *.bz2 *~ +*.json \ No newline at end of file diff --git a/source/arm9/console.c b/source/arm9/console.c index 77b0a91..013d8e7 100644 --- a/source/arm9/console.c +++ b/source/arm9/console.c @@ -34,6 +34,8 @@ distribution. #include #include +#include +#include #include @@ -207,6 +209,12 @@ ssize_t nocash_write(struct _reent *r, void *fd, const char *ptr, size_t len) { //--------------------------------------------------------------------------------- ssize_t con_write(struct _reent *r,void *fd,const char *ptr, size_t len) { //--------------------------------------------------------------------------------- + PrintConsole *tmpConsole = NULL; + if (r->deviceData) { + // save currentConsole + tmpConsole = currentConsole; + currentConsole = r->deviceData; + } char chr; @@ -328,42 +336,27 @@ ssize_t con_write(struct _reent *r,void *fd,const char *ptr, size_t len) { consolePrintChar(chr); } + if (tmpConsole) { + // restore currentConsole + currentConsole = tmpConsole; + } + return count; } -static const devoptab_t dotab_stdout = { - "con", - 0, - NULL, - NULL, - con_write, - NULL, - NULL, - NULL -}; +int consoleCount = 1; // Since con0 already exists +static devoptab_t dotab_stdout = { + .name = "con0", + .write_r = con_write, +}; static const devoptab_t dotab_nocash = { - "nocash", - 0, - NULL, - NULL, - nocash_write, - NULL, - NULL, - NULL + .name = "nocash", + .write_r = nocash_write, }; -static const devoptab_t dotab_null = { - "null", - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; +extern const devoptab_t dotab_stdnull; // from newlib/libgloss/libsysbase/iosupport.c //--------------------------------------------------------------------------------- void consoleLoadFont(PrintConsole* console) { @@ -488,6 +481,10 @@ void consoleLoadFont(PrintConsole* console) { } +int con_open(struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { + return 0; +} + //--------------------------------------------------------------------------------- PrintConsole* consoleInit(PrintConsole* console, int layer, BgType type, BgSize size, @@ -501,10 +498,40 @@ PrintConsole* consoleInit(PrintConsole* console, int layer, devoptab_list[STD_OUT] = &dotab_stdout; devoptab_list[STD_ERR] = &dotab_stdout; + // force con0 to also behave like our custom consoles in con_write + dotab_stdout.deviceData = console ? console : currentConsole; + setvbuf(stdout, NULL , _IONBF, 0); setvbuf(stderr, NULL , _IONBF, 0); firstConsoleInit = false; + + // WARNING: Only 16 devoptab_list slots are set to dotab_stdnull, but AddDevice() iterates + // through to STD_MAX without null-checking... A PR should be put in for this... + // https://github.com/devkitPro/newlib/blob/4cc8767a6067786cbb2da969baff3481bd71461c/libgloss/libsysbase/iosupport.c#L107 + // Temporarily, just to be safe, I'll fix that problem here. + for (int i = 16; i < STD_MAX; ++i) + devoptab_list[i] = &dotab_stdnull; + } else if (console) { + // Make a new device for each new console, so that applications can write + // to consoles that are not currently being rendered. + // The firstConsoleInit code above won't be changed as to not break existing code. + devoptab_t *const dot = malloc(sizeof(devoptab_t)); + dot->write_r = con_write; + + // Set the name to be `con${consoleNumber}`. + const int consoleNumber = consoleCount++; + dot->name = strdup("con\0\0"); + sprintf((char *)dot->name + 3, "%d", consoleNumber); + + // Must set an open() callback. newlib returns ENOSYS if not set: + // https://github.com/devkitPro/newlib/blob/4cc8767a6067786cbb2da969baff3481bd71461c/libgloss/libsysbase/open.c#L12 + dot->open_r = con_open; + + // The important part + dot->deviceData = console; + + AddDevice(dot); } if(console) { @@ -570,7 +597,7 @@ void consoleDebugInit(DebugDevice device){ devoptab_list[STD_ERR] = &dotab_stdout; break; case DebugDevice_NULL: - devoptab_list[STD_ERR] = &dotab_null; + devoptab_list[STD_ERR] = &dotab_stdnull; break; } setvbuf(stderr, NULL , buffertype, 0); diff --git a/source/arm9/keyboard.c b/source/arm9/keyboard.c index 29ec311..a4ebff1 100644 --- a/source/arm9/keyboard.c +++ b/source/arm9/keyboard.c @@ -308,18 +308,8 @@ ssize_t keyboardRead(struct _reent *r, void *unused, char *ptr, size_t len) { } const devoptab_t std_in = { - "stdin", - 0, - NULL, - NULL, - NULL, - keyboardRead, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL + .name = "kb", + .read_r = keyboardRead, }; From 7a10360b5d75c3a8ea42237a6bce24aa864b1b5b Mon Sep 17 00:00:00 2001 From: trustytrojan <87675609+trustytrojan@users.noreply.github.com> Date: Sun, 3 Aug 2025 10:14:12 -0400 Subject: [PATCH 2/2] add `open()` callback for default console, comments --- source/arm9/console.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/source/arm9/console.c b/source/arm9/console.c index 013d8e7..e0f614e 100644 --- a/source/arm9/console.c +++ b/source/arm9/console.c @@ -344,11 +344,16 @@ ssize_t con_write(struct _reent *r,void *fd,const char *ptr, size_t len) { return count; } +int con_open(struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { + return 0; +} + int consoleCount = 1; // Since con0 already exists static devoptab_t dotab_stdout = { .name = "con0", .write_r = con_write, + .open_r = con_open, }; static const devoptab_t dotab_nocash = { @@ -481,10 +486,6 @@ void consoleLoadFont(PrintConsole* console) { } -int con_open(struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { - return 0; -} - //--------------------------------------------------------------------------------- PrintConsole* consoleInit(PrintConsole* console, int layer, BgType type, BgSize size, @@ -498,7 +499,8 @@ PrintConsole* consoleInit(PrintConsole* console, int layer, devoptab_list[STD_OUT] = &dotab_stdout; devoptab_list[STD_ERR] = &dotab_stdout; - // force con0 to also behave like our custom consoles in con_write + // make sure con0 also has the new behavior, in case the application + // consoleSelects a different console dotab_stdout.deviceData = console ? console : currentConsole; setvbuf(stdout, NULL , _IONBF, 0); @@ -514,7 +516,7 @@ PrintConsole* consoleInit(PrintConsole* console, int layer, devoptab_list[i] = &dotab_stdnull; } else if (console) { // Make a new device for each new console, so that applications can write - // to consoles that are not currently being rendered. + // to consoles on different bg layers, just like the Linux VTs. // The firstConsoleInit code above won't be changed as to not break existing code. devoptab_t *const dot = malloc(sizeof(devoptab_t)); dot->write_r = con_write;