Ejemplo n.º 1
0
        public static SoundCacheFileGestalt LoadSoundGestalt(HaloOnlineCacheContext cacheContext, ref CacheFile blamCache)
        {
            CacheFile.IndexItem blamTag = null;

            foreach (var tag in blamCache.IndexItems)
            {
                if (tag.GroupTag == "ugh!")
                {
                    blamTag = tag;
                    break;
                }
            }

            if (blamTag == null)
            {
                return(null);
            }

            var blamContext = new CacheSerializationContext(ref blamCache, blamTag);
            var ugh         = blamCache.Deserializer.Deserialize <SoundCacheFileGestalt>(blamContext);

            //
            // Apply conversion to ugh! data (gain increase and such)
            //

            return(ugh);
        }
        public CacheSerializationContext(ref CacheFile blamCache, CacheFile.IndexItem blamTag)
        {
            if (blamCache.Version < CacheVersion.Halo3Retail)
            {
                var oldBlamCache = blamCache;
                var oldBlamTag   = blamTag;

                if (blamTag.External)
                {
                    try
                    {
                        blamCache = CacheFileGen2.MainMenuCache;
                        blamTag   = blamCache.IndexItems[blamTag.GroupTag, blamTag.Name];
                    }
                    catch (KeyNotFoundException)
                    {
                        blamCache = oldBlamCache;
                        blamTag   = oldBlamTag;
                    }
                }
                if (blamTag.External)
                {
                    try
                    {
                        blamCache = CacheFileGen2.SharedCache;
                        blamTag   = blamCache.IndexItems[blamTag.GroupTag, blamTag.Name];
                    }
                    catch (KeyNotFoundException)
                    {
                        blamCache = oldBlamCache;
                        blamTag   = oldBlamTag;
                    }
                }
                if (blamTag.External)
                {
                    try
                    {
                        blamCache = CacheFileGen2.SinglePlayerSharedCache;
                        blamTag   = blamCache.IndexItems[blamTag.GroupTag, blamTag.Name];
                    }
                    catch (KeyNotFoundException)
                    {
                        blamCache = oldBlamCache;
                        blamTag   = oldBlamTag;
                    }
                }
                if (blamTag.External)
                {
                    throw new KeyNotFoundException($"[{blamTag.GroupTag}] {blamTag.Name}");
                }
            }

            BlamCache = blamCache;
            BlamTag   = blamTag;
        }
Ejemplo n.º 3
0
        private Bitmap ConvertBitmap(CacheFile.IndexItem blamTag, Bitmap bitmap, Dictionary <ResourceLocation, Stream> resourceStreams)
        {
            bitmap.Flags     = BitmapRuntimeFlags.UsingTagInteropAndTagResource;
            bitmap.UnknownB4 = 0;

            if (BlamCache.Version == CacheVersion.HaloReach)
            {
                bitmap.TightBoundsOld = bitmap.TightBoundsNew;

                foreach (var image in bitmap.Images)
                {
                    // For all formats above #38 (reach DXN, CTX1, DXT3a_mono, DXT3a_alpha, DXT5a_mono, DXT5a_alpha, DXN_mono_alpha), subtract 5 to match with H3/ODST/HO enum
                    if (image.Format >= (BitmapFormat)38)
                    {
                        image.Format = image.Format - 5;
                    }
                }
            }

            //
            // For each bitmaps, apply conversion process and create a new list of resources that will replace the one from H3.
            //

            var tagName      = blamTag.Name;
            var resourceList = new List <Bitmap.BitmapResource>();

            for (int i = 0; i < bitmap.Images.Count(); i++)
            {
                var resource = ConvertBitmap(bitmap, resourceStreams, i, tagName);
                if (resource == null)
                {
                    return(null);
                }
                Bitmap.BitmapResource bitmapResource = new Bitmap.BitmapResource
                {
                    Resource = resource
                };
                resourceList.Add(bitmapResource);
            }

            bitmap.Resources = resourceList;
            bitmap.InterleavedResourcesOld = null;

            //fixup for HO expecting 6 sequences in sensor_blips bitmap
            if (tagName == "ui\\chud\\bitmaps\\sensor_blips")
            {
                bitmap.Sequences.Add(bitmap.Sequences[3]);
                bitmap.Sequences.Add(bitmap.Sequences[3]);
            }

            return(bitmap);
        }
Ejemplo n.º 4
0
        public void ExtractXMA(CacheFile.IndexItem blamTag, string directory)
        {
            if (BlamSoundGestalt == null)
            {
                BlamSoundGestalt = PortingContextFactory.LoadSoundGestalt(CacheContext, ref BlamCache);
            }

            var blamContext = new CacheSerializationContext(ref BlamCache, blamTag);

            var sound = BlamCache.Deserializer.Deserialize <Sound>(blamContext);


            var xmaFileSize = BlamSoundGestalt.GetFileSize(sound.SoundReference.PitchRangeIndex, sound.SoundReference.PitchRangeCount);

            if (xmaFileSize < 0)
            {
                return;
            }

            var xmaData = BlamCache.GetSoundRaw(sound.SoundReference.ZoneAssetHandle, xmaFileSize);

            if (xmaData == null)
            {
                Console.WriteLine($"ERROR: Failed to find sound data!");
                return;
            }

            var    parts    = blamTag.Name.Split('\\');
            string baseName = parts[parts.Length - 1];

            for (int pitchRangeIndex = sound.SoundReference.PitchRangeIndex; pitchRangeIndex < sound.SoundReference.PitchRangeIndex + sound.SoundReference.PitchRangeCount; pitchRangeIndex++)
            {
                var relativePitchRangeIndex = pitchRangeIndex - sound.SoundReference.PitchRangeIndex;
                var permutationCount        = BlamSoundGestalt.GetPermutationCount(pitchRangeIndex);

                for (int i = 0; i < permutationCount; i++)
                {
                    BlamSound blamSound       = SoundConverter.GetXMA(BlamCache, BlamSoundGestalt, sound, relativePitchRangeIndex, i, xmaData);
                    string    permutationName = $"{baseName}_{relativePitchRangeIndex}_{i}";
                    var       fileName        = $"{directory}\\{permutationName}.xma";

                    using (EndianWriter output = new EndianWriter(new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None), EndianFormat.BigEndian))
                    {
                        XMAFile XMAfile = new XMAFile(blamSound);
                        XMAfile.Write(output);
                    }
                }
            }
        }
Ejemplo n.º 5
0
        private void ExtractBitmap(CacheFile.IndexItem blamTag, string directory)
        {
            Console.WriteLine($"{blamTag.Name}");
            //
            // Load the Blam tag definition
            //

            var blamContext = new CacheSerializationContext(ref BlamCache, blamTag);

            var bitmap = BlamCache.Deserializer.Deserialize <Bitmap>(blamContext);


            var    ddsOutDir   = directory;
            string bitmap_name = blamTag.Name.Replace('\\', '_');

            if (bitmap.Images.Count > 1)
            {
                ddsOutDir = Path.Combine(directory, bitmap_name);
                Directory.CreateDirectory(ddsOutDir);
            }

            for (var i = 0; i < bitmap.Images.Count; i++)
            {
                var outPath = Path.Combine(ddsOutDir, ((bitmap.Images.Count > 1) ? i.ToString() : bitmap_name) + ".dds");
                var image   = bitmap.Images[i];
                //
                // Get bitmap data and write file
                //

                BaseBitmap baseBitmap = ExtractBitmapData(bitmap, i);

                // Bitmap is not valid (not a failure to convert, tag data is not valid / no data to convert
                if (baseBitmap == null)
                {
                    return;
                }

                var header = new DDSHeader(baseBitmap);


                using (var outStream = File.Open(outPath, FileMode.Create, FileAccess.Write))
                {
                    header.Write(new EndianWriter(outStream));
                    var dataStream = new MemoryStream(baseBitmap.Data);
                    StreamUtil.Copy(dataStream, outStream, baseBitmap.Data.Length);
                }
            }
        }
