Arduino micro-controllers have so little Flash memory and RAM that working with them after coding for so many years on computers with more RAM than we need (innit Bill?), I feel a little cramped. And considering that in an Arduino Uno or clone you have 28KB RAM and 2KB RAM, doing anything that involves graphics on the Esplora (which has a TFT screen with an SD card slot), is going to be an impossible task.
Arduino’s TFTBitmapLogo tutorial uses a 48×48 BMP image that’s less than 7KB and once loaded is probably right within the RAM’s 2KB limit. But try to load any image that’s bigger than that and you’re up a tree scratching your balls with acacia bark. I know how it feels because I tried. To load a bigger image, I mean. No go.
I found this sprite file “somewhere on the intartubes’ — I didn’t even try to remember where 🙂 — and started slicing the different sprites of Mario into separate files. They were way too big, despite their microscopic size, to be loaded with .loadImage(). So I wondered how hard it’d be to hard-code the images as Arduino code. Each image has a green background — which means you don’t need to draw these pixels.
Using Real Studio, which changed name recently to the (ill-suited in my opinion) Xojo, I wrote a small app that writes code for me. It’s basically a bunch of Esplora-specific primitives, EsploraTFT.drawPixel(), drawing the image, pixel by pixel, line by line. This worked, and I was able to write a sketch displaying Mario anywhere I wanted on the screen. But I still ran into Flash memory issues, as the code was too long to host all the images required to make Mario run, crouch and jump.
Looking at the code I noticed that adjacent pixels drawn in the same colour could be drawn with on line of code with EsploraTFT.drawLine(). The first round of dieting worked, and Mario was happily bouncing around on the screen. I even had space for a tree. Zoowie. Then, with the help of a nifty little regex, I was able to squeeze a few more bytes out of the code. I noticed that in a few cases, I had two EsploraTFT.drawLine() primitives in the same colour around other drawing code in a different colour. So if I combined the two function calls in one, and then drew the pixels in between, I could save some memory. For the record the regex is:
EsploraTFT\.drawLine\((x\+\d+), (y\+\d+), (x\+\d+), \2, (\d+)\);\rEsploraTFT.draw.+\rEsploraTFT\.drawLine\((x\+\d+), \2, (x\+\d+), \2, \4\);\r
EsploraTFT.drawLine(\1, \2, \7, \2, \4);\r\5
Using slimmed-down versions of the standard libraries (Esplora, SD, TFT), I reached just under 24K, leaving me some tiny space to code the beginnings of a game. Not much left though…
Binary sketch size: 23,966 bytes (of a 28,672 byte maximum)