Example #1
0
        private void SaveResourceInfoBuffer(byte[] buffer, StructureValueCollection values, IStream stream)
        {
            // Free the old info buffer
            var  oldSize    = (int)values.GetInteger("resource info buffer size");
            uint oldAddress = values.GetInteger("resource info buffer address");

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

            // Write a new one
            uint newAddress = 0;

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

            // Update values
            values.SetInteger("resource info buffer size", (uint)buffer.Length);
            values.SetInteger("resource info buffer address", newAddress);
        }
Example #2
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);
        }
Example #3
0
        private void SaveBitArray(BitArray bits, string countName, string addressName, MetaAllocator allocator, IStream stream, TagBlockCache <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);
        }
Example #4
0
        private void SaveResourceInfoBuffer(byte[] buffer, StructureValueCollection values, IStream stream)
        {
            long newAddress = 0;

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

            // Update values

            uint cont = _expander.Contract(newAddress);

            values.SetInteger("resource info buffer size", (uint)buffer.Length);
            values.SetInteger("resource info buffer address", cont);
        }
Example #5
0
        /// <summary>
        ///     Adds a tag to the table and allocates space for its base data.
        /// </summary>
        /// <param name="classMagic">The magic number (ID) of the tag's class.</param>
        /// <param name="baseSize">The size of the data to initially allocate for the tag.</param>
        /// <param name="stream">The stream to write to.</param>
        /// <returns>
        ///     The tag that was allocated.
        /// </returns>
        public override ITag AddTag(int classMagic, int baseSize, IStream stream)
        {
            /*
             *          //if (_indexHeaderLocation == null)
             *          //	throw new InvalidOperationException("Tags cannot be added to a shared map");
             *
             *          ITagClass tagClass = Classes.FirstOrDefault(c => (c.Magic == classMagic));
             *          if (tagClass == null)
             *                  throw new InvalidOperationException("Invalid tag class");
             *
             *          uint address = _allocator.Allocate(baseSize, stream);
             *          var index = new DatumIndex(0x4153, (ushort) _tags.Count); // 0x4153 = 'AS' because the salt doesn't matter
             * var result = new FourthGenTag(index, tagClass, (uint)stream.Position);
             *          _tags.Add(result);
             *
             *          return result;
             * */

            ITagClass tagClass = Classes.FirstOrDefault(c => (c.Magic == classMagic));

            if (tagClass == null)
            {
                throw new InvalidOperationException("Invalid tag class");
            }

            var  offset  = stream.BaseStream.Position;
            uint address = _allocator.Allocate(baseSize, stream);
            var  index   = new DatumIndex(0x4153, (ushort)_tags.Count); // 0x4153 = 'AS' because the salt doesn't matter

            // File Segment
            FileSegmenter segmenter = new FileSegmenter();

            segmenter.DefineSegment(0, (int)stream.Length, 0x4, SegmentResizeOrigin.Beginning); // Define a segment for the header
            //_eofSegment = segmenter.WrapEOF((int)map_values.GetInteger("file size"));
            FileSegment      segment      = new FileSegment(0, segmenter);
            FileSegmentGroup segmentgroup = new FileSegmentGroup();

            SegmentPointer pointer = new SegmentPointer(segment, segmentgroup, (int)offset);
            FourthGenTag   result  = new FourthGenTag(index, tagClass, pointer, pointer);

            _tags.Add(result);

            return(result);
        }
Example #6
0
        /// <summary>
        ///     Adds a tag to the table and allocates space for its base data.
        /// </summary>
        /// <param name="classMagic">The magic number (ID) of the tag's class.</param>
        /// <param name="baseSize">The size of the data to initially allocate for the tag.</param>
        /// <param name="stream">The stream to write to.</param>
        /// <returns>
        ///     The tag that was allocated.
        /// </returns>
        public override ITag AddTag(int classMagic, int baseSize, IStream stream)
        {
            if (_indexHeaderLocation == null)
            {
                throw new InvalidOperationException("Tags cannot be added to a shared map");
            }

            ITagClass tagClass = Classes.FirstOrDefault(c => (c.Magic == classMagic));

            if (tagClass == null)
            {
                throw new InvalidOperationException("Invalid tag class");
            }

            uint address = _allocator.Allocate(baseSize, stream);
            var  index   = new DatumIndex(0x4153, (ushort)_tags.Count);           // 0x4153 = 'AS' because the salt doesn't matter
            var  result  = new ThirdGenTag(index, tagClass, SegmentPointer.FromPointer(address, _metaArea));

            _tags.Add(result);

            return(result);
        }
Example #7
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);
        }
Example #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);
        }