Dynamic Bitmaps

In case it comes up for someone else and confuses them as much as it confused me, the built-in (Arduboy library) drawBitmap() assumes the sprite data is coming from PROGMEM. This had an extremely strange side effect for me of constantly producing garbage on the screen when I was attempting to manipulate bitmap data in real time. If you think about what it was doing, it was attempting to look something up in in PROGMEM with a RAM address. Needless to say, what was expected to be at the address I was providing was not at all what would be there. That’s like using 100 Main Street in one town and expecting to find the same thing at 100 Main Street in another town.

Essentially I am trying to build a tile based sprite system (similar to how the NES did it) so I can have 1 tile in PROGMEM and I can dynamically invert it (color), flip it horizontally or vertically or any combo of the three. In other words, one tile in PROGMEM gets me 8 versions. Loads of storage space benefits at the cost of a little extra CPU when using it.

To get this to work, I had to actually create an ArduboyCustom with the extra function called drawBitmapFromRam(). This one obviously assumes the bitmap is directly in RAM instead of PROGMEM and allowed me to do what I needed. :smile:

2 Likes

It definitely would save storage as a whole, but are you not worried about having so much less RAM than PROGMEM?

Good question, but in this case, no. The way I’ve coded it, if my sprite system needs to draw a tile in a “non-normal” way (meaning not in the way it was stored in PROGMEM) it only requires 8 bytes of RAM to modify it by whatever transforms are required (invert, horz, vert). That 8-bytes is reused over and over no matter how many tiles or transforms need to be applied.

The idea originally came from looking at the current specs of the Arduboy. I realized that I’m primarily limited by storage for what I’m trying to do and that the CPU is actually impressively powerful. I’m also limited by RAM as well, but with some careful use I should have plenty of that.

Edit: I realized I was actually a little off. I only need 8 bytes of RAM to store my tile for sending to my draw function. Depending on the transforms being applied there are occasionally a few extra bytes of RAM needed during processing.

I think his system is copying an 8x8 bitmap into RAM, where he modifies it and then draws it. It would require only 8 bytes of RAM to work, not counting the usual function variables. Where’s the strikethrough text formatting? He replied while I was typing this!

I would personally either draw the bitmap from PROGMEM onto the screen buffer and then manipulate it there, or have a custom bitmap drawing function that manipulates the bitmap as it is drawn, the 8 byte RAM buffer seems redundant.

I was going for simplicity when I was modifying drawBitmap() since I’m a bit rusty in C/C++. I figured the 8 bytes in RAM was a worthwhile waste to make it so drawBitmapFromRam() was as close to the code from drawBitmap() as possible. :smile:

There is already a sprite class that @JO3RI has developed! He has it in his ARG library which we are working on merging with the core arduboy library too. They just had a game jam this weekend so super excited to see what came from that!

2 Likes