Double pixel size?

any one know how to scale up the screen size without using a bunch of buffers? i know 1 might need to be used for final output . im using a arduboy2 flavor if that matters for a clone that uses a stronger processor than the real thing. its has the code that makes 2 extra colors from crossing from black to white and vise versa. i trimmed it to get back ram.

now im left with wio arduboy extend hackster post mocking has this little snippet of code but no reference for how to implement it and no fork that the article writer speaks of exists on git hub. below the snippet that haunts me. when do i tell it to do the thing ?

void Arduboy2Core::scale(const uint8_t *image, uint16_t w1, 
     uint16_t h1, uint8_t *scaledImage, uint16_t w2, uint16_t h2)
    uint16_t x_ratio = (uint16_t)((w1<<16)/w2) + 1;
    uint16_t y_ratio = (uint16_t)((h1<<16)/h2) + 1;
    uint16_t x2, y2;

    for (uint16_t i=0; i<h2; i++) {
        for (uint16_t j=0; j<w2; j++) {
            x2 = ((j * x_ratio) >> 16) ;
            y2 = ((i * y_ratio) >> 16) ;
            scaledImage[(i * w2) + j] = image[(y2 * w1) + x2] ;

I am not a 100% sure what you are doing. What are you trying to achieve? Does your hardware have a resolution different to the Arduboy and you simply want to scale up graphics by multiples of 2 or some other ratio?

Anyhow the code you have provided allows you to scale up an image from an array into a second array. As it stands, it will support ratios that are not multiples of 2 but the results will probably look very ordinary.

The standard Arduboy library expects images to be in PROGMEM not in RAM, so the methods that draw bitmaps will not work for the output of these.

If you look at this repo, I have extended the Sprites library to support drawing from RAM. It may help.

1 Like

its for esp8266. if your not using a 328p for a standard clone your expected to use a tft not oled. or at least many have used them it would seem. i have a ili9341 (320 x 240). multiple people have shown it can be done but the hackster page doesnt have a implementation demonstration for doubling pixels they just say its a small code here it is and then they do a victory lap.

the screen buffers use ram because they get redrawn constantly and the max number of writes would kill anything being written to flash fast

the arduboy2 esp8266 library i downloaded has a method but it kills ram. its uses like 4 buffers and makes extra colors but i dont need those and want ram.

I am still not clear what you are trying to do. Are you wanting to make existing Arduboy games work on this new hardware? If so, in black and white?

The ratio of your screen might be a little problematic. Yours is 1.333:1 whereas the arduboy is 2:1.

Anyhow, lets assume you want to scale the graphics up by 2x which will result in nice, crisp graphics. The result will be a letterbox approach which uses 256x128 of the screen. To achieve this, grab the Arduboy library and leave everything as is but simply change the code that pushes the existing screen buffer out to the OLED with whatever you need to render on your TFT screen. For every pixel you find in the Arduboy buffer, write out a ‘rectangle’ of 2px x 2px to your TFT.

1 Like

the entirety of the screen isnt used there is a boarder of unused. the pixels should end up 2 times their original size.

thats the thing the buffer 2 times it when written to in the original. i find it hard to believe that this is needed since the the atmega328p doesnt have ram for that .2 kb cant do a full screen buffer and run a game. not even basic binary values i dont think would allow that.

can i just bitshift the output ? i got pretty fast spi

Usually people call it 4:3.

Hence 2:1 scaled up (4:2) will fit if you just leave a border of 0.5 either side.

Arduboy uses an ATmega32u4, not an ATmega328p.
The Arduboy’s ATmega32u4 has 2.5KB.
A 128x64 1 bit-per-pixel frame buffer requires only 1KB (1024 bytes).

Building a clone with an ATmega328p (with only 2KB of RAM) would limit the number of games you could play on it.

@filmote has already said what you’d need to do:

Though that’s if you for some reason can’t support a full 320x240 buffer in the first place. I would have thought a device capable of sparing enough RAM to support a 320x240 screen could spare 1KB for a 128x64 1bpp buffer.

If there’s enough memory to support both the Arduboy’s 128x64 buffer and whatever kind of buffer you need for the native screen then you’d only have to write a function that draws the 128x64 buffer onto the 320x240 buffer.

(I can’t provide you with one because I don’t know what format the 320x240 buffer is in. 24-bit truecolour? 16-bit 565RGB? 8-bit paletted 256-colour? 4-bit paletted 16-colour?)

If there isn’t enough memory for that, or that would take up too much processing time, then you’d have to do what @filmote suggested: skip the 320x240 buffer and just draw the 128x64 buffer straight to the screen (the TFT) by drawing a 2x2 block of pixels rather than just a single pixel. You’d also need to skip over the areas you’re intending to leave blank.

Either way you’re going to need to know what the Arduboy’s frame buffer format is like:


And whatever the frame buffer format is for the device you’re targetting.

Without more information, that’s all we can say really.
We don’t have enough information about your device to be any more specific than that.

The more specific, technical information you can provide, the more likely it is that we’ll be able to provide specific information.

1 Like

He is planning to use an ESP.

Maybe you should look at what @ESPboy has done in his code. His is working in exactly the way described - ie. a letterbox output. Yet another ESP8266 port of Arduboy2 lib. Specially for ESPboy

I saw that much. ESP8266. (Though I can never remember how much RAM most ESP chips have.)

I’m just pointing out that although some people do build clones with Atmega328ps, it’s generally not a good idea because of the 0.5KB difference in RAM to a standard Arduboy. As I’m sure you know, those 512 bytes make all the difference.

ESP8266 has a lot of RAM and therefore I am not sure what all the concern is.

Understood. And yes, its the last 512 bytes that are the cream.

@m101011 Have you spoke to Roman? His device (the ESPBoy) is really well done and can Arduboy games through his modified library. He has spent a bit of time converting most games to his platform. The ESPBoy uses a 128x128 colour TFT screen though not a 320x240.

I wonder if you are just trying to reproduce what has already been done?

well the thing is when you download hatmann1301 esp8266 and 32 library from github the display is managed by 1 of a couple of possibilities. this increases the buffer size (total across all files) because no changes are made to the base line tft_espi (if you use it) and it has a buffer and this is made more complicated by the fact the display file tries to make a extra 2 colors when it crosses from black to white or white to black. so it needs another buffer. then for some reason he has the buffer size at screen width height x 2. maybe it was needed with his version of arduino he was using at the time its a few years old. but right now with the current so its got two 640 x 480 buffers and a 320 x 240 and tft espi has one and arduboy has one the sbuffer

so i previously had trimmed it to much and needed to double back the pixels. i decided not to bother with the obuffer and cut it and all references and left the c and u buffers and dropped their sizes to 320 x 240. this was enough to decrease ram by usage to 1/3 its previous which does not reflect how many pixles its not keeping track of now so idk but its acceptable

no i havent tried to get in touch with any one. im sure they are busy and i figured thats what this place is for

Of course, people will try to help you here but for many (including me) the ESP8266 and screen choice will be foreign to them.

1 Like

can’t figure out the problem)
In my version of the Arduboy2 library, rendering on a 128x128 LCD ST7735 goes almost directly to the screen with a small intermediate buffer of 2k in order to display the screen in 4 receptions, 16 lines at a time. in principle, you can use a buffer of only 256 bytes and render line by line.
in my opinion, the power of the ESP8266 and the SPI bus is not enough to render double-scaled screen with an acceptable framerate. for this task, it is good to use ESP32 with two cores or DMA, so that one core is engaged only in graphics output, and the second for all the rest. as far as I remember doing so @tonym128 and his version of the lib


Which library?

Some links to these things you are referring to would be useful.

I don’t know what you mean by ‘obuffer’ or ‘c’ or ‘u’ buffers.

I would have thought that could be done without needing another buffer.
Though perhaps an extra buffer simplifies the code?

Without having better insight into the code, I can’t imagine why that would be.
(Even then, I expect the author would be a better person to ask.)

If it’s a question about the Arduboy or general programming questions (particularly for C++), we’re almost guaranteed to know the answer, but questions about other people’s ports of Arduboy2 or Arduboy clones is more of a grey area.

Pretty much everyone here has experience with the Arduboy, but far fewer people have experience with ESP chips or ESP-based Arduboy clones, so not many people will have experience with these libraries that you’ve mentioned (but haven’t linked to).

If you’re wanting to know why a particular library is using 3-4 buffers and you think it only needs 1-2 buffers, you’re probably better off asking the library’s author.

But really it depends on what you’re actual objective is, and so far that’s still unclear.

You started asking about how to scale up ‘the screen size’ (which I presume means scaling Arduboy’s 128x64 screen buffer up to 256x128, to fit onto a 320x240 screen), but then you started talking about using other colours, so I’m not really sure what you’re actually trying to do.

Are you:

  • Trying to get some libraries working with your ESP-based clone, and they aren’t working?
  • Trying to figure out how to get the libraries you’re using to use fewer buffers?
  • Trying to write your own version of Arduboy2?
    • With x2 scaling?
    • With x2 scaling and some kind of greyscale system?

I can think of two of ways to “double pixel size”.
First way is the straight, big-buffer approach where you will put a screen buffer of the enlarged screen (say, 320*240), then you enlarge the bitmaps and draw them on the screen.

The second way is to use the current buffer (and all the drawing functions), but send each pixel 4 times (so it’s 2*2 on the physical screen). You will lose resolution but you will not lose any RAM (because the buffer size is the same)

That’s some good questions to start from.

thanks for the replies. if you want some links to what i was fidling with it should be here for the article

and here for the files here

as for what im doing well in a haphazard kind of way im just making a adjusted arduboy for my own usage. its screen resolution right now is 160 x 120 and pixels are doubled in size to fill the ili9341. warning not all games will work and you have to cut out the extra color buffer and remove the *2 on height and width at the bottom where the buffers are or some things cant compile. other things will not have a lot of screen usage out of the box

but i wanted to tinker and am willing top flesh out what i can find that can do full screen without me knowing trig and calc or some dead programing language from 3 decades ago (raycaster ab i dont even know what im looking at when i glance at the ino). micro flight sim looks great at 160 x 120. might try to expand it into a flight sim with enemies just to have something that looks that nice on it. catacombs not so much but i have other games i am going to test. cant get a single old arduboy game to run even if it compiles. given more time i may try to adjust the code a bit to do 4 colors at all times since there is code out there for that

That’s not really practical because it would have to be done for every game.

This is the solution @filmote proposed, and is one of the most efficient solutions.

Another solution (which I mentioned earlier) would be to do the same thing, but send the output to a larger buffer instead of directly to the screen, which would open up the possibility of doing post-processing, and would probably be the easiest option.

Do you mean to say that you are merely using a 160x120 pixel buffer, and that each pixel in the buffer is doubled for rendering on a 320x240 screeen?

If so, I’m not sure what the problem is.

You’d just render the Arduboy2’s buffer onto the 160x120 buffer and then the x2 upscaling you’re using when rendering to the screen would upscale the Arduboy buffer in the process.

Are you trying to rewrite Arduboy games so they function at a resolution of 160x120?

I’m still confused about what it is that you actually need help with.
What is it that you need help with?

no the problem was i overcropped the arduboy2 for (esp32 and esp 8266) file. i ran it and everything displayed and properly but it was small. i stated in another post that i just found the file again and changed what i cropped. it uses tftespi to display to the ili9341. you can use other libraries but out of the box it uses tftespi and has a new .h for it

i left the double buffer in and the original method used to draw the end result to screen when not using the ps2 controller library . the .h for tft espi hartmanns conversion actually has 1 method to double pixel size in it. the buffer arrays never had to be 2 times 320 x 240 so i removed that and got rid of all references to obuffer. this allows for full screen on most games even if full screen isnt used because the game has some restriction

what i was looking for was actually in the original file i just cropped it out. its in the final if statement. filter = 0 has the 2 times pixel size to display . filter is set to zero when you dont use his library for ps2 controller usage with arduboy

:sweat_smile: it´s my code and I had a hard time to find out what those buffers were good for. The answer is, I used the first 1024 bytes for normal scaling and the rest is just for messing around with the color filters.
(ubuffer is a pointer to sbuffer, and cbuffer is always the previous sbuffer)

For scaling the pixels a bigger buffer is not necessary. For highter frame rates I recommend using a second 1024 bytes buffer to store always the previous display pixels. Redraw the pixels only if changed and draw vertical lines as long as possible. This way I achieved moderate framerates.

@m101011 I am glad you found a way to make it work for you, those color filter things must be really confusing

1 Like

wall of text nobody wants to read time time will update with pic 160 x 120 later

not really but at a higher resolution i found i like the raw 1bit better and its not even playable really if it is 255 x 240 mode (im to lazy to make a duplicate buffer to try 320 x 240) and 80 mhz. higher resolution slows everything down and it almost looks like 160 mhz is required for lots of stuff if you like big sprites

im glad some one made a ported version honestly. while i did post a link for those that wouldnt bother doing what i did or wanted more color (understandable) for ordrid go for arduino im still messing with the raycaster for arduboy2. the result is cleaner than i thought i would get at 160 x 120. i wasted more time trying to do vector graphics for everything because of stdint then i just tried a sloppy 2d array for the textures and draw pixel in a if to put black to screen if the int is 1 after its blanked white (cyan) and it works. less math and it worked. so now its admittedly just lodes raycaster vertical floor and ceiling (more stable doesnt do odd rotation at odd angles approaching a wall but slower so more clock cycles needed than 80mhz)… i worked out perpendicular lines (to wall) for a attempted floor ceiling vector code just to abandon it.

i still have to make double line thickness textures and maybe even 3 times line thickness textures for distant applications. 250 x 240 handles it better but is to slow unless 240mhz with vertical floor ceiling code. horizontal is fast but i see this stupid rotation when walking towards a wall at a odd angle and couldnt stand it so i settled in 160 x 120. still looks nice. need to also do a proper ceiling texture. 64 x 64 textures. i have actually updated some of the textures but havent tested them this is current build… goes faster with bigger ones. idk y. tile map is the opposite 32 x 32 is pushing it unless i boost to 160 mhz and 16 x 16 works better for 255 x 240 (my benchmark build) both taking up all pixels on screen.

end goal is to use two 32 x 64 sprites that are animated to rotate 16 times (mirrored for 32) to do archway tops between openings of 2 cell sizes and make a little bit of clutter like barrel and sack. until my dad shows up later in the day i will leave 64 x 64 skele gifskele

i opted for bike riding animation style for approach. bowleged. prevents foot skooting or big stomp walk. also tried to make sure nothing was static and all was moving. failed but came close. full size is 128 x 128 and scales down to what you see here for the small distant one. finiky but a wip. i can handle dirty scaling artifact as long as stuff looks like its moving ok

the current build is 64 x 64 sized textures for wall and 32 x 32 for floor because im doing so many textures i didnt scale it up. i have to manually do all the 1s and 0s in the arrays and its checking back and forth meh

but it can handle 64 x 64 for floor cieling and walls . i did that test already but its a bad texture for floor and ceiling so i swapped it back for the pic. its why its a little more pixelated for the floor and ceiling. its smearing a smaller texture across the same size. oddly due to resolution the dif isnt that much