How the arduboy stores color information

at a glance every one says its a int you tard. but no its not. then some chime in with it binary… you tard… well maybe if you think 01 are enough to justify that designation. but case point if you have 2 ints which only are assigned 1 and 0 and you read both at the same time with intA being counted as first and int B counted as second you get a different value. 10 or 01. now if color is a int than BLACK 0 and WHITE 1 can be reassinged to 00 and 11 and you could change it to have another pointer for the buffer which looks at the next bit in the array to get a 2 bit screen

but if its a bolean you get odd stuff when you try to read the bolean combo as a int. i have trimmed the code to the bare essentials cropping pins , other microntoller instructions and uneeded primative draw functions like rounded rect and even sound related stuff to try to make finding where the #define BLACK and #define WHITE in arduboy2.h is easier and translated into meaningful 0x00 and 0xff but i cant find it

i have found what seemed to be a reference to 0xaf being invert but this may have been a garbled github download instance.

i will find it given time potentially. there is little space for it to hide now. i even got rid of the oled code and can still display to a ili9341. but is it a bolean ? i cant even find it being designated as such and am thinking just setting it as a char which should take the same ammoount of space but have more possibilities

I don’t know what forums you’re visiting, but if they’re insulting you then it clearly isn’t this forum.

I genuinely have no clue what at least half your post is talking about…

To answer the question in the title, the Arduboy stores its pixel information as thus:


Each 8-bit byte represents a column of 8 pixels,
and thus each bit of that 8-bit byte represents a single pixel.

The most significant bit of each byte (the 7th bit) represents the bottom pixel of the column.
The least significant bit of each byte (the 0th bit) represents the top pixel of the column.

A 0 bit represents a black pixel, a 1 bit represents a white pixel.

Because the Arduboy’s screen is 128x64, that means each 128 bytes represents a full 128x8 pixel block, and it takes 8 of those to fill the whole 128x64 screen, so it takes precisely 1024 bytes (8192 bits) to represent the frame buffer.

This is in fact the format that the Arduboy’s screen uses natively, and the Arduboy2 library simply pushes the frame buffer to the screen verbatim over SPI within the display function.

The frame buffer is used by the Arduboy2 library as an array of uint8_t, which is a type alias for unsigned char, which is an 8-bit integer datatype.
(On Arduboy at least. Platforms where char isn’t 8 bit do exist, but they’re incredibly rare.)


Neither do I. At first I thought I was missing something due to the lack of capital letters but then realised I just could not follow what he was saying. @m101011 I am not even sure if this is ultimately a question you are asking the forum or just your findings.

I think the gist is you can store 4 colours / shades of grey in two bits. The four colours being 00, 01, 10, and 11 …

its not the important part but yes its on paper how im doing it. a few extra pointers

in arduboy2.h it defines black as 0 and white as 1. it doesn t read it from arrays like that. so its not really stored like that probably as far as i can tell. so my little system needs to check if the currentcolor “bit” is 0x00 not 0 . also this is made more troublesome in that invert is defined as 2 in arduboy2 right under black and white. so am i to take it that its also hex . im just trying to get 4 colors that look like the ones i defined in tft espi not odd literal grey scale that i think i stumbled on (like if you cropped 565 code every pixel and kept spitting it out to the screen)

but if what your saying is true then a 2bit screen should be possible with the same sized array because its not actually stored as 0 or 1? i sifted through the code and couldnt find any translater code. so all those arrays people use made from little programs to use bitmaps on arduino or even here on arduboy spit out some odd non 0x00 and 0xff in the arrays here and there. i assume its instructions but if i care not about short hand i could high jack a couple for extra color definitions?

No, it doesn’t use arrays of 0s and 1s because that would be horribly wasteful.

The smallest amount of memory addressable by pretty much any modern processor will be a single 8-bit byte, thus the smallest possible size of a single array element is an 8-bit byte.

