DsOut
From StoneHome
Here's a streambuffer for use on simple portable platforms. I originally put this down for the Nintendo GameBoy Advance, though this is the Nintendo DS version. This code assumes the presence of a function called CharToConsole(char) which does the actual painting of a single letter; you can find a simple version of that code in the GBA Extended ASCII System. Apparently libnds has a function called consolePrintChar(char) in console.c which is suitable, but since I don't use libnds, I haven't tested that; use at your own risk.
You can use this code to make something akin to std::cout; an example is below.
class DsStreamBuffer : public std::basic_streambuf<char, std::char_traits<char> > { private: typedef std::char_traits<char> _Tr; protected: virtual int overflow(int = _Tr::eof()); public: DsStreamBuffer(); }; DsStreamBuffer::DsStreamBuffer() {} int DsStreamBuffer::overflow(int c) { typedef std::char_traits<char> _Tr; if(_Tr::eq_int_type(c, _Tr::eof())) return _Tr::not_eof(c); CharToConsole(c); return c; } // Some compiler deployments require this if they're missing some esoterica // it's not really important, but if you get a weird assed error message // about __cxa_pure_virtual in GCC, this'll fix it extern "C" void __cxa_pure_virtual(void) {}
In order to use this to make a standard stream, such as std::cout (making specifically that stream involves some extra work, so I generally just make DsOut instead,) do something like the following. This code is actually for the GameBoy Advance, because I'm too lazy to set up screen mode change stuff in here, and the DS stuff I'm doing is sorta private.
void CharToConsole(char c) { /* Put character draw here; see GBA Extended ASCII System for example code */ } int main(void) { *(u16 *)aDispCnt = MODE_3 | BG2_ON; // Turns on mode 3, and sets // bg layer 2 as on (others all // off). Req'd by mode 3. *(u16 *)aDispStat = 0; // Sets the register state to 0. DsStreamBuffer buf; std::ostream ss ( &buf ); ss << "Hello, world! Ints pass: " << 16 << "; so do floats: " << 23.8 << "! " << (char)0x01; ss << "0a234567890b234567890c234567890d234567890e234567890f234567890g23456789023456789"; while (1) {} }
Anyway, that's pretty much it - just declare an instance of the buffer, pass it as a constructor argument to a standard ostream, and off you go. This is one of the few cases in which global variables would be a reasonable thing to do, by the way; that way it'd just be available 24/7 like std::cout is.
