help with graphics issues

Status
Not open for further replies.

Duhjoker

Well-known member
OK! Quick catch up.... I'm developing an all in one multiple mcu gaming library and diy handheld console that utilizes a teensy3.x and ili9341 tft but almost any mcu and tft can be used as long as it can run a tft that uses ili9341 drivers. Plus an easy to use library for creating your 8bit to 32bit graphical games. I had trouble with my button pad so I just ordered some more buttons and other supplies so I thought I might try to fix some graphical problems that have been plaguing me since day 1.

The main problem lies with in a function I transplanted into my library called tilemap along with the collision functions used with in the tilemap function. the functions come from the OG gamebuino library and functions by allowing you to create terrain maps made from different different bitmaps or tiles. first you make your bitmap tiles the put them into PROGMEM in binary form. different colors means splitting the bitmap tile into each basic color. for example if your bitmap has three colors then you would use three diiferent colored bitmaps stacked on each other but not overlapped to make a single tile.

Next you make a sprite sheet or how ever many you need for your colors. This is done in the same way you do the bitmaps but adding the names of each bitmap in the {} instead of the binary. This gives each bitmap a number in ram. The first bitmap being 0 and the 5th bitmap 4. Now you can recall all those bitmaps in any order you choose with out having to store more bitmaps to PROGMEM.

To do that you need to do now make your tilemap and store it PROGMEM. So do another const byte with the name of the tilemap then the tilemaps size and size of bitmaps and use your ram integers to call them using 0-4 if five bitmaps.

Now to draw it the screen we call the tilemap function with the proper variables listed like tft.drawTilemap(width,height,tilemap,spritesheet,color);

ok so the original tilemap function used int8_t but on the ili9341 it would only show a couple of the tiles on screen. So I thought I am using a bigger screen than the OG 84x48 nokia 5110 so double the int8_t to int16_t. this produced a more desireable effect but its only printing out part of the tilemap cutting 1 off most of the map. Next I tried using int64_t in the tilemap function but it only shows grey screen.


ok here is the functions as written in my library right now
.h bits
Code:
 void        drawBitmapTM(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t *bitmap, uint16_t dx, uint16_t dy, uint16_t dw, uint16_t dh, uint16_t color);
	boolean     getBitmapPixel(const uint8_t* bitmap, uint16_t x, uint16_t y);

	void        drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet, uint16_t color);
	void        drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet, uint32_t dx, uint32_t dy, uint32_t dw, uint32_t dh, uint16_t color);

	typedef struct {       //line 171 "Public Variables   - ADD by Summoner123
		int x;                    //X coordinate                 - ADD by Summoner123
		int y;                    //Y coordinate                 - ADD by Summoner123
		const byte *spritecol;    //Sprite of object             - ADD by Summoner123
	}object;
	object solid[60];         // Matriz were saved a Sprite, X and Y cordinates of all tiles on the screen - ADD by Summoner123

	byte numcolision = 0;     //count of solid objects indacat how many tiles drawed on the screen - ADD by Summoner123

	bool flagcollision = true;

////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
//////////////-----------------------------Collision--------------------------//////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////

	boolean collidePointRect(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t w, int16_t h);
	boolean collideRectRect(int16_t x1, int16_t y1, int16_t w1, int16_t h1, int16_t x2, int16_t y2, int16_t w2, int16_t h2);
	boolean collideBitmapBitmap(int16_t x1, int16_t y1, const uint8_t* b1, int16_t x2, int16_t y2, const uint8_t* b2);

.cpp
Code:
void Grafx_esp::drawBitmapTM(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t *bitmap, uint16_t dx, uint16_t dy, uint16_t dw, uint16_t dh, uint16_t color) {
	int16_t i, j, byteWidth = (w + 7) / 8;
	dw += dx;
	dh += dy;
	int16_t largest = 0;
	int16_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))) {
				int16_t drawX = x + i;
				int16_t drawY = y + j;

				if (drawX >= dx && drawX < dw && drawY >= dy && drawY < dh){
					drawPixel(drawX, drawY, color);
				}
			}
		}
	}
}

boolean Grafx_esp::getBitmapPixel(const uint8_t* bitmap, uint16_t x, uint16_t y){
	return pgm_read_byte(bitmap + 2 + y * ((pgm_read_byte(bitmap) + 7) / 8) + (x >> 3)) & (B10000000 >> (x % 8));
}

void Grafx_esp::drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet, uint16_t color){
	drawTilemap(x, y, tilemap, spritesheet, 0, 0, Grafx_TFTWIDTH, Grafx_TFTHEIGHT, color);
}
void Grafx_esp::drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet, uint32_t dx, uint32_t dy, uint32_t dw, uint32_t dh, uint16_t color){
	uint32_t tilemap_width = pgm_read_byte(tilemap);
	uint32_t tilemap_height = pgm_read_byte(tilemap + 1);
	uint32_t tile_width = pgm_read_byte(tilemap + 2);
	uint32_t tile_height = pgm_read_byte(tilemap + 3);
	tilemap += 4; // now the first tiyleis at tilemap
	uint32_t ddw = dw + dx;
	uint32_t ddh = dh + dy;
	uint32_t maxDdx = (dw - x + tile_width - 1) / tile_width;
	uint32_t maxDdy = (dh - y + tile_height - 1) / tile_height;
	if (tilemap_width < maxDdx){
		maxDdx = tilemap_width;
	}
	if (tilemap_height < maxDdy){
		maxDdy = tilemap_height;
	}
	int32_t startDdx = (-x) / tile_width;
	int32_t startDdy = (-y) / tile_height;
	if (startDdx < 0){
		startDdx = 0;
	}
	if (startDdy < 0){
		startDdy = 0;
	}
	if (flagcollision)numcolision = 0;                                 //Line 735 - clear numcolision - ADD by Summoner123

	for (uint32_t ddy = startDdy; ddy < maxDdy; ddy++){
		for (uint32_t ddx = startDdx; ddx < maxDdx; ddx++){
			int32_t drawX = ddx*tile_width + x + dx;
			int32_t drawY = ddy*tile_height + y + dy;
			uint32_t tile = pgm_read_byte(tilemap + ddy*tilemap_width + ddx);
			if (drawX >= dx && drawY >= dy && drawX <= (ddw - tile_width) && drawY <= (ddh - tile_height)){
				drawBitmap1(drawX, drawY, spritesheet[tile], tile_width, tile_height, color );

				if (flagcollision){
					solid[numcolision].x = drawX;                     //Save X coordinate      - ADD by Summoner123
					solid[numcolision].y = drawY;                     //Save Y coordinate      - ADD by Summoner123
					solid[numcolision].spritecol = spritesheet[tile]; //Save Sprite of tile    - ADD by Summoner123
					numcolision++;                                    //Increment numcolision  - ADD by Summoner123
				}
			}
			else{ // we need to draw a partial bitmap
				drawBitmapTM(drawX, drawY, tile_width, tile_height, spritesheet[tile], dx, dy, dw, dh, color);
			}
		}
	}
}

