Exemple #1
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);
        }
Exemple #2
0
        private void SaveSizeParts(IList <ResourceSizePart> parts, StructureValueCollection values, IStream stream,
                                   ReflexiveCache <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 entry");

            long newAddress;

            if (!cache.TryGetAddress(parts, out newAddress))
            {
                // Write a new reflexive
                IEnumerable <StructureValueCollection> entries = parts.Select(p => SerializeSizePart(p));
                newAddress = ReflexiveWriter.WriteReflexive(entries, oldCount, expand, parts.Count, layout, _metaArea,
                                                            _allocator, stream);
                cache.Add(newAddress, parts);
            }
            else if (oldAddress != 0 && oldCount > 0)
            {
                // Reflexive 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);
        }
Exemple #3
0
        public void SaveSizes(ICollection <ResourceSize> sizes, IStream stream)
        {
            StructureValueCollection values = LoadTag(stream);

            var entries   = new List <StructureValueCollection>();
            var partCache = new ReflexiveCache <ResourceSizePart>();

            foreach (ResourceSize size in sizes)
            {
                StructureValueCollection entry = SerializeSize(size);
                entries.Add(entry);
                SaveSizeParts(size.Parts, entry, stream, partCache);
            }


            StructureLayout layout     = _buildInfo.Layouts.GetLayout("raw size table entry");
            var             oldCount   = (int)values.GetInteger("number of raw sizes");
            uint            oldAddress = (uint)values.GetInteger("raw size table address");

            long expand = _expander.Expand(oldAddress);

            long newAddress = ReflexiveWriter.WriteReflexive(entries, oldCount, expand, sizes.Count, layout, _metaArea,
                                                             _allocator, stream);

            // Update values
            uint cont = _expander.Contract(newAddress);

            values.SetInteger("number of raw sizes", (uint)sizes.Count);
            values.SetInteger("raw size table address", cont);
            SaveTag(values, stream);
        }
Exemple #4
0
        public IList <ResourcePointer> SaveResources(ICollection <Resource> resources, IStream stream)
        {
            StructureValueCollection values = LoadTag(stream);

            // Free everything
            FreeResources(values, stream);

            // Serialize each resource entry
            // This can't be lazily evaluated because allocations might cause the stream to expand
            int infoOffset    = 0;
            var pointers      = new List <ResourcePointer>();
            var entries       = new List <StructureValueCollection>();
            var fixupCache    = new ReflexiveCache <ResourceFixup>();
            var defFixupCache = new ReflexiveCache <ResourceDefinitionFixup>();

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

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

                // Update info offset and pointer info
                if (resource.Info != null)
                {
                    infoOffset += resource.Info.Length;
                }
                if (resource.Location != null)
                {
                    pointers.Add(resource.Location);
                }
            }

            // Write the reflexive and update the tag values
            StructureLayout layout     = _buildInfo.Layouts.GetLayout("resource table entry");
            uint            newAddress = ReflexiveWriter.WriteReflexive(entries, layout, _metaArea, _allocator, stream);

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

            // Build and save the info buffer
            byte[] infoBuffer = BuildResourceInfoBuffer(resources);
            SaveResourceInfoBuffer(infoBuffer, values, stream);

            SaveTag(values, stream);
            return(pointers);
        }
        public IList<ResourcePointer> SaveResources(ICollection<Resource> resources, IStream stream)
        {
            StructureValueCollection values = LoadTag(stream);

            // Free everything
            FreeResources(values, stream);

            // Serialize each resource entry
            // This can't be lazily evaluated because allocations might cause the stream to expand
            int infoOffset = 0;
            var pointers = new List<ResourcePointer>();
            var entries = new List<StructureValueCollection>();
            var fixupCache = new ReflexiveCache<ResourceFixup>();
            var defFixupCache = new ReflexiveCache<ResourceDefinitionFixup>();
            foreach (Resource resource in resources)
            {
                infoOffset = AlignInfoBlockOffset(resource, infoOffset);
                StructureValueCollection entry = SerializeResource(resource, (resource.Location != null) ? pointers.Count : -1,
                    (resource.Info != null) ? infoOffset : 0, stream);
                entries.Add(entry);

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

                // Update info offset and pointer info
                if (resource.Info != null)
                    infoOffset += resource.Info.Length;
                if (resource.Location != null)
                    pointers.Add(resource.Location);
            }

            // Write the reflexive and update the tag values
            StructureLayout layout = _buildInfo.Layouts.GetLayout("resource table entry");
            uint newAddress = ReflexiveWriter.WriteReflexive(entries, layout, _metaArea, _allocator, stream);
            values.SetInteger("number of resources", (uint) entries.Count);
            values.SetInteger("resource table address", newAddress);

            // Build and save the info buffer
            byte[] infoBuffer = BuildResourceInfoBuffer(resources);
            SaveResourceInfoBuffer(infoBuffer, values, stream);

            SaveTag(values, stream);
            return pointers;
        }
		/// <summary>
		///     Saves changes made to zone sets in the table.
		/// </summary>
		/// <param name="stream">The stream to write to.</param>
		/// <exception cref="System.NotImplementedException"></exception>
		public void SaveChanges(IStream stream)
		{
			StructureValueCollection tagValues = _gestalt.LoadTag(stream);
			FreeZoneSets(tagValues, stream);

			var cache = new ReflexiveCache<int>();
			SaveZoneSetTable(GlobalZoneSet, tagValues, "number of global zone sets", "global zone set table address", cache, stream);
			SaveZoneSetTable(UnattachedZoneSet, tagValues, "number of unattached zone sets", "unattached zone set table address", cache, stream);
			SaveZoneSetTable(DiscForbiddenZoneSet, tagValues, "number of disc forbidden zone sets", "disc forbidden zone set table address", cache, stream);
			SaveZoneSetTable(DiscAlwaysStreamingZoneSet, tagValues, "number of disc always streaming zone sets", "disc always streaming zone set table address", cache, stream);
			SaveZoneSetTable(GeneralZoneSets, tagValues, "number of general zone sets", "general zone set table address", cache, stream);
			SaveZoneSetTable(BSPZoneSets, tagValues, "number of bsp zone sets", "bsp zone set table address", cache, stream);
			SaveZoneSetTable(BSPZoneSets2, tagValues, "number of bsp 2 zone sets", "bsp 2 zone set table address", cache, stream);
			SaveZoneSetTable(BSPZoneSets3, tagValues, "number of bsp 3 zone sets", "bsp 3 zone set table address", cache, stream);
			SaveZoneSetTable(CinematicZoneSets, tagValues, "number of cinematic zone sets", "cinematic zone set table address", cache, stream);
			SaveZoneSetTable(CustomZoneSets, tagValues, "number of custom zone sets", "custom zone set table address", cache, stream);

			_gestalt.SaveTag(tagValues, stream);
		}
        /// <summary>
        ///     Saves changes made to zone sets in the table.
        /// </summary>
        /// <param name="stream">The stream to write to.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        public void SaveChanges(IStream stream)
        {
            StructureValueCollection tagValues = _gestalt.LoadTag(stream);

            FreeZoneSets(tagValues, stream);

            var cache = new ReflexiveCache <int>();

            SaveZoneSetTable(GlobalZoneSet, tagValues, "number of global zone sets", "global zone set table address", cache, stream);
            SaveZoneSetTable(UnattachedZoneSet, tagValues, "number of unattached zone sets", "unattached zone set table address", cache, stream);
            SaveZoneSetTable(DiscForbiddenZoneSet, tagValues, "number of disc forbidden zone sets", "disc forbidden zone set table address", cache, stream);
            SaveZoneSetTable(DiscAlwaysStreamingZoneSet, tagValues, "number of disc always streaming zone sets", "disc always streaming zone set table address", cache, stream);
            SaveZoneSetTable(GeneralZoneSets, tagValues, "number of general zone sets", "general zone set table address", cache, stream);
            SaveZoneSetTable(BSPZoneSets, tagValues, "number of bsp zone sets", "bsp zone set table address", cache, stream);
            SaveZoneSetTable(BSPZoneSets2, tagValues, "number of bsp 2 zone sets", "bsp 2 zone set table address", cache, stream);
            SaveZoneSetTable(BSPZoneSets3, tagValues, "number of bsp 3 zone sets", "bsp 3 zone set table address", cache, stream);
            SaveZoneSetTable(CinematicZoneSets, tagValues, "number of cinematic zone sets", "cinematic zone set table address", cache, stream);
            SaveZoneSetTable(CustomZoneSets, tagValues, "number of custom zone sets", "custom zone set table address", cache, stream);

            _gestalt.SaveTag(tagValues, stream);
        }
        private void SaveZoneSetTable(IZoneSet[] sets, StructureValueCollection tagValues, string countName, string addressName, ReflexiveCache <int> cache, IStream stream)
        {
            if (!tagValues.HasInteger(countName) || !tagValues.HasInteger(addressName))
            {
                return;
            }

            var count = (int)tagValues.GetInteger(countName);

            if (count != sets.Length)
            {
                throw new InvalidOperationException("Zone set count does not match");
            }

            uint address = (uint)tagValues.GetInteger(addressName);

            long expand = _expander.Expand(address);

            StructureLayout layout = _buildInfo.Layouts.GetLayout("zone set definition");
            List <StructureValueCollection> entries =
                sets.Select(set => ((ThirdGenZoneSet)set).Serialize(stream, _allocator, cache, _expander)).ToList();

            ReflexiveWriter.WriteReflexive(entries, expand, layout, _metaArea, stream);
        }
 private void SaveZoneSetTable(IZoneSet set, StructureValueCollection tagValues, string countName, string addressName, ReflexiveCache <int> cache, IStream stream)
 {
     SaveZoneSetTable(new[] { set }, tagValues, countName, addressName, cache, stream);
 }
        private void SaveResourceFixups(IList<ResourceFixup> fixups, StructureValueCollection values, IStream stream,
			ReflexiveCache<ResourceFixup> cache)
        {
            var oldCount = (int) values.GetIntegerOrDefault("number of resource fixups", 0);
            uint oldAddress = values.GetIntegerOrDefault("resource fixup table address", 0);
            StructureLayout layout = _buildInfo.Layouts.GetLayout("resource fixup entry");

            uint newAddress;
            if (!cache.TryGetAddress(fixups, out newAddress))
            {
                // Write a new reflexive
                IEnumerable<StructureValueCollection> entries = fixups.Select(f => SerializeResourceFixup(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 resource fixups", (uint) fixups.Count);
            values.SetInteger("resource fixup table address", newAddress);
        }
		private void SaveZoneSetTable(IZoneSet[] sets, StructureValueCollection tagValues, string countName, string addressName, ReflexiveCache<int> cache, IStream stream)
		{
			if (!tagValues.HasInteger(countName) || !tagValues.HasInteger(addressName))
				return;

			var count = (int) tagValues.GetInteger(countName);
			if (count != sets.Length)
				throw new InvalidOperationException("Zone set count does not match");

			uint address = tagValues.GetInteger(addressName);
			StructureLayout layout = _buildInfo.Layouts.GetLayout("zone set definition");
			List<StructureValueCollection> entries =
				sets.Select(set => ((FourthGenZoneSet) set).Serialize(stream, _allocator, cache)).ToList();
			ReflexiveWriter.WriteReflexive(entries, address, layout, _metaArea, stream);
		}
Exemple #12
0
        private void SaveBitArray(BitArray bits, string countName, string addressName, MetaAllocator allocator, IStream stream, ReflexiveCache <int> cache, StructureValueCollection values)
        {
            if (bits.Length == 0)
            {
                values.SetInteger(countName, 0);
                values.SetInteger(addressName, 0);
                return;
            }

            var ints = new int[((bits.Length + 31) & ~31) / 32];

            bits.CopyTo(ints, 0);

            // If the address isn't cached, then allocate space and write a new array
            uint newAddress;

            if (!cache.TryGetAddress(ints, out newAddress))
            {
                newAddress = allocator.Allocate(ints.Length * 4, stream);
                stream.SeekTo(_metaArea.PointerToOffset(newAddress));
                foreach (int i in ints)
                {
                    stream.WriteInt32(i);
                }

                cache.Add(newAddress, ints);
            }

            values.SetInteger(countName, (uint)ints.Length);
            values.SetInteger(addressName, newAddress);
        }
Exemple #13
0
        public StructureValueCollection Serialize(IStream stream, MetaAllocator allocator, ReflexiveCache <int> cache)
        {
            var result = new StructureValueCollection();

            SaveBitArray(_activeResources, "number of raw pool bitfields", "raw pool bitfield table address", allocator, stream, cache, result);
            SaveBitArray(_unknownResources, "number of raw pool 2 bitfields", "raw pool 2 bitfield table address", allocator, stream, cache, result);
            SaveBitArray(_unknownResources2, "number of raw pool 3 bitfields", "raw pool 3 bitfield table address", allocator, stream, cache, result);
            SaveBitArray(_activeTags, "number of tag bitfields", "tag bitfield table address", allocator, stream, cache, result);
            SaveBitArray(_unknownTags, "number of tag 2 bitfields", "tag 2 bitfield table address", allocator, stream, cache, result);
            return(result);
        }
Exemple #14
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);
        }
Exemple #15
0
		public StructureValueCollection Serialize(IStream stream, MetaAllocator allocator, ReflexiveCache<int> cache)
		{
			var result = new StructureValueCollection();
			SaveBitArray(_activeResources, "number of raw pool bitfields", "raw pool bitfield table address", allocator, stream, cache, result);
			SaveBitArray(_unknownResources, "number of raw pool 2 bitfields", "raw pool 2 bitfield table address", allocator, stream, cache, result);
			SaveBitArray(_unknownResources2, "number of raw pool 3 bitfields", "raw pool 3 bitfield table address", allocator, stream, cache, result);
			SaveBitArray(_activeTags, "number of tag bitfields", "tag bitfield table address", allocator, stream, cache, result);
			SaveBitArray(_unknownTags, "number of tag 2 bitfields", "tag 2 bitfield table address", allocator, stream, cache, result);
			return result;
		}
Exemple #16
0
		private void SaveBitArray(BitArray bits, string countName, string addressName, MetaAllocator allocator, IStream stream, ReflexiveCache<int> cache, StructureValueCollection values)
		{
			if (bits.Length == 0)
			{
				values.SetInteger(countName, 0);
				values.SetInteger(addressName, 0);
				return;
			}

			var ints = new int[((bits.Length + 31) & ~31)/32];
			bits.CopyTo(ints, 0);

			// If the address isn't cached, then allocate space and write a new array
			uint newAddress;
			if (!cache.TryGetAddress(ints, out newAddress))
			{
				newAddress = allocator.Allocate(ints.Length*4, stream);
				stream.SeekTo(_metaArea.PointerToOffset(newAddress));
				foreach (int i in ints)
					stream.WriteInt32(i);

				cache.Add(newAddress, ints);
			}

			values.SetInteger(countName, (uint)ints.Length);
			values.SetInteger(addressName, newAddress);
		}
		private void SaveZoneSetTable(IZoneSet set, StructureValueCollection tagValues, string countName, string addressName, ReflexiveCache<int> cache, IStream stream)
		{
			SaveZoneSetTable(new[] {set}, tagValues, countName, addressName, cache, stream);
		}