Ejemplo n.º 6
0
        public EditBlockCommand(CommandContextStack contextStack, CacheFile blamCache, CacheFile.IndexItem tag, object value)
            : base(true,

                   "EditBlock",
                   "Edit the fields of a particular block element.",

                   "EditBlock <name> [element-index (if block)]",

                   "Edit the fields of a particular block element.")
        {
            BlamCache    = blamCache;
            ContextStack = contextStack;
            Tag          = tag;
            Structure    = TagStructure.GetTagStructureInfo(value.GetType(), BlamCache.Version);
            Owner        = value;
        }
Ejemplo n.º 7
0
        public CopyBlockElementsCommand(CommandContextStack contextStack, CacheFile blamCache, CacheFile.IndexItem tag, TagStructureInfo structure, object owner)
            : base(false,

                   "CopyBlockElements",
                   "Copies block elements from one tag to another.",

                   "CopyBlockElements <block name> [index = 0] [count = *]",

                   "Copies block elements from one tag to another.")
        {
            ContextStack = contextStack;
            BlamCache    = blamCache;
            Tag          = tag;
            Structure    = structure;
            Owner        = owner;
        }
Ejemplo n.º 8
0
        public void ExtractWAV(CacheFile.IndexItem blamTag, string directory)
        {
            Console.WriteLine($"Extracting {blamTag.Name}.sound");
            if (BlamSoundGestalt == null)
            {
                BlamSoundGestalt = PortingContextFactory.LoadSoundGestalt(CacheContext, ref BlamCache);
            }

            var blamContext = new CacheSerializationContext(ref BlamCache, blamTag);

            var sound = BlamCache.Deserializer.Deserialize <Sound>(blamContext);

            var xmaFileSize = BlamSoundGestalt.GetFileSize(sound.SoundReference.PitchRangeIndex, sound.SoundReference.PitchRangeCount);

            var xmaData = BlamCache.GetSoundRaw(sound.SoundReference.ZoneAssetHandle, xmaFileSize);

            if (xmaData == null)
            {
                Console.WriteLine($"ERROR: Failed to find sound data!");
                return;
            }

            var    OutDir     = directory;
            string sound_name = blamTag.Name.Replace('\\', '_');

            sound_name = Path.Combine(directory, sound_name);

            for (int pitchRangeIndex = sound.SoundReference.PitchRangeIndex; pitchRangeIndex < sound.SoundReference.PitchRangeIndex + sound.SoundReference.PitchRangeCount; pitchRangeIndex++)
            {
                var relativePitchRangeIndex = pitchRangeIndex - sound.SoundReference.PitchRangeIndex;
                var permutationCount        = BlamSoundGestalt.GetPermutationCount(pitchRangeIndex);

                for (int i = 0; i < permutationCount; i++)
                {
                    string permutationName = $"{sound_name}_{relativePitchRangeIndex}_{i}";
                    permutationName += ".mp3";

                    BlamSound blamSound = SoundConverter.ConvertGen3Sound(BlamCache, BlamSoundGestalt, sound, relativePitchRangeIndex, i, xmaData);
                    using (EndianWriter output = new EndianWriter(new FileStream(permutationName, FileMode.Create, FileAccess.Write, FileShare.None), EndianFormat.BigEndian))
                    {
                        output.WriteBlock(blamSound.Data);
                    }
                }
            }
        }
Ejemplo n.º 9
0
        private void CopyTagNames(Stream cacheStream, CachedTagInstance edTag, CacheFile.IndexItem blamTag)
        {
            if (CopiedTags.ContainsKey(blamTag.GroupTag))
            {
                foreach (var name in CopiedTags[blamTag.GroupTag])
                {
                    if (name == blamTag.Name)
                    {
                        return;
                    }
                }
            }
            else
            {
                CopiedTags[blamTag.GroupTag] = new List <string>();
            }

            CopiedTags[blamTag.GroupTag].Add(blamTag.Name);

            var edDef   = CacheContext.Deserialize(cacheStream, edTag);
            var blamDef = BlamCache.Deserializer.Deserialize(
                new CacheSerializationContext(ref BlamCache, blamTag),
                TagDefinition.Find(blamTag.GroupTag));

            var edInfo   = TagStructure.GetTagStructureInfo(edDef.GetType(), CacheContext.Version);
            var blamInfo = TagStructure.GetTagStructureInfo(blamDef.GetType(), BlamCache.Version);

            var oldName = edTag.Name;

            edTag.Name = blamTag.Name;

            if (edTag.Name != oldName)
            {
                NewNameCount++;
            }

            CopyTagNames(cacheStream, edDef, edInfo, blamDef, blamInfo);
        }
Ejemplo n.º 10
0
        private void MergeMultiplayerGlobals(Stream cacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, CachedTagInstance edTag, CacheFile.IndexItem h3Tag)
        {
            var edDef = CacheContext.Deserialize <MultiplayerGlobals>(cacheStream, edTag);

            var h3Def = BlamCache.Deserializer.Deserialize <MultiplayerGlobals>(
                new CacheSerializationContext(ref BlamCache, h3Tag));

            if (h3Def.Runtime == null || h3Def.Runtime.Count == 0)
            {
                return;
            }

            for (var i = 0; i < h3Def.Runtime[0].GeneralEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].GeneralEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].GeneralEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].GeneralEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].FlavorEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].FlavorEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].FlavorEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].FlavorEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].SlayerEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].SlayerEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].SlayerEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].SlayerEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].CtfEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].CtfEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].CtfEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].CtfEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].OddballEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].OddballEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].OddballEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].OddballEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].KingOfTheHillEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].KingOfTheHillEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].KingOfTheHillEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].KingOfTheHillEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].VipEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].VipEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].VipEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].VipEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].JuggernautEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].JuggernautEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].JuggernautEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].JuggernautEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].TerritoriesEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].TerritoriesEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].TerritoriesEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].TerritoriesEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].AssaultEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].AssaultEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].AssaultEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].AssaultEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].InfectionEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].InfectionEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].InfectionEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].InfectionEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            CacheContext.Serialize(cacheStream, edTag, edDef);
        }
