YatlCPM/xts_yat4l_soft_drawBMP.h
// will takes only 160x120 px of bmp file
will takes only 160x120 px of bmp file
will takes only 160x120 px of bmp file
void _feedSprites(char* filename, int x, int y) {
      if ( filename == NULL || strlen(filename) <= 0 || strlen(filename) >= 32 ) {
         yat4l_dbug("(WW) Wrong BMP filename !");
         return;
      }
      File bmpFile;
      int bmpWidth, bmpHeight;             
      uint8_t bmpDepth;                    
      uint32_t bmpImageoffset;             
      uint32_t rowSize;                    
      uint8_t sdbuffer[3 * BUFFPIXEL];     
      uint16_t buffidx = sizeof(sdbuffer); 
      boolean goodBmp = false;             
      boolean flip = true;                 
      int w, h, row, col;
      uint8_t r, g, b;
      uint32_t pos = 0;
      uint16_t awColors[320]; 
      if (!(bmpFile = SD.open(filename)))
      {
         yat4l_warn("BMP File not found");
         return;
      }
      if (read16(bmpFile) == 0x4D42) { 
         (void)read32(bmpFile);
         (void)read32(bmpFile);            
         bmpImageoffset = read32(bmpFile); 
         (void)read32(bmpFile);
         bmpWidth = read32(bmpFile);
         bmpHeight = read32(bmpFile);
         if (read16(bmpFile) == 1)     { 
            bmpDepth = read16(bmpFile); 
            if ((bmpDepth == 24) && (read32(bmpFile) == 0)) { 
            goodBmp = true; 
            rowSize = (bmpWidth * 3 + 3) & ~3;
            if (bmpHeight < 0) {
               bmpHeight = -bmpHeight;
               flip = false;
            }
            if ((x >= bmpWidth) || (y >= bmpHeight)) {
               yat4l_warn("Sprite OutOfBounds");
               return;
            }
            w = SPRITE_AREA_WIDTH; h = SPRITE_AREA_HEIGHT;
            if ((x + w - 1) >= bmpWidth)
               w = bmpWidth - x;
            if ((y + h - 1) >= bmpHeight)
               h = bmpHeight - y;
            for (row = 0; row < h; row++) { 
               if (flip) 
                  pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
               else 
                  pos = bmpImageoffset + row * rowSize;
               if (bmpFile.position() != pos) { 
                  bmpFile.seek(pos);
                  buffidx = sizeof(sdbuffer); 
               }
               for (col = 0; col < w; col++) { 
                  if (buffidx >= sizeof(sdbuffer)) { 
                     bmpFile.read(sdbuffer, sizeof(sdbuffer));
                     buffidx = 0; 
                  }
                  b = sdbuffer[buffidx++];
                  g = sdbuffer[buffidx++];
                  r = sdbuffer[buffidx++];
                  awColors[col] = tft.color565(r, g, b);
               } 
               memcpy( &spriteArea[ (row*SPRITE_AREA_WIDTH)+col ], &awColors[x], w*2 );
            } 
            } 
         }
      }
      bmpFile.close();
      if (!goodBmp) {
         yat4l_warn("BMP format not recognized.");
      }
   }
