コード例 #1
0
ファイル: RmfProvider.cs プロジェクト: 074769/sledge
        protected override DataStructures.MapObjects.Map GetFromStream(Stream stream)
        {
            var map = new DataStructures.MapObjects.Map();
            var br = new BinaryReader(stream);

            // Only RMF version 2.2 is supported for the moment.
            var version = Math.Round(br.ReadSingle(), 1);
            if (Math.Abs(version - 2.2) > 0.01)
            {
                throw new ProviderException("Incorrect RMF version number. Expected 2.2, got " + version + ".");
            }
            map.Version = (decimal) version;

            // RMF header test
            var header = br.ReadFixedLengthString(Encoding.UTF8, 3);
            if (header != "RMF")
            {
                throw new ProviderException("Incorrect RMF header. Expected 'RMF', got '" + header + "'.");
            }

            // Visgroups
            var visgroups = ReadVisgroups(br);
            map.Visgroups.AddRange(visgroups);

            // Map Objects
            map.IDGenerator.Reset(); // So the world will be ID = 1
            var worldspawn = ReadWorldSpawn(br, map.Visgroups, map.IDGenerator);
            map.WorldSpawn = worldspawn;

            // DOCINFO string check
            var docinfo = br.ReadFixedLengthString(Encoding.UTF8, 8);
            if (docinfo != "DOCINFO")
            {
                throw new ProviderException("Incorrect RMF format. Expected 'DOCINFO', got '" + docinfo + "'.");
            }

            // Cameras
            br.ReadSingle(); // Appears to be a version number for camera data. Unused.
            var activeCamera = br.ReadInt32();
            var cameras = ReadCameras(br);
            map.Cameras.AddRange(cameras);
            if (activeCamera >= 0 && activeCamera < map.Cameras.Count)
            {
                map.ActiveCamera = map.Cameras[activeCamera];
            }

            return map;
        }
コード例 #2
0
ファイル: SprProvider.cs プロジェクト: jpiolho/sledge
 private static Bitmap Parse(FileInfo file)
 {
     // Sprite file spec taken from the spritegen source in the Half-Life SDK.
     using (var br = new BinaryReader(file.OpenRead()))
     {
         var idst = br.ReadFixedLengthString(Encoding.ASCII, 4);
         if (idst != "IDSP") return null;
         var version = br.ReadInt32();
         if (version != 2) return null;
         var type = br.ReadInt32();
         var texFormat = br.ReadInt32();
         var boundingRadius = br.ReadSingle();
         var width = br.ReadInt32();
         var height = br.ReadInt32();
         var numframes = br.ReadInt32();
         var beamlength = br.ReadSingle();
         var synctype = br.ReadInt32();
         var paletteSize = br.ReadInt16();
         var palette = br.ReadBytes(paletteSize * 3);
         // Only read the first frame.
         var frametype = br.ReadInt32();
         if (frametype != 0)
         {
             var num = br.ReadInt32();
             var intervals = br.ReadSingleArray(num);
         }
         var originX = br.ReadInt32();
         var originY = br.ReadInt32();
         var framewidth = br.ReadInt32();
         var frameheight = br.ReadInt32();
         var pixels = br.ReadBytes(framewidth * frameheight);
         var bitmap = new Bitmap(framewidth, frameheight);
         for (var y = 0; y < frameheight; y++)
         {
             for (var x = 0; x < framewidth; x++)
             {
                 var idx = pixels[framewidth * y + x] * 3;
                 var a = 255;
                 var r = palette[idx + 0];
                 var g = palette[idx + 1];
                 var b = palette[idx + 2];
                 if (b == 255 && r == 0 && g == 0) a = b = 0; // blue pixels are transparent
                 var col = Color.FromArgb(a, r, g, b);
                 bitmap.SetPixel(x, y, col);
             }
         }
         return bitmap;
     }
 }
コード例 #3
0
ファイル: SprProvider.cs プロジェクト: KonstantinUb/sledge
        private static Size GetSize(IFile file)
        {
            using (var br = new BinaryReader(file.Open()))
            {
                var idst = br.ReadFixedLengthString(Encoding.ASCII, 4);
                if (idst != "IDSP") return Size.Empty;
                var version = br.ReadInt32();
                if (version != 2) return Size.Empty;
                var type = (SpriteOrientation) br.ReadInt32();
                var texFormat = (SpriteRenderMode) br.ReadInt32();
                var boundingRadius = br.ReadSingle();
                var width = br.ReadInt32();
                var height = br.ReadInt32();

                return new Size(width, height);
            }
        }
コード例 #4
0
ファイル: PakPackage.cs プロジェクト: silky/sledge
        public PakPackage(FileInfo packageFile)
        {
            PackageFile = packageFile;
            Entries = new List<PakEntry>();

            // Read the data from the pak
            using (var br = new BinaryReader(OpenFile(packageFile)))
            {
                var sig = br.ReadFixedLengthString(Encoding.ASCII, 4);
                if (sig != Signature) throw new PackageException("Unknown package signature: Expected '" + Signature + "', got '" + sig + "'.");

                TreeOffset = br.ReadInt32();
                TreeLength = br.ReadInt32();

                // Read all the entries from the pak
                ReadPackageEntries(br);
                BuildDirectories();
            }
        }
コード例 #5
0
ファイル: WadPackage.cs プロジェクト: silky/sledge
        public WadPackage(FileInfo packageFile)
        {
            PackageFile = packageFile;
            Entries = new List<WadEntry>();

            // Read the data from the wad
            using (var br = new BinaryReader(OpenFile(packageFile)))
            {
                var sig = br.ReadFixedLengthString(Encoding.ASCII, 4);
                if (sig != Signature) throw new PackageException("Unknown package signature: Expected '" + Signature + "', got '" + sig + "'.");

                NumTextures = br.ReadUInt32();
                LumpOffset = br.ReadUInt32();

                // Read all the entries from the wad
                ReadTextureEntries(br);
                SetAdditionalEntryData(br);
                RemoveInvalidEntries();
                BuildDirectories();
            }
        }
