Question to keep a generated background

General

jicehel

5 years ago

Hi all, i have a question about a background (a generated by program image)

If we have a program which generate a background with calculations more or less complexes, could it be possible to create it in a virtual picture  to call it each time you need it in place to have to calculate it each time. I hope you understand what i want to do. The idea is to generate the background in a image and to be able to call it back each time it's needed until you reach next level and then calculate the new picture of the background of this level to call it each time you need.

Thanks for your help. I'm sure it's could be done with an array and pointers but i'm not good with that atm (but i'll progress ;) )


makerSquirrel

NEW 5 years ago

You mean a screen puffer?

For that you need to create an Array of Arrays  with the screen size (well, 80x32 when using char/uint8_t, since you probably use 4 bits per pixel, be aware that this costs you 2,5kB of RAM) and then some functions to handle the filling. Since this is something you probably want to re-use, I'd recommend that you write a class, where the puffer is stored as member and then add some convenience functions to set/get pixels with colors and maybe some more stuff with lines and boxes and so. (The gamebuino library will probably use exactly such an approach, since they need to collect the info what you actually want to draw that way as soon as you have finished your event loop iteration. I haven't seen their code yet, so I am just guessing).

jicehel

NEW 5 years ago

Thanks makerSquirrel, if someone could write an example program to show how to use this, it's could be very useful. I understand what you wite but i don't really undestnd / know how to do that atm...

dreamer3

NEW 5 years ago

Depending on how fast/often you need it you could just cache it to "disk" - saving it on the SD card and loading it when you need to show it.

jicehel

NEW 5 years ago

It's to gain time at each refresh of the sceen so about 25 times by sec. Using SD card will be too slow i think to make it quickest than calculs / draws.

jicehel

NEW 5 years ago

Sorry, i said a stupidity. You said me calcultae, save picture as a temp file and load it as image. Yes, that's a good solution. But i have to know how i can save the content of the calculate picture to be able to read it after as an image

dreamer3

NEW 5 years ago

If you need it every single frame SD might not be the best solution.

makerSquirrel

NEW 5 years ago

I thought about the SD-image too, since I haven't used SDFat yet, the write speed still seems to slow for puffering more than once per second.

I have no IDE near, but my pseudo-code for that would look like this:

/// big surprise: struct and class are basically the same in C++, I just use struct so that I do not need to write public:/protected:/private: since I do not care in this example
struct ScreenPuffer
{
/// constructor, call with screenSize: this version expects 4 bits per color.
ScreenPuffer(uint8_t width, uint8_t height) : m_width(width), m_height(height) { m_puffer = new Color[width][height/2];}

/// destructor, call it with "delete yourClassName"
~ScreenPuffer() { delete m_puffer; }

/// safety checks are up to you, or just use std::array/std::vector and .at(..), so you don't have to care :P
const Color& getColor(uint8_t x, uint8_t y) const { return (*m_puffer)[x][y]; }

/// the standard-color I just added to make the cls function smaller:
void setColor(uint8_t x, uint8_t y, Color color = WHITE) { *m_puffer[x][y] = color; }

/// clearScreenPuffer.
void cls()
{
  for(auto i = 0 ; i < m_width; ++i) // with auto the compiler replaces that with whatever he/she thinks is best to use as index type :P
  { for(auto j = 0; j < m_height/2; ++j) setColor(i,j; }
}

/// add convenience functions here, e.g. copyScreen(): loop over all pixels of the screen and do the graphics.getColor(x,y) thingy and call your setColor with the returned parameter copies the current screen state.

/// members, width and height are optional and could be used for range/safety checks:
const uint8_t m_width;
const uint8_t m_height;
Color[][]* m_puffer; // please look that up yourself, I am not fond of using arrays due to their errorprone ways to use. std::array/std::vector typically is good enough for me ;)
};


Edit: as an afterthought: I haven't checked yet, but if the image class of the library is written well, you might use that as a member in that class instead of the array and you don't have to re-invent he wheel that much, e.g. painting your puffer then becomes a one-liner, using different puffer sizes (because why always store the full screen if you just care for a part of it?) get easier and if Sorunome/R0d0t or whoever is behind the Image part is really clever there are some convenience functions for storing/loading it to/from SD as well and you practically just have to use their fancyness...

jicehel

NEW 5 years ago

Nice, i'll try that  ;)  It's enough detailed to let me see how to use it. (Or to try it in all cases  ;) )

makerSquirrel

NEW 5 years ago

Hiho,

if you didn't find anything about image handling in the library, there seems to be a pretty simple alternative: https://gamebuino.com/creations/gamebuino-save-format

The save format seems versatile in design, which should allow you to easily store the array of Colors that way. If it is fast enough, you simply need to write a convenience class handling the screen copy to image process (like the ScreenPuffer from the other post) and then you simply store your image as a save blob (and retrieve it that way), Here the pseudo code modified from Sorunomes tutorial (again, I haven't tested it, :P):


struct ScreenPuffer {
[... functions here, i.e. adapt those from other post ...]
Color[LCDWIDTH][LCDHEIGHT] m_puffer; // for sizeof to work correctly we need to sacrifice the dynamic size, but win the convenience brought to you by Sorunome et al.
};

/// set up for 4 screen puffers ( if you still want to save your saves as well, just combine that.
const SaveDefault savefileDefaults[] = {
  { SAVE_PIC1, SAVETYPE_BLOB, sizeof(ScreenPuffer), 0 },
  { SAVE_PIC2, SAVETYPE_BLOB, sizeof(ScreenPuffer), 0 },
  { SAVE_PIC3, SAVETYPE_BLOB, sizeof(ScreenPuffer), 0 },
  { SAVE_PIC4, SAVETYPE_BLOB, sizeof(ScreenPuffer), 0 }
};

void setup() {
  gb.begin();

  // set the save defaults
  gb.save.config(savefileDefaults);
}

/// assumes that you have filled the screenPuffer
bool YourFancyScreenSaver(ScreenPuffer& yourPuffer, auto picNum)
{
    return gb.save.set(picNum, yourPuffer);
}

/// get it back...
void YourFancyScreenGetter(ScreenPuffer& yourPuffer, auto picNum)
{
    gb.save.get(picNum, yourPuffer);
}

Juice_Lizard

NEW 5 years ago

Maybe you can just show the background on your Gamebuino Meta screen, make a screen shot, take it from the SD card to your computer and then convert it to a sprite, and change your code to draw the background with the gb.display.drawImage function. (And use Piskel with the Gamebuino palette to modify the picture if you need to.)

jicehel

NEW 5 years ago

Yes, it's can be done for example for your prog as there is 3 backgrounds (its one of the things i'll do on the code changes when i'll have some times as some other things) but when i have look at your prog, i have think about a game with more than 100 calculated backgrounds. As we do, we have to calculate it each time and it's a cost of cpu that can be gained if its calculated one time bufferised and if you use this buffer for each of the screen refresh