Example #1
0
        private void Mod_LoadAreas(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List <SDArea>        DArea = new List <SDArea>();
            List <CModel.SMArea> MArea = new List <CModel.SMArea>();

            br.BaseStream.Seek(header.lumps[LUMP_AREAS].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_AREAS].fileofs + header.lumps[LUMP_AREAS].filelen))
            {
                SDArea _DArea;

                _DArea.numareaportals  = br.ReadInt32();
                _DArea.firstareaportal = br.ReadInt32();

                DArea.Add(_DArea);
            }

            for (int i = 0; i < DArea.Count; i++)
            {
                CModel.SMArea _MArea;

                _MArea.numareaportals  = DArea[i].numareaportals;
                _MArea.firstareaportal = DArea[i].firstareaportal;
                _MArea.floodvalid      = 0;
                _MArea.floodnum        = 0;

                MArea.Add(_MArea);
            }

            _SModel.numareas = MArea.Count;
            _SModel.areas    = MArea.ToArray();
        }
Example #2
0
        private void Mod_LoadVisibility(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            int pos_visdata = 0;

            br.BaseStream.Seek(header.lumps[LUMP_VISIBILITY].fileofs, System.IO.SeekOrigin.Begin);

            if (header.lumps[LUMP_VISIBILITY].filelen == 0)
            {
                _SModel.vis.numclusters = 0;
                _SModel.vis.bitofs      = null;
                _SModel.visdata         = null;

                return;
            }

            _SModel.vis.numclusters = br.ReadInt32();
            _SModel.vis.bitofs      = new int[_SModel.vis.numclusters, 2];

            for (int i = 0; i < _SModel.vis.numclusters; i++)
            {
                _SModel.vis.bitofs[i, DVIS_PVS] = br.ReadInt32();
                _SModel.vis.bitofs[i, DVIS_PHS] = br.ReadInt32();

                // decrement the offsets, because the data is stored in a seperate byte array
                _SModel.vis.bitofs[i, DVIS_PVS] -= 4 + ((4 * _SModel.vis.numclusters * 2));
                _SModel.vis.bitofs[i, DVIS_PHS] -= 4 + ((4 * _SModel.vis.numclusters * 2));
            }

            _SModel.visdata = new byte[(header.lumps[LUMP_VISIBILITY].fileofs + header.lumps[LUMP_VISIBILITY].filelen) - br.BaseStream.Position];
            while (br.BaseStream.Position < (header.lumps[LUMP_VISIBILITY].fileofs + header.lumps[LUMP_VISIBILITY].filelen))
            {
                _SModel.visdata[pos_visdata++] = br.ReadByte();
            }
        }
Example #3
0
        private void Mod_LoadAreaPortals(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List <SDAreaPortal>        DAreaPortal = new List <SDAreaPortal>();
            List <CModel.SMAreaPortal> MAreaPortal = new List <CModel.SMAreaPortal>();

            br.BaseStream.Seek(header.lumps[LUMP_AREAPORTALS].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_AREAPORTALS].fileofs + header.lumps[LUMP_AREAPORTALS].filelen))
            {
                SDAreaPortal _DAreaPortal;

                _DAreaPortal.portalnum = br.ReadInt32();
                _DAreaPortal.otherarea = br.ReadInt32();

                DAreaPortal.Add(_DAreaPortal);
            }

            for (int i = 0; i < DAreaPortal.Count; i++)
            {
                CModel.SMAreaPortal _MAreaPortal;

                _MAreaPortal.portalnum = DAreaPortal[i].portalnum;
                _MAreaPortal.otherarea = DAreaPortal[i].otherarea;

                MAreaPortal.Add(_MAreaPortal);
            }

            _SModel.numareaportals = MAreaPortal.Count;
            _SModel.areaportals    = MAreaPortal.ToArray();
        }
Example #4
0
        private void Mod_LoadLighting(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            if (header.lumps[LUMP_LIGHTING].filelen == 0)
            {
                _SModel.lightdata = null;
                return;
            }

            br.BaseStream.Seek(header.lumps[LUMP_LIGHTING].fileofs, System.IO.SeekOrigin.Begin);
            _SModel.lightdata = br.ReadBytes(header.lumps[LUMP_LIGHTING].filelen);
        }
Example #5
0
        private void Mod_LoadSurfedges(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List <int> DSurfEdge = new List <int>();

            br.BaseStream.Seek(header.lumps[LUMP_SURFEDGES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_SURFEDGES].fileofs + header.lumps[LUMP_SURFEDGES].filelen))
            {
                DSurfEdge.Add(br.ReadInt32());
            }

            _SModel.numsurfedges = DSurfEdge.Count;
            _SModel.surfedges    = DSurfEdge.ToArray();
        }
Example #6
0
        private void Mod_LoadPlanes(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            int bits;

            float[] normal = new float[3];
            List <CShared.SCPlane> CPlane = new List <CShared.SCPlane>();

            br.BaseStream.Seek(header.lumps[LUMP_PLANES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_PLANES].fileofs + header.lumps[LUMP_PLANES].filelen))
            {
                CShared.SCPlane _CPlane;

                normal[0] = 0.0f;
                normal[1] = 0.0f;
                normal[2] = 0.0f;

                bits = 0;

                for (int j = 0; j < 3; j++)
                {
                    normal[j] = br.ReadSingle();

                    if (normal[j] < 0)
                    {
                        bits |= 1 << j;
                    }
                }

                _CPlane.normal.X = normal[0];
                _CPlane.normal.Y = normal[1];
                _CPlane.normal.Z = normal[2];

                _CPlane.dist     = br.ReadSingle();
                _CPlane.type     = (byte)br.ReadInt32();
                _CPlane.signbits = (byte)bits;

                _CPlane.pad = new byte[2];

                CPlane.Add(_CPlane);
            }

            _SModel.planes    = CPlane.ToArray();
            _SModel.numplanes = _SModel.planes.Length;
        }
