Example #1
0
		public override void Read(BlamLib.IO.EndianReader s)
		{
			int pos = 0;

			Blam.CacheFile.ValidateHeaderAdjustEndian(s, 0x800);
			s.Seek(4);

			Halo1.Version ver = (Halo1.Version)(version = s.ReadInt32());
			fileLength = s.ReadInt32();
			if (fileLength < s.Length) throw new Debug.ExceptionLog("Compressed map editing not available yet!");

			s.ReadInt32();

			if (ver == Halo1.Version.PC_Demo)
			{
				pos = s.Position;
				s.Position = 0x5EC;
				offsetToIndex = s.ReadInt32();
				s.Position = pos;
			}
			else
				offsetToIndex = s.ReadInt32();

			tagBufferSize = s.ReadInt32();

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

			if (ver == Halo1.Version.PC_Demo)
			{
				pos = s.Position;
				s.Position = 0x5E8;
				name = s.ReadTagString();
				s.Position = pos;
			}
			else
				name = s.ReadTagString();

			build = s.ReadTagString();
			cacheType = (CacheType)s.ReadInt16();
			s.ReadInt16();
			s.ReadInt32(); // CRC

			s.ReadInt32();
			s.Seek((484 * sizeof(int)) + sizeof(uint), System.IO.SeekOrigin.Current);

			CacheFile cache = s.Owner as CacheFile;
			if (ver == Halo1.Version.Xbox)										cache.EngineVersion = BlamVersion.Halo1_Xbox;
			else if (ver == Halo1.Version.PC || ver == Halo1.Version.PC_Demo)
			{
				if(s.State == IO.EndianState.Big)								cache.EngineVersion = BlamVersion.Halo1_XboxX;
				else
				{
					// Interestingly, HaloPC is build 01.00.00.0564, HA10 is build 01.00.01.0563
																				// Little
					if(build == "01.00.01.0563")								cache.EngineVersion = BlamVersion.Halo1_PCX;
					else														cache.EngineVersion = BlamVersion.Halo1_PC;
				}
			}
			else if (ver == Halo1.Version.CE)									cache.EngineVersion = BlamVersion.Halo1_CE;
		}
Example #2
0
		public override void Read(BlamLib.IO.EndianReader s)
		{
			Blam.CacheFile.ValidateHeader(s, 0x800);
			
			s.Seek(4);
			version = s.ReadInt32();
			if (version != 5) throw new InvalidCacheFileException(s.FileName);

			fileLength = s.ReadInt32();

			int xbox = s.ReadInt32(); // Xbox only field

			offsetToIndex = s.ReadInt32();
			s.ReadInt32(); // stream size

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

			name = s.ReadTagString();

			build = s.ReadTagString(); // Xbox only field. Always '400'
			cacheType = (CacheType)s.ReadInt16();
			s.ReadInt16();
			s.ReadInt32(); // CRC

			s.Seek((485 * sizeof(int)) + sizeof(uint), System.IO.SeekOrigin.Current);


			CacheFile cf = s.Owner as CacheFile;
			if (xbox != 0)
				cf.EngineVersion = BlamVersion.Stubbs_Xbox;
			else // no way to tell when it's mac, which just seems to use PC maps anyway (byte swaps everything when map is loaded)
				cf.EngineVersion = BlamVersion.Stubbs_PC;
		}
Example #3
0
		public override void Read(BlamLib.IO.EndianReader s)
		{
			Blam.CacheFile.ValidateHeader(s, 0x800);
			
			s.Seek(4);
			s.ReadInt32(); // version, should be 5

			fileLength = s.ReadInt32();

			int xbox = s.ReadInt32(); // Xbox only field

			offsetToIndex = s.ReadInt32();
			s.ReadInt32(); // stream size

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

			name = s.ReadTagString();

			build = s.ReadTagString(); // Xbox only field. Always '400'
			cacheType = (CacheType)s.ReadInt32();
			s.ReadInt32(); // CRC

			s.Seek((485 * sizeof(int)) + sizeof(uint), System.IO.SeekOrigin.Current);


			CacheFile cf = s.Owner as CacheFile;
			if (xbox != 0) cf.EngineVersion = BlamVersion.Stubbs_Xbox;
			else cf.EngineVersion = BlamVersion.Stubbs_PC; // no way to tell when its mac...
		}
