예제 #1
0
        private void Load(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, StringIDSource stringIDs, BuildInformation buildInfo)
        {
            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");

            Parameters = LoadParameters(reader, values, metaArea, buildInfo);
        }
예제 #2
0
 private string GetObjectName(StructureValueCollection values, StringIDSource stringIDs)
 {
     if (values.HasString("name"))
     {
         return values.GetString("name");
     }
     if (values.HasInteger("name stringid"))
     {
         var sid = new StringID(values.GetInteger("name stringid"));
         return stringIDs.GetString(sid);
     }
     throw new InvalidOperationException("Unable to determine the name of objects in the \"" + _layoutName + "\" layout");
 }
예제 #3
0
        private void CalculateStringGroup(StructureValueCollection values, FileSegmenter segmenter)
        {
            if (DebugPointerConverter == null)
                return;

            StringArea = new FileSegmentGroup(DebugPointerConverter);

            // StringIDs
            StringIDCount = (int) values.GetInteger("string table count");
            if (StringIDCount > 0)
            {
                int sidIndexTableOff = DebugPointerConverter.PointerToOffset(values.GetInteger("string index table offset"));
                int sidDataOff = DebugPointerConverter.PointerToOffset(values.GetInteger("string table offset"));

                var sidTableSize = (int) values.GetInteger("string table size");
                StringIDIndexTable = segmenter.WrapSegment(sidIndexTableOff, StringIDCount*4, 4, SegmentResizeOrigin.End);
                StringIDData = segmenter.WrapSegment(sidDataOff, sidTableSize, 1, SegmentResizeOrigin.End);

                StringIDIndexTableLocation = StringArea.AddSegment(StringIDIndexTable);
                StringIDDataLocation = StringArea.AddSegment(StringIDData);

                // idk what this is, but H3Beta has it
                if (values.HasInteger("string block offset"))
                {
                    int sidBlockOff = DebugPointerConverter.PointerToOffset(values.GetInteger("string block offset"));
                    StringBlock = segmenter.WrapSegment(sidBlockOff, StringIDCount*0x80, 0x80, SegmentResizeOrigin.End);
                    StringBlockLocation = StringArea.AddSegment(StringBlock);
                }
            }

            // Tag names
            FileNameCount = (int) values.GetInteger("file table count");
            if (FileNameCount > 0)
            {
                int nameIndexTableOff = DebugPointerConverter.PointerToOffset(values.GetInteger("file index table offset"));
                int nameDataOff = DebugPointerConverter.PointerToOffset(values.GetInteger("file table offset"));

                var fileTableSize = (int) values.GetInteger("file table size");
                FileNameIndexTable = segmenter.WrapSegment(nameIndexTableOff, FileNameCount*4, 4, SegmentResizeOrigin.End);
                FileNameData = segmenter.WrapSegment(nameDataOff, fileTableSize, 1, SegmentResizeOrigin.End);

                FileNameIndexTableLocation = StringArea.AddSegment(FileNameIndexTable);
                FileNameDataLocation = StringArea.AddSegment(FileNameData);
            }

            // Some H4-only unknown table
            if (values.HasInteger("unknown table count") && values.HasInteger("unknown table offset"))
            {
                UnknownCount = (int) values.GetInteger("unknown table count");
                if (UnknownCount > 0)
                {
                    int unknownOff = DebugPointerConverter.PointerToOffset(values.GetInteger("unknown table offset"));
                    UnknownTable = segmenter.WrapSegment(unknownOff, UnknownCount*0x10, 0x10, SegmentResizeOrigin.End);
                    UnknownTableLocation = StringArea.AddSegment(UnknownTable);
                }
            }
        }
예제 #4
0
 public ThirdGenGlobalObject(StructureValueCollection values, StringIDSource stringIDs)
 {
     Name = values.HasInteger("name index") ? stringIDs.GetString(new StringID(values.GetInteger("name index"))) : values.GetString("name");
     Class = (short)values.GetInteger("type");
     PlacementIndex = (short)values.GetInteger("placement index");
 }
예제 #5
0
        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);
        }
예제 #6
0
        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));
        }
예제 #7
0
        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 = tagValues.GetInteger(addressName);
            StructureLayout layout = _buildInfo.Layouts.GetLayout("zone set definition");
            StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, _metaArea);
            foreach (StructureValueCollection entry in entries)
                ThirdGenZoneSet.Free(entry, _allocator);
        }
예제 #8
0
        private FileSegment CalculateRawTableSegment(StructureValueCollection values, FileSegmenter segmenter)
        {
            // WAT. H3BETA DOESN'T HAVE THIS. WAT.
            if (values.HasInteger("raw table size") && values.HasInteger("raw table offset"))
            {
                // Load the basic values
                int rawTableSize = (int)values.GetInteger("raw table size");
                int rawTableOffset = (int)values.GetInteger("raw table offset");
                _originalRawTableOffset = rawTableOffset;

                // If the original raw table offset was 0, load it from the alternate pointer
                if (rawTableOffset == 0)
                    rawTableOffset = (int)values.GetInteger("alternate raw table offset");

                return segmenter.WrapSegment(rawTableOffset, rawTableSize, 0x1000, SegmentResizeOrigin.End);
            }
            else
            {
                return null;
            }
        }
예제 #9
0
        private int CalculateMetaOffset(StructureValueCollection values)
        {
            if (values.HasInteger("raw table offset") && values.HasInteger("raw table size"))
            {
                // Load raw table info
                int rawTableSize = (int)values.GetInteger("raw table size");
                int rawTableOffset = (int)values.GetInteger("raw table offset");

                // There are two ways to get the meta offset:
                // 1. Raw table offset + raw table size
                // 2. If raw table offset is zero, then the meta offset is directly stored in the header
                //    (The raw table offset can still be calculated in this case, but can't be used to find the meta the traditional way)
                if (rawTableOffset != 0)
                    return rawTableOffset + rawTableSize;
            }

            uint offset;
            if (!values.FindInteger("meta offset", out offset))
                throw new ArgumentException("The XML layout file is missing information on how to find the meta offset.");
            return (int)offset;
        }
예제 #10
0
        private BitArray LoadBitArray(StructureValueCollection values, string countName, string addressName, IReader reader)
        {
            if (!values.HasInteger(countName) || !values.HasInteger(addressName))
                return new BitArray(0);

            var count = (int) values.GetInteger(countName);
            uint address = values.GetInteger(addressName);
            if (count <= 0 || address == 0)
                return new BitArray(0);

            var ints = new int[count];
            reader.SeekTo(_metaArea.PointerToOffset(address));
            for (int i = 0; i < count; i++)
                ints[i] = reader.ReadInt32();

            return new BitArray(ints);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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 ThirdGenResourceType(e, stringIDs)).ToArray();
        }