Arduboy Zero Buffer Format

I wanted to get opinions on the display buffer for the next Arduboy.

If it does have the same screen but the M0+ chip, I’m wondering if it would be worth updating the buffer and image formats to be 2 bits per pixel. In the buffer this would allow grey scale and the timing of refresh could be independent of game frame rate. The flickering effect of gray is not all that noticeable with small amounts of gray on the current device. It would I think add a lot to depth of character design.

Currently it takes two images to allow for transparency, that duplicates the number of bits per pixel only allowing for one extra parameter. Changing the image format to 2 bits per pixel would allow for black 00, gray 01, transparent 10, and white 11. Images that support grayscale and transparency would not take more space than current images with transparency.

There could still be a drawBitmap function for background images that don’t need transparency or grayscale that can use less flash space.

My proficiency in Assembly and hardware isn’t extensive enough to know the perfect solution, but with the added speed of the processor I’m sure I could create a C++ version of the functions.

Any thoughts on whether this seems valuable enough to pursue? Implementation issues that might arise?

It’s possible to have default settings when creating an Arduboy object that can be overwritten. I imagine if we do something like what you’re suggesting, we may be able to have both 2-bit and 1-bit screen buffer modes, right?

Yeah, I think that would be easy enough. The new mode could be optional.

I wonder if it would be better to have two 1 bit buffers. The first would be just like what we have now, and gray would be drawn as white. The second would be all 1’s except gray would be drawn as 0’s. If it’s a gray refresh the regular buffer’s bytes would be AND’d with the gray buffer just before being sent to the screen. That would cut down on processing for refreshes.

I still think a 2-bit image format would be the way to go if we can get it to draw fairly efficiently. When I get a little more time I’ll see if I can find my old demo testing gray in small amounts. The issue was slowdown since my first attempt at the draw function wasn’t terribly efficient.

Why not just have duplicate images in each buffer, except that for grey a bit is 1 in one buffer and 0 in the other? This way you just alternately paint each buffer rapidly to get grey.

You could add a third (or more) buffer(s) and get multiple levels of grey by cycling through each, with the number of times a given corresponding bit is set automatically determining its level of grey.

A drawback is that the buffers themselves don’t retain “transparent” pixel information, but that’s likely something you only need as a specified colour when drawing an object. If necessary, you could add a dedicated “transparency” buffer where each bit represents whether the pixel is transparent or not.

This technique makes inefficient use of RAM but requires no computation during screen painting. This allows the possibility of using DMA for screen updating, leaving much more CPU power for actual sketch code.

The proposed ATSAMD21G18 processor has 32K of RAM (compared to the 2.5K we have now). If we’re keeping the current display, which needs 1K to represent all its pixels, we could afford to have 3 or 4 1K buffers and still have plenty of RAM left over for general use.

1 Like

I like the idea of extending the memory buffer size to adapt to the “color” depth.

1 Like

I’m in the 2-bit buffer camp. Regardless of getting grey to work properly, the transparency option is a must I think.

@MLXXXp I like that idea more. Multiple buffers could also be interesting. It would require drawing every image on every buffer each frame regardless of whether or not it uses gray scale right?

@spinal what would you use transparency in the buffer for?

Correct, unless we include a flag or something to indicate which buffer(s) are currently in use. If you indicate “no greyscale” then drawing functions, and the display updater, would only use one buffer.

Another feature of my “duplicated image” technique is that you could slow down the time between switching from one buffer to the next to create blinking pixels instead of greyscale. A function could be provided to select either greyscale or specify the blink rate.

1 Like

Hm… That’s an interesting thought. Aside from setting frame rate, there could also be a frame buffer switch rate. I don’t see what the need would be for the display buffer to have transparency as long as the images do.

Utilizing multiple frame buffers might also allow other effects besides gray scale, if the contents are computed between switching somehow.

Good question, I think I was confusing the main frame buffer with indevidual image bufferes in me head.

1 Like

Learning from some of the past experience in dedicating resources that cannot then be reused … the extended storage in the suggested newer chip makes possible Zork-like text mode games. For something that is strictly text mode, it should be possible to have zero buffers. This is just one example – there are other text-only (or cell-map only) applications that don’t need the full bitmap buffer.

@ChrisS wouldn’t a text only game actually use less RAM than most graphical games? I can’t imagine the code to handle drawing text using a buffer would take much more flash than alternate methods. But I could be wrong.

@Gaveno - yes, text drawing could use far less of a buffer. If you didn’t need to read back what was on the screen, text could even be done “bufferless”. And that is exactly the point of getting to zero buffers.

The backstory here is that there have been a few points in the original library where resources (RAM, timers) were dedicated to a particular function by the library whether you used that function of not. These are mostly ok, unless you are in a rare case that needs the extra oomph of having the resource for a different purpose. The newer libraries are mostly avoiding this problem – and I would think it good to have that trend continue.

I definitely understand it could less buffer. I’m just wondering what that extra RAM would be used for in a text game. The main area of concern is usually flash space. I’m sure it could save some flash to have the Arduboy library optimized for text based games so I’m all for making buffers optional. I could see a bit of confusion if a person is trying to call any of the graphical draw methods without having the buffer initialized. Added flexibility always adds additional complexity, would the cost savings on space and RAM be worth the extra work and complexity to the library?

If the next version of the Arduboy has memory card support, and 32kb of RAM, text based engines should be easy enough to create with essentially limitless space I would think.

My vote would probably be to create a separate version of the library optimized for text based games rather than support both in the same.

@Gaveno Things like location history, state variables, and inventory, can add to the complexity and richness of a text game, but they can eat up memory to track them. More complex monsters (with even primitive AIs?) may wonder around a dungeon, or even track your scent. Or - you can track their scent. That sort of complexity eats ram in a real hurry.

The advantage of the text game is that text can often more efficiently describe a scene than graphics, so persistent storage is a great place for massive text libraries. Meanwhile, massive state information can create complex environments that reward long-term play, and provide great replay value.

If you want to go all out, use some of the multi-device communication options, and look at building a multi-user dungeon in an Arduboy. Suddenly the states you have to track may explode many times over.