Example #4
0
		public static string ReadCString(uint offset, BlamLib.IO.EndianReader io)
		{
			if (offset == 0) return string.Empty;

			uint pos = io.PositionUnsigned;

			io.Seek(offset);

			byte btchar = 0;
			var cstring = new System.Text.StringBuilder();

			do
			{
				btchar = io.ReadByte();
				if (btchar != 0)
					cstring.Append((char)btchar);

			} while (btchar != 0);

			io.Seek(pos);

			return cstring.ToString();
		}
Example #5
0
		public override void Read(BlamLib.IO.EndianReader s)
		{
			CacheFile cache = s.Owner as CacheFile;

			#region read body
			groupTagsCount = s.ReadInt32();
			groupTagsOffset = (groupTagsAddress = s.ReadUInt32()) - cache.AddressMask;

			tagCount = s.ReadInt32();
			tagsOffset = (address = s.ReadUInt32()) - cache.AddressMask;

			dependentTagsCount = s.ReadInt32();
			dependentTagsOffset = (dependentTagsAddress = s.ReadUInt32()) - cache.AddressMask;

			s.Seek(sizeof(int) +
				sizeof(uint) + // seems to always be the same address as the dependent tags
				sizeof(int), // new to Reach. Only seen as zero so far
				System.IO.SeekOrigin.Current);

			s.ReadUInt32(); // crc?
			s.ReadInt32(); // 'tags'
			#endregion

			ReadDependents(s);

			ReadTagInstances(s);

			ReadGroupTags(s);

			#region fixup group tag info
			for (int x = 0; x < tagCount; x++)
			{
				var item = items[x];
				if (!item.IsEmpty)
				{
					item.GroupTag = groupTags[item.Datum.Index].GroupTag1;
					item.GroupTagInt = item.GroupTag.ID;
					item.Fixup((ushort)x); // Fix the hacks Bungie did for Halo3
				}
			}
			#endregion

			#region Load tag names
			using (var buffer = cache.DecryptCacheSegment(CacheSectionType.Tag, cache.HeaderHaloReach.TagNamesBufferOffset, cache.HeaderHaloReach.TagNamesBufferSize))
			{
				string tag_name;
				foreach (var ci in items)
				{
					if (!ci.IsEmpty)
					{
						// NOTE, we're recording a buffer relative offset here...since the 
						// cache has it encrypted I don't see the point of having the 
						// offset relative to the cache file
						ci.TagNameOffset = buffer.PositionUnsigned;
						tag_name = buffer.ReadCString();
						if (tag_name == "") tag_name = "NONE";
					}
					else
					{
						ci.TagNameOffset = uint.MaxValue;
						ci.ReferenceName = DatumIndex.Null;
						continue;
					}

					ci.ReferenceName = cache.References.AddOptimized(ci.GroupTag, tag_name);
				}
			}
			#endregion
		}
