Пример #1
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");

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

            var newTable = _table.Select(SerializeTag);
            var newAddr  = TagBlockWriter.WriteTagBlock(newTable, oldCount, oldAddress, _table.Count, entryLayout, _metaArea, _allocator, stream);

            scenarioData.SetInteger("simulation definition table count", (uint)_table.Count);
            scenarioData.SetInteger("simulation definition table address", (uint)newAddr);
            stream.SeekTo(_scenario.MetaLocation.AsOffset());
            StructureWriter.WriteStructure(scenarioData, scenarioLayout, stream);
            _changed = false;
        }
Пример #2
0
        public void VisitTagRef(TagRefData field)
        {
            SeekToOffset(field.Offset);

            if (field.WithGroup)
            {
                var values = new StructureValueCollection();
                if (field.Value != null)
                {
                    //hax
                    if (field.Value.RawTag == null)
                    {
                        values.SetInteger("tag group magic", (uint)field.Group.RawGroup.Magic);
                        values.SetInteger("datum index", 0xFFFFFFFF);
                    }
                    else
                    {
                        values.SetInteger("tag group magic", (uint)field.Value.RawTag.Group.Magic);
                        values.SetInteger("datum index", field.Value.RawTag.Index.Value);
                    }
                }
                else
                {
                    values.SetInteger("tag group magic", 0xFFFFFFFF);
                    values.SetInteger("datum index", 0xFFFFFFFF);
                }
                StructureWriter.WriteStructure(values, _tagRefLayout, _writer);
            }
            else
            {
                _writer.WriteUInt32(field.Value == null ? 0xFFFFFFFF : field.Value.RawTag.Index.Value);
            }
        }
Пример #3
0
        public void SaveScripts(ScriptData data, IStream stream, IProgress <int> progress)
        {
            progress.Report(0);
            StructureValueCollection values     = LoadScriptTag(stream, _scnrTag);
            StructureLayout          scnrLayout = _buildInfo.Layouts.GetLayout("scnr");

            progress.Report(10);

            WriteExpressions(data, stream, values);
            progress.Report(40);

            WriteStrings(data, stream, values);
            progress.Report(50);

            WriteGlobals(data, stream, values);
            progress.Report(60);

            WriteTagReferences(data, stream, values);
            progress.Report(70);

            WriteScripts(data, stream, values);
            progress.Report(90);

            stream.SeekTo(_scnrTag.MetaLocation.AsOffset());
            StructureWriter.WriteStructure(values, scnrLayout, stream);
            progress.Report(100);
        }
Пример #4
0
        private void WriteLocalePointer(IWriter writer, StringID id, int offset)
        {
            var values = new StructureValueCollection();

            values.SetInteger("stringid", id.Value);
            values.SetInteger("offset", (uint)offset);
            StructureWriter.WriteStructure(values, _pointerLayout, writer);
        }
Пример #5
0
 private void SaveHeader(StructureValueCollection headerValues, StructureLayout headerLayout, IWriter writer)
 {
     if (_metaArea != null)
     {
         writer.SeekTo(_metaArea.Offset);
         StructureWriter.WriteStructure(headerValues, headerLayout, writer);
     }
 }
Пример #6
0
        public void VisitDataRef(DataRef field)
        {
            var values = new StructureValueCollection();

            values.SetInteger("size", (uint)field.Length);

            SeekToOffset(field.Offset);
            StructureWriter.WriteStructure(values, _dataRefLayout, _writer);

            if (field.DataAddress == 0xFFFFFFFF || field.DataAddress <= 0)
            {
                return;
            }

            // Go to the data location
            uint offset     = field.DataAddress;
            uint dataOffset = offset;

            switch (_type)
            {
            case SaveType.Memory:
            {
                if (_cache.GetType() != typeof(Blamite.Blam.FourthGen.FourthGenCacheFile))
                {
                    values.SetInteger("pointer", offset);
                }
                break;
            }

            case SaveType.File:
            {
                if (_cache.GetType() == typeof(Blamite.Blam.FourthGen.FourthGenCacheFile))
                {
                    offset = offset - _headerOffset + 0x40000000;
                }
                values.SetInteger("pointer", offset);
                dataOffset = (uint)_cache.MetaArea.PointerToOffset(dataOffset);
                break;
            }
            }
            _writer.SeekTo(dataOffset);

            // Write its data
            switch (field.Format)
            {
            default:
                _writer.WriteBlock(FunctionHelpers.HexStringToBytes(field.Value), 0, field.Length);
                break;

            case "unicode":
                _writer.WriteUTF16(field.Value);
                break;

            case "asciiz":
                _writer.WriteAscii(field.Value);
                break;
            }
        }