////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
//////////////-------------------------Collision----------------------//////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
boolean Grafx_esp::collidePointRect(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t w, int16_t h){
	if ((x1 >= x2) && (x1<x2 + w))
		if ((y1 >= y2) && (y1<y2 + h))
			return true;
	return false;
}

boolean Grafx_esp::collideRectRect(int16_t x1, int16_t y1, int16_t w1, int16_t h1, int16_t x2, int16_t y2, int16_t w2, int16_t h2){
	return !(x2 >= x1 + w1 ||
		x2 + w2 <= x1 ||
		y2 >= y1 + h1 ||
		y2 + h2 <= y1);
}

boolean Grafx_esp::collideBitmapBitmap(int16_t x1, int16_t y1, const uint8_t* b1, int16_t x2, int16_t y2, const uint8_t* b2){
	int16_t w1 = pgm_read_byte(b1);
	int16_t h1 = pgm_read_byte(b1 + 1);
	int16_t w2 = pgm_read_byte(b2);
	int16_t h2 = pgm_read_byte(b2 + 1);

	if (collideRectRect(x1, y1, w1, h1, x2, y2, w2, h2) == false){
		return false;
	}

	int16_t xmin = (x1 >= x2) ? 0 : x2 - x1;
	int16_t ymin = (y1 >= y2) ? 0 : y2 - y1;
	int16_t xmax = (x1 + w1 >= x2 + w2) ? x2 + w2 - x1 : w1;
	int16_t ymax = (y1 + h1 >= y2 + h2) ? y2 + h2 - y1 : h1;
	for (uint8_t y = ymin; y < ymax; y++){
		for (uint8_t x = xmin; x < xmax; x++){
			if (getBitmapPixel(b1, x, y) && getBitmapPixel(b2, x1 + x - x2, y1 + y - y2)){
				return true;
			}
		}
	}
	return false;
}

and the example sketch to paste to your teensy

Code:
////////////////////////////////
#include <ILI9341.h>
#include "SPI.h"


int player_x = 160;
 int player_y = 110;
 int player_direction = 2;


int x=-0,y=0;


//////////Paul_Atreades
//////////paul front

const byte paul_frontblack[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x02,0x40,0x02,0x30,0x0c,0x38,0x1c,0x4c,0x32,0x4f,0xf2,0x39,0x9c,0x16,0x68,0x11,0x88,0x08,0x10,0x0e,0x70};

const byte paul_frontblue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x40,0x02,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x01,0x80,0x06,0x60,0x06,0x60,0x00,0x00};

