Draw Bitmap from RAM

Understanding the language, error messages, etc.

Draw Bitmap from RAM

Postby qubist » Sat Aug 23, 2014 4:21 am

Hi,

I want to draw a bitmap from RAM not PROGMEM but it doesn't seem to work. Is there some trick?

The bitmaps that work I declare like this:
Code: Select all
const byte x[] PROGMEM= {
  84, 48,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  ...

The bitmaps that don't work I declare like this:
Code: Select all
byte x[]= {
  84, 48,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  ...


Why does this happen :?: :?

Thanks!
User avatar
qubist
 
Posts: 31
Joined: Thu Mar 27, 2014 1:58 am
Location: USA

Re: Draw Bitmap from RAM

Postby microgamer » Sat Aug 23, 2014 5:57 am

I had the same problem on the microview that arrays around the 500 byte mark would use up all the free SRAM.
Try your code with a smaller bitmap?

Edit - the way PROGMEM arrays are accessed is slightly different. Maybe the routine you are using to display is set up for that?
microgamer
 
Posts: 8
Joined: Tue Aug 12, 2014 9:13 am

Re: Draw Bitmap from RAM

Postby Matrix828 » Sat Aug 23, 2014 8:21 am

The drawBitmap function only works with PROGMEM arrays.
Matrix828
 
Posts: 43
Joined: Tue Jul 22, 2014 7:44 pm

Re: Draw Bitmap from RAM

Postby Myndale » Sat Aug 23, 2014 8:37 am

It's easy enough to modify the drawBitmap function though, the key is this bit of code:

Code: Select all
if (pgm_read_byte(bitmap + j * byteWidth + i / 8) & (B10000000 >> (i % 8))) {
                drawPixel(x + i, y + j);
            }


This code assumes that the bitmap is in progmem, so all you need to do it copy the entire function into your program, rename it and modify it to use RAM instead. Something like this should do it:

Code: Select all
if (bitmap[j * byteWidth + i / 8] & (B10000000 >> (i % 8))) {
                drawPixel(x + i, y + j);
            }
Myndale
 
Posts: 507
Joined: Sat Mar 01, 2014 1:25 am

Re: Draw Bitmap from RAM

Postby Matrix828 » Sat Aug 23, 2014 8:45 am

Following on from Myndale, you'll also need to change
Code: Select all
int8_t w = pgm_read_byte(bitmap);
int8_t h = pgm_read_byte(bitmap + 1);


To something like this:
Code: Select all
int8_t w = bitmap[0];
int8_t h = bitmap[1];
Matrix828
 
Posts: 43
Joined: Tue Jul 22, 2014 7:44 pm

Re: Draw Bitmap from RAM

Postby qubist » Sun Aug 24, 2014 5:56 am

so all you need to do it copy the entire function into your program, rename it and modify it to use RAM instead.


Where would I find the entire function to copy and change that bit?
User avatar
qubist
 
Posts: 31
Joined: Thu Mar 27, 2014 1:58 am
Location: USA

Re: Draw Bitmap from RAM

Postby qubist » Sun Aug 24, 2014 8:06 pm

OK I found it in the library. Here is the original code:

Code: Select all
void Display::drawBitmap(int8_t x, int8_t y, const uint8_t *bitmap) {
   int8_t w = pgm_read_byte(bitmap);
   int8_t h = pgm_read_byte(bitmap + 1);
   bitmap = bitmap + 2; //add an offset to the pointer to start after the width and height
#if (ENABLE_BITMAPS > 0)
    int8_t i, j, byteWidth = (w + 7) / 8;
    for (j = 0; j < h; j++) {
        for (i = 0; i < w; i++) {
            if (pgm_read_byte(bitmap + j * byteWidth + i / 8) & (B10000000 >> (i % 8))) {
                drawPixel(x + i, y + j);
            }
        }
    }
#else
   drawRect(x, y, w, h);
#endif
}


And here is what I changed it to:

Code: Select all
void DrawBitmapRAM(int8_t x, int8_t y, const uint8_t *bitmap) {
   int8_t w = bitmap[0];
   int8_t h = bitmap[1];
   bitmap = bitmap + 2; //add an offset to the pointer to start after the width and height
#if (ENABLE_BITMAPS > 0)
    int8_t i, j, byteWidth = (w + 7) / 8;
    for (j = 0; j < h; j++) {
        for (i = 0; i < w; i++) {
         if (bitmap[j * byteWidth + i / 8] & (B10000000 >> (i % 8))) {
            gb.display.drawPixel(x + i, y + j);
         }
        }
    }
#else
   drawRect(x, y, w, h);
#endif
}


It works now. Thanks!
User avatar
qubist
 
Posts: 31
Joined: Thu Mar 27, 2014 1:58 am
Location: USA

Re: Draw Bitmap from RAM

Postby Myndale » Mon Aug 25, 2014 2:04 am

On a similar note Rodot how would you feel about exposing the back buffer via the interface? It's easy enough to access it at the moment by externing it like so:

Code: Select all
extern uint8_t _displayBuffer[LCDWIDTH * LCDHEIGHT / 8];


It would be nice to make it official though as it would allow people to write highly optimized custom routines without having to go through drawPixel.
Myndale
 
Posts: 507
Joined: Sat Mar 01, 2014 1:25 am

Re: Draw Bitmap from RAM

Postby rodot » Mon Aug 25, 2014 7:31 am

Myndale wrote:On a similar note Rodot how would you feel about exposing the back buffer via the interface? It's easy enough to access it at the moment by externing it like so:

Code: Select all
extern uint8_t _displayBuffer[LCDWIDTH * LCDHEIGHT / 8];


It would be nice to make it official though as it would allow people to write highly optimized custom routines without having to go through drawPixel.


What do you mean "make it official"? Explain in the reference that you can use "extern uint8_t _dipsplayBuffer" ?
User avatar
rodot
Site Admin
 
Posts: 1290
Joined: Mon Nov 19, 2012 11:54 pm
Location: France

Re: Draw Bitmap from RAM

Postby Myndale » Mon Aug 25, 2014 8:54 am

rodot wrote:What do you mean "make it official"? Explain in the reference that you can use "extern uint8_t _dipsplayBuffer" ?


In C there's a general convention that a variable with a leading underscore is considered private, in which case you don't reference it because your code could break in future. At the moment it's certainly possible to access the buffer by externing it, but doing so is bad form. Making it official would simply involve a getBackBuffer() function or something in the Display class, that would future proof the library and give you freedom to rename the buffer or overlay it with the SD buffer or whatever else you want to do without breaking existing code.

It's not a huge deal, just a coding convention thing. You could also just add the extern to the Display.h file, although for the reasons I state above I'd suggest stripping that leading underscore from the array name.
Myndale
 
Posts: 507
Joined: Sat Mar 01, 2014 1:25 am

Next

Return to Programming Questions

Who is online

Users browsing this forum: No registered users and 59 guests