Good news! Fixed the problem, thanks for the answers. here the function now:
size_t
TileSet_encode (struct TileSet_s *tileset,
bytes_t **bytes, size_t bytes_offset, size_t bytes_size)
{
// next we collect the vertices, duplicated aren't stored so we need to collect
// them and then calculate.
struct UnitSet_s set;
if (!UnitSet_init(&set))
{
return 0;
}
for (TileSet_Size_t ti = 0; ti < tileset->count; ++ti)
{ // translation of this stuff:
// iterate each tile and iterate each vertex of each tile.
for (unsigned short vi = 0; vi < TILE_VERTICES_MAX; ++vi)
{ // dump the vertex into the set, if we fail terminate operation.
if (UnitSet_add(&set, tileset->tilearray[ti]->tiledata.vertices[vi]) == UNIT_SET_NOMEM)
{
UnitSet_destroy(&set);
return 0;
}
}
}
// size is ok. :P
size_t size_tiles = tileset->count * TILE_ENCODED_SIZE;
size_t size_vertices = sizeof(double) * set.list.length;
size_t bytes_to_write = 8 + size_tiles + size_vertices;
if ((bytes_size - bytes_offset) < bytes_to_write)
{ // now we know how much space the whole thing takes.
// ensure to increase space if needed.
bytes_size = bytes_offset + ((bytes_size - bytes_offset) + bytes_to_write);
bytes_t *newbytes = realloc(*bytes, sizeof(**bytes) * bytes_size);
if (!newbytes)
{ // failed to increase bytes buffer.
return 0;
}
*bytes = newbytes;
}
// ******************************************************************
// improvements from here.
uint16_t chunk_x = 20;
uint16_t chunk_y = 40;
memset((*bytes) + bytes_offset, 0xAA, bytes_size - bytes_offset); // TEST, remove garbage.
memcpy((*bytes) + bytes_offset, &chunk_x, sizeof(uint16_t));
memcpy((*bytes) + bytes_offset + 0x02, &chunk_y, sizeof(uint16_t));
memcpy((*bytes) + bytes_offset + 0x04, &tileset->count, sizeof(uint16_t));
for (TileSet_Size_t tnum = 0; tnum < tileset->count; ++tnum)
{
size_t bytes_tile_offset = bytes_offset + 0x08 + (tnum * TILE_ENCODED_SIZE);
struct TileSet_Tile_s *tiledata = tileset->tilearray[tnum];
uint8_t tile_id = (uint8_t) tiledata->id;
memcpy((*bytes) + bytes_tile_offset, &tile_id, sizeof(tile_id));
for (size_t vi = 0; vi < TILE_VERTICES_MAX; ++vi)
{
uint16_t tile_vidx = (uint16_t) vi;
memcpy((*bytes) + bytes_tile_offset + 1 + (vi * sizeof(uint16_t)),
&tile_vidx, sizeof(tile_vidx));
}
}
for (size_t vi = 0; vi < set.list.length; ++vi)
{
double unit = (double) set.list.array[vi];
memcpy((*bytes) + bytes_offset + 0x08 + size_tiles + (sizeof(unit) * vi),
&unit, sizeof(unit));
}
// ******************************************************************
UnitSet_destroy(&set);
return bytes_to_write;
}
In Short
The result buffer is what I want. The function needs some extra tweaks and over-all it works.