Ejemplo n.º 11
0
        public override object Execute(List <string> args)
        {
            if (args.Count < 2)
            {
                return(false);
            }

            //
            // Verify Blam tag instance
            //

            var unitName = args[0].ToLower();

            if (unitName != "spartan" && unitName != "elite")
            {
                Console.WriteLine("ERROR: Only 'spartan' and 'elite' armor variants are allowed.");
                return(false);
            }

            args.RemoveAt(0);

            var blamTagName = unitName == "spartan" ?
                              @"objects\characters\masterchief\mp_masterchief\mp_masterchief" :
                              @"objects\characters\elite\mp_elite\mp_elite";

            Console.Write($"Verifying {blamTagName}.render_model...");

            CacheFile.IndexItem blamTag = null;

            foreach (var tag in BlamCache.IndexItems)
            {
                if ((tag.GroupTag == "mode") && (tag.Name == blamTagName))
                {
                    blamTag = tag;
                    break;
                }
            }

            if (blamTag == null)
            {
                Console.WriteLine($"ERROR: Blam tag does not exist: {blamTagName}.render_model");
                return(true);
            }

            Console.WriteLine("done.");

            //
            // Load the Blam tag definition
            //

            var variantName = args[0];

            args.RemoveAt(0);

            CachedTagInstance edModeTag = null;
            var isScenery   = false;
            var regionNames = new List <string>();

            while (args.Count != 0)
            {
                switch (args[0].ToLower())
                {
                case "scenery":
                    isScenery = true;
                    args.RemoveAt(0);
                    break;

                case "replace:":
                    edModeTag = CacheContext.GetTag(args[1]);
                    args.RemoveAt(1);
                    args.RemoveAt(0);
                    break;

                case "regions:":
                    regionNames.AddRange(args.Skip(1));
                    args.Clear();
                    break;

                default:
                    throw new InvalidDataException($"{args}");
                }
            }

            var blamContext      = new CacheSerializationContext(ref BlamCache, blamTag);
            var edModeDefinition = BlamCache.Deserializer.Deserialize <RenderModel>(blamContext);

            var materials = edModeDefinition.Materials.Select(i => new RenderMaterial
            {
                BreakableSurfaceIndex = i.BreakableSurfaceIndex,
                Properties            = i.Properties,
                RenderMethod          = i.RenderMethod,
                Skins    = i.Skins,
                Unknown  = i.Unknown,
                Unknown2 = i.Unknown2,
                Unknown3 = i.Unknown3,
                Unknown4 = i.Unknown4
            }).ToList();

            edModeDefinition = (RenderModel)ConvertData(null, edModeDefinition, false);

            var variantRegions = new List <RenderModel.Region>();

            foreach (var region in edModeDefinition.Regions)
            {
                if (regionNames.Count != 0 && !regionNames.Contains(CacheContext.GetString(region.Name)))
                {
                    continue;
                }

                var variantRegion = new RenderModel.Region
                {
                    Name         = region.Name,
                    Permutations = new List <RenderModel.Region.Permutation>()
                };

                foreach (var permutation in region.Permutations)
                {
                    if (variantName == CacheContext.GetString(permutation.Name))
                    {
                        variantRegion.Permutations.Add(permutation);
                    }
                }

                variantRegions.Add(variantRegion);
            }

            var variantMeshes        = new List <int>();
            var variantMaterials     = new List <int>();
            var variantVertexBuffers = new List <int>();
            var variantIndexBuffers  = new List <int>();

            foreach (var region in variantRegions)
            {
                foreach (var permutation in region.Permutations)
                {
                    for (var i = permutation.MeshIndex; i < (short)(permutation.MeshIndex + permutation.MeshCount); i++)
                    {
                        var mesh = edModeDefinition.Geometry.Meshes[i];

                        foreach (var part in mesh.Parts)
                        {
                            if (part.MaterialIndex != -1 && !variantMaterials.Contains(part.MaterialIndex))
                            {
                                variantMaterials.Add(part.MaterialIndex);
                            }
                        }

                        foreach (var vertexBuffer in mesh.VertexBufferIndices)
                        {
                            if (vertexBuffer != ushort.MaxValue && !variantVertexBuffers.Contains(vertexBuffer))
                            {
                                variantVertexBuffers.Add(vertexBuffer);
                            }
                        }

                        foreach (var indexBuffer in mesh.IndexBufferIndices)
                        {
                            if (indexBuffer != ushort.MaxValue && !variantIndexBuffers.Contains(indexBuffer))
                            {
                                variantIndexBuffers.Add(indexBuffer);
                            }
                        }

                        if (!variantMeshes.Contains(i))
                        {
                            variantMeshes.Add(i);
                        }
                    }
                }
            }

            variantMeshes.Sort();
            variantMaterials.Sort();
            variantVertexBuffers.Sort();
            variantIndexBuffers.Sort();

            foreach (var meshIndex in variantMeshes)
            {
                var mesh = edModeDefinition.Geometry.Meshes[meshIndex];

                foreach (var part in mesh.Parts)
                {
                    if (part.MaterialIndex != -1)
                    {
                        part.MaterialIndex = (short)variantMaterials.IndexOf(part.MaterialIndex);
                    }
                }
            }

            foreach (var region in variantRegions)
            {
                foreach (var permutation in region.Permutations)
                {
                    if (permutation.MeshIndex != -1)
                    {
                        permutation.MeshIndex = (short)variantMeshes.IndexOf(permutation.MeshIndex);
                    }
                }
            }

            foreach (var meshIndex in variantMeshes)
            {
                var mesh = edModeDefinition.Geometry.Meshes[meshIndex];

                for (var i = 0; i < mesh.VertexBufferIndices.Length; i++)
                {
                    if (!variantVertexBuffers.Contains(mesh.VertexBufferIndices[i]))
                    {
                        mesh.VertexBufferIndices[i] = ushort.MaxValue;
                    }
                    else
                    {
                        mesh.VertexBufferIndices[i] = (ushort)variantVertexBuffers.IndexOf(mesh.VertexBufferIndices[i]);
                    }
                }

                for (var i = 0; i < mesh.IndexBufferIndices.Length; i++)
                {
                    if (!variantIndexBuffers.Contains(mesh.IndexBufferIndices[i]))
                    {
                        mesh.IndexBufferIndices[i] = ushort.MaxValue;
                    }
                    else
                    {
                        mesh.IndexBufferIndices[i] = (ushort)variantIndexBuffers.IndexOf(mesh.IndexBufferIndices[i]);
                    }
                }
            }

            edModeDefinition.Regions         = variantRegions;
            edModeDefinition.Geometry.Meshes = edModeDefinition.Geometry.Meshes.Where(i => variantMeshes.Contains(edModeDefinition.Geometry.Meshes.IndexOf(i))).ToList();

            //
            // Port Blam render_model materials
            //

            materials = materials.Where(i => variantMaterials.Contains(materials.IndexOf(i))).ToList();

            using (var stream = CacheContext.OpenTagCacheReadWrite())
            {
                for (var i = 0; i < materials.Count; i++)
                {
                    var material = materials[i];

                    if (material.RenderMethod.Index == -1)
                    {
                        continue;
                    }

                    var blamRenderMethod    = materials[i].RenderMethod;
                    var blamRenderMethodTag = BlamCache.IndexItems.GetItemByID(blamRenderMethod.Index);

                    var renderMethodExists = false;

                    foreach (var instance in CacheContext.TagCache.Index.FindAllInGroup("rm  "))
                    {
                        if (instance?.Name == blamRenderMethodTag.Name)
                        {
                            renderMethodExists    = true;
                            material.RenderMethod = instance;
                            break;
                        }
                    }

                    if (!renderMethodExists)
                    {
                        material.RenderMethod = CacheContext.GetTag <Shader>(@"shaders\invalid");
                    }
                }
            }

            edModeDefinition.Materials = materials;

            //
            // Load Blam resource data
            //

            var resourceData = BlamCache.GetRawFromID(edModeDefinition.Geometry.ZoneAssetHandle);

            if (resourceData == null)
            {
                Console.WriteLine("Blam render_geometry resource contains no data.");
                return(true);
            }

            //
            // Load Blam resource definition
            //

            Console.Write("Loading Blam render_geometry resource definition...");

            var definitionEntry = BlamCache.ResourceGestalt.TagResources[edModeDefinition.Geometry.ZoneAssetHandle.Index];

            var resourceDefinition = new RenderGeometryApiResourceDefinition
            {
                VertexBuffers = new List <TagStructureReference <VertexBufferDefinition> >(),
                IndexBuffers  = new List <TagStructureReference <IndexBufferDefinition> >()
            };

            using (var definitionStream = new MemoryStream(BlamCache.ResourceGestalt.FixupInformation))
                using (var definitionReader = new EndianReader(definitionStream, EndianFormat.BigEndian))
                {
                    var dataContext = new DataSerializationContext(definitionReader, null, CacheResourceAddressType.Definition);

                    definitionReader.SeekTo(definitionEntry.FixupInformationOffset + (definitionEntry.FixupInformationLength - 24));

                    var vertexBufferCount = definitionReader.ReadInt32();
                    definitionReader.Skip(8);
                    var indexBufferCount = definitionReader.ReadInt32();

                    definitionReader.SeekTo(definitionEntry.FixupInformationOffset);

                    for (var i = 0; i < vertexBufferCount; i++)
                    {
                        resourceDefinition.VertexBuffers.Add(new TagStructureReference <VertexBufferDefinition>
                        {
                            Definition = new VertexBufferDefinition
                            {
                                Count      = definitionReader.ReadInt32(),
                                Format     = (VertexBufferFormat)definitionReader.ReadInt16(),
                                VertexSize = definitionReader.ReadInt16(),
                                Data       = new TagData
                                {
                                    Size     = definitionReader.ReadInt32(),
                                    Unused4  = definitionReader.ReadInt32(),
                                    Unused8  = definitionReader.ReadInt32(),
                                    Address  = new CacheResourceAddress(CacheResourceAddressType.Memory, definitionReader.ReadInt32()),
                                    Unused10 = definitionReader.ReadInt32()
                                }
                            }
                        });
                    }

                    definitionReader.Skip(vertexBufferCount * 12);

                    for (var i = 0; i < indexBufferCount; i++)
                    {
                        resourceDefinition.IndexBuffers.Add(new TagStructureReference <IndexBufferDefinition>
                        {
                            Definition = new IndexBufferDefinition
                            {
                                Format = (IndexBufferFormat)definitionReader.ReadInt32(),
                                Data   = new TagData
                                {
                                    Size     = definitionReader.ReadInt32(),
                                    Unused4  = definitionReader.ReadInt32(),
                                    Unused8  = definitionReader.ReadInt32(),
                                    Address  = new CacheResourceAddress(CacheResourceAddressType.Memory, definitionReader.ReadInt32()),
                                    Unused10 = definitionReader.ReadInt32()
                                }
                            }
                        });
                    }
                }

            Console.WriteLine("done.");

            //
            // Convert Blam resource data
            //

            using (var edResourceStream = new MemoryStream())
            {
                //
                // Convert Blam render_geometry_api_resource_definition
                //

                using (var blamResourceStream = new MemoryStream(resourceData))
                {
                    //
                    // Convert Blam vertex buffers
                    //

                    Console.Write("Converting vertex buffers...");

                    var previousVertexBufferCount = -1;

                    for (var i = 0; i < resourceDefinition.VertexBuffers.Count; i++)
                    {
                        if (!variantVertexBuffers.Contains(i))
                        {
                            continue;
                        }

                        blamResourceStream.Position = definitionEntry.ResourceFixups[i].Offset;
                        if (i > 0)
                        {
                            previousVertexBufferCount = resourceDefinition.VertexBuffers[i - 1].Definition.Count;
                        }
                        GeometryConverter.ConvertVertexBuffer(resourceDefinition, blamResourceStream, edResourceStream, i, previousVertexBufferCount);
                    }

                    Console.WriteLine("done.");

                    //
                    // Convert Blam index buffers
                    //

                    Console.Write("Converting index buffers...");

                    for (var i = 0; i < resourceDefinition.IndexBuffers.Count; i++)
                    {
                        if (!variantIndexBuffers.Contains(i))
                        {
                            continue;
                        }

                        blamResourceStream.Position = definitionEntry.ResourceFixups[resourceDefinition.VertexBuffers.Count * 2 + i].Offset;
                        GeometryConverter.ConvertIndexBuffer(resourceDefinition, blamResourceStream, edResourceStream, i);
                    }

                    Console.WriteLine("done.");
                }

                resourceDefinition.VertexBuffers = resourceDefinition.VertexBuffers.Where(i => variantVertexBuffers.Contains(resourceDefinition.VertexBuffers.IndexOf(i))).ToList();
                resourceDefinition.IndexBuffers  = resourceDefinition.IndexBuffers.Where(i => variantIndexBuffers.Contains(resourceDefinition.IndexBuffers.IndexOf(i))).ToList();

                //
                // Finalize the new ElDorado geometry resource
                //

                Console.Write("Writing resource data...");

                edModeDefinition.Geometry.Resource = new PageableResource
                {
                    Page     = new RawPage(),
                    Resource = new TagResourceGen3
                    {
                        ResourceType             = TagResourceTypeGen3.RenderGeometry,
                        ResourceFixups           = new List <TagResourceGen3.ResourceFixup>(),
                        ResourceDefinitionFixups = new List <TagResourceGen3.ResourceDefinitionFixup>(),
                        Unknown2 = 1
                    }
                };

                edResourceStream.Position = 0;

                var resourceContext = new ResourceSerializationContext(CacheContext, edModeDefinition.Geometry.Resource);
                CacheContext.Serializer.Serialize(resourceContext, resourceDefinition);
                edModeDefinition.Geometry.Resource.ChangeLocation(ResourceLocation.ResourcesB);
                CacheContext.AddResource(edModeDefinition.Geometry.Resource, edResourceStream);

                Console.WriteLine("done.");
            }

            edModeDefinition.Name = CacheContext.GetStringId(variantName);

            if (edModeTag == null)
            {
                for (var i = 0; i < CacheContext.TagCache.Index.Count; i++)
                {
                    if (CacheContext.TagCache.Index[i] == null)
                    {
                        CacheContext.TagCache.Index[i] = edModeTag = new CachedTagInstance(i, TagGroup.Instances[new Tag("mode")]);
                        break;
                    }
                }

                if (edModeTag == null)
                {
                    edModeTag = CacheContext.TagCache.AllocateTag(TagGroup.Instances[new Tag("mode")]);
                }
            }

            //
            // Create a new armor model tag
            //

            Model             edHlmtDefinition = null;
            CachedTagInstance edHlmtTag        = null;

            if (isScenery)
            {
                Console.Write($"Verifying {blamTagName}.model...");

                CacheFile.IndexItem blamHlmtTag = null;

                foreach (var tag in BlamCache.IndexItems)
                {
                    if ((tag.GroupTag == "hlmt") && (tag.Name == blamTagName))
                    {
                        blamHlmtTag = tag;
                        break;
                    }
                }

                if (blamHlmtTag == null)
                {
                    Console.WriteLine($"ERROR: Blam tag does not exist: {blamTagName}.model");
                    return(true);
                }

                Console.WriteLine("done.");

                blamContext      = new CacheSerializationContext(ref BlamCache, blamHlmtTag);
                edHlmtDefinition = (Model)ConvertData(null, BlamCache.Deserializer.Deserialize <Model>(blamContext), false);

                edHlmtDefinition.RenderModel        = edModeTag;
                edHlmtDefinition.ReduceToL1SuperLow = 36.38004f;
                edHlmtDefinition.ReduceToL2Low      = 27.28503f;
                edHlmtDefinition.Variants           = new List <Model.Variant>();
                edHlmtDefinition.Materials          = new List <Model.Material>();
                edHlmtDefinition.NewDamageInfo      = new List <Model.GlobalDamageInfoBlock>();
                edHlmtDefinition.Targets            = new List <Model.Target>();

                var collisionRegions = new List <Model.CollisionRegion>();

                foreach (var collisionRegion in edHlmtDefinition.CollisionRegions)
                {
                    var found = false;

                    foreach (var variantRegion in variantRegions)
                    {
                        if (collisionRegion.Name == variantRegion.Name)
                        {
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        continue;
                    }

                    found = false;

                    foreach (var permutation in collisionRegion.Permutations)
                    {
                        if (permutation.Name == CacheContext.GetStringId(variantName))
                        {
                            found = true;
                            break;
                        }
                    }

                    if (found)
                    {
                        collisionRegions.Add(collisionRegion);
                    }
                }

                foreach (var collisionRegion in collisionRegions)
                {
                    Model.CollisionRegion.Permutation permutation = null;

                    foreach (var collisionPermutation in collisionRegion.Permutations)
                    {
                        if (collisionPermutation.Name == CacheContext.GetStringId(variantName))
                        {
                            permutation = collisionPermutation;
                            break;
                        }
                    }

                    if (permutation == null)
                    {
                        throw new KeyNotFoundException();
                    }

                    collisionRegion.Permutations = new List <Model.CollisionRegion.Permutation> {
                        permutation
                    };
                }

                edHlmtDefinition.CollisionRegions = collisionRegions;

                for (var i = 0; i < CacheContext.TagCache.Index.Count; i++)
                {
                    if (CacheContext.TagCache.Index[i] == null)
                    {
                        CacheContext.TagCache.Index[i] = edHlmtTag = new CachedTagInstance(i, TagGroup.Instances[new Tag("hlmt")]);
                        break;
                    }
                }

                if (edHlmtTag == null)
                {
                    edHlmtTag = CacheContext.TagCache.AllocateTag(TagGroup.Instances[new Tag("hlmt")]);
                }
            }

            //
            // Create a new armor scenery tag
            //

            Scenery           edScenDefinition = null;
            CachedTagInstance edScenTag        = null;

            if (isScenery)
            {
                edScenDefinition = new Scenery
                {
                    ObjectType = new GameObjectType
                    {
                        Halo2       = GameObjectTypeHalo2.Scenery,
                        Halo3Retail = GameObjectTypeHalo3Retail.Scenery,
                        Halo3ODST   = GameObjectTypeHalo3ODST.Scenery,
                        HaloOnline  = GameObjectTypeHaloOnline.Scenery
                    },
                    BoundingRadius    = 0.44f,
                    BoundingOffset    = new RealPoint3d(-0.02f, 0.0f, 0.0f),
                    AccelerationScale = 1.2f,
                    SweetenerSize     = GameObject.SweetenerSizeValue.Medium,
                    Model             = edHlmtTag,
                    ChangeColors      = new List <GameObject.ChangeColor>
                    {
                        new GameObject.ChangeColor(),
                        new GameObject.ChangeColor(),
                        new GameObject.ChangeColor(),
                        new GameObject.ChangeColor(),
                        new GameObject.ChangeColor()
                    },
                    NodeMaps = new List <GameObject.NodeMap>()
                };

                for (sbyte i = 0; i < 51; i++)
                {
                    edScenDefinition.NodeMaps.Add(new GameObject.NodeMap {
                        TargetNode = i
                    });
                }

                for (var i = 0; i < CacheContext.TagCache.Index.Count; i++)
                {
                    if (CacheContext.TagCache.Index[i] == null)
                    {
                        CacheContext.TagCache.Index[i] = edScenTag = new CachedTagInstance(i, TagGroup.Instances[new Tag("scen")]);
                        break;
                    }
                }

                if (edScenTag == null)
                {
                    edScenTag = CacheContext.TagCache.AllocateTag(TagGroup.Instances[new Tag("scen")]);
                }
            }

            //
            // Serialize new ElDorado tag definitions
            //

            using (var cacheStream = CacheContext.OpenTagCacheReadWrite())
            {
                CacheContext.Serialize(cacheStream, edModeTag, edModeDefinition);
                edModeTag.Name = isScenery ?
                                 (unitName == "spartan" ?
                                  $@"objects\characters\masterchief\mp_masterchief\armor\{variantName}" :
                                  $@"objects\characters\elite\mp_elite\armor\{variantName}") :
                                 (unitName == "spartan" ?
                                  @"objects\characters\masterchief\mp_masterchief\mp_masterchief" :
                                  @"objects\characters\elite\mp_elite\mp_elite");

                if (isScenery)
                {
                    CacheContext.Serialize(cacheStream, edHlmtTag, edHlmtDefinition);
                    CacheContext.Serialize(cacheStream, edScenTag, edScenDefinition);
                    edScenTag.Name = unitName == "spartan" ?
                                     $@"objects\characters\masterchief\mp_masterchief\armor\{variantName}" :
                                     $@"objects\characters\elite\mp_elite\armor\{variantName}";
                }
            }

            return(true);
        }
Ejemplo n.º 12
0
        public override object Execute(List <string> args)
        {
            if (args.Count != 2)
            {
                return(false);
            }

            var groupTagInput = args[0];
            var blamTagName   = args[1];
            var groupTag      = Tag.Null;

            if (TagDefinition.Exists(groupTagInput))
            {
                groupTag = new Tag(groupTagInput);
            }
            else
            {
                foreach (var tagGroup in BlamCache.IndexItems.ClassList)
                {
                    if (groupTagInput == BlamCache.Strings.GetItemByID(tagGroup.StringID))
                    {
                        var chars = new char[4] {
                            ' ', ' ', ' ', ' '
                        };

                        for (var i = 0; i < 4; i++)
                        {
                            chars[i] = tagGroup.ClassCode[i];
                        }

                        groupTag = new Tag(new string(chars));
                        break;
                    }
                }
            }

            CacheFile.IndexItem tag = null;

            foreach (var blamTag in BlamCache.IndexItems)
            {
                if ((blamTag.GroupTag == groupTag.ToString()) && (blamTagName == "*" || blamTag.Name == blamTagName))
                {
                    tag = blamTag;
                    break;
                }
            }

            if (tag == null)
            {
                throw new Exception();
            }

            var tagName = $"(0x{tag.ID:X8}) {tag.Name.Substring(tag.Name.LastIndexOf('\\') + 1)}";

            var tagType    = TagDefinition.Find(groupTag);
            var definition = (TagStructure)BlamCache.Deserializer.Deserialize(new CacheSerializationContext(ref BlamCache, tag), tagType);
            var structure  = definition.GetTagStructureInfo(BlamCache.Version);

            var oldContext = ContextStack.Context;

            var commandContext = new CommandContext(ContextStack.Context, string.Format("{0}.{1}", tagName, groupTagInput));

            commandContext.AddCommand(new ListFieldsCommand(BlamCache, structure, definition));
            commandContext.AddCommand(new EditBlockCommand(ContextStack, BlamCache, tag, definition));
            commandContext.AddCommand(new CopyBlockElementsCommand(ContextStack, BlamCache, tag, structure, definition));
            commandContext.AddCommand(new Editing.ExitToCommand(ContextStack));
            ContextStack.Push(commandContext);

            Console.WriteLine($"Tag {tagName}.{groupTagInput} has been opened for editing.");
            Console.WriteLine("New commands are now available. Enter \"help\" to view them.");
            Console.WriteLine("Use \"exit\" to return to {0}.", oldContext.Name);

            return(true);
        }
Ejemplo n.º 13
0
        private void MergeMultilingualUnicodeStringList(Stream cacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, CachedTagInstance edTag, CacheFile.IndexItem h3Tag)
        {
            var edDef = CacheContext.Deserialize <MultilingualUnicodeStringList>(cacheStream, edTag);

            var h3Def = BlamCache.Deserializer.Deserialize <MultilingualUnicodeStringList>(
                new CacheSerializationContext(ref BlamCache, h3Tag));

            ConvertMultilingualUnicodeStringList(cacheStream, resourceStreams, h3Def);

            var mergedStringCount = 0;

            for (var i = 0; i < h3Def.Strings.Count; i++)
            {
                var found = false;

                for (var j = 0; j < edDef.Strings.Count; j++)
                {
                    if (h3Def.Strings[i].StringID == edDef.Strings[j].StringID)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    var localizedStr = new LocalizedString
                    {
                        StringID    = h3Def.Strings[i].StringID,
                        StringIDStr = h3Def.Strings[i].StringIDStr
                    };

                    edDef.Strings.Add(localizedStr);

                    for (var x = 0; x < 12; x++)
                    {
                        edDef.SetString(
                            localizedStr,
                            (GameLanguage)x,
                            h3Def.GetString(
                                h3Def.Strings[i],
                                (GameLanguage)x));
                    }

                    mergedStringCount++;
                }
            }

            if (mergedStringCount > 0)
            {
                Console.WriteLine($"Merged {mergedStringCount} localized strings.");
                CacheContext.Serialize(cacheStream, edTag, edDef);
            }
        }
Ejemplo n.º 14
0
        public CachedTagInstance FixRmt2Reference(Stream cacheStream, string blamTagName, CacheFile.IndexItem blamRmt2Tag, RenderMethodTemplate blamRmt2Definition, List <string> bmMaps, List <string> bmArgs)
        {
            switch (blamTagName)
            {
            case @"levels\multi\snowbound\shaders\cov_grey_icy":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_1_7_2_0_0_0_0_0"));
                }
                catch { }
                break;

            case @"objects\vehicles\ghost\shaders\ghost_damage":
            case @"objects\vehicles\wraith\shaders\wraith_blown_open":
            case @"objects\vehicles\banshee\shaders\banshee_damage":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_1_2_2_2_0_1_1_0"));
                }
                catch { }
                break;

            case @"objects\vehicles\ghost\shaders\ghost_torn":
            case @"objects\vehicles\banshee\shaders\banshee_torn":
            case @"objects\vehicles\wraith\shaders\wraith_torn":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_1_1_2_2_0_0_0_1_0"));
                }
                catch { }
                break;

            case @"objects\vehicles\wraith\shaders\wraith_torn_metal":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_1_1_1_2_0_0_0_1_0"));
                }
                catch { }
                break;

            case @"objects\vehicles\ghost\shaders\ghost_dash_zcam":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\halogram_templates\_0_11_0_1_0_2_0"));
                }
                catch { }
                break;

            case @"fx\particles\energy\electric_arcs_blue":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\particle_templates\_2_8_0_0_0_0_1_0_0_0"));
                }
                catch { }
                break;

            case @"objects\weapons\melee\energy_blade\fx\particles\plasma_wispy":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\particle_templates\_5_8_0_0_0_1_0_0_0_0"));
                }
                catch { }
                break;

            case @"objects\weapons\melee\energy_blade\fx\particles\energy_pulse":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\particle_templates\_3_7_0_0_1_0_0_0_0_0"));
                }
                catch { }
                break;

            case @"levels\dlc\fortress\shaders\panel_platform_center":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_0_1_2_2_5_0_1_0_0"));
                }
                catch
                {
                    try
                    {
                        return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_0_1_2_2_5_0_1_0_0_0"));
                    }
                    catch { }
                }
                break;

            case @"levels\dlc\sidewinder\shaders\side_tree_branch_snow":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_1_0_0_2_5_0_0_0_0_0"));
                }
                catch
                {
                    try
                    {
                        return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_1_0_0_2_5_0_0_0_0"));
                    }
                    catch { }
                }
                break;

            case @"levels\dlc\sidewinder\shaders\justin\sw_ground_ice1":
            case @"levels\dlc\sidewinder\shaders\justin\sw_ground_rock1":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\terrain_templates\_0_0_1_1_1_2"));
                }
                catch
                {
                    try
                    {
                        return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\terrain_templates\_0_0_1_1_1_2_0"));
                    }
                    catch { }
                }
                break;

            case @"levels\multi\snowbound\sky\shaders\skydome":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_0_0_0_0_0_0_0_0_0_0_0"));
                }
                catch
                {
                    try
                    {
                        return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_0_0_0_0_0_0_0_0_0_0"));
                    }
                    catch { }
                }
                break;

            case @"levels\solo\020_base\lights\light_volume_hatlight":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\halogram_templates\_0_5_1_0_0_1_1"));
                }
                catch { }
                break;

            case @"levels\dlc\armory\shaders\metal_doodad_a":
            case @"levels\dlc\armory\shaders\metal_doodad_a_illum_blue":
            case @"levels\dlc\armory\shaders\metal_doodad_a_illum_cool":
            case @"levels\dlc\armory\shaders\metal_doodad_a_illum_red":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_7_2_0_1_1_0_1_0_0_0_0"));
                }
                catch { }
                break;

            case @"levels\dlc\armory\shaders\razor_wire":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_1_2_5_2_0_1_0_1_0"));
                }
                catch { }
                break;

            case @"levels\multi\deadlock\shaders\deadlock_concrete_wall_a_rubble":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_0_0_0_0_0_0_0_0"));
                }
                catch { }
                break;

            case @"levels\multi\snowbound\shaders\rock_cliffs":
            case @"levels\multi\snowbound\shaders\rock_rocky":
            case @"levels\multi\snowbound\shaders\rock_rocky_icy":
            case @"levels\solo\020_base\shaders\hb_metal_arch_unwrap_a":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_7_2_0_1_2_1_0_0_1_0_0"));
                }
                catch { }
                break;

            case @"levels\dlc\armory\shaders\concrete_wall_01":
            case @"levels\dlc\armory\shaders\concrete_wall_01_blue":
            case @"levels\dlc\armory\shaders\concrete_wall_01_red":
            case @"levels\dlc\armory\shaders\concrete_wall_02_blue":
            case @"levels\dlc\armory\shaders\concrete_wall_02_red":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_7_2_0_1_7_0_0_0_0_0_0"));
                }
                catch { }
                break;

            case @"objects\levels\solo\010_jungle\shaders\dam_fence":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_1_1_1_2_0_0_0_1_0"));
                }
                catch { }
                break;

            case @"levels\dlc\chillout\shaders\chillout_capsule_liquid":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\halogram_templates\_2_5_1_0_1_2_1"));
                }
                catch { }
                break;

            case @"levels\dlc\chillout\shaders\chillout_flood_godrays":
            case @"levels\dlc\chillout\shaders\chillout_invis_godrays":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\halogram_templates\_0_5_1_0_0_1_1"));
                }
                catch { }
                break;

            case @"objects\levels\dlc\chillout\shaders\chill_energy_blocker_small":
            case @"objects\levels\dlc\chillout\shaders\chill_viewing_area_blocker":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\halogram_templates\_0_8_1_0_0_4_1"));
                }
                catch { }
                break;

            case @"levels\dlc\chillout\shaders\chillout_floodroom01":
            case @"levels\dlc\chillout\shaders\chillout_floodroom02":
            case @"levels\dlc\chillout\shaders\chillout_floodroom03":
            case @"levels\dlc\chillout\shaders\chillout_transporter":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_1_1_2_5_0_0_1_0"));
                }
                catch { }
                break;

            case @"levels\dlc\chillout\shaders\chillout_flood_suckers":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_1_2_1_1_0_0_0_0_0"));
                }
                catch { }
                break;

            case @"levels\shared\shaders\flood\flood_sackyb":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_0_0_1_0_0_3_1_1_0"));
                }
                catch { }
                break;

            case @"objects\characters\flood_infection\shaders\flood_fronds":
            case @"objects\characters\flood_tank\shaders\flood_fronds":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_1_0_0_2_5_0_0_0_0"));
                }
                catch { }
                break;

            case @"objects\characters\flood_infection\shaders\flood_infection":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_1_1_0_1_0_0_1"));
                }
                catch { }
                break;

            case @"objects\weapons\melee\energy_blade\shaders\energy_blade":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_1_1_0_3_3_1_1_0"));
                }
                catch
                {
                    try
                    {
                        return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_1_1_0_3_3_1_1_0_0"));
                    }
                    catch { }
                }
                break;

            case @"objects\weapons\rifle\plasma_rifle_red\shaders\plasma_rifle_red":
            case @"objects\weapons\rifle\plasma_rifle\shaders\plasma_rifle":
            case @"objects\weapons\rifle\covenant_carbine\shaders\carbine":
            case @"objects\weapons\rifle\covenant_carbine\shaders\carbine_dull":
            case @"objects\weapons\pistol\plasma_pistol\shaders\plasma_pistol_metal":
            case @"objects\weapons\pistol\needler\shaders\needler_blue":
            case @"objects\weapons\pistol\needler\shaders\needler_pink":
            case @"objects\weapons\support_high\flak_cannon\shaders\flak_cannon":
            case @"objects\weapons\rifle\beam_rifle\shaders\beam_rifle":
            case @"objects\weapons\rifle\beam_rifle\shaders\beam_rifle2":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_1_2_1_1_0_0_0_0"));
                }
                catch
                {
                    try
                    {
                        return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_1_2_1_1_0_0_0_0_0"));
                    }
                    catch { }
                }
                break;

            case @"objects\weapons\pistol\needler\shaders\needler_glass":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_0_0_0_0_1_0_3_0_0_0"));
                }
                catch
                {
                    try
                    {
                        return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_0_0_0_0_1_0_3_0_0_0_0"));
                    }
                    catch { }
                }
                break;

            case @"objects\weapons\rifle\sniper_rifle\shaders\scope_alpha":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\halogram_templates\_0_11_0_1_0_2_0"));
                }
                catch { }
                break;

            //Vehicles
            case @"objects\vehicles\scorpion\turrets\cannon\shaders\turret_cannon":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_3_2_0_1_1_0_0_0_0_0_0"));
                }
                catch { }
                break;
            }

            // Find existing rmt2 tags
            // If tagnames are not fixed, ms30 tags have an additional _0 or _0_0. This shouldn't happen if the tags have proper names, so it's mostly to preserve compatibility with older tagnames
            using (var reader = new EndianReader(cacheStream, true))
            {
                foreach (var instance in CacheContext.TagCache.Index)
                {
                    if (instance == null || !instance.IsInGroup("rmt2") || instance.Name == null)
                    {
                        continue;
                    }

                    if (instance.Name.StartsWith(blamRmt2Tag.Name))
                    {
                        reader.SeekTo(instance.HeaderOffset + instance.DefinitionOffset + 12);
                        var vertexShaderIndex = reader.ReadInt32();

                        reader.SeekTo(instance.HeaderOffset + instance.DefinitionOffset + 28);
                        var pixelShaderIndex = reader.ReadInt32();

                        if (!UseMS30 && (vertexShaderIndex >= 0x4455 || pixelShaderIndex >= 0x4455))
                        {
                            continue;
                        }

                        return(instance);
                    }
                }
            }

            // if no tagname matches, find rmt2 tags based on the most common values in the name
            return(FindEquivalentRmt2(cacheStream, blamRmt2Tag, blamRmt2Definition, bmMaps, bmArgs));
        }
