//H2X, H3B, H3R, ODST, HRB, HRR, H4R public static bitmap bitm(CacheBase Cache, CacheBase.IndexItem Tag) { switch (Cache.Version) { case DefinitionSet.Halo1PC: return(new Halo1PC.bitmap(Cache, Tag.Offset)); case DefinitionSet.Halo1CE: return(new Halo1CE.bitmap(Cache, Tag.Offset)); case DefinitionSet.Halo2Xbox: return(new Halo2Xbox.bitmap(Cache, Tag.Offset)); case DefinitionSet.Halo3Beta: case DefinitionSet.Halo3Retail: case DefinitionSet.Halo3ODST: return(new Halo3Beta.bitmap(Cache, Tag.Offset)); case DefinitionSet.HaloReachBeta: return(new ReachBeta.bitmap(Cache, Tag.Offset)); case DefinitionSet.HaloReachRetail: case DefinitionSet.Halo4Beta: case DefinitionSet.Halo4Retail: return(new ReachRetail.bitmap(Cache, Tag.Offset)); default: throw new NotSupportedException(errorMessage.Replace("----", "bitm")); } }
//H2X, H3B, H3R, ODST, HRB, HRR, H4R public static scenario_structure_bsp sbsp(CacheBase Cache, CacheBase.IndexItem Tag) { switch (Cache.Version) { case DefinitionSet.Halo1PC: case DefinitionSet.Halo1CE: return(new Halo1PC.scenario_structure_bsp(Cache, Tag)); case DefinitionSet.Halo2Xbox: return(new Halo2Xbox.scenario_structure_bsp(Cache, Tag)); case DefinitionSet.Halo3Beta: return(new Halo3Beta.scenario_structure_bsp(Cache, Tag.Offset)); case DefinitionSet.Halo3Retail: return(new Halo3Retail.scenario_structure_bsp(Cache, Tag.Offset)); case DefinitionSet.Halo3ODST: return(new Halo3ODST.scenario_structure_bsp(Cache, Tag.Offset)); case DefinitionSet.HaloReachBeta: return(new ReachBeta.scenario_structure_bsp(Cache, Tag.Offset)); case DefinitionSet.HaloReachRetail: return(new ReachRetail.scenario_structure_bsp(Cache, Tag.Offset)); case DefinitionSet.Halo4Retail: return(new Halo4Retail.scenario_structure_bsp(Cache, Tag.Offset)); default: throw new NotSupportedException(errorMessage.Replace("----", "sbsp")); } }
//H2X, H3B, H3R, ODST, HRB, HRR, H4R public static shader rmsh(CacheBase Cache, CacheBase.IndexItem Tag) { switch (Cache.Version) { case DefinitionSet.Halo1PC: case DefinitionSet.Halo1CE: return(new Halo1PC.shader_model(Cache, Tag)); case DefinitionSet.Halo2Xbox: return(new Halo2Xbox.shader(Cache, Tag.Offset)); case DefinitionSet.Halo3Beta: case DefinitionSet.Halo3Retail: case DefinitionSet.Halo3ODST: return(new Halo3Beta.shader(Cache, Tag.Offset)); case DefinitionSet.HaloReachBeta: case DefinitionSet.HaloReachRetail: return(new ReachBeta.shader(Cache, Tag.Offset)); case DefinitionSet.Halo4Beta: return(new Halo4Beta.material(Cache, Tag.Offset)); case DefinitionSet.Halo4Retail: return(new Halo4Retail.material(Cache, Tag.Offset)); default: throw new NotSupportedException(errorMessage.Replace("----", "mode")); } }
public CacheHeader(CacheBase Cache) { cache = Cache; EndianReader Reader = cache.Reader; Reader.SeekTo(8); fileSize = Reader.ReadInt32(); Reader.ReadInt32(); indexOffset = Reader.ReadInt32(); }
//---, ---, ---, ----, ---, ---, H4R public static bink bink(CacheBase Cache, CacheBase.IndexItem Tag) { switch (Cache.Version) { case DefinitionSet.Halo4Retail: return(new Halo4Retail.bink(Cache, Tag.Offset)); default: throw new NotSupportedException(errorMessage.Replace("----", "bink")); } }
//---, H3B, H3R, ODST, HRB, HRR, --- public static render_method_template rmt2(CacheBase Cache, CacheBase.IndexItem Tag) { switch (Cache.Version) { case DefinitionSet.Halo3Beta: case DefinitionSet.Halo3Retail: case DefinitionSet.Halo3ODST: case DefinitionSet.HaloReachBeta: case DefinitionSet.HaloReachRetail: return(new Halo3Beta.render_method_template(Cache, Tag.Offset)); default: throw new NotSupportedException(errorMessage.Replace("----", "rmt2")); } }
//---, ---, H3R, ODST, HRB, HRR, H4R public static cache_file_resource_layout_table play(CacheBase Cache, CacheBase.IndexItem Tag) { switch (Cache.Version) { case DefinitionSet.Halo3Retail: case DefinitionSet.Halo3ODST: case DefinitionSet.HaloReachBeta: case DefinitionSet.HaloReachRetail: return(new Halo3Retail.cache_file_resource_layout_table(Cache, Tag.Offset)); case DefinitionSet.Halo4Beta: case DefinitionSet.Halo4Retail: return(new Halo4Beta.cache_file_resource_layout_table(Cache, Tag.Offset)); default: return(null); //this tag is required for map loading, so return null if not supported } }
//---, H3B, H3R, ODST, HRB, HRR, H4R public static multilingual_unicode_string_list unic(CacheBase Cache, CacheBase.IndexItem Tag) { switch (Cache.Version) { case DefinitionSet.Halo3Beta: case DefinitionSet.Halo3Retail: case DefinitionSet.Halo3ODST: return(new Halo3Beta.multilingual_unicode_string_list(Cache, Tag.Offset)); case DefinitionSet.HaloReachBeta: case DefinitionSet.HaloReachRetail: case DefinitionSet.Halo4Beta: case DefinitionSet.Halo4Retail: return(new ReachBeta.multilingual_unicode_string_list(Cache, Tag.Offset)); default: throw new NotSupportedException(errorMessage.Replace("----", "unic")); } }
//---, ---, H3R, ODST, HRB, HRR, H4R public static sound snd_(CacheBase Cache, CacheBase.IndexItem Tag) { switch (Cache.Version) { case DefinitionSet.Halo3Retail: case DefinitionSet.Halo3ODST: return(new Halo3Retail.sound(Cache, Tag.Offset)); case DefinitionSet.HaloReachBeta: case DefinitionSet.HaloReachRetail: return(new ReachBeta.sound(Cache, Tag.Offset)); case DefinitionSet.Halo4Retail: return(new Halo4Retail.sound(Cache, Tag.Offset)); default: throw new NotSupportedException(errorMessage.Replace("----", "snd!")); } }
//---, ---, H3R, ODST, HRB, HRR, --- public static sound_cache_file_gestalt ugh_(CacheBase Cache, CacheBase.IndexItem Tag) { switch (Cache.Version) { case DefinitionSet.Halo3Retail: return(new Halo3Retail.sound_cache_file_gestalt(Cache, Tag.Offset)); case DefinitionSet.Halo3ODST: return(new Halo3ODST.sound_cache_file_gestalt(Cache, Tag.Offset)); case DefinitionSet.HaloReachBeta: return(new ReachBeta.sound_cache_file_gestalt(Cache, Tag.Offset)); case DefinitionSet.HaloReachRetail: return(new ReachRetail.sound_cache_file_gestalt(Cache, Tag.Offset)); default: return(null); //this tag is required for map loading, so return null if not supported } }
public CacheIndexHeader(CacheBase Cache) { cache = Cache; var Reader = cache.Reader; var CH = cache.Header; Reader.SeekTo(CH.indexOffset); var c = Reader.ReadInt32(); cache.Magic = CH.Magic = c - (CH.indexOffset + 40); Reader.Skip(8); tagCount = Reader.ReadInt32(); vertDataCount = Reader.ReadInt32(); vertDataOffset = Reader.ReadInt32(); indexDataCount = Reader.ReadInt32(); indexDataOffset = Reader.ReadInt32(); tagInfoOffset = CH.indexOffset + 40; CH.fileTableOffset = tagInfoOffset + tagCount * 32; }
public static CacheBase GetCache(string Filename) { CacheBase retCache = null; using (var fs = new FileStream(Filename, FileMode.Open, FileAccess.Read)) { var Reader = new EndianReader((Stream)fs, EndianFormat.BigEndian); var head = Reader.ReadInt32(); if (head == 1684104552) { Reader.EndianType = EndianFormat.LittleEndian; } var v = Reader.ReadInt32(); switch (v) { case 5: //H1X case 7: //HPC case 609: //HCE Reader.SeekTo(64); break; case 8: //H2? Reader.SeekTo(36); switch (Reader.ReadInt32()) { case 0: //H2X Reader.SeekTo(288); break; case -1: //H2V Reader.SeekTo(300); break; } break; default: //360 Reader.SeekTo(284); break; } var build = Reader.ReadString(32); var node = CacheBase.GetBuildNode(build); switch (node.Attributes["definitions"].Value) { case "Halo1PC": retCache = new Halo1PC.CacheFile(Filename, build); break; case "Halo1CE": retCache = new Halo1CE.CacheFile(Filename, build); break; case "Halo1AE": retCache = new Halo1AE.CacheFile(Filename, build); break; case "Halo2Xbox": retCache = new Halo2Xbox.CacheFile(Filename, build); break; case "Halo2Vista": retCache = new Halo2Vista.CacheFile(Filename, build); break; case "Halo3Beta": retCache = new Halo3Beta.CacheFile(Filename, build); break; case "Halo3Retail": retCache = new Halo3Retail.CacheFile(Filename, build); break; case "Halo3ODST": retCache = new Halo3ODST.CacheFile(Filename, build); break; case "ReachBeta": retCache = new ReachBeta.CacheFile(Filename, build); break; case "ReachRetail": retCache = new ReachRetail.CacheFile(Filename, build); break; case "Halo4Beta": retCache = new Halo4Beta.CacheFile(Filename, build); break; case "Halo4Retail": retCache = new Halo4Retail.CacheFile(Filename, build); break; } } if (retCache != null) { retCache.LoadPlayZone(); return(retCache); } else { throw new NotSupportedException("Cache version is unknown, unsupported or invalid."); } }
public LocaleTable(CacheBase Cache, Language Lang) { cache = Cache; EndianReader Reader = cache.Reader; CacheHeader CH = cache.Header; #region Get Info int matgOffset = -1; foreach (IndexItem item in cache.IndexItems) { if (item.ClassCode == "matg") { matgOffset = item.Offset; break; } } if (matgOffset == -1) { return; } int localeStart = int.Parse(cache.buildNode.Attributes["localesStart"].Value); Reader.SeekTo(matgOffset + localeStart + (int)Lang * int.Parse(cache.buildNode.Attributes["languageSize"].Value)); int localeCount = Reader.ReadInt32(); int tableSize = Reader.ReadInt32(); int indexOffset = Reader.ReadInt32() + CH.localeModifier; int tableOffset = Reader.ReadInt32() + CH.localeModifier; #endregion #region Read Indices Reader.SeekTo(indexOffset); int[] indices = new int[localeCount]; for (int i = 0; i < localeCount; i++) { this.Add(""); Reader.ReadInt32(); indices[i] = Reader.ReadInt32(); } #endregion #region Read Names Reader.SeekTo(tableOffset); EndianReader newReader = (cache.localesKey == "" || cache.localesKey == null) ? new EndianReader(new MemoryStream(Reader.ReadBytes(tableSize)), EndianFormat.BigEndian) : AES.DecryptSegment(Reader, tableOffset, tableSize, cache.localesKey); for (int i = 0; i < indices.Length; i++) { if (indices[i] == -1) { this[i] = "<null>"; continue; } newReader.SeekTo(indices[i]); int length; if (i == indices.Length - 1) { length = tableSize - indices[i]; } else { length = (indices[i + 1] != -1) ? indices[i + 1] - indices[i] : indices[i + 2] - indices[i]; } if (length == 1) { this[i] = "<blank>"; continue; } this[i] = newReader.ReadString(length); } newReader.Close(); newReader.Dispose(); #endregion }
public StringTable(CacheBase Cache) { if (Cache.Version <= DefinitionSet.Halo1AE) { return; } cache = Cache; var Reader = cache.Reader; var CH = cache.Header; #region Read Indices Reader.SeekTo(CH.stringTableIndexOffset); int[] indices = new int[CH.stringCount]; for (int i = 0; i < CH.stringCount; i++) { indices[i] = Reader.ReadInt32(); this.Add(""); } #endregion #region Read Names Reader.SeekTo(CH.stringTableOffset); EndianReader newReader = (cache.stringsKey == "" || cache.stringsKey == null) ? new EndianReader(new MemoryStream(Reader.ReadBytes(CH.stringTableSize)), EndianFormat.BigEndian) : AES.DecryptSegment(Reader, CH.stringTableOffset, CH.stringTableSize, cache.stringsKey); for (int i = 0; i < indices.Length; i++) { if (indices[i] == -1) { this[i] = "<null>"; continue; } newReader.SeekTo(indices[i]); int length; if (i == indices.Length - 1) { length = CH.stringTableSize - indices[i]; } else { length = (indices[i + 1] != -1) ? indices[i + 1] - indices[i] : indices[i + 2] - indices[i]; } if (length == 1) { this[i] = "<blank>"; continue; } this[i] = newReader.ReadString(length); } newReader.Close(); newReader.Dispose(); #endregion }
public IndexTable(CacheBase Cache) { cache = Cache; var IH = cache.IndexHeader; var CH = cache.Header; var Reader = cache.Reader; #region Read Tags' Info ClassList = new List <TagClass>(); var classDic = new Dictionary <string, int>(); int[] sbspOffset = new int[0]; int[] sbspMagic = new int[0]; int[] sbspID = new int[0]; int[] indices = new int[IH.tagCount]; Reader.SeekTo(IH.tagInfoOffset); for (int i = 0; i < IH.tagCount; i++) { var cname = Reader.ReadString(4); if (Reader.EndianType == EndianFormat.LittleEndian) { var tname = cname.ToCharArray(); Array.Reverse(tname); cname = new string(tname); } int index; if (!classDic.TryGetValue(cname, out index)) { index = classDic.Count; classDic.Add(cname, classDic.Count); } Reader.Skip(8); //parent classes IndexItem item = new IndexItem() { Cache = cache }; item.ClassIndex = index; item.ID = Reader.ReadInt32(); indices[i] = Reader.ReadInt32() - CH.Magic - CH.fileTableOffset; item.Offset = Reader.ReadInt32() - CH.Magic; this.Add(item); Reader.Skip(8); //empty? if (cname == "scnr") { long tempOffset = Reader.Position; Reader.SeekTo(item.Offset + 1444); int jCount = Reader.ReadInt32(); int jOffset = Reader.ReadInt32() - cache.Magic; sbspOffset = new int[jCount]; sbspMagic = new int[jCount]; sbspID = new int[jCount]; for (int j = 0; j < jCount; j++) { Reader.SeekTo(jOffset + j * 32); sbspOffset[j] = Reader.ReadInt32(); Reader.ReadInt32(); sbspMagic[j] = Reader.ReadInt32() - sbspOffset[j]; Reader.SeekTo(jOffset + j * 32 + 28); sbspID[j] = Reader.ReadInt32(); } Reader.SeekTo(tempOffset); } } for (int i = 0; i < sbspID.Length; i++) { var tag = GetItemByID(sbspID[i]); tag.Offset = sbspOffset[i]; tag.Magic = sbspMagic[i]; } CH.fileTableSize = this[0].Offset - CH.fileTableOffset; foreach (var pair in classDic) { ClassList.Add(new TagClass() { ClassCode = pair.Key }); } #endregion #region Read Names Reader.StreamOrigin = CH.fileTableOffset; for (int i = 0; i < indices.Length; i++) { if (indices[i] == -1) { this[i].Filename = "<null>"; continue; } Reader.SeekTo(indices[i]); int length; if (i == indices.Length - 1) { length = CH.fileTableSize - indices[i]; } else { if (indices[i + 1] == -1) { int index = -1; for (int j = i + 1; j < indices.Length; j++) { if (indices[j] != -1) { index = j; break; } } length = (index == -1) ? CH.fileTableSize - indices[i] : indices[index] - indices[i]; } else { length = indices[i + 1] - indices[i]; } } if (length <= 1) { this[i].Filename = this[i].Offset.ToString("X8"); continue; } this[i].Filename = Reader.ReadNullTerminatedString(length); } Reader.StreamOrigin = 0; #endregion }