コード例 #1
0
        public CacheSegmenter(IGen3CacheFile cache)
        {
            if (cache.CacheType < CacheType.Halo3Retail || cache.Metadata.IsPreRelease)
            {
                throw new NotSupportedException();
            }

            this.cache = cache;

            var debugTranslator    = new SectionAddressTranslator(cache, 0);
            var resourceTranslator = new SectionAddressTranslator(cache, 1);
            var metadataTranslator = new SectionAddressTranslator(cache, 2);
            var localeTranslator   = new SectionAddressTranslator(cache, 3);

            //header
            segments.Add(new Segment(0, cache.GetHeaderSize(), 1));

            //eof
            segments.Add(new Segment((int)cache.Header.FileSize, 0, 1));

            //sections
            var origin = (int)resourceTranslator.GetAddress(resourceTranslator.VirtualAddress);
            var size   = (int)cache.Header.SectionTable[1].Size;

            segments.Add(resourceSegment = new Segment(origin, size, 0x1000));

            origin = (int)metadataTranslator.GetAddress(metadataTranslator.VirtualAddress);
            size   = cache.Header.VirtualSize;
            segments.Add(metadataSegment = new Segment(origin, size, 0x10000));

            //strings
            origin = (int)debugTranslator.GetAddress(cache.Header.StringTableIndexPointer.Value);
            size   = cache.Header.StringCount * 4;
            segments.Add(stringsGroup.Add(stringSegments[0] = new Segment(origin, size, 4)));

            origin = (int)debugTranslator.GetAddress(cache.Header.StringTablePointer.Value);
            size   = cache.Header.StringTableSize;
            segments.Add(stringsGroup.Add(stringSegments[1] = new Segment(origin, size, cache.UsesStringEncryption ? 16 : 1)));

            //tag names
            origin = (int)debugTranslator.GetAddress(cache.Header.FileTableIndexPointer.Value);
            size   = cache.Header.FileCount * 4;
            segments.Add(stringsGroup.Add(stringSegments[2] = new Segment(origin, size, 4)));

            origin = (int)debugTranslator.GetAddress(cache.Header.FileTablePointer.Value);
            size   = cache.Header.FileTableSize;
            segments.Add(stringsGroup.Add(stringSegments[3] = new Segment(origin, size, 1)));

            //only exists in mcc reach (U3+)
            var mcc3 = cache.Header as IMccGen3Header;

            if (mcc3?.StringNamespaceCount > 0)
            {
                origin = (int)debugTranslator.GetAddress(mcc3.StringNamespaceTablePointer.Value);
                size   = mcc3.StringNamespaceCount * 4;
                segments.Add(stringSegments[4] = stringsGroup.Add(new Segment(origin, size, 4)));
            }

            var gen4 = cache.Header as IGen4Header;

            if (gen4?.UnknownTableSize > 0)
            {
                origin = (int)debugTranslator.GetAddress(gen4.UnknownTablePointer.Value);
                size   = gen4.UnknownTableSize * 16;
                segments.Add(stringSegments[5] = stringsGroup.Add(new Segment(origin, size, 16)));
            }

            for (int i = 0; i < cache.LocaleIndex.Languages.Count; i++)
            {
                var def = cache.LocaleIndex.Languages[i];
                if (def.StringCount <= 0)
                {
                    continue;
                }

                var segs = new Segment[2];

                origin = (int)localeTranslator.GetAddress(def.IndicesOffset);
                size   = def.StringCount * 8;
                segments.Add(segs[0] = localesGroup.Add(new Segment(origin, size, 8)));

                origin = (int)localeTranslator.GetAddress(def.StringsOffset);
                size   = def.StringsSize;
                segments.Add(segs[1] = localesGroup.Add(new Segment(origin, size, cache.UsesStringEncryption ? 16 : 1)));

                localeSegments.Add(i, segs);
            }

            segments.Sort((a, b) => a.Offset.CompareTo(b.Offset));

            for (int i = 0; i < segments.Count - 1; i++)
            {
                segments[i].NextSegment = segments[i + 1];
            }
        }