79192320

Date: 2024-11-15 12:15:06
Score: 1.5
Natty:
Report link

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.

Reasons:
  • Blacklisted phrase (0.5): thanks
  • RegEx Blacklisted phrase (1): I want
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: magg