コード例 #6
0
ファイル: RmfProvider.cs プロジェクト: 074769/sledge
 private static Path ReadPath(BinaryReader br)
 {
     var path = new Path
         {
             Name = br.ReadFixedLengthString(Encoding.UTF8, 128),
             Type = br.ReadFixedLengthString(Encoding.UTF8, 128),
             Direction = (PathDirection) br.ReadInt32()
         };
     var numNodes = br.ReadInt32();
     for (var i = 0; i < numNodes; i++)
     {
         var node = ReadPathNode(br);
         node.Parent = path;
         path.Nodes.Add(node);
     }
     return path;
 }
コード例 #7
0
ファイル: RmfProvider.cs プロジェクト: 074769/sledge
 private static PathNode ReadPathNode(BinaryReader br)
 {
     var node = new PathNode
         {
             Position = br.ReadCoordinate(),
             ID = br.ReadInt32(),
             Name = br.ReadFixedLengthString(Encoding.UTF8, 128)
         };
     var numProps = br.ReadInt32();
     for (var i = 0; i < numProps; i++)
     {
         node.Properties.Add(ReadProperty(br));
     }
     return node;
 }
コード例 #8
0
ファイル: VtfProvider.cs プロジェクト: silky/sledge
        public static Bitmap GetImage(Stream stream, int maxWidth = 0, int maxHeight = 0)
        {
            using (var br = new BinaryReader(stream))
            {
                var header = br.ReadFixedLengthString(Encoding.ASCII, 4);
                if (header != VtfHeader) throw new ProviderException("Invalid VTF header. Expected '" + VtfHeader + "', got '" + header + "'.");

                var v1 = br.ReadUInt32();
                var v2 = br.ReadUInt32();
                var version = v1 + (v2 / 10m); // e.g. 7.3

                var headerSize = br.ReadUInt32();
                var width = br.ReadUInt16();
                var height = br.ReadUInt16();

                var flags = (VtfImageFlag) br.ReadUInt32();

                var numFrames = br.ReadUInt16();
                var firstFrame = br.ReadUInt16();

                br.ReadBytes(4); // padding

                var reflectivity = br.ReadCoordinate();

                br.ReadBytes(4); // padding

                var bumpmapScale = br.ReadSingle();

                var highResImageFormat = (VtfImageFormat) br.ReadUInt32();
                var mipmapCount = br.ReadByte();
                var lowResImageFormat = (VtfImageFormat) br.ReadUInt32();
                var lowResWidth = br.ReadByte();
                var lowResHeight = br.ReadByte();

                ushort depth = 1;
                uint numResources = 0;

                if (version >= 7.2m)
                {
                    depth = br.ReadUInt16();
                }
                if (version >= 7.3m)
                {
                    br.ReadBytes(3);
                    numResources = br.ReadUInt32();
                }

                var faces = 1;
                if (flags.HasFlag(VtfImageFlag.Envmap))
                {
                    faces = version < 7.5m && firstFrame != 0xFFFF ? 7 : 6;
                }

                var imageSize = ComputeImageSize(width, height, depth, mipmapCount, highResImageFormat) * faces * numFrames;
                var thumbnailSize = lowResImageFormat == VtfImageFormat.None
                    ? 0
                    : ComputeImageSize(lowResWidth, lowResHeight, 1, lowResImageFormat);

                var thumbnailPos = headerSize;
                var dataPos = headerSize + thumbnailSize;

                for (var i = 0; i < numResources; i++)
                {
                    var type = br.ReadUInt32();
                    var data = br.ReadUInt32();
                    switch (type)
                    {
                        case 0x01:
                            // Low res image
                            thumbnailPos = data;
                            break;
                        case 0x30:
                            // Regular image
                            dataPos = data;
                            break;
                    }
                }

                if (lowResImageFormat != VtfImageFormat.None)
                {
                    br.BaseStream.Position = thumbnailPos;
                    var thumbnail = br.ReadBytes((int) thumbnailSize);
                    //var thumbImage = LoadImage(br, lowResWidth, lowResHeight, lowResImageFormat);
                    //return thumbImage;
                }

                var mipNum = 0;
                if (maxWidth > 0 || maxHeight > 0) mipNum = GetMipToLoad(width, height, maxWidth > 0 ? maxWidth : width, maxHeight > 0 ? maxHeight : height, mipmapCount);

                for (var frame = 0; frame < numFrames; frame++)
                {
                    for (var face = 0; face < faces; face++)
                    {
                        for (var slice = 0; slice < depth; slice++)
                        {
                            for (var mip = mipNum; mip < mipmapCount; mip++)
                            {
                                var wid = MipmapResize(width, mip);
                                var hei = MipmapResize(height, mip);
                                var offset = GetImageDataLocation(frame, face, slice, mip, highResImageFormat, width, height, numFrames, faces, depth, mipmapCount);
                                br.BaseStream.Position = offset + dataPos;

                                var img = LoadImage(br, (uint) wid, (uint) hei, highResImageFormat);
                                //img.Save(String.Format(@"D:\Github\sledge\_Resources\VTF\_test_fr{0}_fa{1}_sl{2}_m{3}.png", frame, face, slice, mip));
                                return img;
                            }
                        }
                    }
                }

                return null;
            }
        }
