示例#1
0
        /// <summary>
        /// Postprocess tag data that has been streamed to a cache block
        /// </summary>
        /// <param name="locator">Offset of the tag data header in the section</param>
        /// <param name="data"></param>
        /// <returns></returns>
        internal bool ReconstructTagData(short locator, TagInterface.Data data)
        {
            int index = 0;

            IO.EndianReader er;

            if (GeometryBlock == null)
            {
                return(false);
            }

            foreach (geometry_block_resource_block gb in Resources)
            {
                er = new BlamLib.IO.EndianReader(GeometryBlock[index]);

                switch (gb.Type.Value)
                {
                    #region TagData
                case (int)geometry_block_resource_type.TagData:
                    if (gb.PrimaryLocater.Value == locator)
                    {
                        data.Reset(er.ReadBytes(gb.Size));
                    }
                    break;
                    #endregion
                }

                index++;
                er.Close();
                er = null;
            }

            return(true);
        }
        internal bool Reconstruct(geometry_block_info_struct gbi)
        {
            int index = 0;

            byte[][] data = gbi.GeometryBlock;

            if (data == null)
            {
                return(false);
            }

            foreach (geometry_block_resource_block gb in gbi.Resources)
            {
                using (IO.EndianReader er = new BlamLib.IO.EndianReader(data[index]))
                {
                    switch (gb.Type.Value)
                    {
                        #region TagBlock
                    case (int)geometry_block_resource_type.TagBlock:
                        int count = gb.GetCount();
                        switch (gb.PrimaryLocater.Value)
                        {
                        case OffsetSoundDialogueInfo:
                            SoundDialogueInfo.Resize(count);
                            SoundDialogueInfo.Read(er);
                            break;
                        }
                        break;

                        #endregion
                        #region TagData
                    case (int)geometry_block_resource_type.TagData:
                        if (gb.PrimaryLocater.Value == OffsetEncodedData)
                        {
                            EncodedData.Reset(er.ReadBytes(gb.Size));
                        }
                        break;
                        #endregion
                    }
                }

                index++;
            }

            return(true);
        }
        public override void Read(BlamLib.IO.EndianReader s)
        {
            bool is_beta = false;
            bool is_odst = !((s.Owner as Blam.CacheFile).EngineVersion == BlamVersion.Halo3);

            Blam.CacheFile.ValidateHeader(s, kSizeOf);

            s.Seek(4);
            version = s.ReadInt32(); is_beta = version == 9;
            if (version != 9 && version != 11)
            {
                throw new InvalidCacheFileException(s.FileName);
            }
            fileLength = s.ReadInt32();
            s.ReadInt32();
            tagIndexAddress    = s.ReadUInt32();
            memoryBufferOffset = s.ReadInt32();
            memoryBufferSize   = s.ReadInt32();

            sourceFile = s.ReadAsciiString(256);
            build      = s.ReadTagString();
            cacheType  = (Blam.CacheType)s.ReadInt16();

            if (is_beta)
            {
                s.ReadInt16(); sharedType = Cache.SharedType.Beta;
                ReadBeta(s);
                return;
            }
            else
            {
                sharedType = (Cache.SharedType)s.ReadInt16();
            }

            s.ReadBool();
            s.ReadBool();             // false if it belongs to a untracked build
            s.ReadBool();
            s.ReadByte();             // appears to be an ODST-only field

            s.ReadInt32(); s.ReadInt32();
            s.ReadInt32(); s.ReadInt32(); s.ReadInt32();

            #region string id table
            // 0x158
            // old 128 byte aligned string table not used after the Delta builds of Halo 3

            stringIdsCount        = s.ReadInt32();
            stringIdsBufferSize   = s.ReadInt32();           // cstring buffer total size in bytes
            stringIdIndicesOffset = s.ReadInt32();
            stringIdsBufferOffset = s.ReadInt32();           // cstring buffer
            #endregion

            #region filetimes?
            // pretty sure this is a flags field
            // used to tell which of the following 64bit values
            // are used. Damn sure this are FILETIME structures, but
            // hex workshop doesn't like them so I can't be for sure...
            needsShared             = s.ReadInt32() != 0; // just a little 'hack' if you will. if zero, the map is self reliant, so no worries
            Filetime.dwHighDateTime = s.ReadInt32();
            Filetime.dwLowDateTime  = s.ReadInt32();
            if (s.ReadInt32() != 0)
            {
                flags.Add(CacheHeaderFlags.DependsOnMainMenu);
            }
            s.ReadInt32();
            if (s.ReadInt32() != 0)
            {
                flags.Add(CacheHeaderFlags.DependsOnShared);
            }
            s.ReadInt32();
            if (s.ReadInt32() != 0)
            {
                flags.Add(CacheHeaderFlags.DependsOnCampaign);
            }
            s.ReadInt32();
            #endregion

            name = s.ReadTagString();
            s.ReadInt32();
            scenarioPath = s.ReadAsciiString(256);
            s.ReadInt32();             // minor version, normally not used

            #region tag names
            tagNamesCount        = s.ReadInt32();
            tagNamesBufferOffset = s.ReadInt32();           // cstring buffer
            tagNamesBufferSize   = s.ReadInt32();           // cstring buffer total size in bytes
            tagNameIndicesOffset = s.ReadInt32();
            #endregion

            checksum = s.ReadUInt32();                // 0x2C4
            s.Seek(32, System.IO.SeekOrigin.Current); // these bytes are always the same

            baseAddress = s.ReadUInt32();             // expected base address
            xdkVersion  = s.ReadInt32();              // xdk version

            #region memory partitions
            // 0x2E8

            // memory partitions
            memoryPartitions = new Partition[6];
            memoryPartitions[0].BaseAddress = s.ReadUInt32();             // cache resource buffer
            memoryPartitions[0].Size        = s.ReadInt32();

            // readonly
            memoryPartitions[1].BaseAddress = s.ReadUInt32();             // sound cache resource buffer
            memoryPartitions[1].Size        = s.ReadInt32();

            memoryPartitions[2].BaseAddress = s.ReadUInt32();             // global tags buffer
            memoryPartitions[2].Size        = s.ReadInt32();
            memoryPartitions[3].BaseAddress = s.ReadUInt32();             // shared tag blocks?
            memoryPartitions[3].Size        = s.ReadInt32();
            memoryPartitions[4].BaseAddress = s.ReadUInt32();             // address
            memoryPartitions[4].Size        = s.ReadInt32();

            // readonly
            memoryPartitions[5].BaseAddress = s.ReadUInt32();             // map tags buffer
            memoryPartitions[5].Size        = s.ReadInt32();
            #endregion

            int count = s.ReadInt32();
            s.Seek(12, System.IO.SeekOrigin.Current);             // these bytes are always the same
            // if there is a hash in the header, this is the ONLY
            // place where it can be
            s.Seek(20 /*SHA1*/ + 40 + 256 /*RSA*/, System.IO.SeekOrigin.Current);             // ???

            // 0x46C
            cacheInterop.Read(s);
            cacheInterop.PostprocessForCacheRead(kSizeOf);

            s.Seek(16, System.IO.SeekOrigin.Current);             // GUID?, these bytes are always the same. ODST is different from Halo 3

            #region blah 1
            // 0x4AC

            // campaign has a shit load of these
            // but shared doesn't nor mainmenu
            // I compared the sc110 french and english and both have the SAME counts and element data. So
            // I don't think this is a hash or something. At least, if it is, it's not runtime relative so
            // nothing we have to worry about

            s.ReadInt16();             // I've only seen this be two different values (besides zero).
            count = s.ReadInt16();
            s.ReadInt32();             // seems to always be zero
            CompressionGuid = new Guid(s.ReadBytes(16));

            s.Seek(count * 28, System.IO.SeekOrigin.Current);             // seek past the elements
            // dword
            // long
            // buffer [0x14] (probably a sha1 hash)
            s.Seek((320 - count) * 28, System.IO.SeekOrigin.Current);             // seek past the unused elements
            #endregion

            #region blah 2
            {
                // 0x27C4
                // This on the other hand, sc110 french and english had MINOR differences. Those differences were in
                // DWORDs @ 0x4 and 0x8

                // 005 - 1
                // 010 - 3
                // 020 - 3
                // 030 - 2
                // 040 - 2
                // 050 - 2
                // 070 - 3
                // 100 - 3
                // 110 - 2
                // 120 - 2
                // 130 - 1

                // c100  - 1
                // c200  - 1
                // h100  - 9
                // l200  - 7
                // l300  - 8
                // sc100 - 5
                // sc110 - 5
                // sc120 - 6
                // sc130 - 6
                // sc140 - 6
                // sc150 - 6

                // going to punt and just assume there is a max count of 10 of these possible

                // maybe related to bsp\'zones'?
                int blah2_sizeof = !is_odst ? 172 : 180;

                count = (int)(s.ReadUInt32() >> 24);                               // did someone forget to f*****g byte swap something?
                s.Seek(count * blah2_sizeof, System.IO.SeekOrigin.Current);        // seek past the elements
                s.Seek((10 - count) * blah2_sizeof, System.IO.SeekOrigin.Current); // seek past the unused elements
            }
            #endregion

            s.Seek((!is_odst ? 380 : 300) + sizeof(uint), System.IO.SeekOrigin.Current);             // zero


            ReadPostprocessForInterop();

            ReadPostprocessForBaseAddresses(s);
        }