Example #6
0
				public void Read(BlamLib.IO.EndianReader s)
				{
					GameMode = s.ReadInt32();
					GameSimulation = (GameSimulation)s.ReadByte();
					GameNetworkType = s.ReadByte();
					GameTickRate = s.ReadInt16();
					GameInstance = s.ReadUInt64();
					Unknown010 = s.ReadInt32();
					Language = s.ReadInt32();
					DeterminismVersion = s.ReadInt32();
					MapId.Read(s);
					CachePath = s.ReadAsciiString(260);
					InitialZoneSetIndex = s.ReadInt16();
					Unknown12A = s.ReadBool();
					DumpMachineIndex = s.ReadByte();
					Unknown12C = s.ReadBool();
					Unknown12D = s.ReadBool();
					Unknown12E = s.ReadBool();
					s.Seek(1, System.IO.SeekOrigin.Current);
					GamePlayback = (GamePlayback)s.ReadInt16();
					Unknown132 = s.ReadBool();
					s.Seek(1, System.IO.SeekOrigin.Current);
					Unknown134 = s.ReadInt32();
					Unknown138 = s.ReadInt32();
					CampaignDifficulty = s.ReadInt16();
					CampaignInsertionPoint = s.ReadInt16();
					CampaignMetagameScoring = s.ReadInt16();
					Unknown142 = s.ReadBool();
					Unknown143 = s.ReadBool();
					PrimarySkulls = s.ReadInt32();
					SecondarySkulls = s.ReadInt32();
					for (int x = 0; x < Unknown14C.Length; x++) Unknown14C[x] = s.ReadBytes(30);
					Unknown1C4 = s.ReadBool();
					s.Seek(3 + 4, System.IO.SeekOrigin.Current);
					Unknown1CC = s.ReadBytes(92);
					EngineVariant.Read(s);
					s.Seek(4, System.IO.SeekOrigin.Current);
					MapVariant.Read(s);
					Game.Read(s);
				}
Example #7
0
		protected void ReadTagInstances(BlamLib.IO.EndianReader s)
		{
			items = new Cache.CacheItemGen3[tagCount];
			s.Seek(tagsOffset, System.IO.SeekOrigin.Begin);
			for (int x = 0; x < tagCount; x++)
				(items[x] = new Cache.CacheItemGen3()).Read(s);
		}
Example #8
0
		public override void Read(BlamLib.IO.EndianReader s)
		{
			if (isLoaded) return;

			// goto the start if we're leaching off another cache's IO
			if (IsSharedReference)
				s.Seek(0);

			cacheHeader.Read(s);

			DetermineEngineVersion();

			// Shared caches can't be loaded from here
			if (cacheHeader.SharedType == Cache.SharedType.Shared || 
				cacheHeader.SharedType == Cache.SharedType.Campaign) 
				throw new SharedCacheAccessException();

			TagIndexInitializeAndRead(s);

			isLoaded = true;
		}
Example #9
0
		public override void Read(BlamLib.IO.EndianReader s)
		{
			DataCacheFile cache = s.Owner as DataCacheFile;

			type = (DataCacheType)s.ReadInt32();
			tagNamesTableOffset = s.ReadInt32();
			tagInstancesTableOffset = s.ReadInt32();
			tagCount = s.ReadInt32();
			items = new DataItem[tagCount];

			TagInterface.TagGroup tgroup = null;
			switch(type)
			{
				case DataCacheType.Bitmap: tgroup = TagGroups.bitm; break;
				case DataCacheType.Sound: tgroup = TagGroups.snd_; break;
				case DataCacheType.Loc:
					break;
			}

			s.Seek(TagNamesTableOffset, System.IO.SeekOrigin.Begin);
			DataItem item = null;
			for (int x = 0; x < TagCount; x++)
			{
				item = new DataItem();
				items[x] = item;
				item.GroupTag = tgroup;
				item.ReferenceName = cache.References.AddOptimized(item.GroupTag, s.ReadCString());
			}

			s.Seek(tagInstancesTableOffset, System.IO.SeekOrigin.Begin);
			for (int x = 0; x < TagCount; x++)
				items[x].Read(s);
		}
