Using frame buffering to solidify tft displayed objects

Status
Not open for further replies.

Duhjoker

Well-known member
[SOLVED] Using frame buffering to solidify tft displayed objects

This thread has been solved. For more info on the GameR-iot arduino driven multiple MCU gaming platform thing, please catch me on github or join us on Facebook at GameR-Iot advanced multiple MCU gaming.


Ok guys I'm almost done with my project. For those that need a catch up..... I've been building a library for easy 8 to 32bit gaming on a console you build yourself using most Arduino driven MCU's but is focused around T3 MCU's. Its been shaky getting going. I have had to upgrade and update the original Gamebuino library to run on a teensy and with full color. But with the dedicated patience of the people here ive almost got everything working...... properly at least.

We fixed the tile map and fill screen functions and every thing displays but I'm having problems with flashing when the player sprite is set up over a tilemap. Both the tilemap and the character sprites flash. This was originally fixed in another library with kurts spin and frame buffer functions which kept the player sprites from flashing and making it solid. But sitting on top of the tilemapis another matter entirely.

I think this is frame buffer problem, maybe it cant catch up or maybe I'm using the functions wrong. Shouldn't it kind of clear the screen at a certain rate of speed so it looks solid? I also have a setoff frame rate commands that can be utilized but I need a lil working out the problem.

I have all that and more in my library as seen here. So first lets look at some OG Gamebuino functions.....


///from gamebuino display.h
Code:
extern uint8_t _displayBuffer[];


uint8_t* getBuffer();

void clear(void);
	void update();

boolean persistence;

byte frameCount;

	  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;	

inline uint8_t* Display::getBuffer(){
	return _displayBuffer;
}

the cpp counterparts from display.cpp
Code:
void Display::clear(void) {
    memset(_displayBuffer, 0, LCDWIDTH * LCDHEIGHT / 8);
    cursorY = cursorX = 0;
}

void Display::update(void) {
	frameCount ++;
    uint8_t col, maxcol, p;

    for (p = 0; p < 6; p++) {

        command(PCD8544_SETYADDR | p);

        // start at the beginning of the row
        col = 0;
        maxcol = LCDWIDTH_NOROT - 1;

        command(PCD8544_SETXADDR | col);

        digitalWrite(dc, HIGH);
        if (cs > 0)
            digitalWrite(cs, LOW);
        for (; col <= maxcol; col++) {
            SPI.transfer(_displayBuffer[(LCDWIDTH_NOROT * p) + col]);
        }

        if (cs > 0)
            digitalWrite(cs, HIGH);

    }

    command(PCD8544_SETYADDR); // no idea why this is necessary but it is to finish the last byte?
}

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;
    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);
            }
        }
    }
  */
  uint8_t * buffer = getBuffer();
  const uint8_t col = color;
  const uint8_t bw = (w+7) / 8;
  
  // clip
  if (x >= LCDWIDTH)
    return;
  if (x + w <= 0)
    return;
  if (y >= LCDHEIGHT)
    return;
  if (y + h <= 0)
    return;
  if (y < 0)
    h += y, bitmap -= bw * y, y = 0;
  if (y + h > LCDHEIGHT)
    h = LCDHEIGHT - y;  
  uint8_t x1 = max(0, x);
  uint8_t x2 = min(LCDWIDTH, x + w);
  
#ifdef ENABLE_GRAYSCALE
   uint8_t g = y ^ frameCount;
#endif  

  // draw
  uint8_t first_bitmap_mask = 0x80 >> ((x1 - x) & 7);
  const uint8_t * bitmap_line = bitmap + (x1 - x) / 8;
  uint8_t screen_mask = 0x01 << (y % 8);
  uint8_t * screen_row = buffer + (y / 8) * LCDWIDTH + x1;  
  for (uint8_t dy=0; dy<h; dy++, bitmap_line+=bw)
  {
    const uint8_t * bitmap_ptr = bitmap_line;    
    uint8_t bitmap_mask = first_bitmap_mask;    
    uint8_t pixels = pgm_read_byte(bitmap_ptr);
    uint8_t * dst = screen_row;
    
    if (col == BLACK)
      for (uint8_t sx=x1; sx<x2; sx++, dst++)
      {
        if (pixels & bitmap_mask)
          *dst |= screen_mask;
        bitmap_mask >>= 1;
        if (!bitmap_mask)
        {
          bitmap_mask = 0x80;
          pixels = pgm_read_byte(++bitmap_ptr);
        }
      }
    else if (col == WHITE)
    {
      uint8_t inv_screen_mask = ~screen_mask;
      for (uint8_t sx=x1; sx<x2; sx++, dst++)
      {
        if (pixels & bitmap_mask)
          *dst &= inv_screen_mask;
        bitmap_mask >>= 1;
        if (!bitmap_mask)
        {
          bitmap_mask = 0x80;
          pixels = pgm_read_byte(++bitmap_ptr);
        }
      }
    }
#ifdef ENABLE_GRAYSCALE
    else if (col == GRAY)
    {
      uint8_t inv_screen_mask = ~screen_mask;
      for (uint8_t sx=x1; sx<x2; sx++, dst++)
      {
        if (pixels & bitmap_mask)
        {
         if ((sx^g) & 1)
            *dst |= screen_mask;
          else
           *dst &= inv_screen_mask;
        }
        bitmap_mask >>= 1;
        if (!bitmap_mask)
        {
          bitmap_mask = 0x80;
          pixels = pgm_read_byte(++bitmap_ptr);
        }
      }
       g ^= 1;
    }
#endif
   else // invert
      for (uint8_t sx=x1; sx<x2; sx++, dst++)
      {
        if (pixels & bitmap_mask)
          *dst ^= screen_mask;
        bitmap_mask >>= 1;
        if (!bitmap_mask)
        {
          bitmap_mask = 0x80;
          pixels = pgm_read_byte(++bitmap_ptr);
        }
      }
    
    screen_mask <<= 1;
    if (!screen_mask)
    {
      screen_mask = 1;
      screen_row += LCDWIDTH;
    }
  }
#else
   drawRect(x, y, w, h);
#endif
}

as you can see the bitmap function uses a buffer and framecount to help make grey scale and animations. The update uses the framecount as well but has the collision built into it as well. so I need to move some of that into the updateScreen() we will get to shortly. the problem with the gamebuino version is due to the pcd stuff and I'm not quite sure how to update the parts I need.

Here are the Gamebuino.h stuff
Code:
uint8_t startMenuTimer;
    uint32_t frameCount;
    void setFrameRate(uint8_t fps)

uint8_t getCpuLoad();
    uint16_t getFreeRam();
    uint16_t frameDurationMicros;
    uint32_t frameStartMicros, frameEndMicros;
    
private:
    uint8_t timePerFrame;
    uint32_t nextFrameMillis;

and its .cpp counterparts
Code:
void Gamebuino::begin() {
	timePerFrame = 50;
	//nextFrameMillis = 0;
	//frameCount = 0;
	frameEndMicros = 1;
	startMenuTimer = 255;
	//read default settings from flash memory (set using settings.hex)
	readSettings();
	//init everything
	backlight.begin();
	backlight.set(BACKLIGHT_MAX);
	buttons.begin();
	buttons.update();
	battery.begin();
	display.begin(SCR_CLK, SCR_DIN, SCR_DC, SCR_CS, SCR_RST);
	sound.begin();
	
	//mute when B is held during start up
	if(buttons.pressed(BTN_B)){
		sound.setVolume(0);
	}
	else{ //play the startup sound on each channel for it to be louder
		#if(NUM_CHANNELS > 0)
			sound.playPattern(startupSound, 0);
		#endif
		#if(NUM_CHANNELS > 1)
			sound.playPattern(startupSound, 1);
		#endif
		#if(NUM_CHANNELS > 2)
			sound.playPattern(startupSound, 2);
		#endif
		#if(NUM_CHANNELS > 3)
			sound.playPattern(startupSound, 3);
		#endif
	}
}

boolean Gamebuino::update() {
	if (((nextFrameMillis - millis()) > timePerFrame) && frameEndMicros) { //if time to render a new frame is reached and the frame end has ran once
		nextFrameMillis = millis() + timePerFrame;
		frameCount++;

		frameEndMicros = 0;
		frameStartMicros = micros();

		backlight.update();
		buttons.update();
		battery.update();

		return true;

	} else {
		if (!frameEndMicros) { //runs once at the end of the frame
			sound.updateTrack();
			sound.updatePattern();
			sound.updateNote();
			updatePopup();
			displayBattery();
			
			display.update(); //send the buffer to the screen
			if(!display.persistence)
			display.clear(); //clear the buffer

			frameEndMicros = micros(); //measure the frame's end time
			frameDurationMicros = frameEndMicros - frameStartMicros;

			//            display.setTextColor(BLACK);
			//            display.setCursor(0, 40);
			//            display.print(frameDurationMicros / timePerFrame);
			//            display.print(" ");
			//            display.print(2048 - freeRam());

			//            display.setCursor(0, 32);
			//            display.print("CPU:");
			//            display.print(frameDurationMicros / timePerFrame);
			//            display.println("/1000");
			//            display.print("RAM:");
			//            display.print(2048 - freeRam());
			//            display.println("/2048");
		}
		return false;
	}
}

void Gamebuino::setFrameRate(uint8_t fps) {
	timePerFrame = 1000 / fps;
	sound.prescaler = fps / 20;
	sound.prescaler = max(1, sound.prescaler);
}

uint8_t Gamebuino::getCpuLoad(){
	return(frameDurationMicros/(10*timePerFrame));
}

uint16_t Gamebuino::getFreeRam() {
	//from http://www.controllerprojects.com/2011/05/23/determining-sram-usage-on-arduino/
	extern int __heap_start, *__brkval;
	int v;
	return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

boolean Gamebuino::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 Gamebuino::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 Gamebuino::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(display.getBitmapPixel(b1, x, y) && display.getBitmapPixel(b2, x1+x-x2, y1+y-y2)){
        return true;
      }
    }
  }
  return false;
}

now we can see right away in begin that the frame count stuff needs to be added to my libraries begin. My update all command has all the stuff as the update above but I'm using kurts update screen command but its not working as it should. but now I have all this included in my librariesa like so.....

Code:
// added support to use optional Frame buffer KurtE
	uint8_t     useFrameBuffer(boolean b);		// use the frame buffer?  First call will allocate
	void	    freeFrameBuffer(void);			// explicit call to release the buffer  
	void	    updateScreen(void);			        // call to say update the screen now.    

	uint16_t    frameDurationMicros;                   ////DUHJOKER GAMEBUINO
	uint32_t    frameStartMicros, frameEndMicros;      ////DUHJOKER GAMEBUINO
	uint32_t    frameCount;                            ////DUHJOKER GAMEBUINO

	void        setFrameRate(uint8_t fps);                 ////DUHJOKER GAMEBUINO

	inline void drawPixel(int16_t x, int16_t y, uint16_t color);

	uint8_t startMenuTimer;

    uint8_t* getBuffer();