Example #7
0
        private void Mod_LoadVertexes(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List <CModel.SMVertex> MVertex = new List <CModel.SMVertex>();

            br.BaseStream.Seek(header.lumps[LUMP_VERTEXES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_VERTEXES].fileofs + header.lumps[LUMP_VERTEXES].filelen))
            {
                CModel.SMVertex _MVertex;

                _MVertex.Position.X = br.ReadSingle();
                _MVertex.Position.Y = br.ReadSingle();
                _MVertex.Position.Z = br.ReadSingle();

                MVertex.Add(_MVertex);
            }

            _SModel.numvertexes = MVertex.Count;
            _SModel.vertexes    = MVertex.ToArray();
        }
Example #8
0
        private void Mod_LoadMarksurfaces(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List <int> MarkSurface = new List <int>();

            br.BaseStream.Seek(header.lumps[LUMP_LEAFFACES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_LEAFFACES].fileofs + header.lumps[LUMP_LEAFFACES].filelen))
            {
                int msurf = br.ReadInt16();

                if (msurf < 0 || msurf >= _SModel.numsurfaces)
                {
                    CMain.Error(CMain.EErrorParm.ERR_FATAL, "Mod_ParseMarksurfaces: bad surface number");
                }

                MarkSurface.Add(msurf);
            }

            _SModel.nummarksurfaces = MarkSurface.Count;
            _SModel.marksurfaces    = MarkSurface.ToArray();
        }
Example #9
0
        private void Mod_LoadEntityString(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            if (header.lumps[LUMP_ENTITIES].filelen > MAX_MAP_ENTSTRING)
            {
                // entity string exceeds maximum
                _SModel.map_entitystring = null;
                return;
            }

            br.BaseStream.Seek(header.lumps[LUMP_ENTITIES].fileofs, System.IO.SeekOrigin.Begin);
            if (br.BaseStream.Position < (header.lumps[LUMP_ENTITIES].fileofs + header.lumps[LUMP_ENTITIES].filelen))
            {
                _SModel.map_entitystring = CShared.Com_ToString(br.ReadChars(header.lumps[LUMP_ENTITIES].filelen));
                _SModel.map_entitystring = _SModel.map_entitystring.Replace("\r", "").Replace("\n", "\r\n");
            }
            else
            {
                _SModel.map_entitystring = null;
            }
        }
Example #10
0
        private void Mod_LoadEdges(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List <CModel.SMEdge> MEdge = new List <CModel.SMEdge>();

            br.BaseStream.Seek(header.lumps[LUMP_EDGES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_EDGES].fileofs + header.lumps[LUMP_EDGES].filelen))
            {
                CModel.SMEdge _MEdge;

                _MEdge.v    = new ushort[2];
                _MEdge.v[0] = br.ReadUInt16();
                _MEdge.v[1] = br.ReadUInt16();

                _MEdge.cachededgeoffset = 0;

                MEdge.Add(_MEdge);
            }

            _SModel.numedges = MEdge.Count;
            _SModel.edges    = MEdge.ToArray();
        }
Example #11
0
        private void Mod_LoadFaces(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List<SDFace> DFace = new List<SDFace>();
            List<CModel.SMSurface> MSurface = new List<CModel.SMSurface>();

            br.BaseStream.Seek(header.lumps[LUMP_FACES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_FACES].fileofs + header.lumps[LUMP_FACES].filelen))
            {
                SDFace _DFace;

                _DFace.planenum = br.ReadUInt16();
                _DFace.side = br.ReadInt16();

                _DFace.firstedge = br.ReadInt32();
                _DFace.numedges = br.ReadInt16();
                _DFace.texinfo = br.ReadInt16();

                _DFace.styles = br.ReadBytes(MAXLIGHTMAPS);
                _DFace.lightofs = br.ReadInt32();

                DFace.Add(_DFace);
            }

            CProgram.gQ2Game.gCMain.gCSurface.BeginBuildingLightmaps(ref _SModel);

            for (int i = 0; i < DFace.Count; i++)
            {
                CModel.SMSurface _MSurface;
                int side;
                short ti;

                _MSurface.firstedge = DFace[i].firstedge;
                _MSurface.numedges = DFace[i].numedges;
                _MSurface.flags = 0;
                _MSurface.polys = null;
                _MSurface.ibSurface = null;
                _MSurface.ibData = null;

                side = DFace[i].side;
                if (side != 0)
                    _MSurface.flags |= CModel.EMSurface.SURF_PLANEBACK;

                _MSurface.plane = DFace[i].planenum;

                _MSurface.plane2 = new Microsoft.Xna.Framework.Plane();

                ti = DFace[i].texinfo;
                if (ti < 0 || ti >= _SModel.numtexinfo)
                    CMain.Error(CMain.EErrorParm.ERR_WARNING, "MOD_LoadBmodel: bad texinfo number");
                _MSurface.texinfo = ti;

                _MSurface.bounds = CLocal.ClearBounds();

                _MSurface.boundsMid.X = 0.0f;
                _MSurface.boundsMid.Y = 0.0f;
                _MSurface.boundsMid.Z = 0.0f;

                _MSurface.lightIndex = null;
                _MSurface.lightLength = null;

                _MSurface.texturechain = 0;
                _MSurface.visframe = 0;

                // lighting info
                _MSurface.dlightframe = 0;
                _MSurface.dlightbits = 0;
                _MSurface.lightmaptexturenum = 0;
                _MSurface.styles = new byte[MAXLIGHTMAPS];
                for (int j = 0; j < MAXLIGHTMAPS; j++)
                {
                    _MSurface.styles[j] = DFace[i].styles[j];
                }

                _MSurface.cached_light = null;
                _MSurface.samples = DFace[i].lightofs;

                _MSurface.light_s = 0;
                _MSurface.light_t = 0;
                _MSurface.dlight_s = 0;
                _MSurface.dlight_t = 0;

                _MSurface.extents = null;
                _MSurface.texturemins = null;
                CModel.CalcSurfaceExtents(ref _SModel, ref _MSurface);

                // set the drawing flags
                if ((_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_WARP) == ESurface.SURF_WARP)
                {
                    _MSurface.flags |= CModel.EMSurface.SURF_DRAWTURB;

                    for (int j = 0; j < 2; j++)
                    {
                        _MSurface.extents[j] = 16384;
                        _MSurface.texturemins[j] = -8192;
                    }

                    // TODO
                    // cut up polygon for warps
                    //SubdivideSurface(i, ref _WorldModel.mfaces[i]);
                    //SubdivideSurface (out);
                }

                // create lightmaps and polygons
                if (
                    (_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_SKY) != ESurface.SURF_SKY
                    && (_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_TRANS33) != ESurface.SURF_TRANS33
                    && (_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_TRANS66) != ESurface.SURF_TRANS66
                    && (_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_WARP) != ESurface.SURF_WARP
                    )
                {
                    CProgram.gQ2Game.gCMain.gCSurface.CreateSurfaceLightmap(_SModel, ref _MSurface);
                }

                if ((_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_WARP) == ESurface.SURF_WARP)
                    CProgram.gQ2Game.gCMain.gCSurface.BuildPolygonFromSurface(ref _MSurface);

                MSurface.Add(_MSurface);
            }

            CProgram.gQ2Game.gCMain.gCSurface.EndBuildingLightmaps(ref _SModel);

            _SModel.numsurfaces = MSurface.Count;
            _SModel.surfaces = MSurface.ToArray();
        }