Example #10
0
		public override void Read(BlamLib.IO.EndianReader s)
		{
			CacheFileBase cache = s.Owner as CacheFileBase;

			#region read body
			groupTagsCount = s.ReadInt32();
			groupTagsOffset = (groupTagsAddress = s.ReadUInt32()) - cache.AddressMask;

			tagCount = s.ReadInt32();
			tagsOffset = (address = s.ReadUInt32()) - cache.AddressMask;

			dependentTagsCount = s.ReadInt32();
			dependentTagsOffset = (dependentTagsAddress = s.ReadUInt32()) - cache.AddressMask;

			s.ReadInt32();
			s.ReadUInt32(); // seems to be the same address as the dependent tags

			s.ReadUInt32(); // crc?
			s.ReadInt32(); // 'tags'
			#endregion

			ReadDependents(s);

			ReadTagInstances(s);

			ReadGroupTags(s);

			#region fixup group tag info
			for (int x = 0; x < tagCount; x++)
			{
				var item = items[x];
				if (!item.IsEmpty)
				{
					item.GroupTag = groupTags[item.Datum.Index].GroupTag1;
					item.GroupTagInt = item.GroupTag.ID;
					item.Fixup((ushort)x); // Fix the hacks Bungie did for Halo3
				}
			}
			#endregion

			#region Load tag names
			s.Seek(cache.HeaderHalo3.TagNamesBufferOffset);
			string file_name;
			foreach (var ci in items)
			{
				if (!ci.IsEmpty)
				{
					ci.TagNameOffset = s.PositionUnsigned;
					file_name = s.ReadCString();
					if (file_name == "") file_name = "NONE";
				}
				else
				{
					ci.TagNameOffset = uint.MaxValue;
					ci.ReferenceName = DatumIndex.Null;
					continue;
				}

				ci.ReferenceName = cache.References.AddOptimized(ci.GroupTag, file_name);
			}
			#endregion
		}
Example #11
0
		void ReadBeta(BlamLib.IO.EndianReader s)
		{
			s.ReadUInt32();

			//s.ReadBool();
			//s.ReadBool(); // false if it belongs to a untracked build
			//s.ReadBool();
			//s.ReadBool();
			// Just read the booleans as a f*****g int...
			s.ReadInt32();

			// Filetime.dwHighDateTime = s.ReadInt32();
			// Filetime.dwLowDateTime = s.ReadInt32();
			s.ReadInt32(); s.ReadInt32();

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

			#region string id
			// retail doesn't include the 128 byte per string id table, so nix the members
			/*stringIdsBufferAlignedOffset = */s.ReadInt32();
			stringIdsCount = s.ReadInt32();

			stringIdsBufferSize = s.ReadInt32();
			stringIdIndicesOffset = s.ReadInt32();
			stringIdsBufferOffset = s.ReadInt32();
			#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...
			s.ReadInt32();
			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);
			needsShared = s.ReadInt32() == 1;

			#region tag names
			tagNamesCount = s.ReadInt32();
			tagNamesBufferOffset = s.ReadInt32();
			tagNamesBufferSize = s.ReadInt32();
			tagNameIndicesOffset = s.ReadInt32();
			#endregion

			checksum = s.ReadUInt32(); // 0x2CC
			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
			memoryPartitions = new Partition[3];
			memoryPartitions[0].BaseAddress = s.ReadUInt32(); // address
			memoryPartitions[0].Size = s.ReadInt32(); // size
			memoryPartitions[1].BaseAddress = s.ReadUInt32(); // address
			memoryPartitions[1].Size = s.ReadInt32(); // size
			memoryPartitions[2].BaseAddress = s.ReadUInt32(); // address
			memoryPartitions[2].Size = s.ReadInt32(); // size
			#endregion

			s.Seek(256, System.IO.SeekOrigin.Current);

			s.Seek(1004 + sizeof(uint), System.IO.SeekOrigin.Current);


			Managers.BlamDefinition bdef = Program.GetManager(BlamVersion.Halo3_Beta);

			uint base_address = (s.Owner as Blam.CacheFile).AddressMask = bdef[BlamVersion.Halo3_Beta].CacheTypes.BaseAddress - (uint)MemoryBufferOffset;

			offsetToIndex = (int)(tagIndexAddress - base_address);
			CalculatePartitionOffsets();
		}
Example #12
0
		public void Read(BlamLib.IO.EndianReader s)
		{
			s.Seek(4 + 4, System.IO.SeekOrigin.Current);
			Count.Read(s);
			Size.Read(s);
			OffsetReferences.Read(s);
			OffsetStrings.Read(s);
			s.Seek(1 + 3, System.IO.SeekOrigin.Current);
		}