示例#4
0
        internal bool Reconstruct(
            BlamLib.Blam.CacheFile c,
            global_geometry_section_info_struct section,
            geometry_block_info_struct gbi
            )
        {
            int index = 0;

            byte[][] data = gbi.GeometryBlock;

            if (data == null)
            {
                return(false);
            }

            foreach (geometry_block_resource_block gb in gbi.Resources)
            {
                using (IO.EndianReader er = new BlamLib.IO.EndianReader(data[index]))
                {
                    switch (gb.Type.Value)
                    {
                        #region TagBlock
                    case (int)geometry_block_resource_type.TagBlock:
                        int count = gb.GetCount();
                        switch (gb.PrimaryLocater.Value)
                        {
                        case OffsetRawPoints:
                            RawPoints.Resize(count);
                            RawPoints.Read(er);
                            break;

                        case OffsetRigidPointGroups:
                            RigidPointGroups.Resize(count);
                            RigidPointGroups.Read(er);
                            break;

                        case OffsetVertexPointIndices:
                            VertexPointIndices.Resize(count);
                            VertexPointIndices.Read(er);
                            break;
                        }
                        break;

                        #endregion
                        #region TagData
                    case (int)geometry_block_resource_type.TagData:
                        switch (gb.PrimaryLocater.Value)
                        {
                        case OffsetRuntimePointData:
                            RuntimePointData.Reset(er.ReadBytes(gb.Size));
                            break;
                        }
                        break;
                        #endregion
                        #region VertexBuffer
                        //case (int)geometry_block_resource_type.VertexBuffer:
                        #endregion
                    }

                    index++;
                }
            }

            return(true);
        }