Example #12
0
        private void Mod_LoadEntityString(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            if (header.lumps[LUMP_ENTITIES].filelen > MAX_MAP_ENTSTRING)
            {
                // entity string exceeds maximum
                _SModel.map_entitystring = null;
                return;
            }

            br.BaseStream.Seek(header.lumps[LUMP_ENTITIES].fileofs, System.IO.SeekOrigin.Begin);
            if (br.BaseStream.Position < (header.lumps[LUMP_ENTITIES].fileofs + header.lumps[LUMP_ENTITIES].filelen))
            {
                _SModel.map_entitystring = CShared.Com_ToString(br.ReadChars(header.lumps[LUMP_ENTITIES].filelen));
                _SModel.map_entitystring = _SModel.map_entitystring.Replace("\r", "").Replace("\n", "\r\n");
            }
            else
            {
                _SModel.map_entitystring = null;
            }
        }
Example #13
0
        private void Mod_LoadEdges(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List<CModel.SMEdge> MEdge = new List<CModel.SMEdge>();

            br.BaseStream.Seek(header.lumps[LUMP_EDGES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_EDGES].fileofs + header.lumps[LUMP_EDGES].filelen))
            {
                CModel.SMEdge _MEdge;

                _MEdge.v = new ushort[2];
                _MEdge.v[0] = br.ReadUInt16();
                _MEdge.v[1] = br.ReadUInt16();

                _MEdge.cachededgeoffset = 0;

                MEdge.Add(_MEdge);
            }

            _SModel.numedges = MEdge.Count;
            _SModel.edges = MEdge.ToArray();
        }
Example #14
0
        private void Mod_LoadAreas(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List<SDArea> DArea = new List<SDArea>();
            List<CModel.SMArea> MArea = new List<CModel.SMArea>();

            br.BaseStream.Seek(header.lumps[LUMP_AREAS].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_AREAS].fileofs + header.lumps[LUMP_AREAS].filelen))
            {
                SDArea _DArea;

                _DArea.numareaportals = br.ReadInt32();
                _DArea.firstareaportal = br.ReadInt32();

                DArea.Add(_DArea);
            }

            for (int i = 0; i < DArea.Count; i++)
            {
                CModel.SMArea _MArea;

                _MArea.numareaportals = DArea[i].numareaportals;
                _MArea.firstareaportal = DArea[i].firstareaportal;
                _MArea.floodvalid = 0;
                _MArea.floodnum = 0;

                MArea.Add(_MArea);
            }

            _SModel.numareas = MArea.Count;
            _SModel.areas = MArea.ToArray();
        }
Example #15
0
        private void Mod_LoadAreaPortals(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List<SDAreaPortal> DAreaPortal = new List<SDAreaPortal>();
            List<CModel.SMAreaPortal> MAreaPortal = new List<CModel.SMAreaPortal>();

            br.BaseStream.Seek(header.lumps[LUMP_AREAPORTALS].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_AREAPORTALS].fileofs + header.lumps[LUMP_AREAPORTALS].filelen))
            {
                SDAreaPortal _DAreaPortal;

                _DAreaPortal.portalnum = br.ReadInt32();
                _DAreaPortal.otherarea = br.ReadInt32();

                DAreaPortal.Add(_DAreaPortal);
            }

            for (int i = 0; i < DAreaPortal.Count; i++)
            {
                CModel.SMAreaPortal _MAreaPortal;

                _MAreaPortal.portalnum = DAreaPortal[i].portalnum;
                _MAreaPortal.otherarea = DAreaPortal[i].otherarea;

                MAreaPortal.Add(_MAreaPortal);
            }

            _SModel.numareaportals = MAreaPortal.Count;
            _SModel.areaportals = MAreaPortal.ToArray();
        }
