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); }
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 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); }
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); }
/// <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); }
/// <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); }
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); }
/// <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); }