示例#5
0
        /// <summary></summary>
        /// <param name="c"></param>
        /// <param name="section_info">Can be null if tag data doesn't have it</param>
        /// <param name="gbi"></param>
        /// <returns></returns>
        internal bool Reconstruct(Blam.CacheFile c,
                                  global_geometry_section_info_struct section_info,
                                  geometry_block_info_struct gbi)
        {
            int index = 0;
            int x;

            byte[][] data = gbi.GeometryBlock;

            if (data == null)
            {
                return(false);
            }

            foreach (geometry_block_resource_block gb in gbi.Resources)
            {
                using (IO.EndianReader er = new BlamLib.IO.EndianReader(data[index]))
                {
                    switch (gb.Type.Value)
                    {
                        #region TagBlock
                    case (int)geometry_block_resource_type.TagBlock:
                        int count = gb.GetCount();
                        switch (gb.PrimaryLocater.Value)
                        {
                        case OffsetParts:
                            Parts.Resize(count);
                            Parts.Read(er);
                            break;

                        case OffsetSubparts:
                            Subparts.Resize(count);
                            Subparts.Read(er);
                            break;

                        case OffsetVisibilityBounds:
                            VisibilityBounds.Resize(count);
                            VisibilityBounds.Read(er);
                            break;

                        case OffsetStripIndices:
                            StripIndices.Resize(count);
                            StripIndices.Read(er);
                            break;

                        case OffsetMoppReorderTable:
                            MoppReorderTable.Resize(count);
                            MoppReorderTable.Read(er);
                            break;

                        case OffsetVertexBuffers:
                            VertexBuffers.Resize(count);
                            VertexBuffers.Read(er);
                            break;
                        }
                        break;

                        #endregion
                        #region TagData
                    case (int)geometry_block_resource_type.TagData:
                        switch (gb.PrimaryLocater.Value)
                        {
                        case OffsetVisibilityMoppCode:
                            VisibilityMoppCode.Reset(er.ReadBytes(gb.Size));
                            break;
                        }
                        break;

                        #endregion
                        #region VertexBuffer
                    case (int)geometry_block_resource_type.VertexBuffer:
                        var vb_defs = (c.TagIndexManager as InternalCacheTagIndex).kVertexBuffers;

                        var stream_readers = new Render.VertexBufferInterface.StreamReader[VertexBuffers.Count];
                        for (x = 0; x < VertexBuffers.Count; x++)
                        {
                            VertexBuffers[x].VertexBuffer.InitializeStreamReader(vb_defs, out stream_readers[x]);
                        }

                        if (RawVertices.Count == 0)
                        {
                            int vertex_count = section_info != null ?
                                               section_info.TotalVertexCount :
                                               gb.Size.Value / VertexBuffers[0].VertexBuffer.StrideSize;

                            RawVertices.Resize(vertex_count);
                        }

                        for (x = 0; x < RawVertices.Count; x++)
                        {
                            RawVertices[x].Reconstruct(section_info, gb,
                                                       er, stream_readers);
                        }
                        break;
                        #endregion
                    }
                }

                index++;
            }

            VertexBuffers.DeleteAll();

            return(true);
        }
