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; }
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); } }
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); }
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); }
private void SaveHeader(StructureValueCollection headerValues, StructureLayout headerLayout, IWriter writer) { if (_metaArea != null) { writer.SeekTo(_metaArea.Offset); StructureWriter.WriteStructure(headerValues, headerLayout, writer); } }
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; } }
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); } }
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); }
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); } }
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); }
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); }
/// <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++; } }
/// <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++; } }
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++; } }
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); }
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); } }
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); }
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); }
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; } }
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); }
/// <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); }
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); }
private void WriteHeader(IWriter writer) { writer.SeekTo(0); StructureWriter.WriteStructure(_header.Serialize(), _buildInfo.Layouts.GetLayout("header"), writer); }
public void SaveTag(StructureValueCollection values, IWriter writer) { writer.SeekTo(_tag.MetaLocation.AsOffset()); StructureWriter.WriteStructure(values, _buildInfo.Layouts.GetLayout("resource gestalt"), writer); }