private void SaveResourceFixups(IList <ResourceFixup> fixups, StructureValueCollection values, IStream stream, ReflexiveCache <ResourceFixup> cache) { var oldCount = (int)values.GetIntegerOrDefault("number of resource fixups", 0); uint oldAddress = (uint)values.GetIntegerOrDefault("resource fixup table address", 0); long oldExpand = _expander.Expand(oldAddress); StructureLayout layout = _buildInfo.Layouts.GetLayout("resource fixup entry"); long newAddress; if (!cache.TryGetAddress(fixups, out newAddress)) { // Write a new reflexive IEnumerable <StructureValueCollection> entries = fixups.Select(f => SerializeResourceFixup(f)); newAddress = ReflexiveWriter.WriteReflexive(entries, oldCount, oldExpand, fixups.Count, layout, _metaArea, _allocator, stream); cache.Add(newAddress, fixups); } else if (oldAddress != 0 && oldCount > 0) { // Reflexive was cached - just free it _allocator.Free(oldExpand, oldCount * layout.Size); } uint cont = _expander.Contract(newAddress); values.SetInteger("number of resource fixups", (uint)fixups.Count); values.SetInteger("resource fixup table address", cont); }
private void SaveSizeParts(IList <ResourceSizePart> parts, StructureValueCollection values, IStream stream, TagBlockCache <ResourceSizePart> cache) { var oldCount = (int)values.GetIntegerOrDefault("number of size parts", 0); uint oldAddress = (uint)values.GetIntegerOrDefault("size part table address", 0); long expand = _expander.Expand(oldAddress); StructureLayout layout = _buildInfo.Layouts.GetLayout("size part table element"); long newAddress; if (!cache.TryGetAddress(parts, out newAddress)) { // Write a new block IEnumerable <StructureValueCollection> entries = parts.Select(p => SerializeSizePart(p)); newAddress = TagBlockWriter.WriteTagBlock(entries, oldCount, expand, parts.Count, layout, _metaArea, _allocator, stream); cache.Add(newAddress, parts); } else if (oldAddress != 0 && oldCount > 0) { // Block was cached - just free it _allocator.Free(expand, oldCount * layout.Size); } uint cont = _expander.Contract(newAddress); values.SetInteger("number of size parts", (uint)parts.Count); values.SetInteger("size part table address", cont); }
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 static void FreeBitArray(StructureValueCollection values, string countName, string addressName, MetaAllocator allocator) { if (!values.HasInteger(countName) || !values.HasInteger(addressName)) { return; } var oldCount = (int)values.GetInteger(countName); uint oldAddress = values.GetInteger(addressName); if (oldCount > 0 && oldAddress > 0) { allocator.Free(oldAddress, oldCount * 4); } }
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); }