コード例 #9
0
ファイル: RmfProvider.cs プロジェクト: 074769/sledge
 private static Face ReadFace(BinaryReader br, IDGenerator generator)
 {
     var face = new Face(generator.GetNextFaceID());
     var textureName = br.ReadFixedLengthString(Encoding.UTF8, 256);
     br.ReadBytes(4); // Unused
     face.Texture.Name = textureName;
     face.Texture.UAxis = br.ReadCoordinate();
     face.Texture.XShift = br.ReadSingleAsDecimal();
     face.Texture.VAxis = br.ReadCoordinate();
     face.Texture.YShift = br.ReadSingleAsDecimal();
     face.Texture.Rotation = br.ReadSingleAsDecimal();
     face.Texture.XScale = br.ReadSingleAsDecimal();
     face.Texture.YScale = br.ReadSingleAsDecimal();
     br.ReadBytes(16); // Unused
     var numVerts = br.ReadInt32();
     for (var i = 0; i < numVerts; i++)
     {
         face.Vertices.Add(new Vertex(br.ReadCoordinate(), face));
     }
     face.Plane = br.ReadPlane();
     face.UpdateBoundingBox();
     return face;
 }
コード例 #10
0
ファイル: SprProvider.cs プロジェクト: KonstantinUb/sledge
        private static Bitmap Parse(IFile file)
        {
            // Sprite file spec taken from the spritegen source in the Half-Life SDK.
            using (var br = new BinaryReader(file.Open()))
            {
                var idst = br.ReadFixedLengthString(Encoding.ASCII, 4);
                if (idst != "IDSP") return null;
                var version = br.ReadInt32();
                if (version != 2) return null;
                var type = (SpriteOrientation) br.ReadInt32();
                var texFormat = (SpriteRenderMode) br.ReadInt32();
                var boundingRadius = br.ReadSingle();
                var width = br.ReadInt32();
                var height = br.ReadInt32();
                var numframes = br.ReadInt32();
                var beamlength = br.ReadSingle();
                var synctype = br.ReadInt32();
                var paletteSize = br.ReadInt16();
                var palette = br.ReadBytes(paletteSize * 3);

                if (paletteSize > 256) paletteSize = 256; // Don't accept anything higher
                var colours = new Color[256];
                for (var i = 0; i < paletteSize; i++)
                {
                    var r = palette[i * 3 + 0];
                    var g = palette[i * 3 + 1];
                    var b = palette[i * 3 + 2];
                    colours[i] = Color.FromArgb(255, r, g, b);
                }

                // Only read the first frame.
                var frametype = br.ReadInt32();
                if (frametype != 0)
                {
                    var num = br.ReadInt32();
                    var intervals = br.ReadSingleArray(num);
                }
                var originX = br.ReadInt32();
                var originY = br.ReadInt32();
                var framewidth = br.ReadInt32();
                var frameheight = br.ReadInt32();
                var pixels = br.ReadBytes(framewidth * frameheight);

                var bitmap = new Bitmap(framewidth, frameheight, PixelFormat.Format8bppIndexed);

                // Pre-process the palette
                var pal = bitmap.Palette;
                var last = colours[255];
                for (var i = 0; i < paletteSize; i++)
                {
                    var c = colours[i];
                    if (texFormat == SpriteRenderMode.Additive)
                    {
                        var a = (int) ((c.R + c.G + c.B) / 3f);
                        c = Color.FromArgb(a, c);
                    }
                    else if (texFormat == SpriteRenderMode.IndexAlpha && i < 255)
                    {
                        var a = (int) ((c.R + c.G + c.B) / 3f);
                        c = Color.FromArgb(a, last);
                    }
                    pal.Entries[i] = c;
                }
                if (texFormat == SpriteRenderMode.AlphaTest)
                {
                    pal.Entries[255] = Color.FromArgb(0, 0, 0, 0);
                }
                bitmap.Palette = pal;

                // Set the pixel data
                var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
                Marshal.Copy(pixels, 0, data.Scan0, data.Width * data.Height);
                bitmap.UnlockBits(data);

                return bitmap;
            }
        }
コード例 #11
0
ファイル: VtfProvider.cs プロジェクト: silky/sledge
        public static Size GetSize(Stream stream)
        {
            using (var br = new BinaryReader(stream))
            {
                var header = br.ReadFixedLengthString(Encoding.ASCII, 4);
                if (header != VtfHeader) throw new ProviderException("Invalid VTF header. Expected '" + VtfHeader + "', got '" + header + "'.");

                var v1 = br.ReadUInt32();
                var v2 = br.ReadUInt32();
                var version = v1 + (v2 / 10); // e.g. 7.3

                var headerSize = br.ReadUInt32();
                var width = br.ReadUInt16();
                var height = br.ReadUInt16();

                return new Size(width, height);
            }
        }
