public void SavePages(ICollection <ResourcePage> pages, ICollection <ResourcePointer> pointers, IStream stream)
        {
            StructureValueCollection values = LoadTag(stream);

            ThirdGenCacheFileReference[] files = LoadExternalFiles(values, stream);

            StructureLayout layout     = _buildInfo.Layouts.GetLayout("raw page table element");
            var             oldCount   = (int)values.GetInteger("number of raw pages");
            uint            oldAddress = (uint)values.GetInteger("raw page table address");

            long expand = _expander.Expand(oldAddress);

            // recount asset count values for every page for predictions
            foreach (ResourcePage p in pages)
            {
                p.AssetCount = pointers.Count(x => x.PrimaryPage == p || x.SecondaryPage == p || x.TertiaryPage == p);
            }

            IEnumerable <StructureValueCollection> entries = pages.Select(p => SerializePage(p, files));
            long newAddress = TagBlockWriter.WriteTagBlock(entries, oldCount, expand, pages.Count, layout, _metaArea,
                                                           _allocator, stream);

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

            values.SetInteger("number of raw pages", (uint)pages.Count);
            values.SetInteger("raw page table address", cont);
            SaveTag(values, stream);
        }
Exemple #2
0
        public void SaveChanges(IStream stream)
        {
            if (!_changed)
            {
                return;
            }

            var scenarioLayout = _buildInfo.Layouts.GetLayout("scnr");

            stream.SeekTo(_scenario.MetaLocation.AsOffset());
            var scenarioData = StructureReader.ReadStructure(stream, scenarioLayout);
            var oldCount     = (int)scenarioData.GetInteger("simulation definition table count");
            var oldAddress   = (uint)scenarioData.GetInteger("simulation definition table address");

            long expand = _expander.Expand(oldAddress);

            var entryLayout = _buildInfo.Layouts.GetLayout("simulation definition table entry");

            var newTable = _table.Select(SerializeTag);
            var newAddr  = ReflexiveWriter.WriteReflexive(newTable, oldCount, expand, _table.Count, entryLayout, _metaArea, _allocator, stream);

            uint cont = _expander.Contract(newAddr);

            scenarioData.SetInteger("simulation definition table count", (uint)_table.Count);
            scenarioData.SetInteger("simulation definition table address", cont);
            stream.SeekTo(_scenario.MetaLocation.AsOffset());
            StructureWriter.WriteStructure(scenarioData, scenarioLayout, stream);
            _changed = false;
        }
        private void SaveBitArray(BitArray bits, string countName, string addressName, MetaAllocator allocator, IStream stream, ReflexiveCache <int> cache, StructureValueCollection values, IPointerExpander expander)
        {
            if (bits.Length == 0)
            {
                values.SetInteger(countName, 0);
                values.SetInteger(addressName, 0);
                return;
            }

            var ints = bits.ToIntArray();

            // If the address isn't cached, then allocate space and write a new array
            long 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);
            }

            uint cont = expander.Contract(newAddress);

            values.SetInteger(countName, (uint)ints.Length);
            values.SetInteger(addressName, cont);
        }
Exemple #4
0
		public StructureValueCollection Serialize(IList<ITagGroup> groupList, IPointerExpander expander)
		{
			var result = new StructureValueCollection();

			uint cont = 0;
			if (MetaLocation != null)
				cont = expander.Contract(MetaLocation.AsPointer());

			result.SetInteger("memory address", cont);
			result.SetInteger("tag group index", (Group != null) ? (uint) groupList.IndexOf(Group) : 0xFFFFFFFF);
			result.SetInteger("datum index salt", Index.Salt);
			return result;
		}
Exemple #5
0
        public StructureValueCollection Serialize(IList <ITagClass> classList, IPointerExpander expander)
        {
            var result = new StructureValueCollection();

            uint cont = 0;

            if (MetaLocation != null)
            {
                cont = expander.Contract(MetaLocation.AsPointer());
            }

            result.SetInteger("memory address", cont);
            result.SetInteger("class index", (Class != null) ? (uint)classList.IndexOf(Class) : 0xFFFFFFFF);
            result.SetInteger("datum index salt", Index.Salt);
            return(result);
        }