Example #13
0
		public override void Read(BlamLib.IO.EndianReader s)
		{
			bool is_alpha;
			bool is_pc = false;
			Blam.CacheFile.ValidateHeader(s, 0x800);

			#region figure out if this is a alpha map
			s.Seek(0x120);
			is_alpha = s.ReadTagString() == "02.06.28.07902";
			#endregion
			#region figure out if this is a pc map
			if (!is_alpha)
			{
				s.Seek(0x24);
				int test = s.ReadInt32();
				if (test == -1 || (test != 0 && test < s.Length)) is_pc = true;
			}
			#endregion
			s.Seek(4);

			version = s.ReadInt32();
			fileLength = s.ReadInt32();
			s.ReadInt32();
			offsetToIndex = s.ReadInt32();
			indexStreamSize = s.ReadInt32();

			tagBufferSize = s.ReadInt32(); // size of the tag data, excluding the bsp data
			s.ReadInt32(); // max size: 0x3200000, indexStreamSize+tagBufferSize

			if(is_pc)
			{
				PcFields.VirtualAddress = s.ReadUInt32(); // virtual base address

				PcFields.TagDependencyGraphOffset = s.ReadInt32(); // buffer offset (starts right before tag index, 512 byte aligned). not shared? should equal -1
				PcFields.TagDependencyGraphSize = s.ReadUInt32(); // buffer size. not shared? should be zero. Max: 0x100000
			}

			sourceFile = s.ReadAsciiString(256);
			build = s.ReadTagString();
			cacheType = (Blam.CacheType)s.ReadInt32();
				// SP Filesize Max: 0x11800000
				// MP Filesize Max: 0x5000000
				// Mainmenu Filesize Max: 0x20800000
				// Shared Filesize Max: 0xB400000
				// Single Player Shared Filesize Max: 0x20800000
			s.ReadInt32(); // cache resource (tag) crc
			s.ReadInt32(); // boolean, set to true in pc when building cache

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

			s.ReadInt32(); // count of some sort? only on the xbox

			// offset, then size
			// (size+0xFFF) & 0xFFFFF000
			// test that with 0x1FF, if true, or with 0x1FF then add 1
			s.ReadInt32(); // begins with 0x200 bytes of a chunk of the tag filenames table and ends with the same
			s.ReadInt32(); // has something to do with bitmaps. the bigger the file, the bigger this is

			#region string id
			// each string this buffer is aligned to 128 characters (the max length + 1 of a string_id)
			/*stringIdsBufferAlignedOffset = */s.ReadInt32();
			stringIdsCount = s.ReadInt32();

			stringIdsBufferSize = s.ReadInt32();
			stringIdIndicesOffset = s.ReadInt32();
			stringIdsBufferOffset = s.ReadInt32();
			#endregion

			s.ReadInt32(); // 4 bools

			Filetime.dwHighDateTime = s.ReadInt32();
			Filetime.dwLowDateTime = s.ReadInt32();

			/*MainmenuFiletime.dwHighDateTime*/				SharedFiletimes[0].dwHighDateTime = s.ReadInt32();
			/*MainmenuFiletime.dwLowDateTime = */			SharedFiletimes[0].dwLowDateTime = s.ReadInt32();

			/*SharedFiletime.dwHighDateTime*/				SharedFiletimes[1].dwHighDateTime = s.ReadInt32();
			/*SharedFiletime.dwLowDateTime*/				SharedFiletimes[1].dwLowDateTime = s.ReadInt32();

			/*SharedSingleplayerFiletime.dwHighDateTime*/	SharedFiletimes[2].dwHighDateTime = s.ReadInt32();
			/*SharedSingleplayerFiletime.dwLowDateTime*/	SharedFiletimes[2].dwLowDateTime = s.ReadInt32();

			name = s.ReadTagString();
			s.ReadInt32(); // dword, but unused
			scenarioPath = s.ReadAsciiString(256);

			// minor version
			needsShared = s.ReadInt32() == 1; // doesn't exist on the pc

			#region tag names
			tagNamesCount = s.ReadInt32(); // not used in alpha
			tagNamesBufferOffset = s.ReadInt32(); // not used in alpha
			tagNamesBufferSize = s.ReadInt32(); // not used in alpha
			tagNameIndicesOffset = s.ReadInt32(); // not used in alpha
			#endregion

			if (is_pc)
			{
				// s_cache_language_pack
				PcFields.LanguagePacksOffset = s.ReadInt32(); // offset, shared database = -1
				// sizeof(s_cache_language_pack) * LanguageType.kMax
				PcFields.LanguagePacksSizeOf = s.ReadUInt32(); // sizeof, shared database = 0

				// secondary sound gestalt
				PcFields.SecondarySoundGestalt.Read(s); // shared database = -1

				// fast geometry load region
				PcFields.FastLoadGeometryBlockOffset = s.ReadInt32(); // offset to a cache block resource
				PcFields.FastLoadGeometryBlockSize = s.ReadUInt32(); // sizeof entire cache block resources partition. max size: 0x4000000

				checksum = s.ReadUInt32();

				// another xor checksum
				// sbsp
				//	- data 0x28C: global_structure_physics_struct->MoppCode
				//	- data 0x2BC: global_structure_physics_struct->BreakableSurfacesMoppCode
				//	- block 0xD4: structure_bsp_cluster_block
				//		* data 0xC4: "Collision mopp Code"
				//		* block 0x54: structure_bsp_cluster_data_block_new
				//			- data 0x3C: global_geometry_section_struct->"Visibility mopp Code"
				// phmo
				//	- data 0xE8: "mopp codes"
				// coll
				//	- block 0x28: collision_model_region_block
				//		* block 0x04: collision_model_permutation_block
				//			- block 0x10: collision_bsp_physics_block
				//				* data 0x64: "mopp Code Data"
				// mode
				//	- block 0x30: render_model_section_block
				//		* block 0x34: render_model_section_data_block
				//			- data 0x3C: global_geometry_section_struct->"Visibility mopp Code"
				// ltmp
				//	- block 0x80: structure_lightmap_group_block
				//		* block 0x30: lightmap_geometry_section_block
				//			- block 0x54: lightmap_geometry_section_cache_data_block
				//				* data 0x3C: global_geometry_section_struct->"Visibility mopp Code"
				//		* block 0x48: lightmap_geometry_section_block
				//			- block 0x54: lightmap_geometry_section_cache_data_block
				//				* data 0x3C: global_geometry_section_struct->"Visibility mopp Code"
				PcFields.MoppCodesChecksum = s.ReadUInt32(); // shared databases = 0

				s.Seek(1284 + sizeof(uint), System.IO.SeekOrigin.Current);
			}
			else
			{

				checksum = s.ReadUInt32();

				s.Seek(1320 + sizeof(uint), System.IO.SeekOrigin.Current);
			}

			CacheFile cf = s.Owner as CacheFile;
			if (is_pc) cf.EngineVersion = BlamVersion.Halo2_PC;
			else if (build == "02.08.28.09214") cf.EngineVersion = BlamVersion.Halo2_Epsilon;
			else if (is_alpha) cf.EngineVersion = BlamVersion.Halo2_Alpha;
			else cf.EngineVersion = BlamVersion.Halo2_Xbox;
		}