Пример #7
0
 private void SaveHeader(StructureValueCollection headerValues, IWriter writer)
 {
     if (_indexHeaderLocation != null)
     {
         writer.SeekTo(_indexHeaderLocation.AsOffset());
         StructureLayout headerLayout = _buildInfo.Layouts.GetLayout("index header");
         StructureWriter.WriteStructure(headerValues, headerLayout, writer);
     }
 }
Пример #8
0
        private void WriteHeader(IWriter writer)
        {
            // Update tagname and stringid info (so. ugly.)
            _header.FileNameCount = _fileNames.Count;
            _header.StringIDCount = _stringIDs.Count;

            writer.SeekTo(0);
            StructureWriter.WriteStructure(_header.Serialize(), _buildInfo.Layouts.GetLayout("header"), writer);
        }
Пример #9
0
        public void VisitReflexive(ReflexiveData field)
        {
            var values = new StructureValueCollection();

            values.SetInteger("entry count", (uint)field.Length);
            values.SetInteger("pointer", field.FirstEntryAddress);

            SeekToOffset(field.Offset);
            StructureWriter.WriteStructure(values, _reflexiveLayout, _writer);
        }
        /// <summary>
        ///     Saves changes made to the string list.
        /// </summary>
        /// <param name="writer">The stream to write to.</param>
        public void SaveChanges(IWriter writer)
        {
            var values = new StructureValueCollection();

            StructureValueCollection[] rangeValues = Ranges.Select(r => r.Serialize()).ToArray();
            values.SetArray("language ranges", rangeValues);

            writer.SeekTo(Tag.MetaLocation.AsOffset());
            StructureWriter.WriteStructure(values, _layout, writer);
        }
 private void SaveTag(StructureValueCollection values, IWriter writer)
 {
     writer.SeekTo(_tag.MetaLocation.AsOffset());
     if (!_zone)
     {
         StructureWriter.WriteStructure(values, _buildInfo.Layouts.GetLayout("resource layout table"), writer);
     }
     else
     {
         StructureWriter.WriteStructure(values, _buildInfo.Layouts.GetLayout("resource layout table alt"), writer);
     }
 }
Пример #12
0
        private void WriteHeader(IWriter writer)
        {
            // Update tagname and stringid info (so. ugly.)
            _header.FileNameCount = _fileNames.Count;
            _header.StringIDCount = _stringIds.Count;

            // Serialize and write the header
            StructureValueCollection values = _header.Serialize(_languageInfo.LocaleArea);

            writer.SeekTo(0);
            StructureWriter.WriteStructure(values, _buildInfo.Layouts.GetLayout("header"), writer);
        }
Пример #13
0
        public void VisitReflexive(ReflexiveData field)
        {
            var values = new StructureValueCollection();

            values.SetInteger("entry count", _cache.MetaArea.ContainsBlockPointer(field.FirstEntryAddress, (int)(field.Length * field.EntrySize)) ? (uint)field.Length : 0);

            uint cont = _cache.PointerExpander.Contract(field.FirstEntryAddress);

            values.SetInteger("pointer", cont);

            SeekToOffset(field.Offset);
            StructureWriter.WriteStructure(values, _reflexiveLayout, _writer);
        }
Пример #14
0
        /// <summary>
        ///     Writes data to a block at a particular address.
        /// </summary>
        /// <param name="elements">The entries to write.</param>
        /// <param name="address">The address to write to.</param>
        /// <param name="layout">The layout of the data to write.</param>
        /// <param name="metaArea">The meta area of the cache file.</param>
        /// <param name="writer">The stream to write to.</param>
        public static void WriteTagBlock(IEnumerable <StructureValueCollection> elements, long address, StructureLayout layout,
                                         FileSegmentGroup metaArea, IWriter writer)
        {
            int offset = metaArea.PointerToOffset(address);
            int index  = 0;

            foreach (StructureValueCollection element in elements)
            {
                writer.SeekTo(offset + index * layout.Size);
                StructureWriter.WriteStructure(element, layout, writer);
                index++;
            }
        }
Пример #15
0
        /// <summary>
        ///     Writes data to a reflexive at a particular address.
        /// </summary>
        /// <param name="entries">The entries to write.</param>
        /// <param name="address">The address to write to.</param>
        /// <param name="layout">The layout of the data to write.</param>
        /// <param name="metaArea">The meta area of the cache file.</param>
        /// <param name="writer">The stream to write to.</param>
        public static void WriteReflexive(IEnumerable <StructureValueCollection> entries, uint address, StructureLayout layout,
                                          FileSegmentGroup metaArea, IWriter writer)
        {
            int offset = metaArea.PointerToOffset(address);
            int index  = 0;

            foreach (StructureValueCollection entry in entries)
            {
                writer.SeekTo(offset + index * layout.Size);
                StructureWriter.WriteStructure(entry, layout, writer);
                index++;
            }
        }
