RenderWare binary stream: C++/STL parsing library

Application

Games based on RenderWare engine (Grand Theft Auto 3D series)

This page hosts a formal specification of RenderWare binary stream using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Usage

Using Kaitai Struct in C++/STL usually consists of 3 steps.

  1. We need to create an STL input stream (std::istream).
    • One can open a stream for reading from a local file:
      #include <fstream>
      
      std::ifstream is("path/to/local/file.renderware_binary_stream", std::ifstream::binary);
    • Or one can prepare a stream for reading from existing std::string str:
      #include <sstream>
      
      std::istringstream is(str);
    • Or one can parse arbitrary char* buffer in memory, given that we know its size:
      #include <sstream>
      
      const char buf[] = { ... };
      std::string str(buf, sizeof buf);
      std::istringstream is(str);
  2. We need to wrap our input stream into Kaitai stream:
    #include <kaitai/kaitaistream.h>
    
    kaitai::kstream ks(&is);
  3. And finally, we can invoke the parsing:
    renderware_binary_stream_t data(&ks);

After that, one can get various attributes from the structure by invoking getter methods like:

data.code() // => get code

C++/STL source code to parse RenderWare binary stream

renderware_binary_stream.h

#ifndef RENDERWARE_BINARY_STREAM_H_
#define RENDERWARE_BINARY_STREAM_H_

// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

#include "kaitai/kaitaistruct.h"

#include <stdint.h>
#include <vector>

#if KAITAI_STRUCT_VERSION < 7000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.7 or later is required"
#endif

/**
 * \sa Source
 */

class renderware_binary_stream_t : public kaitai::kstruct {

public:
    class struct_clump_t;
    class struct_geometry_t;
    class geometry_non_native_t;
    class struct_geometry_list_t;
    class rgba_t;
    class sphere_t;
    class morph_target_t;
    class surface_properties_t;
    class struct_frame_list_t;
    class matrix_t;
    class vector_3d_t;
    class list_with_header_t;
    class triangle_t;
    class frame_t;
    class tex_coord_t;
    class struct_texture_dictionary_t;

