1. 4FIPS
  2. PHOTOS
  3. VIDEOS
  4. APPS
  5. CODE
  6. FORUMS
  7. ABOUT
#!/usr/bin/env python

# /*
# (c) 2013-14 Filip Stoklas, aka FipS, www.4FipS.com
# THIS CODE IS FREE - LICENSED UNDER THE MIT LICENSE
# */

import os
def resolve_path(rel_path):
    return os.path.abspath(os.path.join(os.path.dirname(__file__), rel_path))

import sys
sys.path.append(resolve_path("../deps"))

from construct import *
from fs_util import bindump

# --- GEOMETRY ---

Geometry = Struct("geometry",
    Struct("header",
        Const(Bytes("magic", 6), "FS-GEO"),
        ULInt8("major_ver"),
        ULInt8("minor_ver"),
        ULInt32("size"),
        Const(Bytes("term", 4), "::::"),
    ),
    Struct("jump_table",
        ULInt32("vertex_format"),
        ULInt32("vertex_data"),
    ),
    Anchor("_anchor_vertex_format"),
    Struct("vertex_format",
        ULInt8("num_elems"),
        Padding(1),
        Array(lambda ctx: ctx.num_elems,
            Struct("elems",
                Enum(ULInt8("type"),
                    float_4 = 0,
                    float_3 = 1,
                    float_2 = 2,
                    float_1 = 3,
                    uint8_4 = 4,
                    uint8_3 = 5,
                    uint8_2 = 6,
                    uint8_1 = 7,
                ),
                Enum(ULInt8("semantics"),
                    position = 0,
                    color = 1,
                    normal = 2,
                    texcoord0 = 3,
                    texcoord1 = 4,
                ),
            ),
        ),
    ),
    Anchor("_anchor_vertex_data"),
    Struct("vertex_data",
        ULInt32("num_bytes"),
        Bytes("bytes", lambda ctx: ctx.num_bytes),
    ),
    Anchor("_anchor_end"),
)

def build_geometry(container):
    geom_data = Geometry.build(container)
    geom = Geometry.parse(geom_data)
    # 2nd pass: set size & offsets:
    geom.header.size = geom._anchor_end
    geom.jump_table.vertex_format = geom._anchor_vertex_format
    geom.jump_table.vertex_data = geom._anchor_vertex_data
    geom_data = Geometry.build(geom)
    return geom_data

def test_geometry():
    geom = build_geometry(Container(
        header = Container(
            magic = "FS-GEO",
            major_ver = 1,
            minor_ver = 0,
            size = 0, # set in the 2nd pass
            term = "::::",
        ),
        jump_table = Container(
            vertex_format = 0, # set in the 2nd pass
            vertex_data = 0, # set in the 2nd pass
        ),
        _anchor_vertex_format = 0, # capture stream pos, set automatically
        vertex_format = Container(
            num_elems = 2,
            elems = [
                Container(type = "float_3", semantics = "position"),
                Container(type = "uint8_4", semantics = "color"),
            ]
        ),
        _anchor_vertex_data = 0, # capture stream pos, set automatically
        vertex_data = Container(
            num_bytes = 6,
            bytes = "ABC...",
        ),
        _anchor_end = 0, # capture stream pos, set automatically
    ))
    print(Geometry.parse(geom))
    print("\n" + bindump(geom))

# --- TEXTURE ---

Texture = Struct("texture",
    Struct("header",
        Const(Bytes("magic", 6), "FS-TEX"),
        ULInt8("major_ver"),
        ULInt8("minor_ver"),
        ULInt32("size"),
        Const(Bytes("term", 4), "::::"),
    ),
    Struct("jump_table",
        ULInt32("texel_format"),
        ULInt32("texel_data"),
    ),
    Anchor("_anchor_texel_format"),
    Struct("texel_format",
        ULInt32("width"),
        ULInt32("height"),
        Enum(ULInt8("format"),
            rgb8 = 0,
            rgba8 = 1,
        ),
    ),
    Anchor("_anchor_texel_data"),
    Struct("texel_data",
        ULInt32("num_bytes"),
        Bytes("bytes", lambda ctx: ctx.num_bytes),
    ),
    Anchor("_anchor_end"),
)

def build_texture(container):
    tex_data = Texture.build(container)
    tex = Texture.parse(tex_data)
    # 2nd pass: set size & offsets:
    tex.header.size = tex._anchor_end
    tex.jump_table.texel_format = tex._anchor_texel_format
    tex.jump_table.texel_data = tex._anchor_texel_data
    tex_data = Texture.build(tex)
    return tex_data

def test_texture():
    tex = build_texture(Container(
        header = Container(
            magic = "FS-TEX",
            major_ver = 1,
            minor_ver = 0,
            size = 0, # set in the 2nd pass
            term = "::::"
        ),
        jump_table = Container(
            texel_format = 0, # set in the 2nd pass
            texel_data = 0, # set in the 2nd pass
        ),
        _anchor_texel_format = 0, # capture stream pos, set automatically
        texel_format = Container(
            width = 2,
            height = 3,
            format = "rgba8"
        ),
        _anchor_texel_data = 0, # capture stream pos, set automatically
        texel_data = Container(
            num_bytes = 6,
            bytes = "ABC...",
        ),
        _anchor_end = 0, # capture stream pos, set automatically
    ))
    print(Texture.parse(tex))
    print("\n" + bindump(tex))

# --- TEST ---

if __name__ == "__main__":
    print("--- TEST BEGIN ---")
    test_geometry()
    test_texture()
    print("--- TEST END ---")