private void Load(StructureValueCollection values, IReader reader) { Name = new StringID(values.GetInteger("name stringid")); _activeResources = LoadBitArray(values, "number of raw pool bitfields", "raw pool bitfield table address", reader); _unknownResources = LoadBitArray(values, "number of raw pool 2 bitfields", "raw pool 2 bitfield table address", reader); _unknownResources2 = LoadBitArray(values, "number of raw pool 3 bitfields", "raw pool 3 bitfield table address", reader); _activeTags = LoadBitArray(values, "number of tag bitfields", "tag bitfield table address", reader); _unknownTags = LoadBitArray(values, "number of tag 2 bitfields", "tag 2 bitfield table address", reader); }
public void SavePages(ICollection <ResourcePage> pages, IStream stream) { StructureValueCollection values = LoadTag(stream); ThirdGenCacheFileReference[] files = LoadExternalFiles(values, stream); StructureLayout layout = _buildInfo.Layouts.GetLayout("raw page table entry"); var oldCount = (int)values.GetInteger("number of raw pages"); uint oldAddress = values.GetInteger("raw page table address"); IEnumerable <StructureValueCollection> entries = pages.Select(p => SerializePage(p, files)); uint newAddress = ReflexiveWriter.WriteReflexive(entries, oldCount, oldAddress, pages.Count, layout, _metaArea, _allocator, stream); // Update values values.SetInteger("number of raw pages", (uint)pages.Count); values.SetInteger("raw page table address", newAddress); SaveTag(values, stream); }
private void Load(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, EngineDescription buildInfo) { ModelResourceIndex = new DatumIndex(values.GetInteger("resource datum index")); LoadRegions(values, reader, metaArea, buildInfo); LoadSections(values, reader, metaArea, buildInfo); LoadBoundingBoxes(values, reader, metaArea, buildInfo); }
private Dictionary <int, ITag> LoadGlobalTags(IReader reader, StructureValueCollection headerValues, List <ITag> tags) { var count = (int)headerValues.GetInteger("number of global tags"); long address = (long)headerValues.GetInteger("global tag table address"); StructureLayout layout = _buildInfo.Layouts.GetLayout("global tag element"); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, address, layout, _metaArea); Dictionary <int, ITag> output = new Dictionary <int, ITag>(); foreach (StructureValueCollection ent in entries) { output[(int)ent.GetInteger("tag group magic")] = tags[(int)ent.GetInteger("datum index") & 0xFFFF]; } return(output); }
private static CompressionState AnalyzeSecondGen(IReader reader, EngineDescription engineInfo, out StructureValueCollection headerValues) { // H2 header is uncompressed, so the cache file needs to be loaded enough to check if the tag table is readable var segmenter = new FileSegmenter(engineInfo.SegmentAlignment); reader.SeekTo(0); var headerLayout = engineInfo.Layouts.GetLayout("header"); headerValues = StructureReader.ReadStructure(reader, headerLayout); //hax headerValues.SetInteger("_header_length_", (ulong)headerLayout.Size); if (headerLayout.HasField("compression data chunk size")) { headerValues.SetInteger("_header_chunk_size_", (ulong)headerLayout.GetFieldOffset("compression data chunk size")); } if (headerLayout.HasField("compression data offset")) { headerValues.SetInteger("_header_data_offset_", (ulong)headerLayout.GetFieldOffset("compression data offset")); } if (headerLayout.HasField("compression chunk table offset")) { headerValues.SetInteger("_header_chunks_offset_", (ulong)headerLayout.GetFieldOffset("compression chunk table offset")); } if (headerLayout.HasField("compression chunk table count")) { headerValues.SetInteger("_header_chunk_count_", (ulong)headerLayout.GetFieldOffset("compression chunk table count")); } if (headerLayout.HasField("flags")) { headerValues.SetInteger("_header_flags_", (ulong)headerLayout.GetFieldOffset("flags")); } var metaOffset = (int)headerValues.GetInteger("meta offset"); var metaSize = (int)headerValues.GetInteger("meta size"); uint metaOffsetMask = (uint)headerValues.GetInteger("meta offset mask"); var metaSegment = new FileSegment( segmenter.DefineSegment(metaOffset, metaSize, 0x200, SegmentResizeOrigin.Beginning), segmenter); var MetaArea = new FileSegmentGroup(new MetaOffsetConverter(metaSegment, metaOffsetMask)); MetaArea.AddSegment(metaSegment); if (MetaArea.Offset >= reader.Length) { return(CompressionState.Compressed); } reader.SeekTo(MetaArea.Offset); StructureValueCollection tagTableValues = StructureReader.ReadStructure(reader, engineInfo.Layouts.GetLayout("meta header")); if ((uint)tagTableValues.GetInteger("magic") != CharConstant.FromString("tags")) { return(CompressionState.Compressed); } return(CompressionState.Decompressed); }
private void Load(StructureValueCollection values, IReader reader, IPointerExpander expander) { Name = new StringID(values.GetInteger("name stringid")); _activeResources = LoadBitArray(values, "number of raw pool flags", "raw pool flag table address", reader, expander); _unknownResources = LoadBitArray(values, "number of raw pool 2 flags", "raw pool 2 flag table address", reader, expander); _unknownResources2 = LoadBitArray(values, "number of raw pool 3 flags", "raw pool 3 flag table address", reader, expander); _activeTags = LoadBitArray(values, "number of tag flags", "tag flag table address", reader, expander); _unknownTags = LoadBitArray(values, "number of tag 2 flags", "tag 2 flag table address", reader, expander); }
private List <ScriptGlobal> LoadVariables(IReader reader, StructureValueCollection values) { if (_buildInfo.Layouts.HasLayout("script variable element")) { var count = (int)values.GetInteger("number of script variables"); uint address = (uint)values.GetInteger("script variable table address"); long expand = _expander.Expand(address); StructureLayout layout = _buildInfo.Layouts.GetLayout("script variable element"); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, expand, layout, _metaArea); return(entries.Select(e => new ScriptGlobal(e, _stringIDs)).ToList()); } else { return(null); } }
private void Load(StructureValueCollection values, StringID[] stringIds) { SoundName = stringIds[values.GetInteger("sound name index")]; EncodedSkipFraction = (int)values.GetInteger("encoded skip fraction"); EncodedGain = (int)values.GetInteger("encoded gain"); PermutationInfoIndex = (int)values.GetInteger("permutation info index"); LanguageNeutralTime = (int)values.GetInteger("language neutral time"); PermutationChunkIndex = (int)values.GetInteger("raw chunk index"); ChunkCount = (int)values.GetInteger("chunk count"); EncodedPermutationIndex = (int)values.GetInteger("encoded permutation index"); }
private void FreeResources(StructureValueCollection values, IReader reader) { var count = (int)values.GetInteger("number of resources"); uint address = values.GetInteger("resource table address"); StructureLayout layout = _buildInfo.Layouts.GetLayout("resource table entry"); StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, _metaArea); foreach (StructureValueCollection entry in entries) { FreeResource(entry); } int size = count * layout.Size; if (address >= 0 && size > 0) { _allocator.Free(address, size); } }
private FileSegment CalculateTagDataSegment(StructureValueCollection values, FileSegmenter segmenter) { if (TagBufferPointerConverter != null) { int tagDataOffset = TagBufferPointerConverter.PointerToOffset(TagBufferPointerConverter.BasePointer); var tagDataSize = (int)values.GetInteger("virtual size"); return(segmenter.WrapSegment(tagDataOffset, tagDataSize, 0x10000, SegmentResizeOrigin.Beginning)); } return(null); }
private void Load(StructureValueCollection values, FileSegmenter segmenter) { _eofSegment = segmenter.WrapEOF((int)values.GetInteger("file size")); var metaOffset = (int)values.GetInteger("meta offset"); int metaSize; // TODO (Dragon): hack for h2 alpha if (BuildString == "02.01.07.4998") { metaSize = (int)values.GetInteger("tag data offset") + (int)values.GetInteger("tag data size"); // hack to rewrite the "meta size" value even though its not actually the meta size //_saved_meta_size_hack = (uint)values.GetInteger("meta size"); } else { metaSize = (int)values.GetInteger("meta size"); } var metaSegment = new FileSegment( segmenter.DefineSegment(metaOffset, metaSize, 0x4, SegmentResizeOrigin.Beginning), segmenter); // we hacked in a meta header size into the values earlier in the cache load uint metaOffsetMask = (uint)(values.GetInteger("tag table offset") - values.GetInteger("meta header size")); MetaArea = new FileSegmentGroup(new MetaOffsetConverter(metaSegment, metaOffsetMask)); IndexHeaderLocation = MetaArea.AddSegment(metaSegment); Type = (CacheFileType)values.GetInteger("type"); var headerGroup = new FileSegmentGroup(); headerGroup.AddSegment(segmenter.WrapSegment(0, HeaderSize, 1, SegmentResizeOrigin.None)); InternalName = values.GetString("internal name"); Checksum = (uint)values.GetInteger("checksum"); // dummy partition Partitions = new Partition[1]; Partitions[0] = new Partition(SegmentPointer.FromOffset(MetaArea.Offset, MetaArea), (uint)MetaArea.Size); // dummy stringids StringIDCount = 0; StringIDData = _eofSegment; StringIDIndexTable = _eofSegment; }
private void Load(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, StringIDSource stringIDs, EngineDescription buildInfo, IPointerExpander expander) { Name = values.HasInteger("name index") ? stringIDs.GetString(new StringID(values.GetInteger("name index"))) : values.GetString("name"); ExecutionType = (short)values.GetInteger("execution type"); ReturnType = (short)values.GetInteger("return type"); RootExpressionIndex = new DatumIndex(values.GetInteger("first expression index")); if (Name == null) { Name = "script_" + RootExpressionIndex.Value.ToString("X8"); } if (buildInfo.Layouts.HasLayout("script parameter element")) { Parameters = LoadParameters(reader, values, metaArea, buildInfo, expander); } }
private void LoadModelCompressionData(ITag modelTag, BlamCacheFile blamCacheFile) { ulong numBoundingBoxes = renderModelValues.GetInteger("number of bounding boxes"); ulong boundingBoxTableAddr = renderModelValues.GetInteger("bounding box table address"); ulong boundingboxTableOffset = (ulong)blamCacheFile.PointerToFileOffset((uint)boundingBoxTableAddr); StructureLayout boundingBoxElementLayout = blamCacheFile.GetLayout("model bounding box"); Compression = new BlamModelCompression(); List <StructureValueCollection> boundingBoxTableData = new List <StructureValueCollection>((int)numBoundingBoxes); for (ulong i = 0; i < numBoundingBoxes; i++) { ulong offset = (i * (ulong)boundingBoxElementLayout.Size); blamCacheFile.Reader.SeekTo((long)(boundingboxTableOffset + offset)); boundingBoxTableData.Add(StructureReader.ReadStructure(blamCacheFile.Reader, boundingBoxElementLayout)); } Compression.ReadCompressionData(boundingBoxTableData); }
private void Load(StructureValueCollection values, FileSegmentGroup metaArea, Dictionary <int, ITagGroup> groupsById) { Offset = (int)values.GetInteger("offset"); if (Offset > 0) { MetaLocation = SegmentPointer.FromPointer(Offset, metaArea); } // Load the tag group by looking up the magic value that's stored var groupMagic = (int)values.GetInteger("tag group magic"); if (groupMagic != -1) { Group = groupsById[groupMagic]; } Index = new DatumIndex(values.GetInteger("datum index")); DataSize = (int)values.GetInteger("data size"); }
private void Load(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, EngineDescription buildInfo) { SoundClass = (byte)values.GetInteger("sound class"); SampleRate = (SampleRate)values.GetInteger("sample rate"); Encoding = (Encoding)values.GetInteger("encoding"); CodecIndex = (byte)values.GetInteger("codec index"); PlaybackIndex = (short)values.GetInteger("playback index"); PermutationChunkCount = (byte)values.GetInteger("permutation chunk count"); ResourceIndex = new DatumIndex(values.GetInteger("resource datum index")); MaxPlaytime = (short)values.GetInteger("max playtime"); }
private void ReadReflexive(DataBlock block, uint offset, uint entrySize, int align) { // Read the count and pointer SeekToOffset(block, offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _reflexiveLayout); var count = (int)values.GetInteger("entry count"); uint pointer = values.GetInteger("pointer"); if (count > 0 && _cacheFile.MetaArea.ContainsBlockPointer(pointer, (int)(count * entrySize))) { DataBlock newBlock = ReadDataBlock(pointer, (int)entrySize, count, align); // Now create a fixup for the block var fixup = new DataBlockAddressFixup(pointer, (int)offset + _reflexiveLayout.GetFieldOffset("pointer")); block.AddressFixups.Add(fixup); // Add it to _reflexiveBlocks so it'll be recursed into _reflexiveBlocks.Add(newBlock); } }
private ScriptExpressionTable LoadExpressions(IReader reader, StructureValueCollection values, StringTableReader stringReader) { var count = (int)values.GetInteger("number of script expressions"); uint address = values.GetInteger("script expression table address"); StructureLayout layout = _buildInfo.Layouts.GetLayout("script expression entry"); StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, _metaArea); var result = new ScriptExpressionTable(); result.AddExpressions(entries.Select((e, i) => new ScriptExpression(e, (ushort)i, stringReader))); foreach (ScriptExpression expr in result.Where(expr => expr != null)) { expr.ResolveReferences(result); } return(result); }
private void Load(StructureValueCollection values, ushort index, FileSegmentGroup metaArea, IList<ITagGroup> groupList, IPointerExpander expander) { uint address = (uint)values.GetInteger("memory address"); if (address != 0 && address != 0xFFFFFFFF) { long expanded = expander.Expand(address); MetaLocation = SegmentPointer.FromPointer(expanded, metaArea); } var groupIndex = (int) values.GetInteger("tag group index"); if (groupIndex >= 0 && groupIndex < groupList.Count) Group = groupList[groupIndex]; var salt = (ushort) values.GetInteger("datum index salt"); if (salt != 0xFFFF) Index = new DatumIndex(salt, index); else Index = DatumIndex.Null; }
private ScriptObject[] ReadPointSets(IReader reader, StructureValueCollection values) { // Point sets are nested in another block for whatever reason // Seems like the length of the outer is always 1, so just take the first element and process it var count = (int)values.GetInteger("point set data count"); if (count == 0) { return(new ScriptObject[0]); } uint address = (uint)values.GetInteger("point set data address"); long expand = _expander.Expand(address); StructureLayout layout = _buildInfo.Layouts.GetLayout("point set data element"); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, expand, layout, _metaArea); return(ReadObjects(reader, entries.First(), _pointSets)); }
private CachedStringTable LoadStrings(IReader reader, StructureValueCollection values, StringTableReader stringReader) { var stringsSize = (int)values.GetInteger("script string table size"); if (stringsSize == 0) { return(new CachedStringTable()); } var result = new CachedStringTable(); uint tableAddr = (uint)values.GetInteger("script string table address"); long expand = _expander.Expand(tableAddr); int tableOffset = _metaArea.PointerToOffset(expand); stringReader.ReadRequestedStrings(reader, tableOffset, result); return(result); }
private void FreeZoneSetsInTable(StructureValueCollection tagValues, string countName, string addressName, IReader reader) { if (!tagValues.HasInteger(countName) || !tagValues.HasInteger(addressName)) { return; } var count = (int)tagValues.GetInteger(countName); uint address = (uint)tagValues.GetInteger(addressName); long expand = _expander.Expand(address); StructureLayout layout = _buildInfo.Layouts.GetLayout("zone set definition"); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, expand, layout, _metaArea); foreach (StructureValueCollection entry in entries) { ThirdGenZoneSet.Free(entry, _allocator, _expander); } }
private void Load(StructureValueCollection values, FileSegmentGroup metaArea, Dictionary <int, ITagClass> classesById) { uint offset = values.GetInteger("offset"); if (offset > 0) { MetaLocation = SegmentPointer.FromPointer(offset, metaArea); } // Load the tag class by looking up the magic value that's stored var classMagic = (int)values.GetInteger("class magic"); if (classMagic != -1) { Class = classesById[classMagic]; } Index = new DatumIndex(values.GetInteger("datum index")); DataSize = (int)values.GetInteger("data size"); }
public void VisitReflexive(ReflexiveData field) { SeekToOffset(field.Offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _tagBlockLayout); var length = (int)values.GetInteger("entry count"); uint pointer = values.GetInteger("pointer"); // Make sure the pointer looks valid if (length < 0 || !_cache.MetaArea.ContainsBlockPointer(pointer, (int)(length * field.EntrySize))) { length = 0; pointer = 0; } field.Length = length; if (pointer != field.FirstEntryAddress) { field.FirstEntryAddress = pointer; } }
private void WriteTagReferences(ScriptData data, IStream stream, StructureValueCollection scnr) { int oldRefCount = (int)scnr.GetInteger("number of script tag references"); uint oldRefAddress = (uint)scnr.GetInteger("script tag references table address"); long expOldRefAddress = _expander.Expand(oldRefAddress); int oldRefSize = oldRefCount * 0x10; long newRefAddress = 0; //check if the returned data contained tag references if (data.TagReferences.Count > 0) { int newRefSize = data.TagReferences.Count * 0x10; // allocate space for the references if (oldRefCount > 0) { newRefAddress = _allocator.Reallocate(expOldRefAddress, oldRefSize, newRefSize, stream); } else { newRefAddress = _allocator.Allocate(newRefSize, stream); } //write the references stream.SeekTo(_metaArea.PointerToOffset(newRefAddress)); foreach (ITag tag in data.TagReferences) { stream.WriteInt32(tag.Group.Magic); stream.WriteUInt32(0); stream.WriteUInt32(0); stream.WriteUInt32(tag.Index.Value); } } else if (oldRefCount > 0) { _allocator.Free(expOldRefAddress, oldRefSize); } scnr.SetInteger("number of script tag references", (uint)data.TagReferences.Count); scnr.SetInteger("script tag references table address", _expander.Contract(newRefAddress)); }
private void SaveZoneSetTable(IZoneSet[] sets, StructureValueCollection tagValues, string countName, string addressName, ReflexiveCache <int> cache, IStream stream) { if (!tagValues.HasInteger(countName) || !tagValues.HasInteger(addressName)) { return; } var count = (int)tagValues.GetInteger(countName); if (count != sets.Length) { throw new InvalidOperationException("Zone set count does not match"); } uint address = tagValues.GetInteger(addressName); StructureLayout layout = _buildInfo.Layouts.GetLayout("zone set definition"); List <StructureValueCollection> entries = sets.Select(set => ((ThirdGenZoneSet)set).Serialize(stream, _allocator, cache)).ToList(); ReflexiveWriter.WriteReflexive(entries, address, layout, _metaArea, stream); }
public void SavePointers(ICollection <ResourcePointer> pointers, IStream stream) { StructureValueCollection values = LoadTag(stream); StructureLayout layout = _buildInfo.Layouts.GetLayout("raw segment table element"); var oldCount = (int)values.GetInteger("number of raw segments"); uint oldAddress = (uint)values.GetInteger("raw segment table address"); long expand = _expander.Expand(oldAddress); IEnumerable <StructureValueCollection> entries = pointers.Select(p => SerializePointer(p)); long newAddress = TagBlockWriter.WriteTagBlock(entries, oldCount, expand, pointers.Count, layout, _metaArea, _allocator, stream); // Update values uint cont = _expander.Contract(newAddress); values.SetInteger("number of raw segments", (uint)pointers.Count); values.SetInteger("raw segment table address", cont); SaveTag(values, stream); }
private void LoadRegions(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, EngineDescription buildInfo) { var count = (int)values.GetInteger("number of regions"); long address = (long)owningCacheFile.PointerExpander.Expand((uint)values.GetInteger("region table address")); StructureLayout layout = buildInfo.Layouts.GetLayout("model region"); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, address, layout, metaArea); Regions = (from entry in entries select new ThirdGenModelRegion(entry, reader, metaArea, buildInfo)).ToArray(); }
public BlamRenderModelRegion(long addr, BlamCacheFile blamCacheFile) { Permutations = new List <BlamRenderModelPermutation>(); StructureLayout regionLayout = blamCacheFile.GetLayout("model region"); StructureLayout permutationLayout = blamCacheFile.GetLayout("model permutation"); blamCacheFile.Reader.SeekTo(addr); StructureValueCollection values = StructureReader.ReadStructure(blamCacheFile.Reader, regionLayout); Name = blamCacheFile.Get().StringIDs.GetString(new StringID(values.GetInteger("name stringid"))); ulong numPermutations = values.GetInteger("number of permutations"); long permutationTableAddress = blamCacheFile.ExpandPointer((uint)values.GetInteger("permutation table address")); long permutationRegionTableOffset = blamCacheFile.Get().MetaArea.PointerToOffset(permutationTableAddress); for (ulong permutationNum = 0; permutationNum < numPermutations; permutationNum++) { long permutationAddr = permutationRegionTableOffset + (long)((ulong)permutationLayout.Size * permutationNum); Permutations.Add(new BlamRenderModelPermutation(permutationAddr, blamCacheFile, permutationLayout)); } }
private ResourceSize LoadSize(StructureValueCollection values, int index, IReader reader) { var result = new ResourceSize(); result.Index = index; result.Size = (int)values.GetInteger("overall size"); result.Parts.AddRange(LoadSizeParts(values, reader)); return(result); }
private void Load(StructureValueCollection values, FileSegmenter segmenter) { segmenter.DefineSegment(0, HeaderSize, 1, SegmentResizeOrigin.Beginning); // Define a segment for the header _eofSegment = segmenter.WrapEOF((int)values.GetInteger("file size")); Type = (CacheFileType)values.GetInteger("type"); LoadInteropData(values); RawTable = CalculateRawTableSegment(segmenter); InternalName = values.GetString("internal name"); ScenarioName = values.GetString("scenario name"); XDKVersion = (int)values.GetInteger("xdk version"); FileSegment metaSegment = CalculateTagDataSegment(values, segmenter); if (metaSegment != null) { ulong virtualBase = values.GetInteger("virtual base address"); MetaArea = new FileSegmentGroup(new MetaAddressConverter(metaSegment, (long)virtualBase)); MetaArea.AddSegment(metaSegment); IndexHeaderLocation = SegmentPointer.FromPointer((long)values.GetInteger("index header address"), MetaArea); Partitions = LoadPartitions(values.GetArray("partitions")); } else { Partitions = new Partition[0]; } CalculateStringGroup(values, segmenter); Checksum = (uint)values.GetInteger("checksum"); }