    enum sections_t {
        SECTIONS_STRUCT = 1,
        SECTIONS_STRING = 2,
        SECTIONS_EXTENSION = 3,
        SECTIONS_CAMERA = 5,
        SECTIONS_TEXTURE = 6,
        SECTIONS_MATERIAL = 7,
        SECTIONS_MATERIAL_LIST = 8,
        SECTIONS_ATOMIC_SECTION = 9,
        SECTIONS_PLANE_SECTION = 10,
        SECTIONS_WORLD = 11,
        SECTIONS_SPLINE = 12,
        SECTIONS_MATRIX = 13,
        SECTIONS_FRAME_LIST = 14,
        SECTIONS_GEOMETRY = 15,
        SECTIONS_CLUMP = 16,
        SECTIONS_LIGHT = 18,
        SECTIONS_UNICODE_STRING = 19,
        SECTIONS_ATOMIC = 20,
        SECTIONS_TEXTURE_NATIVE = 21,
        SECTIONS_TEXTURE_DICTIONARY = 22,
        SECTIONS_ANIMATION_DATABASE = 23,
        SECTIONS_IMAGE = 24,
        SECTIONS_SKIN_ANIMATION = 25,
        SECTIONS_GEOMETRY_LIST = 26,
        SECTIONS_ANIM_ANIMATION = 27,
        SECTIONS_TEAM = 28,
        SECTIONS_CROWD = 29,
        SECTIONS_DELTA_MORPH_ANIMATION = 30,
        SECTIONS_RIGHT_TO_RENDER = 31,
        SECTIONS_MULTITEXTURE_EFFECT_NATIVE = 32,
        SECTIONS_MULTITEXTURE_EFFECT_DICTIONARY = 33,
        SECTIONS_TEAM_DICTIONARY = 34,
        SECTIONS_PLATFORM_INDEPENDENT_TEXTURE_DICTIONARY = 35,
        SECTIONS_TABLE_OF_CONTENTS = 36,
        SECTIONS_PARTICLE_STANDARD_GLOBAL_DATA = 37,
        SECTIONS_ALTPIPE = 38,
        SECTIONS_PLATFORM_INDEPENDENT_PEDS = 39,
        SECTIONS_PATCH_MESH = 40,
        SECTIONS_CHUNK_GROUP_START = 41,
        SECTIONS_CHUNK_GROUP_END = 42,
        SECTIONS_UV_ANIMATION_DICTIONARY = 43,
        SECTIONS_COLL_TREE = 44,
        SECTIONS_METRICS_PLG = 257,
        SECTIONS_SPLINE_PLG = 258,
        SECTIONS_STEREO_PLG = 259,
        SECTIONS_VRML_PLG = 260,
        SECTIONS_MORPH_PLG = 261,
        SECTIONS_PVS_PLG = 262,
        SECTIONS_MEMORY_LEAK_PLG = 263,
        SECTIONS_ANIMATION_PLG = 264,
        SECTIONS_GLOSS_PLG = 265,
        SECTIONS_LOGO_PLG = 266,
        SECTIONS_MEMORY_INFO_PLG = 267,
        SECTIONS_RANDOM_PLG = 268,
        SECTIONS_PNG_IMAGE_PLG = 269,
        SECTIONS_BONE_PLG = 270,
        SECTIONS_VRML_ANIM_PLG = 271,
        SECTIONS_SKY_MIPMAP_VAL = 272,
        SECTIONS_MRM_PLG = 273,
        SECTIONS_LOD_ATOMIC_PLG = 274,
        SECTIONS_ME_PLG = 275,
        SECTIONS_LIGHTMAP_PLG = 276,
        SECTIONS_REFINE_PLG = 277,
        SECTIONS_SKIN_PLG = 278,
        SECTIONS_LABEL_PLG = 279,
        SECTIONS_PARTICLES_PLG = 280,
        SECTIONS_GEOMTX_PLG = 281,
        SECTIONS_SYNTH_CORE_PLG = 282,
        SECTIONS_STQPP_PLG = 283,
        SECTIONS_PART_PP_PLG = 284,
        SECTIONS_COLLISION_PLG = 285,
        SECTIONS_HANIM_PLG = 286,
        SECTIONS_USER_DATA_PLG = 287,
        SECTIONS_MATERIAL_EFFECTS_PLG = 288,
        SECTIONS_PARTICLE_SYSTEM_PLG = 289,
        SECTIONS_DELTA_MORPH_PLG = 290,
        SECTIONS_PATCH_PLG = 291,
        SECTIONS_TEAM_PLG = 292,
        SECTIONS_CROWD_PP_PLG = 293,
        SECTIONS_MIP_SPLIT_PLG = 294,
        SECTIONS_ANISOTROPY_PLG = 295,
        SECTIONS_GCN_MATERIAL_PLG = 297,
        SECTIONS_GEOMETRIC_PVS_PLG = 298,
        SECTIONS_XBOX_MATERIAL_PLG = 299,
        SECTIONS_MULTI_TEXTURE_PLG = 300,
        SECTIONS_CHAIN_PLG = 301,
        SECTIONS_TOON_PLG = 302,
        SECTIONS_PTANK_PLG = 303,
        SECTIONS_PARTICLE_STANDARD_PLG = 304,
        SECTIONS_PDS_PLG = 305,
        SECTIONS_PRTADV_PLG = 306,
        SECTIONS_NORMAL_MAP_PLG = 307,
        SECTIONS_ADC_PLG = 308,
        SECTIONS_UV_ANIMATION_PLG = 309,
        SECTIONS_CHARACTER_SET_PLG = 384,
        SECTIONS_NOHS_WORLD_PLG = 385,
        SECTIONS_IMPORT_UTIL_PLG = 386,
        SECTIONS_SLERP_PLG = 387,
        SECTIONS_OPTIM_PLG = 388,
        SECTIONS_TL_WORLD_PLG = 389,
        SECTIONS_DATABASE_PLG = 390,
        SECTIONS_RAYTRACE_PLG = 391,
        SECTIONS_RAY_PLG = 392,
        SECTIONS_LIBRARY_PLG = 393,
        SECTIONS_PLG_2D = 400,
        SECTIONS_TILE_RENDER_PLG = 401,
        SECTIONS_JPEG_IMAGE_PLG = 402,
        SECTIONS_TGA_IMAGE_PLG = 403,
        SECTIONS_GIF_IMAGE_PLG = 404,
        SECTIONS_QUAT_PLG = 405,
        SECTIONS_SPLINE_PVS_PLG = 406,
        SECTIONS_MIPMAP_PLG = 407,
        SECTIONS_MIPMAPK_PLG = 408,
        SECTIONS_FONT_2D = 409,
        SECTIONS_INTERSECTION_PLG = 410,
        SECTIONS_TIFF_IMAGE_PLG = 411,
        SECTIONS_PICK_PLG = 412,
        SECTIONS_BMP_IMAGE_PLG = 413,
        SECTIONS_RAS_IMAGE_PLG = 414,
        SECTIONS_SKIN_FX_PLG = 415,
        SECTIONS_VCAT_PLG = 416,
        SECTIONS_PATH_2D = 417,
        SECTIONS_BRUSH_2D = 418,
        SECTIONS_OBJECT_2D = 419,
        SECTIONS_SHAPE_2D = 420,
        SECTIONS_SCENE_2D = 421,
        SECTIONS_PICK_REGION_2D = 422,
        SECTIONS_OBJECT_STRING_2D = 423,
        SECTIONS_ANIMATION_PLG_2D = 424,
        SECTIONS_ANIMATION_2D = 425,
        SECTIONS_KEYFRAME_2D = 432,
        SECTIONS_MAESTRO_2D = 433,
        SECTIONS_BARYCENTRIC = 434,
        SECTIONS_PLATFORM_INDEPENDENT_TEXTURE_DICTIONARY_TK = 435,
        SECTIONS_TOC_TK = 436,
        SECTIONS_TPL_TK = 437,
        SECTIONS_ALTPIPE_TK = 438,
        SECTIONS_ANIMATION_TK = 439,
        SECTIONS_SKIN_SPLIT_TOOKIT = 440,
        SECTIONS_COMPRESSED_KEY_TK = 441,
        SECTIONS_GEOMETRY_CONDITIONING_PLG = 442,
        SECTIONS_WING_PLG = 443,
        SECTIONS_GENERIC_PIPELINE_TK = 444,
        SECTIONS_LIGHTMAP_CONVERSION_TK = 445,
        SECTIONS_FILESYSTEM_PLG = 446,
        SECTIONS_DICTIONARY_TK = 447,
        SECTIONS_UV_ANIMATION_LINEAR = 448,
        SECTIONS_UV_ANIMATION_PARAMETER = 449,
        SECTIONS_BIN_MESH_PLG = 1294,
        SECTIONS_NATIVE_DATA_PLG = 1296,
        SECTIONS_ZMODELER_LOCK = 61982,
        SECTIONS_ATOMIC_VISIBILITY_DISTANCE = 39055872,
        SECTIONS_CLUMP_VISIBILITY_DISTANCE = 39055873,
        SECTIONS_FRAME_VISIBILITY_DISTANCE = 39055874,
        SECTIONS_PIPELINE_SET = 39056115,
        SECTIONS_UNUSED_5 = 39056116,
        SECTIONS_TEXDICTIONARY_LINK = 39056117,
        SECTIONS_SPECULAR_MATERIAL = 39056118,
        SECTIONS_UNUSED_8 = 39056119,
        SECTIONS_EFFECT_2D = 39056120,
        SECTIONS_EXTRA_VERT_COLOUR = 39056121,
        SECTIONS_COLLISION_MODEL = 39056122,
        SECTIONS_GTA_HANIM = 39056123,
        SECTIONS_REFLECTION_MATERIAL = 39056124,
        SECTIONS_BREAKABLE = 39056125,
        SECTIONS_FRAME = 39056126,
        SECTIONS_UNUSED_16 = 39056127
    };

