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..e0f614e 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,43 +336,33 @@ 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 con_open(struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { + return 0; +} +int consoleCount = 1; // Since con0 already exists -static const devoptab_t dotab_nocash = { - "nocash", - 0, - NULL, - NULL, - nocash_write, - NULL, - NULL, - NULL +static devoptab_t dotab_stdout = { + .name = "con0", + .write_r = con_write, + .open_r = con_open, }; -static const devoptab_t dotab_null = { - "null", - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL +static const devoptab_t dotab_nocash = { + .name = "nocash", + .write_r = nocash_write, }; +extern const devoptab_t dotab_stdnull; // from newlib/libgloss/libsysbase/iosupport.c + //--------------------------------------------------------------------------------- void consoleLoadFont(PrintConsole* console) { //--------------------------------------------------------------------------------- @@ -501,10 +499,41 @@ PrintConsole* consoleInit(PrintConsole* console, int layer, devoptab_list[STD_OUT] = &dotab_stdout; devoptab_list[STD_ERR] = &dotab_stdout; + // 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); 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 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; + + // 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 +599,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, };