Example #1
0
        public void LoadBinary(string filename)
        {
            using (var stream = new BinaryStream(filename))
            {
                Debug.WriteLine(">> Reading infos header...");
                var infosOffset = stream.ReadInt32();
                var infosCount  = stream.ReadInt32();

                Use32Bit = ((stream.Length - (infosCount * 0xC)) == infosOffset);

                Debug.WriteLine(">> Reading FCB header...");
                var magic = stream.ReadInt32();

                if (magic != Magic)
                {
                    throw new InvalidOperationException("Bad magic, no FCB data to parse!");
                }

                var type = stream.ReadInt16();

                if (type != Type)
                {
                    throw new InvalidOperationException("FCB library reported the incorrect type?!");
                }

                stream.Position += 2;                // ;)

                var totalCount = stream.ReadInt32(); // * 3
                var nodesCount = stream.ReadInt32(); // * 4

                var dataOffset = (int)stream.Position;

                var memSize      = ((totalCount * 3) + nodesCount) * 4;
                var memSizeAlign = Memory.Align(memSize, 16);

#if DEBUG
                Console.WriteLine("[Library.Header]");
                Console.WriteLine($"  Total: {totalCount}");
                Console.WriteLine($"  Nodes: {nodesCount}");
                Console.WriteLine($"  MemSize: {memSize:X8}");
#endif

                // read the infos first!
                Debug.WriteLine(">> Reading infos...");
                stream.Position = infosOffset;

                var nInfosTotal = 0;
                var nInfosNodes = 0;

                var refDatas = new Dictionary <int, EntityReferenceData>(infosCount);

                for (int i = 0; i < infosCount; i++)
                {
                    var refData = new EntityReferenceData(stream, Use32Bit);

                    nInfosTotal += refData.TotalCount;
                    nInfosNodes += refData.NodesCount;

                    refDatas.Add(refData.Offset, refData);
                }

                var count1Diff = (totalCount - nInfosTotal);
                var count2Diff = (nodesCount - nInfosNodes);

#if DEBUG
                Console.WriteLine("[Library.Infos]");
                Console.WriteLine($"  Total: {nInfosTotal}");
                Console.WriteLine($"  Nodes: {nInfosNodes}");
                Console.WriteLine("[Library.Logging]");
                Console.WriteLine($"  TotalDiff: {count1Diff}");
                Console.WriteLine($"  NodesDiff: {count2Diff}");
#endif

                // read fcb data
                Debug.WriteLine(">> Reading libraries...");
                stream.Position = dataOffset;

                var root = new NodeClass(stream);

                Libraries = new List <EntityLibrary>(root.Children.Count);

                foreach (var library in root.Children)
                {
                    // deserialize from the class
                    var lib = new EntityLibrary()
                    {
                        Use32Bit = Use32Bit,
                    };

                    lib.Deserialize(library);

                    // update UIDs
                    foreach (var entry in lib.Entries)
                    {
                        var node   = entry.GroupNode;
                        var offset = node.Offset;

                        if (refDatas.ContainsKey(offset))
                        {
                            var entRef = refDatas[offset];
                            entry.UID = entRef.UID;
                        }
                    }

                    Libraries.Add(lib);
                }

                Console.WriteLine($"Finished reading {Libraries.Count} libraries. Collected {Utils.GetTotalNumberOfNodes(root)} nodes in total.");
            }
        }
Example #2
0
        public void SaveBinary(string filename)
        {
            var root = GetNodeClass();

            byte[] buffer;

            Debug.WriteLine(">> Generating binary data...");
            using (var stream = new BinaryStream(BufferSize))
            {
                // list of references sorted by their UID
                var references = GetEntityReferences(true);

                // we need to write the offset to our infos here
                Debug.WriteLine(">> Writing infos header...");
                var ptr = stream.Position;
                stream.Position += 4;

                stream.Write(references.Count);

                Debug.WriteLine(">> Writing FCB header...");
                stream.Write((int)Magic);

                stream.Write((short)Type);
                stream.Write((short)MagicNumber.FB); // ;)

                var nodesCount = Utils.GetTotalNumberOfNodes(root);
                var attrCount  = root.Attributes.Count;

                if (attrCount == 0)
                {
                    attrCount = 1;
                }

                var totalCount = (nodesCount + attrCount);

                stream.Write(totalCount);
                stream.Write(nodesCount);

                root.Serialize(stream);

                //Debug.WriteLine(">> Optimizing data...");
                //using (var bs = new BinaryStream(BufferSize))
                //{
                //    root.Serialize(bs);
                //
                //    var dataLen = bs.Position;
                //    bs.SetLength(dataLen);
                //
                //    var data = OptimizedData.Create(nodesCount, bs.ToArray());
                //    data.WriteTo(stream);
                //}

                var refsOffset = (int)(Memory.Align(stream.Position, 8) - ptr);

                Debug.WriteLine(">> Writing infos offset...");
                stream.Position = ptr;
                stream.Write(refsOffset);

                Debug.WriteLine(">> Writing infos...");
                stream.Position = refsOffset;

                foreach (var reference in references)
                {
                    var refData = new EntityReferenceData(reference)
                    {
                        Use32Bit = Use32Bit,
                    };

                    refData.Serialize(stream);
                }

                var size = (int)stream.Position;
                buffer = new byte[size];

                Debug.WriteLine(">> Copying to buffer...");
                stream.Position = 0;
                stream.Read(buffer, 0, size);
            }

            Debug.WriteLine(">> Writing to file...");
            File.WriteAllBytes(filename, buffer);
        }