diff --git a/libraries/Gamebuino/Display.cpp b/libraries/Gamebuino/Display.cpp index 1d8a84e..6076dda 100644 --- a/libraries/Gamebuino/Display.cpp +++ b/libraries/Gamebuino/Display.cpp @@ -496,6 +496,10 @@ 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 + drawBitmap(x,y,w,h,bitmap); +} + +void Display::drawBitmap(int8_t x, int8_t y, int8_t w, int8_t h , const uint8_t *bitmap) { #if (ENABLE_BITMAPS > 0) /* original code int8_t i, j, byteWidth = (w + 7) / 8; @@ -618,6 +622,26 @@ void Display::drawBitmap(int8_t x, int8_t y, const uint8_t *bitmap) { #endif } +void Display::drawBitmap(int8_t x, int8_t y, int8_t w,int8_t h, const uint8_t *bitmap, uint8_t dx, uint8_t dy, uint8_t dw, uint8_t dh) { + int8_t i, j, byteWidth = (w + 7) / 8; + dw += dx; + dh += dy; + int8_t largest = 0; + int8_t largesty = 0; + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) { + if (pgm_read_byte(bitmap + j * byteWidth + i / 8) & (B10000000 >> (i % 8))) { + int8_t drawX = x + i; + int8_t drawY = y + j; + + if(drawX >= dx && drawX < dw && drawY >= dy && drawY < dh){ + drawPixel(drawX, drawY); + } + } + } + } +} + boolean Display::getBitmapPixel(const uint8_t* bitmap, uint8_t x, uint8_t y){ return pgm_read_byte(bitmap+2 + y * ((pgm_read_byte(bitmap)+7)/8) + (x >> 3)) & (B10000000 >> (x % 8)); } @@ -681,6 +705,47 @@ void Display::drawBitmap(int8_t x, int8_t y, const uint8_t *bitmap, #endif } +void Display::drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet){ + drawTilemap(x,y,tilemap,spritesheet,0,0,LCDWIDTH,LCDHEIGHT); +} +void Display::drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet,uint8_t dx,uint8_t dy,uint8_t dw,uint8_t dh){ + uint8_t tilemap_width = pgm_read_byte(tilemap); + uint8_t tilemap_height = pgm_read_byte(tilemap + 1); + uint8_t tile_width = pgm_read_byte(tilemap + 2); + uint8_t tile_height = pgm_read_byte(tilemap + 3); + tilemap += 4; // now the first tiyleis at tilemap + uint8_t ddw = dw + dx; + uint8_t ddh = dh + dy; + uint8_t maxDdx = (dw - x + tile_width - 1) / tile_width; + uint8_t maxDdy = (dh - y + tile_height - 1) / tile_height; + if(tilemap_width < maxDdx){ + maxDdx = tilemap_width; + } + if(tilemap_height < maxDdy){ + maxDdy = tilemap_height; + } + int8_t startDdx = (-x) / tile_width; + int8_t startDdy = (-y) / tile_height; + if(startDdx < 0){ + startDdx = 0; + } + if(startDdy < 0){ + startDdy = 0; + } + for(uint8_t ddy = startDdy;ddy < maxDdy;ddy++){ + for(uint8_t ddx = startDdx;ddx < maxDdx;ddx++){ + int8_t drawX = ddx*tile_width + x + dx; + int8_t drawY = ddy*tile_height + y + dy; + uint8_t tile = pgm_read_byte(tilemap + ddy*tilemap_width + ddx); + if(drawX >= dx && drawY >= dy && drawX <= (ddw-tile_width) && drawY <= (ddh-tile_height)){ + drawBitmap(drawX,drawY,tile_width,tile_height,spritesheet[tile]); + }else{ // we need to draw a partial bitmap + drawBitmap(drawX,drawY,tile_width,tile_height,spritesheet[tile],dx,dy,dw,dh); + } + } + } +} + #if ARDUINO >= 100 size_t Display::write(uint8_t c) { #else diff --git a/libraries/Gamebuino/Display.h b/libraries/Gamebuino/Display.h index 26d1d29..665ada5 100644 --- a/libraries/Gamebuino/Display.h +++ b/libraries/Gamebuino/Display.h @@ -144,9 +144,14 @@ class Display : public Print { void fillRoundRect(int8_t x0, int8_t y0, int8_t w, int8_t h, int8_t radius); void drawBitmap(int8_t x, int8_t y, const uint8_t *bitmap); + void drawBitmap(int8_t x, int8_t y, int8_t w, int8_t h , const uint8_t *bitmap); void drawBitmap(int8_t x, int8_t y, const uint8_t *bitmap, uint8_t rotation, uint8_t flip); + void drawBitmap(int8_t x, int8_t y, int8_t w, int8_t h, const uint8_t *bitmap, uint8_t dx, uint8_t dy, uint8_t dw, uint8_t dh); boolean getBitmapPixel(const uint8_t* bitmap, uint8_t x, uint8_t y); + void drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet); + void drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet,uint8_t dx,uint8_t dy,uint8_t dw,uint8_t dh); + void setFont(const uint8_t* f); uint8_t fontWidth, fontHeight; void drawChar(int8_t x, int8_t y, unsigned char c, uint8_t size); diff --git a/libraries/Gamebuino/examples/5.Reference/display/tilemap/tilemap.ino b/libraries/Gamebuino/examples/5.Reference/display/tilemap/tilemap.ino new file mode 100644 index 0000000..001b26b --- /dev/null +++ b/libraries/Gamebuino/examples/5.Reference/display/tilemap/tilemap.ino @@ -0,0 +1,139 @@ +#include +#include +Gamebuino gb; + + //map followed by tilesprites + + const byte + +tilemap[] PROGMEM = {24,24, + 5,5, + 0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,6,1,1,3,0,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,2,0,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,8,1,1,1,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,0,6,1,1,1,1,8,0,0,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,4,1,1,1,1,1,1,8,1,1,1,1,3,0,0,0,0, + 0,0,4,1,8,1,1,5,0,0,0,0,0,0,2,0,0,0,0,6,1,1,1,1, + 0,0,2,0,6,1,1,1,1,3,0,0,0,0,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,0,0,0,2,0,0,0,0,6,1,1,3,0,0,0,0,0,0, + 1,1,5,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,0,8,3,0,0,0,0,0,0,2,0,0,0,0,0,0, + 0,0,0,1,8,1,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,0,8,3,0,0,0,4,3,0,0,4,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,8,5,0,0,0,6,5,0,0,6,5,0,0,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,2,0,0,0, + 0,0,0,4,1,1,1,1,1,5,0,0,0,6,1,1,1,1,1,1,5,0,0,0, + 0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,8,0,0,0,0,0,0, + 0,0,0,2,0,0,0,0,0,0,2,0,2,0,0,0,0,0,8,0,0,0,0,0, + 0,0,0,2,0,0,0,0,2,0,2,0,2,0,0,0,0,0,0,8,0,0,0,0 + }, + + sprite0[] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + }, + + // - + sprite1[] PROGMEM = { + B00000000, + B11111000, + B10001000, + B11111000, + B00000000, + }, + + // | + sprite2[] PROGMEM = { + B01110000, + B01010000, + B01010000, + B01010000, + B01110000, + }, + + // -. + sprite3[] PROGMEM = { + B00000000, + B11100000, + B10110000, + B11010000, + B01110000, + }, + + // .- + sprite4[] PROGMEM = { + B00000000, + B00111000, + B01101000, + B01011000, + B01110000, + }, + + // -' + sprite5[] PROGMEM = { + B01110000, + B11010000, + B10110000, + B11100000, + B00000000, + }, + + // '- + sprite6[] PROGMEM = { + B01110000, + B01011000, + B01101000, + B00111000, + B00000000, + }, + + + // '- + sprite7[] PROGMEM = { + B11111000, + B10001000, + B10001000, + B10001000, + B11111000, + }, + + // '- + sprite8[] PROGMEM = { + B01110000, + B11011000, + B10000000, + B11011000, + B01110000, + }; + +// define the spritesheet +const byte *spritesheet[] = {sprite0,sprite1,sprite2,sprite3,sprite4,sprite5,sprite6,sprite7,sprite8}; + + + +int x=0,y=0; + +void setup() { + gb.begin(); + gb.titleScreen(F("test")); + gb.display.persistence = false; +} +void loop() { + if(gb.update()){ + if (gb.buttons.repeat(BTN_RIGHT,1)){x--;} + if (gb.buttons.repeat(BTN_LEFT,1)){x++;} + if (gb.buttons.repeat(BTN_DOWN,1)){y--;} + if (gb.buttons.repeat(BTN_UP,1)){y++;} + gb.display.drawTilemap(x,y,tilemap,spritesheet); // draw the tilemap + gb.display.cursorY = 12; gb.display.println( x );gb.display.println( y ); + } +}