GwRoad_Z - widberg/fmtk GitHub Wiki

ImZouna GwRoad_Z

See also: Map

GenWorld Road

struct GwRoad_Z : ResourceObject_Z {
    // thiscall 007DAAF0
    // thiscall 008145A0
    // thiscall 006CFEA0
    // end thiscall
    std::uint32_t roadCount;
    Vec2f genRoadMin;
    Vec2f genRoadMax;
    struct Road {
        std::uint8_t type;
        PascalArray<struct Point {
            std::int32_t a;
            std::uint8_t b;
                // see decode_vec2f_data below
        }, std::uint16_t> points;
    } roads[roadCount];
    std::uint32_t unused5Count;
    Vec2f unused5Min;
        // (-1, -1)
    Vec2f unused5Max;
        // (1, 1)
    struct Unused5 {
        std::uint32_t unused0;
        std::uint32_t unused1;
        std::uint32_t unused2;
        std::uint32_t unused3;
        std::uint32_t unused4;
        std::uint32_t unused5;
        std::uint32_t unused6;
        std::uint32_t unused7;
        std::uint32_t unused8s[unused0 & 0xFFFF];
    } unused5s[unused5Count];
    crc32_t genWorldCRC32;
};

Function to decode the encodedVec2fData, 2 packed 20-bit signed integers this takes 5 bytes which is 3 less than the 8 it would take to store 2 floats. Sign extend and divide by 4 to get the float value.

a           b
01 23 45 67 89
\_____/\_____/
   x      y

Note the use of signed integers. This is important because the right shifts must be arithmetic for the bit hacks to work. p.b should not be sign extended.

Vec2f decode_vec2f_data(const Point p) {
    std::int32_t a = _byteswap_ulong(p.a); // p.a should be big endian
    std::int32_t x = a >> 12;
    std::int32_t y = (((a << 20) >> 12) | p.b);
    return Vec2f { x / 4.0, y / 4.0 };
}
//------------------------------------------------
//--- 010 Editor v11.0.1 Binary Template
//------------------------------------------------

struct GwRoad_Z
{
    uint32 roadCount;
    float genRoadMin[2];
    float genRoadMax[2];
    struct Road
    {
        byte type;
        uint16 pointCount;
        struct Point
        {
            uint32 encodedVec2hf;
            byte a;
        } points[pointCount];
    } roads[roadCount] <optimize=false>;
    uint32 unknown5Count;
    float unknown5Min[2];
    float unknown5Max[2];
    struct Unknown5
    {
        uint32 unknown0;
        uint32 unknown1;
        uint32 unknown2;
        uint32 unknown3;
        uint32 unknown4;
        uint32 unknown5;
        uint32 unknown6;
        uint32 unknown7;
        uint32 unknown8s[unknown0 & 0xFFFF];
    } unknown5s[unknown5Count];
    uint32 unknownCRC32;
} gwroad;
⚠️ **GitHub.com Fallback** ⚠️