Example #16
0
        private void Mod_LoadNodesAndLeafs(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List<SDNode> DNode = new List<SDNode>();
            List<SDLeaf> DLeaf = new List<SDLeaf>();
            List<CModel.SMNode> MNode = new List<CModel.SMNode>();

            // load nodes
            br.BaseStream.Seek(header.lumps[LUMP_NODES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_NODES].fileofs + header.lumps[LUMP_NODES].filelen))
            {
                SDNode _DNode;

                _DNode.planenum = br.ReadInt32();

                _DNode.children = new int[2];
                _DNode.children[0] = br.ReadInt32();
                _DNode.children[1] = br.ReadInt32();

                _DNode.mins = new short[3];
                _DNode.mins[0] = br.ReadInt16();
                _DNode.mins[1] = br.ReadInt16();
                _DNode.mins[2] = br.ReadInt16();

                _DNode.maxs = new short[3];
                _DNode.maxs[0] = br.ReadInt16();
                _DNode.maxs[1] = br.ReadInt16();
                _DNode.maxs[2] = br.ReadInt16();

                _DNode.firstface = br.ReadUInt16();
                _DNode.numfaces = br.ReadUInt16();

                DNode.Add(_DNode);
            }

            for (int i = 0; i < DNode.Count; i++)
            {
                CModel.SMNode _MNode;
                int p;

                _MNode.bounds.Min.X = DNode[i].mins[0];
                _MNode.bounds.Min.Y = DNode[i].mins[1];
                _MNode.bounds.Min.Z = DNode[i].mins[2];
                _MNode.bounds.Max.X = DNode[i].maxs[0];
                _MNode.bounds.Max.Y = DNode[i].maxs[1];
                _MNode.bounds.Max.Z = DNode[i].maxs[2];

                _MNode.plane = DNode[i].planenum;

                _MNode.firstsurface = DNode[i].firstface;
                _MNode.numsurfaces = DNode[i].numfaces;
                _MNode.contents = -1; // differentiate from leafs

                _MNode.children = new int[2];
                for (int j = 0; j < 2; j++)
                {
                    p = DNode[i].children[j];

                    if (p >= 0)
                        _MNode.children[j] = p;
                    else
                        _MNode.children[j] = DNode.Count + (-1 - p);
                }

                _MNode.parent = 0;
                _MNode.visframe = 0;

                // leaf specific
                _MNode.cluster = 0;
                _MNode.area = 0;
                _MNode.firstmarksurface = 0;
                _MNode.nummarksurfaces = 0;

                MNode.Add(_MNode);
            }

            // load leafs
            br.BaseStream.Seek(header.lumps[LUMP_LEAFS].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_LEAFS].fileofs + header.lumps[LUMP_LEAFS].filelen))
            {
                SDLeaf _DLeaf;

                _DLeaf.contents = br.ReadInt32();

                _DLeaf.cluster = br.ReadInt16();
                _DLeaf.area = br.ReadInt16();

                _DLeaf.mins = new short[3];
                _DLeaf.mins[0] = br.ReadInt16();
                _DLeaf.mins[1] = br.ReadInt16();
                _DLeaf.mins[2] = br.ReadInt16();

                _DLeaf.maxs = new short[3];
                _DLeaf.maxs[0] = br.ReadInt16();
                _DLeaf.maxs[1] = br.ReadInt16();
                _DLeaf.maxs[2] = br.ReadInt16();

                _DLeaf.firstleafface = br.ReadUInt16();
                _DLeaf.numleaffaces = br.ReadUInt16();

                _DLeaf.firstleafbrush = br.ReadUInt16();
                _DLeaf.numleafbrushes = br.ReadUInt16();

                DLeaf.Add(_DLeaf);
            }

            for (int i = 0; i < DLeaf.Count; i++)
            {
                CModel.SMNode _MNode;

                _MNode.bounds.Min.X = DLeaf[i].mins[0];
                _MNode.bounds.Min.Y = DLeaf[i].mins[1];
                _MNode.bounds.Min.Z = DLeaf[i].mins[2];
                _MNode.bounds.Max.X = DLeaf[i].maxs[0];
                _MNode.bounds.Max.Y = DLeaf[i].maxs[1];
                _MNode.bounds.Max.Z = DLeaf[i].maxs[2];

                _MNode.contents = DLeaf[i].contents;

                _MNode.cluster = DLeaf[i].cluster;
                _MNode.area = DLeaf[i].area;

                _MNode.firstmarksurface = DLeaf[i].firstleafface;
                _MNode.nummarksurfaces = DLeaf[i].numleaffaces;

                _MNode.parent = 0;
                _MNode.visframe = 0;

                // node specific
                _MNode.plane = 0;
                _MNode.firstsurface = 0;
                _MNode.numsurfaces = 0;
                _MNode.children = null;

                MNode.Add(_MNode);
            }

            _SModel.numnodes = DNode.Count + DLeaf.Count;
            _SModel.numDecisionNodes = DNode.Count;
            _SModel.numleafs = DLeaf.Count;
            _SModel.nodes = MNode.ToArray();

            // chain decendants
            Mod_SetParent(ref _SModel, 0, -1);
        }