void _feedSprites ( char * filename , int x , int y ) { if ( filename == NULL || strlen ( filename ) <= 0 || strlen ( filename ) >= 32 ) { yat4l_dbug ( " " ) ; return ; } File bmpFile ; int bmpWidth , bmpHeight ; uint8_t bmpDepth ; uint32_t bmpImageoffset ; uint32_t rowSize ; uint8_t sdbuffer [ 3 * BUFFPIXEL ] ; uint16_t buffidx = sizeof ( sdbuffer ) ; boolean goodBmp = false ; boolean flip = true ; int w , h , row , col ; uint8_t r , g , b ; uint32_t pos = 0 ; uint16_t awColors [ 320 ] ; if ( ! ( bmpFile = SD . open ( filename ) ) ) { yat4l_warn ( " " ) ; return ; } if ( read16 ( bmpFile ) == 0x4D42 ) { ( void ) read32 ( bmpFile ) ; ( void ) read32 ( bmpFile ) ; bmpImageoffset = read32 ( bmpFile ) ; ( void ) read32 ( bmpFile ) ; bmpWidth = read32 ( bmpFile ) ; bmpHeight = read32 ( bmpFile ) ; if ( read16 ( bmpFile ) == 1 ) { bmpDepth = read16 ( bmpFile ) ; if ( ( bmpDepth == 24 ) && ( read32 ( bmpFile ) == 0 ) ) { goodBmp = true ; rowSize = ( bmpWidth * 3 + 3 ) & ~ 3 ; if ( bmpHeight < 0 ) { bmpHeight = - bmpHeight ; flip = false ; } if ( ( x >= bmpWidth ) || ( y >= bmpHeight ) ) { yat4l_warn ( " " ) ; return ; } w = SPRITE_AREA_WIDTH ; h = SPRITE_AREA_HEIGHT ; if ( ( x + w - 1 ) >= bmpWidth ) w = bmpWidth - x ; if ( ( y + h - 1 ) >= bmpHeight ) h = bmpHeight - y ; for ( row = 0 ; row < h ; row ++ ) { if ( flip ) pos = bmpImageoffset + ( bmpHeight - 1 - row ) * rowSize ; else pos = bmpImageoffset + row * rowSize ; if ( bmpFile . position ( ) != pos ) { bmpFile . seek ( pos ) ; buffidx = sizeof ( sdbuffer ) ; } for ( col = 0 ; col < w ; col ++ ) { if ( buffidx >= sizeof ( sdbuffer ) ) { bmpFile . read ( sdbuffer , sizeof ( sdbuffer ) ) ; buffidx = 0 ; } b = sdbuffer [ buffidx ++ ] ; g = sdbuffer [ buffidx ++ ] ; r = sdbuffer [ buffidx ++ ] ; awColors [ col ] = tft . color565 ( r , g , b ) ; } memcpy ( & spriteArea [ ( row * SPRITE_AREA_WIDTH ) + col ] , & awColors [ x ] , w * 2 ) ; } } } } bmpFile . close ( ) ; if ( ! goodBmp ) { yat4l_warn ( " " ) ; } }
will takes only 160x120 px of bmp file
will takes only 160x120 px of bmp file
// W+H in pixels // Bit depth (currently must be 24) // Start of image data in file // Not always = bmpWidth; may have padding // pixel buffer (R+G+B per pixel) // Current position in sdbuffer // Set to true on valid header parse // BMP is stored bottom-to-top //, startTime = millis(); // hold colors for one row at a time... // if ((x >= tft.width()) || (y >= tft.height())) //    return; // Open requested file on SD card // Parse BMP header // BMP signature // Read & ignore creator bytes // Start of image data // # planes -- must be '1' // bits per pixel // 0 = uncompressed // Supported BMP format -- proceed! // BMP rows are padded (if needed) to 4-byte boundary // If bmpHeight is negative, image is in top-down order. // This is not canon but has been observed in the wild. // Crop area to be loaded // w = bmpWidth; // h = bmpHeight; // For each scanline... // Seek to start of scan line.  It might seem labor- // intensive to be doing this on every line, but this // method covers a lot of gritty details like cropping // and scanline padding.  Also, the seek only takes // place if the file position actually needs to change // (avoids a lot of cluster math in SD library). // Bitmap is stored bottom-to-top order (normal BMP) // Bitmap is stored top-to-bottom // Need seek? // Force buffer reload // For each pixel... // Time to read more pixel data? // Indeed // Set index to beginning // Convert pixel from BMP to TFT format, push to display // end pixel // tft.writeRect(0, row, w, 1, awColors); // *2 Cf uint16_t // end scanline // long timeElapsed = millis() - startTime; // end goodBmp