/// <summary> /// Takes the input stream and does any version specific /// data operations to get the tag manager ready for reading /// </summary> void CalculateVersion() { InputStream.Seek(60); InputStream.State = BlamLib.IO.EndianState.Little; uint group_tag = InputStream.ReadTagUInt(); BlamBuild bb = FromSignature(group_tag); #region Endian handling if (bb == BlamBuild.Halo1) { endianState = BlamLib.IO.EndianState.Big; } else { endianState = BlamLib.IO.EndianState.Little; } if (InputStream != null) { InputStream.State = endianState; } if (OutputStream != null) { OutputStream.State = endianState; } #endregion if (engine == BlamVersion.Unknown) { engine = bb.ToVersion(); ManageSetupTagGroup(); } }
/// <summary>Invalid engine exception details</summary> /// <param name="expected">The engine build we were expecting</param> /// <param name="got">The engine build we actually got</param> /// <remarks>Meant for general engine conflictions</remarks> public InvalidBlamVersionException(BlamBuild expected, BlamBuild got) : base(null, "Invalid engine build") { Debug.LogFile.WriteLine( "Invalid engine build: expected '{0}' but got '{1}'", expected, got); }
/// <summary> /// Open a tag in the cache file /// </summary> /// <param name="tag_datum">index of tag</param> /// <returns> /// The tag_index handle associated to the <see cref="TagManager"/> object used to open the tag, /// or <see cref="Blam.DatumIndex.Null"/> if this operations fails /// </returns> public Blam.DatumIndex Open(Blam.DatumIndex tag_datum) { if (tag_datum == Blam.DatumIndex.Null) { return(Blam.DatumIndex.Null); } Blam.CacheIndex.Item i = cacheFile.Index.Tags[tag_datum.Index]; if (i.IsEmpty) { throw new ArgumentNullException("tag_datum", string.Format("The tag handle {0} references an empty tag. We can't open this!", tag_datum.ToString())); } // How can we open it if we don't know where it F*****G IS YOU C**T?? if (i.Location != Blam.CacheIndex.ItemLocation.Internal && !i.IsFeignItem) { return(Blam.DatumIndex.Null); } // Is this tag already loaded? if so, reuse handle Blam.DatumIndex di = IsLoaded(i); if (di != Blam.DatumIndex.Null) { Array.IncrementReference(di); return(di); } TagManager tm = new TagManager(this); tm.ReferenceName = i.ReferenceName; // sync the tag manager's name with the cache item's bool group_tag_hack = false; BlamBuild build = Engine.ToBuild(); // HACK: Halo1 PC uses gbx's variant of the model tag if (Engine == BlamVersion.Halo1_CE && i.GroupTag == Blam.Halo1.TagGroups.mode) { tm.Manage(Blam.Halo1.TagGroups.mod2); group_tag_hack = true; } else // HACK: Halo 2/3 use a the 'sound' group tag for their 'cache_file_sound' definitions #if !NO_HALO2 if (build == BlamBuild.Halo2 && i.GroupTag == Blam.Halo2.TagGroups.snd_) { tm.Manage(Blam.Halo2.TagGroups.shit); group_tag_hack = true; } else #endif #if !NO_HALO3 if (build == BlamBuild.Halo3 && i.GroupTag == Blam.Halo3.TagGroups.snd_) { tm.Manage(Blam.Halo3.TagGroups.shit); group_tag_hack = true; } else #endif #if !NO_HALO_ODST if (build == BlamBuild.HaloOdst && i.GroupTag == Blam.Halo3.TagGroups.snd_) { tm.Manage(Blam.Halo3.TagGroups.shit); group_tag_hack = true; } else #endif #if !NO_HALO_REACH if (build == BlamBuild.HaloReach && i.GroupTag == Blam.HaloReach.TagGroups.snd_) { tm.Manage(Blam.HaloReach.TagGroups.shit); group_tag_hack = true; } else #endif #if !NO_HALO4 if (build == BlamBuild.Halo4 && i.GroupTag == Blam.Halo4.TagGroups.snd_) { tm.Manage(Blam.Halo4.TagGroups.shit); group_tag_hack = true; } else #endif { tm.Manage(i.GroupTag); } if (!i.IsFeignItem) { // We don't care about this shit when extracting or opening from a cache file const uint k_open_flags = IO.ITagStreamFlags.DontTrackTagManagerReferences | IO.ITagStreamFlags.DontTrackTagReferencers; tm.Flags.Add(k_open_flags); try { tm.Read(i, cacheFile, group_tag_hack); } catch (Exception ex) { indexTrace.WriteLine("Cache Index: Failed to open tag from cache: {0}{1}'{2}.{3}'{4}{5}", cacheFile.InputStream.FileName, Program.NewLine, cacheFile.GetReferenceName(i), i.GroupTag.Name, Program.NewLine, ex); return(Blam.DatumIndex.Null); } // Remove the flag we set before reading tm.Flags.Remove(k_open_flags); } tm.TagIndex = Array.Add(tm); base.OnEventOpen(new TagIndexEventArgs(this, tm)); return(tm.TagIndex); }
/// <summary>BlamVersion from BlamBuild and BlamPlatform</summary> /// <param name="build">game engine</param> /// <param name="platform">game engine platform</param> /// <returns></returns> public static BlamVersion Version(BlamBuild build, BlamPlatform platform) { return ((BlamVersion)build) | ((BlamVersion)platform); }
/// <summary>BlamVersion from BlamBuild and BlamPlatform</summary> /// <param name="build">game engine</param> /// <param name="platform">game engine platform</param> /// <returns></returns> public static BlamVersion Version(BlamBuild build, BlamPlatform platform) { return(((BlamVersion)build) | ((BlamVersion)platform)); }
/// <summary>BlamVersion from BlamBuild</summary> /// <param name="build">game engine</param> /// <returns></returns> public static BlamVersion ToVersion(this BlamBuild build) { return((BlamVersion)build); }
/// <summary> /// Extension method for <see cref="BlamBuild"/> for streaming an instance to a stream /// </summary> /// <param name="build"></param> /// <param name="s"></param> public static void Write(this BlamBuild build, IO.EndianWriter s) { s.Write((ushort)build); }
/// <summary> /// Extension method for <see cref="BlamBuild"/> for streaming an instance from a stream /// </summary> /// <param name="build"></param> /// <param name="s"></param> public static void Read(this BlamBuild build, IO.EndianReader s) { build = (BlamBuild)s.ReadUInt16(); }