Example #17
0
        private void Mod_LoadTexinfo(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List <CModel.SMTexInfo> MTexInfo = new List <CModel.SMTexInfo>();

            br.BaseStream.Seek(header.lumps[LUMP_TEXINFO].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_TEXINFO].fileofs + header.lumps[LUMP_TEXINFO].filelen))
            {
                CModel.SMTexInfo _MTexInfo;
                string           texture;
                int next;

                _MTexInfo.vecs = new Microsoft.Xna.Framework.Vector4[2];
                for (int i = 0; i < 2; i++)
                {
                    _MTexInfo.vecs[i].X = br.ReadSingle();
                    _MTexInfo.vecs[i].Y = br.ReadSingle();
                    _MTexInfo.vecs[i].Z = br.ReadSingle();
                    _MTexInfo.vecs[i].W = br.ReadSingle();
                }

                _MTexInfo.flags = (ESurface)br.ReadInt32();
                br.ReadInt32(); // value
                texture = CShared.Com_ToString(br.ReadChars(32));
                texture = "textures/" + texture;

                next = br.ReadInt32();
                if (next > 0)
                {
                    _MTexInfo.next = next;
                }
                else
                {
                    _MTexInfo.next = 0;
                }

                _MTexInfo.image = CProgram.gQ2Game.gCMain.gCImage.FindImage(texture, out _MTexInfo.Width, out _MTexInfo.Height, CImage.EImageType.IT_WALL);

                // TODO
                //out->image = GL_FindImage (name, it_wall);
                //if (!out->image)
                //{
                //    ri.Con_Printf (PRINT_ALL, "Couldn't load %s\n", name);
                //    out->image = r_notexture;
                //}

                _MTexInfo.numframes = 0;

                MTexInfo.Add(_MTexInfo);
            }

            // count animation frames
            for (int i = 0; i < MTexInfo.Count; i++)
            {
                CModel.SMTexInfo _MTexInfo = MTexInfo[i];
                _MTexInfo.numframes = 1;

                for (int step = _MTexInfo.next; step != 0 && step != i; step = MTexInfo[step].next)
                {
                    _MTexInfo.numframes++;
                }

                MTexInfo[i] = _MTexInfo;
            }

            _SModel.numtexinfo = MTexInfo.Count;
            _SModel.texinfo    = MTexInfo.ToArray();
        }
Example #18
0
        private void Mod_LoadSubmodels(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List<SDModel> DModel = new List<SDModel>();
            List<CModel.SMModel> MModel = new List<CModel.SMModel>();

            br.BaseStream.Seek(header.lumps[LUMP_MODELS].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_MODELS].fileofs + header.lumps[LUMP_MODELS].filelen))
            {
                SDModel _DModel;

                _DModel.mins = new float[3];
                _DModel.mins[0] = br.ReadSingle();
                _DModel.mins[1] = br.ReadSingle();
                _DModel.mins[2] = br.ReadSingle();

                _DModel.maxs = new float[3];
                _DModel.maxs[0] = br.ReadSingle();
                _DModel.maxs[1] = br.ReadSingle();
                _DModel.maxs[2] = br.ReadSingle();

                _DModel.origin = new float[3];
                _DModel.origin[0] = br.ReadSingle();
                _DModel.origin[1] = br.ReadSingle();
                _DModel.origin[2] = br.ReadSingle();

                _DModel.headnode = br.ReadInt32();

                _DModel.firstface = br.ReadInt32();
                _DModel.numfaces = br.ReadInt32();

                DModel.Add(_DModel);
            }

            for (int i = 0; i < DModel.Count; i++)
            {
                CModel.SMModel _MModel;

                _MModel.bounds.Min.X = DModel[i].mins[0] - 1;
                _MModel.bounds.Min.Y = DModel[i].mins[1] - 1;
                _MModel.bounds.Min.Z = DModel[i].mins[2] - 1;
                _MModel.bounds.Max.X = DModel[i].maxs[0] + 1;
                _MModel.bounds.Max.Y = DModel[i].maxs[1] + 1;
                _MModel.bounds.Max.Z = DModel[i].maxs[2] + 1;

                _MModel.origin.X = DModel[i].origin[0];
                _MModel.origin.Y = DModel[i].origin[1];
                _MModel.origin.Z = DModel[i].origin[2];

                _MModel.radius = RadiusFromBounds(_MModel.bounds);

                _MModel.headnode = DModel[i].headnode;
                _MModel.firstface = DModel[i].firstface;
                _MModel.numfaces = DModel[i].numfaces;

                _MModel.visleafs = 0;

                MModel.Add(_MModel);
            }

            _SModel.numsubmodels = MModel.Count;
            _SModel.submodels = MModel.ToArray();
        }
