Arduino Forum

Using Arduino => Programming Questions => Topic started by: Duhjoker on Oct 01, 2017, 01:29 am

Title: compressing and using Json data for gaming project
Post by: Duhjoker on Oct 01, 2017, 01:29 am

    I've built a hand held gaming system that does more than just game using Arduino compatible mcu's and any tft that uses spi ili9341 drivers. I'm actually building a game but one function is eating up my flash space.

   The function is for tilemapping or world mapping.  it was originally made for a nokia 5110 and ive had to alter it quite a lot for it work wih the color graphics and such. the amount of space it took to use it with the nokia was pretty insignificant but for color its pretty expensive.

Here is the cpp version of the function
Code: [Select]

void Grafx::drawTilemap(int x, int y, const uint16_t *tilemap, const uint8_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 uint8_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 to use it we list all our bitmaps in an appropriate area of your code then name a sprite sheet which is a list of your bitmaps in the  order you want them represented in and this gives each bitmap in your list an integer number 1-????. like so....

Code: [Select]

const byte *spritesheet[] = { blank_tile,
bedtop, bedbot, bones11, bones12, bones13, bones21, bones22, bones23, bookstop, booksbot,                                                                 ////////10
cabtop, cabbot, cactus, chair, chimneytop, chimneybot, coconut, couchtop, couchbot, debris,                                                               ////////20
dish11, dish12, dish13, dish21, dish22, dish23, dish31, dish32, dish33, dishv2,                                                                           ////////30
floort, machine1t, machine1b, machine2t, machine2b, machine3t, machine3b, machine4t, machine4b, machine511,                                               ////////40
machine512, machine513, machine521, machine522, machine523, machine531, machine532, machine533, machine611, machine612,                                   ////////50
machine613, machine621, machine622, machine623, machine631, machine632, machine633, mart, palmtl, palmtr,                                                 ////////60
palmbl, palmbr, plant1, plant2, pot, printerl, printerr, ptreebot, ptreetop, rocktopcap,                                                                  ////////70
rockbotcap, rockleftcap, rockrightcap, rockcornertl, rockcornertr, rockcornerbl, rockcornerbr, rockcornersharptl, rockcornersharptr, rockcornersharpbl,   ////////80
rockcornersharpbr, rockwalllc, rockwall, rockwallrc, sand, skeleton, stonewall1, stonewall2, tablel, tabler,
tablesm, tank11, tank12, tank21, tank22, tank31, tank32, tomb, water, watergate,    etc                                           


 now we can use the integers to form a tilemap in the same way but using the integer of each bitmap to represent where the bitmaps go. like this

Code: [Select]

const uint16_t weatherstation2[] = {0,25,0,25,
16,16,
74, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 75,
73, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 72,
73, 83, 83, 83, 83, 83, 83, 83, 83, 83, 15, 15, 15, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 72,
73, 83, 83, 83, 83, 83, 83, 83, 83, 83, 15, 15, 15, 83, 83, 83, 83, 49, 50, 51, 83, 83, 83, 83, 72,
73, 83, 83, 83, 83, 32, 32, 32, 83, 83, 15, 15, 15, 83, 38, 38, 83, 52, 53, 54, 83, 36, 34, 32, 72,
73, 21, 22, 23, 30, 33, 33, 33, 30, 31, 16, 16, 16, 65, 39, 39, 65, 55, 56, 57, 65, 37, 35, 33, 72,
73, 24, 25, 26, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 72,
73, 27, 28, 29, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 72,
73, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 72,
73, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 72,
73, 31, 31, 31, 14, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 65, 72,
73, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 65, 65, 65, 31, 31, 31, 31, 31, 31, 31, 65, 65, 72,
73, 31, 31, 31, 31, 89, 90, 31, 31, 31, 31, 31, 78, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 77,
73, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 80, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 75,
73, 31, 31, 31, 31, 31, 31, 14, 31, 31, 31, 31, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 72,
73, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 72,
73, 18, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 83, 34, 34, 9, 36, 36, 9, 32, 32, 83, 83, 83, 72,
73, 19, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 35, 35, 10, 37, 37, 10, 33, 33, 40, 41, 42, 72,
73, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 43, 44, 45, 72,
73, 31, 31, 31, 31, 91, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 46, 47, 48, 72,
73, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 72,
73, 21, 22, 23, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 72,
73, 24, 25, 26, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 65, 72,
73, 27, 28, 29, 30, 31, 31, 31, 31, 31, 105, 105, 105, 105, 105, 31, 31, 31, 31, 31, 31, 31, 65, 65, 72,
76, 70, 70, 70, 70, 70, 70, 70, 70, 70, 105, 105, 105, 105, 105, 70, 70, 70, 70, 70, 70, 70, 70, 70, 77};


Then when we call the function in our code it will display the above as a big picture on screen.

 What I don't know is if its the actual json data or something else in the function.

  if it is the json data, can it be compressed and read from? like make a pointer to the compressed data that points to the right set of data when the tilemap function is called
Title: Re: compressing and using Json data for gaming project
Post by: MorganS on Oct 01, 2017, 04:01 am
Quote
const uint16_t weatherstation2[]
All of those numbers are less than 128 so they can be stored in a byte or int8_t. However I don't think that is going to make a significant saving over the size of the bitmaps you're storing.

I don't see where JSON fits into that code.
Title: Re: compressing and using Json data for gaming project
Post by: PaulMurrayCbr on Oct 01, 2017, 06:19 am
Code: [Select]

const byte *spritesheet[] = { blank_tile,
bedtop, bedbot, bones11, bones12, bones13, bones21, bones22, bones23, bookstop, booksbot,                                                                 ////////10
cabtop, cabbot, cactus, chair, chimneytop, chimneybot, coconut, couchtop, couchbot, debris,                                                               ////////20


This is not JSON data. This is an array of pointers. It looks like JSON data because Javascript borrows a lot of its syntax from Java, which borrows a lot of its syntax from C.

The issue on an arduino is that this data will be copied into ram at boot time. This is unnecessary, because it is static data. To fix this, you use progmem to tell the system not to do this. It does, however, mean that to get the actual data, you need to use the various built-in functions whose job it is to get data out of progmem.

 
Title: Re: compressing and using Json data for gaming project
Post by: Duhjoker on Oct 01, 2017, 11:31 am
The json data would be the code block for weather station. Each of those numbers represent a tile in the code block you pointed out.

In order for the function to be able to display tilemaps of higher intergers than 256 we had to adjust the function.

In the code block for weather station we had to change the math. For example to print out a map at 300 tiles we go 1, which equals 256, then subtract the total number by 256 and there is your second number. Repeat for Y.

   I think we changed to uint16 from 8 for a reason but i can change it back and see what happens. I would really like to add a ton more content but its getting slim.

I tried adding to progmem over flash but there was no change