private void FixDecalSystems(GameCacheContextHaloOnline destCacheContext, int firstNewIndex) { // decs tags need to be updated to use the old rmdf for decals, // because the decal planes seem to be generated by the engine and // therefore need to use the old vertex format. // // This could probably be done as a post-processing step in // ConvertStructure to avoid the extra deserialize-reserialize // pass, but we'd have to store the rmdf somewhere and frankly I'm // too lazy to do that... var firstDecalSystemTag = destCacheContext.TagCache.FindFirstInGroup("decs"); if (firstDecalSystemTag == null) { return; } using (var stream = destCacheContext.OpenTagCacheReadWrite()) { var firstDecalSystem = destCacheContext.Deserialize <DecalSystem>(stream, firstDecalSystemTag); foreach (var decalSystemTag in destCacheContext.TagCache.Index.FindAllInGroup("decs").Where(t => t.Index >= firstNewIndex)) { TagPrinter.PrintTagShort(decalSystemTag); var decalSystem = destCacheContext.Deserialize <DecalSystem>(stream, decalSystemTag); foreach (var system in decalSystem.Decal) { system.RenderMethod.BaseRenderMethod = firstDecalSystem.Decal[0].RenderMethod.BaseRenderMethod; } destCacheContext.Serialize(stream, decalSystemTag, decalSystem); } } }
private CachedTagHaloOnline ConvertTag(CachedTagHaloOnline srcTag, GameCacheContextHaloOnline srcCacheContext, Stream srcStream, GameCacheContextHaloOnline destCacheContext, Stream destStream, TagVersionMap tagMap) { TagPrinter.PrintTagShort(srcTag); // Uncomment this to use 0x101F for all shaders /*if (srcTag.IsClass("rm ")) * return destCacheContext.Cache.Tags[0x101F];*/ // Check if the tag is in the map, and just return the translated tag if so var destIndex = tagMap.Translate(srcCacheContext.Version, srcTag.Index, destCacheContext.Version); if (destIndex >= 0) { Console.WriteLine("- Using already-known index {0:X4}", destIndex); return(destCacheContext.TagCache.Index[destIndex]); } // Deserialize the tag from the source cache var tagData = srcCacheContext.Deserialize(srcStream, srcTag); // Uncomment this to use 0x101F in place of shaders that need conversion /*if (tagData is RenderMethod) * { * var rm = (RenderMethod)tagData; * foreach (var prop in rm.ShaderProperties) * { * if (tagMap.Translate(srcCacheContext.Version, prop.Template.Index, destCacheContext.Version) < 0) * return destCacheContext.Cache.Tags[0x101F]; * } * }*/ // Allocate a new tag and create a mapping for it CachedTagHaloOnline instance = null; if (srcCacheContext.Version != destCacheContext.Version) { for (var i = 0; i < destCacheContext.TagCache.Index.Count; i++) { if (destCacheContext.TagCache.Index[i] == null) { destCacheContext.TagCache.Index[i] = instance = new CachedTagHaloOnline(i, TagGroup.Instances[srcTag.Group.Tag]); break; } } } else { if (destCacheContext.TagCache.Index[srcTag.Index] != null) { if (destCacheContext.TagCache.Index[srcTag.Index].IsInGroup(srcTag.Group)) { return(destCacheContext.TagCache.Index[srcTag.Index]); } } else { destCacheContext.TagCache.Index[srcTag.Index] = instance = new CachedTagHaloOnline(srcTag.Index, TagGroup.Instances[srcTag.Group.Tag], srcTag.Name); } } if (instance == null) { instance = destCacheContext.TagCache.AllocateTag(srcTag.Group); } tagMap.Add(srcCacheContext.Version, srcTag.Index, destCacheContext.Version, instance.Index); if (srcTag.IsInGroup("decs") || srcTag.IsInGroup("rmd ")) { IsDecalShader = true; } // Convert it tagData = Convert(tagData, srcCacheContext, srcStream, destCacheContext, destStream, tagMap); if (srcTag.IsInGroup("decs") || srcTag.IsInGroup("rmd ")) { IsDecalShader = false; } // Re-serialize into the destination cache destCacheContext.Serialize(destStream, instance, tagData); return(instance); }