Example #19
0
        private void Mod_LoadFaces(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List <SDFace>           DFace    = new List <SDFace>();
            List <CModel.SMSurface> MSurface = new List <CModel.SMSurface>();

            br.BaseStream.Seek(header.lumps[LUMP_FACES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_FACES].fileofs + header.lumps[LUMP_FACES].filelen))
            {
                SDFace _DFace;

                _DFace.planenum = br.ReadUInt16();
                _DFace.side     = br.ReadInt16();

                _DFace.firstedge = br.ReadInt32();
                _DFace.numedges  = br.ReadInt16();
                _DFace.texinfo   = br.ReadInt16();

                _DFace.styles   = br.ReadBytes(MAXLIGHTMAPS);
                _DFace.lightofs = br.ReadInt32();

                DFace.Add(_DFace);
            }

            CProgram.gQ2Game.gCMain.gCSurface.BeginBuildingLightmaps(ref _SModel);

            for (int i = 0; i < DFace.Count; i++)
            {
                CModel.SMSurface _MSurface;
                int   side;
                short ti;

                _MSurface.firstedge = DFace[i].firstedge;
                _MSurface.numedges  = DFace[i].numedges;
                _MSurface.flags     = 0;
                _MSurface.polys     = null;
                _MSurface.ibSurface = null;
                _MSurface.ibData    = null;


                side = DFace[i].side;
                if (side != 0)
                {
                    _MSurface.flags |= CModel.EMSurface.SURF_PLANEBACK;
                }

                _MSurface.plane = DFace[i].planenum;

                _MSurface.plane2 = new Microsoft.Xna.Framework.Plane();

                ti = DFace[i].texinfo;
                if (ti < 0 || ti >= _SModel.numtexinfo)
                {
                    CMain.Error(CMain.EErrorParm.ERR_WARNING, "MOD_LoadBmodel: bad texinfo number");
                }
                _MSurface.texinfo = ti;

                _MSurface.bounds = CLocal.ClearBounds();

                _MSurface.boundsMid.X = 0.0f;
                _MSurface.boundsMid.Y = 0.0f;
                _MSurface.boundsMid.Z = 0.0f;

                _MSurface.lightIndex  = null;
                _MSurface.lightLength = null;

                _MSurface.texturechain = 0;
                _MSurface.visframe     = 0;

                // lighting info
                _MSurface.dlightframe        = 0;
                _MSurface.dlightbits         = 0;
                _MSurface.lightmaptexturenum = 0;
                _MSurface.styles             = new byte[MAXLIGHTMAPS];
                for (int j = 0; j < MAXLIGHTMAPS; j++)
                {
                    _MSurface.styles[j] = DFace[i].styles[j];
                }

                _MSurface.cached_light = null;
                _MSurface.samples      = DFace[i].lightofs;

                _MSurface.light_s  = 0;
                _MSurface.light_t  = 0;
                _MSurface.dlight_s = 0;
                _MSurface.dlight_t = 0;

                _MSurface.extents     = null;
                _MSurface.texturemins = null;
                CModel.CalcSurfaceExtents(ref _SModel, ref _MSurface);

                // set the drawing flags
                if ((_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_WARP) == ESurface.SURF_WARP)
                {
                    _MSurface.flags |= CModel.EMSurface.SURF_DRAWTURB;

                    for (int j = 0; j < 2; j++)
                    {
                        _MSurface.extents[j]     = 16384;
                        _MSurface.texturemins[j] = -8192;
                    }

                    // TODO
                    // cut up polygon for warps
                    //SubdivideSurface(i, ref _WorldModel.mfaces[i]);
                    //SubdivideSurface (out);
                }

                // create lightmaps and polygons
                if (
                    (_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_SKY) != ESurface.SURF_SKY &&
                    (_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_TRANS33) != ESurface.SURF_TRANS33 &&
                    (_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_TRANS66) != ESurface.SURF_TRANS66 &&
                    (_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_WARP) != ESurface.SURF_WARP
                    )
                {
                    CProgram.gQ2Game.gCMain.gCSurface.CreateSurfaceLightmap(_SModel, ref _MSurface);
                }

                if ((_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_WARP) == ESurface.SURF_WARP)
                {
                    CProgram.gQ2Game.gCMain.gCSurface.BuildPolygonFromSurface(ref _MSurface);
                }

                MSurface.Add(_MSurface);
            }

            CProgram.gQ2Game.gCMain.gCSurface.EndBuildingLightmaps(ref _SModel);

            _SModel.numsurfaces = MSurface.Count;
            _SModel.surfaces    = MSurface.ToArray();
        }
Example #20
0
        private void Mod_LoadSubmodels(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List <SDModel>        DModel = new List <SDModel>();
            List <CModel.SMModel> MModel = new List <CModel.SMModel>();

            br.BaseStream.Seek(header.lumps[LUMP_MODELS].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_MODELS].fileofs + header.lumps[LUMP_MODELS].filelen))
            {
                SDModel _DModel;

                _DModel.mins    = new float[3];
                _DModel.mins[0] = br.ReadSingle();
                _DModel.mins[1] = br.ReadSingle();
                _DModel.mins[2] = br.ReadSingle();

                _DModel.maxs    = new float[3];
                _DModel.maxs[0] = br.ReadSingle();
                _DModel.maxs[1] = br.ReadSingle();
                _DModel.maxs[2] = br.ReadSingle();

                _DModel.origin    = new float[3];
                _DModel.origin[0] = br.ReadSingle();
                _DModel.origin[1] = br.ReadSingle();
                _DModel.origin[2] = br.ReadSingle();

                _DModel.headnode = br.ReadInt32();

                _DModel.firstface = br.ReadInt32();
                _DModel.numfaces  = br.ReadInt32();

                DModel.Add(_DModel);
            }

            for (int i = 0; i < DModel.Count; i++)
            {
                CModel.SMModel _MModel;

                _MModel.bounds.Min.X = DModel[i].mins[0] - 1;
                _MModel.bounds.Min.Y = DModel[i].mins[1] - 1;
                _MModel.bounds.Min.Z = DModel[i].mins[2] - 1;
                _MModel.bounds.Max.X = DModel[i].maxs[0] + 1;
                _MModel.bounds.Max.Y = DModel[i].maxs[1] + 1;
                _MModel.bounds.Max.Z = DModel[i].maxs[2] + 1;

                _MModel.origin.X = DModel[i].origin[0];
                _MModel.origin.Y = DModel[i].origin[1];
                _MModel.origin.Z = DModel[i].origin[2];

                _MModel.radius = RadiusFromBounds(_MModel.bounds);

                _MModel.headnode  = DModel[i].headnode;
                _MModel.firstface = DModel[i].firstface;
                _MModel.numfaces  = DModel[i].numfaces;

                _MModel.visleafs = 0;

                MModel.Add(_MModel);
            }

            _SModel.numsubmodels = MModel.Count;
            _SModel.submodels    = MModel.ToArray();
        }
Example #21
0
        private void Mod_LoadLighting(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            if (header.lumps[LUMP_LIGHTING].filelen == 0)
            {
                _SModel.lightdata = null;
                return;
            }

            br.BaseStream.Seek(header.lumps[LUMP_LIGHTING].fileofs, System.IO.SeekOrigin.Begin);
            _SModel.lightdata = br.ReadBytes(header.lumps[LUMP_LIGHTING].filelen);
        }
Example #22
0
        private void Mod_LoadVertexes(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List<CModel.SMVertex> MVertex = new List<CModel.SMVertex>();

            br.BaseStream.Seek(header.lumps[LUMP_VERTEXES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_VERTEXES].fileofs + header.lumps[LUMP_VERTEXES].filelen))
            {
                CModel.SMVertex _MVertex;

                _MVertex.Position.X = br.ReadSingle();
                _MVertex.Position.Y = br.ReadSingle();
                _MVertex.Position.Z = br.ReadSingle();

                MVertex.Add(_MVertex);
            }

            _SModel.numvertexes = MVertex.Count;
            _SModel.vertexes = MVertex.ToArray();
        }
