private ResourcePage LoadPage(StructureValueCollection values, int index, ThirdGenCacheFileReference[] externalFiles)
        {
            var result = new ResourcePage();

            result.Index             = index;
            result.Salt              = (ushort)values.GetInteger("salt");
            result.Flags             = (byte)values.GetInteger("flags");
            result.CompressionMethod = ((int)values.GetInteger("compression codec index") != -1)
                                ? ResourcePageCompression.Deflate
                                : ResourcePageCompression.None; // FIXME: hax/laziness
            var externalFile = (int)values.GetInteger("shared cache file index");

            result.FilePath         = (externalFile != -1) ? externalFiles[externalFile].Path : null;
            result.Unknown1         = (int)values.GetIntegerOrDefault("unknown 1", 0);
            result.Offset           = (int)values.GetInteger("compressed block offset");
            result.CompressedSize   = (int)values.GetInteger("compressed block size");
            result.UncompressedSize = (int)values.GetInteger("uncompressed block size");
            result.Checksum         = values.GetInteger("checksum");
            result.Hash1            = values.GetRaw("hash 1");
            result.Hash2            = values.GetRaw("hash 2");
            result.Hash3            = values.GetRaw("hash 3");
            result.Unknown2         = (int)values.GetIntegerOrDefault("unknown 2", 0);
            result.Unknown3         = (int)values.GetIntegerOrDefault("unknown 3", 0);
            return(result);
        }
        private void SaveDefinitionFixups(IList <ResourceDefinitionFixup> fixups, StructureValueCollection values,
                                          IStream stream, TagBlockCache <ResourceDefinitionFixup> cache)
        {
            var  oldCount   = (int)values.GetIntegerOrDefault("number of definition fixups", 0);
            uint oldAddress = (uint)values.GetIntegerOrDefault("definition fixup table address", 0);

            long oldExpand = _expander.Expand(oldAddress);

            StructureLayout layout = _buildInfo.Layouts.GetLayout("definition fixup element");

            long newAddress;

            if (!cache.TryGetAddress(fixups, out newAddress))
            {
                // Write a new block
                IEnumerable <StructureValueCollection> entries = fixups.Select(f => SerializeDefinitionFixup(f));
                newAddress = TagBlockWriter.WriteTagBlock(entries, oldCount, oldExpand, fixups.Count, layout, _metaArea,
                                                          _allocator, stream);
                cache.Add(newAddress, fixups);
            }
            else if (oldAddress != 0 && oldCount > 0)
            {
                // Block was cached - just free it
                _allocator.Free(oldExpand, oldCount * layout.Size);
            }

            uint cont = _expander.Contract(newAddress);

            values.SetInteger("number of definition fixups", (uint)fixups.Count);
            values.SetInteger("definition fixup table address", cont);
        }
Esempio n. 3
0
        private void SaveDefinitionFixups(IList <ResourceDefinitionFixup> fixups, StructureValueCollection values,
                                          IStream stream, ReflexiveCache <ResourceDefinitionFixup> cache)
        {
            var             oldCount   = (int)values.GetIntegerOrDefault("number of definition fixups", 0);
            uint            oldAddress = values.GetIntegerOrDefault("definition fixup table address", 0);
            StructureLayout layout     = _buildInfo.Layouts.GetLayout("definition fixup entry");

            uint newAddress;

            if (!cache.TryGetAddress(fixups, out newAddress))
            {
                // Write a new reflexive
                IEnumerable <StructureValueCollection> entries = fixups.Select(f => SerializeDefinitionFixup(f));
                newAddress = ReflexiveWriter.WriteReflexive(entries, oldCount, oldAddress, fixups.Count, layout, _metaArea,
                                                            _allocator, stream);
                cache.Add(newAddress, fixups);
            }
            else if (oldAddress != 0 && oldCount > 0)
            {
                // Reflexive was cached - just free it
                _allocator.Free(oldAddress, oldCount * layout.Size);
            }

            values.SetInteger("number of definition fixups", (uint)fixups.Count);
            values.SetInteger("definition fixup table address", newAddress);
        }
        private void SaveSizeParts(IList <ResourceSizePart> parts, StructureValueCollection values, IStream stream,
                                   TagBlockCache <ResourceSizePart> cache)
        {
            var  oldCount   = (int)values.GetIntegerOrDefault("number of size parts", 0);
            uint oldAddress = (uint)values.GetIntegerOrDefault("size part table address", 0);

            long expand = _expander.Expand(oldAddress);

            StructureLayout layout = _buildInfo.Layouts.GetLayout("size part table element");

            long newAddress;

            if (!cache.TryGetAddress(parts, out newAddress))
            {
                // Write a new block
                IEnumerable <StructureValueCollection> entries = parts.Select(p => SerializeSizePart(p));
                newAddress = TagBlockWriter.WriteTagBlock(entries, oldCount, expand, parts.Count, layout, _metaArea,
                                                          _allocator, stream);
                cache.Add(newAddress, parts);
            }
            else if (oldAddress != 0 && oldCount > 0)
            {
                // Block was cached - just free it
                _allocator.Free(expand, oldCount * layout.Size);
            }

            uint cont = _expander.Contract(newAddress);

            values.SetInteger("number of size parts", (uint)parts.Count);
            values.SetInteger("size part table address", cont);
        }