Ejemplo n.º 15
0
        public CachedTagInstance FindEquivalentRmt2(Stream cacheStream, CacheFile.IndexItem blamRmt2Tag, RenderMethodTemplate blamRmt2Definition, List <string> bmMaps, List <string> bmArgs)
        {
            // Find similar shaders by finding tags with as many common bitmaps and arguments as possible.
            var edRmt2Temp = new List <ShaderTemplateItem>();

            // Make a new dictionary with rmt2 of the same shader type
            var edRmt2BestStats = new List <ShaderTemplateItem>();

            edRmt2BestStats = CollectRmt2Info(cacheStream, blamRmt2Tag, bmMaps, bmArgs);

            // rmt2 tagnames have a bunch of values, they're tagblock indexes in rmdf methods.ShaderOptions
            foreach (var d in edRmt2BestStats)
            {
                var dInstance = CacheContext.GetTag(d.rmt2TagIndex);

                if (dInstance == null || dInstance.Name == null)
                {
                    continue;
                }

                var edSplit      = dInstance.Name.Split("\\".ToCharArray());
                var edType       = edSplit[1];
                var edRmdfValues = edSplit[2].Split("_".ToCharArray()).ToList();
                edRmdfValues.RemoveAt(0);

                var bmSplit      = blamRmt2Tag.Name.Split("\\".ToCharArray());
                var bmType       = bmSplit[1];
                var bmRmdfValues = bmSplit[2].Split("_".ToCharArray()).ToList();
                bmRmdfValues.RemoveAt(0);

                int matchingValues = 0;
                for (int i = 0; i < bmRmdfValues.Count; i++)
                {
                    var weight = 0;
                    if (bmRmdfValues[i] == edRmdfValues[i])
                    {
                        switch (i)
                        {
                        case 00:
                        case 06: weight = 1; break;
                        }
                        matchingValues = matchingValues + 1 + weight;
                    }
                }

                d.rmdfValuesMatchingCount = matchingValues;

                if (edType != bmType)
                {
                    d.rmdfValuesMatchingCount = 0;
                }
            }

            var edRmt2BestStatsSorted = edRmt2BestStats.OrderBy(x => x.rmdfValuesMatchingCount);

            if (edRmt2BestStats.Count == 0)
            {
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_0_0_0_0_0_0_0_0_0_0"));
                }
                catch (KeyNotFoundException)
                {
                    return(null);
                }
            }

            return(CacheContext.GetTag(edRmt2BestStatsSorted.Last().rmt2TagIndex));
        }
