Using frame buffering to solidify tft displayed objects

Status
Not open for further replies.
All right the problem is definitely in the frame buffer code above for that function. I got the clear pixels right and the color doesnt shift when not using the frame buffer. But when i use the frame buffer it shifts color but still gives me clear pixels. Ive been staring at it for hours now rrying to spot what i did wrong.

Can someone please take a look at the post above and see of you cant spot what i did wrong in the frame buffer part.

Other than that i got every thing else working and im using bounce again for the button inputs.
 
Last edited:
Ok so We know that the problem for sure is in the nbpp functions framebuffer. We also know that the transparency works either way. When I woke up I opened two windows for sublime text and brought both frame buffer parts up to view side by side. I see two problems now up front. First lets look at what yall gave me for the t3 for our control.

Code:
#ifdef ENABLE_GrafxT3_FRAMEBUFFER
	if (_use_fbtft) {
		uint16_t * pfbPixel_row = &_pfbtft[ y*_width + x];
		for (;h>0; h--) {
			uint16_t * pfbPixel = pfbPixel_row;
			pixels = pixels_row_start;				// setup for this row
			uint8_t pixel_shift = row_shift_init;			// Setup mask

			for (int i = 0 ; i < w; i++) {
///				*pfbPixel++ = palette[((*pixels)>>pixel_shift) & pixel_bit_mask];
				uint8_t palette_index = ((*pixels)>>pixel_shift) & pixel_bit_mask;
                if (palette_index != TRANSPARENT_INDEX)
                *pfbPixel = palette[palette_index];
                *pfbPixel++;
				if (!pixel_shift) {
					pixel_shift = 8 - bits_per_pixel;	//setup next mask
					pixels++;
				} else {
					pixel_shift -= bits_per_pixel;
				}
			}
			pfbPixel_row += _width;
			pixels_row_start += count_of_bytes_per_row;
		}
		return;	

	}
	#endif

now lets look at my try..

Code:
#ifdef ENABLE_Grafx_FRAMEBUFFER
	if (_use_fbtft) {
		for (; h>0; h--) {
			uint16_t * pfbPixel = mapYtoFBPtr(y) + x;
			pixels = pixels_row_start;				// setup for this row
			uint8_t pixel_shift = row_shift_init;			// Setup mask

			for (int i = 0; i < w; i++) {
///				*pfbPixel++ = FBmapColor(palette[((*pixels) >> pixel_shift) & pixel_bit_mask]);
				uint8_t palette_index = ((*pixels)>>pixel_shift) & pixel_bit_mask;
                if (palette_index != TRANSPARENT_INDEX)
                *pfbPixel = palette[palette_index];
                *pfbPixel++;
				if (!pixel_shift) {
					pixel_shift = 8 - bits_per_pixel;	//setup next mask
					pixels++;
				}
				else {
					pixel_shift -= bits_per_pixel;
				}
			}
			y++;
			pixels_row_start += count_of_bytes_per_row;
		}
		return;

	}
#endif

ok so right off the bat I can see I left this line out here from the third line of the top code block
Code:
uint16_t * pfbPixel_row = &_pfbtft[ y*_width + x];

but for some reason I ended the frame buffer this way
Code:
					pixel_shift -= bits_per_pixel;
				}
			}
			y++;
			pixels_row_start += count_of_bytes_per_row;
		}
		return;

	}
#endif

instead of this way

Code:
		}
			}
			pfbPixel_row += _width;
			pixels_row_start += count_of_bytes_per_row;
		}
		return;	

	}
	#endif

there might have been a reason for this but its beyond me at the moment. Any clues or suggestions please. can any one think why I might have done it this way?
 
All right guys I hate to bug you about the esp32 and I totally understand why. I have an account over there and ive been using it but the library originated here and you guys are the ones that understand it the most. If you can just help me fix this color shift thing I promise to chill with the esp here. Every thing else is working any way.

ive been looking at it for another day now and I really cant see the problem. I tried chaging the things I mentioned earlier but they were not right at all. Please help me with this
 
Could it be that the items in the function are in the wrong order? I dont see how the non frame buffer part works but the frame buffer part shows the wrong colors. Could some one please please please take a look and see if you cant spot the problem. Every thing ive tried makes it worse or has no change.

Edit:::::

Fixed it!!!
 
Last edited:
My soldering iron came in a couple days ago and I was able to get the pin moved in code so now my teensy is working again and hooked up. Yay!!!!!!!

