예제 #1
0
def write_typetree(obj: dict,
                   nodes: List[Union[dict, TypeTreeNode]],
                   writer: EndianBinaryWriter = None) -> EndianBinaryWriter:
    """Writes the data of the object via the given typetree of the object into the writer.

        Parameters
        ----------
        obj : dict
            Object to be saved
        nodes : list
            List of nodes/nodes
        writer : EndianBinaryWriter
            Writer of the object to be saved

        Returns
        -------
        EndianBinaryWriter
            The writer that was used to save the data of the given object.
    """
    if not writer:
        writer = EndianBinaryWriter()

    nodes = check_nodes(nodes)

    i = c_uint32(1)
    while i.value < len(nodes):
        value = obj[nodes[i.value].name]
        write_value(value, nodes, writer, i)
        i.value += 1
    return writer
예제 #2
0
def subsound_to_wav(subsound):
    # get sound settings
    length = subsound.get_length(0x00000004)  # TIMEUNIT.PCMBYTES
    channels = subsound.format.channels
    bits = subsound.format.bits
    sample_rate = int(subsound.default_frequency)
    
    # write to buffer
    w = EndianBinaryWriter(endian="<")
    # riff chucnk
    w.write(b"RIFF")
    w.write_int(length + 36)  # sizeof(FmtChunk) + sizeof(RiffChunk) + length
    w.write(b"WAVE")
    # fmt chunck
    w.write(b"fmt ")
    w.write_int(16)  # sizeof(FmtChunk) - sizeof(RiffChunk)
    w.write_short(1)
    w.write_short(channels)
    w.write_int(sample_rate)
    w.write_int(sample_rate * channels * bits // 8)
    w.write_short(channels * bits // 8)
    w.write_short(bits)
    # data chunck
    w.write(b"data")
    w.write_int(length)
    # data
    lock = subsound.lock(0, length)
    for ptr, length in lock:
        ptr_data = string_at(ptr, length.value)
        w.write(ptr_data)
    subsound.unlock(*lock)
    return w.bytes
예제 #3
0
def write_value(value: Any, nodes: List[TypeTreeNode],
                writer: EndianBinaryWriter, i: c_uint32):
    node = nodes[i.value]
    typ = node.type
    align = (node.meta_flag & 0x4000) != 0

    if typ == "SInt8":
        writer.write_byte(value)
    elif typ in ["UInt8", "char"]:
        writer.write_u_byte(value)
    elif typ in ["short", "SInt16"]:
        writer.write_short(value)
    elif typ in ["UInt16", "unsigned short"]:
        writer.write_u_short(value)
    elif typ in ["int", "SInt32"]:
        writer.write_int(value)
    elif typ in ["UInt32", "unsigned int", "Type*"]:
        writer.write_u_int(value)
    elif typ in ["long long", "SInt64"]:
        writer.write_long(value)
    elif typ in ["UInt64", "unsigned long long", "FileSize"]:
        writer.write_u_long(value)
    elif typ == "float":
        writer.write_float(value)
    elif typ == "double":
        writer.write_double(value)
    elif typ == "bool":
        writer.write_boolean(value)
    elif typ == "string":
        writer.write_aligned_string(value)
        i.value += 3  # Array, Size, Data(typ)
    elif typ == "map":
        if (nodes[i.value + 1].meta_flag & 0x4000) != 0:
            align = True
        map_ = get_nodes(nodes, i.value)
        i.value += len(map_) - 1
        first = get_nodes(map_, 4)
        second = get_nodes(map_, 4 + len(first))
        # size
        writer.write_int(len(value))
        # data
        for key, val in value:
            write_value(key, first, writer, c_uint32(0))
            write_value(val, second, writer, c_uint32(0))

    elif typ == "TypelessData":
        writer.write_int(len(value))
        writer.write_bytes(value)
        i.value += 2  # Size == int, Data(typ) == char/uint8
    else:
        # Vector
        if i.value < len(nodes) - 1 and nodes[i.value + 1].type == "Array":
            if (nodes[i.value + 1].meta_flag & 0x4000) != 0:
                align = True
            vector = get_nodes(nodes, i.value)
            i.value += len(vector) - 1
            writer.write_int(len(value))
            for val in value:
                write_value(val, vector, writer, c_uint32(3))
        else:  # Class
            clz = get_nodes(nodes, i.value)
            i.value += len(clz) - 1
            j = c_uint32(1)
            while j.value < len(clz):
                val = value[clz[j.value].name]
                write_value(val, clz, writer, j)
                j.value += 1

    if align:
        writer.align_stream()