Ejemplo n.º 16
0
        private List <ShaderTemplateItem> CollectRmt2Info(Stream cacheStream, CacheFile.IndexItem bmRmt2Instance, List <string> bmMaps, List <string> bmArgs)
        {
            var edRmt2BestStats = new List <ShaderTemplateItem>();

            var bmRmt2Context = new CacheSerializationContext(ref BlamCache, bmRmt2Instance);
            var bmRmt2        = BlamCache.Deserializer.Deserialize <RenderMethodTemplate>(bmRmt2Context);
            var bmPixlContext = new CacheSerializationContext(ref BlamCache, BlamCache.IndexItems.GetItemByID(bmRmt2.PixelShader.Index));
            var bmPixl        = BlamCache.Deserializer.Deserialize <PixelShader>(bmPixlContext);

            // loop trough all rmt2 and find the closest
            foreach (var edRmt2_ in Rmt2TagsInfo)
            {
                var rmt2Type = bmRmt2Instance.Name.Split("\\".ToArray())[1];

                var edRmt2Tag = CacheContext.GetTag(edRmt2_.Key);

                // Ignore all rmt2 that are not of the same type.
                if (edRmt2Tag == null || !(edRmt2Tag.Name?.Contains(rmt2Type) ?? false))
                {
                    continue;
                }

                using (var reader = new EndianReader(cacheStream, true))
                {
                    reader.SeekTo(edRmt2Tag.HeaderOffset + edRmt2Tag.DefinitionOffset + 28);
                    var edPixl = CacheContext.GetTag(reader.ReadInt32());

                    if (edPixl == null)
                    {
                        continue;
                    }

                    reader.SeekTo(edPixl.HeaderOffset + edPixl.DefinitionOffset + 0x4);
                    var drawModeCount = reader.ReadInt32();

                    reader.SeekTo(edPixl.HeaderOffset + edPixl.DefinitionOffset + 0x14);
                    var shaderCount = reader.ReadInt32();

                    if (bmPixl.DrawModes.Count > drawModeCount || bmPixl.Shaders.Count > shaderCount)
                    {
                        continue;
                    }
                }

                int mapsCommon   = 0;
                int argsCommon   = 0;
                int mapsUncommon = 0;
                int argsUncommon = 0;
                int mapsMissing  = 0;
                int argsMissing  = 0;

                var edMaps_ = new List <string>();
                var edArgs_ = new List <string>();

                foreach (var a in edRmt2_.Value[0])
                {
                    edMaps_.Add(a);
                }

                foreach (var a in edRmt2_.Value[1])
                {
                    edArgs_.Add(a);
                }

                foreach (var a in bmMaps)
                {
                    if (edMaps_.Contains(a))
                    {
                        mapsCommon++;
                    }
                }

                foreach (var a in bmMaps)
                {
                    if (!edMaps_.Contains(a))
                    {
                        mapsMissing++;
                    }
                }

                foreach (var a in edMaps_)
                {
                    if (!bmMaps.Contains(a))
                    {
                        mapsUncommon++;
                    }
                }

                foreach (var a in bmArgs)
                {
                    if (edArgs_.Contains(a))
                    {
                        argsCommon++;
                    }
                }

                foreach (var a in bmArgs)
                {
                    if (!edArgs_.Contains(a))
                    {
                        argsMissing++;
                    }
                }

                foreach (var a in edArgs_)
                {
                    if (!bmArgs.Contains(a))
                    {
                        argsUncommon++;
                    }
                }

                edRmt2BestStats.Add(new ShaderTemplateItem
                {
                    rmt2TagIndex            = edRmt2_.Key,
                    rmdfValuesMatchingCount = 0,
                    mapsCountEd             = edRmt2_.Value[0].Count,
                    argsCountEd             = edRmt2_.Value[1].Count,
                    mapsCountBm             = bmMaps.Count,
                    argsCountBm             = bmArgs.Count,
                    mapsCommon   = mapsCommon,
                    argsCommon   = argsCommon,
                    mapsUncommon = mapsUncommon,
                    argsUncommon = argsUncommon,
                    mapsMissing  = mapsMissing,
                    argsMissing  = argsMissing
                });
            }

            return(edRmt2BestStats);
        }