ok so space.........

So what ive noticed in working with both mcu's is that both use the same amount of space but the installer compresses the data to the wroom chip. Where the teensy just flashes it to the board. Nothing wrong with either way and no complaints from me but it would be cool if we compress the tilemap data somehow.

why the tilemap data? well its been bothering how many bitmaps I was using to trigger stuff like room slides. I was up to 260 sprites in my spritesheet just for individual caves and their specific exit tiles. I had 58 cave entrances. so the other day it hit me that the "if collide and && room =" conditional would also work to use multiple bitmaps of a few listed. Easy enough so I went through and removed the extra 160 tiles and dropped it to just 45 extra. Then compiled it.

Guess how much the percentage dropped by? Give up? 1% difference. But I understood what the problem was at that moment. Tile map data which is usually insignifigant using the regular Gamebuino library with a nokia5110 screen is eating up my space for the color on the teensy. So as another experiment I took all nine of my 150x150 tilemaps and converted them into a single world map at 358x358. I used Rcarr's change to the tile map function and used the simple math you taught me to accomplish this.

This dropped the 39% down to 32%. So now I know for sure where all the space is going. Now I redid all my tile rooms to be no wider than the screen and 5 more tiles high at 25. so 20wx25h. but I'm afraid I'm gonna run out of space still. I'm also learning to use structure to define sides of a square more movey block puzzles.

ok so now that we know the tilemap data is so expensive, can any one think of a way to make the tilemap data less expensive? with out having to make my world map even smaller.
 
Nice project. have you considered using an IPS display for it? The viewing angles on that ILI9341 are really poor.
 
Ok so i made a few changes to my game since i learned how to use the same bitmaps over and over again to do stuff with. Plus some extra graphis in grey to kill all the brown.

That being said i have over 300 bitmaps being used in the spritesheet for the tilemap. Because of that the compiler is the stuff after 256 removing them and doing the first 256 over again. Im assumming i need to change the bitmap funtcions to uint16_t instead of uint16_t?

Or is it the sprite sheet that holds all the tilemap bitmaps need to uint_16

Should i still be using const byte for the bitmaps

Im a lil confused
 
Last edited:
Ok so i made a few changes to my game since i learned how to use the same bitmaps over and over again to do stuff with. Plus some extra graphis in grey to kill all the brown.

That being said i have over 300 bitmaps being used in the spritesheet for the tilemap. Because of that the compiler is the stuff after 256 removing them and doing the first 256 over again. Im assumming i need to change the bitmap funtcions to uint16_t instead of uint16_t?

Or is it the sprite sheet that holds all the tilemap bitmaps need to uint_16

Should i still be using const byte for the bitmaps

Im a lil confused
I think you meant to say I'm assumming i need to change the bitmap functions to uint16_t instead of uint8_t?.

If you are using the uint8_t, BYTE, or unsigned char types, that type can only hold values 0 through 255. If you store anything above 255 into a uint8_t value, the modulus (value % 256) be stored.