Пример #16
0
        public static void WriteContractedTagBlock(IEnumerable <StructureValueCollection> elements, uint address, StructureLayout layout,
                                                   FileSegmentGroup metaArea, IWriter writer, IPointerExpander expander)
        {
            long cont   = expander.Expand(address);
            int  offset = metaArea.PointerToOffset(address);
            int  index  = 0;

            foreach (StructureValueCollection entry in elements)
            {
                writer.SeekTo(offset + index * layout.Size);
                StructureWriter.WriteStructure(entry, layout, writer);
                index++;
            }
        }
Пример #17
0
        public void VisitTagBlock(TagBlockData field)
        {
            var values = new StructureValueCollection();

            bool isValid = _cache.MetaArea.ContainsBlockPointer(field.FirstElementAddress, (int)(field.Length * field.ElementSize));

            values.SetInteger("entry count", isValid ? (uint)field.Length : 0);

            uint cont = _cache.PointerExpander.Contract(field.FirstElementAddress);

            values.SetInteger("pointer", isValid ? cont : 0);

            SeekToOffset(field.Offset);
            StructureWriter.WriteStructure(values, _tagBlockLayout, _writer);
        }
Пример #18
0
        public void VisitDataRef(DataRef field)
        {
            var  values  = new StructureValueCollection();
            bool isValid = _cache.MetaArea.ContainsBlockPointer(field.DataAddress, field.Length);

            values.SetInteger("size", isValid ? (uint)field.Length : 0);

            uint cont = _cache.PointerExpander.Contract(field.DataAddress);

            values.SetInteger("pointer", isValid ? cont : 0);

            SeekToOffset(field.Offset);
            StructureWriter.WriteStructure(values, _dataRefLayout, _writer);

            if (isValid)
            {
                // Go to the data location
                long offset = field.DataAddress;
                if (_type == SaveType.File)
                {
                    offset = _cache.MetaArea.PointerToOffset(offset);
                }
                _writer.SeekTo(offset);

                // Build the data
                byte[] buffer = new byte[field.Length];
                byte[] bytes;

                switch (field.Format)
                {
                default:
                    bytes = FunctionHelpers.HexStringToBytes(field.Value);
                    break;

                case "utf16":
                    bytes = Encoding.GetEncoding(1200).GetBytes(field.Value);
                    break;

                case "asciiz":
                    bytes = Encoding.GetEncoding(28591).GetBytes(field.Value);
                    break;
                }

                Array.Copy(bytes, buffer, bytes.Length > field.Length ? field.Length : bytes.Length);
                _writer.WriteBlock(buffer, 0, buffer.Length);
            }
        }
Пример #19
0
        private void WriteLanguageInfo(IWriter writer)
        {
            // Find the language data
            ITag            languageTag;
            StructureLayout tagLayout;

            if (!FindLanguageTable(out languageTag, out tagLayout))
            {
                return;
            }

            // Write it
            StructureValueCollection values = _languageInfo.Serialize();

            writer.SeekTo(languageTag.MetaLocation.AsOffset());
            StructureWriter.WriteStructure(values, tagLayout, writer);
        }
Пример #20
0
        private int WriteHeader(IWriter writer)
        {
            // Update tagname and stringid info (so. ugly.)
            _header.FileNameCount = _fileNames.Count;
            _header.StringIDCount = _stringIDs.Count;

            StructureLayout headerLayout = _buildInfo.Layouts.GetLayout("header");

            writer.SeekTo(0);
            StructureWriter.WriteStructure(_header.Serialize(), headerLayout, writer);
            int checksumOffset = -1;

            if (headerLayout.HasField("checksum"))
            {
                checksumOffset = headerLayout.GetFieldOffset("checksum");
            }
            return(checksumOffset);
        }
Пример #21
0
        public void VisitDataRef(DataRef field)
        {
            var values = new StructureValueCollection();

            values.SetInteger("size", (uint)field.Length);

            uint cont = _cache.PointerExpander.Contract(field.DataAddress);

            values.SetInteger("pointer", cont);

            SeekToOffset(field.Offset);
            StructureWriter.WriteStructure(values, _dataRefLayout, _writer);

            if (field.DataAddress == 0xFFFFFFFF || field.DataAddress <= 0)
            {
                return;
            }

            // Go to the data location
            long offset = field.DataAddress;

            if (_type == SaveType.File)
            {
                offset = _cache.MetaArea.PointerToOffset(offset);
            }
            _writer.SeekTo(offset);

            // Write its data
            switch (field.Format)
            {
            default:
                _writer.WriteBlock(FunctionHelpers.HexStringToBytes(field.Value), 0, field.Length);
                break;

            case "unicode":
                _writer.WriteUTF16(field.Value);
                break;

            case "asciiz":
                _writer.WriteAscii(field.Value);
                break;
            }
        }