Ejemplo n.º 17
0
        public override object Execute(List <string> args)
        {
            var  directory   = "";
            var  blamTagName = "";
            bool convertAll  = false;

            if (args.Count == 2)
            {
                blamTagName = args[0];
                directory   = args[1];
            }
            else if (args.Count == 1)
            {
                blamTagName = args[0];
                directory   = "Sounds";
            }
            else
            {
                return(false);
            }

            if (args[0].ToLower() == "all")
            {
                convertAll = true;
            }

            if (!Directory.Exists(directory))
            {
                Console.Write("Destination directory does not exist. Create it? [y/n] ");
                var answer = Console.ReadLine().ToLower();

                if (answer.Length == 0 || !(answer.StartsWith("y") || answer.StartsWith("n")))
                {
                    return(false);
                }

                if (answer.StartsWith("y"))
                {
                    Directory.CreateDirectory(directory);
                }
                else
                {
                    return(false);
                }
            }

            if (!convertAll)
            {
                CacheFile.IndexItem blamTag = null;

                foreach (var tag in BlamCache.IndexItems)
                {
                    if ((tag.GroupTag == "snd!") && (tag.Name == blamTagName))
                    {
                        blamTag = tag;
                        break;
                    }
                }

                if (blamTag == null)
                {
                    Console.WriteLine($"ERROR: Blam tag does not exist: {blamTagName}.sound");
                    return(true);
                }

                ExtractWAV(blamTag, directory);
            }
            else
            {
                foreach (var tag in BlamCache.IndexItems)
                {
                    if ((tag.GroupTag == "snd!"))
                    {
                        ExtractWAV(tag, directory);
                    }
                }
            }

            Console.WriteLine("done.");

            return(true);
        }
 public XboxSerializationContext(CacheFile.IndexItem tag)
 {
     _tag = tag;
 }
