/// <summary> /// Loads a structure layout based upon an XML container's children. /// </summary> /// <param name="parentElement">The element containing the value elements to parse.</param> /// <param name="size">The size of the structure in bytes.</param> /// <returns>The structure layout that was loaded.</returns> public static StructureLayout LoadLayout(XElement parentElement, int size) { var layout = new StructureLayout(size); foreach (XElement element in parentElement.Elements()) HandleElement(layout, element); return layout; }
private void LoadBoundingBoxes(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, EngineDescription buildInfo) { var count = (int)values.GetInteger("number of bounding boxes"); uint address = values.GetInteger("bounding box table address"); StructureLayout layout = buildInfo.Layouts.GetLayout("model bounding box"); StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, 1, address, layout, metaArea); BoundingBoxes = (from entry in entries select BoundingBox.Deserialize(entry)).ToArray(); }
private void LoadPermutations(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, EngineDescription buildInfo) { var count = (int)values.GetInteger("number of permutations"); uint address = (uint)values.GetInteger("permutation table address"); StructureLayout layout = buildInfo.Layouts.GetLayout("model permutation"); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, address, layout, metaArea); Permutations = (from entry in entries select new ThirdGenModelPermutation(entry)).ToArray(); }
private List <Script> LoadScripts(IReader reader, StructureValueCollection values) { int count = (int)values.GetInteger("number of scripts"); uint address = (uint)values.GetInteger("script table address"); long expand = _expander.Expand(address); StructureLayout layout = _buildInfo.Layouts.GetLayout("script element"); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, expand, layout, _metaArea); var result = entries.Select(e => new Script(e, reader, _metaArea, _stringIDs, _buildInfo, _expander)).ToList(); return(result); }
private ThirdGenCacheFileReference[] LoadExternalFiles(StructureValueCollection values, IReader reader) { var count = (int)values.GetInteger("number of external cache files"); uint address = (uint)values.GetInteger("external cache file table address"); long expand = _expander.Expand(address); StructureLayout layout = _buildInfo.Layouts.GetLayout("external cache file table element"); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, expand, layout, _metaArea); return(entries.Select(e => new ThirdGenCacheFileReference(e)).ToArray()); }
private void FreeDefinitionFixups(StructureValueCollection values) { var count = (int)values.GetInteger("number of definition fixups"); uint address = values.GetInteger("definition fixup table address"); StructureLayout layout = _buildInfo.Layouts.GetLayout("definition fixup entry"); int size = count * layout.Size; if (address >= 0 && size > 0) { _allocator.Free(address, size); } }
private void LoadVertexGroups(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, EngineDescription buildInfo, IModelSubmesh[] submeshes) { var count = (int)values.GetInteger("number of vertex groups"); uint address = values.GetInteger("vertex group table address"); StructureLayout layout = buildInfo.Layouts.GetLayout("model vertex group"); StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, metaArea); VertexGroups = (from entry in entries select new FourthGenModelVertexGroup(entry, submeshes)).ToArray(); }
private List <ScriptGlobal> LoadGlobals(IReader reader, StructureValueCollection values) { var count = (int)values.GetInteger("number of script globals"); uint address = (uint)values.GetInteger("script global table address"); long expand = _expander.Expand(address); StructureLayout layout = _buildInfo.Layouts.GetLayout("script global element"); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, expand, layout, _metaArea); return(entries.Select(e => new ScriptGlobal(e, _stringIDs)).ToList()); }
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(); }
private void LoadSections(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, EngineDescription buildInfo) { var count = (int)values.GetInteger("number of sections"); uint address = values.GetInteger("section table address"); StructureLayout layout = buildInfo.Layouts.GetLayout("model section"); StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, metaArea); Sections = (from entry in entries select new ThirdGenModelSection(entry, reader, metaArea, buildInfo)).ToArray(); }
/// <summary> /// Reads all child objects of this block. /// </summary> /// <param name="values">The values read from the parent.</param> /// <param name="reader">The stream to read from.</param> /// <param name="metaArea">The meta area of the cache file.</param> /// <param name="stringIDs">The string ID source for the cache file.</param> /// <param name="buildInfo">The build info for the cache file.</param> /// <returns>The objects that were read.</returns> public ScriptObject[] ReadObjects(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, StringIDSource stringIDs, EngineDescription buildInfo, IPointerExpander expander) { var count = (int)values.GetInteger(_countEntryName); uint address = (uint)values.GetInteger(_addressEntryName); long expand = expander.Expand(address); StructureLayout layout = buildInfo.Layouts.GetLayout(_layoutName); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, expand, layout, metaArea); return(entries.Select(e => ReadScriptObject(e, reader, metaArea, stringIDs, buildInfo, expander)).ToArray()); }
private void SaveTags(StructureValueCollection headerValues, IStream stream) { var oldCount = (int)headerValues.GetInteger("number of tags"); long oldAddress = (long)headerValues.GetInteger("tag table address"); StructureLayout layout = _buildInfo.Layouts.GetLayout("tag element"); IEnumerable <StructureValueCollection> entries = _tags.Select(t => ((ThirdGenTag)t).Serialize(Groups, _expander)); // hax, _tags is a list of ITag objects so we have to upcast long newAddress = TagBlockWriter.WriteTagBlock(entries, oldCount, oldAddress, _tags.Count, layout, _metaArea, _allocator, stream); headerValues.SetInteger("number of tags", (uint)_tags.Count); headerValues.SetInteger("tag table address", (ulong)newAddress); }
private IList <ScriptParameter> LoadParameters(IReader reader, StructureValueCollection values, FileSegmentGroup metaArea, EngineDescription buildInfo, IPointerExpander expander) { var count = (int)values.GetInteger("number of parameters"); uint address = (uint)values.GetInteger("address of parameter list"); long expand = expander.Expand(address); StructureLayout layout = buildInfo.Layouts.GetLayout("script parameter element"); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, expand, layout, metaArea); return(entries.Select(e => new ScriptParameter(e)).ToList()); }
/// <summary> /// Initializes a new instance of the <see cref="DataBlockBuilder" /> class. /// </summary> /// <param name="reader">The stream to read from.</param> /// <param name="tagLocation">The location of the tag to load data blocks for.</param> /// <param name="cacheFile">The cache file.</param> /// <param name="buildInfo">The build info for the cache file.</param> public DataBlockBuilder(IReader reader, SegmentPointer tagLocation, ICacheFile cacheFile, EngineDescription buildInfo) { _reader = reader; _tagLocation = tagLocation; _cacheFile = cacheFile; _tagRefLayout = buildInfo.Layouts.GetLayout("tag reference"); _reflexiveLayout = buildInfo.Layouts.GetLayout("reflexive"); _dataRefLayout = buildInfo.Layouts.GetLayout("data reference"); DataBlocks = new List <DataBlock>(); ReferencedTags = new HashSet <DatumIndex>(); ReferencedResources = new HashSet <DatumIndex>(); }
public IEnumerable <ResourcePointer> LoadPointers(IReader reader, IList <ResourcePage> pages, IList <ResourceSize> sizes) { StructureValueCollection values = LoadTag(reader); var count = (int)values.GetInteger("number of raw segments"); uint address = (uint)values.GetInteger("raw segment table address"); long expand = _expander.Expand(address); StructureLayout layout = _buildInfo.Layouts.GetLayout("raw segment table element"); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, expand, layout, _metaArea); return(entries.Select(e => LoadPointer(e, pages, sizes))); }
public List <ResourceSize> LoadSizes(IReader reader) { StructureValueCollection values = LoadTag(reader); var count = (int)values.GetInteger("number of raw sizes"); uint address = (uint)values.GetInteger("raw size table address"); long expand = _expander.Expand(address); StructureLayout layout = _buildInfo.Layouts.GetLayout("raw size table element"); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, expand, layout, _metaArea); return(entries.Select((e, i) => LoadSize(e, i, reader)).ToList()); }
private int SaveGroups(StructureValueCollection headerValues, int offset, IStream stream) { StructureLayout layout = _buildInfo.Layouts.GetLayout("tag group element"); IEnumerable <StructureValueCollection> entries = _groups.Select(g => ((SecondGenTagGroup)g).Serialize()); var addr = _metaArea.OffsetToPointer(_metaArea.Offset + offset); TagBlockWriter.WriteTagBlock(entries, addr, layout, _metaArea, stream); headerValues.SetInteger("number of tag groups", (uint)_groups.Count); headerValues.SetInteger("tag group table offset", (uint)offset); return(Groups.Count * layout.Size); }
public IEnumerable <ResourcePage> LoadPages(IReader reader) { StructureValueCollection values = LoadTag(reader); ThirdGenCacheFileReference[] files = LoadExternalFiles(values, reader); var count = (int)values.GetInteger("number of raw pages"); uint address = values.GetInteger("raw page table address"); StructureLayout layout = _buildInfo.Layouts.GetLayout("raw page table entry"); StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, _metaArea); return(entries.Select((e, i) => LoadPage(e, i, files))); }
public IEnumerable <Resource> LoadResources(IReader reader, TagTable tags, IList <ResourcePointer> pointers) { StructureValueCollection values = LoadTag(reader); byte[] infoBuffer = LoadResourceInfoBuffer(values, 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); return(entries.Select((e, i) => LoadResource(e, i, tags, pointers, infoBuffer, reader))); }
private IEnumerable <ResourceDefinitionFixup> LoadDefinitionFixups(StructureValueCollection values, IReader reader) { var count = (int)values.GetInteger("number of definition fixups"); uint address = values.GetInteger("definition fixup table address"); StructureLayout layout = _buildInfo.Layouts.GetLayout("definition fixup entry"); StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, _metaArea); return(entries.Select(e => new ResourceDefinitionFixup { Offset = (int)e.GetInteger("offset"), Type = (int)e.GetInteger("type index") })); }
private void SaveTags(StructureValueCollection headerValues, IStream stream) { var oldCount = (int)headerValues.GetInteger("number of tags"); uint oldAddress = headerValues.GetInteger("tag table address"); StructureLayout layout = _buildInfo.Layouts.GetLayout("tag entry"); IEnumerable <StructureValueCollection> entries = _tags.Select(t => ((NewThirdGenTag)t).Serialize(Classes)); // hax, _tags is a list of ITag objects so we have to upcast uint newAddress = ReflexiveWriter.WriteReflexive(entries, oldCount, oldAddress, _tags.Count, layout, _metaArea, _allocator, stream); headerValues.SetInteger("number of tags", (uint)_tags.Count); headerValues.SetInteger("tag table address", newAddress); }
public void Read(BlamCacheFile cacheFile, Resource resourceRef) { IReader reader = cacheFile.Reader; StructureLayout meshLayout = cacheFile.GetLayout("model section"); for (int i = 0; i < Meshes.Capacity; i++) { reader.SeekTo(meshTableOffset + (i * meshLayout.Size)); Meshes.Add(new BlamModelMesh(cacheFile, i, meshLayout)); } ReadResourceBuffers(cacheFile, ref resourceRef); }
public IList <ResourcePointer> SaveResources(ICollection <Resource> resources, IStream stream) { StructureValueCollection values = LoadTag(stream); // Free everything FreeResources(values, stream); // Serialize each resource entry // This can't be lazily evaluated because allocations might cause the stream to expand int infoOffset = 0; var pointers = new List <ResourcePointer>(); var entries = new List <StructureValueCollection>(); var fixupCache = new ReflexiveCache <ResourceFixup>(); var defFixupCache = new ReflexiveCache <ResourceDefinitionFixup>(); foreach (Resource resource in resources) { infoOffset = AlignInfoBlockOffset(resource, infoOffset); StructureValueCollection entry = SerializeResource(resource, (resource.Location != null) ? pointers.Count : -1, (resource.Info != null) ? infoOffset : 0, stream); entries.Add(entry); // Save fixups SaveResourceFixups(resource.ResourceFixups, entry, stream, fixupCache); SaveDefinitionFixups(resource.DefinitionFixups, entry, stream, defFixupCache); // Update info offset and pointer info if (resource.Info != null) { infoOffset += resource.Info.Length; } if (resource.Location != null) { pointers.Add(resource.Location); } } // Write the reflexive and update the tag values StructureLayout layout = _buildInfo.Layouts.GetLayout("resource table entry"); uint newAddress = ReflexiveWriter.WriteReflexive(entries, layout, _metaArea, _allocator, stream); values.SetInteger("number of resources", (uint)entries.Count); values.SetInteger("resource table address", newAddress); // Build and save the info buffer byte[] infoBuffer = BuildResourceInfoBuffer(resources); SaveResourceInfoBuffer(infoBuffer, values, stream); SaveTag(values, stream); return(pointers); }
public MetaReader(IStreamManager streamManager, long baseOffset, ICacheFile cache, EngineDescription buildInfo, LoadType type, FieldChangeSet ignore) { _streamManager = streamManager; BaseOffset = baseOffset; _cache = cache; _ignoredFields = ignore; _type = type; // Load layouts _tagBlockLayout = buildInfo.Layouts.GetLayout("tag block"); _tagRefLayout = buildInfo.Layouts.GetLayout("tag reference"); _dataRefLayout = buildInfo.Layouts.GetLayout("data reference"); }
private List <ITagInterop> LoadTagInterops(IReader reader, StructureValueCollection headerValues) { if (!headerValues.HasInteger("number of tag interops")) { return(null); } var count = (int)headerValues.GetInteger("number of tag interops"); long address = (long)headerValues.GetInteger("tag interop table address"); StructureLayout layout = _buildInfo.Layouts.GetLayout("tag interop element"); StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, count, address, layout, _metaArea); return(entries.Select <StructureValueCollection, ITagInterop>(e => new ThirdGenTagInterop(e, _metaArea)).ToList()); }
private List <IPolyart> LoadPolyart(IReader reader, StructureValueCollection headerValues) { if (!headerValues.HasInteger("number of polyart fixups")) { return(null); } var count = (int)headerValues.GetInteger("number of polyart fixups"); long address = (long)headerValues.GetInteger("polyart fixup table address"); StructureLayout layout = _buildInfo.Layouts.GetLayout("polyart table entry"); StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, _metaArea); return(entries.Select <StructureValueCollection, IPolyart>(e => new ThirdGenPolyart(e, _metaArea)).ToList()); }
/// <summary> /// Initializes a new instance of the <see cref="DataBlockBuilder" /> class. /// </summary> /// <param name="reader">The stream to read from.</param> /// <param name="tag">The tag to load data blocks for.</param> /// <param name="cacheFile">The cache file.</param> /// <param name="buildInfo">The build info for the cache file.</param> public DataBlockBuilder(IReader reader, ITag tag, ICacheFile cacheFile, EngineDescription buildInfo) { _reader = reader; _tag = tag; _cacheFile = cacheFile; _languageCache = new CachedLanguagePackLoader(_cacheFile.Languages); _tagRefLayout = buildInfo.Layouts.GetLayout("tag reference"); _tagBlockLayout = buildInfo.Layouts.GetLayout("tag block"); _dataRefLayout = buildInfo.Layouts.GetLayout("data reference"); DataBlocks = new List <DataBlock>(); ReferencedTags = new HashSet <DatumIndex>(); ReferencedResources = new HashSet <DatumIndex>(); }
private void LoadResourceTypes(StructureValueCollection values, IReader reader, StringIDSource stringIDs) { if (!values.HasInteger("number of resource types") || !values.HasInteger("resource type table address")) { return; } var count = (int)values.GetInteger("number of resource types"); uint address = values.GetInteger("resource type table address"); StructureLayout layout = _buildInfo.Layouts.GetLayout("resource type entry"); StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, _metaArea); _resourceTypes = entries.Select(e => new FourthGenResourceType(e, stringIDs)).ToArray(); }
private IEnumerable <ThirdGenZoneSet> ReadZoneSetTable(StructureValueCollection tagValues, string countName, string addressName, IReader reader) { if (!tagValues.HasInteger(countName) || !tagValues.HasInteger(addressName)) { return(Enumerable.Empty <ThirdGenZoneSet>()); } var count = (int)tagValues.GetInteger(countName); uint address = tagValues.GetInteger(addressName); StructureLayout layout = _buildInfo.Layouts.GetLayout("zone set definition"); StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, _metaArea); return(entries.Select(e => new ThirdGenZoneSet(e, reader, _metaArea))); }
private static void MapLoadUnitTest() { string targetFile = Core.Util.VisualStudioProvider.TryGetSolutionDirectoryInfo().FullName + "\\" + TARGET_MAP_FILE; using (BlamCacheFile blamCacheFile = new BlamCacheFile(targetFile)) { const int VEHICLE_MODEL_OFFSET = 0x34; ICacheFile cacheFile = blamCacheFile.Get(); IEnumerable <ITag> vehicleTags = cacheFile.Tags.FindTagsByGroup("vehi"); StructureLayout layout = blamCacheFile.BuildInfo.Layouts.GetLayout("tag reference"); foreach (ITag vehicleTag in vehicleTags) { string name = cacheFile.FileNames.GetTagName(vehicleTag); //This is where in the memory region that the map exists a structure for the meta data exists long tagRefPointer = vehicleTag.MetaLocation.AsOffset() + VEHICLE_MODEL_OFFSET; blamCacheFile.Reader.SeekTo(tagRefPointer); StructureValueCollection collection = StructureReader.ReadStructure(blamCacheFile.Reader, layout); //Try to read it //Extract fields ulong groupMagic = collection.GetInteger("tag group magic"); DatumIndex datumIndex = new DatumIndex(collection.GetInteger("datum index")); //Is this a valid datum? bool isValid = cacheFile.Tags.IsValidIndex(datumIndex); ITag vehicleModelTag = cacheFile.Tags[datumIndex]; string vehicleModelName = cacheFile.FileNames.GetTagName(vehicleModelTag); string group = CharConstant.ToString(vehicleModelTag.Group.Magic); if (!TARGET_MODEL.Equals(vehicleModelName)) { continue; } tagRefPointer = vehicleModelTag.MetaLocation.AsOffset(); blamCacheFile.Reader.SeekTo(tagRefPointer); collection = StructureReader.ReadStructure(blamCacheFile.Reader, layout); groupMagic = collection.GetInteger("tag group magic"); datumIndex = new DatumIndex(collection.GetInteger("datum index")); isValid = cacheFile.Tags.IsValidIndex(datumIndex); ITag vehicleRenderModelTag = cacheFile.Tags[datumIndex]; string renderModelTagName = CharConstant.ToString(vehicleRenderModelTag.Group.Magic); BlamRenderModel warthogModel = new BlamRenderModel(vehicleRenderModelTag, blamCacheFile); } } Logger.LogReport("MapLoadUnitTest: Success!"); }
private List <ITag> LoadTags(IReader reader, uint tagTableOffset, int numTags, EngineDescription buildInfo, FileSegmentGroup metaArea) { StructureLayout layout = buildInfo.Layouts.GetLayout("tag element"); var result = new List <ITag>(); reader.SeekTo(tagTableOffset); for (int i = 0; i < numTags; i++) { StructureValueCollection values = StructureReader.ReadStructure(reader, layout); result.Add(new SecondGenTag(values, metaArea, _groupsById)); } return(result); }
/// <summary> /// Parses an XML element representing an array field and adds the field /// information to a structure layout. /// </summary> /// <param name="layout">The structure layout to add the field's information to.</param> /// <param name="element">The XML element to parse.</param> /// <param name="name">The name of the field to add.</param> /// <param name="offset">The offset (in bytes) of the field from the beginning of the structure.</param> private void HandleArrayElement(StructureLayout layout, XElement element, string name, int offset) { int count = XMLUtil.GetNumericAttribute(element, "count"); int entrySize = XMLUtil.GetNumericAttribute(element, "entrySize"); layout.AddArrayField(name, offset, count, LoadLayout(element, entrySize)); }
/// <summary> /// Parses an XML element representing a basic structure field and adds /// the field information to a structure layout. /// </summary> /// <param name="layout">The structure layout to add the field's information to.</param> /// <param name="element">The XML element to parse.</param> /// <param name="name">The name of the field to add.</param> /// <param name="offset">The offset (in bytes) of the field from the beginning of the structure.</param> private void HandleBasicElement(StructureLayout layout, XElement element, string name, int offset) { StructureValueType type = IdentifyValueType(element.Name.LocalName); layout.AddBasicField(name, type, offset); }
/// <summary> /// Parses an XML element and adds the field that it represents to a /// structure layout. /// </summary> /// <param name="layout">The layout to add the parsed field to.</param> /// <param name="element">The element to parse.</param> private void HandleElement(StructureLayout layout, XElement element) { // Every structure field at least has a name and an offset string name = XMLUtil.GetStringAttribute(element, "name"); int offset = XMLUtil.GetNumericAttribute(element, "offset"); if (IsArrayElement(element)) HandleArrayElement(layout, element, name, offset); else if (IsRawElement(element)) HandleRawElement(layout, element, name, offset); else if (IsStructElement(element)) HandleStructElement(layout, element, name, offset); else HandleBasicElement(layout, element, name, offset); }
/// <summary> /// Parses an XML element representing an raw byte array and adds the /// field information to a structure layout. /// </summary> /// <param name="layout">The structure layout to add the field's information to.</param> /// <param name="element">The XML element to parse.</param> /// <param name="name">The name of the field to add.</param> /// <param name="offset">The offset (in bytes) of the field from the beginning of the structure.</param> private void HandleRawElement(StructureLayout layout, XElement element, string name, int offset) { int size = XMLUtil.GetNumericAttribute(element, "size"); layout.AddRawField(name, offset, size); }
/// <summary> /// Parses an XML element representing an embedded structure and /// adds the field information to a structure layout. /// </summary> /// <param name="layout">The structure layout to add the field's information to.</param> /// <param name="element">The XML element to parse.</param> /// <param name="name">The name of the field to add.</param> /// <param name="offset">The offset (in bytes) of the field from the beginning of the structure.</param> private void HandleStructElement(StructureLayout layout, XElement element, string name, int offset) { string layoutName = XMLUtil.GetStringAttribute(element, "layout"); // Queue the structure to have its layout resolved later after all layouts have been loaded _structs.Enqueue(new QueuedStructure(name, offset, layoutName, layout)); }
public QueuedStructure(string name, int offset, string layoutName, StructureLayout owner) { Name = name; Offset = offset; LayoutName = layoutName; Owner = owner; }