示例#6
0
		internal bool Reconstruct(geometry_block_info_struct gbi)
		{
			int index = 0;
			byte[][] data = gbi.GeometryBlock;

			if (data == null) return false;

			foreach (geometry_block_resource_block gb in gbi.Resources)
			{
				using (IO.EndianReader er = new BlamLib.IO.EndianReader(data[index]))
				{
					switch (gb.Type.Value)
					{
						#region TagBlock
						case (int)geometry_block_resource_type.TagBlock:
							int count = gb.GetCount();
							switch (gb.PrimaryLocater.Value)
							{
								case OffsetSoundDialogueInfo:
									SoundDialogueInfo.Resize(count);
									SoundDialogueInfo.Read(er);
									break;
							}
							break;
						#endregion
						#region TagData
						case (int)geometry_block_resource_type.TagData:
							if (gb.PrimaryLocater.Value == OffsetEncodedData)
								EncodedData.Reset(er.ReadBytes(gb.Size));
							break;
						#endregion
					}
				}

				index++;
			}

			return true;
		}
示例#7
0
		internal bool Reconstruct(
			BlamLib.Blam.CacheFile c,
			global_geometry_section_info_struct section,
			geometry_block_info_struct gbi
			)
		{
			int index = 0;
			byte[][] data = gbi.GeometryBlock;

			if (data == null) return false;

			foreach (geometry_block_resource_block gb in gbi.Resources)
			{
				using (IO.EndianReader er = new BlamLib.IO.EndianReader(data[index]))
				{
					switch (gb.Type.Value)
					{
						#region TagBlock
						case (int)geometry_block_resource_type.TagBlock:
							int count = gb.GetCount();
							switch (gb.PrimaryLocater.Value)
							{
								case OffsetRawPoints:
									RawPoints.Resize(count);
									RawPoints.Read(er);
									break;

								case OffsetRigidPointGroups:
									RigidPointGroups.Resize(count);
									RigidPointGroups.Read(er);
									break;

								case OffsetVertexPointIndices:
									VertexPointIndices.Resize(count);
									VertexPointIndices.Read(er);
									break;
							}
							break;
						#endregion
						#region TagData
						case (int)geometry_block_resource_type.TagData:
							switch (gb.PrimaryLocater.Value)
							{
								case OffsetRuntimePointData:
									RuntimePointData.Reset(er.ReadBytes(gb.Size));
									break;
							}
							break;
						#endregion
						#region VertexBuffer
						//case (int)geometry_block_resource_type.VertexBuffer:
						#endregion
					}

					index++;
				}
			}

			return true;
		}