The values of 0 and 1 would only use 1 of those 8 bits, hence if each array element only stored 0 or 1, that would be 7 bits of each element going to waste, and the array would then be 8 times larger than it needed to be. (And would also consume more memory than the Arduboy actually has.)

So instead Arduboy2 packs 8 pixels into each byte of the array, in the format I described earlier.

0x00 and 0 are the same number.

Hexadecimal, binary and decimal are all simply different ways of representing the same numbers.

0xF in hexadecimal is the same thing as 15 in decimal, which is the same thing as 1111 in binary.
They are all simply different ways of writing the same number.
When a computer stores them, it will store them all in the same way.

Both 0x00 == 0 and 0x0F == 15 will evaluate to true in any sensible programming language, and in languages that support binary literals 0b1111 == 15 and 0b1111 == 0x0F will also be true.

That’s because the invert value isn’t actually stored anywhere, it’s used exclusively by the drawBitmap function, and it’s used as an indicator that a different kind of drawing operation should be used.

Specifically it’s interpreted as meaning that the 1 bits of the bitmap should be exclusive-ored with the bits in the frame buffer, which has the effect of inverting the pixels corresponding to the 1 bits in the image being drawn.


The colours are stored as 0 and 1, with 0 being black and 1 being white, but those values are stored as bits within an array of 8-bit bytes.

There is no ‘bit’ data type because bytes are the smallest addressable unit. To manipulate a bit, the computer must handle an entire byte.

The bitmaps used in Arduboy code are in the same format as the screen buffer.

Each byte of the array represents a column of 8 pixels,
as indicated in the image I shared earlier, and as I explained below that image.

No, it’s data.

There is nothing to hijack. Arduboy2’s frame buffer has no wasted space.
It is as compact as it could possibly be.

Unless whatever port of Arduboy2 you are using is doing something different for some reason, that should remain true even for ports of the library.


no. what your saying is straight from the arduboy files.

if i have 2 pointers at the screen buffer and 1 is offset to the previous pixel it should read 2 bits at a time.which it seems to do. however i have been fiddling with stuff and changing #define BLACK 0 to char BLACK 0 and doing the same for white changed zero buffer size. if it was a bolean i could understand but nothing changed and no where in the files does it say this is a bolean. not even when adding a 2 to the mix. granted the screen thought 2 was some kind of pattern not another color but the buffer size never changed AAANNND it caused zero screen distortion. everything that was supposed to be color value 2 had some odd triangle with qr code at the end. this patter was repeated vertically across the raycaster wall. my half assed grayscale 4 color did better than that

when looking through how color is even read from the buffer its odd. why not just ask if its 0 or 1. whats with this & 0x01 business? i dont think the buffer works the way every one was told nor is it the size you think it is

No one on this forum talks to anyone like that and I would kindly ask you refrain from using that kind of vocabulary in the future on the forum. This is a space for people of all ages to learn and ask questions. That kind of language is going to alienate others, whether used by a strawman or actually directed towards another user, it’s not acceptable and has no place in these forums.

1 Like

No, a pointer cannot point to a bit.

The smallest addressable unit is a byte, thus the smallest quantity a pointer can point to is a byte.

(That’s not a language limitation either, that’s a hardware limitation.)

That in turn means that a pointer can’t point to a single pixel in the format used by the Arduboy unless a single pixel is represented with an entire (8-bit) byte.

Since bits are packed in 8 per byte, that means that if you had two pointers pointing at the Arduboy’s frame buffer, with one pointing to the first byte and one pointing to the second byte, the first would be pointing to 8 pixels and the other would be pointing to a different set of 8 pixels. Dereferencing either pointer will read 8 bits (1 byte) at a time.

It wouldn’t do. BLACK and WHITE do not affect the size of the buffer because they are independent entities, even if you declare them as variables instead of macros.

Typically sizeof(bool) == sizeof(char) on most systems.
Both are typically 8 bits wide.

If anyone has ever told you that a bool only consumes a single bit, they were sorely mistaken. bool is not the same thing as a bit, despite having (theoretically) only two values.

