Skip to content

Conversation

@trustytrojan
Copy link

Feature additions

  • Creates a new devoptab_t for every new console created after the first, named conN, where N is a monotonically increasing integer starting at 0 for the default ( console.
  • You can open() console devices by passing conN: as the filename (the colon is important!)
  • This also allows the use of the C FILE * streams API and C++'s std::fstream classes for opening consoles (make sure to disable buffering!)
  • Calling write() on an opened console file descriptor will simply set currentConsole in console.c to the attached console passed through devoptab_t.deviceData. currentConsole is restored after all characters are printed, so that normal use of stdout/stderr can continue.

Feature demo/test

Initialize two consoles on different bg layers AND map bases, write a simple loop to hide/show the two layers on a button press, open con0: and con1:, write to the file descriptors, and observe the output on the different consoles by pressing the configured button. (See here for a more complete test using all bg layers except the last reserved for the keyboard.)

Backwards compatibility

To keep backwards compatibility, the first initialized console (first call to consoleInit()) will still be attached to the stdout (1) and stderr (2) file descriptors. Its deviceData will be set to itself so that you can open("con0:") to grab a new file descriptor to that console.

Bug discovered in newlib

Not enough devoptab_list slots are initially filled with &dotab_stdnull, so in AddDevices() the loop can dereference a null pointer. In this PR I'm fixing it on the fly on the first consoleInit() call (console.c 511-516). I didn't consider it a huge problem worth PR'ing since creating more than 7 consoles is pretty useless, and there arent many other (official) ways to create devices.

Misc changes

  • Removed braced-list initialization of the default devoptab_t structs in console.c and keyboard.c, opting for the cleaner field-setting braced-list initialization. This removes the need to comment every line of the braced-list.
  • Changed the default console/keyboard device names to con0 and kb respectively. kb (keyboard) makes more sense to see than stdin as a device, IMHO.
  • Replace dotab_null in console.c with dotab_stdnull from newlib's iosupport.c. It already exists so I don't see why we should make a new one.
    • Off-topic: Realistically, there should only be one dotab_stdnull in devoptab_list, and more checks for NULL pointers should be in place instead. This would prevent the bug described above.

@trustytrojan trustytrojan changed the title Consoles are devices, allowing multiplexed writes to consoles by opening their device paths Turn all consoles into devices, allowing Linux VT-like functionality Aug 3, 2025
@trustytrojan
Copy link
Author

Just realized that, assuming you guys don't care what can be extern'd from any part of the libnds stack, I can just extern and edit devoptab_list myself with a modified copy of con_write, making this PR unnecessary for my needs.

Still would be nice for you to consider the change though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Ability to map file descriptors to consoles

1 participant