コード例 #12
0
ファイル: MdlProvider.cs プロジェクト: silky/sledge
        private static void LoadSourceMeshData(ModelData modelData, IFile file)
        {
            modelData.Meshes = new List<VTXModel>();
            // In Source the vertices are saved to the VVD file
            // The vertex windings are saved in the VTX file
            var vvd = file.GetRelatedFile("vvd");
            var vtx = file.GetRelatedFile("vtx");
            if (vvd == null) throw new ProviderException("Unable to locate " + file.NameWithoutExtension + ".vvd");
            if (vtx == null) throw new ProviderException("Unable to locate " + file.NameWithoutExtension + ".vtx");

            var vertices = new List<VVDPoint>();

            using (var fs = vvd.Open())
            {
                using (var vbr = new BinaryReader(fs))
                {
                    var magicString = vbr.ReadFixedLengthString(Encoding.UTF8, 4);
                    if (magicString != MagicStringIDSV)
                    {
                        throw new ProviderException("Bad magic number for vertex file. Expected IDSV, got: " + magicString);
                    }

                    var version = vbr.ReadInt32();
                    if (version != VVDVersionSource)
                    {
                        throw new ProviderException("Bad version number for vertex file. Expected 4, got: " + version);
                    }

                    long checksum = vbr.ReadInt32();
                    var numLods = vbr.ReadInt32();
                    var numLodVertices = vbr.ReadIntArray(8);

                    var numFixups = vbr.ReadInt32();
                    var fixupTableStart = vbr.ReadInt32();
                    var vertexDataStart = vbr.ReadInt32();
                    var tangentDataStart = vbr.ReadInt32();

                    vbr.BaseStream.Position = vertexDataStart;

                    // Read all the vertices from LOD 0 (this should contain the vertices for all LODs)
                    for (var i = 0; i < numLodVertices[0]; i++)
                    {
                        var boneWeights = vbr.ReadSingleArray(3);
                        var bones = vbr.ReadBytes(3);
                        var numBones = vbr.ReadByte();
                        var position = vbr.ReadCoordinateF();
                        var normal = vbr.ReadCoordinateF();
                        var textureS = vbr.ReadSingle();
                        var textureT = vbr.ReadSingle();
                        vertices.Add(new VVDPoint(boneWeights, bones, numBones, position, normal, textureS, textureT));
                    }

                    // Apply the fixup table, this re-orders the indices in reverse LOD order for performance reasons
                    if (numFixups > 0)
                    {
                        vbr.BaseStream.Position = fixupTableStart;
                        var newVerts = new List<VVDPoint>();
                        for (var i = 0; i < numFixups; i++)
                        {
                            var fuLod = vbr.ReadInt32();
                            var fuvertid = vbr.ReadInt32();
                            var funumverts = vbr.ReadInt32();
                            newVerts.AddRange(vertices.GetRange(fuvertid, funumverts));
                        }
                        vertices.Clear();
                        vertices.AddRange(newVerts);
                    }

                    modelData.Vertices = vertices;
                }
            }
            using (var fs = vtx.Open())
            {
                using (var vbr = new BinaryReader(fs))
                {
                    var version = vbr.ReadInt32(); // 7
                    if (version != VTXVersionSource)
                    {
                        throw new ProviderException("Bad version number for vertex file. Expected 7, got: " + version);
                    }
                    var vertCacheSize = vbr.ReadInt32();
                    var maxBonesPerStrip = vbr.ReadUInt16();
                    var maxBonesPerTri = vbr.ReadUInt16();
                    var maxBonesPerVert = vbr.ReadInt32();
                    long checksum = vbr.ReadInt32();
                    var numLods = vbr.ReadInt32();
                    var materialReplacementListOffset = vbr.ReadInt32();
                    var numBodyParts = vbr.ReadInt32();
                    var bodyPartOffset = vbr.ReadInt32();

                    // BODY PARTS
                    long posbp = bodyPartOffset;
                    for (var bp = 0; bp < numBodyParts; bp++)
                    {
                        vbr.BaseStream.Position = posbp;

                        var numModels = vbr.ReadInt32();
                        var modelOffset = vbr.ReadInt32();

                        var posmdl = posbp + modelOffset;
                        posbp = vbr.BaseStream.Position;

                        // MODELS
                        for (var mdl = 0; mdl < numModels; mdl++)
                        {
                            vbr.BaseStream.Position = posmdl;

                            var numLod = vbr.ReadInt32();
                            var lodOffset = vbr.ReadInt32();

                            var poslod = posmdl + lodOffset;
                            posmdl = vbr.BaseStream.Position;

                            // LODS
                            for (var lod = 0; lod < numLod; lod++)
                            {
                                vbr.BaseStream.Position = poslod;

                                var meshNum = vbr.ReadInt32();
                                var meshOffset = vbr.ReadInt32();
                                var switchPoint = vbr.ReadSingle();

                                var posmesh = poslod + meshOffset;
                                poslod = vbr.BaseStream.Position;

                                // MESHES
                                for (var msh = 0; msh < meshNum; msh++)
                                {
                                    vbr.BaseStream.Position = posmesh;

                                    var sgNum = vbr.ReadInt32();
                                    var sgOffset = vbr.ReadInt32();
                                    var meshFlags = vbr.ReadByte();

                                    var possg = posmesh + sgOffset;
                                    posmesh = vbr.BaseStream.Position;

                                    var mesh = new VTXModel(bp, mdl, lod, msh);

                                    // STRIP GROUPS
                                    for (var sg = 0; sg < sgNum; sg++)
                                    {
                                        vbr.BaseStream.Position = possg;

                                        var vertNum = vbr.ReadInt32();
                                        var vertOffset = vbr.ReadInt32();
                                        var indexNum = vbr.ReadInt32();
                                        var indexOffset = vbr.ReadInt32();
                                        var stripNum = vbr.ReadInt32();
                                        var stripOffset = vbr.ReadInt32();
                                        var sgFlags = vbr.ReadByte();
                                        // vbr.ReadIntArray(2); //TODO FIXME Newer model format 49's (DOTA2, CSGO) have two extra integers here, (num + offset, purpose unknown)

                                        var posvert = possg + vertOffset;
                                        var posidx = possg + indexOffset;
                                        var posstrip = possg + stripOffset;
                                        possg = vbr.BaseStream.Position;

                                        var vertinfo = new List<VTXPoint>();
                                        vbr.BaseStream.Position = posvert;
                                        for (var vert = 0; vert < vertNum; vert++)
                                        {
                                            var boneWeightIndices = vbr.ReadBytes(3);
                                            var numBones = vbr.ReadByte();
                                            var meshVertex = vbr.ReadInt16();
                                            var boneIDs = vbr.ReadBytes(3);

                                            vertinfo.Add(new VTXPoint(boneWeightIndices, numBones, meshVertex, boneIDs));
                                        }

                                        vbr.BaseStream.Position = posidx;
                                        var indices = vbr.ReadShortArray(indexNum);

                                        // The strips hold info about whether this is a triangle strip or just a list
                                        vbr.BaseStream.Position = posstrip;
                                        for (var st = 0; st < stripNum; st++)
                                        {
                                            var numStIndices = vbr.ReadInt32();
                                            var stIndexOffset = vbr.ReadInt32();
                                            var numStVerts = vbr.ReadInt32();
                                            var stVertOffset = vbr.ReadInt32();
                                            var numStBones = vbr.ReadInt16();
                                            var stFlags = vbr.ReadByte();
                                            var numStBoneStateChanges = vbr.ReadInt32();
                                            var stBoneStateChangeOffset = vbr.ReadInt32();
                                            // vbr.ReadIntArray(2); //TODO FIXME Newer model format 49's (DOTA2, CSGO) have two extra integers here, (num + offset, purpose unknown)

                                            if ((stFlags & VTXStripGroupTriListFlag) > 0)
                                            {
                                                for (var j = stIndexOffset; j < stIndexOffset + numStIndices; j++)
                                                {
                                                    mesh.Mesh.Points.Add(vertinfo[indices[j]]);
                                                    //mesh.Vertices.Add(vertices[vertinfo[indices[j]]]);
                                                }
                                            }
                                            else if ((stFlags & VTXStripGroupTriStripFlag) > 0)
                                            {
                                                for (var j = stIndexOffset; j < stIndexOffset + numStIndices - 2; j++)
                                                {
                                                    var add = j % 2 == 1 ? new[] { j + 1, j, j + 2 } : new[] { j, j + 1, j + 2 };
                                                    foreach (var idx in add)
                                                    {
                                                        mesh.Mesh.Points.Add(vertinfo[indices[idx]]);
                                                        //mesh.Vertices.Add(vertices[vertinfo[indices[idx]]]);
                                                    }
                                                }
                                            }
                                        } // Strips
                                    } // Strip Groups
                                    modelData.Meshes.Add(mesh);
                                } // Meshes
                            } // LODs
                        } // Models
                    } // Body Parts
                } // using (var br)
            } // using (var fs)
        }