Example #14
0
				//PAD16

				#region IStreamable Members
				public virtual void Read(BlamLib.IO.EndianReader s)
				{
					MiscOptions.Read(s);
					RespawnOptions.Read(s);
					SocialFlags = s.ReadUInt16();
					SocialTeamChanging = s.ReadInt16();
					MapOverrides.Read(s);
					Unknown0A8 = s.ReadUInt16();
					TeamScoringMethod = s.ReadInt16();
					Unknown0AC = s.ReadUInt16();
					s.Seek(2, System.IO.SeekOrigin.Current);
				}
Example #15
0
				public override void Read(BlamLib.IO.EndianReader s)
				{
					base.Read(s);

					ScoreToWin = s.ReadInt16();
					Flags = s.ReadUInt16();
					KillPoints = s.ReadByte();
					TakedownPoints = s.ReadByte();
					KillAsVipPoints = s.ReadByte();
					VipDeathPoints = s.ReadByte();
					DestinationArrivalPoints = s.ReadByte();
					SuicidePoints = s.ReadByte();
					BetrayalPoints = s.ReadByte();
					VipSuicidePoints = s.ReadByte();
					VipSelection = s.ReadByte();
					ZoneMovement = s.ReadByte();
					ZoneOrder = s.ReadByte();
					s.Seek(1, System.IO.SeekOrigin.Current);
					InfluenceRadius = s.ReadInt16();
					VipTraits.Read(s);
					ProximityTraits.Read(s);
					VipTeamTraits.Read(s);
				}