Пример #22
0
        private int WriteHeader(IWriter writer)
        {
            // Update tagname and stringid info (so. ugly.)
            _header.FileNameCount = _fileNames.Count;
            _header.StringIDCount = _stringIds.Count;

            // Serialize and write the header
            StructureValueCollection values       = _header.Serialize(_languageInfo.LocaleArea);
            StructureLayout          headerLayout = _buildInfo.Layouts.GetLayout("header");

            writer.SeekTo(0);
            StructureWriter.WriteStructure(values, headerLayout, writer);
            int checksumOffset = -1;

            if (headerLayout.HasField("checksum"))
            {
                checksumOffset = headerLayout.GetFieldOffset("checksum");
            }
            return(checksumOffset);
        }
Пример #23
0
        /// <summary>
        /// Deserializes a serialized shader and injects it into the cache file.
        /// </summary>
        /// <param name="serializedShader">The serialized shader data to inject.</param>
        /// <param name="stream">The stream to manipulate. It should be positioned where the shader pointer should be written.</param>
        /// <returns>
        ///   <c>true</c> if the shader was successfully deserialized and injected.
        /// </returns>
        public bool ImportShader(byte[] serializedShader, IStream stream)
        {
            if (serializedShader == null || serializedShader.Length == 0)
            {
                // Null shader
                stream.WriteUInt32(0);
                return(true);
            }

            var pointerOffset = stream.Position + _cacheFile.MetaArea.OffsetToPointer(0);

            using (var reader = new EndianReader(new MemoryStream(serializedShader), Endian.BigEndian))
            {
                // Check the magic
                if (reader.ReadInt32() != SerializationMagic)
                {
                    return(false);
                }

                // Read the shader type and determine which info layout to use
                var             type       = (ShaderType)reader.ReadByte();
                StructureLayout infoLayout = null;
                if (type == ShaderType.Pixel)
                {
                    infoLayout = _pixelShaderInfoLayout;
                }
                else if (type == ShaderType.Vertex)
                {
                    infoLayout = _vertexShaderInfoLayout;
                }
                if (infoLayout == null)
                {
                    return(false);
                }

                // Read and verify the layout size
                var infoLayoutSize = reader.ReadInt32();
                if (infoLayoutSize != infoLayout.Size)
                {
                    return(false);
                }

                // Read the raw debug info and data
                var debugInfoSize = reader.ReadUInt32();
                var debugInfo     = reader.ReadBlock((int)debugInfoSize);
                var dataSize      = reader.ReadUInt32();
                var data          = reader.ReadBlock((int)dataSize);

                // Allocate space for the shader data and write it in
                var dataAddr   = _cacheFile.Allocator.Allocate((int)dataSize, 0x10, stream);               // 16-byte aligned
                var dataOffset = _cacheFile.MetaArea.PointerToOffset(dataAddr);
                stream.SeekTo(dataOffset);
                stream.WriteBlock(data);

                // Allocate and zero space for the info structures
                var infoSize   = infoLayoutSize + (int)debugInfoSize;
                var infoAddr   = _cacheFile.Allocator.Allocate(infoSize, 0x10, stream);               // 16-byte aligned too
                var infoOffset = _cacheFile.MetaArea.PointerToOffset(infoAddr);
                stream.SeekTo(infoOffset);
                StreamUtil.Fill(stream, 0, infoSize);

                // Write the basic info structure
                stream.SeekTo(infoOffset);
                var infoValues = new StructureValueCollection();
                infoValues.SetInteger("shader data address", (uint)dataAddr);
                StructureWriter.WriteStructure(infoValues, infoLayout, stream);

                // Write the debug info structure
                stream.WriteBlock(debugInfo);

                // Finally, write the shader pointer
                stream.SeekTo(pointerOffset - _cacheFile.MetaArea.OffsetToPointer(0));
                stream.WriteUInt32((uint)infoAddr);
            }
            return(true);
        }
Пример #24
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);
        }
Пример #25
0
 private void WriteHeader(IWriter writer)
 {
     writer.SeekTo(0);
     StructureWriter.WriteStructure(_header.Serialize(), _buildInfo.Layouts.GetLayout("header"), writer);
 }
Пример #26
0
 public void SaveTag(StructureValueCollection values, IWriter writer)
 {
     writer.SeekTo(_tag.MetaLocation.AsOffset());
     StructureWriter.WriteStructure(values, _buildInfo.Layouts.GetLayout("resource gestalt"), writer);
 }