Пример #1
0
            void DisallowTags()
            {
                BlamLib.IO.EndianReader input = new BlamLib.IO.EndianReader(output.FileName);
                input.BaseAddress = Program.PeAddressMask;
                input.Seek(AddressOf.TagGroupDefinitions[Platform.Guerilla] - Program.PeAddressMask);

                uint[] offsets = new uint[Constants.StockTagGroupCount];
                for (int x = 0; x < offsets.Length; x++)
                {
                    offsets[x] = input.ReadPointer();
                }

                for (int x = 0; x < offsets.Length; x++)
                {
                    input.Seek(offsets[x]);
                    string name = Program.ReadCString(input.ReadPointer(), input);
                    if (IsDisallowedTag(name))
                    {
                        input.Seek(0x20, System.IO.SeekOrigin.Current);
                        output.Seek(input.Position - 2);
                        output.Write((short)1);
                        output.Seek(input.ReadPointer() + 0x14);
                        output.Write(0);
                        output.Write(0);
                        output.Write(0);
                    }
                }
                input.Close();
            }
        public override void Read(BlamLib.IO.EndianReader s)
        {
            CacheFile cache  = s.Owner as CacheFile;
            bool      isHA10 = cache.EngineVersion == BlamVersion.Halo1_XboxX || cache.EngineVersion == BlamVersion.Halo1_PCX;

            GameDefinition gd = Program.Halo1.Manager;

            GroupTagInt = s.ReadUInt32();
            groupTag    = gd.TagGroupFind(TagInterface.TagGroup.FromUInt(GroupTagInt));
            IO.ByteSwap.SwapUDWord(ref GroupTagInt);

            uint group_tag_int = s.ReadUInt32();

            if (group_tag_int != uint.MaxValue)
            {
                groupParent1 = gd.TagGroupFind(TagInterface.TagGroup.FromUInt(group_tag_int));
            }
            else
            {
                groupParent1 = TagInterface.TagGroup.Null;
            }

            group_tag_int = s.ReadUInt32();
            if (group_tag_int != uint.MaxValue)
            {
                groupParent2 = gd.TagGroupFind(TagInterface.TagGroup.FromUInt(group_tag_int));
            }
            else
            {
                groupParent2 = TagInterface.TagGroup.Null;
            }

            datum.Read(s);
            tagNameOffset = s.ReadPointer();

            address = s.ReadUInt32();             // external index for pc\ce, if its a bitmap, ptr if its a sound or anything else
            // TODO: HA10 Xbox doesn't use data files (and a PC port probably won't either)
            if (isHA10 || address > s.BaseAddress)
            {
                offset = (int)(address - s.BaseAddress);
            }
            this.location = (CacheIndex.ItemLocation)s.ReadInt32();             // bool_in_data_file

            s.ReadInt32();
        }
Пример #3
0
        public override void Read(BlamLib.IO.EndianReader s)
        {
            GameDefinition gd = Program.Stubbs.Manager;

            GroupTagInt = s.ReadUInt32();
            groupTag    = gd.TagGroupFind(TagInterface.TagGroup.FromUInt(GroupTagInt));
            Debug.Assert.If(groupTag != null, "{0}", new string(TagInterface.TagGroup.FromUInt(GroupTagInt)));
            IO.ByteSwap.SwapUDWord(ref GroupTagInt);

            uint group_tag_int = s.ReadUInt32();

            if (group_tag_int != uint.MaxValue)
            {
                groupParent1 = gd.TagGroupFind(TagInterface.TagGroup.FromUInt(group_tag_int));
            }
            else
            {
                groupParent1 = TagInterface.TagGroup.Null;
            }

            group_tag_int = s.ReadUInt32();
            if (group_tag_int != uint.MaxValue)
            {
                groupParent2 = gd.TagGroupFind(TagInterface.TagGroup.FromUInt(group_tag_int));
            }
            else
            {
                groupParent2 = TagInterface.TagGroup.Null;
            }

            datum.Read(s);
            tagNameOffset = s.ReadPointer();

            address = s.ReadUInt32();
            offset  = (int)(address - s.BaseAddress);

            s.ReadInt32();
            s.ReadInt32();
        }