Now you want the index value (the value that addresses which bitmap to copy to the display to be uint16_t. You don't want to change the actual declaration of the bitmap itself, just the index to the bitmap. You need to go through the code, changing all of the functions that return a bitmap index to use and functions that take a bitmap index to copy to be at least uint16_t.

You want to continue to use const on the bitmaps. If you use const on the Teensys, all of the data is stored in the same area as the program is (flash memory), and it can't normally be changed by the program. The read/write memory (SDRAM) that non-const variables are stored in is much smaller. On a Teensy 3.2, the flash memory is 256 kilobytes while the SDRAM memory is 64 kilobytes.

As a footnote, the const applies to arm-based processors like Teensy 3.2 where both the flash memory and the SDRAM memory are in the same address space. The AVR processor that is used in the older Arduinos (like the Ardunio Uno) has a more complicated method of accessing read only memory.
 
Thank you!! ok I'm running in circles here. I now have all the bitmaps listed as so.....

Code:
const uint16_t blank_tile[] = {
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,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,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,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,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,0x00,0x00,0x00};

I changed the sprite sheet to const uint16_t as well...

Code:
const uint16_t *spritesheet[] = { blank_tile,
bedtop, bedbot, bones11, bones12, bones13, bones21, bones22, bones23, bookstop, booksbot,                                                                 ////////10
boulder, boulders, bus11, bus12, bus13, bus21, bus22, bus23, bus31, bus32, 
bus33, bus41, bus43, bus44, bush, cabtop, cabbot, cactus, caveintl, caveintr, 
caveinbr, caveoutbl, caveoutbr,  chair, chimneytop, chimneybot, coconut, couchtopl, couchbotl, couchtopr,
couchbotr, dish11, dish12, dish13, dish21, dish22, dish23, dish31, dish32, dish33,

now lets look at the library changes. In order for any of that to compile I had change the unsigned 8 to 16 as well as change the sprite collection to unsigned16 as well. If not it gives errors pointing at my collision function.

Code:
void        drawTilemap(int x, int y, const uint16_t *tilemap, const uint16_t **spritesheet, const uint16_t * palette);
	void        drawTilemap(int x, int y, const uint16_t *tilemap, const uint16_t **spritesheet, uint16_t dx, uint16_t dy, uint16_t dw, uint16_t dh, const uint16_t * palette);

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

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

	bool flagcollision = true;

cpp
Code:
void GrafxT3::drawTilemap(int x, int y, const uint16_t *tilemap, const uint16_t **spritesheet, const uint16_t * palette){
	drawTilemap(x, y, tilemap, spritesheet, 0, 0, GrafxT3_TFTHEIGHT, GrafxT3_TFTWIDTH, palette);
}

void GrafxT3::drawTilemap(int x, int y, const uint16_t *tilemap, const uint16_t **spritesheet, uint16_t dx, uint16_t dy, uint16_t dw, uint16_t dh, const uint16_t * palette){
 //  uint8_t tilemap_width = pgm_read_byte(tilemap);
//   uint8_t tilemap_height = pgm_read_byte(tilemap + 1);
//   uint8_t tile_width = pgm_read_byte(tilemap + 2);
//   uint8_t tile_height = pgm_read_byte(tilemap + 3);
//   tilemap += 4; // now the first tiyleis at tilemap
 uint16_t tilemap_width = pgm_read_byte(tilemap)* 256 + pgm_read_byte(tilemap + 1);
 uint16_t tilemap_height = pgm_read_byte(tilemap + 2)* 256 + pgm_read_byte(tilemap + 3);
 uint16_t tile_width = pgm_read_byte(tilemap + 4);
 uint16_t tile_height = pgm_read_byte(tilemap + 5);
 tilemap += 6; // now the first tile is at tilemap

	uint16_t ddw = dw + dx;
	uint16_t ddh = dh + dy;
	uint16_t maxDdx = (dw - x + tile_width - 1) / tile_width;
	uint16_t maxDdy = (dh - y + tile_height - 1) / tile_height;
	if (tilemap_width < maxDdx){
		maxDdx = tilemap_width;
	}
	if (tilemap_height < maxDdy){
		maxDdy = tilemap_height;
	}
	int16_t startDdx = (-x) / tile_width;
	int16_t startDdy = (-y) / tile_height;
	if (startDdx < 0){
		startDdx = 0;
	}
	if (startDdy < 0){
		startDdy = 0;
	}
	if (flagcollision)numcolision = 0;                                 //Line 735 - clear numcolision - ADD by Summoner123

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

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

so now when I try to compile I get errors pointing to these functions

.h
Code:
void writeRect4BPPtm(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t *pixels, uint16_t dx, uint16_t dy, uint16_t dw, uint16_t dh, const uint16_t * palette );

void writeRectNBPP(int16_t x, int16_t y, int16_t w, int16_t h,  uint8_t bits_per_pixel, 
		const uint8_t *pixels, const uint16_t * palette );

but points to this with in the .cpp's part of tile map here...

Code:
				writeRectNBPP(drawX, drawY,tile_width, tile_height, 4, spritesheet[tile], palette );

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

and here are the two errors....

Code:
C:\Users\Duhjoker\Documents\Arduino\libraries\GameR-Iot_T3\GrafxT3.cpp: In member function 'void GrafxT3::drawTilemap(int, int, const uint16_t*, const uint16_t**, uint16_t, uint16_t, uint16_t, uint16_t, const uint16_t*)':

C:\Users\Duhjoker\Documents\Arduino\libraries\GameR-Iot_T3\GrafxT3.cpp:1298:87: error: no matching function for call to 'GrafxT3::writeRectNBPP(int16_t&, int16_t&, uint16_t&, uint16_t&, int, const uint16_t*&, const uint16_t*&)'

     writeRectNBPP(drawX, drawY,tile_width, tile_height, 4, spritesheet[tile], palette );

                                                                                       ^

In file included from C:\Users\Duhjoker\Documents\Arduino\libraries\GameR-Iot_T3\GrafxT3.cpp:50:0:

C:\Users\Duhjoker\Documents\Arduino\libraries\GameR-Iot_T3\GrafxT3.h:565:7: note: candidate: void GrafxT3::writeRectNBPP(int16_t, int16_t, int16_t, int16_t, uint8_t, const uint8_t*, const uint16_t*)

  void writeRectNBPP(int16_t x, int16_t y, int16_t w, int16_t h,  uint8_t bits_per_pixel, 

       ^

C:\Users\Duhjoker\Documents\Arduino\libraries\GameR-Iot_T3\GrafxT3.h:565:7: note:   no known conversion for argument 6 from 'const uint16_t* {aka const short unsigned int*}' to 'const uint8_t* {aka const unsigned char*}'

C:\Users\Duhjoker\Documents\Arduino\libraries\GameR-Iot_T3\GrafxT3.cpp:1308:102: error: no matching function for call to 'GrafxT3::writeRect4BPPtm(int16_t&, int16_t&, uint16_t&, uint16_t&, const uint16_t*&, uint16_t&, uint16_t&, uint16_t&, uint16_t&, const uint16_t*&)'

     writeRect4BPPtm(drawX, drawY, tile_width, tile_height, spritesheet[tile], dx, dy, dw, dh, palette);

                                                                                                      ^

In file included from C:\Users\Duhjoker\Documents\Arduino\libraries\GameR-Iot_T3\GrafxT3.cpp:50:0:

C:\Users\Duhjoker\Documents\Arduino\libraries\GameR-Iot_T3\GrafxT3.h:543:10: note: candidate: void GrafxT3::writeRect4BPPtm(int16_t, int16_t, int16_t, int16_t, const uint8_t*, uint16_t, uint16_t, uint16_t, uint16_t, const uint16_t*)

     void writeRect4BPPtm(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t *pixels, uint16_t dx, uint16_t dy, uint16_t dw, uint16_t dh, const uint16_t * palette );

          ^

Can someone do spot check see what I'm missing please?



https://github.com/Duhjoker/GameR-Iot_T3



edit::::

fixed it had to change the byte to unsigned in a few more places. One was tricky to find though
 
Last edited:
All right now I'm really confused. After all that and its still showing weird tiles for any of the tiles after 256 tiles.
 
Remember that pesky popup function I was having trouble with? you know the one that lets me popup a word ballon? Well I finally fixed it. Well I re-wrote it. the problem was with the time left stuff. I got rid of all that and now the popup stays lit as long as the player is touching the object and disappears when not touching. It still needs to be tweaked and I need to make a couple more for paragraphs but here it is....

Code:
void GrafxT3::Popup(const __FlashStringHelper* text){
	    popupText = text;
		setTextSize(2);
        fillRoundRect(0,0,320,60,4,BLUE);
        drawRoundRect(0,0,320,60,4,WHITE);
        setCursor(20,20);
        print(popupText);

I'm having a problem though. for some reason the edges of the screen don't scroll properly and it leaves a bit of the first or last set of tiles depending on player movement.

You tube us killing the resolution but you can the problem well enough

https://youtu.be/0dZt5Mn5xCE


Made the popup function better. the way it was og written and the way it was written by me, the text size and cursor were set up to only use one set of coordinates for placement and only one size for the text.

So to fix that added text size and coordinates to the function like so....

Code:
oid GrafxT3::Popup(const __FlashStringHelper* text, uint8_t s, int16_t x, int16_t y){
	    popupText = text;
          textsize = (s > 0) ? s : 1;
		
          fillRoundRect(0,0,320,60,4,BLUE);
          drawRoundRect(0,0,320,60,4,WHITE);

             if (x < 0) x = 0;
	    else if (x >= _width) x = _width - 1;
	    cursor_x = x;
	         if (y < 0) y = 0;
	    else if (y >= _height) y = _height - 1;
	    cursor_y = y;
		print(popupText);
		
	
}

So now when you call it you can have text size big or small and can place it any where in the bubble!!!!!
 
Last edited:
Status
Not open for further replies.
Back
Top