Example #23
0
        private void Mod_LoadMarksurfaces(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List<int> MarkSurface = new List<int>();

            br.BaseStream.Seek(header.lumps[LUMP_LEAFFACES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_LEAFFACES].fileofs + header.lumps[LUMP_LEAFFACES].filelen))
            {
                int msurf = br.ReadInt16();

                if (msurf < 0 || msurf >= _SModel.numsurfaces)
                    CMain.Error(CMain.EErrorParm.ERR_FATAL, "Mod_ParseMarksurfaces: bad surface number");

                MarkSurface.Add(msurf);
            }

            _SModel.nummarksurfaces = MarkSurface.Count;
            _SModel.marksurfaces = MarkSurface.ToArray();
        }
Example #24
0
        private void Mod_LoadVisibility(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            int pos_visdata = 0;
            br.BaseStream.Seek(header.lumps[LUMP_VISIBILITY].fileofs, System.IO.SeekOrigin.Begin);

            if (header.lumps[LUMP_VISIBILITY].filelen == 0)
            {
                _SModel.vis.numclusters = 0;
                _SModel.vis.bitofs = null;
                _SModel.visdata = null;

                return;
            }

            _SModel.vis.numclusters = br.ReadInt32();
            _SModel.vis.bitofs = new int[_SModel.vis.numclusters, 2];

            for (int i = 0; i < _SModel.vis.numclusters; i++)
            {
                _SModel.vis.bitofs[i, DVIS_PVS] = br.ReadInt32();
                _SModel.vis.bitofs[i, DVIS_PHS] = br.ReadInt32();

                // decrement the offsets, because the data is stored in a seperate byte array
                _SModel.vis.bitofs[i, DVIS_PVS] -= 4 + ((4 * _SModel.vis.numclusters * 2));
                _SModel.vis.bitofs[i, DVIS_PHS] -= 4 + ((4 * _SModel.vis.numclusters * 2));
            }

            _SModel.visdata = new byte[(header.lumps[LUMP_VISIBILITY].fileofs + header.lumps[LUMP_VISIBILITY].filelen) - br.BaseStream.Position];
            while (br.BaseStream.Position < (header.lumps[LUMP_VISIBILITY].fileofs + header.lumps[LUMP_VISIBILITY].filelen))
            {
                _SModel.visdata[pos_visdata++] = br.ReadByte();
            }
        }
Example #25
0
        private void Mod_LoadPlanes(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            int bits;
            float[] normal = new float[3];
            List<CShared.SCPlane> CPlane = new List<CShared.SCPlane>();

            br.BaseStream.Seek(header.lumps[LUMP_PLANES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_PLANES].fileofs + header.lumps[LUMP_PLANES].filelen))
            {
                CShared.SCPlane _CPlane;

                normal[0] = 0.0f;
                normal[1] = 0.0f;
                normal[2] = 0.0f;

                bits = 0;

                for (int j = 0; j < 3; j++)
                {
                    normal[j] = br.ReadSingle();

                    if (normal[j] < 0)
                        bits |= 1 << j;
                }

                _CPlane.normal.X = normal[0];
                _CPlane.normal.Y = normal[1];
                _CPlane.normal.Z = normal[2];

                _CPlane.dist = br.ReadSingle();
                _CPlane.type = (byte)br.ReadInt32();
                _CPlane.signbits = (byte)bits;

                _CPlane.pad = new byte[2];

                CPlane.Add(_CPlane);
            }

            _SModel.planes = CPlane.ToArray();
            _SModel.numplanes = _SModel.planes.Length;
        }