Пример #4
0
			void DisallowTags()
			{
				BlamLib.IO.EndianReader input = new BlamLib.IO.EndianReader(output.FileName);
				input.BaseAddress = Program.PeAddressMask;
				input.Seek(AddressOf.TagGroupDefinitions[Platform.Guerilla] - Program.PeAddressMask);

				uint[] offsets = new uint[Constants.StockTagGroupCount];
				for (int x = 0; x < offsets.Length; x++)
					offsets[x] = input.ReadPointer();

				for (int x = 0; x < offsets.Length; x++)
				{
					input.Seek(offsets[x]);
					string name = Program.ReadCString(input.ReadPointer(), input);
					if (IsDisallowedTag(name))
					{
						input.Seek(0x20, System.IO.SeekOrigin.Current);
						output.Seek(input.Position - 2);
						output.Write((short)1);
						output.Seek(input.ReadPointer() + 0x14);
						output.Write(0);
						output.Write(0);
						output.Write(0);
					}
				}
				input.Close();
			}
Пример #5
0
        public override void Read(BlamLib.IO.EndianReader s)
        {
            CacheFile cache = s.Owner as CacheFile;

            tagsOffset = (uint)(cache.Header.OffsetToIndex + cache.HeaderHalo2.IndexStreamSize);
            bool is_alpha = cache.EngineVersion == BlamVersion.Halo2_Alpha;
            bool is_echo  = cache.EngineVersion == BlamVersion.Halo2_Epsilon;
            bool is_pc    = cache.EngineVersion == BlamVersion.Halo2_PC;
            bool is_mp    = cache.HeaderHalo2.CacheType == CacheType.Multiplayer;

            Managers.BlamDefinition bdef = Program.GetManager(cache.EngineVersion);

            uint tags_addressmask;

            if (!is_pc)
            {
                cache.AddressMask =
                    bdef[cache.EngineVersion].CacheTypes.BaseAddress - (uint)cache.Header.OffsetToIndex;
                tags_addressmask =
                    (uint)(cache.Header.OffsetToIndex + cache.HeaderHalo2.IndexStreamSize);
            }
            else
            {
                // pc maps use virtual addresses which are actually offsets relative to
                // the start of the tag memory buffer. since these are offsets and not actually
                // addresses which we would normally mask the base off of, we have to do some
                // number magic so our subtraction operations actually end up working in reverse
                // to get the correct file offset
                tags_addressmask = 0 - (uint)cache.Header.OffsetToIndex;

                cache.AddressMask = tags_addressmask;
            }

            #region version dependant loading
            if (is_alpha)
            {
                groupTagsAddress = address = s.ReadUInt32();
                groupTagsCount   = 0;
                scenario.Read(s);
                s.ReadInt32();                 // crc
                tagCount = s.ReadInt32();
                items    = new CacheItem[tagCount];
                s.ReadInt32();                 // 'tags'
            }
            else if (is_pc)
            {
                groupTagsAddress = s.ReadPointer();            // offset (relative to the tag index offset)
                groupTagsCount   = s.ReadInt32();
                uint offset = s.ReadPointer();                 // offset (relative to the tag index offset) to the tag entries
                scenario.Read(s);
                gameGlobals.Read(s);
                s.ReadInt32();                 // crc
                tagCount = s.ReadInt32();
                items    = new CacheItem[tagCount];
                s.ReadInt32();                                         // 'tags'

                s.Seek(offset /*- 32, System.IO.SeekOrigin.Current*/); // go to the first tag entry
            }
            else
            {
                groupTagsAddress = s.ReadUInt32();
                groupTagsCount   = s.ReadInt32();
                address          = s.ReadUInt32();
                scenario.Read(s);
                gameGlobals.Read(s);
                s.ReadInt32();                 // crc
                tagCount = s.ReadInt32();
                items    = new CacheItem[tagCount];
                s.ReadInt32();                                             // 'tags'

                s.Seek(groupTagsCount * 12, System.IO.SeekOrigin.Current); // go to the first tag entry
            }

            this.groupTagsOffset = this.groupTagsAddress - s.BaseAddress;
            #endregion

            CacheItem item;
            uint      temp_pos    = 0;
            uint      sbsp_offset = 0;

            DatumIndex[] ltmps = null;
            Tags.scenario_structure_bsp_reference_block bsp_block = new Tags.scenario_structure_bsp_reference_block();

            if (is_pc)             // MP maps need this adjustment
            {
                cache.AddressMask = tags_addressmask += cache.HeaderHalo2.PcFields.VirtualAddress;
            }

            for (int x = 0; x < items.Length; x++)
            {
                item     = new CacheItem();
                items[x] = item;
                if (is_alpha)
                {
                    item.ReadAlpha(s);
                }
                else
                {
                    item.Read(s);
                }

                if (item.Location == ItemLocation.Unknown)
                {
                    items[x] = CacheItem.Null;
                }
                else if (is_pc && item.HasExternalData)
                {
                    HasExternalTags = true;
                }
            }

            if (!is_pc)
            {
                // While the tag definitions come right after the tag header in a cache file, when
                // finally loaded into game memory this isn't the case. The 'stream' size of the tag
                // header is how much actual memory is used by map's generated the tag header, but the
                // map's tag header may not utilize the entire memory space dedicated to it in game memory.
                // So, the game would read the tag header data using the offset and 'stream' size data from
                // the cache header, then it would seek to offset+stream_size to get to the tag definitions
                // which it would then read into game memory at the memory location defined by 'address'
                tags_addressmask =
                    items[0].Address - tags_addressmask;
                cache.AddressMask = tags_addressmask;
                for (int x = 0; x < items.Length; x++)
                {
                    item        = items[x];
                    item.Offset = (int)(item.Address - tags_addressmask);

                    #region on scnr tag
                    if (!is_alpha && !is_echo && TagGroups.scnr.ID == item.GroupTag.ID)
                    {
                        temp_pos = s.PositionUnsigned;

                        //if (is_alpha || is_echo)
                        //	s.Seek(item.Offset + 828);
                        //else
                        s.Seek(item.Offset + 528);

                        bspTags     = new Item[s.ReadInt32()];
                        sbsp_offset = s.ReadPointer();

                        ltmps = new DatumIndex[bspTags.Length];

                        s.Seek(temp_pos);
                    }
                    #endregion
                    #region on sbsp tag
                    else if (!is_alpha && !is_echo && TagGroups.sbsp.ID == item.GroupTag.ID)
                    {
                        temp_pos = s.PositionUnsigned;

                        s.Seek(sbsp_offset + (uint)(bspCount *
                                                    Halo2.Tags.scenario_structure_bsp_reference_block.kRuntimeSizeOf));
                        bspTags[bspCount] = item;
                        bsp_block.Read(cache);

                        if (bsp_block.RuntimeOffset != 0)
                        {
                            item.Offset  = bsp_block.RuntimeOffset;
                            item.Size    = bsp_block.RuntimeSize;
                            item.Address = (uint)bsp_block.RuntimeAddress.Value;
                            //cache.BspAddressMasks.Add((uint)(item.Address - item.Offset));
                        }

                        ltmps[bspCount] = bsp_block.Lightmap.Datum;
                        item.BspIndex   = bspCount++;

                        s.Seek(temp_pos);
                    }
                    #endregion
                }
            }

            #region alpha tag name code
            if (is_alpha)
            {
                // following the tag datums in alpha builds is the tag names buffer
                foreach (Halo2.CacheItem ci in items)
                {
                    ci.TagNameOffset = s.PositionUnsigned;
                    ci.ReferenceName = cache.References.AddOptimized(ci.GroupTag, s.ReadCString());
                }
            }
            #endregion
            #region retail tag name & bsp offset fixup code
            else
            {
                // Build the absolute tag name offsets
                s.Seek(cache.HeaderHalo2.TagNameIndicesOffset);
                int[] offsets = new int[tagCount];
                for (int x = 0; x < offsets.Length; x++)
                {
                    int offset = s.ReadInt32();
                    // Offset will be -1 if the tag in question is 'null'
                    if (offset != -1)
                    {
                        offset += cache.HeaderHalo2.TagNamesBufferOffset;
                    }

                    offsets[x] = offset;
                }
                // Fixup all tag instances which are named
                for (int x = 0; x < tagCount; x++)
                {
                    if (offsets[x] != -1)
                    {
                        FixupTagInstanceHeaderName(cache, items[x], offsets[x], s);
                    }
                }

                // PC maps store all zones in the tag memory, they don't need to swap out and thus don't
                // need any fix ups (durrr, PCs have loltons of RAM)
                if (!is_pc && !is_echo)
                {
                    var head = new Halo2.Tags.scenario_structure_bsps_header();
                    foreach (CacheItem tmp_item in bspTags)
                    {
                        s.Seek(tmp_item.Offset);
                        head.Read(cache);

                        // bsp
                        uint bsp_address_mask = head.FixupBspInstanceHeader(tmp_item, s.Position);
                        cache.BspAddressMasks.Add(bsp_address_mask);

                        // ltmp
                        DatumIndex ltmp_datum = ltmps[tmp_item.BspIndex];
                        if (ltmp_datum != DatumIndex.Null)
                        {
                            head.FixupLightmapInstanceHeader(this.items[ltmp_datum.Index], tmp_item);
                        }
                    }
                }
            }
            #endregion
        }