const byte paul_frontbrown[] PROGMEM = {16,16,
0x0e,0x70,0x1b,0xd8,0x16,0x68,0x19,0x98,0x20,0x04,0x16,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_frontgreen[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_frontgrey[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x08,0x10,0x00,0x00,0x00,0x00};

const byte paul_frontpink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x0f,0xf0,0x29,0x94,0x3d,0xbc,0x0d,0xb0,0x07,0xe0,0x33,0xcc,0x30,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_frontred[] PROGMEM = {16,16,
0x01,0x80,0x04,0x20,0x09,0x90,0x20,0x04,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0,0x00,0x00,0x00,0x00};

////////paul_front_walk_1

const byte paul_frontw1black[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x02,0x40,0x02,0x30,0x0e,0x38,0x1a,0x24,0x3c,0x27,0x98,0x19,0x68,0x0e,0x88,0x0e,0x10,0x00,0x10,0x00,0x70};

const byte paul_frontw1blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x40,0x02,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x80,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00};

const byte paul_frontw1brown[] PROGMEM = {16,16,
0x0e,0x70,0x1b,0xd8,0x16,0x68,0x19,0x98,0x20,0x04,0x16,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_frontw1green[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_frontw1grey[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_frontw1pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x0f,0xf0,0x29,0x94,0x3d,0xbc,0x0d,0xb0,0x07,0xe4,0x1b,0xc0,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_frontw1red[] PROGMEM = {16,16,
0x01,0x80,0x04,0x20,0x09,0x90,0x20,0x04,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

////////paul_front_walk_2

const byte paul_frontw2black[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x02,0x40,0x02,0x70,0x0c,0x58,0x1c,0x3c,0x24,0x19,0xe4,0x16,0x98,0x11,0x70,0x08,0x70,0x08,0x00,0x0e,0x00};

const byte paul_frontw2blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x40,0x02,0x40,0x00,0x00,0x00,0x00,0x06,0x00,0x01,0x60,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00};

const byte paul_frontw2brown[] PROGMEM = {16,16,
0x0e,0x70,0x1b,0xd8,0x16,0x68,0x19,0x98,0x20,0x04,0x16,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_frontw2green[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_frontw2grey[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_frontw2pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x0f,0xf0,0x29,0x94,0x3d,0xbc,0x0d,0xb0,0x27,0xe0,0x03,0xd8,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_frontw2red[] PROGMEM = {16,16,
0x01,0x80,0x04,0x20,0x09,0x90,0x20,0x04,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

////////paul left

 const byte paul_leftblack[] PROGMEM = {16,16,
0x00,0x00,0x00,0x0,0x00,0x00,0x00,0x00,0x10,0x00,0x14,0x00,0x10,0x00,0x10,0x00,0x08,0x60,0x07,0xe0,0x00,0x20,0x03,0x20,0x04,0xe0,0x04,0x20,0x01,0xc0,0x03,0xc0};

const byte paul_leftblue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00};

const byte paul_leftbrown[] PROGMEM = {16,16,
0x0e,0xd8,0x0d,0xa8,0x1b,0x74,0x3e,0xec,0x01,0xd8,0x00,0xb4,0x00,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_leftgreen[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_leftgrey[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0xc0,0x00,0x00,0x00,0x00};

const byte paul_leftpink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x0b,0x00,0x0b,0x60,0x0f,0xe0,0x07,0x80,0x00,0x00,0x00,0xc0,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_leftred[] PROGMEM = {16,16,
0x01,0x20,0x12,0x54,0x24,0x88,0x01,0x10,0x00,0x24,0x00,0x48,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

///////paul_left_walk

const byte paul_leftwblack[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x14,0x00,0x10,0x00,0x10,0x00,0x08,0x60,0x04,0xe0,0x1f,0x98,0x24,0x94,0x13,0xe4,0x12,0x44,0x02,0x24,0x0e,0x18};

const byte paul_leftwblue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x08,0x08,0x18,0x0c,0x38,0x0c,0x18,0x00,0x00};

const byte paul_leftwbrown[] PROGMEM = {16,16,
0x0e,0xe8,0x0d,0xd8,0x1b,0xb4,0x3f,0x6c,0x01,0xd8,0x00,0xb4,0x00,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_leftwgreen[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_leftwgrey[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_leftwpink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x0b,0x00,0x0b,0x60,0x0f,0xe0,0x07,0x80,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_leftwred[] PROGMEM = {16,16,
0x01,0x10,0x12,0x24,0x24,0x48,0x00,0x90,0x00,0x24,0x00,0x48,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

////////paul_rear

 const byte paul_rearblack[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x02,0x40,0x02,0x30,0x0c,0x38,0x1c,0x49,0x92,0x5e,0x7a,0x39,0x9c,0x16,0x68,0x11,0x80,0x08,0x10,0x0e,0x70};

const byte paul_rearblue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x01,0x80,0x06,0x60,0x01,0x80,0x06,0x60,0x06,0x60,0x00,0x00};

const byte paul_rearbrown[] PROGMEM = {16,16,
0x0d,0xb0,0x0b,0xd0,0x1d,0xb8,0x1a,0x58,0x37,0xec,0x0d,0xb0,0x0b,0xd0,0x02,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_reargrey[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x08,0x10,0x00,0x00,0x00,0x00};

const byte paul_rearpink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x04,0x30,0x0c,0x0c,0x30,0x07,0xe0,0x30,0x0c,0x20,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rearred[] PROGMEM = {16,16,
0x02,0x40,0x14,0x28,0x02,0x40,0x25,0xa4,0x08,0x10,0x12,0x48,0x04,0x20,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

///////paul_rear_walk1

 const byte paul_rearw1black[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x02,0x40,0x02,0x30,0x0e,0x3c,0x1a,0x49,0x9c,0x4e,0x78,0x33,0xe8,0x0e,0x88,0x0e,0x10,0x00,0x10,0x00,0x70};

const byte paul_rearw1blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x01,0x80,0x0c,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00};

const byte paul_rearw1brown[] PROGMEM = {16,16,
0x0d,0xb0,0x0b,0xd0,0x1d,0xb8,0x1a,0x58,0x37,0xec,0x0d,0xb0,0x0b,0xd0,0x02,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rearw1grey[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rearw1pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x04,0x30,0x0c,0x0c,0x30,0x03,0xe4,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rearw1red[] PROGMEM = {16,16,
0x02,0x40,0x14,0x28,0x02,0x40,0x25,0xa4,0x08,0x10,0x12,0x48,0x04,0x20,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

///////paul_rear_walk2

const byte paul_rearw2black[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x02,0x40,0x02,0x70,0x0c,0x58,0x1c,0x39,0x92,0x1e,0x72,0x17,0x4c,0x11,0x70,0x08,0x70,0x08,0x00,0x0e,0x00};

const byte paul_rearw2blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x01,0x80,0x00,0x30,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00};

const byte paul_rearw2brown[] PROGMEM = {16,16,
0x0d,0xb0,0x0b,0xd0,0x1d,0xb8,0x1a,0x58,0x37,0xec,0x0d,0xb0,0x0b,0xd0,0x02,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rearw2grey[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rearw2pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x04,0x30,0x0c,0x0c,0x30,0x27,0xc,0x00,0x0c,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rearw2red[] PROGMEM = {16,16,
0x02,0x40,0x14,0x28,0x02,0x40,0x25,0xa4,0x08,0x10,0x12,0x48,0x04,0x20,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

////////paul_right

 const byte paul_rightblack[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x00,0x08,0x00,0x08,0x06,0x10,0x07,0xe0,0x04,0x00,0x04,0xc0,0x07,0x20,0x04,0x20,0x03,0x80,0x03,0xc0};

const byte paul_rightblue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x00};

const byte paul_rightbrown[] PROGMEM = {16,16,
0x1b,0x70,0x15,0xb0,0x2e,0xd8,0x37,0x7c,0x1b,0x80,0x2d,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rightgrey[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x80,0x00,0x00,0x00,0x00};

const byte paul_rightpink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0xd0,0x06,0xd0,0x07,0xf0,0x01,0xe0,0x00,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rightred[] PROGMEM = {16,16,
0x04,0x80,0x2a,0x48,0x11,0x24,0x08,0x80,0x24,0x00,0x12,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

////////paul_right_walk

 const byte paul_rightwblack[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x00,0x08,0x00,0x08,0x06,0x10,0x07,0x20,0x19,0xf8,0x29,0x24,0x27,0xc8,0x22,0x48,0x24,0x40,0x18,0x70};

const byte paul_rightwblue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x10,0x18,0x18,0x10,0x1c,0x30,0x18,0x30,0x00,0x00};

const byte paul_rightwbrown[] PROGMEM = {16,16,
0x17,0x70,0x1b,0xb0,0x2d,0xd8,0x36,0xfc,0x1b,0x80,0x2d,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rightwgrey[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rightwpink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0xd0,0x06,0xd0,0x07,0xf0,0x01,0xe0,0x00,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rightwred[] PROGMEM = {16,16,
0x08,0x80,0x24,0x48,0x12,0x24,0x09,0x00,0x24,0x00,0x12,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

const byte rock_black[] PROGMEM = {16,16,
B00010101,B10110100,B00001101,B10001110,B00001101,B10001101,B00001101,B10000101,B00001001,B10000101,B00001001,B10000001,B00001001,B10000110,B00001011,B00000010,B00001001,B10000001,B00011001,B10000001,B00111011,B10000011,B00100011,B11000010,B01000001,B10000010,B01000001,B10000010,B00000001,B11000111,B10000001,B10100110};

const byte rock_beige[] PROGMEM = {16,16,
B00001000,B00001000,B00000010,B00000001,B00000010,B00000000,B10000010,B00000000,B10000100,B00000000,B00000100,B00000000,B00000100,B00011001,B00000100,B00100001,B00000100,B00100000,B00000100,B00010000,B10000100,B00100000,B10011100,B00000001,B00100000,B01000001,B00100000,B01000001,B01000000,B00000000,B01010010,B0011001};

const byte rock_brown[] PROGMEM = {16,16,
B11100010,B01000011,B11110000,B01110000,B11110000,B01110010,B01110000,B01111010,B01110010,B01111010,B11110010,B01111110,B11110010,B01100000,B11110010,B01011100,B11110010,B01011110,B11100010,B01011110,B01000000,B01011100,B01000000,B00111100,B10011110,B00111100,B10011110,B00111100,B10111110,B00111000,B00101100,B01000000};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

const byte sand_brown[] PROGMEM = {16,16,
B00100100,B10010010,B00000000,B00000000,B00100100,B10010010,B00000000,B00000000,B00100100,B10010010,B00000000,B00000000,B00100100,B10010010,B00000000,B00000000,B00100100,B10010010,B00000000,B00000000,B00100100,B10010010,B00000000,B00000000,B00100100,B10010010,B00000000,B00000000,B00100100,B10010010,B00000000,B00000000};

const byte sand_beige[] PROGMEM = {16,16,
B11011011,B01101101,B11111111,B11111111,B11011011,B01101101,B11111111,B11111111,B11011011,B01101101,B11111111,B11111111,B11011011,B01101101,B11111111,B11111111,B11011011,B01101101,B11111111,B11111111,B11011011,B01101101,B11111111,B11111111,B11011011,B01101101,B11111111,B11111111,B11011011,B01101101,B11111111,B11111111};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

const byte blank_tile1[] PROGMEM = {16,16,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};

const byte blank_tile2[] PROGMEM = {16,16,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};

const byte blank_tile3[] PROGMEM = {16,16,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};




const byte *spritesheet1[] PROGMEM = {blank_tile1,rock_black,};

const byte *spritesheet2[] PROGMEM = {blank_tile2, rock_brown, sand_brown,};

const byte *spritesheet3[] PROGMEM = {blank_tile3, rock_beige, sand_beige,};

///black
const byte tilemap_black[] PROGMEM = {22,14,
16,16,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,
0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,};

///brown
const byte tilemap_brown[] PROGMEM = {22,14,
16,16,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,
1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,1,1,1,};

///beige
const byte tilemap_beige[] PROGMEM = {22,14,
16,16,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,
2,2,2,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,
1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,1,1,1,};

  

void setup() {
    Serial.begin(921600);
    long unsigned debug_start = millis();
    while (!Serial && (millis() < 4000)) ;
  tft.begin();
//   tft.titleScreen(F("Dune esp demo"));
  tft.setFrameRate(62);
  tft.persistence = false;
  tft.setRotation(1);
  tft.fillScreen(BLACK);

tft.drawTilemap(x, y, tilemap_black, spritesheet1, BLACK);
  tft.drawTilemap(x, y, tilemap_brown, spritesheet2, BROWN);
   tft.drawTilemap(x, y, tilemap_beige, spritesheet3, LIGHTBROWN);
  
  }

//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////

void loop(void) {
//updates the GameRIot (the display, the sound, the buttons, everyyhing)
  //returns true when it's time to render a new frame (20 times/second)
   if(tft.updateAll()){
    if (tft.buttons.repeat(BTN_RIGHT,1));//{X--:}
    if (tft.buttons.repeat(BTN_LEFT,1));//{X++:}
    if (tft.buttons.repeat(BTN_DOWN,1));//{Y--:}
    if (tft.buttons.repeat(BTN_UP,1));//{Y--:}


//tft.drawTilemap(x, y, tilemap_black, spritesheet1, BLACK);
//  tft.drawTilemap(x, y, tilemap_brown, spritesheet2, BROWN);
//   tft.drawTilemap(x, y, tilemap_beige, spritesheet3, LIGHTBROWN);

    if (tft.buttons.repeat(BTN_UP,1)){
       tft.drawBitmap1(player_x, player_y,paul_rearblack,16,16,BLACK);
         tft.drawBitmap1(player_x, player_y,paul_rearblue,16,16,BLUE);
          tft.drawBitmap1(player_x, player_y,paul_rearbrown,16,16,BROWN);
          tft.drawBitmap1(player_x, player_y,paul_reargrey,16,16,GREY);
           tft.drawBitmap1(player_x, player_y,paul_rearpink,16,16,PINK);
            tft.drawBitmap1(player_x, player_y,paul_rearred,16,16,YELLOW);

            player_direction = 1;
             player_y = player_y - 1;}
            if(player_y <= 0){
              player_y = 0;}

       if (tft.buttons.repeat(BTN_DOWN,1)){
        tft.drawBitmap1(player_x, player_y,paul_frontblack,16,16,BLACK);
         tft.drawBitmap1(player_x, player_y,paul_frontblue,16,16,BLUE);
          tft.drawBitmap1(player_x, player_y,paul_frontbrown,16,16,BROWN);
          tft.drawBitmap1(player_x, player_y,paul_frontgrey,16,16,GREY);
          tft.drawBitmap1(player_x, player_y,paul_frontgreen,16,16,GREEN);
           tft.drawBitmap1(player_x, player_y,paul_frontpink,16,16,PINK);
            tft.drawBitmap1(player_x, player_y,paul_frontred,16,16,RED);

            player_direction = 2;
             player_y = player_y + 1;}
            if(player_y <= 40){
              player_y = 40;}

       if (tft.buttons.repeat(BTN_LEFT,1)){
        tft.drawBitmap1(player_x, player_y,paul_leftblack,16,16,BLACK);
         tft.drawBitmap1(player_x, player_y,paul_leftblue,16,16,BLUE);
          tft.drawBitmap1(player_x, player_y,paul_leftbrown,16,16,BROWN);
          tft.drawBitmap1(player_x, player_y,paul_leftgreen,16,16,GREEN);
          tft.drawBitmap1(player_x, player_y,paul_leftgrey,16,16,GREY);
           tft.drawBitmap1(player_x, player_y,paul_leftpink,16,16,PINK);
            tft.drawBitmap1(player_x, player_y,paul_leftred,16,16,RED);

            player_direction = 3;
             player_x = player_x - 1;}
            if(player_x <= -2){
              player_x = -2;}

        if (tft.buttons.repeat(BTN_RIGHT,1)){
        tft.drawBitmap1(player_x, player_y,paul_rightblack,16,16,BLACK);
         tft.drawBitmap1(player_x, player_y,paul_rightblue,16,16,BLUE);
          tft.drawBitmap1(player_x, player_y,paul_rightbrown,16,16,BROWN);
          tft.drawBitmap1(player_x, player_y,paul_rightbrown,16,16,GREY);
           tft.drawBitmap1(player_x, player_y,paul_rightpink,16,16,PINK);
            tft.drawBitmap1(player_x, player_y,paul_rightred,16,16,RED);

            player_direction = 3;
            player_x = player_x - 1;}
           if(player_x <= -2){
              player_x = -2;}

       /////////////////PLAYER DIRECTION/////////////////

        if (player_direction == 1){
          tft.drawBitmap1(player_x, player_y,paul_rearblack,16,16,BLACK);
         tft.drawBitmap1(player_x, player_y,paul_rearblue,16,16,BLUE);
          tft.drawBitmap1(player_x, player_y,paul_rearbrown,16,16,BROWN);
          tft.drawBitmap1(player_x, player_y,paul_reargrey,16,16,GREY);
           tft.drawBitmap1(player_x, player_y,paul_rearpink,16,16,PINK);
            tft.drawBitmap1(player_x, player_y,paul_rearred,16,16,YELLOW);

       }

      else if (player_direction == 2){
         tft.drawBitmap1(player_x, player_y,paul_frontblack,16,16,BLACK);
         tft.drawBitmap1(player_x, player_y,paul_frontblue,16,16,BLUE);
          tft.drawBitmap1(player_x, player_y,paul_frontbrown,16,16,BROWN);
          tft.drawBitmap1(player_x, player_y,paul_frontgrey,16,16,GREY);
          tft.drawBitmap1(player_x, player_y,paul_frontgreen,16,16,GREEN);
           tft.drawBitmap1(player_x, player_y,paul_frontpink,16,16,PINK);
            tft.drawBitmap1(player_x, player_y,paul_frontred,16,16,RED);

              }


       else if (player_direction == 3){
         tft.drawBitmap1(player_x, player_y,paul_leftblack,16,16,BLACK);
         tft.drawBitmap1(player_x, player_y,paul_leftblue,16,16,BLUE);
          tft.drawBitmap1(player_x, player_y,paul_leftbrown,16,16,BROWN);
          tft.drawBitmap1(player_x, player_y,paul_leftgreen,16,16,GREEN);
          tft.drawBitmap1(player_x, player_y,paul_leftgrey,16,16,GREY);
           tft.drawBitmap1(player_x, player_y,paul_leftpink,16,16,PINK);
            tft.drawBitmap1(player_x, player_y,paul_leftred,16,16,RED);

            }


        else if (player_direction == 4){
          tft.drawBitmap1(player_x, player_y,paul_rightblack,16,16,BLACK);
         tft.drawBitmap1(player_x, player_y,paul_rightblue,16,16,BLUE);
          tft.drawBitmap1(player_x, player_y,paul_rightbrown,16,16,BROWN);
          tft.drawBitmap1(player_x, player_y,paul_rightbrown,16,16,GREY);
           tft.drawBitmap1(player_x, player_y,paul_rightpink,16,16,PINK);
            tft.drawBitmap1(player_x, player_y,paul_rightred,16,16,RED);

               }

            
       }
}



Any im hoping somebody can help me figure this out. Please!!!!
 
Last edited:
Ok do int8_t integers have to double into 16 and 32 and 64 and so on? Or can it just be multiples of 8?
 
Just a quick note - 1 byte - or 2 for 16 bits or 4 for 32 bits are just bits/bytes in a row. One way it could matter would be ordering when taken as pairs or quads. If the display is looking for 16 bit color values - the byte order matters.
 
A couple of other notes:

Progmem is a construct needed for AVR Atmega like chips where they have two different memory addressing schemes (Data vs Code area). With the Teensy and like boards who have one address space, they are not needed. Simply defining an array as const will put the data into the program space...

Ok do int8_t integers have to double into 16 and 32 and 64 and so on? Or can it just be multiples of 8?
Not sure what you are asking here? what do you mean by double into 16...? If you are asking about how to convert a byte to a word? Or how to convert multiple bytes into a word, than Defragster mentioned, the order of the bytes matters and not all processors have the bytes in the same order. Some have the most significant byte first some have the least.

Or are you asking how to convert the bytes in your arrays into the right colors? Then again it depends on what your bytes signify and what each of your displays require. That is for example the ili9341 display you typically give it a 16 bit value per pixel, where there are so many bits for red, so many bits for green and so many bits for blue: As you can see by the function that creates a color value:
static uint16_t color565(uint8_t r, uint8_t g, uint8_t b) {
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);

So if your array is setup where these values hold some color data, you need to convert that data into the specifics for the display.

If however this array is setup like an 8 bit bitmap, where somewhere else defines what each color is (i.e a palette) , like index 1 is white or 0xffff and 0 is black 0x0000

Then you maybe should look at my ili9341_t3n functions where I merged in code to do this (writeRect8BPP)... There are also functions that handle 4BPP and 2BPP...
 
Thanks KurtE for the details showing where I was 'going'. I made mention of PROGMEM IIRC on another Duhjoker thread on this so skipped it here - I might suggest keeping more of the project core in a single thread for easier reference.

One other thing I see is the explosion of the source file holding the bitmaps. It might be better to isolate them to external files. For an example o that see:
I:\arduino-1.8.1\hardware\teensy\avr\libraries\Audio\examples\Tutorial\Part_3_02_Fourier_Transform\Part_3_02_Fourier_Transform.ino

A bit of extra work to create the header for inclusion that links to the data stored in the cpp file. But that puts those data arrays into separate files 'out of the way'.
 
I am not sure what a game boy display should look like, but I assume it should fill the screen and not have horizontal blue lines?
Your tilemap is 22x16 by 14x16 or 352 by 224. And the display is 320 by 240. It looks like you get 15 tiles across and 14 tiles down.
I think that accounts for the blank space at the bottom of one tile, 16 bits, or 14 tiles correctly displayed as programmed.

15 tiles across is very suspiciously the same as the short side of the display ( 15x16 = 240 ). So perhaps look at what Grafx_TFTWIDTH, Grafx_TFTHEIGHT are set as, or call the long form of the function with the correct values.

For the blue lines I think I would try removing the size information in the sprites for the tiles???? Functions are missing in the code you posted and it is too complicated to wade through anyway. I get confused with too much indirection and I am not not not joking.

But it looks like an off by one error. Your code is very complicated and if you continue to have trouble you should maybe just try to display one tile and use some debugging print statements to see why one of the lines is missing from each tile.
 
actually what I was asking if I could go like int40_t. The reason being that at int32 in the tilemap code gave me more screen but int64_t gave a grey screen. So I was wondering if there was a way to do a happy medium. I got on my text editor and tried but it would light up so........

I don't think it's color that's the problem. I mean the colors turn out fine and I can display multiple colors at once.

The functions are actually meant for a Nokia 5110 LCD. I've used it a lot on my lil Gamebuino system and can print tilemaps as big as 300 tiles by 300 tiles using 16bit bitmaps. Though they are huge on the smaller display. Then I use camera controls to scroll. But the code is originally designed to handle the 84x48 LCD.

So I started looking at the original code including the bitmap functions and found some differences in the way they were written. I'm not fished de-bugging it yet but just for $#!+$ and giggles I decided to kill my updated version with color and all that by commenting it all out and then transplanted the entire libraries bitmap and tilemap function. From thier I made a pair setColor functions that can be called before each tilemap. That way the tilemap uses the the same binary/hex bitmap image.

Edit::

when I try to set color before the functions I get nothing but black screen or gray screen

Also when I add a couple more rows to the bottom it shows the bottom line but when I add a few more vertical rows it still still cuts off from the left side.

There's a different way as seen here.......

https://github.com/Rodot/Gamebuino/blob/master/examples/2.Intermediate/TileMapRAM/TileMapRAM.ino

Still trying to understand it though.
 
Last edited:
In terms of int types, you are restricted to powers of 2:
  • int8_t and uint8_t
  • int16_t and uint16_t
  • int32_t and uint32_t
  • int64_t and uint64_t

That's just the way microprocessors are designed. They typically have 1 or 2 sizes that are done directly with a single instruction. Smaller types are done by loading the value into a register which sign/zero extended it to the supported size. Calculations are done in that size, and then it is stored via truncation back into memory. Types larger than the supported size are done as several instructions, much like you learned to do arithmetic in school, doing the calculation one digit at a time. The ARM processors used in Teensy are 32-bit processors, so 32-bit is the native type. I don't recall if 8/16-bit types are directly handled, or if it is converted to 32-bits. The 64-bit types will be done as multiple instructions.
 
Awesome that makes since!

Ok so if I try just print one tile using the tilemap it prints one tile where I want it. But any thing after the 5th vertical column refuse to show. It's really weird. Like I said I once made made a map at 300 by 300 tiles using the original code and had to use scrolling of course to see it all.

The rotation is set to landscape mode and the Grafx_TFTWIDTH and height are listed as 340 and 220 respectively. Just moved my player Sprite to the part of the screen that won't show the tilemap and he appears there. But if I try to change the placement of the map itself I get black screen

Edit::::

Ok the Grafx_TFT height and width were back wards. So I switched them to landscape mode. With no change. I then started playing around with the set rotation function in my void set up. No change. But I noticed in the begin function that it has a rotation set with in it calling it

Rotation = 0;

I looked and found that the uint8_t rotation in with all the rest. But when I change the number to say... 1,2 or 3 I get no change.

When I remove the bitmap size 16,16 from the array it will not print any thing. I also tried changing the 22,14 as well in the tile map array. It just changed the direction the that the tiles appear. But still cuts off the right side of the screen. If I change the tilemap to 29,17 or reverse of that it will fill the bottom row. But still cuts 5 off from the right side.
 

Attachments

  • GamerRIot-master.zip
    236.3 KB · Views: 149
Last edited:
ok so I took a day to do some research but came up short in every way. I even went to the source but I'm not going to talk about that conversation.:p

Any way I started looking closer at the tilemap() functions themselves with their included drawbitmap commands. Now bare with me. I changed all the int's and the uint's which gave me the most of the map. But I did change the const uint8_t spritesheet, or the tilemap in either the fuction prototype or the definition. For example......

Code:
void        drawBitmapTMA(int32_t x, int32_t y, int32_t w, int32_t h , const uint8_t *bitmap, uint16_t color);
    void        drawBitmapTM(int32_t x, int32_t y, int32_t w, int32_t h, const uint8_t *bitmap, uint32_t dx, uint32_t dy, uint32_t dw, uint32_t dh, uint16_t color);
	boolean     getBitmapPixel(const uint8_t* bitmap, uint32_t x, uint32_t y);

	void        drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet, uint16_t color);
	void        drawTilemap(int x, int y, const uint8_t *tilemap, const uint8_t **spritesheet, uint32_t dx, uint32_t dy, uint32_t dw, uint32_t dh, uint16_t color);

But if I try to change them to const uint16_t I get error messages like this.......

Code:
Arduino: 1.8.1 (Windows 10), TD: 1.36, Board: "ESP32 Dev Module, 80MHz, 921600, None"

WARNING: library SPI claims to run on [esp32] architecture(s) and may be incompatible with your current board which runs on [Esp32] architecture(s).
C:\Users\chuck\Desktop\GameRIot_esp_demo\GameRIot_esp_demo.ino: In function 'void setup()':

GameRIot_esp_demo:359: error: no matching function for call to 'Grafx_esp::drawTilemap(int&, int&, const byte [497], const byte* [2], int)'

 tft.drawTilemap(x, y, tilemap_black, spritesheet1, BLACK);

                                                         ^

In file included from C:\Users\chuck\Desktop\GameRIot_esp_demo\GameRIot_esp_demo.ino:2:0:

C:\Users\chuck\OneDrive\Documents\Arduino\libraries\GameRIot_esp/Grafx_esp.h:273:14: note: candidate: void Grafx_esp::drawTilemap(int, int, const uint16_t*, const uint16_t**, uint16_t)

  void        drawTilemap(int x, int y, const uint16_t *tilemap, const uint16_t **spritesheet, uint16_t color);

              ^

C:\Users\chuck\OneDrive\Documents\Arduino\libraries\GameRIot_esp/Grafx_esp.h:273:14: note:   no known conversion for argument 3 from 'const byte [497] {aka const unsigned char [497]}' to 'const uint16_t* {aka const short unsigned int*}'

C:\Users\chuck\OneDrive\Documents\Arduino\libraries\GameRIot_esp/Grafx_esp.h:274:14: note: candidate: void Grafx_esp::drawTilemap(int, int, const uint16_t*, const uint16_t**, uint32_t, uint32_t, uint32_t, uint32_t, uint16_t)

  void        drawTilemap(int x, int y, const uint16_t *tilemap, const uint16_t **spritesheet, uint32_t dx, uint32_t dy, uint32_t dw, uint32_t dh, uint16_t color);

              ^

C:\Users\chuck\OneDrive\Documents\Arduino\libraries\GameRIot_esp/Grafx_esp.h:274:14: note:   candidate expects 9 arguments, 5 provided

GameRIot_esp_demo:360: error: no matching function for call to 'Grafx_esp::drawTilemap(int&, int&, const byte [497], const byte* [3], int)'

 tft.drawTilemap(x, y, tilemap_brown, spritesheet2, BROWN);

                                                         ^

In file included from C:\Users\chuck\Desktop\GameRIot_esp_demo\GameRIot_esp_demo.ino:2:0:

C:\Users\chuck\OneDrive\Documents\Arduino\libraries\GameRIot_esp/Grafx_esp.h:273:14: note: candidate: void Grafx_esp::drawTilemap(int, int, const uint16_t*, const uint16_t**, uint16_t)

  void        drawTilemap(int x, int y, const uint16_t *tilemap, const uint16_t **spritesheet, uint16_t color);

              ^

C:\Users\chuck\OneDrive\Documents\Arduino\libraries\GameRIot_esp/Grafx_esp.h:273:14: note:   no known conversion for argument 3 from 'const byte [497] {aka const unsigned char [497]}' to 'const uint16_t* {aka const short unsigned int*}'

C:\Users\chuck\OneDrive\Documents\Arduino\libraries\GameRIot_esp/Grafx_esp.h:274:14: note: candidate: void Grafx_esp::drawTilemap(int, int, const uint16_t*, const uint16_t**, uint32_t, uint32_t, uint32_t, uint32_t, uint16_t)

  void        drawTilemap(int x, int y, const uint16_t *tilemap, const uint16_t **spritesheet, uint32_t dx, uint32_t dy, uint32_t dw, uint32_t dh, uint16_t color);

              ^

C:\Users\chuck\OneDrive\Documents\Arduino\libraries\GameRIot_esp/Grafx_esp.h:274:14: note:   candidate expects 9 arguments, 5 provided

GameRIot_esp_demo:361: error: no matching function for call to 'Grafx_esp::drawTilemap(int&, int&, const byte [497], const byte* [3], int)'

  tft.drawTilemap(x, y, tilemap_beige, spritesheet3, LIGHTBROWN);

                                                               ^

In file included from C:\Users\chuck\Desktop\GameRIot_esp_demo\GameRIot_esp_demo.ino:2:0:

C:\Users\chuck\OneDrive\Documents\Arduino\libraries\GameRIot_esp/Grafx_esp.h:273:14: note: candidate: void Grafx_esp::drawTilemap(int, int, const uint16_t*, const uint16_t**, uint16_t)

  void        drawTilemap(int x, int y, const uint16_t *tilemap, const uint16_t **spritesheet, uint16_t color);

              ^

C:\Users\chuck\OneDrive\Documents\Arduino\libraries\GameRIot_esp/Grafx_esp.h:273:14: note:   no known conversion for argument 3 from 'const byte [497] {aka const unsigned char [497]}' to 'const uint16_t* {aka const short unsigned int*}'

C:\Users\chuck\OneDrive\Documents\Arduino\libraries\GameRIot_esp/Grafx_esp.h:274:14: note: candidate: void Grafx_esp::drawTilemap(int, int, const uint16_t*, const uint16_t**, uint32_t, uint32_t, uint32_t, uint32_t, uint16_t)

  void        drawTilemap(int x, int y, const uint16_t *tilemap, const uint16_t **spritesheet, uint32_t dx, uint32_t dy, uint32_t dw, uint32_t dh, uint16_t color);

              ^

C:\Users\chuck\OneDrive\Documents\Arduino\libraries\GameRIot_esp/Grafx_esp.h:274:14: note:   candidate expects 9 arguments, 5 provided

exit status 1
no matching function for call to 'Grafx_esp::drawTilemap(int&, int&, const byte [497], const byte* [2], int)'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

but I know they match!!!!!!!!!

ok I was also curiuos about the draw bitmap functions and changing the const uint8_t bitmap. so I did a search for const uint16_t bitmap and came across this page for a adafruit gfx library.....

https://github.com/adafruit/Adafruit-GFX-Library/blob/master/Adafruit_GFX.h

specifically these functions.........

Code:
 drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[],

      int16_t w, int16_t h),

    drawRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap,

      int16_t w, int16_t h),

    drawRGBBitmap(int16_t x, int16_t y,

      const uint16_t bitmap[], const uint8_t mask[],

      int16_t w, int16_t h),

    drawRGBBitmap(int16_t x, int16_t y,

      uint16_t *bitmap, uint8_t *mask, int16_t w, int16_t h),

and the .cpp

Code:
// Draw a PROGMEM-resident 16-bit image (RGB 5/6/5) at the specified (x,y)

// position.  For 16-bit display devices; no color reduction performed.

void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y,

  const uint16_t bitmap[], int16_t w, int16_t h) {

    startWrite();

    for(int16_t j=0; j<h; j++, y++) {

        for(int16_t i=0; i<w; i++ ) {

            writePixel(x+i, y, pgm_read_word(&bitmap[j * w + i]));

        }

    }

    endWrite();

}



// Draw a RAM-resident 16-bit image (RGB 5/6/5) at the specified (x,y)

// position.  For 16-bit display devices; no color reduction performed.

void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y,

  uint16_t *bitmap, int16_t w, int16_t h) {

    startWrite();

    for(int16_t j=0; j<h; j++, y++) {

        for(int16_t i=0; i<w; i++ ) {

            writePixel(x+i, y, bitmap[j * w + i]);

        }

    }

    endWrite();

}



// Draw a PROGMEM-resident 16-bit image (RGB 5/6/5) with a 1-bit mask

// (set bits = opaque, unset bits = clear) at the specified (x,y) position.

// BOTH buffers (color and mask) must be PROGMEM-resident.

// For 16-bit display devices; no color reduction performed.

void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y,

  const uint16_t bitmap[], const uint8_t mask[],

  int16_t w, int16_t h) {

    int16_t bw   = (w + 7) / 8; // Bitmask scanline pad = whole byte

    uint8_t byte = 0;

    startWrite();

    for(int16_t j=0; j<h; j++, y++) {

        for(int16_t i=0; i<w; i++ ) {

            if(i & 7) byte <<= 1;

            else      byte   = pgm_read_byte(&mask[j * bw + i / 8]);

            if(byte & 0x80) {

                writePixel(x+i, y, pgm_read_word(&bitmap[j * w + i]));

            }

        }

    }

    endWrite();

}



// Draw a RAM-resident 16-bit image (RGB 5/6/5) with a 1-bit mask

// (set bits = opaque, unset bits = clear) at the specified (x,y) pos.

// BOTH buffers (color and mask) must be RAM-resident, no mix-and-match.

// For 16-bit display devices; no color reduction performed.

void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y,

  uint16_t *bitmap, uint8_t *mask, int16_t w, int16_t h) {

    int16_t bw   = (w + 7) / 8; // Bitmask scanline pad = whole byte

    uint8_t byte = 0;

    startWrite();

    for(int16_t j=0; j<h; j++, y++) {

        for(int16_t i=0; i<w; i++ ) {

            if(i & 7) byte <<= 1;

            else      byte   = mask[j * bw + i / 8];

            if(byte & 0x80) {

                writePixel(x+i, y, bitmap[j * w + i]);

            }

        }

    }

    endWrite();

}


it says what it says in the .cpp part but I'm not seeing where it gets the color part. would this be better way to do he bitmaps? what about upping the const uint in the tilemap for tilemap and sprite sheet? could this be part of the problem. By the way the library is super organized and placement of functions and //// comment dividers match in order for both .h and .cpp. takes alil time but makes it so much easier to find what I need.


Edit :::::

I found this example and I ran a preliminary test and it works but guess what? It still cuts the last five rows off. This flat insanity!!!!! What do I do lol!!!

Note........ When ever I try to print out a bitmap the same size as the screen resolution it gives me errors. It's late now but I'll do it first thing tomorrow so I can post the errors.
 
Last edited:
Again it is hard to know what is going on... Also not sure what this has to do with Teensy? Sounds like ESP32 and Adafruit code with a different display...

But if it were me, I would start looking at some of the simple math... What I mean is, when you see lines in the code like:
writePixel(x+i, y, pgm_read_word(&bitmap[j * w + i]));

What are the values/ranges of the variables: J, w, i that you are using?
Could it be when you are using your larger images, that maybe the system is using 16 bit math and when J is large enough j*w > 65535? And so it wraps around?

What happens if you change these variables from int16 to int32? Or maybe do a cast to uint32_t in the math cases like this?

Sometimes you run into issues if you have math like z = (x*y*z)/t if the code first does the x*y*z and it overflows, to where you need to rework the equation...

I am suspecting you are running into those types of issues.

Edit: suppose that display is 320x240 (ili9341) = 76800 which is > 65536

How many lines or rows fit in 16 bits?
65536/320 = 204+ so about 35+ rows will wrap...
65536/240 = 273+ so about 46+ will rap.
 
Last edited:
>>>When I remove the bitmap size 16,16 from the array it will not print any thing.

I was not very clear what I meant about the size information, so let me try again.

In function drawTilemap you have this line of code: tilemap += 4; // now the first tiyleis at tilemap
So that skips past the size information in the tilemap ( the 22,14,16,16 ) and that looks correct.

Where the sprites are used I do not see where the ( 16, 16 ) is skipped in the file. You do not post the code for
function drawBitmap1, but it looks like function drawBitmapTM should be very similar.

So the first lines of your drawBitmapTM is

Code:
void Grafx_esp::drawBitmapTM(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t *bitmap, uint16_t dx, uint16_t dy, uint16_t dw, uint16_t dh, uint16_t color) {
	int16_t i, j, byteWidth = (w + 7) / 8;
	dw += dx;
	dh += dy;
	int16_t largest = 0;
	int16_t largesty = 0;
	for (j = 0; j < h; j++) {
		for (i = 0; i < w; i++) {
			if (pgm_read_byte([B]bitmap[/B] + j * byteWidth + i / 8) & (B10000000 >> (i % 8))) {

so the spritesheet pointer has been used without removing the offset of the first two bytes. I suspect you have fudged your maps, but they still can't look correct as the code is picking up the 16,16 as the first two bytes of your map.

Of course since you haven't posted complete code, this detail may have been handled elsewhere in your code.
 
Ok we can come back to that. I and another poster from Gamebuino gave it a full day changing stuff and trying different things but no go.

I am how e ear having trouble with tron trails. When the player Sprite moves he leaves a trial like a tron light cycle. I tried a few things like adding fill screen to the update hoping it would paint over the trails but that didn't work. If I add the working part of the tilemap the player moves annoyingly slow but can be sped up by changing a variable in the walk function.

Any clues how to fix this?

 
Last edited:
You need to erase ( or return to background color ) the space that that the sprite has moved from. The simplest way would be to put a border of background color around the sprite ( of 2 pixels for example ) and then don't ever move the sprite more than the width of the border ( 2 pixels in the example ) at any one time.
The downside of this approach will be that your collisions will happen 2 pixels away from the object you bump in to. You may not like how that looks, but try it and see. Someone just playing may not even notice.
 
You can do as rcarr mentioned, or you may need to do some smart updates code. Again I have not looked through your current stuff.
But you may need to do something like: have old rectangle and new rectangle and figure out the differences between the two and redraw the old area that is no longer in your object.
However what I don't know is if you can simply fill to background color, or potentially a different object is there and as such you need to redraw those portions with the appropriate part of the other object(s).

With some other systems, I have played with another approach is to before you draw a sprite, you read in the current stuff into a save area, and when you move, you restore those areas no longer occupied by the sprite from your save data.

But again I have not looked at your current stuff. For example are you now using screen buffer? If so are you also using clip rectangles? If so, when you are redrawing the new location do you set a clip rectangle to the area where the sprite now is? If so a fillRect outside of this area won't do anything...
 
Status
Not open for further replies.
Back
Top