コード例 #13
0
ファイル: MdlProvider.cs プロジェクト: silky/sledge
        private static DataStructures.Models.Model ReadModel(BinaryReader br, IFile file, ModelLoadItems loadItems)
        {
            // int id - Not really an int. This is a magic string, either "IDST" or "IDSQ".
            var magicString = br.ReadFixedLengthString(Encoding.UTF8, 4);
            if (magicString != MagicStringIDST && magicString != MagicStringIDSQ)
            {
                throw new ProviderException("Bad magic number for model. Expected [IDST,IDSQ], got: " + magicString);
            }

            // int version - Half-life 1 models are version 10.
            var version = br.ReadInt32();
            if (version != MDLVersionGoldsource
                && version != MDLVersionSource2006
                && version != MDLVersionSourceEpisode2
                && version != MDLVersionSourcePortal
                && version != MDLVersionSource2007
                && version != MDLVersionSource2012)
            {
                throw new ProviderException("Bad version number for model. Expected [10,44,45,46,48,49], got: " + version);
            }

            var modelData = new ModelData {Version = version};

            if (version >= MDLVersionSource2006)
            {
                if (loadItems.HasFlag(ModelLoadItems.Meshes))
                {
                    // Source vertex and mesh info is stored in flat file structures, preload these separately.
                    LoadSourceMeshData(modelData, file);
                }
            }

            long checksum = 0;
            if (version >= MDLVersionSource2006)
            {
                checksum = br.ReadInt32(); // This is a long in the headers but is only written to the file in 4 bytes. Why? I don't know.
            }

            // char name[64] - The name of the model (file path)
            var path = br.ReadFixedLengthString(Encoding.UTF8, 64);

            // int length - The size of the model file in bytes
            var fileSize = br.ReadInt32();

            var eyePosition = br.ReadCoordinateF();

            var illumPosition = CoordinateF.Zero;
            if (version >= MDLVersionSource2006)
            {
                illumPosition = br.ReadCoordinateF();
            }

            var hullMin = br.ReadCoordinateF();
            var hullMax = br.ReadCoordinateF();

            var bbMin = br.ReadCoordinateF();
            var bbMax = br.ReadCoordinateF();

            // int flags - Unknown.
            var flags = br.ReadInt32();

            var numBones = br.ReadInt32();
            var boneIndex = br.ReadInt32();

            var numBoneControllers = br.ReadInt32();
            var boneControllerIndex = br.ReadInt32();

            var numHitBoxes = br.ReadInt32();
            var hitboxIndex = br.ReadInt32();

            if (version >= MDLVersionSource2006)
            {
                var numAnim = br.ReadInt32();
                var animIndex = br.ReadInt32();
                if (loadItems.HasFlag(ModelLoadItems.Animations))
                {
                    // Source animation data is stored on their own instead of inside the sequence
                    LoadSourceAnimationData(br, modelData, numAnim, animIndex);
                }
            }

            var numSeq = br.ReadInt32();
            var seqIndex = br.ReadInt32();

            int numSeqGroups = 0, seqGroupIndex = 0, activitylistversion = 0, eventsindexed = 0;
            if (version >= MDLVersionSource2006)
            {
                activitylistversion = br.ReadInt32();
                eventsindexed = br.ReadInt32();
            }
            else if (version == MDLVersionGoldsource)
            {
                numSeqGroups = br.ReadInt32();
                seqGroupIndex = br.ReadInt32();
            }

            var numTextures = br.ReadInt32();
            var textureIndex = br.ReadInt32();
            var textureDataIndex = 0;

            if (version == MDLVersionGoldsource)
            {
                textureDataIndex = br.ReadInt32();
            }

            if (version >= MDLVersionSource2006)
            {
                var numcdtextures = br.ReadInt32();
                var cdtextureindex = br.ReadInt32();
            }

            var numSkinRef = br.ReadInt32();
            var numSkinFamilies = br.ReadInt32();
            var skinIndex = br.ReadInt32();

            var numBodyParts = br.ReadInt32();
            var bodyPartIndex = br.ReadInt32();

            var numAttachments = br.ReadInt32();
            var attachmentIndex = br.ReadInt32();

            if (version >= MDLVersionSource2006)
            {
                var numlocalnodes = br.ReadInt32();
                var localnodeindex = br.ReadInt32();
                var localnodenameindex = br.ReadInt32();

                var numflexdesc = br.ReadInt32();
                var flexdescindex = br.ReadInt32();

                var numflexcontrollers = br.ReadInt32();
                var flexcontrollerindex = br.ReadInt32();

                var numflexrules = br.ReadInt32();
                var flexruleindex = br.ReadInt32();

                var numikchains = br.ReadInt32();
                var ikchainindex = br.ReadInt32();

                var nummouths = br.ReadInt32();
                var mouthindex = br.ReadInt32();

                var numlocalposeparameters = br.ReadInt32();
                var localposeparamindex = br.ReadInt32();

                var surfacepropindex = br.ReadInt32();

                var keyvalueindex = br.ReadInt32();
                var keyvaluesize = br.ReadInt32();

                var numlocalikautoplaylocks = br.ReadInt32();
                var localikautoplaylockindex = br.ReadInt32();

                var mass = br.ReadSingle();
                var contents = br.ReadInt32();

                var numincludemodels = br.ReadInt32();
                var includemodelindex = br.ReadInt32();

                var virtualModelPointer = br.ReadInt32();

                var szanimblocknameindex = br.ReadInt32();
                var numanimblocks = br.ReadInt32();
                var animblockindex = br.ReadInt32();
                var animblockModelPointer = br.ReadInt32();

                var bonetablebynameindex = br.ReadInt32();

                var pVertexBasePointer = br.ReadInt32();
                var pIndexBasePointer = br.ReadInt32();

                var constdirectionallightdot = br.ReadByte();
                var rootLod = br.ReadByte();
                var numAllowedRootLods = br.ReadByte(); // Unused in Source2006
                br.ReadByte(); // Unused

                var zeroframecacheindex = br.ReadInt32(); // Unused in Source2007

                if (version == MDLVersionSource2006)
                {
                    br.ReadBytes(6); // Unused
                }
                else if (version == MDLVersionSource2007)
                {
                    var numflexcontrollerui = br.ReadInt32();
                    var flexcontrolleruiindex = br.ReadInt32();

                    br.ReadIntArray(2); // Unused

                    var studiohdr2Index = br.ReadInt32();
                    br.ReadInt32(); // Unused
                }
            }
            else if (version == MDLVersionGoldsource)
            {
                var soundTable = br.ReadInt32();
                var soundIndex = br.ReadInt32();
                var soundGroups = br.ReadInt32();
                var soundGroupIndex = br.ReadInt32();

                var numTransitions = br.ReadInt32();
                var transitionIndex = br.ReadInt32();
            }

            var model = new DataStructures.Models.Model();
            model.Name = file.NameWithoutExtension;
            model.BonesTransformMesh = modelData.Version == MDLVersionGoldsource;

            if (loadItems.HasFlag(ModelLoadItems.Bones))
            {
                // Bones
                br.BaseStream.Position = boneIndex;
                for (var i = 0; i < numBones; i++) ReadBone(br, i, modelData, model);
            }

            // Controllers
            // TODO

            // Attachments
            // TODO

            // Hitboxes
            // TODO

            if (loadItems.HasFlag(ModelLoadItems.Animations))
            {
                if (version >= MDLVersionSource2006)
                {
                    throw new ProviderException("Source animations are currently not supported.");
                }

                // Sequence Groups
                var groups = new List<SequenceGroup>();
                br.BaseStream.Position = seqGroupIndex;
                for (var i = 0; i < numSeqGroups; i++) groups.Add(ReadSequenceGroup(br, modelData));

                // Sequences
                br.BaseStream.Position = seqIndex;
                for (var i = 0; i < numSeq; i++) ReadSequence(br, i, modelData, model, groups);
            }

            // Transitions
            // TODO

            if (loadItems.HasFlag(ModelLoadItems.Meshes))
            {
                // Body parts
                br.BaseStream.Position = bodyPartIndex;
                for (var i = 0; i < numBodyParts; i++) ReadBodyPart(br, i, modelData, model);
            }

            // Texture Info
            if (loadItems.HasFlag(ModelLoadItems.TextureInfo) || loadItems.HasFlag(ModelLoadItems.TextureData))
            {
                ReadTextureInfo(file, br, modelData, model, numTextures, textureIndex);
            }

            // Textures

            return model;
        }