Ejemplo n.º 19
0
        private void MergeCharacter(Stream cacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, CachedTagInstance edTag, CacheFile.IndexItem h3Tag)
        {
            var edDef = CacheContext.Deserialize <Character>(cacheStream, edTag);

            var h3Def = BlamCache.Deserializer.Deserialize <Character>(
                new CacheSerializationContext(ref BlamCache, h3Tag));

            var merged = false;

            if (edDef.WeaponsProperties.Count == h3Def.WeaponsProperties.Count)
            {
                for (var i = 0; i < edDef.WeaponsProperties.Count; i++)
                {
                    if (edDef.WeaponsProperties[i].Weapon != null || h3Def.WeaponsProperties[i].Weapon == null)
                    {
                        continue;
                    }

                    edDef.WeaponsProperties[i].Weapon = ConvertTag(cacheStream, resourceStreams,
                                                                   BlamCache.GetIndexItemFromID(h3Def.WeaponsProperties[i].Weapon.Index));

                    merged = true;
                }
            }

            if (edDef.VehicleProperties.Count == h3Def.VehicleProperties.Count)
            {
                for (var i = 0; i < edDef.VehicleProperties.Count; i++)
                {
                    if (edDef.VehicleProperties[i].Unit != null || h3Def.VehicleProperties[i].Unit == null)
                    {
                        continue;
                    }

                    edDef.VehicleProperties[i].Unit = ConvertTag(cacheStream, resourceStreams,
                                                                 BlamCache.GetIndexItemFromID(h3Def.VehicleProperties[i].Unit.Index));

                    merged = true;
                }
            }

            if (edDef.EquipmentProperties.Count == h3Def.EquipmentProperties.Count)
            {
                for (var i = 0; i < edDef.EquipmentProperties.Count; i++)
                {
                    if (edDef.EquipmentProperties[i].Equipment != null || h3Def.EquipmentProperties[i].Equipment == null)
                    {
                        continue;
                    }

                    edDef.EquipmentProperties[i].Equipment = ConvertTag(cacheStream, resourceStreams,
                                                                        BlamCache.GetIndexItemFromID(h3Def.EquipmentProperties[i].Equipment.Index));

                    merged = true;
                }
            }

            if (merged)
            {
                CacheContext.Serialize(cacheStream, edTag, edDef);
            }
        }