Because, like I said before, the buffer stores 8 pixels per byte.

You cannot just “ask if it’s 0 or 1” because that would be comparing 8 bits (i.e. 8 pixels) at once.
The individual bits need to be extracted with bit shifting and masking using bitwise operators.

The & in & 0x01 is the bitwise and operator, and & 0x01 is used specifically for extracting the least significant (0th) bit of a value.

If you have not encountered bitwise operators before, you will need to know about masking and shifting to be able to properly manipulate the Arduboy’s frame buffer.

It works precisely how I stated earlier.
It is 1024 bytes, as should be apparent from the source code:

HEIGHT is 64, WIDTH is 128, so 128 * 64 / 8 is 1024.
uint8_t is 8 bits wide, thus an array of 1024 uint8_ts has 8192 bits, as I said earlier.
The / 8 is there precisely because the pixels are packed in 8 per byte.

If you were to index the array as sBuffer[0], the uint8_t that you get would not represent a single pixel, it would represent 8 pixels in a column in the format I specified earlier - the least significant bit (i.e. 0th bit, as obtained by ((sBuffer[0] >> 0) & 0x01) would be the top pixel of the first column (the red bar in the image I linked to earlier), and the most significant bit (i.e. the 7th bit, as obtained by ((sBuffer[0] >> 7) & 0x1)) would be the bottom pixel of the first column.

If sBuffer were instead defined as uint8_t sBuffer[WIDTH * HEIGHT], having one 8-bit byte per pixel such that you could simply do sBuffer[0] == 1 or sBuffer[0] == 0, then aside from the display function having to be seriously rewritten, the code would never be able to run on the Arduboy because the Arduboy doesn’t have 8192 bytes of RAM, it only has 2560 bytes of RAM.

Without knowing what your raycaster code is like, I can’t even begin to comment on what’s going on.

It sounds like it’s probably a buffer overrun, but I can only guess.


thats what the pointers are for (not the sbuffer or *ptr oor any of that thats reading whats being drawn and putting it on the buffer). the pointer looks at the buffer and reads it back to the screen. its forced to do this bit by bit

but you have to store a value as something. are you saying its storing strings because thats way more expensive than a char. a char still is 1 byte not a bit. a string is obscene for data storage. its adding char of 1 digit length to the end of the previous until it gets 8 and that is turned into a char of 1 byte

but inverse uses 2. there is no way to read 2 when it packed. it becomes 01. thats binary for 2. but in the code it would seem there is a implementation for it other wise why even have that “#define inverse 2” and right below “#define black 0” and “#define white 1”. it doesnt seem to read the 2 before its packed. at least not in the version im using.

it cant stream whats being drawn to the screen because everything would flicker. you need to redraw the screen all at 1 time or just what needs to be redrawn at 1 time. so the 2 got me thinking that it would have to be stored differently because its not in the part that reads the buffer

also on your part about the bool 8 bits that is a byte and thats enough to store more information. i think the arduboy for clones uses some kind of arduino code that isnt even in arduboy its in arduino to handle it and thats why 2 is valid but takes 2 slots if it was passed into the buffer and the off the rack arduboys has some special case that works similarly

for the record i cut all oled code and anny reference to any atmel chip but have a older version of the library i didnt do that to for testing .since im using a bigger tft. still works. but black and white seem to be hardcoded outside of arduboy in any version. grey when typed will never change to blue color in arduino even when added to keywords in the library below black

why would arduboy have a deal with arduino? why does arduino shill atmel chips? 1 relies on the other. as far as i can tell 2 was meant to bring up some kind of raster for shading but it doesnt come out right and isnt used. the triangle is long and has no variance and the qr code bit at the end should be across the triangle. from there you would have to pass in another value to determine depth

Doesn’t seem like you’re reading into (or maybe just believing?) what’s being presented, but everything @Pharap has said so far is correct, I advise you read it again until you understand.

Tip: use the forum’s search bar to see if similar niche questions might have already been talked about. Arduboy has been around for a while now.

The clones and the production arduboys are the same, there’s no “special case” involved with either. Arduboy is an Arduino based GameBoy like system. Arduboy doesn’t have a “deal” with arduino, it just uses an ATMEGA32u4 chip as its brains, because it’s readily available ((or was until the great semiconductor shortage that’s happening)) and there’s tons of 32u4 based dev-boards that are popular out there (Arduino Leonardo, Arduino Pro Micro, etc). This is why arduboy (clones AND production) run arduino code. In fact, there’s a number of times I’ve used my production arduboy as a regular arduino when I didn’t have one on hand.

It sounds like you may be unfamiliar with the arduboy’s hardware and software in general. I don’t know if you’ve had a look through any of the guides or lessons on the forum, but they have lots of really useful information about the specific ways the arduboy works and its limitations. This one is a great place to start. Also useful to you might be the discontinued arduboy magazines, full of great tips and info about hardware and software regarding arduboy. They can be found on google drive here.

1 Like

What is? Which pointers?

A pointer cannot point to an individual bit.
The minimum unit of data that a pointer can be used to read is a byte (i.e. 8 bits).
Thus it would go byte-by-byte, not bit-by-bit.

At what point did I mention strings?

I have explained at least twice already that the Arduboy’s frame buffer consists of an array of 1024 bytes, and each bit of those bytes represents a pixel.

There are 8 bits in 1 byte, thus there are 8192 bits in 1024 bytes, which is precisely the amount of bits needed to store the 8192 pixels required by a 128x64 pixel frame buffer.

There are no strings, only bytes. The datatype uint8_t represents an 8-bit byte, and the bits are extracted using bitwise operations as I stated before.

No, 01 is the binary representation of 1 in decimal.
The binary representation of 2 would be 10.

The Arduboy’s frame buffer does not store an ‘inverse’, it only stores black values (represented with 0 bits) and white values (represented with 1 bits). There is no ‘2’ being stored.

As I said before, only one function accepts an INVERT value.
INVERT is used only by drawBitmap. No other functions use it.
The Arduboy’s frame buffer does not use it either.

If you are not implementing drawBitmap then INVERT is irrelevant because nothing else uses it.

I have literally no clue what you’re talking about.

There is no ‘deal’ with Arduino, the Arduboy’s specs are based on the Arduino Leonardo board, thus Arduboy is compatible with Arduino and so the Arduino library is used to support the Arduboy’s infrastructure.

I presume this is to do with your attempts at making/porting a raycaster?

If so, I can make no comment on what’s wrong because I know nothing about the code in question.

I’m a programmer, not a mind reader.


If what @Pharap is saying isn’t making sense to you, I highly suggest reading the datasheet of the SSD1306 display controller. This will tell you exactly how the arduboy communicates display data to the OLED. It’s also not a bad idea to write your own buffered display driver, this will give you first hand experience how these displays and double buffering work. Other than that I don’t know what else I could say, Pharap already succinctly described how the arduboy stores and manipulates image data.


dont get defensive its not like your paid to defend the company and its hayday is over.

as for your comment on clones well clones dont take hex files. thast why dark and under for clones is a arduino sketch. also your assumption is i and every one else who ever made a clone is using a monochrome oled. hartmanns version is a nice start to a proper esp32 / esp8266 implementation. 2 problems. 1 it throws a warning due to the library mentionining of avr and leaves tons of atmel chip references . i just adjusted it.

then noticed the screen buffer sizes were wrong. no need for them ever to be 2 times width and height. some one has been telling others thats how you get 2 times pixel size but its not. he solved 2 times pixel size but left this in so it was taking up way more ram than needed. this meant i could even with the esp32s lack of single slab ram i could fit a 2 bit 160 x 120 screen buffer in the 160kb (96kb due to ram slab size) and mirror its size in dynamic ram for double buffering

your getting way off topic and i dont find this to be a productive area of discussion. lets just agree to disagree. i have tested the double buffer 160 x 120 1 bit screen and found it working fine. i have tested the 160 x 120 2 bit screen and found it throwing literal grey and dark grey so as far as i can tell its cropping the tft espi default pallet some where.

i could even do true 320 x 240 1bit but i have to overclock to 240mhz and i have it set in the sketch to only do 80 despite arduino wanting to set it to 240 in the board definition

right now im still fiddling with things in a raycaster to gauge results. i bounce between micro flight sim and a 250 line of code arduboy 2 raycaster thats lodes raycaster no textures . its like the worst one to mess with since they didnt define lots of stuff and i cant for the life of me find posZ anywhere in it or any file it includes. its like some figure just pulled out of thin air and arduino never says its not defined.

so you can see how this plus the hidden screen texture that seems to be part of arduino that only gets called if you try to use 2 for a color and comment out inverse and invert makes it seem like arduboy has code that relies on arduino in a way that was constructed for the sake of arduboy. the triangle and qr code thingy seem like its part of a 3d engine hidden in arduino that only works for arduboy. if the qr code was drawn across the triangle its raster shading and the triangle is by default going to be able to cover a tri

What company? What hayday? All I did was explain why arduboy and arduino are the same thing, which you seem to just be in denial of. I cannot convince you that 2 == 2 if you are unwilling to accept it.

Yes they do. If you wire it to the same pins as the production arduboy’s chip, then you can upload hex files for arduboy without recompilation through arduino code. The difference between the clone and the production is not a hardware difference, it’s a bootloader difference. The original arduino bootloader was optimized for the arduboy as Caterina & Cathy 3k.

yes… the arduboy games are all monochrome… if you want to use a different display, the hex files would be telling it the info for the old display. That’s not a difference between the 32u4 in clones and the 32u4 in arduboys. it’s a difference in your display.

Who? You need to leave links to what you’re talking about, we have no context. But cool for him I guess.

None of this has been productive, you’re ignoring every response that people have taken dedicated time out of their day to help you with an issue you brought to this community. I addressed only the things you were talking about, so I have no idea what you mean by getting “way off-topic”.

Again, we are going to need to see your code to understand even the smallest iota of what’s going on. We cannot help you otherwise because we don’t know how your raycaster works.

Once again, as it’s been said two or three times already, the arduboy only accepts 0 and 1 for colors. Not 2. Also mentioned a few times, the inverse/invert definition is not used by anything other than drawBitmap().

The “qr code and triangle” you keep seeing is likely out of bounds information being displayed because you’re using values that were undefined, you’re acessing a different part of memory than you think you are. this is a beginner issue shown in this example here.

At this point it seems clear that if you don’t listen to those giving you the best, fully fleshed out answers you could ask for,(@pharap @filmote you’re just here to be a troll and waste people’s time. You have all the answers you came here for. Whether you accept it as fact is up to you.

1 Like

@m101011 I am going to suggest that you look at the language and tone of your responses. If you cannot be civil then it may be time to find a new forum.

@poevoid and @Pharap have explained a lot to you. You are not listening and I am surprised they are continuing to assist beyond that. They must be better people than me.

1 Like

@m101011, we have been exceptionally patient with you so far.
We have tried to assist you as best as we can despite an apparent communication barrier.

None of us are paid to be here, and none of us are obligated to help you. We all give up our free time and energy to assist relative strangers of our own free will.

So far have shown no signs of gratitude for the help you have received, you appear to be ignoring a substantial portion of what has been said to you, and you have been quite uncooperative.

Your account has not been silenced or suspened yet, so you will have chance to show that you can be more courteous and cooperative, but if you don’t start behaving in a more constructive and more cooperative way, it may be necessary for me or another moderator to take further action.

I suggest you read the FAQ before making any futher posts:

It would do you well to carefully consider your responses in future, and in particularly it would do you well to consider how other users interpret your comments, and how those comments might make other users feel.

This is an official warning.

I will be locking this post as it is clearly not being productive.
The original question of the title has been answered multiple times, and further posts are likely to simply further devolve the discussion.

1 Like