コード例 #14
0
ファイル: WadPackage.cs プロジェクト: silky/sledge
        private void ReadTextureEntries(BinaryReader br)
        {
            var validTypes = Enum.GetValues(typeof (WadEntryType)).OfType<WadEntryType>().Select(x => (byte) x).ToArray();
            br.BaseStream.Position = LumpOffset;
            for (int i = 0; i < NumTextures; i++)
            {
                var offset = br.ReadUInt32();
                var compressedLength = br.ReadUInt32();
                var fullLength = br.ReadUInt32();
                var type =  br.ReadByte();
                var compressionType = br.ReadByte();
                br.ReadBytes(2); // struct padding
                var name = br.ReadFixedLengthString(Encoding.ASCII, 16).ToLowerInvariant();

                if (!validTypes.Contains(type)) continue; // Skip unsupported types
                if (Entries.Any(x => x.Name == name)) continue; // Don't add duplicates
                Entries.Add(new WadEntry(this, name, (WadEntryType) type, offset, compressionType, compressedLength, fullLength));
            }
        }
コード例 #15
0
ファイル: MdlProvider.cs プロジェクト: silky/sledge
        private static void ReadBodyPart(BinaryReader br, int bodyPartIndex, ModelData data, DataStructures.Models.Model model)
        {
            var startIndex = data.Version == MDLVersionGoldsource ? 0 : br.BaseStream.Position;
            var name = "";
            var nameIndex = 0;
            if (data.Version >= MDLVersionSource2006)
            {
                nameIndex = br.ReadInt32();
                var idx = br.BaseStream.Position;
                br.BaseStream.Position = startIndex + nameIndex;
                name = br.ReadNullTerminatedString();
                br.BaseStream.Position = idx;
            }
            else if (data.Version == MDLVersionGoldsource)
            {
                name = br.ReadFixedLengthString(Encoding.UTF8, 64);
            }
            var numModels = br.ReadInt32();
            var baseIndex = br.ReadInt32();
            var modelIndex = br.ReadInt32();

            var endIndex = br.BaseStream.Position;

            br.BaseStream.Position = modelIndex + startIndex;
            for (var i = 0; i < numModels; i++)
            {
                ReadStudioModel(br, name, bodyPartIndex, i, data, model);
            }

            br.BaseStream.Position = endIndex;
        }