boolean persistence; //disable clean() at each frame if true //Duhjoker
	
 uint8_t timePerFrame;          ////DUHJOKER GAMEBUINO
	 uint32_t nextFrameMillis;      ////DUHJOKER GAMEBUINO


inline uint8_t* Grafx::getBuffer(){
	return _displayBuffer;
}

and all that in cpp
Code:
//=======================================================================
// Add optinal support for using frame buffer to speed up complex outputs
//=======================================================================
uint8_t Grafx::useFrameBuffer(boolean b)		// use the frame buffer?  First call will allocate
{
#ifdef ENABLE_ILI9341_FRAMEBUFFER
	if (b) {
		// First see if we need to allocate buffer
		if (_pfbtft == NULL) {
			_pfbtft = (uint16_t *)malloc(Grafx_TFTHEIGHT* Grafx_TFTWIDTH * 2);
			if (_pfbtft == NULL)
				return 0;	// failed 
			memset(_pfbtft, 0, Grafx_TFTHEIGHT* Grafx_TFTWIDTH * 2);
		}
		_use_fbtft = 1;
	}
	else
		_use_fbtft = 0;

	return _use_fbtft;
#else
	return 0;
#endif
}

void Grafx::freeFrameBuffer(void)						// explicit call to release the buffer
{
#ifdef ENABLE_ILI9341_FRAMEBUFFER
	if (_pfbtft != NULL) {
		free(_pfbtft);
		_pfbtft = NULL;
		_use_fbtft = 0;	// make sure the use is turned off
	}
#endif
}
void Grafx::updateScreen(void)					// call to say update the screen now.
{
	frameCount ++;
	
	// Not sure if better here to check flag or check existence of buffer.
	// Will go by buffer as maybe can do interesting things?

//	buttons.update();

#ifdef ENABLE_ILI9341_FRAMEBUFFER
	if (_use_fbtft) {
		beginSPITransaction();
		if (_standard) {
			// Doing full window. 
			setAddr(0, 0, _width - 1, _height - 1);
			writecommand_cont(Grafx_RAMWR);

			// BUGBUG doing as one shot.  Not sure if should or not or do like
			// main code and break up into transactions...
			uint16_t *pfbtft_end = &_pfbtft[(Grafx_TFTWIDTH* Grafx_TFTHEIGHT) - 1];	// setup 
			uint16_t *pftbft = _pfbtft;

			// Quick write out the data;
			while (pftbft < pfbtft_end) {
				writedata16_cont(*pftbft++);
			}
			writedata16_last(*pftbft);
		}
		else {
			// setup just to output the clip rectangle area. 
			setAddr(_displayclipx1, _displayclipy1, _displayclipx2 - 1, _displayclipy2 - 1);
			writecommand_cont(Grafx_RAMWR);

			// BUGBUG doing as one shot.  Not sure if should or not or do like
			// main code and break up into transactions...
			uint16_t * pfbPixel_row = &_pfbtft[_displayclipy1*_width + _displayclipx1];
			for (uint16_t y = _displayclipy1; y < _displayclipy2; y++) {
				uint16_t * pfbPixel = pfbPixel_row;
				for (uint16_t x = _displayclipx1; x < (_displayclipx2 - 1); x++) {
					writedata16_cont(*pfbPixel++);
				}
				if (y < (_displayclipy2 - 1))
					writedata16_cont(*pfbPixel);
				else
					writedata16_last(*pfbPixel);
				pfbPixel_row += _width;	// setup for the next row. 
			}
		}
		endSPITransaction();
	}
#endif
}

boolean Grafx::updateAll() {
	if (((nextFrameMillis - millis()) > timePerFrame) && frameEndMicros) { //if time to render a new frame is reached and the frame end has ran once
		nextFrameMillis = millis() + timePerFrame;
		frameCount++;

		frameEndMicros = 0;
		frameStartMicros = micros();

//		backlight.update();
//		sound.updateTrack();
//		sound.updatePattern();
//		sound.updateNote();
//		buttons.update();
//		battery.update();
		return true;

	}
	else {
		if (!frameEndMicros) { //runs once at the end of the frame
//			sound.updateTrack();
//			sound.updatePattern();
//			sound.updateNote();
//			updatePopup();
//			displayBattery();

			update(); //send the buffer to the screen
			if (!persistence)
				freeFrameBuffer(); //clear the buffer

			frameEndMicros = micros(); //measure the frame's end time
			frameDurationMicros = frameEndMicros - frameStartMicros;

			//            display.setTextColor(BLACK);
			//            display.setCursor(0, 40);
			//            display.print(frameDurationMicros / timePerFrame);
			//            display.print(" ");
			//            display.print(2048 - freeRam());

			//            display.setCursor(0, 32);
			//            display.print("CPU:");
			//            display.print(frameDurationMicros / timePerFrame);
			//            display.println("/1000");
			//            display.print("RAM:");
			//            display.print(2048 - freeRam());
			//            display.println("/2048");
		}
		return false;
	}
}

void Grafx::setFrameRate(uint8_t fps) {
	timePerFrame = 1000 / fps;
//	sound.prescaler = fps / 20;
//	sound.prescaler = max(1, sound.prescaler);
}

cpp is too long to post everything but everything can be found any of my libraries on GitHub. I use the same hanfle every where so it should be easy to find


any way I have more than enough stuff but I don't how to use it in a way that solidifies whats being displayed
 
Last edited:
???

Not sure why you started a new thread again???

If you are having problems with flashing? Than break the problem down...
If you get it down to several calls in a row that is causing the flash.

Maybe out some print statements that tell you exactly what things are doing.
Also maybe add in code that waits for input for user input before doing the next part.
Like: while (Serial.read() == -1) ; while (Serial.read() != -1) ;

Then watch your display and step through your output functions...

It may be that you are not using frame buffer and doing three outputs that overwrite the same place and therefore flash.

Or maybe the wrong things are being called... But hopefully between doing some printing of data as well as stepping through
you can figure out what is going wrong...
 
Been away the past couple days. but ive been trying to think of what I might be doing or just how to fix the problem. I tried a couple things today but no luck. But I think I'm looking at it wrong. To be honest I don't think I completely know the buffer functions work for the t3n library. Of course they are noted but I was hoping you might be able to clue me in if possible in lay terms what these functions are actually doing.......

Code:
	uint8_t useFrameBuffer(boolean b);		// use the frame buffer?  First call will allocate
	void	freeFrameBuffer(void);			// explicit call to release the buffer
	void	updateScreen(void);			// call to say update the screen now. 


 protected:
 	SPINClass *_pspin;
#ifdef KINETISK
 	KINETISK_SPI_t *_pkinetisk_spi;
#endif
#ifdef KINETISL
 	KINETISL_SPI_t *_pkinetisl_spi;
#endif

	int16_t _width, _height; // Display w/h as modified by current rotation
	int16_t  cursor_x, cursor_y;

	int16_t  _clipx1, _clipy1, _clipx2, _clipy2;
	int16_t  _originx, _originy;
	int16_t  _displayclipx1, _displayclipy1, _displayclipx2, _displayclipy2;
	bool _invisible = false; 
	bool _standard = true; // no bounding rectangle or origin set. 

	inline void updateDisplayClip() {
		_displayclipx1 = max(0,min(_clipx1+_originx,width()));
		_displayclipx2 = max(0,min(_clipx2+_originx,width()));

		_displayclipy1 = max(0,min(_clipy1+_originy,height()));
		_displayclipy2 = max(0,min(_clipy2+_originy,height()));
		_invisible = (_displayclipx1 == _displayclipx2 || _displayclipy1 == _displayclipy2);
		_standard =  (_displayclipx1 == 0) && (_displayclipx2 == _width) && (_displayclipy1 == 0) && (_displayclipy2 == _height);
		if (Serial) {
			//Serial.printf("UDC (%d %d)-(%d %d) %d %d\n", _displayclipx1, _displayclipy1, _displayclipx2, 
			//	_displayclipy2, _invisible, _standard);

		}
	}

I did have one idea that might work though. My updateAll() function has a timer that's supposed to update the buttons, display and everything else 20x a second. I could add the same timer to my bitmap function that supports the tilemap and my player sprites to update at the same frequency or faster. Just put this right after the { bracket before it goes into the functions normal structure. So when drawbitmap is called the image is able to update itself at a rate not fully visible to the naked eye? Sounds good in theory what do you think?

Edit:: how do I enable the frameBuffer properly in the t3n. #define enable_framebuffer?
 
Last edited:
Ok so I opened up the framebuffer clip tests example in the t3n library to see if I could figure out how to use all this properly. I was able to try this but it has no effect.....

Code:
#include <GrafxT3.h>
#include <SPIN.h>
#include "SPI.h"
#include <Bounce.h>

#define TFT_DC  9
#define TFT_CS 10
#define TFT_RST 7
#define TFT_SCK 13
#define TFT_MISO 12
#define TFT_MOSI 11

uint8_t use_fb = 0;
uint8_t use_clip_rect = 0;
uint8_t use_set_origin = 0;


GrafxT3 tft = GrafxT3(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO, &SPIN);

 int player_x = 100;
 int player_y = 70;
 int player_direction = 2;

 int x=-0,y=0;
 
 int camerax = 160 ;
 int cameray = 120 ;
 int xmax = 160;