Exemple #6
0
        private void SaveData(IStream stream, EffectInteropType type)
        {
            long pointer;

            byte[] data;
            switch (type)
            {
            case EffectInteropType.Effect:
                pointer = _effePointer;
                data    = _effe.SelectMany(a => a).ToArray();
                break;

            case EffectInteropType.Beam:
                pointer = _beamPointer;
                data    = _beam.SelectMany(a => a).ToArray();
                break;

            case EffectInteropType.Contrail:
                pointer = _cntlPointer;
                data    = _cntl.SelectMany(a => a).ToArray();
                break;

            case EffectInteropType.LightVolume:
                pointer = _ltvlPointer;
                data    = _ltvl.SelectMany(a => a).ToArray();
                break;

            default:
                return;
            }

            var pointerLayout = _buildInfo.Layouts.GetLayout("data reference");

            stream.SeekTo(_metaArea.PointerToOffset(pointer));
            var pointerData = StructureReader.ReadStructure(stream, pointerLayout);

            var oldSize    = (int)pointerData.GetInteger("size");
            var oldAddress = (uint)pointerData.GetInteger("pointer");

            var oldExpand = _expander.Expand(oldAddress);

            if (oldExpand >= 0 && oldSize > 0)
            {
                _allocator.Free(oldExpand, oldSize);
            }

            long newAddress = 0;

            if (data.Length > 0)
            {
                newAddress = _allocator.Allocate(data.Length, 0x10, stream);
                stream.SeekTo(_metaArea.PointerToOffset(newAddress));
                stream.WriteBlock(data);
            }

            uint cont = _expander.Contract(newAddress);

            pointerData.SetInteger("size", (ulong)data.Length);
            pointerData.SetInteger("pointer", cont);

            stream.SeekTo(_metaArea.PointerToOffset(pointer));
            StructureWriter.WriteStructure(pointerData, pointerLayout, stream);
        }
Exemple #7
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 #8
0
        /// <summary>
        ///     Frees the old Script Parameters and writes new ones to the stream.
        /// </summary>
        /// <param name="data">The new script data</param>
        /// <param name="stream">The stream to write to</param>
        /// <param name="scnr">scnr Meta Data</param>
        /// <returns>A dictionary containing the hashes of parameter groups an their new addresses.</returns>
        private Dictionary <int, uint> WriteParams(ScriptData data, IStream stream, StructureValueCollection scnr)
        {
            StructureLayout scrlayout   = _buildInfo.Layouts.GetLayout("script element");
            StructureLayout paramlayout = _buildInfo.Layouts.GetLayout("script parameter element");

            int  oldScriptCount      = (int)scnr.GetInteger("number of scripts");
            uint oldScriptAddress    = (uint)scnr.GetInteger("script table address");
            long expOldScriptAddress = _expander.Expand(oldScriptAddress);
            int  oldParamSize        = 0;

            StructureValueCollection[] oldScripts = TagBlockReader.ReadTagBlock(stream, oldScriptCount, expOldScriptAddress, scrlayout, _metaArea);

            HashSet <uint> freedParamAddresses = new HashSet <uint>();

            int oldTotalParamCount = 0;

            // loop through old scripts
            for (int i = 0; i < oldScripts.Length; i++)
            {
                int  paramCount = (int)oldScripts[i].GetInteger("number of parameters");
                uint addr       = (uint)oldScripts[i].GetInteger("address of parameter list");

                oldTotalParamCount += paramCount;

                // free params
                if (addr != 0 && !freedParamAddresses.Contains(addr))
                {
                    long exp       = _expander.Expand(addr);
                    int  blockSize = paramCount * paramlayout.Size;
                    _allocator.Free(exp, blockSize);
                    oldParamSize += blockSize;
                    freedParamAddresses.Add(addr);
                }
            }

            int newTotalParamCount = 0;
            int newParamSize       = 0;
            Dictionary <int, uint> newParamAddresses = new Dictionary <int, uint>();

            // loop through new scripts
            foreach (var scr in data.Scripts)
            {
                int count = scr.Parameters.Count;

                if (count > 0)
                {
                    int paramHash = SequenceHash.GetSequenceHashCode(scr.Parameters);
                    if (!newParamAddresses.ContainsKey(paramHash))
                    {
                        long newAddr    = _allocator.Allocate(paramlayout.Size * count, stream);
                        uint conNewAddr = _expander.Contract(newAddr);
                        stream.SeekTo(_metaArea.PointerToOffset(newAddr));
                        // write params to stream
                        foreach (var par in scr.Parameters)
                        {
                            par.Write(stream);
                        }

                        newParamAddresses.Add(paramHash, conNewAddr);
                        newParamSize += scr.Parameters.Count * 36;
                    }
                }
                newTotalParamCount += scr.Parameters.Count;
            }

            return(newParamAddresses);
        }