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"); }
private void Load(StructureValueCollection values, ushort index, FileSegmentGroup metaArea, IList <ITagClass> classList, 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 classIndex = (int)values.GetInteger("class index"); if (classIndex >= 0 && classIndex < classList.Count) { Class = classList[classIndex]; } var salt = (ushort)values.GetInteger("datum index salt"); if (salt != 0xFFFF) { Index = new DatumIndex(salt, index); } else { Index = DatumIndex.Null; } }
private void AdjustPartitions() { if (MetaArea == null) { return; } // Find the first partition and change it to the meta area's base address Partition partition = Partitions.First(); if (partition != null) { partition.BasePointer = SegmentPointer.FromPointer(MetaArea.BasePointer, MetaArea); } // Recalculate the size of each partition int partitionEnd = MetaArea.Offset + MetaArea.Size; for (int i = Partitions.Length - 1; i >= 0; i--) { if (Partitions[i].BasePointer == null) { continue; } int offset = Partitions[i].BasePointer.AsOffset(); Partitions[i].Size = (uint)(partitionEnd - offset); partitionEnd = offset; } }
private void Load(StructureValueCollection values, ushort index, FileSegmentGroup metaArea, IList <ITagClass> classList) { uint address = values.GetInteger("memory address"); VirtualAddr = address; address = NewPointerConverter.ConvertToPointer(address); if (address != 0 && address != 0xFFFFFFFF) { MetaLocation = SegmentPointer.FromPointer(address, metaArea); } var classIndex = (int)values.GetInteger("class index"); if (classIndex >= 0 && classIndex < classList.Count) { Class = classList[classIndex]; } var salt = (ushort)values.GetInteger("datum index salt"); if (salt != 0xFFFF) { Index = new DatumIndex(salt, index); } else { Index = DatumIndex.Null; } }
private Partition[] LoadPartitions(StructureValueCollection[] partitionValues) { IEnumerable <Partition> result = from partition in partitionValues select new Partition ( partition.GetInteger("load address") != 0 ? SegmentPointer.FromPointer((long)partition.GetInteger("load address"), MetaArea) : null, (uint)partition.GetInteger("size") ); return(result.ToArray()); }
/* * private void AdjustPartitions() * { * if (MetaArea == null) * return; * * // Find the first partition with a non-null address and change it to the meta area's base address * Partition partition = Partitions.First(p => p.BasePointer != null); * if (partition != null) * partition.BasePointer = SegmentPointer.FromPointer(MetaArea.BasePointer, MetaArea); * * // Recalculate the size of each partition * int partitionEnd = MetaArea.Offset + MetaArea.Size; * for (int i = Partitions.Length - 1; i >= 0; i--) * { * if (Partitions[i].BasePointer == null) * continue; * * int offset = Partitions[i].BasePointer.AsOffset(); * Partitions[i].Size = (uint) (partitionEnd - offset); * partitionEnd = offset; * } * } */ /* * private StructureValueCollection[] SerializePartitions() * { * if (Partitions == null) * return new StructureValueCollection[0]; * * var results = new StructureValueCollection[Partitions.Length]; * for (int i = 0; i < Partitions.Length; i++) * { * var values = new StructureValueCollection(); * values.SetInteger("load address", Partitions[i].BasePointer != null ? Partitions[i].BasePointer.AsPointer() : 0); * values.SetInteger("size", Partitions[i].Size); * results[i] = values; * } * return results; * } */ /// <summary> /// Rebuilds the interop data table in a cache file. /// </summary> /// <param name="localeArea">The localization area of the file.</param> /* * private void RebuildInteropData(FileSegmentGroup localeArea) * { * * FourthGenInteropSection debugSection = Sections[(int) FourthGenInteropSectionType.Debug]; * FourthGenInteropSection rsrcSection = Sections[(int) FourthGenInteropSectionType.Resource]; * FourthGenInteropSection tagSection = Sections[(int) FourthGenInteropSectionType.Tag]; * FourthGenInteropSection localeSection = Sections[(int) FourthGenInteropSectionType.Localization]; * * // Recompute base addresses * // Section addresses are usually in the following order: resource, locale, tag, debug. * // Each address can immediately follow after the previous non-null section, * // even though this isn't the case in some of the official files (because of removed debug data). * // * // TODO: This could possibly be made into a for loop and cleaned up if the pointer converters are stored in an array. * // I just want to get this working for now. * rsrcSection.VirtualAddress = 0; // This is always zero * rsrcSection.Size = (ResourcePointerConverter != null) ? (uint) RawTable.Size : 0; * localeSection.VirtualAddress = (LocalePointerConverter != null) ? rsrcSection.VirtualAddress + rsrcSection.Size : 0; * localeSection.Size = (LocalePointerConverter != null) ? (uint) localeArea.Size : 0; * tagSection.VirtualAddress = (TagBufferPointerConverter != null) * ? rsrcSection.VirtualAddress + rsrcSection.Size + localeSection.Size * : 0; * tagSection.Size = (TagBufferPointerConverter != null) ? (uint) MetaArea.Size : 0; * debugSection.VirtualAddress = (DebugPointerConverter != null) * ? rsrcSection.VirtualAddress + rsrcSection.Size + localeSection.Size + tagSection.Size * : 0; * debugSection.Size = (DebugPointerConverter != null) ? (uint) StringArea.Size : 0; * * // If the offset mask for the debug section wasn't originally zero, then we have to subtract the first partition size from the debug base address * // Not entirely sure why this is the case, but that's what the official files do * if (debugSection.VirtualAddress != 0 && SectionOffsetMasks[(int) FourthGenInteropSectionType.Debug] != 0) * debugSection.VirtualAddress -= Partitions[0].Size; * * // Recompute offset masks * SectionOffsetMasks[(int) FourthGenInteropSectionType.Debug] = (debugSection.Size > 0) * ? (uint) (StringArea.Offset - debugSection.VirtualAddress) * : 0; * SectionOffsetMasks[(int) FourthGenInteropSectionType.Resource] = (rsrcSection.Size > 0) * ? (uint) (RawTable.Offset - rsrcSection.VirtualAddress) * : 0; * SectionOffsetMasks[(int) FourthGenInteropSectionType.Tag] = (tagSection.Size > 0) * ? (uint) (MetaArea.Offset - tagSection.VirtualAddress) * : 0; * SectionOffsetMasks[(int) FourthGenInteropSectionType.Localization] = (localeSection.Size > 0) * ? (uint) (localeArea.Offset - localeSection.VirtualAddress) * : 0; * * // Update pointer converters * if (DebugPointerConverter != null) * DebugPointerConverter.BasePointer = debugSection.VirtualAddress; * if (ResourcePointerConverter != null) * ResourcePointerConverter.BasePointer = rsrcSection.VirtualAddress; * if (TagBufferPointerConverter != null) * TagBufferPointerConverter.BasePointer = tagSection.VirtualAddress; * if (LocalePointerConverter != null) * LocalePointerConverter.BasePointer = localeSection.VirtualAddress; * } */ private void Load(StructureValueCollection map_values, StructureValueCollection tag_values, StructureValueCollection string_values, FileSegmenter map_segmenter) { map_segmenter.DefineSegment(0, HeaderSize, 1, SegmentResizeOrigin.Beginning); // Define a segment for the header _eofSegment = map_segmenter.WrapEOF((int)map_values.GetInteger("file size")); //LoadInteropData(map_values, tag_values); //RawTable = CalculateRawTableSegment(segmenter); Type = (CacheFileType)map_values.GetInteger("type"); InternalName = map_values.GetString("internal name"); ScenarioPath = map_values.GetString("scenario path"); uint index_header_address = map_values.GetInteger("index header address"); // File Segment FileSegmenter tags_segmenter = new FileSegmenter(); tags_segmenter.DefineSegment(0, (int)EngineInfo.TagsDataSize, 0x1, SegmentResizeOrigin.Beginning); // Define a segment for the header FileSegment metaSegment = new FileSegment(0, tags_segmenter); //FileSegment metaSegment = CalculateTagDataSegment(tag_values, segmenter); MetaArea = new FileSegmentGroup(new MetaAddressConverter(metaSegment, index_header_address)); MetaArea.AddSegment(metaSegment); IndexHeaderLocation = SegmentPointer.FromPointer(index_header_address, MetaArea); //XDKVersion = (int) values.GetInteger("xdk version"); /* * FileSegment metaSegment = CalculateTagDataSegment(values, segmenter); * if (metaSegment != null) * { * uint virtualBase = values.GetInteger("virtual base address"); * MetaArea = new FileSegmentGroup(new MetaAddressConverter(metaSegment, virtualBase)); * MetaArea.AddSegment(metaSegment); * * IndexHeaderLocation = SegmentPointer.FromPointer(values.GetInteger("index header address"), MetaArea); * Partitions = LoadPartitions(values.GetArray("partitions")); * } * else * { * Partitions = new Partition[0]; * } */ CalculateStringGroup(string_values, map_segmenter); }
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, 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"); }
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 void Load(StructureValueCollection values, FileSegmentGroup metaArea, Dictionary <int, ITagGroup> groupsById) { // 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")); // NOTE: cant really split filenames into a segment // because offset is relative to the meta header uint nameOffset = (uint)values.GetInteger("name offset"); if (nameOffset > 0) { FileNameOffset = SegmentPointer.FromPointer(nameOffset, metaArea); } //FileNameOffset = SegmentPointer.FromOffset((int)nameOffset, metaArea); uint offset = (uint)values.GetInteger("offset"); // checking the meta area contains the offset // and that the tag element is not pointing to a data file if (offset > 0 && metaArea.ContainsPointer(offset) && (values.GetInteger("is in data file") != 1)) { MetaLocation = SegmentPointer.FromPointer(offset, metaArea); } // TODO (Dragon): the offset can actually be 0 when used // as a data file table index //else if (offset > 0 && !metaArea.ContainsPointer(offset)) // TODO (Dragon): load the tag from a data file // bitm: bitmaps.map // font: loc.map // ustr: loc.map // hmt : loc.map }
public long InjectDataBlock(DataBlock block, IStream stream) { if (block == null) { throw new ArgumentNullException("block is null"); } // Don't inject the block if it's already been injected long newAddress; if (_dataBlockAddresses.TryGetValue(block, out newAddress)) { return(newAddress); } // Allocate space for it and write it to the file newAddress = _cacheFile.Allocator.Allocate(block.Data.Length, (uint)block.Alignment, stream); SegmentPointer location = SegmentPointer.FromPointer(newAddress, _cacheFile.MetaArea); WriteDataBlock(block, location, stream); return(newAddress); }
/// <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); }