//////////////////projectile////////////////////
////////////////////////////////////////////////
////LEFT
const byte projectile_left_blue[] PROGMEM = {16,9,
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x1e,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte projectile_left_red[] PROGMEM = {16,9,
0x00,0x00,0x1c,0x00,0x23,0x00,0x54,0xc8,0x21,0x34,0x54,0xc8,0x23,0x00,0x1c,0x00,0x00,0x00};

const byte projectile_left_yellow[] PROGMEM = {16,9,
0x1c,0x00,0x23,0x00,0x5c,0xc0,0xa3,0x34,0xc0,0xcb,0xa3,0x34,0x5c,0xc0,0x23,0x00,0x1c,0x00};

////RIGHT///////////////////////////////////////////
////////////////////////////////////////////////////
const byte projectile_right_blue[] PROGMEM = {16,9,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x78,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00};

const byte projectile_right_red[] PROGMEM = {16,9,
0x00,0x00,0x00,0x38,0x00,0xc4,0x13,0x2a,0x2c,0x84,0x13,0x2a,0x00,0xc4,0x00,0x38,0x00,0x00};

const byte projectile_right_yellow[] PROGMEM = {16,9,
0x00,0x38,0x00,0xc4,0x03,0x3a,0x2c,0xc5,0xd3,0x03,0x2c,0xc5,0x03,0x3a,0x00,0xc4,0x00,0x38};

////UP///////////////////////////////////////////////
/////////////////////////////////////////////////////
const byte projectile_up_blue[] PROGMEM = {9,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x1c,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte projectile_up_red[] PROGMEM = {9,16,
0x00,0x00,0x14,0x00,0x2a,0x00,0x55,0x00,0x41,0x00,0x55,0x00,0x22,0x00,0x2a,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x00};

const byte projectile_up_yellow[] PROGMEM = {9,16,
0x1c,0x00,0x2a,0x00,0x55,0x00,0xa2,0x80,0xa2,0x80,0xa2,0x80,0x55,0x00,0x55,0x00,0x2a,0x00,0x2a,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x14,0x00,0x08,0x00,0x08,0x00};


////DOWN//////////////////////////////////////////////
//////////////////////////////////////////////////////
const byte projectile_down_blue[] PROGMEM = {9,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x1c,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte projectile_down_red[] PROGMEM = {9,16,
0x00,0x00,0x00,0x00,0x08,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x14,0x00,0x14,0x00,0x2a,0x00,0x22,0x00,0x55,0x00,0x41,0x00,0x55,0x00,0x2a,0x00,0x14,0x00,0x00,0x00};

const byte projectile_down_yellow[] PROGMEM = {9,16,
0x08,0x00,0x08,0x00,0x14,0x00,0x08,0x00,0x14,0x00,0x14,0x00,0x2a,0x00,0x2a,0x00,0x55,0x00,0x55,0x00,0xa2,0x80,0xa2,0x80,0xa2,0x80,0x55,0x00,0x2a,0x00,0x1c,0x00};


////////////////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_rightwLIGHTBROWN[] 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,
B00010001,B00010001,B00000000,B00000000,B10001000,B10001000,B00000000,B00000000,B00010001,B00010001,B00000000,B00000000,B10001000,B10001000,B00000000,B00000000,B00010001,B00010001,B00000000,B00000000,B10001000,B10001000,B00000000,B00000000,B00010001,B00010001,B00000000,B00000000,B10001000,B10001000,B00000000,B00000000};

const byte sand_beige[] PROGMEM = {16,16,
B11101110,B11101110,B11111111,B11111111,B01110111,B01110111,B11111111,B11111111,B11101110,B11101110,B11111111,B11111111,B01110111,B01110111,B11111111,B11111111,B11101110,B11101110,B11111111,B11111111,B01110111,B01110111,B11111111,B11111111,B11101110,B11101110,B11111111,B11111111,B01110111,B01110111,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[] = {blank_tile1,rock_black,};

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

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

///black
const byte tilemap1[] PROGMEM = {32,32,
16,16,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
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,1,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,1,
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,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,};

///brown
const byte tilemap2[] PROGMEM = {32,32,
16,16,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
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,1,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,1,
1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,
1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,
1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,
1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,
1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,1,
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,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,};

///beige
const byte tilemap3[] PROGMEM = {32,32,
16,16,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
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,1,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,1,
1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,
1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,
1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,
1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,
1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,1,
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,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,};


//////dpad + select buttons
const int buttonUp = 33; //up button
Bounce ButtonUp = Bounce(buttonUp, 10);  // 10 ms debounce
const int buttonDown = 38; //down_button
Bounce ButtonDown = Bounce(buttonDown, 10);  // 10 ms debounce
const int buttonLeft = 35; //left button
Bounce ButtonLeft = Bounce(buttonLeft, 10);  // 10 ms debounce
const int buttonRight = 17; //right button
Bounce ButtonRight = Bounce(buttonRight, 10);  // 10 ms debounce
const int buttonS = 21; //select button
Bounce ButtonS = Bounce(buttonS, 10);  // 10 ms debounce

//////action + start buttons
const int buttonX = 32; // X button up
Bounce ButtonX = Bounce(buttonX, 10);  // 10 ms debounce
const int buttonY = 26; // Y button left
Bounce ButtonY = Bounce(buttonY, 10);  // 10 ms debounce
const int buttonA = 21; // A button right
Bounce ButtonA = Bounce(buttonA, 10);  // 10 ms debounce
const int buttonB = 28; // B buttun down
Bounce ButtonB = Bounce(buttonB, 10);  // 10 ms debounce
const int buttonT = 4; // Start button
Bounce ButtonT = Bounce(buttonT, 10);  // 10 ms debounce



void setup() {
  while (!Serial && (millis() < 4000)) ;
  Serial.begin(115200);
  tft.begin();
  tft.setRotation(1);
  tft.setFrameRate(80);
  tft.persistence = false;
 pinMode(buttonUp, INPUT_PULLUP);
   pinMode(buttonDown, INPUT_PULLUP);
   pinMode(buttonLeft, INPUT_PULLUP);
   pinMode(buttonRight, INPUT_PULLUP);
   pinMode(buttonS, INPUT_PULLUP);
   pinMode(buttonX, INPUT_PULLUP);
   pinMode(buttonY, INPUT_PULLUP);
   pinMode(buttonA, INPUT_PULLUP);
   pinMode(buttonB, INPUT_PULLUP);
   pinMode(buttonT, INPUT_PULLUP); 
}

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()){

////////////////////////////////////////////////
/////////////////camera controls////////////////
////////////////////////////////////////////////

        if(player_x > 160 && camerax < 0 && camerax > -160) {player_x = 160;camerax--;}
//value 59 equals player position on right when camera will start to follow 
//value 0 and -52 equals camers boundary positions
      else  if(player_x < 160 && camerax <  0 && camerax  > -160){player_x = 160;camerax++;}
//value 15 equals player position on left when camera will start to follow
//value 0 and -52 equals camera boundary positions 
      else  if(player_x > 160 && camerax <= 0 && camerax >= -160)camerax--;
      else  if(player_x < 160 && camerax <= 0 && camerax >= -160)camerax++;
      if(player_y > 160 && cameray < 0 && cameray >  -160){player_y = 160;cameray--;}
//value 28 equals player position on right when camera will start to folow
//value 0 and -40 equals camera boundary positions 
      else  if(player_y < 120 && cameray < 0 && cameray >  -120){player_y = 120;cameray++;}
//value 15 equals player position on left when camera will start to follow
//value 0 and -40 equals camera boundary positions
     else  if(player_y > 120 && cameray <= 0 && cameray >= -120)cameray--;
     else  if(player_y < 120 && cameray <= 0 && cameray >= -120)cameray++;

           if(camerax > 0)camerax= 0;
     else  if(camerax < -160) camerax = -160;
//value 0 and -52 equals camera boundary positions
           if(cameray > 0)cameray= 0;
     else  if(cameray < -120) cameray = -120;
//value 0 and -40 equals camera boundary positions

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


 tft.useFrameBuffer(use_fb);{
  uint32_t start_time = millis();
  tft.drawTilemap(camerax, cameray, tilemap1, spritesheet1, BLACK);
   tft.drawTilemap(camerax, cameray, tilemap2, spritesheet2, BROWN);
     tft.drawTilemap(camerax, cameray, tilemap3, spritesheet3, LIGHTBROWN);
     tft.updateScreen();
     }
     
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
  
   if (ButtonUp.update());
    if (ButtonDown.update());
     if (ButtonLeft.update());
      if (ButtonRight.update());

      ButtonUp.rebounce(10);
     ButtonDown.rebounce(10);
    ButtonLeft.rebounce(10);
   ButtonRight.rebounce(10);

///////////////////////////////////////////////////////////////////////////////   
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
    if (ButtonUp.fallingEdge()){
  tft.useFrameBuffer(use_fb);{
     uint32_t start_time = millis();
      tft.drawBitmap(player_x, player_y,paul_rearblack,16,16,BLACK);
        tft.drawBitmap(player_x, player_y,paul_rearblue,16,16,BLUE);
         tft.drawBitmap(player_x, player_y,paul_rearbrown,16,16,BROWN);
          tft.drawBitmap(player_x, player_y,paul_reargrey,16,16,GREY);
           tft.drawBitmap(player_x, player_y,paul_rearpink,16,16,LIGHTBROWN);
            tft.drawBitmap(player_x, player_y,paul_rearred,16,16,RED);
            tft.updateScreen();
  }

    tft.useFrameBuffer(use_fb);{
     uint32_t start_time = millis();
        tft.drawBitmap(player_x, player_y,paul_rearw1black,16,16,BLACK);
         tft.drawBitmap(player_x, player_y,paul_rearw1blue,16,16,BLUE);
          tft.drawBitmap(player_x, player_y,paul_rearw1brown,16,16,BROWN);
           tft.drawBitmap(player_x, player_y,paul_rearw1grey,16,16,GREY);
            tft.drawBitmap(player_x, player_y,paul_rearw1pink,16,16,LIGHTBROWN);
             tft.drawBitmap(player_x, player_y,paul_rearw1red,16,16,RED);
 tft.updateScreen();
  }
                player_direction = 1;
             player_y = player_y - 5;}
//             if(checkcolision())player_y--;} 
           if(player_y <= 0){
              player_y = 0;}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
       if (ButtonDown.fallingEdge()){
     tft.useFrameBuffer(use_fb);{
     uint32_t start_time = millis();
      tft.drawBitmap(player_x, player_y,paul_frontblack,16,16,BLACK);
       tft.drawBitmap(player_x, player_y,paul_frontblue,16,16,BLUE);
        tft.drawBitmap(player_x, player_y,paul_frontbrown,16,16,BROWN);
         tft.drawBitmap(player_x, player_y,paul_frontgrey,16,16,GREY);
          tft.drawBitmap(player_x, player_y,paul_frontgreen,16,16,GREEN);
           tft.drawBitmap(player_x, player_y,paul_frontpink,16,16,LIGHTBROWN);
            tft.drawBitmap(player_x, player_y,paul_frontred,16,16,RED);
             tft.updateScreen();
     }

       tft.useFrameBuffer(use_fb);{
     uint32_t start_time = millis(); 
       tft.drawBitmap(player_x, player_y,paul_frontw1black,16,16,BLACK);
        tft.drawBitmap(player_x, player_y,paul_frontw1blue,16,16,BLUE);
         tft.drawBitmap(player_x, player_y,paul_frontw1brown,16,16,BROWN);
          tft.drawBitmap(player_x, player_y,paul_frontw1grey,16,16,GREY);
           tft.drawBitmap(player_x, player_y,paul_frontw1green,16,16,GREEN);
            tft.drawBitmap(player_x, player_y,paul_frontw1pink,16,16,LIGHTBROWN);
             tft.drawBitmap(player_x, player_y,paul_frontw1red,16,16,RED);
              tft.updateScreen();
                }
               player_direction = 2;
            player_y = player_y + 5;}
//            if(checkcolision())player_y++;}
            if(player_y >= 224){
              player_y = 224;}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
      if (ButtonLeft.fallingEdge()){
         tft.useFrameBuffer(use_fb);{
     uint32_t start_time = millis();
     tft.drawBitmap(player_x, player_y,paul_leftblack,16,16,BLACK);
       tft.drawBitmap(player_x, player_y,paul_leftblue,16,16,BLUE);
        tft.drawBitmap(player_x, player_y,paul_leftbrown,16,16,BROWN);
         tft.drawBitmap(player_x, player_y,paul_leftgreen,16,16,GREEN);
          tft.drawBitmap(player_x, player_y,paul_leftgrey,16,16,GREY);
           tft.drawBitmap(player_x, player_y,paul_leftpink,16,16,LIGHTBROWN);
            tft.drawBitmap(player_x, player_y,paul_leftred,16,16,RED);
             tft.updateScreen();
             }

        tft.useFrameBuffer(use_fb);{
     uint32_t start_time = millis(); 
       tft.drawBitmap(player_x, player_y,paul_leftwblack,16,16,BLACK);
        tft.drawBitmap(player_x, player_y,paul_leftwblue,16,16,BLUE);
         tft.drawBitmap(player_x, player_y,paul_leftwbrown,16,16,BROWN);
          tft.drawBitmap(player_x, player_y,paul_leftwgreen,16,16,GREEN);
           tft.drawBitmap(player_x, player_y,paul_leftwgrey,16,16,GREY);
            tft.drawBitmap(player_x, player_y,paul_leftwpink,16,16,LIGHTBROWN);
             tft.drawBitmap(player_x, player_y,paul_leftwred,16,16,RED);
              tft.updateScreen();
     }
                player_direction = 3;
             player_x = player_x - 5;}
//             if(checkcolision())player_x--;}  
            if(player_x >= 304){
              player_x = 304;}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
       if (ButtonRight.fallingEdge()){
     tft.useFrameBuffer(use_fb);{
     uint32_t start_time = millis();
       tft.drawBitmap(player_x, player_y,paul_rightblack,16,16,BLACK);
        tft.drawBitmap(player_x, player_y,paul_rightblue,16,16,BLUE);
         tft.drawBitmap(player_x, player_y,paul_rightbrown,16,16,BROWN);
          tft.drawBitmap(player_x, player_y,paul_rightgrey,16,16,GREY);
           tft.drawBitmap(player_x, player_y,paul_rightpink,16,16,LIGHTBROWN);
            tft.drawBitmap(player_x, player_y,paul_rightred,16,16,RED);
             tft.updateScreen();
     }

    tft.useFrameBuffer(use_fb);{
     uint32_t start_time = millis(); 
       tft.drawBitmap(player_x, player_y,paul_rightblack,16,16,BLACK);
        tft.drawBitmap(player_x, player_y,paul_rightblue,16,16,BLUE);
         tft.drawBitmap(player_x, player_y,paul_rightbrown,16,16,BROWN);
          tft.drawBitmap(player_x, player_y,paul_rightgrey,16,16,GREY);
           tft.drawBitmap(player_x, player_y,paul_rightpink,16,16,LIGHTBROWN);
            tft.drawBitmap(player_x, player_y,paul_rightred,16,16,RED);
             tft.updateScreen();
       }
               player_direction = 4;
            player_x = player_x + 5;}
//           if(checkcolision())player_x++;}
            if(player_x <= -2){
              player_x = -2;}
///////////////////////////////////////////////////////////////////////////////     
//////////////////////////////PLAYER DIRECTION/////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
     if (player_direction == 1){
 tft.useFrameBuffer(use_fb);{
     uint32_t start_time = millis();
      tft.drawBitmap(player_x, player_y,paul_rearblack,16,16,BLACK);
       tft.drawBitmap(player_x, player_y,paul_rearblue,16,16,BLUE);
        tft.drawBitmap(player_x, player_y,paul_rearbrown,16,16,BROWN);
         tft.drawBitmap(player_x, player_y,paul_reargrey,16,16,GREY);
          tft.drawBitmap(player_x, player_y,paul_rearpink,16,16,LIGHTBROWN);
           tft.drawBitmap(player_x, player_y,paul_rearred,16,16,RED);
           tft.updateScreen();
        }
     }
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
      else if (player_direction == 2){
      tft.useFrameBuffer(use_fb);{
     uint32_t start_time = millis();
      tft.drawBitmap(player_x, player_y,paul_frontblack,16,16,BLACK);
       tft.drawBitmap(player_x, player_y,paul_frontblue,16,16,BLUE);
        tft.drawBitmap(player_x, player_y,paul_frontbrown,16,16,BROWN);
         tft.drawBitmap(player_x, player_y,paul_frontgrey,16,16,GREY);
          tft.drawBitmap(player_x, player_y,paul_frontgreen,16,16,GREEN);
           tft.drawBitmap(player_x, player_y,paul_frontpink,16,16,LIGHTBROWN);
            tft.drawBitmap(player_x, player_y,paul_frontred,16,16,RED);
            tft.updateScreen();
        }
      }
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
       else if (player_direction == 3){
        tft.useFrameBuffer(use_fb);{
     uint32_t start_time = millis();
        tft.drawBitmap(player_x, player_y,paul_leftblack,16,16,BLACK);
         tft.drawBitmap(player_x, player_y,paul_leftblue,16,16,BLUE);
          tft.drawBitmap(player_x, player_y,paul_leftbrown,16,16,BROWN);
           tft.drawBitmap(player_x, player_y,paul_leftgreen,16,16,GREEN);
            tft.drawBitmap(player_x, player_y,paul_leftgrey,16,16,GREY);
             tft.drawBitmap(player_x, player_y,paul_leftpink,16,16,LIGHTBROWN);
              tft.drawBitmap(player_x, player_y,paul_leftred,16,16,RED);
              tft.updateScreen();
        }
       }
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
         else if (player_direction == 4){
  tft.useFrameBuffer(use_fb);{
     uint32_t start_time = millis();
         tft.drawBitmap(player_x, player_y,paul_rightblack,16,16,BLACK);
          tft.drawBitmap(player_x, player_y,paul_rightblue,16,16,BLUE);
           tft.drawBitmap(player_x, player_y,paul_rightbrown,16,16,BROWN);
            tft.drawBitmap(player_x, player_y,paul_rightgrey,16,16,GREY);
             tft.drawBitmap(player_x, player_y,paul_rightpink,16,16,LIGHTBROWN);
              tft.drawBitmap(player_x, player_y,paul_rightred,16,16,RED);
                 }
          }
   }
}
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////collision/////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
   bool checkcolision() // Transformed it into a function 

    {
    uint16_t i;  
     for(i=0; i < tft.numcolision + 1; i++)

   {
    if(tft.collideRectRect(player_x, player_y,16,16,tft.solid[i].x,tft.solid[i].y,16,16))

   {
    
     if(tft.solid[i].spritecol == blank_tile1); //Do nothing because it's floor - this line not needed
     if(tft.solid[i].spritecol == blank_tile2);
     if(tft.solid[i].spritecol == blank_tile3);
else if(tft.solid[i].spritecol == rock_black)return true;
else if(tft.solid[i].spritecol == rock_brown)return true;
else if(tft.solid[i].spritecol == rock_beige)return true;
   }

   }
return false; // Return false if don't touch anything

  }


do I need to use clips? how exactly

https://github.com/Duhjoker/GameRIot_T3
 
Did the sample work right? You are stacking multiple bitmaps - so yes you should use the framebuffer AFAIK from what I read of Kurt's work. That will keep the SPI bus work and wait down and speed things up as well as prevent failures.

Edit the sample perhaps to work with your personal bitmaps in place of the sample bitmaps to see it work right.

Still odd to see PROGMEM - I think it falls out - but it has no value on Teensy and can only get in the way.
 
Progmem is the only way I know, but I'm willing to learn how to do it right.

When I google storing bitmaps Teensy 3 all I get is sd card storage
 
Last edited:
Just drop the PROGMEM. As const they will be put into FLASH. On Teensy ARM RAM and FLASH are one continuous addressable space - not intermingled of course - but fully accessible one the same as the other as far as the pointers to them know. Different places - but all addressed the same. On AVR FLASH is 'elsewhere' segmented from RAM and PROGMEM puts it there and allows it to be brought to RAM as needed.
 
For the most part there is no magic about how the frame buffer and clipping code works. Unless maybe you started to use the DMA support I have in it...

That is when you turn on frame buffer, all of the graphic primitives were updated to write the new data into memory instead of using SPI to write the data to the display.

Only when you tell it to updateScreen will it take whatever is in the off screen memory and write that data to the screen.

Now the library also has the concept of a clipping rectangle and offset, which allows you to tell the system, to only allow pixels in some range to output, otherwise the changes will be ignored.

I used the frame buffer clip test that is part of my library, to test out and fix the different graphic primitives to make sure that I handled properly converting the different functions to use the frame buffer as well as clip rectangles. There are lots of interesting conditions to test. Example draw a bitmap which is clipped. You not only need to know that certain pixels are not drawn, you also need to know which bits/bytes/words in the bitmap data to ignore as to align the data to the pixels drawn...

The test program is setup, that if you hit a <cr> in the terminal window, it will alternate redrawing the screen using frame buffer or not using frame buffer, with different background color... So you can see if the graphic primitive is working in both modes... There are other things in this test program as well. Easiest to look through the code to figure it out, but does things like:
t<cr> - will draw a text screen (using fonts) - It again will test with or without frame buffer... It will also test without opaque text.
o<cr> - like T but with opaque text, to test my added support for this.
d<cr> - toggle using DMA ...
c<cr> - Sets some clipping rectangle...
s<cr> - sets on origin to test if that works...

Things that can go wrong?

a) If you add in any code that directly writes to SPI device... Example some new draw bitmap function from some other library. You need to go through and make sure it is checking if it is in frame buffer mode and do the right thing... likewise handle the clipping rectangle. You can find this by either visual inspection of your code and/or adding the idea of stepping through your output code, like I mentioned in previous post.