Example #16
0
					public void Read(BlamLib.IO.EndianReader s)
					{
						MovementSpeed = s.ReadByte();
						Gravity = s.ReadByte();
						VehicleUsage = s.ReadByte();
						s.Seek(1, System.IO.SeekOrigin.Current);
					}
Example #17
0
					public void Read(BlamLib.IO.EndianReader s)
					{
						DamageResistance = s.ReadByte();
						ShieldRechargeRate = s.ReadByte();
						Vampirism = s.ReadByte();
						HeadshotImmunity = s.ReadByte();
						ShieldMultiplier = s.ReadByte();
						s.Seek(3, System.IO.SeekOrigin.Current);
					}
Example #18
0
			public override void Read(BlamLib.IO.EndianReader s)
			{
				base.Read(s);

				MapId = s.ReadInt32();
				ScenarioType = s.ReadInt32();
				Names.Read(s);
				Descriptions.Read(s);
				BlfName = s.ReadAsciiString(256);
				FileName = s.ReadAsciiString(256);
				MapIndex = s.ReadInt32();
				Unknown1118 = s.ReadInt32();
				Unknown111C = s.ReadByte();
				Unknown111D = s.ReadByte();
				MaxTeams = s.ReadBytes(11);
				Unknown1129 = s.ReadByte();
				s.Seek(2, System.IO.SeekOrigin.Current);
				Unknown112C = s.ReadUInt32();
				foreach (CheckpointData cp in Checkpoints) cp.Read(s);
			}
Example #19
0
		void ReadGroupTags(BlamLib.IO.EndianReader s)
		{
			groupTags = new CacheItemGroupTag[groupTagsCount];
			s.Seek(groupTagsOffset, System.IO.SeekOrigin.Begin);
			for (int x = 0; x < groupTagsCount; x++)
				(groupTags[x] = new CacheItemGroupTag()).Read(s);
		}
Example #20
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
		}
Example #21
0
		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);
		}
Example #22
0
		public override void Read(BlamLib.IO.EndianReader s)
		{
			if (isLoaded) return;

			// goto the start if we're leaching off another cache's IO
			if (IsSharedReference)
				s.Seek(0);

			cacheHeader.Read(s);

			TagIndexInitializeAndRead(s);

			isLoaded = true;
		}
Example #23
0
		void ReadGroupTags(BlamLib.IO.EndianReader s)
		{
			groupTags = CreateEngineItemGroupTags(groupTagsCount);
			s.Seek(groupTagsOffset, System.IO.SeekOrigin.Begin);
			for (int x = 0; x < groupTagsCount; x++)
				(groupTags[x] = CreateEngineItemGroupTag()).Read(s);
		}