コード例 #16
0
ファイル: MdlProvider.cs プロジェクト: silky/sledge
        private static void ReadStudioModel(BinaryReader br, string groupName, int bodyPartIndex, int modelIndex, ModelData data, DataStructures.Models.Model model)
        {
            var startModelPos = br.BaseStream.Position;
            var name = br.ReadFixedLengthString(Encoding.ASCII, 64);
            var type = br.ReadInt32();
            var radius = br.ReadSingle();

            var numMesh = br.ReadInt32();
            var meshIndex = br.ReadInt32();

            var numVerts = br.ReadInt32();
            var vertInfoIndex = 0;
            if (data.Version == MDLVersionGoldsource)
            {
                vertInfoIndex = br.ReadInt32();
            }
            var vertIndex = br.ReadInt32();
            int numNorms = 0, normInfoIndex = 0, normIndex = 0;
            if (data.Version == MDLVersionGoldsource)
            {
                numNorms = br.ReadInt32();
                normInfoIndex = br.ReadInt32();
                normIndex = br.ReadInt32();
            }
            else if (data.Version >= MDLVersionSource2006)
            {
                var tangentsIndex = br.ReadInt32();
            }

            var numGroups = br.ReadInt32(); // Attachments in source
            var groupIndex = br.ReadInt32(); // Attachments

            if (data.Version >= MDLVersionSource2006)
            {
                var numEyeballs = br.ReadInt32();
                var eyeballIndex = br.ReadInt32();

                var vertexDataPointer = br.ReadInt32();
                var tangentDataPointer = br.ReadInt32();

                br.ReadIntArray(8); // Unused
            }

            var endPos = br.BaseStream.Position;

            if (data.Version == MDLVersionGoldsource)
            {
                ReadVerticesGoldSource(br, groupName, modelIndex, model, numVerts, vertInfoIndex, vertIndex, numMesh, meshIndex, numNorms, normInfoIndex, normIndex);
            }
            else if (data.Version >= MDLVersionSource2006)
            {
                ReadVerticesSource(br, groupName, bodyPartIndex, modelIndex, data, model, numMesh, startModelPos + meshIndex);
            }

            br.BaseStream.Position = endPos;
        }
コード例 #17
0
ファイル: MdlProvider.cs プロジェクト: silky/sledge
 private static SequenceGroup ReadSequenceGroup(BinaryReader br, ModelData data)
 {
     var name = br.ReadFixedLengthString(Encoding.ASCII, 32);
     var filename = br.ReadFixedLengthString(Encoding.ASCII, 64);
     var cachepointer = br.ReadInt32();
     var groupZeroDataIndex = br.ReadInt32();
     return new SequenceGroup
                {
                    Name = name,
                    FileName = filename,
                    CachePointer = cachepointer,
                    GroupZeroDataIndex = groupZeroDataIndex
                };
 }
コード例 #18
0
ファイル: MdlProvider.cs プロジェクト: silky/sledge
        private static void ReadSequence(BinaryReader br, int index, ModelData data, DataStructures.Models.Model model, IList<SequenceGroup> groups)
        {
            var startReadIndex = br.BaseStream.Position;
            var name = "";
            var fps = 0f;
            if (data.Version == MDLVersionGoldsource)
            {
                name = br.ReadFixedLengthString(Encoding.ASCII, 32);
                fps = br.ReadSingle();
            }
            else if (data.Version >= MDLVersionSource2006)
            {
                var baseIndex = br.ReadInt32();
                var labelIndex = br.ReadInt32();
                var activityNameIndex = br.ReadInt32();
            }

            var flags = br.ReadInt32();

            var activity = br.ReadInt32();
            var actweight = br.ReadInt32();

            var numevents = br.ReadInt32();
            var eventindex = br.ReadInt32();

            var numframes = 0;

            if (data.Version == MDLVersionGoldsource)
            {
                numframes = br.ReadInt32();
                var numpivots = br.ReadInt32();
                var pivotindex = br.ReadInt32();
                var motiontype = br.ReadInt32();
                var motionbone = br.ReadInt32();
                var linearmovement = br.ReadCoordinateF();
                var automoveposindex = br.ReadInt32();
                var automoveangleindex = br.ReadInt32();
            }

            var bbmin = br.ReadCoordinateF();
            var bbmax = br.ReadCoordinateF();

            var numblends = br.ReadInt32();

            var animindex = br.ReadInt32();

            var groupsize = new int[0];
            if (data.Version >= MDLVersionSource2006)
            {
                var movementindex = br.ReadInt32();
                groupsize = br.ReadIntArray(2);
            }

            var blendtype = br.ReadIntArray(2); // paramindex in source
            var blendstart = br.ReadSingleArray(2); // paramstart
            var blendend = br.ReadSingleArray(2); // paramend
            var blendparent = br.ReadInt32(); // paramparent

            var seqgroup = 0;
            if (data.Version == MDLVersionGoldsource)
            {
                seqgroup = br.ReadInt32();
            }

            if (data.Version >= MDLVersionSource2006)
            {
                var fadeintime = br.ReadSingle();
                var fadeouttime = br.ReadSingle();
            }

            var entrynode = br.ReadInt32();
            var exitnode = br.ReadInt32();
            var nodeflags = br.ReadInt32();

            if (data.Version >= MDLVersionSource2006)
            {
                var entryphase = br.ReadSingle();
                var exitphase = br.ReadSingle();

                var lastframe = br.ReadSingle();
            }

            var nextseq = br.ReadInt32();

            if (data.Version >= MDLVersionSource2006)
            {
                var pose = br.ReadInt32();

                var numikrules = br.ReadInt32();

                var numautolayers = br.ReadInt32();
                var autolayerindex = br.ReadInt32();

                var weightlistindex = br.ReadInt32();

                var wlpos = br.BaseStream.Position;
                br.BaseStream.Position = startReadIndex + weightlistindex;

                var weightList = br.ReadSingleArray(model.Bones.Count);

                br.BaseStream.Position = wlpos;

                var posekeyindex = br.ReadInt32();

                var numiklocks = br.ReadInt32();
                var iklockindex = br.ReadInt32();

                var keyvalueindex = br.ReadInt32();
                var keyvaluesize = br.ReadInt32();

                var cycleposeindex = br.ReadInt32();
                br.ReadIntArray(7); // Unused
            }

            // Load animtion values
            var pos = br.BaseStream.Position;

            if (data.Version == MDLVersionGoldsource)
            {
                if (seqgroup > 0)
                {
                    //TODO: load animations from other files
                    return;
                    // sub out br for another br against the new SG file
                    // br = new BinaryReader(file....etc)
                    // br.BaseStream.Position = animindex;
                }
                br.BaseStream.Position = groups[seqgroup].GroupZeroDataIndex + animindex;
                ReadAnimationGoldsource(br, model, numframes);
            }
            else if (data.Version >= MDLVersionSource2006)
            {
                br.BaseStream.Position = startReadIndex + animindex;
                ReadAnimationSource(br, data, model, groupsize);
            }

            br.BaseStream.Position = pos;
        }