b) You are calling updateScreen too often or at the wrong time - That is if you do something like:
Update buttons and tiles, updateScreen, update user sprite, updatescreen



It will do exactly what you said and draw the screen twice, probably first time without your sprite on the screen and then the 2nd time with sprite there... So you will see a flash.
You instead need to do something like:
update buttons and tiles, update user sprite, updatescreen

Then it is all done in one update. You can draw over parts screen once or 50 times using the frame buffer and again the changes only when you tell it to update will the combination of all of the updates will show up on the screen.

c) You just plain do something in the wrong order or... Example if your code does something like:
<clear the screen>, <draw tiles and like>, <clear where old user sprite was>, <draw user sprite>, <updateScreen>
Your clear of old position, could wipe out what some of your previous graphic outputs did...

DMA - My current library has support for using DMA to update the screen (with frame buffer), like Franks. This adds some capabilities and some pitfalls. To use this in current code, I believe the call is something like tft.startUpdateScreenDMA instead of tft.updateScreen. This tells the system to transfer the current state of the frame buffer to the display using DMA and it returns as soon as the update starts. This is great for allowing your code to do other things like check buttons, or usb input... While the display gets updated. Note: there is an option on that call to turn on continuous update (until you turn it off).

Additional Pitfalls with DMA update
a) If you call any graphic primitives while the update is happening, Some of the update may happen, some of it may not... Example if you do something like a
fillScreen(RED) right after that call. Some of your screen state before this call will show up as before and then some of the screen will simply be RED. Sort of a race condition on when the fill code in memory catches up with the DMA output code...