Esempio n. 5
0
        private void Load(StructureValueCollection values, ushort index, StringTableReader stringReader)
        {
            Index              = new DatumIndex((ushort)values.GetInteger("datum index salt"), index);
            Opcode             = (ushort)values.GetInteger("opcode");
            ReturnType         = (short)values.GetInteger("value type");
            Type               = (ScriptExpressionType)values.GetInteger("expression type");
            _nextIndex         = new DatumIndex(values.GetInteger("next expression index"));
            _stringTableOffset = (int)values.GetIntegerOrDefault("string table offset", 0);
            Value              = values.GetInteger("value");
            LineNumber         = (short)values.GetIntegerOrDefault("source line", 0);

            stringReader.RequestString(_stringTableOffset);
        }
Esempio n. 6
0
 private void Load(StructureValueCollection values)
 {
     Magic            = (int)values.GetInteger("magic");
     ParentMagic      = (int)values.GetInteger("parent magic");
     GrandparentMagic = (int)values.GetInteger("grandparent magic");
     Description      = new StringID(values.GetIntegerOrDefault("stringid", 0));
 }
Esempio n. 7
0
        /// <summary>
        ///     Deserializes a bounding box from a set of values read from a structure.
        /// </summary>
        /// <param name="values">The values to use.</param>
        /// <returns>The bounding box.</returns>
        public static BoundingBox Deserialize(StructureValueCollection values)
        {
            var result = new BoundingBox();

            result.MinX     = values.GetFloat("min x");
            result.MaxX     = values.GetFloat("max x");
            result.MinY     = values.GetFloat("min y");
            result.MaxY     = values.GetFloat("max y");
            result.MinZ     = values.GetFloat("min z");
            result.MaxZ     = values.GetFloat("max z");
            result.MinU     = values.GetFloat("min u");
            result.MaxU     = values.GetFloat("max u");
            result.MinV     = values.GetFloat("min v");
            result.MaxV     = values.GetFloat("max v");
            result.Unknown1 = (int)values.GetIntegerOrDefault("unknown 1", 3);
            result.Unknown2 = (int)values.GetIntegerOrDefault("unknown 2", 0);
            result.Unknown3 = (int)values.GetIntegerOrDefault("unknown 3", 0);
            result.Unknown4 = (int)values.GetIntegerOrDefault("unknown 4", 0);
            return(result);
        }