    renderware_binary_stream_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, renderware_binary_stream_t* p__root = 0);

private:
    void _read();

public:
    ~renderware_binary_stream_t();

    /**
     * \sa Source
     */

    class struct_clump_t : public kaitai::kstruct {

    public:

        struct_clump_t(kaitai::kstream* p__io, renderware_binary_stream_t::list_with_header_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~struct_clump_t();

    private:
        uint32_t m_num_atomics;
        uint32_t m_num_lights;
        bool n_num_lights;

    public:
        bool _is_null_num_lights() { num_lights(); return n_num_lights; };

    private:
        uint32_t m_num_cameras;
        bool n_num_cameras;

    public:
        bool _is_null_num_cameras() { num_cameras(); return n_num_cameras; };

    private:
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::list_with_header_t* m__parent;

    public:
        uint32_t num_atomics() const { return m_num_atomics; }
        uint32_t num_lights() const { return m_num_lights; }
        uint32_t num_cameras() const { return m_num_cameras; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::list_with_header_t* _parent() const { return m__parent; }
    };

    /**
     * \sa Source
     */

    class struct_geometry_t : public kaitai::kstruct {

    public:

        struct_geometry_t(kaitai::kstream* p__io, renderware_binary_stream_t::list_with_header_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~struct_geometry_t();

    private:
        bool f_is_textured;
        bool m_is_textured;

    public:
        bool is_textured();

    private:
        bool f_is_prelit;
        bool m_is_prelit;

    public:
        bool is_prelit();

    private:
        bool f_is_textured2;
        bool m_is_textured2;

    public:
        bool is_textured2();

    private:
        bool f_is_native;
        bool m_is_native;

    public:
        bool is_native();

    private:
        uint32_t m_format;
        uint32_t m_num_triangles;
        uint32_t m_num_vertices;
        uint32_t m_num_morph_targets;
        surface_properties_t* m_surf_prop;
        bool n_surf_prop;

    public:
        bool _is_null_surf_prop() { surf_prop(); return n_surf_prop; };

    private:
        geometry_non_native_t* m_geometry;
        bool n_geometry;

    public:
        bool _is_null_geometry() { geometry(); return n_geometry; };

    private:
        std::vector<morph_target_t*>* m_morph_targets;
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::list_with_header_t* m__parent;

    public:
        uint32_t format() const { return m_format; }
        uint32_t num_triangles() const { return m_num_triangles; }
        uint32_t num_vertices() const { return m_num_vertices; }
        uint32_t num_morph_targets() const { return m_num_morph_targets; }
        surface_properties_t* surf_prop() const { return m_surf_prop; }
        geometry_non_native_t* geometry() const { return m_geometry; }
        std::vector<morph_target_t*>* morph_targets() const { return m_morph_targets; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::list_with_header_t* _parent() const { return m__parent; }
    };

    class geometry_non_native_t : public kaitai::kstruct {

    public:

        geometry_non_native_t(kaitai::kstream* p__io, renderware_binary_stream_t::struct_geometry_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~geometry_non_native_t();

    private:
        std::vector<rgba_t*>* m_prelit_colors;
        bool n_prelit_colors;

    public:
        bool _is_null_prelit_colors() { prelit_colors(); return n_prelit_colors; };

    private:
        std::vector<tex_coord_t*>* m_tex_coords;
        bool n_tex_coords;

    public:
        bool _is_null_tex_coords() { tex_coords(); return n_tex_coords; };

    private:
        std::vector<triangle_t*>* m_triangles;
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::struct_geometry_t* m__parent;

    public:
        std::vector<rgba_t*>* prelit_colors() const { return m_prelit_colors; }
        std::vector<tex_coord_t*>* tex_coords() const { return m_tex_coords; }
        std::vector<triangle_t*>* triangles() const { return m_triangles; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::struct_geometry_t* _parent() const { return m__parent; }
    };

    /**
     * \sa Source
     */

    class struct_geometry_list_t : public kaitai::kstruct {

    public:

        struct_geometry_list_t(kaitai::kstream* p__io, renderware_binary_stream_t::list_with_header_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~struct_geometry_list_t();

    private:
        uint32_t m_num_geometries;
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::list_with_header_t* m__parent;

    public:
        uint32_t num_geometries() const { return m_num_geometries; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::list_with_header_t* _parent() const { return m__parent; }
    };

    class rgba_t : public kaitai::kstruct {

    public:

        rgba_t(kaitai::kstream* p__io, renderware_binary_stream_t::geometry_non_native_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~rgba_t();

    private:
        uint8_t m_r;
        uint8_t m_g;
        uint8_t m_b;
        uint8_t m_a;
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::geometry_non_native_t* m__parent;

    public:
        uint8_t r() const { return m_r; }
        uint8_t g() const { return m_g; }
        uint8_t b() const { return m_b; }
        uint8_t a() const { return m_a; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::geometry_non_native_t* _parent() const { return m__parent; }
    };

    class sphere_t : public kaitai::kstruct {

    public:

        sphere_t(kaitai::kstream* p__io, renderware_binary_stream_t::morph_target_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~sphere_t();

    private:
        float m_x;
        float m_y;
        float m_z;
        float m_radius;
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::morph_target_t* m__parent;

    public:
        float x() const { return m_x; }
        float y() const { return m_y; }
        float z() const { return m_z; }
        float radius() const { return m_radius; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::morph_target_t* _parent() const { return m__parent; }
    };

    class morph_target_t : public kaitai::kstruct {

    public:

        morph_target_t(kaitai::kstream* p__io, renderware_binary_stream_t::struct_geometry_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~morph_target_t();

    private:
        sphere_t* m_bounding_sphere;
        uint32_t m_has_vertices;
        uint32_t m_has_normals;
        std::vector<vector_3d_t*>* m_vertices;
        bool n_vertices;

    public:
        bool _is_null_vertices() { vertices(); return n_vertices; };

    private:
        std::vector<vector_3d_t*>* m_normals;
        bool n_normals;

    public:
        bool _is_null_normals() { normals(); return n_normals; };

    private:
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::struct_geometry_t* m__parent;

    public:
        sphere_t* bounding_sphere() const { return m_bounding_sphere; }
        uint32_t has_vertices() const { return m_has_vertices; }
        uint32_t has_normals() const { return m_has_normals; }
        std::vector<vector_3d_t*>* vertices() const { return m_vertices; }
        std::vector<vector_3d_t*>* normals() const { return m_normals; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::struct_geometry_t* _parent() const { return m__parent; }
    };

    /**
     * \sa Source
     */

    class surface_properties_t : public kaitai::kstruct {

    public:

        surface_properties_t(kaitai::kstream* p__io, renderware_binary_stream_t::struct_geometry_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~surface_properties_t();

    private:
        float m_ambient;
        float m_specular;
        float m_diffuse;
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::struct_geometry_t* m__parent;

    public:
        float ambient() const { return m_ambient; }
        float specular() const { return m_specular; }
        float diffuse() const { return m_diffuse; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::struct_geometry_t* _parent() const { return m__parent; }
    };

    /**
     * \sa Source
     */

    class struct_frame_list_t : public kaitai::kstruct {

    public:

        struct_frame_list_t(kaitai::kstream* p__io, renderware_binary_stream_t::list_with_header_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~struct_frame_list_t();

    private:
        uint32_t m_num_frames;
        std::vector<frame_t*>* m_frames;
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::list_with_header_t* m__parent;

    public:
        uint32_t num_frames() const { return m_num_frames; }
        std::vector<frame_t*>* frames() const { return m_frames; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::list_with_header_t* _parent() const { return m__parent; }
    };

    /**
     * \sa Source
     */

    class matrix_t : public kaitai::kstruct {

    public:

        matrix_t(kaitai::kstream* p__io, renderware_binary_stream_t::frame_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~matrix_t();

    private:
        std::vector<vector_3d_t*>* m_entries;
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::frame_t* m__parent;

    public:
        std::vector<vector_3d_t*>* entries() const { return m_entries; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::frame_t* _parent() const { return m__parent; }
    };

    /**
     * \sa Source
     */

    class vector_3d_t : public kaitai::kstruct {

    public:

        vector_3d_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~vector_3d_t();

    private:
        float m_x;
        float m_y;
        float m_z;
        renderware_binary_stream_t* m__root;
        kaitai::kstruct* m__parent;

    public:
        float x() const { return m_x; }
        float y() const { return m_y; }
        float z() const { return m_z; }
        renderware_binary_stream_t* _root() const { return m__root; }
        kaitai::kstruct* _parent() const { return m__parent; }
    };

    /**
     * Typical structure used by many data types in RenderWare binary
     * stream. Substream contains a list of binary stream entries,
     * first entry always has type "struct" and carries some specific
     * binary data it in, determined by the type of parent. All other
     * entries, beside the first one, are normal, self-describing
     * records.
     */

    class list_with_header_t : public kaitai::kstruct {

    public:

        list_with_header_t(kaitai::kstream* p__io, renderware_binary_stream_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~list_with_header_t();

    private:
        std::string m_code;
        uint32_t m_header_size;
        uint32_t m_version;
        kaitai::kstruct* m_header;
        bool n_header;

    public:
        bool _is_null_header() { header(); return n_header; };

    private:
        std::vector<renderware_binary_stream_t*>* m_entries;
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t* m__parent;
        std::string m__raw_header;
        kaitai::kstream* m__io__raw_header;

    public:
        std::string code() const { return m_code; }
        uint32_t header_size() const { return m_header_size; }
        uint32_t version() const { return m_version; }
        kaitai::kstruct* header() const { return m_header; }
        std::vector<renderware_binary_stream_t*>* entries() const { return m_entries; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t* _parent() const { return m__parent; }
        std::string _raw_header() const { return m__raw_header; }
        kaitai::kstream* _io__raw_header() const { return m__io__raw_header; }
    };

    class triangle_t : public kaitai::kstruct {

    public:

        triangle_t(kaitai::kstream* p__io, renderware_binary_stream_t::geometry_non_native_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~triangle_t();

    private:
        uint16_t m_vertex2;
        uint16_t m_vertex1;
        uint16_t m_material_id;
        uint16_t m_vertex3;
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::geometry_non_native_t* m__parent;

    public:
        uint16_t vertex2() const { return m_vertex2; }
        uint16_t vertex1() const { return m_vertex1; }
        uint16_t material_id() const { return m_material_id; }
        uint16_t vertex3() const { return m_vertex3; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::geometry_non_native_t* _parent() const { return m__parent; }
    };

    /**
     * \sa Source
     */

    class frame_t : public kaitai::kstruct {

    public:

        frame_t(kaitai::kstream* p__io, renderware_binary_stream_t::struct_frame_list_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~frame_t();

    private:
        matrix_t* m_rotation_matrix;
        vector_3d_t* m_position;
        int32_t m_cur_frame_idx;
        uint32_t m_matrix_creation_flags;
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::struct_frame_list_t* m__parent;

    public:
        matrix_t* rotation_matrix() const { return m_rotation_matrix; }
        vector_3d_t* position() const { return m_position; }
        int32_t cur_frame_idx() const { return m_cur_frame_idx; }
        uint32_t matrix_creation_flags() const { return m_matrix_creation_flags; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::struct_frame_list_t* _parent() const { return m__parent; }
    };

    class tex_coord_t : public kaitai::kstruct {

    public:

        tex_coord_t(kaitai::kstream* p__io, renderware_binary_stream_t::geometry_non_native_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~tex_coord_t();

    private:
        float m_u;
        float m_v;
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::geometry_non_native_t* m__parent;

    public:
        float u() const { return m_u; }
        float v() const { return m_v; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::geometry_non_native_t* _parent() const { return m__parent; }
    };

    class struct_texture_dictionary_t : public kaitai::kstruct {

    public:

        struct_texture_dictionary_t(kaitai::kstream* p__io, renderware_binary_stream_t::list_with_header_t* p__parent = 0, renderware_binary_stream_t* p__root = 0);

    private:
        void _read();

    public:
        ~struct_texture_dictionary_t();

    private:
        uint32_t m_num_textures;
        renderware_binary_stream_t* m__root;
        renderware_binary_stream_t::list_with_header_t* m__parent;

    public:
        uint32_t num_textures() const { return m_num_textures; }
        renderware_binary_stream_t* _root() const { return m__root; }
        renderware_binary_stream_t::list_with_header_t* _parent() const { return m__parent; }
    };

private:
    sections_t m_code;
    uint32_t m_size;
    uint32_t m_version;
    list_with_header_t* m_body;
    bool n_body;

public:
    bool _is_null_body() { body(); return n_body; };

private:
    renderware_binary_stream_t* m__root;
    kaitai::kstruct* m__parent;
    std::string m__raw_body;
    kaitai::kstream* m__io__raw_body;

public:
    sections_t code() const { return m_code; }
    uint32_t size() const { return m_size; }
    uint32_t version() const { return m_version; }
    list_with_header_t* body() const { return m_body; }
    renderware_binary_stream_t* _root() const { return m__root; }
    kaitai::kstruct* _parent() const { return m__parent; }
    std::string _raw_body() const { return m__raw_body; }
    kaitai::kstream* _io__raw_body() const { return m__io__raw_body; }
};

#endif  // RENDERWARE_BINARY_STREAM_H_

renderware_binary_stream.cpp

// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

#include "renderware_binary_stream.h"



renderware_binary_stream_t::renderware_binary_stream_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = this;
    _read();
}

void renderware_binary_stream_t::_read() {
    m_code = static_cast<renderware_binary_stream_t::sections_t>(m__io->read_u4le());
    m_size = m__io->read_u4le();
    m_version = m__io->read_u4le();
    n_body = true;
    switch (code()) {
    case SECTIONS_TEXTURE_DICTIONARY: {
        n_body = false;
        m__raw_body = m__io->read_bytes(size());
        m__io__raw_body = new kaitai::kstream(m__raw_body);
        m_body = new list_with_header_t(m__io__raw_body, this, m__root);
        break;
    }
    case SECTIONS_GEOMETRY_LIST: {
        n_body = false;
        m__raw_body = m__io->read_bytes(size());
        m__io__raw_body = new kaitai::kstream(m__raw_body);
        m_body = new list_with_header_t(m__io__raw_body, this, m__root);
        break;
    }
    case SECTIONS_CLUMP: {
        n_body = false;
        m__raw_body = m__io->read_bytes(size());
        m__io__raw_body = new kaitai::kstream(m__raw_body);
        m_body = new list_with_header_t(m__io__raw_body, this, m__root);
        break;
    }
    case SECTIONS_TEXTURE_NATIVE: {
        n_body = false;
        m__raw_body = m__io->read_bytes(size());
        m__io__raw_body = new kaitai::kstream(m__raw_body);
        m_body = new list_with_header_t(m__io__raw_body, this, m__root);
        break;
    }
    case SECTIONS_FRAME_LIST: {
        n_body = false;
        m__raw_body = m__io->read_bytes(size());
        m__io__raw_body = new kaitai::kstream(m__raw_body);
        m_body = new list_with_header_t(m__io__raw_body, this, m__root);
        break;
    }
    case SECTIONS_GEOMETRY: {
        n_body = false;
        m__raw_body = m__io->read_bytes(size());
        m__io__raw_body = new kaitai::kstream(m__raw_body);
        m_body = new list_with_header_t(m__io__raw_body, this, m__root);
        break;
    }
    default: {
        m__raw_body = m__io->read_bytes(size());
        break;
    }
    }
}

renderware_binary_stream_t::~renderware_binary_stream_t() {
    if (!n_body) {
        delete m__io__raw_body;
        delete m_body;
    }
}

renderware_binary_stream_t::struct_clump_t::struct_clump_t(kaitai::kstream* p__io, renderware_binary_stream_t::list_with_header_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::struct_clump_t::_read() {
    m_num_atomics = m__io->read_u4le();
    n_num_lights = true;
    if (_parent()->version() >= 208896) {
        n_num_lights = false;
        m_num_lights = m__io->read_u4le();
    }
    n_num_cameras = true;
    if (_parent()->version() >= 208896) {
        n_num_cameras = false;
        m_num_cameras = m__io->read_u4le();
    }
}

renderware_binary_stream_t::struct_clump_t::~struct_clump_t() {
    if (!n_num_lights) {
    }
    if (!n_num_cameras) {
    }
}

renderware_binary_stream_t::struct_geometry_t::struct_geometry_t(kaitai::kstream* p__io, renderware_binary_stream_t::list_with_header_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    f_is_textured = false;
    f_is_prelit = false;
    f_is_textured2 = false;
    f_is_native = false;
    _read();
}

void renderware_binary_stream_t::struct_geometry_t::_read() {
    m_format = m__io->read_u4le();
    m_num_triangles = m__io->read_u4le();
    m_num_vertices = m__io->read_u4le();
    m_num_morph_targets = m__io->read_u4le();
    n_surf_prop = true;
    if (_parent()->version() < 212992) {
        n_surf_prop = false;
        m_surf_prop = new surface_properties_t(m__io, this, m__root);
    }
    n_geometry = true;
    if (!(is_native())) {
        n_geometry = false;
        m_geometry = new geometry_non_native_t(m__io, this, m__root);
    }
    int l_morph_targets = num_morph_targets();
    m_morph_targets = new std::vector<morph_target_t*>();
    m_morph_targets->reserve(l_morph_targets);
    for (int i = 0; i < l_morph_targets; i++) {
        m_morph_targets->push_back(new morph_target_t(m__io, this, m__root));
    }
}

renderware_binary_stream_t::struct_geometry_t::~struct_geometry_t() {
    if (!n_surf_prop) {
        delete m_surf_prop;
    }
    if (!n_geometry) {
        delete m_geometry;
    }
    for (std::vector<morph_target_t*>::iterator it = m_morph_targets->begin(); it != m_morph_targets->end(); ++it) {
        delete *it;
    }
    delete m_morph_targets;
}

bool renderware_binary_stream_t::struct_geometry_t::is_textured() {
    if (f_is_textured)
        return m_is_textured;
    m_is_textured = (format() & 4) != 0;
    f_is_textured = true;
    return m_is_textured;
}

bool renderware_binary_stream_t::struct_geometry_t::is_prelit() {
    if (f_is_prelit)
        return m_is_prelit;
    m_is_prelit = (format() & 8) != 0;
    f_is_prelit = true;
    return m_is_prelit;
}

bool renderware_binary_stream_t::struct_geometry_t::is_textured2() {
    if (f_is_textured2)
        return m_is_textured2;
    m_is_textured2 = (format() & 128) != 0;
    f_is_textured2 = true;
    return m_is_textured2;
}

bool renderware_binary_stream_t::struct_geometry_t::is_native() {
    if (f_is_native)
        return m_is_native;
    m_is_native = (format() & 16777216) != 0;
    f_is_native = true;
    return m_is_native;
}

renderware_binary_stream_t::geometry_non_native_t::geometry_non_native_t(kaitai::kstream* p__io, renderware_binary_stream_t::struct_geometry_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::geometry_non_native_t::_read() {
    n_prelit_colors = true;
    if (_parent()->is_prelit()) {
        n_prelit_colors = false;
        int l_prelit_colors = _parent()->num_vertices();
        m_prelit_colors = new std::vector<rgba_t*>();
        m_prelit_colors->reserve(l_prelit_colors);
        for (int i = 0; i < l_prelit_colors; i++) {
            m_prelit_colors->push_back(new rgba_t(m__io, this, m__root));
        }
    }
    n_tex_coords = true;
    if ( ((_parent()->is_textured()) || (_parent()->is_textured2())) ) {
        n_tex_coords = false;
        int l_tex_coords = _parent()->num_vertices();
        m_tex_coords = new std::vector<tex_coord_t*>();
        m_tex_coords->reserve(l_tex_coords);
        for (int i = 0; i < l_tex_coords; i++) {
            m_tex_coords->push_back(new tex_coord_t(m__io, this, m__root));
        }
    }
    int l_triangles = _parent()->num_triangles();
    m_triangles = new std::vector<triangle_t*>();
    m_triangles->reserve(l_triangles);
    for (int i = 0; i < l_triangles; i++) {
        m_triangles->push_back(new triangle_t(m__io, this, m__root));
    }
}

renderware_binary_stream_t::geometry_non_native_t::~geometry_non_native_t() {
    if (!n_prelit_colors) {
        for (std::vector<rgba_t*>::iterator it = m_prelit_colors->begin(); it != m_prelit_colors->end(); ++it) {
            delete *it;
        }
        delete m_prelit_colors;
    }
    if (!n_tex_coords) {
        for (std::vector<tex_coord_t*>::iterator it = m_tex_coords->begin(); it != m_tex_coords->end(); ++it) {
            delete *it;
        }
        delete m_tex_coords;
    }
    for (std::vector<triangle_t*>::iterator it = m_triangles->begin(); it != m_triangles->end(); ++it) {
        delete *it;
    }
    delete m_triangles;
}

renderware_binary_stream_t::struct_geometry_list_t::struct_geometry_list_t(kaitai::kstream* p__io, renderware_binary_stream_t::list_with_header_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::struct_geometry_list_t::_read() {
    m_num_geometries = m__io->read_u4le();
}

renderware_binary_stream_t::struct_geometry_list_t::~struct_geometry_list_t() {
}

renderware_binary_stream_t::rgba_t::rgba_t(kaitai::kstream* p__io, renderware_binary_stream_t::geometry_non_native_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::rgba_t::_read() {
    m_r = m__io->read_u1();
    m_g = m__io->read_u1();
    m_b = m__io->read_u1();
    m_a = m__io->read_u1();
}

renderware_binary_stream_t::rgba_t::~rgba_t() {
}

renderware_binary_stream_t::sphere_t::sphere_t(kaitai::kstream* p__io, renderware_binary_stream_t::morph_target_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::sphere_t::_read() {
    m_x = m__io->read_f4le();
    m_y = m__io->read_f4le();
    m_z = m__io->read_f4le();
    m_radius = m__io->read_f4le();
}

renderware_binary_stream_t::sphere_t::~sphere_t() {
}

renderware_binary_stream_t::morph_target_t::morph_target_t(kaitai::kstream* p__io, renderware_binary_stream_t::struct_geometry_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::morph_target_t::_read() {
    m_bounding_sphere = new sphere_t(m__io, this, m__root);
    m_has_vertices = m__io->read_u4le();
    m_has_normals = m__io->read_u4le();
    n_vertices = true;
    if (has_vertices() != 0) {
        n_vertices = false;
        int l_vertices = _parent()->num_vertices();
        m_vertices = new std::vector<vector_3d_t*>();
        m_vertices->reserve(l_vertices);
        for (int i = 0; i < l_vertices; i++) {
            m_vertices->push_back(new vector_3d_t(m__io, this, m__root));
        }
    }
    n_normals = true;
    if (has_normals() != 0) {
        n_normals = false;
        int l_normals = _parent()->num_vertices();
        m_normals = new std::vector<vector_3d_t*>();
        m_normals->reserve(l_normals);
        for (int i = 0; i < l_normals; i++) {
            m_normals->push_back(new vector_3d_t(m__io, this, m__root));
        }
    }
}

renderware_binary_stream_t::morph_target_t::~morph_target_t() {
    delete m_bounding_sphere;
    if (!n_vertices) {
        for (std::vector<vector_3d_t*>::iterator it = m_vertices->begin(); it != m_vertices->end(); ++it) {
            delete *it;
        }
        delete m_vertices;
    }
    if (!n_normals) {
        for (std::vector<vector_3d_t*>::iterator it = m_normals->begin(); it != m_normals->end(); ++it) {
            delete *it;
        }
        delete m_normals;
    }
}

renderware_binary_stream_t::surface_properties_t::surface_properties_t(kaitai::kstream* p__io, renderware_binary_stream_t::struct_geometry_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::surface_properties_t::_read() {
    m_ambient = m__io->read_f4le();
    m_specular = m__io->read_f4le();
    m_diffuse = m__io->read_f4le();
}

renderware_binary_stream_t::surface_properties_t::~surface_properties_t() {
}

renderware_binary_stream_t::struct_frame_list_t::struct_frame_list_t(kaitai::kstream* p__io, renderware_binary_stream_t::list_with_header_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::struct_frame_list_t::_read() {
    m_num_frames = m__io->read_u4le();
    int l_frames = num_frames();
    m_frames = new std::vector<frame_t*>();
    m_frames->reserve(l_frames);
    for (int i = 0; i < l_frames; i++) {
        m_frames->push_back(new frame_t(m__io, this, m__root));
    }
}

renderware_binary_stream_t::struct_frame_list_t::~struct_frame_list_t() {
    for (std::vector<frame_t*>::iterator it = m_frames->begin(); it != m_frames->end(); ++it) {
        delete *it;
    }
    delete m_frames;
}

renderware_binary_stream_t::matrix_t::matrix_t(kaitai::kstream* p__io, renderware_binary_stream_t::frame_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::matrix_t::_read() {
    int l_entries = 3;
    m_entries = new std::vector<vector_3d_t*>();
    m_entries->reserve(l_entries);
    for (int i = 0; i < l_entries; i++) {
        m_entries->push_back(new vector_3d_t(m__io, this, m__root));
    }
}

renderware_binary_stream_t::matrix_t::~matrix_t() {
    for (std::vector<vector_3d_t*>::iterator it = m_entries->begin(); it != m_entries->end(); ++it) {
        delete *it;
    }
    delete m_entries;
}

renderware_binary_stream_t::vector_3d_t::vector_3d_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::vector_3d_t::_read() {
    m_x = m__io->read_f4le();
    m_y = m__io->read_f4le();
    m_z = m__io->read_f4le();
}

renderware_binary_stream_t::vector_3d_t::~vector_3d_t() {
}

renderware_binary_stream_t::list_with_header_t::list_with_header_t(kaitai::kstream* p__io, renderware_binary_stream_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::list_with_header_t::_read() {
    m_code = m__io->ensure_fixed_contents(std::string("\x01\x00\x00\x00", 4));
    m_header_size = m__io->read_u4le();
    m_version = m__io->read_u4le();
    n_header = true;
    switch (_parent()->code()) {
    case SECTIONS_TEXTURE_DICTIONARY: {
        n_header = false;
        m__raw_header = m__io->read_bytes(header_size());
        m__io__raw_header = new kaitai::kstream(m__raw_header);
        m_header = new struct_texture_dictionary_t(m__io__raw_header, this, m__root);
        break;
    }
    case SECTIONS_GEOMETRY_LIST: {
        n_header = false;
        m__raw_header = m__io->read_bytes(header_size());
        m__io__raw_header = new kaitai::kstream(m__raw_header);
        m_header = new struct_geometry_list_t(m__io__raw_header, this, m__root);
        break;
    }
    case SECTIONS_CLUMP: {
        n_header = false;
        m__raw_header = m__io->read_bytes(header_size());
        m__io__raw_header = new kaitai::kstream(m__raw_header);
        m_header = new struct_clump_t(m__io__raw_header, this, m__root);
        break;
    }
    case SECTIONS_FRAME_LIST: {
        n_header = false;
        m__raw_header = m__io->read_bytes(header_size());
        m__io__raw_header = new kaitai::kstream(m__raw_header);
        m_header = new struct_frame_list_t(m__io__raw_header, this, m__root);
        break;
    }
    case SECTIONS_GEOMETRY: {
        n_header = false;
        m__raw_header = m__io->read_bytes(header_size());
        m__io__raw_header = new kaitai::kstream(m__raw_header);
        m_header = new struct_geometry_t(m__io__raw_header, this, m__root);
        break;
    }
    default: {
        m__raw_header = m__io->read_bytes(header_size());
        break;
    }
    }
    m_entries = new std::vector<renderware_binary_stream_t*>();
    {
        int i = 0;
        while (!m__io->is_eof()) {
            m_entries->push_back(new renderware_binary_stream_t(m__io));
            i++;
        }
    }
}

renderware_binary_stream_t::list_with_header_t::~list_with_header_t() {
    if (!n_header) {
        delete m__io__raw_header;
        delete m_header;
    }
    for (std::vector<renderware_binary_stream_t*>::iterator it = m_entries->begin(); it != m_entries->end(); ++it) {
        delete *it;
    }
    delete m_entries;
}

renderware_binary_stream_t::triangle_t::triangle_t(kaitai::kstream* p__io, renderware_binary_stream_t::geometry_non_native_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::triangle_t::_read() {
    m_vertex2 = m__io->read_u2le();
    m_vertex1 = m__io->read_u2le();
    m_material_id = m__io->read_u2le();
    m_vertex3 = m__io->read_u2le();
}

renderware_binary_stream_t::triangle_t::~triangle_t() {
}

renderware_binary_stream_t::frame_t::frame_t(kaitai::kstream* p__io, renderware_binary_stream_t::struct_frame_list_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::frame_t::_read() {
    m_rotation_matrix = new matrix_t(m__io, this, m__root);
    m_position = new vector_3d_t(m__io, this, m__root);
    m_cur_frame_idx = m__io->read_s4le();
    m_matrix_creation_flags = m__io->read_u4le();
}

renderware_binary_stream_t::frame_t::~frame_t() {
    delete m_rotation_matrix;
    delete m_position;
}

renderware_binary_stream_t::tex_coord_t::tex_coord_t(kaitai::kstream* p__io, renderware_binary_stream_t::geometry_non_native_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::tex_coord_t::_read() {
    m_u = m__io->read_f4le();
    m_v = m__io->read_f4le();
}

renderware_binary_stream_t::tex_coord_t::~tex_coord_t() {
}

renderware_binary_stream_t::struct_texture_dictionary_t::struct_texture_dictionary_t(kaitai::kstream* p__io, renderware_binary_stream_t::list_with_header_t* p__parent, renderware_binary_stream_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void renderware_binary_stream_t::struct_texture_dictionary_t::_read() {
    m_num_textures = m__io->read_u4le();
}

renderware_binary_stream_t::struct_texture_dictionary_t::~struct_texture_dictionary_t() {
}