示例#8
0
		/// <summary></summary>
		/// <param name="c"></param>
		/// <param name="section_info">Can be null if tag data doesn't have it</param>
		/// <param name="gbi"></param>
		/// <returns></returns>
		internal bool Reconstruct(Blam.CacheFile c,
			global_geometry_section_info_struct section_info,
			geometry_block_info_struct gbi)
		{
			int index = 0;
			int x;
			byte[][] data = gbi.GeometryBlock;

			if (data == null) return false;

			foreach (geometry_block_resource_block gb in gbi.Resources)
			{
				using (IO.EndianReader er = new BlamLib.IO.EndianReader(data[index]))
				{
					switch (gb.Type.Value)
					{
						#region TagBlock
						case (int)geometry_block_resource_type.TagBlock:
							int count = gb.GetCount();
							switch (gb.PrimaryLocater.Value)
							{
								case OffsetParts:
									Parts.Resize(count);
									Parts.Read(er);
									break;

								case OffsetSubparts:
									Subparts.Resize(count);
									Subparts.Read(er);
									break;

								case OffsetVisibilityBounds:
									VisibilityBounds.Resize(count);
									VisibilityBounds.Read(er);
									break;

								case OffsetStripIndices:
									StripIndices.Resize(count);
									StripIndices.Read(er);
									break;

								case OffsetMoppReorderTable:
									MoppReorderTable.Resize(count);
									MoppReorderTable.Read(er);
									break;

								case OffsetVertexBuffers:
									VertexBuffers.Resize(count);
									VertexBuffers.Read(er);
									break;
							}
							break;
						#endregion
						#region TagData
						case (int)geometry_block_resource_type.TagData:
							switch (gb.PrimaryLocater.Value)
							{
								case OffsetVisibilityMoppCode:
									VisibilityMoppCode.Reset(er.ReadBytes(gb.Size));
									break;
							}
							break;
						#endregion
						#region VertexBuffer
						case (int)geometry_block_resource_type.VertexBuffer:
							var vb_defs = (c.TagIndexManager as InternalCacheTagIndex).kVertexBuffers;

							var stream_readers = new Render.VertexBufferInterface.StreamReader[VertexBuffers.Count];
							for (x = 0; x < VertexBuffers.Count; x++)
								VertexBuffers[x].VertexBuffer.InitializeStreamReader(vb_defs, out stream_readers[x]);

							if (RawVertices.Count == 0)
							{
								int vertex_count = section_info != null ?
									section_info.TotalVertexCount :
									gb.Size.Value / VertexBuffers[0].VertexBuffer.StrideSize;

								RawVertices.Resize(vertex_count);
							}

							for (x = 0; x < RawVertices.Count; x++)
								RawVertices[x].Reconstruct(section_info, gb, 
									er, stream_readers);
							break;
						#endregion
					}
				}

				index++;
			}

			VertexBuffers.DeleteAll();

			return true;
		}
示例#9
0
		/// <summary>
		/// Postprocess tag data that has been streamed to a cache block
		/// </summary>
		/// <param name="locator">Offset of the tag data header in the section</param>
		/// <param name="data"></param>
		/// <returns></returns>
		internal bool ReconstructTagData(short locator, TagInterface.Data data)
		{
			int index = 0;
			IO.EndianReader er;

			if (GeometryBlock == null) return false;

			foreach (geometry_block_resource_block gb in Resources)
			{
				er = new BlamLib.IO.EndianReader(GeometryBlock[index]);

				switch (gb.Type.Value)
				{
					#region TagData
					case (int)geometry_block_resource_type.TagData:
						if(gb.PrimaryLocater.Value == locator)
								data.Reset(er.ReadBytes(gb.Size));
						break;
					#endregion
				}

				index++;
				er.Close();
				er = null;
			}

			return true;
		}