I was tinkering with the Woopsi documentation earlier, writing a section about the TextViewer, when I realised that the TextViewer had a design flaw - it used twice as much memory as it needed to.
When the constructor or setText() function is called, the TextViewer class runs the text through a word wrapping function, splitting it into individual lines and pushing those lines into a vector. This gives it pre-formatted text data to work with later for display. However, it doesn’t really split anything - it creates a copy of each line of text and stores the duplicate in the vector. This means that, once the wrap function has finished running, the TextViewer class contains a complete copy of the original text split into chunks. If we send it 2MB of text, the TextViewer will contain a pointer to the original (2MB) of text, plus the duplicate text (2MB plus any overheads associated with the vector class). It wastes vast amounts of memory.
I had a think about this, and decided that I didn’t actually need to copy the text. If I scrapped the text vector and replaced it with a vector that stored the offsets of the start and end of each line of text (as a struct), I’d need to store only 8 bytes (two 32-bit integers) per line instead of around 32 (maximum number of characters per line for an 8x8 font). Thinking about it some more, I could store the start offset (4 bytes) and line length (1 byte) instead of the start and end addresses, and save a further 3 bytes. If our 2MB text file consists of one long line of ASCII it’d contain 2,097,152 characters, or 65,536 lines of DS-formatted text. Each line consumes 5 bytes of mapping data in the vector, which totals 320K of wasted memory (plus overhead, natch) instead of 2MB.
Implementing this change was simple enough, and it should make things a tiny bit quicker, too.
Following on from Jeff’s comment that highlighted the problems with functions that sometimes do what they’re called and sometimes do something entirely different, I’ve fixed the inconsistent behaviour of the gadget close function - it now closes and marks a gadget as deleted, instead of changing its function depending on the situation. I’ve also added the missing events - close, hide and show.
Another idea for a new Woopsi feature - animated buttons. It would be fairly easy to change the BitmapButton class so that it contains a sequence of frames for each clicked state instead of just a single image. I’d need to write an Animation class that has various options, such as playback speed and loop type (none, loop, ping-pong), and I’d just drop that into the button in place of the current single bitmap.
Finally, it seems Nintendo read my blog, because they’re apparently considering releasing a flash cart of their own. Assuming they release some sort of dev kit for it that lets me get at the hardware, code in C++, and isn’t just a cheap copy of SEUCK, I’ll buy it as soon as it’s available.