Example #26
0
        private void Mod_LoadNodesAndLeafs(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List <SDNode>        DNode = new List <SDNode>();
            List <SDLeaf>        DLeaf = new List <SDLeaf>();
            List <CModel.SMNode> MNode = new List <CModel.SMNode>();


            // load nodes
            br.BaseStream.Seek(header.lumps[LUMP_NODES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_NODES].fileofs + header.lumps[LUMP_NODES].filelen))
            {
                SDNode _DNode;

                _DNode.planenum = br.ReadInt32();

                _DNode.children    = new int[2];
                _DNode.children[0] = br.ReadInt32();
                _DNode.children[1] = br.ReadInt32();

                _DNode.mins    = new short[3];
                _DNode.mins[0] = br.ReadInt16();
                _DNode.mins[1] = br.ReadInt16();
                _DNode.mins[2] = br.ReadInt16();

                _DNode.maxs    = new short[3];
                _DNode.maxs[0] = br.ReadInt16();
                _DNode.maxs[1] = br.ReadInt16();
                _DNode.maxs[2] = br.ReadInt16();

                _DNode.firstface = br.ReadUInt16();
                _DNode.numfaces  = br.ReadUInt16();

                DNode.Add(_DNode);
            }

            for (int i = 0; i < DNode.Count; i++)
            {
                CModel.SMNode _MNode;
                int           p;

                _MNode.bounds.Min.X = DNode[i].mins[0];
                _MNode.bounds.Min.Y = DNode[i].mins[1];
                _MNode.bounds.Min.Z = DNode[i].mins[2];
                _MNode.bounds.Max.X = DNode[i].maxs[0];
                _MNode.bounds.Max.Y = DNode[i].maxs[1];
                _MNode.bounds.Max.Z = DNode[i].maxs[2];

                _MNode.plane = DNode[i].planenum;

                _MNode.firstsurface = DNode[i].firstface;
                _MNode.numsurfaces  = DNode[i].numfaces;
                _MNode.contents     = -1; // differentiate from leafs

                _MNode.children = new int[2];
                for (int j = 0; j < 2; j++)
                {
                    p = DNode[i].children[j];

                    if (p >= 0)
                    {
                        _MNode.children[j] = p;
                    }
                    else
                    {
                        _MNode.children[j] = DNode.Count + (-1 - p);
                    }
                }

                _MNode.parent   = 0;
                _MNode.visframe = 0;

                // leaf specific
                _MNode.cluster          = 0;
                _MNode.area             = 0;
                _MNode.firstmarksurface = 0;
                _MNode.nummarksurfaces  = 0;

                MNode.Add(_MNode);
            }


            // load leafs
            br.BaseStream.Seek(header.lumps[LUMP_LEAFS].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_LEAFS].fileofs + header.lumps[LUMP_LEAFS].filelen))
            {
                SDLeaf _DLeaf;

                _DLeaf.contents = br.ReadInt32();

                _DLeaf.cluster = br.ReadInt16();
                _DLeaf.area    = br.ReadInt16();

                _DLeaf.mins    = new short[3];
                _DLeaf.mins[0] = br.ReadInt16();
                _DLeaf.mins[1] = br.ReadInt16();
                _DLeaf.mins[2] = br.ReadInt16();

                _DLeaf.maxs    = new short[3];
                _DLeaf.maxs[0] = br.ReadInt16();
                _DLeaf.maxs[1] = br.ReadInt16();
                _DLeaf.maxs[2] = br.ReadInt16();

                _DLeaf.firstleafface = br.ReadUInt16();
                _DLeaf.numleaffaces  = br.ReadUInt16();

                _DLeaf.firstleafbrush = br.ReadUInt16();
                _DLeaf.numleafbrushes = br.ReadUInt16();

                DLeaf.Add(_DLeaf);
            }

            for (int i = 0; i < DLeaf.Count; i++)
            {
                CModel.SMNode _MNode;

                _MNode.bounds.Min.X = DLeaf[i].mins[0];
                _MNode.bounds.Min.Y = DLeaf[i].mins[1];
                _MNode.bounds.Min.Z = DLeaf[i].mins[2];
                _MNode.bounds.Max.X = DLeaf[i].maxs[0];
                _MNode.bounds.Max.Y = DLeaf[i].maxs[1];
                _MNode.bounds.Max.Z = DLeaf[i].maxs[2];

                _MNode.contents = DLeaf[i].contents;

                _MNode.cluster = DLeaf[i].cluster;
                _MNode.area    = DLeaf[i].area;

                _MNode.firstmarksurface = DLeaf[i].firstleafface;
                _MNode.nummarksurfaces  = DLeaf[i].numleaffaces;

                _MNode.parent   = 0;
                _MNode.visframe = 0;

                // node specific
                _MNode.plane        = 0;
                _MNode.firstsurface = 0;
                _MNode.numsurfaces  = 0;
                _MNode.children     = null;

                MNode.Add(_MNode);
            }

            _SModel.numnodes         = DNode.Count + DLeaf.Count;
            _SModel.numDecisionNodes = DNode.Count;
            _SModel.numleafs         = DLeaf.Count;
            _SModel.nodes            = MNode.ToArray();

            // chain decendants
            Mod_SetParent(ref _SModel, 0, -1);
        }
Example #27
0
        private void Mod_LoadSurfedges(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List<int> DSurfEdge = new List<int>();

            br.BaseStream.Seek(header.lumps[LUMP_SURFEDGES].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_SURFEDGES].fileofs + header.lumps[LUMP_SURFEDGES].filelen))
            {
                DSurfEdge.Add(br.ReadInt32());
            }

            _SModel.numsurfedges = DSurfEdge.Count;
            _SModel.surfedges = DSurfEdge.ToArray();
        }
Example #28
0
        private void Mod_LoadTexinfo(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br)
        {
            List<CModel.SMTexInfo> MTexInfo = new List<CModel.SMTexInfo>();

            br.BaseStream.Seek(header.lumps[LUMP_TEXINFO].fileofs, System.IO.SeekOrigin.Begin);
            while (br.BaseStream.Position < (header.lumps[LUMP_TEXINFO].fileofs + header.lumps[LUMP_TEXINFO].filelen))
            {
                CModel.SMTexInfo _MTexInfo;
                string texture;
                int next;

                _MTexInfo.vecs = new Microsoft.Xna.Framework.Vector4[2];
                for (int i = 0; i < 2; i++)
                {
                    _MTexInfo.vecs[i].X = br.ReadSingle();
                    _MTexInfo.vecs[i].Y = br.ReadSingle();
                    _MTexInfo.vecs[i].Z = br.ReadSingle();
                    _MTexInfo.vecs[i].W = br.ReadSingle();
                }

                _MTexInfo.flags = (ESurface)br.ReadInt32();
                br.ReadInt32(); // value
                texture = CShared.Com_ToString(br.ReadChars(32));
                texture = "textures/" + texture;

                next = br.ReadInt32();
                if (next > 0)
                    _MTexInfo.next = next;
                else
                    _MTexInfo.next = 0;

                _MTexInfo.image = CProgram.gQ2Game.gCMain.gCImage.FindImage(texture, out _MTexInfo.Width, out _MTexInfo.Height, CImage.EImageType.IT_WALL);

                // TODO
                //out->image = GL_FindImage (name, it_wall);
                //if (!out->image)
                //{
                //    ri.Con_Printf (PRINT_ALL, "Couldn't load %s\n", name);
                //    out->image = r_notexture;
                //}

                _MTexInfo.numframes = 0;

                MTexInfo.Add(_MTexInfo);
            }

            // count animation frames
            for (int i = 0; i < MTexInfo.Count; i++)
            {
                CModel.SMTexInfo _MTexInfo = MTexInfo[i];
                _MTexInfo.numframes = 1;

                for (int step = _MTexInfo.next; step != 0 && step != i; step = MTexInfo[step].next)
                {
                    _MTexInfo.numframes++;
                }

                MTexInfo[i] = _MTexInfo;
            }

            _SModel.numtexinfo = MTexInfo.Count;
            _SModel.texinfo = MTexInfo.ToArray();
        }