コード例 #19
0
ファイル: RmfProvider.cs プロジェクト: 074769/sledge
 private static IEnumerable<Visgroup> ReadVisgroups(BinaryReader br)
 {
     var numVisgroups = br.ReadInt32();
     for (var i = 0; i < numVisgroups; i++)
     {
         var vis = new Visgroup
             {
                 Name = br.ReadFixedLengthString(Encoding.UTF8, 128),
                 Colour = br.ReadRGBAColour(),
                 ID = br.ReadInt32(),
                 Visible = br.ReadBoolean()
             };
         vis.Colour = Color.FromArgb(255, vis.Colour);
         br.ReadBytes(3);
         yield return vis;
     }
 }
コード例 #20
0
ファイル: RmfProvider.cs プロジェクト: silky/sledge
 private static IEnumerable<Visgroup> ReadVisgroups(BinaryReader br)
 {
     var list = new List<Visgroup>();
     var numVisgroups = br.ReadInt32();
     for (var i = 0; i < numVisgroups; i++)
     {
         var vis = new Visgroup
             {
                 Name = br.ReadFixedLengthString(Encoding.UTF8, 128),
                 Colour = br.ReadRGBAColour(),
                 ID = br.ReadInt32(),
                 Visible = br.ReadBoolean()
             };
         vis.Colour = Color.FromArgb(255, vis.Colour);
         br.ReadBytes(3);
         list.Add(vis);
     }
     // Get rid of zero groups
     foreach (var vg in list.Where(x => x.ID == 0))
     {
         vg.ID = list.Max(x => x.ID) + 1;
     }
     return list;
 }
コード例 #21
0
ファイル: PakPackage.cs プロジェクト: silky/sledge
 private void ReadPackageEntries(BinaryReader br)
 {
     br.BaseStream.Position = TreeOffset;
     var numEntries = TreeLength / 64;
     for (int i = 0; i < numEntries; i++)
     {
         var path = br.ReadFixedLengthString(Encoding.ASCII, 56).ToLowerInvariant();
         var offset = br.ReadInt32();
         var length = br.ReadInt32();
         Entries.Add(new PakEntry(this, path, offset, length));
     }
 }
コード例 #22
0
ファイル: MdlProvider.cs プロジェクト: silky/sledge
        private static void ReadBone(BinaryReader br, int index, ModelData data, DataStructures.Models.Model model)
        {
            var name = "";
            var nameIndex = 0;
            if (data.Version >= MDLVersionSource2006)
            {
                nameIndex = br.ReadInt32();
            }
            else if (data.Version == MDLVersionGoldsource)
            {
                name = br.ReadFixedLengthString(Encoding.UTF8, 32);
            }
            var parent = br.ReadInt32();
            int flags = 0;
            if (data.Version == MDLVersionGoldsource)
            {
                flags = br.ReadInt32();
            }
            var boneController = br.ReadIntArray(6);        // 3 pos, 3 rot
            var defPos = br.ReadCoordinateF();
            QuaternionF quat = null;
            if (data.Version >= MDLVersionSource2006)
            {
                // quaternion
                quat = new QuaternionF(br.ReadCoordinateF(), br.ReadSingle());
            }
            var defAng = br.ReadCoordinateF();
            var defPosScale = br.ReadCoordinateF();
            var defAngScale = br.ReadCoordinateF();

            if (data.Version >= MDLVersionSource2006)
            {
                var poseToBone = br.ReadIntArray(12); // 3x4 matrix
                var qAlignment = new QuaternionF(br.ReadCoordinateF(), br.ReadSingle());
                flags = br.ReadInt32();
                var proctype = br.ReadInt32();
                var procindex = br.ReadInt32();
                var physicsbone = br.ReadInt32();
                var surfacepropidx = br.ReadInt32();
                var contents = br.ReadInt32();
                br.ReadIntArray(8); // Unused
            }

            var parentBone = parent < 0 ? null : model.Bones[parent];
            model.Bones.Add(new Bone(index, parent, parentBone, name, defPos, defAng, defPosScale, defAngScale));
        }