b) continuous mode - Like a) but worse. When in this mode when the DMA finishes outputting the whole screen of data, it simply starts over and redraws the screen with whatever is there now... There is now synchronization of data or the like. Works fine if maybe doing something like video frames. Worst case is part of the screen will have frame X on it and part of it will have frame X+1 on it...

---------------------------------------

So Again not sure what you are expecting here? Example in #5, you say... Nothing happens... What is it you expect to happen?

What did you do to debug it? For example if your bitmaps are not working properly, have you done a simple test program, that simply displays each one, maybe waiting for character input in between? If they are smaller images, maybe multiple ones on the display... Did they display properly? If not are you using the right graphic primitives for them, example there are different ones in my library depending on are you passing 16 bits per pixel or are you passing less 8, 4, 2, 1 bits per pixel using a color palette. Are you calling the right one for the right number of bits? Is the palette set up properly?

If the images work properly, but your display does not, have you added debug outputs, to figure out what state you are in, what primitives are being called... Is it doing what you think it should be doing?

If things are drawing OK, but you have flashing or the like, then again debug it, either using some simply debug prints, like put a Serial.println("US n");
everywhere you call tft.updateScreen with some different value for N, such that you can see which one... Then maybe simple prints in your update code, like start update, end update...

Or again if it were me, I would use unused IO pins, and do something like toggle an IO pin each time updateScreen is called, and for each major ouput to the screen code portion have different IO pin, where I set it high at start of output and low at end... Then hook up logic analyzer and see if things are happening in the expected order...

And again I would check for things like the c) above where you erase data from one type of output when you are doing another...

Again like above you can easily check this, by setting a logical break point after each place in your code that calls updateScreen. Simply add code like: while (Serial.read() == -1) ; while (Serial.read() != -1) ;
Right after that call, with maybe again a printf with which of your updateScreens is called. Then watch to see if one output is wiping out part of the output of the previous screen... Which would cause flashing!

So hopefully there are enough clues here on how YOU can debug your program.

Good luck!
 
Last edited:
Sorry. Yes it's the flashing I am trying to stop and also the tron trails. The bitmaps display fine, I just need every thing to be solid. I can build games with out floor tiles but the trails make that a problem. I've been contemplating doing some thing like TOG the legend of Zelda. Ok back to the bitmaps...... You said all I needed to do was drop the Progmem. Do I need to use int or uint instead of byte? I assume 16 since my bitmaps are 16x16.

I thought I had the fillscreen fixed so it was turned the right way but no go there. If I do a fill screen black it still cuts off the right side.

Still going through every thing of course. I started out using my own bitmap functions because I was using a different library but I dumped the all in one and I'm using your T3n library instead. But now every thing I'm calling is what you added to the library so I'm using your functions to display out put.

i don't know to much debug code I just use what I can gleam from you guys.
 
i don't know to much debug code I just use what I can gleam from you guys.
Good time to learn ;)

As I am busy with other stuff and need to spend time developing and debugging my own projects...

a) Again with fillScreen (with or without using frame buffer?). Check to make sure that the screen orientation stuff is correct. That is you might try a simple app that works with your library and my library and do something like:
Code:
for (auto i=0; i < 4) {
    tft.setRotation(i);
    Serial.printf("%d - W(%d) H(%d)\n", i, tft.width(), tft.height());
}
Are the W and H values the same for both libraries? If not things will be screwed up. That is because this command configures the board to know what direction it is and how memory is accessed... i.e. look at the data it sets in the write_data8... If these are the same for both libraries, then look at the fillRect/fillScreen and see what might be different...

b) flash: Again I gave several hints on debugging, again try adding debug prints in your code at all of the places that call updateScreen. And then do a loop to wait for character input. This way you can set on Serial Monitor window or Tyqt windown and step through the updates....
If you see something like a screen that shows all of your tiles and then you tell it to step and then you see a screen which shows character sprite or tail and none of the background data, and then next one shows background data... you know you need to reorganize how you code works to update the screen...
 
im in the process of trying to build a new library. Had a couple ideas but I wanted to make sure that when using the frame buffer that it only uses the functions needed BY the framebuffer. im trying to do something like this but when I go to define enable framebuffer it gives me doubles errors so I know its not right.........

Code:
#ifdef ENABLE_ILI9341_FRAMEBUFFER
    void        setRotation(uint8_t r);
    uint8_t     getRotation(void);
    void        invertDisplay(boolean i);
    void        setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
    void        drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size);
#endif    
    void        setRotation(uint8_t r);
    uint8_t 	getRotation(void);
	void 		setBackground(uint16_t color);
	void 		setForeground(uint16_t color);
	uint16_t 	getBackground(void);
	uint16_t 	getForeground(void);

maybe #else instead?


Edit:::::

Never mind I got it. I put the enabled functions after the ifdefine then else with the other functions and then endif. I'm learning

Edit:::: ok so now I have it set up now where I can switch between a new incarnation of library that works with every thing but esp32. Then I added kurts T3N library in its entirety to the new library. Took a lil time to debug to the point of flashing and displaying on the system but it works. Now I can toggle both libraries to Check the functions and correct them at one time with out having to switch libraries in and out because of the keywords I use. And I learned another piece of programming so win win

Now I have to tweak every thing so it works properly.
 
Last edited:
Not sure what you are doing - if the prototypes don't change (as above) - there is no need for any #ifdef.

However if they are to change - then they need to be EITHER under an #IF or an #ELSE - or the compiler will make a point of that as you see.

What's with continual NEW or combined or whatever libs?

Perhaps get it working with independent pieces of code that are known to work as they were and then make explicit changes as needed - and tag each one // JOKER_HERE so they can be found. Using a base library that is known and unchanged would allow the author to help. It is on your machine and need not be made unique first thing - just functional. Once you have it working with needed changes it can be reduced or refactored and should it stop working you'd have something to go back to.

Except for FRAMEBUFFER and perhaps DMA - or multiple SPI buses there isn't anything to be done faster than in the default _t3 lib - it provides the needed primitives the controller is capable of. Moving to Kurt's code for specific improvements says start with that which is already tested ( at least by Kurt ) to be fully compatible and functional with all prior performance to run on Teensy. If you find a bug or place for improvement and Kurt's code is intact he may quickly see what and why something was broken or how to extend it. If you 'make it unique' as the first step then 'you break it you bought it'.

Also spending time with tested and working code will allow you to see and understand proper use of #IFdef and other logic as expressed by 'a master' so roadblocks like this won't distract from the task at hand.
 
New laptop crashed and I had to send it back. So now I'm back at the beast with no USB for a few days. Decided I would make a new All in one with dedicated T3 buffer bits. Needed to learn how to do else if defines and stuff so I thought I would play with a library that could toggle functions as needed. Yea Kurts functions were a lil different than the ones in my library and I wanted to make sure when I made a program test or what ever that it uses what I want it to use. It works now


I do have a question related to the thread though. I'm using a homegrown way to scroll my character through the tilemaps but it's slow as all hell. I would like to try to scroll and cursor instead of my camera routine which can be seen in the demo in post 5. Maybe I can get a faster scroll rate on the bigger maps. Would any one happen to know of a good example on how to do such?
 
All right guys back to the real work at hand for me. I have a way to flash my teensy again but its a pain. Any way......

I was thinking that using my updateAll() command would be better than calling update this and that any way. Especially since it runs 20x a second. The right order to use them nin is the trick so lets look at the original updateAll() function here.....

Code:
boolean Gamebuino::update() {
	if (((nextFrameMillis - millis()) > timePerFrame) && frameEndMicros) { //if time to render a new frame is reached and the frame end has ran once
		nextFrameMillis = millis() + timePerFrame;
		frameCount++;

		frameEndMicros = 0;
		frameStartMicros = micros();

		backlight.update();
		buttons.update();
		battery.update();

		return true;

	} else {
		if (!frameEndMicros) { //runs once at the end of the frame
			sound.updateTrack();
			sound.updatePattern();
			sound.updateNote();
			updatePopup();
			displayBattery();
			
			display.update(); //send the buffer to the screen
			if(!display.persistence)
			display.clear(); //clear the buffer

			frameEndMicros = micros(); //measure the frame's end time
			frameDurationMicros = frameEndMicros - frameStartMicros;

		}
		return false;
	}
}

ok so first it takes care of the frame count stuff. Next it updates the back light vuttons and battery. else if end frame, then updates popup bubble, battery level and sound. Now it updates the the screen by calling update which sends the buffer to the screen then clearing the buffer then ending the frame.

But kurts doesn't work that way. it needs to call update last. So heres what I came with.........

Code:
boolean GrafxT3::updateAll() {
	if (((nextFrameMillis - millis()) > timePerFrame) && frameEndMicros) { //if time to render a new frame is reached and the frame end has ran once
		nextFrameMillis = millis() + timePerFrame;
		frameCount++;

		frameEndMicros = 0;
		frameStartMicros = micros();
        return true;

	}
	else {
		if (!frameEndMicros) { //runs once at the end of the frame
//			
           useFrameBuffer();
			if (!persistence)
				updateScreen();
				freeFrameBuffer(); //clear the buffer

			frameEndMicros = micros(); //measure the frame's end time
			frameDurationMicros = frameEndMicros - frameStartMicros;

		}
		return false;
	}
}

Im not using buttons in this way and sound is not needed right now. All I need is to update the screen consistently constant to kill the trails and flashing. Seems you would call clear buffer after updating the screen to me. But I also need something to seperate groups of bit maps to create player walking effects

Edit::::::
Ok it wants something in the parameters for useFrameBuffer(); since I'm using the command in library and not a sketch I don't know what to do. I tried use_fb but that didn't work either.

Edit::: I tried 1 in the useFrameBuffer () but it just makes it flash worse or slower.
 
Last edited:
useFrameBuffer - In my library was a call to say I want to use it (non-zero) or I don't want to use it (0)