Example #24
0
			public Base VariantOptions; // 0x160

			#region IStreamable Members
			public void Read(BlamLib.IO.EndianReader s)
			{
				GameEngineIndex = (GameEngineType)s.ReadInt32();
				_vtable = s.ReadUInt32();
				Unknown008 = s.ReadInt32();
				Header.Read(s);

				switch(GameEngineIndex)
				{
					case GameEngineType.Ctf:			VariantOptions = new Ctf();			break;
					case GameEngineType.Slayer:			VariantOptions = new Slayer();		break;
					case GameEngineType.Oddball:		VariantOptions = new Oddball();		break;
					case GameEngineType.King:			VariantOptions = new King();		break;
					case GameEngineType.Sandbox:		VariantOptions = new Sandbox();		break;
					case GameEngineType.Vip:			VariantOptions = new Vip();			break;
					case GameEngineType.Juggernaut:		VariantOptions = new Juggernaut();	break;
					case GameEngineType.Territories:	VariantOptions = new Teritories();	break;
					case GameEngineType.Assault:		VariantOptions = new Assault();		break;
					case GameEngineType.Infection:		VariantOptions = new Infection();	break;
					default:							throw new Debug.Exceptions.UnreachableException();
				}

				VariantOptions.Read(s);

				s.Seek(0x160 - VariantOptions.Sizeof, System.IO.SeekOrigin.Current);
			}
Example #25
0
		protected void TagIndexInitializeAndRead(BlamLib.IO.EndianReader s)
		{
			base.StringIdManagerInitializeAndRead();
			base.InitializeReferenceManager(s.FileName);
			base.InitializeTagIndexManager();

			s.Seek(cacheHeader.OffsetToIndex, System.IO.SeekOrigin.Begin);
			cacheIndex.Read(s);
		}
Example #26
0
				public void Read(BlamLib.IO.EndianReader s)
				{
					Valid = s.ReadBool();
					PrimaryColor = s.ReadByte();
					SecondaryColor = s.ReadByte();
					TertiaryColor = s.ReadByte();
					PlayerModelChoice = s.ReadByte();
					ForegroundEmblem = s.ReadByte();
					BackgroundEmblem = s.ReadByte();
					EmblemFlags = s.ReadByte();
					EmblemPrimaryColor = s.ReadByte();
					EmblemSecondaryColor = s.ReadByte();
					EmblemBackgroundColor = s.ReadByte();
					ModelChoices[0] = s.ReadBytes(4);
					ModelChoices[1] = s.ReadBytes(4);
					ServiceTag = s.ReadUnicodeString(4);
					s.Seek(sizeof(ushort), System.IO.SeekOrigin.Current); // alignment
				}
Example #27
0
		public override void Read(BlamLib.IO.EndianReader s)
		{
			if (!isMemoryMap)	Header.Read(s);

			if (!isMemoryMap)	s.Seek(Header.OffsetToIndex, System.IO.SeekOrigin.Begin);
			else				s.Seek(Program.GetManager(engineVersion)[engineVersion].CacheTypes.BaseAddress, System.IO.SeekOrigin.Begin);

			base.InitializeReferenceManager(s.FileName);
			base.InitializeTagIndexManager();

			cacheIndex.Read(s);
		}
Example #28
0
		protected void ReadDependents(BlamLib.IO.EndianReader s)
		{
			DependentDatums = new DatumIndex[dependentTagsCount];
			s.Seek(dependentTagsOffset, System.IO.SeekOrigin.Begin);
			for (int x = 0; x < dependentTagsCount; x++)
			{
				s.Seek(sizeof(uint), System.IO.SeekOrigin.Current); // group tag
				DependentDatums[x].Read(s);
			}
		}
Example #29
0
			public override void Read(BlamLib.IO.EndianReader s)
			{
				base.Read(s);

				EndianId = s.ReadUInt16();
				TypeString = s.ReadTagString();
				s.Seek(2, System.IO.SeekOrigin.Current);
			}
Example #30
0
				public void Read(BlamLib.IO.EndianReader s)
				{
					Valid = s.ReadBool();
					LeftGame = s.ReadBool();
					UserIndex = s.ReadInt16();
					ControllerIndex = s.ReadInt16();
					s.Seek(2, System.IO.SeekOrigin.Current);
					MachineId = s.ReadBytes(6);
					Unknown000E = s.ReadUInt64();
					s.Seek(2, System.IO.SeekOrigin.Current);
					Data.Read(s);
					MatchData.Read(s);
				}