#
# $Id: alcurugeom.py 539 2006-07-19 17:17:06Z Robert The Rebuilder $
#
#    Copyright (C) 2005-2006  Alcugs pyprp Project Team
#    See the file AUTHORS for more info about the team
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#    Please see the file COPYING for the full license.
#    Please see the file DISCLAIMER for more details, before doing nothing.
#

# Help library

try:
    import Blender
    try:
        from Blender import NMesh
    except Exception, detail:
        print detail
except ImportError:
    pass

import struct, array, StringIO
from alc_AbsClasses import *

def FVFSize(flags):
    size = ((flags&0xF) + 2 * 12 + (flags&0x30) / 4 + (flags&0x40) / 16)
    return size

#TODO: hsMatrix34

class hsMatrix44: #TODO: Rename to hsMatrix44
    def __init__(self):
        self.matrix=[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
        self.update()
    
    
    def read(self,buf):
        for i in range(4):
            for j in range(4):
                self.matrix[i][j] = buf.ReadFloat()
        self.update()
    
    
    def write(self,buf):
        for i in range(4):
            for e in range(4):
                buf.WriteFloat(self.matrix[i][e])
    
    
    def update(self):
        a=[self.matrix[0][0],self.matrix[0][1],self.matrix[0][2],self.matrix[0][3]]
        b=[self.matrix[1][0],self.matrix[1][1],self.matrix[1][2],self.matrix[1][3]]
        c=[self.matrix[2][0],self.matrix[2][1],self.matrix[2][2],self.matrix[2][3]]
        d=[self.matrix[3][0],self.matrix[3][1],self.matrix[3][2],self.matrix[3][3]]
        try:
            self.vmatrix=Blender.Mathutils.Matrix(a,b,c,d)
        except NameError:
            pass
    
    
    def get(self):
        self.update()
        return(self.vmatrix)
    
    
    def X(self):
        return self.matrix[0][3]
    
    
    def Y(self):
        return self.matrix[1][3]
    
    
    def Z(self):
        return self.matrix[2][3]
    
    
    def set(self,matrix):
        for j in range(4):
            for k in range(4):
                self.matrix[j][k]=matrix[j][k]
        self.update()
    
    
    def __str__(self):
        out="{\n"
        for j in range(4):
            out = out + "["
            for k in range(4):
                val = "%10.2f" %self.matrix[j][k]
                out = out + val + ","
            out = out + "]\n"
        out = out + "}"
        return out
    
    
    def identity(self):
        self.matrix=[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
        self.update()
    
    
    def transformvector(self,v):
        m=self.matrix
        x, y, z = v
        x = m[0][0]*self.x + m[0][1]*self.y + m[0][2]*self.z + m[0][3]
        y = m[1][0]*self.x + m[1][1]*self.y + m[1][2]*self.z + m[1][3]
        z = m[2][0]*self.x + m[2][1]*self.y + m[2][2]*self.z + m[2][3]
        return [x,y,z]


class RGBA:
    def __init__(self,r=255,g=255,b=255,a=255,type=0):
        self.r=r
        self.g=g
        self.b=b
        self.a=a
        self.type=type
        #type 0 -> U32 format
        #type 1 -> 4 floats
    
    
    def __repr__(self):
        return (self.r,self.g,self.b,self.a)
    
    
    def __str__(self):
        if self.type==0:
            return "%03i,%03i,%03i,%03i" %(self.r,self.g,self.b,self.a)
        else:
            return "%10.2f %10.2f %10.2f %10.2f" %(self.r,self.g,self.b,self.a)
    
    
    def set(self,r=255,g=255,b=255,a=255):
        self.r=r
        self.g=g
        self.b=b
        self.a=a
    
    
    def uset(self,r=255,g=255,b=255,a=255):
        self.r=r
        self.g=g
        self.b=b
        self.a=a
    
    
    def get(self):
        return self.__repr__()
    
    
    def uget(self):
        return (self.r,self.g,self.b,self.a)
    
    
    def read(self,buf):
        self.r = buf.ReadFloat()
        self.g = buf.ReadFloat()
        self.b = buf.ReadFloat()
        self.a = buf.ReadFloat()
    
    
    def write(self,buf):
        buf.WriteFloat(self.r)
        buf.WriteFloat(self.g)
        buf.WriteFloat(self.b)
        buf.WriteFloat(self.a)


class Vertex:
    def __init__(self,x=0,y=0,z=0):
        self.x=x
        self.y=y
        self.z=z
        #normals
        self.nx=0
        self.ny=0
        self.nz=0
        #Base vertex (x=px + offset/1024.0), so ((x-px)*1024 = offset)
        ##self.base=[0,0,0]
        ##self.off=[0,0,0]
        #weights - bone influence (0-1)
        self.blend=[]
        ###self.blendbase=[]
        ###self.blendoff=[]
        #bones - link to bone
        self.bones=[]
        #color
        self.color=RGBA()
        #Texture coordinates
        self.tex=[]
        ###self.texbase=[]
        ###self.texoff=[]
    
    
    def isequal(self,v):
        return(self.x==v.x and self.y==v.y and self.z==v.z)
    
    
    def dump(self):
        #if len(self.blend)==0:
            #return
        print "coords:" + str(self),
        print "nx:%10.3f,%10.3f,%10.3f" %(self.nx,self.ny,self.nz)
##        print "base:",
##        for i in self.base:
##            print "%10.3f" %i,
##        print "off:",
##        for i in self.off:
##            print "%04i" %i,
##        print ""
        print "blend:",
        for i in self.blend:
            print "%10.3f" %i,
##        for i in self.blendbase:
##            print "%10.3f" %i,
##        for i in self.blendoff:
##            print "%04i" %i,
        print ""
        print "bones:",
        for i in self.bones:
            print "%04X" %i,
##        print "color:",
##        print self.color,
##        print ""
        print "tex:",
        for e in self.tex:
            print "[",
            for i in e:
                print "%10.3f" %i,
            print "],"
##        for e in self.texbase:
##            print "[",
##            for i in e:
##                print "%10.3f" %i,
##            print "]",
##        for e in self.texoff:
##            print "[",
##            for i in e:
##                print "%04i" %i,
##            print "],"
        print ""
  
    
    def __repr__(self):
        return (self.x,self.y,self.z)
    
    
    def __str__(self):
        return "%10.3f,%10.3f,%10.3f" % (self.x,self.y,self.z)
    
    
    def read(self,buf):
        self.x = buf.ReadFloat()
        self.y = buf.ReadFloat()
        self.z = buf.ReadFloat()
    
    
    def write(self,buf):
        buf.WriteFloat(self.x)
        buf.WriteFloat(self.y)
        buf.WriteFloat(self.z)
    
    
    def X(self):
        return self.x
    
    
    def Y(self):
        return self.y
    
    
    def Z(self):
        return self.z
    
    
    def transform(self,matrix):
        m=matrix.matrix
        x = m[0][0]*self.x + m[0][1]*self.y + m[0][2]*self.z + m[0][3]
        y = m[1][0]*self.x + m[1][1]*self.y + m[1][2]*self.z + m[1][3]
        z = m[2][0]*self.x + m[2][1]*self.y + m[2][2]*self.z + m[2][3]
        self.x=x
        self.y=y
        self.z=z


class Vertex4:
    def __init__(self):
        self.f1 = 0
        self.f2 = 0
        self.f3 = 0
        self.f4 = 0
    
    
    def read(self,buf):
        self.f1 = buf.ReadFloat()
        self.f2 = buf.ReadFloat()
        self.f3 = buf.ReadFloat()
        self.f4 = buf.ReadFloat()
    
    
    def write(self,buf):
        buf.WriteFloat(self.f1)
        buf.WriteFloat(self.f2)
        buf.WriteFloat(self.f3)
        buf.WriteFloat(self.f4)


class hsBounds:
    def __init__(self):
        self.mode = 0 # formerly known as self.i1
    
    
    def read(self,buf):
        self.mode = buf.Read32()
    
    
    def write(self,buf):
        buf.Write32(self.mode)


class hsBounds3(hsBounds):
    def __init__(self):
        hsBounds.__init__(self)
        self.min = Vertex()
        self.max = Vertex()
    
    
    def read(self,buf):
        hsBounds.read(self,buf)
        self.min.read(buf)
        self.max.read(buf)
    
    
    def write(self,buf):
        hsBounds.write(self,buf)
        self.min.write(buf)
        self.max.write(buf)


class hsBounds3Ext(hsBounds3):
    def __init__(self):
        hsBounds3.__init__(self)
        self.flags = 0
        # 0x01 - on axis, else off-axis
        # 0x02 - NPI (seen on avatar bones spans)
        # box corners?
        # 0x100000 -
        # 0x200000 -
        # 0x400000 -
        self.corner = hsScalarTriple() # formerly known as self.ST34
        self.diff = [] # formerly known as self.ST40
        self.f64 = []
        for i in range(3):
            self.diff.append(hsScalarTriple())
            floatList = []
            floatList.append(0.0)
            floatList.append(0.0)
            self.f64.append(floatList)
    
    
    def __str__(self):
        return "f:%08X,min:%s,max:%s,corner:%s,diff:[(%s),(%s),(%s)]" %\
               (self.flags,str(self.min),str(self.max),str(self.corner),\
                str(self.diff[0]),str(self.diff[1]),str(self.diff[2]))

    
    def read(self,buf):
        self.flags = buf.Read32()
        if self.flags not in (0x00,0x01,0x03,0x100000,0x200000,0x300000,0x400000):
            raise RuntimeError, "BBox flag %08X" % self.flags
        hsBounds3.read(self,buf)
        assert(self.mode==0x00)
        if not(self.flags & 0x01):
            self.corner.read(buf)
            for i in range(3):
                self.diff[i].read(buf)
                self.f64[i][0] = buf.ReadFloat()
                self.f64[i][1] = buf.ReadFloat()
    
    
    def write(self,buf):
        buf.Write32(self.flags)
        hsBounds3.write(self,buf)
        if not(self.flags & 0x01):
            self.corner.write(buf)
            for i in range(3):
                self.diff[i].write(buf)
                buf.WriteFloat(self.f64[i][0])
                buf.WriteFloat(self.f64[i][1])


class plGBufferTriangle:
    def __init__(self):
        self.s1 = 0
        self.s2 = 0
        self.s3 = 0
        self.s4 = 0
        self.scalar = hsScalarTriple()
    
    
    def read(self,buf):
        self.s1 = buf.Read16()
        self.s2 = buf.Read16()
        self.s3 = buf.Read16()
        self.s4 = buf.Read16()
        self.scalar.read(buf)
    
    
    def write(self,buf):
        buf.Write16(self.s1)
        buf.Write16(self.s2)
        buf.Write16(self.s3)
        buf.Write16(self.s4)
        self.scalar.write(buf)


class plFogEnvironment:
    def __init__(self):
        self.c10 = 0 #CHAR
        self.f14 = 0 #FLOAT
        self.f18 = 0 #FLOAT
        self.f1C = 0 #FLOAT
        self.f20 = 0 #FLOAT
        self.f24 = 0 #FLOAT
        self.f28 = 0 #FLOAT
        self.f2C = 0 #FLOAT
    
    
    def read(self,buf):
        self.c10 = buf.ReadByte()
        self.f14 = buf.ReadFloat()
        self.f18 = buf.ReadFloat()
        self.f1C = buf.ReadFloat()
        self.f20 = buf.ReadFloat()
        self.f24 = buf.ReadFloat()
        self.f28 = buf.ReadFloat()
        self.f2C = buf.ReadFloat()
    
    
    def write(self,buf):
        buf.WriteByte(self.c10)
        buf.WriteFloat(self.f14)
        buf.WriteFloat(self.f18)
        buf.WriteFloat(self.f1C)
        buf.WriteFloat(self.f20)
        buf.WriteFloat(self.f24)
        buf.WriteFloat(self.f28)
        buf.WriteFloat(self.f2C)


class plSpan:
    def __init__(self):
        self.subDrawableType = 0 #WORD
        self.subMaterialType = 0 #DWORD
        self.L2WMatrix = hsMatrix44() #hsMatrix444
        self.W2LMatrix = hsMatrix44() #hsMatrix444
        self.blendflag = 0 #CHAR, but read as int; formerly knowns as self.c98
        self.blendindex = 0 #DWORD; formerly known as self.i94
        self.s9A = 0 #WORD
        self.s9C = 0 #WORD
        self.s9E = 0 #WORD
        self.flags = 0 #DWORD
        self.bounds1 = hsBounds3Ext() #hsBounds3Ext
        self.bounds2 = hsBounds3Ext() #hsBounds3Ext
        self.fog = UruObjectRef() #plFogEnvironment //See plDrawableSpans
        self.f1A8 = 0 #FLOAT
        self.f1AC = 0 #FLOAT
        self.f1B0 = 0 #FLOAT
        self.lights1 = hsTArray([0x55,0x56,0x57,0x6A]) #plLightInfo refs
        self.lights2 = hsTArray([0x55,0x56,0x57,0x6A]) #plLightInfo refs
    
    
    def read(self,buf):
        self.subDrawableType = buf.Read32()
        self.subMaterialType = buf.Read32()
        self.L2WMatrix.read(buf)
        self.W2LMatrix.read(buf)
        self.flags = buf.Read32()
        #shadow/light flags
        # 0x80000000 - *unused* *no apparent effect*
        # 0x40000000 - *unused* *no apparent effect*
        # 0x20000000 - *unused* *no apparent effect*
        # 0x10000000 - *unused* *no apparent effect*
        # 0x08000000 - *unused* *no apparent effect*
        # 0x04000000 - *unused* *no apparent effect*
        # 0x02000000 - *unused* *no apparent effect*
        # 0x01000000 - ???? *no apparent effect*
        # 0x00800000 - *unused* *no apparent effect*
        # 0x00400000 - *unused* *no apparent effect*
        # 0x00200000 - *unused* *no apparent effect*
        # 0x00100000 - ??? *no apparent effect*
        # 0x00080000 - ??? - no shadows     -- (water?/ripple effect?)
        # 0x00040000 - *unused* - no shadows (also some no apparent effects on other flags may be no shadows also)
        # 0x00020000 - *unused* - no shadows
        # 0x00010000 - animated? *no apparent effect*  -- (water?/ripple effect?)
        # 0x00008000 - *unused* *no apparent effect*
        # 0x00004000 - *unused* - FX
        # 0x00002000 - *unused* - FX
        # 0x00001000 - *unused* - FX
        # 0x00000800 - *unused* - FX flag - weird lighting effects
        # 0x00000400 - vertex alpha? <- global light?
        # 0x00000200 - *unused* - everything is dark, no lighting on several objects
        # 0x00000100 - ?? (not the spot light flag; unknown)
        # 0x00000080 - use lighting info - seen 0x56 OmniLightInfo, 0x55 DirectionalLightInfo, 0x57 SpotLightInfo
        # 0x00000040 - ?? *no apparent effect* - no animation perhaps -- (water?/ripple effect?)
        # 0x00000020 - ignore vertex colors - if not set vertex colors are blended with the material.
        # 0x00000010 - additional float - ?? *no apparent effect* -- (water?/ripple effect?) (float=radius?)
        # 0x00000008 - *unused* *no apparent effect*
        # 0x00000004 - *unused* *crash*
        # 0x00000002 - *unused* *no apparent effect*
        # 0x00000001 - alpha/vis (some objects are invisible) use alpha info, or make it invisible
        self.bounds1.read(buf)
        self.bounds2.read(buf)
        self.blendflag = buf.Read32() #Take it up with PW :P
        self.blendindex = buf.Read32()
        self.s9A = buf.Read16()
        self.s9C = buf.Read16()
        self.s9E = buf.Read16()
        #sanity check; are these water/ripple flags?
        if self.s9A not in [0x00,0x0102]:
            raise RuntimeError, "s9A %04X" %self.s9A
        if self.s9C not in [0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0F,\
                             0x13,0x15,0x16,0x1A,0x20,0x23,0x24,0x2D,0x27,0x2E,0x2F,0x3F,0x45,0x47,0x48]:
            raise RuntimeError, "s9C %08X" %self.s9C
        if self.s9E not in [0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0F,\
                             0x15,0x16,0x1A,0x20,0x23,0x24,0x27,0x29,0x2D,0x2E,0x2F,0x3F,0x45,0x47,0x48]:
            raise RuntimeError, "s9E %08X" %self.s9E
        if self.blendflag==0:
            assert(self.s9C==0)
            assert(self.s9E==0)
        if self.blendflag==2:
            assert(self.s9C==0)
            assert(self.s9E==0)
        # end check
        self.f1A8 = buf.ReadFloat()
        self.f1AC = buf.ReadFloat()
        if (self.flags&0x10):
            self.f1B0 = buf.ReadFloat()
    
    
    def write(self,buf):
        # RTR: Temporary 
        self.flags = self.flags & ~0x080 #0x55,0x56,0x57
        self.flags = self.flags & ~0x100 #Who knows?
        if len(self.lights1)!=0:
            self.flags = self.flags | 0x080
        if len(self.lights2)!=0:
            self.flags = self.flags | 0x100
        # RTR: end temporary
        buf.Write32(self.subDrawableType)
        buf.Write32(self.subMaterialType)
        self.L2WMatrix.write(buf)
        self.W2LMatrix.write(buf)
        buf.Write32(self.flags)
        self.bounds1.write(buf)
        self.bounds2.write(buf)
        buf.Write32(self.blendflag)
        buf.Write32(self.blendindex)
        buf.Write16(self.s9A)
        buf.Write16(self.s9C)
        buf.Write16(self.s9E)
        buf.WriteFloat(self.f1A8)
        buf.WriteFloat(self.f1AC)
        if (self.flags&0x10):
            buf.WriteFloat("f",self.f1B0)


class plVertexSpan(plSpan):
    def __init__(self):
        plSpan.__init__(self)
        self.vdbidx = 0 #DWORD; formerly known as self.i230
        self.i234 = 0 #DWORD
        self.i238 = 0 #DWORD
        self.vertexStart = 0 #DWORD; formerly known as self.i23C
        self.vertexStart2 = 0 #DWORD; formerly known as self.i240
        self.vertexCount = 0 #DWORD; formerly known as self.i244
    
    
    def read(self,buf):
        plSpan.read(self,buf)
        self.vdbidx = buf.Read32()
        self.i234 = buf.Read32()
        self.i238 = buf.Read32()
        self.vertexStart = buf.Read32()
        self.vertexStart2 = buf.Read32()
        self.vertexCount = buf.Read32()
        #sanity check
        assert(self.i234==0)
        assert(self.i238==0)
        assert(self.vertexStart==self.vertexStart2)
    
    
    def write(self,buf):
        plSpan.write(self,buf)
        buf.Write32(self.vdbidx)
        buf.Write32(self.i234)
        buf.Write32(self.i238)
        buf.Write32(self.vertexStart)
        buf.Write32(self.vertexStart2)
        buf.Write32(self.vertexCount)


class plIcicle(plVertexSpan):
    def __init__(self):
        plVertexSpan.__init__(self)
        self.surfaceIdx = 0 #DWORD; formerly known as self.i248
        self.idxStart = 0 #DWORD; formerly known as self.i24C
        self.triCount = 0 #DOWRD
        #self.i254 = 0 #DWORD - not used
        self.triangles = [] #*plGBufferTriangle
    
    def read(self,buf):
        plVertexSpan.read(self,buf)
        self.surfaceIdx = buf.Read32()
        self.idxStart = buf.Read32()
        self.triCount = buf.Read32()
        if (self.flags & 0x04):
            for i in range(self.triCount / 3):
                self.triangles[i] = plGBufferTriangle()
                self.triangles[i].read(buf)
    
    
    def write(self,buf):
        plVertexSpan.write(self,buf)
        buf.Write32(self.surfaceIdx)
        buf.Write32(self.idxStart)
        buf.Write32(self.triCount)
        if (self.flags & 0x04):
            for bufferTriangle in self.triangles.vector:
                bufferTriangle.write(buf)


class plGeometrySpan:
    def __init__(self):
        self.m4 = hsMatrix44()
        self.m48 = hsMatrix44()
        self.BE8C = hsBounds3Ext()
        self.i190 = 0 #DWORD
        self.c194 = 0 #CHAR
        self.s196 = 0 #WORD
        self.s198 = 0 #WORD
        self.i19C = 0 #DWORD
        self.f1A0 = 0 #FLOAT
        self.f1A4 = 0 #FLOAT
        self.f1A8 = 0 #FLOAT
        self.c1AC = 0 #CHAR
        self.i1B0 = 0 #DWORD
        self.i1B4 = 0 #DWORD
        self.i1B8 = 0 #DWORD
        self.i1BC = 0 #DWORD
        self.ac1C4 = [] #CHAR
        self.as1C8 = [] #WORD
        self.V1D0 = [] #Vertex4
        self.V1D4 = [] #Vertex4
        self.ai1D8 = [] #DWORD
        self.ai1DC = [] #DWORD
        self.i1E4 = 0 #DWORD
        self.m1F0 = hsMatrix44()
        self.m234 = hsMatrix44()
        self.trash = 0
    
    
    def read(self,buf):
        self.m4.read(buf)
        self.m48.read(buf)
        self.BE8C.read(buf)
        self.m234.read(buf)
        self.m1F0.read(buf)
        self.i190 = buf.Read32()
        self.c194 = buf.ReadByte()
        self.s196 = buf.Read16()
        self.s198 = buf.Read16()
        self.il9C = buf.Read16() #Take it up with PW
        self.f1A0 = buf.ReadFloat()
        self.f1A4 = buf.ReadFloat()
        self.c1AC = buf.ReadByte()
        self.i1B0 = buf.Read32()
        self.i1B4 = buf.Read32()
        self.i1B8 = buf.Read32()
        self.i1BC = buf.Read32()
        if (i1B0&0x800):
            self.f1A8 = buf.ReadFloat()
        #I am not too certain about this one...
        #self.ac1C4 = buf.read(self.i1B4*FVFSize(self.c1AC))
        for i in range(self.i1B4*FVFSize(self.c1AC)):
            self.ac1C4[i].append(buf.read(1)) #THIS IS CORRECT!!! DO NOT CHANGE!!!
        for i in range(self.i1B4):
            self.V1D0[i] = Vertex4()
            self.V1D0[i].read(buf)
            self.V1D4[i] = Vertex4()
            self.V1D4[i].read(buf)
        for i in range(self.i1B4):
            self.ai1D8.append(buf.Read32())
        for i in range(self.i1B4):
            self.ai1DC.append(buf.Read32())
        for i in range(self.i1B8):
            self.as1C8.append(buf.Read16())
        self.i1E4 = buf.Read32()
        if(self.i1E4):
            self.trash = buf.Read32() #Garbage
    
    
    def write(self,buf):
        self.m4.write(buf)
        self.m48.write(buf)
        self.BE8C.write(buf)
        self.m234.write(buf)
        self.m1F0.write(buf)
        buf.Write32(self.i190)
        buf.WriteByte(self.c194)
        buf.Write16(self.s196)
        buf.Write16(self.s198)
        buf.Write16(self.s19C)
        buf.WriteFloat(self.f1A0)
        buf.WriteFloat(self.f1A4)
        buf.WriteFloat(self.f1AC)
        buf.Write32(self.i1B0)
        buf.Write32(self.i1B4)
        buf.Write32(self.i1B8)
        buf.Write32(self.i1BC)
        if (i1B0&0x800):
            buf.WriteFloat(self.f1A8)
        #Oh crap...
        for i in range(self.i1B4*FVFSize(self.c1AC)):
            buf.write(self.ac1C4[i])
        for i in range(self.i1B4):
            self.V1D0[i] = Vertex4()
            self.V1D0[i].write(buf)
            self.V1D4[i] = Vertex4()
            self.V1D4[i].write(buf)
        for i in range(self.i1B4):
            buf.Write32(self.ai1D8[i])
        for i in range(self.i1B4):
            buf.Write32(self.ai1DC[i])
        for i in range(self.i1B8):
            buf.Write16(self.as1C8[i])
        buf.Write32(self.i1E4)
        if (self.i1E4):
            buf.Write32(self.trash) #Garbage...