As for debugging your code? My previous N posts should have enough hints on how you can debug! Example have you put in, what I called a Logical Break point, in your code at each spot that does an updateScreen? Preferably with some form of print just before it to tell you which one it is... You could also temporarily do it within updateScreen code. Then walk your way through and see how things update... If it looks like something is updating between calls, you could put a logical print someplace probably in your library code that outputs to the SPI, maybe like where it does the output for bounding rectangle for the screen writes and see if that is called in-between....
 
Well i thought i read that i was calling the update screen too many times in the sketch so i removed all that for a trade to have updateAll() handle the updating. Its running constantly any way. It did give me an effect just not what i wanted.

Because i dont have an actual buttons class in my library any more and since im using bounce, the buttons update at the top of the void loop as well as get thier rebounce command. That works just fine the way it is. I dont understand how i update tiles then screen. Then update sprite and uodate screen. How would i add simething like that to my updateAll() function.
 
ok so if I use my update function like so with no tilemap, the trails when the character moves stop.

Code:
boolean GrafxT3::updateAll() {
	if (((nextFrameMillis - millis()) > timePerFrame) && frameEndMicros) { //if time to render a new frame is reached and the frame end has ran once
		nextFrameMillis = millis() + timePerFrame;
		frameCount++;

		frameEndMicros = 0;
		frameStartMicros = micros();
        return true;

	}
	else {
		if (!frameEndMicros) { //runs once at the end of the frame
//			
         useFrameBuffer(1);
			if (!persistence)
				  updateScreen();
				freeFrameBuffer(); //clear the buffer
 //                updateScreen();

			frameEndMicros = micros(); //measure the frame's end time
			frameDurationMicros = frameEndMicros - frameStartMicros;

		}
		return false;
	}
}

But the player sprite remains a lil dim and a lil flashy but looks more solid. If I add the tilemap back to my sketch and run the demo again, its horrible with the screen flashing black and then printing then going black and printing and so on
 
Ok I cant figure out what the problem is. Here is my new sketch.......

Code:
#include <GrafxT3.h>
#include <SPIN.h>
#include "SPI.h"
#include <Bounce.h>

#define TFT_DC  9
#define TFT_CS 10
#define TFT_RST 7
#define TFT_SCK 13
#define TFT_MISO 12
#define TFT_MOSI 11

uint8_t use_fb = 0;
uint8_t use_clip_rect = 0;
uint8_t use_set_origin = 0;


GrafxT3 tft = GrafxT3(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO, &SPIN);

 int player_x = 100;
 int player_y = 70;
 int player_direction = 2;

 int x=-0,y=0;
 
 int camerax = 216 ;
 int cameray = 90 ;
 int xmax = 216;