Esempio n. 8
0
        public IList <ResourcePointer> SaveResources(ICollection <Resource> resources, IStream stream)
        {
            StructureValueCollection values = LoadTag(stream);
            StructureLayout          layout = _buildInfo.Layouts.GetLayout("resource table entry");

            FreeResources(values, stream);
            FreeInfoBuffer(values);

            // Serialize each resource entry
            // This can't be lazily evaluated because allocations might cause the stream to expand
            int infoOffset    = 0;
            int altInfoOffset = 0;
            var infocache     = new ReflexiveCache <int>();

            var pointers      = new List <ResourcePointer>();
            var entries       = new List <StructureValueCollection>();
            var fixupCache    = new ReflexiveCache <ResourceFixup>();
            var defFixupCache = new ReflexiveCache <ResourceDefinitionFixup>();

            List <byte[]> paddedInfos = new List <byte[]>();

            foreach (Resource resource in resources)
            {
                StructureValueCollection entry = SerializeResource(resource, (resource.Location != null) ? pointers.Count : -1, stream);
                entries.Add(entry);

                // Save fixups
                SaveResourceFixups(resource.ResourceFixups, entry, stream, fixupCache);
                SaveDefinitionFixups(resource.DefinitionFixups, entry, stream, defFixupCache);

                uint bits = (uint)entry.GetInteger("resource bits");
                int  size = (int)entry.GetInteger("resource info size");

                List <int> offsets = new List <int>();

                if (size > 0)
                {
                    int dirtyoffset = infoOffset;

                    infoOffset = AlignInfoBlockOffset(resource, infoOffset);

                    offsets.Add(infoOffset);

                    int padding = infoOffset - dirtyoffset;

                    byte[] temp = new byte[padding + size];

                    Buffer.BlockCopy(resource.Info, 0, temp, padding, size);

                    paddedInfos.Add(temp);

                    infoOffset += size;
                }
                else
                {
                    offsets.Add(0);
                }

                if ((bits & 2) > 0)
                {
                    int tempalt = AlignInfoBlockOffset(resource, altInfoOffset);
                    offsets.Add(tempalt);

                    altInfoOffset += size;
                }
                else
                {
                    offsets.Add(size > 0 ? -1 : 0);
                }

                if ((bits & 4) > 0)
                {
                    int tempalt = AlignInfoBlockOffset(resource, altInfoOffset);
                    offsets.Add(tempalt);

                    altInfoOffset += size;
                }
                else
                {
                    offsets.Add(size > 0 ? -1 : 0);
                }

                if (layout.HasField("number of resource info offsets"))
                {
                    var  oldCount   = (int)entry.GetIntegerOrDefault("number of resource info offsets", 0);
                    uint oldAddress = (uint)entry.GetIntegerOrDefault("resource info offsets table address", 0);

                    long expand = _expander.Expand(oldAddress);

                    StructureLayout infolayout = _buildInfo.Layouts.GetLayout("resource info offset entry");

                    if (size > 0)
                    {
                        long newBlockAddress;

                        // Write a new reflexive
                        IEnumerable <StructureValueCollection> infoentries = offsets.Select(f => SerializeInfos(f));
                        newBlockAddress = ReflexiveWriter.WriteReflexive(infoentries, oldCount, expand, offsets.Count, infolayout, _metaArea,
                                                                         _allocator, stream);
                        infocache.Add(newBlockAddress, offsets);

                        uint cont = _expander.Contract(newBlockAddress);

                        entry.SetInteger("number of resource info offsets", (uint)offsets.Count);
                        entry.SetInteger("resource info offsets table address", cont);
                    }
                    else
                    {
                        entry.SetInteger("number of resource info offsets", 0);
                        entry.SetInteger("resource info offsets table address", 0);
                    }
                }
                else
                {
                    if (size > 0)
                    {
                        entry.SetInteger("resource info offset", (uint)offsets[0]);
                        entry.SetInteger("alt resource info offset", (uint)offsets[1]);
                    }
                    else
                    {
                        entry.SetInteger("resource info offset", 0);
                        entry.SetInteger("alt resource info offset", 0);
                    }
                }

                // Update pointer info
                if (resource.Location != null)
                {
                    pointers.Add(resource.Location);
                }
            }

            // Write the reflexive and update the tag values
            long newAddress = ReflexiveWriter.WriteReflexive(entries, layout, _metaArea, _allocator, stream);

            uint contr = _expander.Contract(newAddress);

            values.SetInteger("number of resources", (uint)entries.Count);
            values.SetInteger("resource table address", contr);

            // Save the info buffer
            SaveResourceInfoBuffer(paddedInfos.SelectMany(a => a).ToArray(), values, stream);

            SaveTag(values, stream);
            return(pointers);
        }