//////////////////projectile////////////////////
////////////////////////////////////////////////
////LEFT
const byte projectile_left_blue[] = {16,9,
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x1e,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte projectile_left_red[] = {16,9,
0x00,0x00,0x1c,0x00,0x23,0x00,0x54,0xc8,0x21,0x34,0x54,0xc8,0x23,0x00,0x1c,0x00,0x00,0x00};

const byte projectile_left_yellow[] = {16,9,
0x1c,0x00,0x23,0x00,0x5c,0xc0,0xa3,0x34,0xc0,0xcb,0xa3,0x34,0x5c,0xc0,0x23,0x00,0x1c,0x00};

////RIGHT///////////////////////////////////////////
////////////////////////////////////////////////////
const byte projectile_right_blue[] = {16,9,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x78,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00};

const byte projectile_right_red[] = {16,9,
0x00,0x00,0x00,0x38,0x00,0xc4,0x13,0x2a,0x2c,0x84,0x13,0x2a,0x00,0xc4,0x00,0x38,0x00,0x00};

const byte projectile_right_yellow[] = {16,9,
0x00,0x38,0x00,0xc4,0x03,0x3a,0x2c,0xc5,0xd3,0x03,0x2c,0xc5,0x03,0x3a,0x00,0xc4,0x00,0x38};

////UP///////////////////////////////////////////////
/////////////////////////////////////////////////////
const byte projectile_up_blue[] = {9,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x1c,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte projectile_up_red[] = {9,16,
0x00,0x00,0x14,0x00,0x2a,0x00,0x55,0x00,0x41,0x00,0x55,0x00,0x22,0x00,0x2a,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x00};

const byte projectile_up_yellow[] = {9,16,
0x1c,0x00,0x2a,0x00,0x55,0x00,0xa2,0x80,0xa2,0x80,0xa2,0x80,0x55,0x00,0x55,0x00,0x2a,0x00,0x2a,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x14,0x00,0x08,0x00,0x08,0x00};


////DOWN//////////////////////////////////////////////
//////////////////////////////////////////////////////
const byte projectile_down_blue[]  = {9,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x1c,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte projectile_down_red[] = {9,16,
0x00,0x00,0x00,0x00,0x08,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x14,0x00,0x14,0x00,0x2a,0x00,0x22,0x00,0x55,0x00,0x41,0x00,0x55,0x00,0x2a,0x00,0x14,0x00,0x00,0x00};

const byte projectile_down_yellow[] = {9,16,
0x08,0x00,0x08,0x00,0x14,0x00,0x08,0x00,0x14,0x00,0x14,0x00,0x2a,0x00,0x2a,0x00,0x55,0x00,0x55,0x00,0xa2,0x80,0xa2,0x80,0xa2,0x80,0x55,0x00,0x2a,0x00,0x1c,0x00};


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

const byte paul_frontblack[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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[] = {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_rightwLIGHTBROWN[] = {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[] = {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[] = {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[] = {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[] = {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[] = {16,16,
B00010001,B00010001,B00000000,B00000000,B10001000,B10001000,B00000000,B00000000,B00010001,B00010001,B00000000,B00000000,B10001000,B10001000,B00000000,B00000000,B00010001,B00010001,B00000000,B00000000,B10001000,B10001000,B00000000,B00000000,B00010001,B00010001,B00000000,B00000000,B10001000,B10001000,B00000000,B00000000};

const byte sand_beige[] = {16,16,
B11101110,B11101110,B11111111,B11111111,B01110111,B01110111,B11111111,B11111111,B11101110,B11101110,B11111111,B11111111,B01110111,B01110111,B11111111,B11111111,B11101110,B11101110,B11111111,B11111111,B01110111,B01110111,B11111111,B11111111,B11101110,B11101110,B11111111,B11111111,B01110111,B01110111,B11111111,B11111111};

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

const byte blank_tile1[] = {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[] = {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[] = {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[] = {blank_tile1,rock_black,};

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

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

///black
const byte tilemap1[] = {32,32,
16,16,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
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,1,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,1,
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,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,};

///brown
const byte tilemap2[] = {32,32,
16,16,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
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,1,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,1,
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,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,};

///beige
const byte tilemap3[] = {32,32,
16,16,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
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,1,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,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,1,1,1,
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,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,};

//////dpad + select buttons
const int buttonUp = 33; //up button
Bounce ButtonUp = Bounce(buttonUp, 10);  // 10 ms debounce
const int buttonDown = 38; //down_button
Bounce ButtonDown = Bounce(buttonDown, 10);  // 10 ms debounce
const int buttonLeft = 35; //left button
Bounce ButtonLeft = Bounce(buttonLeft, 10);  // 10 ms debounce
const int buttonRight = 17; //right button
Bounce ButtonRight = Bounce(buttonRight, 10);  // 10 ms debounce
const int buttonS = 21; //select button
Bounce ButtonS = Bounce(buttonS, 10);  // 10 ms debounce

//////action + start buttons
const int buttonX = 32; // X button up
Bounce ButtonX = Bounce(buttonX, 10);  // 10 ms debounce
const int buttonY = 26; // Y button left
Bounce ButtonY = Bounce(buttonY, 10);  // 10 ms debounce
const int buttonA = 21; // A button right
Bounce ButtonA = Bounce(buttonA, 10);  // 10 ms debounce
const int buttonB = 28; // B buttun down
Bounce ButtonB = Bounce(buttonB, 10);  // 10 ms debounce
const int buttonT = 4; // Start button
Bounce ButtonT = Bounce(buttonT, 10);  // 10 ms debounce



void setup() {
  while (!Serial && (millis() < 4000)) ;
  Serial.begin(115200);
  tft.begin();
  tft.setRotation(1);
  //tft.setFrameRate(60);
  tft.persistence = false;
   pinMode(buttonUp, INPUT_PULLUP);
   pinMode(buttonDown, INPUT_PULLUP);
   pinMode(buttonLeft, INPUT_PULLUP);
   pinMode(buttonRight, INPUT_PULLUP);
   pinMode(buttonS, INPUT_PULLUP);
   pinMode(buttonX, INPUT_PULLUP);
   pinMode(buttonY, INPUT_PULLUP);
   pinMode(buttonA, INPUT_PULLUP);
   pinMode(buttonB, INPUT_PULLUP);
   pinMode(buttonT, INPUT_PULLUP); 

   //tft.drawTilemap(x, y, tilemap1, spritesheet1, BLACK);
   // tft.drawTilemap(x, y, tilemap2, spritesheet2, BROWN);
   //  tft.drawTilemap(x, y, tilemap3, 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()){

////////////////////////////////////////////////
/////////////////camera controls////////////////
////////////////////////////////////////////////

//        if(player_x > 216 && camerax < 0 && camerax > -216) {player_x = 216;camerax--;}
//value 59 equals player position on right when camera will start to follow 
//value 0 and -52 equals camers boundary positions
//      else  if(player_x < 216 && camerax <  0 && camerax  > -216){player_x = 216;camerax++;}
//value 15 equals player position on left when camera will start to follow
//value 0 and -52 equals camera boundary positions 
//      else  if(player_x > 216 && camerax <= 0 && camerax >= -216)camerax--;
//      else  if(player_x < 216 && camerax <= 0 && camerax >= -216)camerax++;
//      if(player_y > 216 && cameray < 0 && cameray >  -216){player_y = 216;cameray--;}
//value 28 equals player position on right when camera will start to folow
//value 0 and -40 equals camera boundary positions 
//      else  if(player_y < 90 && cameray < 0 && cameray >  -90){player_y = 90;cameray++;}
//value 15 equals player position on left when camera will start to follow
//value 0 and -40 equals camera boundary positions
//     else  if(player_y > 90 && cameray <= 0 && cameray >= -90)cameray--;
//     else  if(player_y < 90 && cameray <= 0 && cameray >= -90)cameray++;

//           if(camerax > 0)camerax= 0;
//     else  if(camerax < -216) camerax = -216;
//value 0 and -52 equals camera boundary positions
//           if(cameray > 0)cameray= 0;
//     else  if(cameray < -90) cameray = -90;
//value 0 and -40 equals camera boundary positions

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

  tft.drawTilemap(x, y, tilemap1, spritesheet1, BLACK);
   tft.drawTilemap(x, y, tilemap2, spritesheet2, BROWN);
     tft.drawTilemap(x, y, tilemap3, spritesheet3, LIGHTBROWN);

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
  
             if (ButtonUp.update());
              if (ButtonDown.update());
               if (ButtonLeft.update());
                if (ButtonRight.update());

                ButtonUp.rebounce(10);
               ButtonDown.rebounce(10);
              ButtonLeft.rebounce(10);
            ButtonRight.rebounce(10);

///////////////////////////////////////////////////////////////////////////////   
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
    if (ButtonUp.fallingEdge()){
      tft.drawBitmap(player_x, player_y,paul_rearblack,16,16,BLACK);
        tft.drawBitmap(player_x, player_y,paul_rearblue,16,16,BLUE);
         tft.drawBitmap(player_x, player_y,paul_rearbrown,16,16,BROWN);
          tft.drawBitmap(player_x, player_y,paul_reargrey,16,16,GREY);
           tft.drawBitmap(player_x, player_y,paul_rearpink,16,16,LIGHTBROWN);
            tft.drawBitmap(player_x, player_y,paul_rearred,16,16,RED);

        tft.drawBitmap(player_x, player_y,paul_rearw1black,16,16,BLACK);
         tft.drawBitmap(player_x, player_y,paul_rearw1blue,16,16,BLUE);
          tft.drawBitmap(player_x, player_y,paul_rearw1brown,16,16,BROWN);
           tft.drawBitmap(player_x, player_y,paul_rearw1grey,16,16,GREY);
            tft.drawBitmap(player_x, player_y,paul_rearw1pink,16,16,LIGHTBROWN);
             tft.drawBitmap(player_x, player_y,paul_rearw1red,16,16,RED);
 
                player_direction = 1;
             player_y = player_y - 5;}
//             if(checkcolision())player_y--;} 
           if(player_y <= 0){
              player_y = 0;}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
       if (ButtonDown.fallingEdge()){
      tft.drawBitmap(player_x, player_y,paul_frontblack,16,16,BLACK);
       tft.drawBitmap(player_x, player_y,paul_frontblue,16,16,BLUE);
        tft.drawBitmap(player_x, player_y,paul_frontbrown,16,16,BROWN);
         tft.drawBitmap(player_x, player_y,paul_frontgrey,16,16,GREY);
          tft.drawBitmap(player_x, player_y,paul_frontgreen,16,16,GREEN);
           tft.drawBitmap(player_x, player_y,paul_frontpink,16,16,LIGHTBROWN);
            tft.drawBitmap(player_x, player_y,paul_frontred,16,16,RED);

       tft.drawBitmap(player_x, player_y,paul_frontw1black,16,16,BLACK);
        tft.drawBitmap(player_x, player_y,paul_frontw1blue,16,16,BLUE);
         tft.drawBitmap(player_x, player_y,paul_frontw1brown,16,16,BROWN);
          tft.drawBitmap(player_x, player_y,paul_frontw1grey,16,16,GREY);
           tft.drawBitmap(player_x, player_y,paul_frontw1green,16,16,GREEN);
            tft.drawBitmap(player_x, player_y,paul_frontw1pink,16,16,LIGHTBROWN);
             tft.drawBitmap(player_x, player_y,paul_frontw1red,16,16,RED);
             
               player_direction = 2;
            player_y = player_y + 5;}
//            if(checkcolision())player_y++;}
            if(player_y >= 224){
              player_y = 224;}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
      if (ButtonLeft.fallingEdge()){
     tft.drawBitmap(player_x, player_y,paul_leftblack,16,16,BLACK);
       tft.drawBitmap(player_x, player_y,paul_leftblue,16,16,BLUE);
        tft.drawBitmap(player_x, player_y,paul_leftbrown,16,16,BROWN);
         tft.drawBitmap(player_x, player_y,paul_leftgreen,16,16,GREEN);
          tft.drawBitmap(player_x, player_y,paul_leftgrey,16,16,GREY);
           tft.drawBitmap(player_x, player_y,paul_leftpink,16,16,LIGHTBROWN);
            tft.drawBitmap(player_x, player_y,paul_leftred,16,16,RED);

       tft.drawBitmap(player_x, player_y,paul_leftwblack,16,16,BLACK);
        tft.drawBitmap(player_x, player_y,paul_leftwblue,16,16,BLUE);
         tft.drawBitmap(player_x, player_y,paul_leftwbrown,16,16,BROWN);
          tft.drawBitmap(player_x, player_y,paul_leftwgreen,16,16,GREEN);
           tft.drawBitmap(player_x, player_y,paul_leftwgrey,16,16,GREY);
            tft.drawBitmap(player_x, player_y,paul_leftwpink,16,16,LIGHTBROWN);
             tft.drawBitmap(player_x, player_y,paul_leftwred,16,16,RED);

                player_direction = 3;
             player_x = player_x - 5;}
//             if(checkcolision())player_x--;}  
            if(player_x >= 304){
              player_x = 304;}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
       if (ButtonRight.fallingEdge()){
       tft.drawBitmap(player_x, player_y,paul_rightblack,16,16,BLACK);
        tft.drawBitmap(player_x, player_y,paul_rightblue,16,16,BLUE);
         tft.drawBitmap(player_x, player_y,paul_rightbrown,16,16,BROWN);
          tft.drawBitmap(player_x, player_y,paul_rightgrey,16,16,GREY);
           tft.drawBitmap(player_x, player_y,paul_rightpink,16,16,LIGHTBROWN);
            tft.drawBitmap(player_x, player_y,paul_rightred,16,16,RED);
 
       tft.drawBitmap(player_x, player_y,paul_rightblack,16,16,BLACK);
        tft.drawBitmap(player_x, player_y,paul_rightblue,16,16,BLUE);
         tft.drawBitmap(player_x, player_y,paul_rightbrown,16,16,BROWN);
          tft.drawBitmap(player_x, player_y,paul_rightgrey,16,16,GREY);
           tft.drawBitmap(player_x, player_y,paul_rightpink,16,16,LIGHTBROWN);
            tft.drawBitmap(player_x, player_y,paul_rightred,16,16,RED);
             tft.updateScreen();
       
               player_direction = 4;
            player_x = player_x + 5;}
//           if(checkcolision())player_x++;}
            if(player_x <= -2){
              player_x = -2;}
///////////////////////////////////////////////////////////////////////////////     
//////////////////////////////PLAYER DIRECTION/////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
     if (player_direction == 1){
      tft.drawBitmap(player_x, player_y,paul_rearblack,16,16,BLACK);
       tft.drawBitmap(player_x, player_y,paul_rearblue,16,16,BLUE);
        tft.drawBitmap(player_x, player_y,paul_rearbrown,16,16,BROWN);
         tft.drawBitmap(player_x, player_y,paul_reargrey,16,16,GREY);
          tft.drawBitmap(player_x, player_y,paul_rearpink,16,16,LIGHTBROWN);
           tft.drawBitmap(player_x, player_y,paul_rearred,16,16,RED);
        }
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
      else if (player_direction == 2){
      tft.drawBitmap(player_x, player_y,paul_frontblack,16,16,BLACK);
       tft.drawBitmap(player_x, player_y,paul_frontblue,16,16,BLUE);
        tft.drawBitmap(player_x, player_y,paul_frontbrown,16,16,BROWN);
         tft.drawBitmap(player_x, player_y,paul_frontgrey,16,16,GREY);
          tft.drawBitmap(player_x, player_y,paul_frontgreen,16,16,GREEN);
           tft.drawBitmap(player_x, player_y,paul_frontpink,16,16,LIGHTBROWN);
            tft.drawBitmap(player_x, player_y,paul_frontred,16,16,RED);
      }
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
       else if (player_direction == 3){
        tft.drawBitmap(player_x, player_y,paul_leftblack,16,16,BLACK);
         tft.drawBitmap(player_x, player_y,paul_leftblue,16,16,BLUE);
          tft.drawBitmap(player_x, player_y,paul_leftbrown,16,16,BROWN);
           tft.drawBitmap(player_x, player_y,paul_leftgreen,16,16,GREEN);
            tft.drawBitmap(player_x, player_y,paul_leftgrey,16,16,GREY);
             tft.drawBitmap(player_x, player_y,paul_leftpink,16,16,LIGHTBROWN);
              tft.drawBitmap(player_x, player_y,paul_leftred,16,16,RED);
        }
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
         else if (player_direction == 4){
         tft.drawBitmap(player_x, player_y,paul_rightblack,16,16,BLACK);
          tft.drawBitmap(player_x, player_y,paul_rightblue,16,16,BLUE);
           tft.drawBitmap(player_x, player_y,paul_rightbrown,16,16,BROWN);
            tft.drawBitmap(player_x, player_y,paul_rightgrey,16,16,GREY);
             tft.drawBitmap(player_x, player_y,paul_rightpink,16,16,LIGHTBROWN);
              tft.drawBitmap(player_x, player_y,paul_rightred,16,16,RED);
                 }
          }
}
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////collision/////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
   bool checkcolision() // Transformed it into a function 

    {
    uint16_t i;  
     for(i=0; i < tft.numcolision + 1; i++)

   {
    if(tft.collideRectRect(player_x, player_y,16,16,tft.solid[i].x,tft.solid[i].y,16,16))

   {
    
     if(tft.solid[i].spritecol == blank_tile1); //Do nothing because it's floor - this line not needed
else if(tft.solid[i].spritecol == rock_black)return true;
   }

   }
return false; // Return false if don't touch anything

  }

as you can see I removed all the non working updates littered through out it for this updateAll() command.....
Code:
boolean GrafxT3::updateAll() {
	if (((nextFrameMillis - millis()) > timePerFrame) && frameEndMicros) { //if time to render a new frame is reached and the frame end has ran once
		nextFrameMillis = millis() + timePerFrame;
		frameCount++;

		frameEndMicros = 0;
		frameStartMicros = micros();
        return true;

	}
	else {
		if (!frameEndMicros) { //runs once at the end of the frame
//			
         useFrameBuffer(1);
			if (!persistence)
				  updateScreen();
				freeFrameBuffer(); //clear the buffer
 //                updateScreen();

			frameEndMicros = micros(); //measure the frame's end time
			frameDurationMicros = frameEndMicros - frameStartMicros;

		}
		return false;
	}
}

Now this works and kills the trailing but it has problems. When the player sprite moves up the screen he fades. but he looks more solid. The other problem is that when the tilemap is turned on the whole screen flashes annoyingly. I tried to do something like this........

Code:
useFrameBuffer(1);
 tft.drawTilemap(x, y, tilemap1, spritesheet1, BLACK);
   tft.drawTilemap(x, y, tilemap2, spritesheet2, BROWN);
     tft.drawTilemap(x, y, tilemap3, spritesheet3, LIGHTBROWN);
  updateScreen();
freeFrameBuffer(); //clear the buffer

but that results in the same problem heres a couple vids

https://youtu.be/Sh64m6Fkb6k

https://youtu.be/Ji3oocZQnOI

I'll do any debug statement you think will help just tell me where and what

Edit:::::

I tried using a fill screen to see if that would solidify the player Sprite at the top as it is on the bottom. No go. But when I called it the whole screen is black. I'm trying to add a fireball feature at the press of a button but the firebal won't show. On the other hand with the fireball stuff added it slows the tilemap to a flash every few seconds. So now I'm really confused.
 
Last edited:
On the blank screen with just the sprite - print numbers on the screen one per line out of the active area. Perhaps start with a not black background. Change the color and print 1-2 characters to the right each time you move the sprite. Draw a rectangle around where you expect the sprite to update - filled or not - perhaps filled before you start for the whole area the sprite moves over then not filled on each move - change the size as needed.

Simple things like this will show where and what part of the screen is being (re)drawn - pixels will go away or show up in odd places. Anytime you put black on black - or leave black areas - you don't see what is happening there if it redraws in black/clears the screen. Or in the case of your second video - everything just flashes.

For that sprite move it looks like the screen is updating and redrawing the whole screen top to bottom and it is only more apparent as it nears the top as it is perhaps blanking the whole screen (slow) then plopping the sprite (fast) - so at the bottom it persists for longer until blanking - then quickly moves the sprite. At the top it goes off at clear screen start - and stays off until done.

The Update should do nothing and be skipped when the screen isn't changed - nothing moves.

As noted before - start with a simple example - fix all of its issues - the first vid - once that works as expected there will be fewer things wrong (if any) on subsequent variations causing distraction or hiding the real issue.

Put prints anywhere you expect something to change. Kurt and I left many notes before - slow the update rate during testing - perhaps 5 or 1 fps - so things are not missed or hidden. The sooner you slow it down enough to 'see' and correct the problems the faster. Connect a second Teensy unit with display with Serial ( 1 or 2 Mbaud ) to the first [Serial 1 or 2 with rx/tx crossed and ground]. Have the first write out an index which tells the second unit what line to write to - pass a string with text and values as needed for that indexed line. Program the second teensy to read the index line number and then display the text. Then with the two display side by side will let you see without scrolling or having to look at the computer. Put a function in your code to STOP anywhere you put it until you press/release any spare button you have connected - this will be easier and faster than watching for USB input.

So many debug ideas - many have been put out before as tools for use - practice with them - then when needed the right one will be apparent - or what simple variation or combination will do the trick.
 
@duhjoker - I do try to help out, but I also have my own projects to work out. So I don't have the time or energy to debug your program and libraries. Also don't want to keep repeating the same suggestions over and over, ...

But all of this comes down to YOU need to figure out how each thing is drawn on the screen and how it reacts with other things drawn on the screen. Again as Defragster mentioned, start with the simplest cases first. That is if you have a reasonably simple program that is not working right, debug it and eliminate it's issues and then add more parts of your main program on, debug them...

Often the first thing to do, is to take a step back and think about the problem. Example if you are drawing a logical Sprite on the background that moves, how does that effect the background, and likewise if you have a sprite and you need to redraw the background, how does that effect where the sprite is drawn.. And just logically walk your way through the code. And know that everywhere you do something like a fillScreen is suspect...

As noted by defragster and myself, there are many ways to get an idea of what pieces of code that are being executed. Either Serial.prints, output something to display or Serial port. Again if it were me, I would put toggle (and/or set high/low) of IO pins around main drawing functions, and watch the flow of the code through a logic analyzer. If the flicker and stuff happens easily, you could use the Teensy logic analyzer setup using a different teensy....

Code:
useFrameBuffer(1);
 tft.drawTilemap(x, y, tilemap1, spritesheet1, BLACK);
   tft.drawTilemap(x, y, tilemap2, spritesheet2, BROWN);
     tft.drawTilemap(x, y, tilemap3, spritesheet3, LIGHTBROWN);
  updateScreen();
freeFrameBuffer(); //clear the buffer
? is this the freeFrameBuffer() call like what is in my ili9341_t3n library? That frees the allocated buffer for the frame buffer. I never all it! useFrameBuffer, I would typically only call once in setup, unless I was doing code to debug, my library.....

So again if your code logically works like: Draw the background, draw the sprite, redraw the sprite in new location... Then this seams like a simple test case to setup and debug.
I already gave you ideas like, at each point that calls UpdateScreen, put a logical breakpoint before that call and after that call. Could be any method of doing so (Serial.read, or button press, or ...), and the call just before UpdateScreen, nothing should have changed on the screen at the before call, and then after the call, should have the new screen. Does it look correct? Or do you see alternating things changing, like one frame the sprite is drawn and the next frame it is not? Or in one frame the background is drawn and the next one it is not... These are all things that will simply show up as flash...

There are several ways to approach. The simplest is to logically draw the full screen through the frame buffer and always do all of the graphic updates in the same order...

A more complicated approach to simply moving a sprite, involves having the sprite have a logical save buffer to remember what was behind it before it was drawn, and if it moves to restore those bits on the display. But this can get complicated. If you are using the frame buffer for everything, than not so bad.

With frame buffer: you do a readRect of the rectangle, before you draw the sprite, you draw the sprite... Then to move, you restore the rectangle, do the next read and draw sprite in new position...

Without using frame buffer: the above will cause flash, as you clear the whole sprite, then redraw it in new position. So to do this correct, that instead of restoring the rectangle, you only writeRect, those positions, that would be uncovered, which will typically require one or two writeRects, depending on if the sprite is moving horizontal or vertical or diagonal... But again this is more complicated.

So again try to isolate the drawing issues and step through them and see if each screen logically looks correct. You are typically not going to solve it by simply looking at somthing drawn many times a second...
 
Im trying im just having a hard time understanding what I need to do. I know its frustrating. I would never ask any one to debug my code. I wouldn't learn anything if I did. Lol!!!

It was mentioned earlier that running your fb clip tests would give me a better idea of how all this works. And as I learn by example I think its a great idea. So ive got a copy of the t3n library in my arduino libraries folder and im trying to compile but I keep getting errors about the text and button parts........

Code:
In file included from C:\Users\Duhjoker\AppData\Local\Temp\arduino_modified_sketch_42655\Kurts_ILI9341_t3n_FB_and_clip_tests.ino:3:0:

C:\Users\Duhjoker\Documents\Arduino\libraries\ILI9341_t3n-master/ILI9341_t3n.h:173:3: error: conflicting declaration 'typedef struct ILI9341_t3_font_t ILI9341_t3_font_t'

 } ILI9341_t3_font_t;

   ^

In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\ILI9341_t3/font_Arial.h:4:0,

                 from C:\Users\Duhjoker\AppData\Local\Temp\arduino_modified_sketch_42655\Kurts_ILI9341_t3n_FB_and_clip_tests.ino:1:

C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\ILI9341_t3/ILI9341_t3.h:160:3: note: previous declaration as 'typedef struct ILI9341_t3_font_t ILI9341_t3_font_t'

 } ILI9341_t3_font_t;

   ^

In file included from C:\Users\Duhjoker\AppData\Local\Temp\arduino_modified_sketch_42655\Kurts_ILI9341_t3n_FB_and_clip_tests.ino:3:0:

C:\Users\Duhjoker\Documents\Arduino\libraries\ILI9341_t3n-master/ILI9341_t3n.h:626:7: error: redefinition of 'class Adafruit_GFX_Button'

 class Adafruit_GFX_Button {

       ^

In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\ILI9341_t3/font_Arial.h:4:0,

                 from C:\Users\Duhjoker\AppData\Local\Temp\arduino_modified_sketch_42655\Kurts_ILI9341_t3n_FB_and_clip_tests.ino:1:

C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\ILI9341_t3/ILI9341_t3.h:398:7: error: previous definition of 'class Adafruit_GFX_Button'

 class Adafruit_GFX_Button {

       ^

Kurts_ILI9341_t3n_FB_and_clip_tests: In function 'void setup()':
Kurts_ILI9341_t3n_FB_and_clip_tests:55: error: no matching function for call to 'Adafruit_GFX_Button::initButton(ILI9341_t3n*, int, int, int, int, int, int, int, const char [3], int)'
   button.initButton(&tft, 200, 125, 100, 40, ILI9341_GREEN, ILI9341_YELLOW, ILI9341_RED, "UP", 1);

the places the errors point to don't make sense. the text one refers to a line with in the typedef struct for the font the other points to a weird spot as well.
 
I see this indicating two libs with different names that are being pulled in. Choose one and remove the other:

>> C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\ILI9341_t3/ILI9341_t3.h:
>> C:\Users\Duhjoker\Documents\Arduino\libraries\ILI9341_t3n-master/ILI9341_t3n.h

If it were me - I would - do this to avoid duplication or hassles for changes ::
>> install a CLEAN IDE
>> EMPTY sketchbook libraries
>> Run a sample of PJRC ILI9341_t3
>> Put the KURT or other lib you want in SKETCHBOOK\libraries
>> Run a sample from Kurt's library
>> In a TEMP folder put a copy of any files you change - you can then DIFF with SublimeText
>> Add any code or changes you want under #ifdef DUHJOKER - directly in THIS code -
-->> don't blend or merge into another lib
-->> bring any thing needed here
-->> ifdef out anything you don't want or need to change.
>> This may break Kurt's samples - but work in place here to get a simple sample you want that needs the changes.
-->> As you go make sure there are no warnings or errors.
 
Last edited:
Ok I removed the offending library for now so I could get it to compile but it wont accept the fonts included in the library.....

#include <font_Arial.h>
#include <font_ArialBoldX.h>
#include <ILI9341_t3n.h>

Code:
Arduino: 1.8.2 (Windows 7), TD: 1.36, Board: "Teensy 3.6, Serial, 180 MHz, Faster, US English"

C:\Users\Duhjoker\Documents\Arduino\libraries\ILI9341_t3n-master\examples\Kurts_ILI9341_t3n_FB_and_clip_tests\Kurts_ILI9341_t3n_FB_and_clip_tests.ino:1:24: fatal error: font_Arial.h: No such file or directory

compilation terminated.

Error compiling for board Teensy 3.6.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
 
Looks like the header files called for in that program in the default branch may not have been updated to the new font file names in that folder.

The problem with those file names is: if you have multiple libraries that have those header files in them, it is pot luck on which one may be included...

So they were renamed to make them unique.

Change them like:
#include <ili9341_t3n_font_Arial.h>
#include <ili9341_t3n_font_ArialBold.h>
 
Status
Not open for further replies.
Back
Top