예제 #1
0
        public override bool Execute(List <string> args)
        {
            if (args.Count != 0)
            {
                return(false);
            }

            foreach (var property in Definition.ShaderProperties)
            {
                RenderMethodTemplate template = null;

                using (var cacheStream = Info.CacheFile.Open(FileMode.Open, FileAccess.Read))
                {
                    var context = new TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, property.Template);
                    template = Info.Deserializer.Deserialize <RenderMethodTemplate>(context);
                }

                for (var i = 0; i < template.ShaderMaps.Count; i++)
                {
                    var mapTemplate = template.ShaderMaps[i];

                    Console.WriteLine($"Bitmap {i} ({Info.StringIDs.GetString(mapTemplate.Name)}): {property.ShaderMaps[i].Bitmap.Group.Tag} 0x{property.ShaderMaps[i].Bitmap.Index:X4}");
                }
            }

            return(true);
        }
예제 #2
0
        public override object Execute(List <string> args)
        {
            if (args.Count < 1 || args.Count > 2)
            {
                return(false);
            }

            if (args[0] == "new")
            {
                return(MatchShaderNew(args[1]));
            }
            else if (args.Count == 2)
            {
                return(false);
            }

            RenderMethodTemplate bmRmt2 = new RenderMethodTemplate();
            CachedTag            bmRmt2Instance;

            using (var blamStream = BlamCache.OpenCacheRead())
            {
                if (BlamCache.TryGetCachedTag(args[0], out bmRmt2Instance))
                {
                    bmRmt2 = BlamCache.Deserialize <RenderMethodTemplate>(blamStream, bmRmt2Instance);
                }
                else
                {
                    return(false);
                }
            }

            List <string> bmMaps = new List <string>();
            List <string> bmArgs = new List <string>();

            // Get a simple list of H3 bitmaps and arguments names
            foreach (var a in bmRmt2.TextureParameterNames)
            {
                bmMaps.Add(BlamCache.StringTable.GetString(a.Name));
            }
            foreach (var a in bmRmt2.RealParameterNames)
            {
                bmArgs.Add(BlamCache.StringTable.GetString(a.Name));
            }

            string result = null;

            using (var cacheStream = Cache.OpenCacheRead())
            {
                ShaderMatcher Matcher = new ShaderMatcher();
                Matcher.Init(cacheStream, Cache, BlamCache);

                // Find a HO equivalent rmt2
                var edRmt2Instance = Matcher.FixRmt2Reference(cacheStream, bmRmt2Instance.Name, bmRmt2Instance, bmRmt2, bmMaps, bmArgs);
                result = edRmt2Instance.Name;
            }

            Console.WriteLine($"Blam template \"{bmRmt2Instance.Name}.rmt2\"\n matched with \"{result}.rmt2\".");
            return(true);
        }
        public GenerateRenderMethodTemplate(GameCacheContext cacheContext, CachedTagInstance tag, RenderMethodTemplate definition) :
            base(true,

                 "Generate",
                 "Compiles HLSL source file from scratch :D",
                 "Generate <shader_type> <parameters...>",
                 "Compiles HLSL source file from scratch :D")
        {
            CacheContext = cacheContext;
            Tag          = tag;
            Definition   = definition;
        }
        private static void ResetRMT2(RenderMethodTemplate Definition)
        {
            Definition.DrawModeBitmask = 0;
            Definition.DrawModes       = new List <RenderMethodTemplate.DrawMode>();

            Definition.ArgumentMappings = new List <RenderMethodTemplate.ArgumentMapping>();
            Definition.RegisterOffsets  = new List <RenderMethodTemplate.DrawModeRegisterOffsetBlock>();

            Definition.VectorArguments  = new List <RenderMethodTemplate.ShaderArgument>();
            Definition.IntegerArguments = new List <RenderMethodTemplate.ShaderArgument>();
            Definition.BooleanArguments = new List <RenderMethodTemplate.ShaderArgument>();
            Definition.SamplerArguments = new List <RenderMethodTemplate.ShaderArgument>();
        }
        private static void ResetRMT2(RenderMethodTemplate Definition)
        {
            Definition.ValidEntryPoints = 0;
            Definition.EntryPoints      = new List <RenderMethodTemplate.PackedInteger_10_6>();

            Definition.Parameters      = new List <RenderMethodTemplate.ParameterMapping>();
            Definition.ParameterTables = new List <RenderMethodTemplate.ParameterTable>();

            Definition.RealParameterNames    = new List <RenderMethodTemplate.ShaderArgument>();
            Definition.IntegerParameterNames = new List <RenderMethodTemplate.ShaderArgument>();
            Definition.BooleanParameterNames = new List <RenderMethodTemplate.ShaderArgument>();
            Definition.TextureParameterNames = new List <RenderMethodTemplate.ShaderArgument>();
        }
예제 #6
0
        public override bool Execute(List <string> args)
        {
            if (args.Count != 0)
            {
                return(false);
            }

            var shaderMaps = new Dictionary <StringID, TagInstance>();

            foreach (var property in Definition.ShaderProperties)
            {
                RenderMethodTemplate template = null;

                using (var cacheStream = Info.CacheFile.Open(FileMode.Open, FileAccess.Read))
                {
                    var context = new TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, property.Template);
                    template = Info.Deserializer.Deserialize <RenderMethodTemplate>(context);
                }

                for (var i = 0; i < template.ShaderMaps.Count; i++)
                {
                    var mapTemplate = template.ShaderMaps[i];

                    Console.Write(string.Format("Please enter the {0} index: ", Info.StringIDs.GetString(mapTemplate.Name)));
                    shaderMaps[mapTemplate.Name]  = ArgumentParser.ParseTagIndex(Info, Console.ReadLine());
                    property.ShaderMaps[i].Bitmap = shaderMaps[mapTemplate.Name];
                }
            }

            foreach (var import in Definition.ImportData)
            {
                if (shaderMaps.ContainsKey(import.MaterialType))
                {
                    import.Bitmap = shaderMaps[import.MaterialType];
                }
            }

            using (var cacheStream = Info.CacheFile.Open(FileMode.Open, FileAccess.ReadWrite))
            {
                var context = new TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, Tag);
                Info.Serializer.Serialize(context, Definition);
            }

            Console.WriteLine("Done!");

            return(true);
        }
예제 #7
0
        public override object Execute(List <string> args)
        {
            if (args.Count != 0)
            {
                return(false);
            }

            var shaderMaps = new Dictionary <StringId, CachedTag>();

            foreach (var property in Definition.ShaderProperties)
            {
                RenderMethodTemplate template = null;

                using (var cacheStream = Cache.OpenCacheRead())
                    template = Cache.Deserialize <RenderMethodTemplate>(cacheStream, property.Template);

                for (var i = 0; i < template.TextureParameterNames.Count; i++)
                {
                    var mapTemplate = template.TextureParameterNames[i];

                    Console.Write(string.Format("Please enter the {0} index: ", Cache.StringTable.GetString(mapTemplate.Name)));

                    if (!Cache.TryGetCachedTag(Console.ReadLine(), out var shaderMap))
                    {
                        Console.WriteLine($"ERROR: Invalid bitmap name, setting to null.");
                        shaderMaps[mapTemplate.Name] = null;
                    }

                    property.TextureConstants[i].Bitmap = shaderMaps[mapTemplate.Name];
                }
            }

            foreach (var import in Definition.ImportData)
            {
                if (shaderMaps.ContainsKey(import.Name))
                {
                    import.Bitmap = shaderMaps[import.Name];
                }
            }

            using (var cacheStream = Cache.OpenCacheReadWrite())
                Cache.Serialize(cacheStream, Tag, Definition);

            Console.WriteLine("Done!");

            return(true);
        }
예제 #8
0
 public static void FixRenderMethodTemplate(RenderMethodTemplate template)
 {
     FixDrawModeList(template.DrawModes);
     if (template.DrawModes.Count > 18)
     {
         template.DrawModes[18].UnknownBlock2Pointer = 0; // Disable z_only
     }
     // Rebuild the bitmask of valid draw modes
     template.DrawModeBitmask = 0;
     for (var i = 0; i < template.DrawModes.Count; i++)
     {
         if (template.DrawModes[i].UnknownBlock2Pointer != 0)
         {
             template.DrawModeBitmask |= (uint)(1 << i);
         }
     }
 }
예제 #9
0
        public override bool Execute(List <string> args)
        {
            foreach (var property in Definition.ShaderProperties)
            {
                RenderMethodTemplate template = null;

                using (var cacheStream = Info.CacheFile.Open(FileMode.Open, FileAccess.Read))
                {
                    var context = new TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, property.Template);
                    template = Info.Deserializer.Deserialize <RenderMethodTemplate>(context);
                }

                for (var i = 0; i < template.Arguments.Count; i++)
                {
                    Console.WriteLine("");

                    var argumentName  = Info.StringIDs.GetString(template.Arguments[i].Name);
                    var argumentValue = new Vector4(
                        property.Arguments[i].Arg1,
                        property.Arguments[i].Arg2,
                        property.Arguments[i].Arg3,
                        property.Arguments[i].Arg4);

                    Console.WriteLine(string.Format("{0}:", argumentName));

                    if (argumentName.EndsWith("_map"))
                    {
                        Console.WriteLine(string.Format("\tX Scale: {0}", argumentValue.X));
                        Console.WriteLine(string.Format("\tY Scale: {0}", argumentValue.Y));
                        Console.WriteLine(string.Format("\tX Offset: {0}", argumentValue.Z));
                        Console.WriteLine(string.Format("\tY Offset: {0}", argumentValue.W));
                    }
                    else
                    {
                        Console.WriteLine(string.Format("\tX: {0}", argumentValue.X));
                        Console.WriteLine(string.Format("\tY: {0}", argumentValue.Y));
                        Console.WriteLine(string.Format("\tZ: {0}", argumentValue.Z));
                        Console.WriteLine(string.Format("\tW: {0}", argumentValue.W));
                    }
                }
            }

            return(true);
        }
예제 #10
0
        private void FixRenderMethodTemplate(RenderMethodTemplate template)
        {
            FixDrawModeList(template.DrawModes);

            template.DrawModeBitmask = 0;
            if (template.DrawModes.Count > (int)RenderMethodTemplate.ShaderMode.Z_Only)
            {
                template.DrawModes[(int)RenderMethodTemplate.ShaderMode.Z_Only].Count = 0; // Use default z-only
            }

            // Rebuild the bitmask of valid draw modes
            for (var i = 0; i < template.DrawModes.Count; i++)
            {
                if (template.DrawModes[i].Count > 0)
                {
                    template.DrawModeBitmask |= (RenderMethodTemplate.ShaderModeBitmask)(1 << i);
                }
            }
        }
예제 #11
0
        public override object Execute(List <string> args)
        {
            foreach (var property in Definition.ShaderProperties)
            {
                RenderMethodTemplate template = null;

                using (var cacheStream = Cache.OpenCacheRead())
                    template = Cache.Deserialize <RenderMethodTemplate>(cacheStream, property.Template);

                for (var i = 0; i < template.RealParameterNames.Count; i++)
                {
                    Console.WriteLine("");

                    var argumentName  = Cache.StringTable.GetString(template.RealParameterNames[i].Name);
                    var argumentValue = new RealQuaternion(property.RealConstants[i].Values);

                    Console.WriteLine(string.Format("{0}:", argumentName));

                    if (argumentName.EndsWith("_map"))
                    {
                        Console.WriteLine(string.Format("\tX Scale: {0}", argumentValue.I));
                        Console.WriteLine(string.Format("\tY Scale: {0}", argumentValue.J));
                        Console.WriteLine(string.Format("\tX Offset: {0}", argumentValue.K));
                        Console.WriteLine(string.Format("\tY Offset: {0}", argumentValue.W));
                    }
                    else
                    {
                        Console.WriteLine(string.Format("\tX: {0}", argumentValue.I));
                        Console.WriteLine(string.Format("\tY: {0}", argumentValue.J));
                        Console.WriteLine(string.Format("\tZ: {0}", argumentValue.K));
                        Console.WriteLine(string.Format("\tW: {0}", argumentValue.W));
                    }
                }
            }

            return(true);
        }
예제 #12
0
        private bool GetRenderMethodTemplate(
            Mutex mutex,
            Stream stream,
            CachedTagInstance instance,
            ConcurrentBag <int> serilaizedRmt2,
            RenderMethod rm_shader_definition,
            out RenderMethodTemplate rmt2_definition,
            out TagSerializationContext rmt2_context,
            out string rmt2_name
            )
        {
            // get render method template
            rmt2_definition = null;
            rmt2_context    = null;
            rmt2_name       = null;
            {
                stream.Position = 0;
                rmt2_context    = new TagSerializationContext(stream, CacheContext, rm_shader_definition.ShaderProperties[0].Template);

                // Skip previously finished RMT2 tags
                if (serilaizedRmt2.Contains(rmt2_context.Tag.Index))
                {
                    mutex.ReleaseMutex();
                    return(true);
                }

                serilaizedRmt2.Add(rmt2_context.Tag.Index);

                rmt2_definition = CacheContext.Deserializer.Deserialize <RenderMethodTemplate>(rmt2_context);

                // console output
                rmt2_name = rmt2_context?.Tag?.Name ?? rmt2_context.Tag.Index.ToString("X");
                Console.WriteLine($"Regenerating {rmt2_name}");
            }

            return(false);
        }
예제 #13
0
        public override object Execute(List <string> args)
        {
            if (args.Count != 0)
            {
                return(false);
            }

            foreach (var property in Definition.ShaderProperties)
            {
                RenderMethodTemplate template = null;

                using (var cacheStream = Cache.OpenCacheRead())
                    template = Cache.Deserialize <RenderMethodTemplate>(cacheStream, property.Template);

                for (var i = 0; i < template.TextureParameterNames.Count; i++)
                {
                    var mapTemplate = template.TextureParameterNames[i];

                    Console.WriteLine($"Bitmap {i} ({Cache.StringTable.GetString(mapTemplate.Name)}): {property.TextureConstants[i].Bitmap.Group.Tag} 0x{property.TextureConstants[i].Bitmap.Index:X4}");
                }
            }

            return(true);
        }
예제 #14
0
 /// <summary>
 /// Modifies the input render method to make it work using the matchedTemplate
 /// </summary>
 private RenderMethod MatchRenderMethods(RenderMethod renderMethod, RenderMethodTemplate matchedTemplate, RenderMethodTemplate originalTemplate)
 {
     return(renderMethod);
 }
예제 #15
0
        private void GenerateCortanaRMT2Tag(List <int> options, Stream cacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, out CachedTagInstance rmt2Instance, out RenderMethodTemplate rmt2)
        {
            string template_name = $@"shaders\cortana_templates\_{string.Join("_", options)}";

            rmt2 = new RenderMethodTemplate();
            var rmt2_group = TagGroup.Instances[new TagStructureInfo(typeof(RenderMethodTemplate)).GroupTag];

            rmt2Instance = CacheContext.TagCache.AllocateTag(rmt2_group);
            var pixl      = new PixelShader();
            var pixlGroup = TagGroup.Instances[new TagStructureInfo(typeof(PixelShader)).GroupTag];
            CachedTagInstance newPIXLInstance = CacheContext.TagCache.AllocateTag(pixlGroup);
            var vtsh      = new VertexShader();
            var vtshGroup = TagGroup.Instances[new TagStructureInfo(typeof(VertexShader)).GroupTag];
            CachedTagInstance newVTSHInstance = CacheContext.TagCache.AllocateTag(vtshGroup);

            rmt2.PixelShader  = newPIXLInstance;
            rmt2.VertexShader = newVTSHInstance;

            rmt2.DrawModeBitmask |= RenderMethodTemplate.ShaderModeBitmask.Active_Camo;

            rmt2.VectorArguments  = new List <RenderMethodTemplate.ShaderArgument>();
            rmt2.IntegerArguments = new List <RenderMethodTemplate.ShaderArgument>();
            rmt2.BooleanArguments = new List <RenderMethodTemplate.ShaderArgument>();
            rmt2.SamplerArguments = new List <RenderMethodTemplate.ShaderArgument>();
            rmt2.ArgumentMappings = new List <RenderMethodTemplate.ArgumentMapping>();
            rmt2.RegisterOffsets  = new List <RenderMethodTemplate.DrawModeRegisterOffsetBlock>();

            pixl.Shaders   = new List <PixelShaderBlock>();
            pixl.DrawModes = new List <ShaderDrawMode>();
            rmt2.DrawModes = new List <RenderMethodTemplate.DrawMode>();
            foreach (RenderMethodTemplate.ShaderMode mode in Enum.GetValues(typeof(RenderMethodTemplate.ShaderMode)))
            {
                var pixelShaderDrawmode = new ShaderDrawMode();
                pixl.DrawModes.Add(pixelShaderDrawmode);
                var rmt2Drawmode = new RenderMethodTemplate.DrawMode();
                rmt2.DrawModes.Add(rmt2Drawmode);

                if (!HaloShaderGenerator.HaloShaderGenerator.IsShaderSuppored(
                        HaloShaderGenerator.Enums.ShaderType.Cortana,
                        (HaloShaderGenerator.Enums.ShaderStage)(int) mode
                        ))
                {
                    continue;
                }

                rmt2Drawmode.Offset = (ushort)rmt2.RegisterOffsets.Count();
                rmt2Drawmode.Count  = 1;


                var shader_gen_result = HaloShaderGenerator.HaloShaderGenerator.GenerateShaderCortana(HaloShaderGenerator.Enums.ShaderStage.Active_Camo);

                var pixelShaderBlock = GeneratePixelShaderBlock(CacheContext, shader_gen_result);
                pixelShaderDrawmode.Count  = 1;
                pixelShaderDrawmode.Offset = (byte)pixl.Shaders.Count;
                pixl.Shaders.Add(pixelShaderBlock);

                var registerOffsets = new RenderMethodTemplate.DrawModeRegisterOffsetBlock();
                rmt2.RegisterOffsets.Add(registerOffsets);

                registerOffsets.RenderMethodExternArguments_Offset = (ushort)rmt2.ArgumentMappings.Count;
                var srcRenderMethodExternArguments = shader_gen_result.Registers.Where(r => r.Scope == HaloShaderGenerator.ShaderGeneratorResult.ShaderRegister.ShaderRegisterScope.RenderMethodExtern_Arguments);
                foreach (var src_arg in srcRenderMethodExternArguments)
                {
                    var argument_mapping = new RenderMethodTemplate.ArgumentMapping
                    {
                        RegisterIndex = (ushort)src_arg.Register
                    };

                    foreach (var _enum in Enum.GetValues(typeof(RenderMethodTemplate.RenderMethodExtern)))
                    {
                        if (_enum.ToString().ToLower() == src_arg.Name)
                        {
                            argument_mapping.ArgumentIndex = (byte)_enum;
                            break;
                        }
                    }

                    rmt2.ArgumentMappings.Add(argument_mapping);
                    registerOffsets.RenderMethodExternArguments_Count++;
                }

                registerOffsets.SamplerArguments_Offset = (ushort)rmt2.ArgumentMappings.Count;
                var srcSamplerArguments = shader_gen_result.Registers.Where(r => r.Scope == HaloShaderGenerator.ShaderGeneratorResult.ShaderRegister.ShaderRegisterScope.TextureSampler_Arguments);
                foreach (var samplerRegister in srcSamplerArguments)
                {
                    var argumentMapping = new RenderMethodTemplate.ArgumentMapping
                    {
                        RegisterIndex = (ushort)samplerRegister.Register,
                        ArgumentIndex = (byte)registerOffsets.SamplerArguments_Count++
                    };

                    rmt2.ArgumentMappings.Add(argumentMapping);

                    var shaderArgument = new RenderMethodTemplate.ShaderArgument
                    {
                        Name = CacheContext.GetStringId(samplerRegister.Name)
                    };
                    rmt2.SamplerArguments.Add(shaderArgument);
                }

                registerOffsets.VectorArguments_Offset = (ushort)rmt2.ArgumentMappings.Count;
                // add xform args
                foreach (var samplerRegister in srcSamplerArguments)
                {
                    int index = GetArgumentIndex(samplerRegister.Name, rmt2.VectorArguments);
                    HaloShaderGenerator.ShaderGeneratorResult.ShaderRegister xformRegister = null;
                    foreach (var register in shader_gen_result.Registers)
                    {
                        if (register.Name == $"{samplerRegister.Name}_xform")
                        {
                            xformRegister = register;
                            break;
                        }
                    }
                    if (xformRegister == null)
                    {
                        continue;
                    }

                    var argumentMapping = new RenderMethodTemplate.ArgumentMapping
                    {
                        RegisterIndex = (ushort)xformRegister.Register,

                        ArgumentIndex = (byte)(index != -1 ? index : rmt2.VectorArguments.Count)
                    };
                    rmt2.ArgumentMappings.Add(argumentMapping);

                    var shaderArgument = new RenderMethodTemplate.ShaderArgument
                    {
                        Name = CacheContext.GetStringId(samplerRegister.Name)
                    };
                    rmt2.VectorArguments.Add(shaderArgument);

                    registerOffsets.VectorArguments_Count++;
                }

                var srcVectorArguments = shader_gen_result.Registers.Where(r => r.Scope == HaloShaderGenerator.ShaderGeneratorResult.ShaderRegister.ShaderRegisterScope.Vector_Arguments);
                foreach (var vectorRegister in srcVectorArguments)
                {
                    if (vectorRegister.IsXFormArgument)
                    {
                        continue;                                 // we've already added these
                    }
                    var argumentMapping = new RenderMethodTemplate.ArgumentMapping
                    {
                        RegisterIndex = (ushort)vectorRegister.Register,
                        ArgumentIndex = (byte)rmt2.VectorArguments.Count
                    };
                    rmt2.ArgumentMappings.Add(argumentMapping);

                    var shaderArgument = new RenderMethodTemplate.ShaderArgument
                    {
                        Name = CacheContext.GetStringId(vectorRegister.Name)
                    };
                    rmt2.VectorArguments.Add(shaderArgument);

                    registerOffsets.VectorArguments_Count++;
                }
            }

            newPIXLInstance.Name = template_name;
            CacheContext.Serialize(new TagSerializationContext(cacheStream, CacheContext, newPIXLInstance), pixl);
            newVTSHInstance.Name = template_name;
            CacheContext.Serialize(new TagSerializationContext(cacheStream, CacheContext, newVTSHInstance), vtsh);
            rmt2Instance.Name = template_name;
            CacheContext.Serialize(new TagSerializationContext(cacheStream, CacheContext, rmt2Instance), rmt2);

            CacheContext.SaveTagNames();
        }
예제 #16
0
        private void ConvertShaderCortana(ShaderCortana shaderCortana, Stream cacheStream, Dictionary <ResourceLocation, Stream> resourceStreams)
        {
            var render_method_option_indices = shaderCortana.RenderMethodDefinitionOptionIndices.Select(c => (int)c.OptionIndex).ToList();

            //CachedTagInstance newCortanaShaderInstance = CacheContext.TagCache.AllocateTag(TagGroup.Instances[groupTag]);
            //var ho_cortana_shader = (ShaderCortana)Activator.CreateInstance(typeof(ShaderCortana));

            var rmdf_instance = shaderCortana.BaseRenderMethod;
            var rmdf          = CacheContext.Deserialize <RenderMethodDefinition>(new TagSerializationContext(cacheStream, CacheContext, rmdf_instance));

            //var shader_instance = CacheContext.GetTag<Shader>(@"shaders\invalid");
            //var shader = CacheContext.Deserialize<Shader>(new TagSerializationContext(cacheStream, CacheContext, shader_instance));

            //ho_cortana_shader.ImportData = shader.ImportData;
            //ho_cortana_shader.ShaderProperties = shader.ShaderProperties;

            var shader_properties = shaderCortana.ShaderProperties[0];

            shader_properties.ShaderMaps          = new List <RenderMethod.ShaderProperty.ShaderMap>();
            shader_properties.Arguments           = new List <RenderMethod.ShaderProperty.Argument>();
            shader_properties.Unknown             = new List <RenderMethod.ShaderProperty.UnknownBlock1>();
            shader_properties.DrawModes           = new List <RenderMethodTemplate.DrawMode>();
            shader_properties.Unknown3            = new List <RenderMethod.ShaderProperty.UnknownBlock3>();
            shader_properties.ArgumentMappings    = new List <RenderMethod.ShaderProperty.ArgumentMapping>();
            shader_properties.AnimationProperties = new List <RenderMethod.AnimationPropertiesBlock>();

            List <RenderMethodOption.OptionBlock> templateOptions = new List <RenderMethodOption.OptionBlock>();

            for (int i = 0; i < rmdf.Methods.Count; i++)
            {
                var method = rmdf.Methods[i];
                int selected_option_index = render_method_option_indices.Count > i ? render_method_option_indices[i] : 0;
                var selected_option       = method.ShaderOptions[selected_option_index];

                var rmop_instance = selected_option.Option;
                if (rmop_instance != null)
                {
                    var rmop = CacheContext.Deserialize <RenderMethodOption>(new TagSerializationContext(cacheStream, CacheContext, rmop_instance));

                    templateOptions.AddRange(rmop.Options);
                }
            }

            RenderMethodTemplate rmt2 = null;

            if (shader_properties.Template == null)
            {
                GenerateCortanaRMT2Tag(
                    render_method_option_indices,
                    cacheStream,
                    resourceStreams,
                    out CachedTagInstance rmt2Instance,
                    out RenderMethodTemplate newRMT2);

                shader_properties.Template = rmt2Instance;
                rmt2 = newRMT2;
            }
            else
            {
                rmt2 = CacheContext.Deserialize <RenderMethodTemplate>(new TagSerializationContext(cacheStream, CacheContext, shader_properties.Template));
            }
            //shader_properties.DrawModes = rmt2.DrawModes;

            var shaderFunctions       = new List <RenderMethod.AnimationPropertiesBlock>();
            var shaderVectorArguments = new RenderMethod.ShaderProperty.Argument[rmt2.VectorArguments.Count];

            var shaderSamplerArguments = new RenderMethod.ShaderProperty.ShaderMap[rmt2.SamplerArguments.Count];

            for (int rmt2SamplerIndex = 0; rmt2SamplerIndex < rmt2.SamplerArguments.Count; rmt2SamplerIndex++)
            {
                var rmt2SamplerArgument = rmt2.SamplerArguments[rmt2SamplerIndex];
                var name     = rmt2SamplerArgument.Name;
                var name_str = CacheContext.GetString(name);
                var shaderSamplerArgument = new RenderMethod.ShaderProperty.ShaderMap();
                {
                    foreach (var importData in shaderCortana.ImportData)
                    {
                        if (importData.Type != RenderMethodOption.OptionBlock.OptionDataType.Sampler)
                        {
                            continue;
                        }
                        if (importData.Name.Index != name.Index)
                        {
                            continue;
                        }

                        if (importData.Bitmap != null)
                        {
                            shaderSamplerArgument.Bitmap = importData.Bitmap;
                            goto datafound;
                        }
                    }

                    foreach (var deafult_option in templateOptions)
                    {
                        if (deafult_option.Type != RenderMethodOption.OptionBlock.OptionDataType.Sampler)
                        {
                            continue;
                        }
                        if (deafult_option.Name.Index != name.Index)
                        {
                            continue;
                        }

                        shaderSamplerArgument.Bitmap = deafult_option.Bitmap;

                        goto datafound;
                    }

                    shaderSamplerArguments[rmt2SamplerIndex] = shaderSamplerArgument;

datafound:
                    if (shaderSamplerArgument.Bitmap == null)
                    {
                        Console.WriteLine($"WARNING: RMCT Conversion couldn't find a shader map for {name_str}");
                        shaderSamplerArgument.Bitmap = CacheContext.GetTag <Bitmap>(@"shaders\default_bitmaps\bitmaps\gray_50_percent");
                    }
                    shaderSamplerArguments[rmt2SamplerIndex] = shaderSamplerArgument;
                }

                {
                    int xform_index = GetExistingXFormArgumentIndex(name, rmt2.VectorArguments);
                    if (xform_index == -1)
                    {
                        Console.WriteLine($"WARNING: RMCT Conversion couldn't find a shader xform argument for {name_str}. Defaulting to 0");
                        xform_index = 0;
                    }
                    else
                    {
                        var shaderVectorArgument = ProcessArgument(rmt2SamplerArgument, shaderFunctions, templateOptions, shaderCortana);
                        shaderVectorArguments[xform_index] = shaderVectorArgument;
                    }
                    shaderSamplerArgument.XFormArgumentIndex = (sbyte)xform_index;
                }
            }
            shader_properties.ShaderMaps = shaderSamplerArguments.ToList();

            for (int rmt2ArgumentIndex = 0; rmt2ArgumentIndex < rmt2.VectorArguments.Count; rmt2ArgumentIndex++)
            {
                if (shaderVectorArguments[rmt2ArgumentIndex] != null)
                {
                    continue;
                }
                var vectorArgument = rmt2.VectorArguments[rmt2ArgumentIndex];

                var shaderArgument = ProcessArgument(vectorArgument, shaderFunctions, templateOptions, shaderCortana);
                shaderVectorArguments[rmt2ArgumentIndex] = shaderArgument;
            }
            shader_properties.Arguments           = shaderVectorArguments.ToList();
            shader_properties.AnimationProperties = shaderFunctions;

            if (shaderCortana.Material.Index == 0)
            {
                if (CacheContext.StringIdCache.Contains("default_material"))
                {
                    shaderCortana.Material = CacheContext.StringIdCache.GetStringId("default_material");
                }
            }

            //shader_cortana.Material = shader.Material;

            //ho_cortana_shader.BaseRenderMethod = shader.BaseRenderMethod;
            //newCortanaShaderInstance.Name = blamTag.Name;
            //CacheContext.Serialize(new TagSerializationContext(cacheStream, CacheContext, newCortanaShaderInstance), ho_cortana_shader);
            //CacheContext.SaveTagNames();
        }
예제 #17
0
        public CachedTag FixRmt2Reference(Stream cacheStream, string blamTagName, CachedTag blamRmt2Tag, RenderMethodTemplate blamRmt2Definition, List <string> bmMaps, List <string> bmArgs)
        {
            switch (blamTagName)
            {
            case @"levels\multi\snowbound\shaders\cov_grey_icy":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"ms30\shaders\shader_templates\_0_2_0_1_7_2_0_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_0_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_0_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
                { }
                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"));
                }
                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
                { }
                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"));
                }
                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_0_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>(@"ms30\shaders\shader_templates\_0_2_0_1_1_0_1_0_0_0_0_0"));
                }
                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
                { }
                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
                { }
                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
                { }
                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.TagTable)
                {
                    if (instance == null || !instance.IsInGroup("rmt2") || instance.Name == null)
                    {
                        continue;
                    }

                    var rmt2Name = instance.Name;

                    // ignore s3d rmt2s
                    if (rmt2Name.StartsWith("s3d"))
                    {
                        continue;
                    }

                    // check if rmt2 is from ms30
                    if (rmt2Name.StartsWith("ms30"))
                    {
                        rmt2Name = rmt2Name.Replace("ms30\\", "");
                        // skip over ms30 rmt2s
                        if (!UseMS30)
                        {
                            continue;
                        }
                    }

                    //match found
                    if (rmt2Name.StartsWith(blamRmt2Tag.Name))
                    {
                        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));
        }
예제 #18
0
        private RenderMethod FixAnimationProperties(Stream cacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, CacheFile blamCache, HaloOnlineCacheContext CacheContext, RenderMethod finalRm, RenderMethodTemplate edRmt2, RenderMethodTemplate bmRmt2, string blamTagName)
        {
            // finalRm is a H3 rendermethod with ported bitmaps,
            if (finalRm.ShaderProperties[0].AnimationProperties.Count == 0)
            {
                return(finalRm);
            }

            foreach (var properties in finalRm.ShaderProperties[0].AnimationProperties)
            {
                properties.InputName = ConvertStringId(properties.InputName);
                properties.RangeName = ConvertStringId(properties.RangeName);

                ConvertTagFunction(properties.Function);
            }

            var pixlTag = CacheContext.Deserialize(cacheStream, edRmt2.PixelShader);
            var edPixl  = (PixelShader)pixlTag;

            var blamContext = new CacheSerializationContext(ref BlamCache, blamCache.IndexItems.Find(x => x.ID == bmRmt2.PixelShader.Index));
            var bmPixl      = BlamCache.Deserializer.Deserialize <PixelShader>(blamContext);

            // Make a collection of drawmodes and their DrawModeItem's
            // DrawModeItem are has info about all registers modified by functions for each drawmode.

            var bmPixlParameters = new Dictionary <int, List <ArgumentMapping> >(); // key is shader index

            // pixl side
            // For each drawmode, find its shader, and get all that shader's parameter.
            // Each parameter has a registerIndex, a registerType, and a registerName.
            // We'll use this to know which function acts on what shader and which registers

            var RegistersList = new Dictionary <int, string>();

            foreach (var a in finalRm.ShaderProperties[0].ArgumentMappings)
            {
                if (!RegistersList.ContainsKey(a.RegisterIndex))
                {
                    RegistersList.Add(a.RegisterIndex, "");
                }
            }

            var DrawModeIndex = -1;

            foreach (var a in bmPixl.DrawModes)
            {
                DrawModeIndex++;

                bmPixlParameters.Add(DrawModeIndex, new List <ArgumentMapping>());

                if (a.Count == 0)
                {
                    continue;
                }

                foreach (var b in bmPixl.Shaders[a.Offset].XboxParameters)
                {
                    var ParameterName = BlamCache.Strings.GetItemByID(b.ParameterName.Index);

                    bmPixlParameters[DrawModeIndex].Add(new ArgumentMapping
                    {
                        ShaderIndex   = a.Offset,
                        ParameterName = ParameterName,
                        RegisterIndex = b.RegisterIndex,
                        RegisterType  = b.RegisterType
                    });
                }
            }

            // rm side
            var bmDrawmodesFunctions = new Dictionary <int, Unknown3Tagblock>(); // key is shader index

            DrawModeIndex = -1;
            foreach (var a in finalRm.ShaderProperties[0].DrawModes)
            {
                DrawModeIndex++;

                // These are not modes. This is an indireciton table of packed 10_6 shorts
                // from RMT2 ShaderDrawmodes to RegisterOffsets
                // register_offset = ShaderDrawmodes[current_drawmode].Offset
                var drawmodeRegisterOffset = (int)a.Offset;
                var drawmodeRegisterCount  = (int)a.Count;


                var ArgumentMappingsIndexSampler = (byte)finalRm.ShaderProperties[0].Unknown3[drawmodeRegisterOffset].DataHandleSampler;
                var ArgumentMappingsCountSampler = finalRm.ShaderProperties[0].Unknown3[drawmodeRegisterOffset].DataHandleSampler >> 8;
                var ArgumentMappingsIndexUnknown = (byte)finalRm.ShaderProperties[0].Unknown3[drawmodeRegisterOffset].DataHandleUnknown;
                var ArgumentMappingsCountUnknown = finalRm.ShaderProperties[0].Unknown3[drawmodeRegisterOffset].DataHandleUnknown >> 8;
                var ArgumentMappingsIndexVector  = (byte)finalRm.ShaderProperties[0].Unknown3[drawmodeRegisterOffset].DataHandleVector;
                var ArgumentMappingsCountVector  = finalRm.ShaderProperties[0].Unknown3[drawmodeRegisterOffset].DataHandleVector >> 8;
                var ArgumentMappings             = new List <ArgumentMapping>();

                for (int j = 0; j < ArgumentMappingsCountSampler / 4; j++)
                {
                    ArgumentMappings.Add(new ArgumentMapping
                    {
                        RegisterIndex = finalRm.ShaderProperties[0].ArgumentMappings[ArgumentMappingsIndexSampler + j].RegisterIndex,
                        ArgumentIndex = finalRm.ShaderProperties[0].ArgumentMappings[ArgumentMappingsIndexSampler + j].ArgumentIndex, // i don't think i can use it to match stuf
                        ArgumentMappingsTagblockIndex = ArgumentMappingsIndexSampler + j,
                        RegisterType = TagTool.Shaders.ShaderParameter.RType.Sampler,
                        ShaderIndex  = drawmodeRegisterOffset,
                        // WARNING i think drawmodes in rm aren't the same as in pixl, because rm drawmodes can point to a global shader .
                        // say rm.drawmodes[17]'s value is 13, pixl.drawmodes[17] would typically be 12
                    });
                }

                for (int j = 0; j < ArgumentMappingsCountUnknown / 4; j++)
                {
                    ArgumentMappings.Add(new ArgumentMapping
                    {
                        RegisterIndex = finalRm.ShaderProperties[0].ArgumentMappings[ArgumentMappingsIndexUnknown + j].RegisterIndex,
                        ArgumentIndex = finalRm.ShaderProperties[0].ArgumentMappings[ArgumentMappingsIndexUnknown + j].ArgumentIndex,
                        ArgumentMappingsTagblockIndex = ArgumentMappingsIndexUnknown + j,
                        RegisterType = TagTool.Shaders.ShaderParameter.RType.Vector,
                        ShaderIndex  = drawmodeRegisterOffset,
                        // it's something else, uses a global shader or some shit, one water shader pointed to a vtsh in rasg, but not in H3, maybe coincidence
                        // yeah guaranteed rmdf's glvs or rasg shaders
                    });
                }

                for (int j = 0; j < ArgumentMappingsCountVector / 4; j++)
                {
                    ArgumentMappings.Add(new ArgumentMapping
                    {
                        RegisterIndex = finalRm.ShaderProperties[0].ArgumentMappings[ArgumentMappingsIndexVector + j].RegisterIndex,
                        ArgumentIndex = finalRm.ShaderProperties[0].ArgumentMappings[ArgumentMappingsIndexVector + j].ArgumentIndex,
                        ArgumentMappingsTagblockIndex = ArgumentMappingsIndexVector + j,
                        RegisterType = TagTool.Shaders.ShaderParameter.RType.Vector,
                        ShaderIndex  = drawmodeRegisterOffset,
                    });
                }

                bmDrawmodesFunctions.Add(DrawModeIndex, new Unknown3Tagblock
                {
                    Unknown3Index = drawmodeRegisterOffset, // not shader index for rm and rmt2
                    Unknown3Count = drawmodeRegisterCount,  // should always be 4 for enabled drawmodes
                    ArgumentMappingsIndexSampler = ArgumentMappingsIndexSampler,
                    ArgumentMappingsCountSampler = ArgumentMappingsCountSampler,
                    ArgumentMappingsIndexUnknown = ArgumentMappingsIndexUnknown, // no clue what it's used for, global shaders? i know one of the drawmodes will use one or more shaders from glvs, no idea if always or based on something
                    ArgumentMappingsCountUnknown = ArgumentMappingsCountUnknown,
                    ArgumentMappingsIndexVector  = ArgumentMappingsIndexVector,
                    ArgumentMappingsCountVector  = ArgumentMappingsCountVector,
                    ArgumentMappings             = ArgumentMappings
                });
            }

            DrawModeIndex = -1;
            foreach (var a in bmDrawmodesFunctions)
            {
                DrawModeIndex++;
                if (a.Value.Unknown3Count == 0)
                {
                    continue;
                }

                foreach (var b in a.Value.ArgumentMappings)
                {
                    foreach (var c in bmPixlParameters[a.Key])
                    {
                        if (b.RegisterIndex == c.RegisterIndex && b.RegisterType == c.RegisterType)
                        {
                            b.ParameterName = c.ParameterName;
                            break;
                        }
                    }
                }
            }

            // // Now that we know which register is what for each drawmode, find its halo online equivalent register indexes based on register name.
            // // This is where it gets tricky because drawmodes count changed in HO.
            foreach (var a in bmDrawmodesFunctions)
            {
                if (a.Value.Unknown3Count == 0)
                {
                    continue;
                }

                foreach (var b in a.Value.ArgumentMappings)
                {
                    foreach (var c in edPixl.Shaders[edPixl.DrawModes[a.Key].Offset].PCParameters)
                    {
                        var ParameterName = CacheContext.StringIdCache.GetString(c.ParameterName);

                        if (ParameterName == b.ParameterName && b.RegisterType == c.RegisterType)
                        {
                            if (RegistersList[b.RegisterIndex] == "")
                            {
                                RegistersList[b.RegisterIndex] = $"{c.RegisterIndex}";
                            }
                            else
                            {
                                RegistersList[b.RegisterIndex] = $"{RegistersList[b.RegisterIndex]},{c.RegisterIndex}";
                            }

                            b.EDRegisterIndex = c.RegisterIndex;
                        }
                    }
                }
            }

            // DEBUG draw registers
            // DEBUG check for invalid registers
            foreach (var a in bmDrawmodesFunctions)
            {
                if (a.Value.Unknown3Count == 0)
                {
                    continue;
                }

                foreach (var b in a.Value.ArgumentMappings)
                {
                    finalRm.ShaderProperties[0].ArgumentMappings[b.ArgumentMappingsTagblockIndex].RegisterIndex = (short)b.EDRegisterIndex;
                }
            }

            // one final check
            // Gather all register indexes from pixl tag. Then check against all the converted register indexes.
            // It should detect registers that are invalid and would crash, but it does not verify if the register is valid.
            var validEDRegisters = new List <int>();

            foreach (var a in edPixl.Shaders)
            {
                foreach (var b in a.PCParameters)
                {
                    if (!validEDRegisters.Contains(b.RegisterIndex))
                    {
                        validEDRegisters.Add(b.RegisterIndex);
                    }
                }
            }

            foreach (var a in finalRm.ShaderProperties[0].ArgumentMappings)
            {
                if (!validEDRegisters.Contains((a.RegisterIndex)))
                {
                    // Display a warning
                    // Console.WriteLine($"INVALID REGISTERS IN TAG {blamTagName}!");

                    // Abort, disable functions
                    finalRm.ShaderProperties[0].Unknown             = new List <RenderMethod.ShaderProperty.UnknownBlock1>(); // no idea what it does, but it crashes sometimes if it's null. on Shrine, it's the shader loop effect
                    finalRm.ShaderProperties[0].AnimationProperties = new List <RenderMethod.AnimationPropertiesBlock>();
                    finalRm.ShaderProperties[0].ArgumentMappings    = new List <RenderMethod.ShaderProperty.ArgumentMapping>();
                    finalRm.ShaderProperties[0].Unknown3            = new List <RenderMethod.ShaderProperty.UnknownBlock3>();
                    foreach (var b in edRmt2.RegisterOffsets) // stops crashing for some shaders if the drawmodes count is still the same
                    {
                        finalRm.ShaderProperties[0].Unknown3.Add(new RenderMethod.ShaderProperty.UnknownBlock3());
                    }

                    return(finalRm);
                }
            }

            return(finalRm);
        }
예제 #19
0
        void _RegenerateShaders(RenderMethodTemplate rmt2, PixelShader pixl, int[] shader_args, string shader_type)
        {
            switch (shader_type)
            {
            case "cortana_templates":
            case "cortana_template":
            {
                RegenerateShader(
                    rmt2,
                    pixl,
                    shader_args,
                    ShaderType.Cortana,
                    ShaderStage.Active_Camo,
                    RenderMethodTemplate.ShaderModeBitmask.Active_Camo,
                    RenderMethodTemplate.ShaderMode.Active_Camo
                    );
            }
            break;


            case "shader_templates":
            case "shader_template":
            {
                //RegenerateShader(
                //    rmt2,
                //    pixl,
                //    shader_args,
                //    ShaderType.Shader,
                //    ShaderStage.Albedo,
                //    RenderMethodTemplate.ShaderModeBitmask.Albedo,
                //    RenderMethodTemplate.ShaderMode.Albedo
                //);

                //RegenerateShader(
                //    rmt2,
                //    pixl,
                //    shader_args,
                //    ShaderType.Shader,
                //    ShaderStage.Active_Camo,
                //    RenderMethodTemplate.ShaderModeBitmask.Active_Camo,
                //    RenderMethodTemplate.ShaderMode.Active_Camo
                //);

                RegenerateShader(
                    rmt2,
                    pixl,
                    shader_args,
                    ShaderType.Shader,
                    ShaderStage.Static_Prt_Ambient,
                    RenderMethodTemplate.ShaderModeBitmask.Static_Prt_Ambient,
                    RenderMethodTemplate.ShaderMode.Static_Prt_Ambient
                    );

                //RegenerateShader(
                //    rmt2,
                //    pixl,
                //    shader_args,
                //    ShaderType.Shader,
                //    ShaderStage.Static_Prt_Linear,
                //    RenderMethodTemplate.ShaderModeBitmask.Static_Prt_Linear,
                //    RenderMethodTemplate.ShaderMode.Static_Prt_Linear
                //);
                //RegenerateShader(
                //    rmt2,
                //    pixl,
                //    shader_args,
                //    ShaderType.Shader,
                //    ShaderStage.Static_Prt_Quadratic,
                //    RenderMethodTemplate.ShaderModeBitmask.Static_Prt_Quadratic,
                //    RenderMethodTemplate.ShaderMode.Static_Prt_Quadratic
                //);
            }
            break;

            default:
                break;
            }
        }
예제 #20
0
        bool RegenerateShader(
            RenderMethodTemplate rmt2,
            PixelShader pixl,
            int[] shader_args,
            ShaderType type,
            ShaderStage shaderstage,
            RenderMethodTemplate.ShaderModeBitmask bit,
            RenderMethodTemplate.ShaderMode mode
            )
        {
            MethodInfo method = null;

            switch (type)
            {
            case ShaderType.Shader:
                method = typeof(HaloShaderGenerator.HaloShaderGenerator).GetMethod("GenerateShader");
                break;

            case ShaderType.Cortana:
                method = typeof(HaloShaderGenerator.HaloShaderGenerator).GetMethod("GenerateShaderCortana");
                break;

            default:
                return(false);
            }
            if (method == null)
            {
                return(false);
            }

            //TODO: Rewrite this crazyness
            if ((rmt2.DrawModeBitmask | bit) != 0)
            {
                if (HaloShaderGenerator.HaloShaderGenerator.IsShaderSuppored(type, shaderstage))
                {
                    var GenerateShaderArgs = CreateArguments(method, shaderstage, shader_args);

                    //TODO: Remove this
                    switch (shaderstage)
                    {
                    case ShaderStage.Albedo:
                        Albedo albedo = GenerateShaderArgs.Where(x => x.GetType() == typeof(Albedo)).Cast <Albedo>().FirstOrDefault();
                        if (albedo > Albedo.Two_Detail_Black_Point)
                        {
                            return(false);                                            // saber territory
                        }
                        Bump_Mapping bumpmapping = GenerateShaderArgs.Where(x => x.GetType() == typeof(Bump_Mapping)).Cast <Bump_Mapping>().FirstOrDefault();
                        if (bumpmapping > Bump_Mapping.Detail)
                        {
                            return(false);                                       // saber territory
                        }
                        break;
                    }

                    var shaderGeneratorResult = method.Invoke(null, GenerateShaderArgs) as HaloShaderGenerator.ShaderGeneratorResult;

                    if (shaderGeneratorResult?.Bytecode == null)
                    {
                        return(false);
                    }

                    var offset = pixl.DrawModes[(int)mode].Offset;
                    var count  = pixl.DrawModes[(int)mode].Count;

                    var pixelShaderBlock = Porting.PortTagCommand.GeneratePixelShaderBlock(CacheContext, shaderGeneratorResult);
                    pixl.Shaders[offset] = pixelShaderBlock;

                    rmt2.DrawModeBitmask |= bit;

                    return(true);
                }
                // todo, disable it. but for now, we'll just keep the other shaders here
            }
            return(false);
        }
 public static void Populate(CommandContext commandContext, GameCacheContext cacheContext, CachedTagInstance tag, RenderMethodTemplate render_method_template)
 {
     commandContext.AddCommand(new GenerateRenderMethodTemplate(cacheContext, tag, render_method_template));
 }
예제 #22
0
        /// <summary>
        /// Find the closest template in the base cache to the input template.
        /// </summary>
        private CachedTag FindClosestTemplate(CachedTag sourceRmt2Tag, RenderMethodTemplate sourceRmt2)
        {
            Debug.Assert(IsInitialized);

            Rmt2Descriptor sourceRmt2Desc;

            if (!Rmt2Descriptor.TryParse(sourceRmt2Tag.Name, out sourceRmt2Desc))
            {
                throw new ArgumentException($"Invalid rmt2 name '{sourceRmt2Tag.Name}'", nameof(sourceRmt2Tag));
            }

            var relevantRmt2s = new List <Rmt2Pairing>();

            foreach (var rmt2Tag in BaseCache.TagCache.NonNull().Where(tag => tag.IsInGroup("rmt2")))
            {
                Rmt2Descriptor destRmt2Desc;
                if (!Rmt2Descriptor.TryParse(rmt2Tag.Name, out destRmt2Desc))
                {
                    continue;
                }

                // ignore ms30 templates if desired
                if (!UseMs30 && destRmt2Desc.IsMs30)
                {
                    continue;
                }

                // ignore templates that are not of the same type
                if (destRmt2Desc.Type != sourceRmt2Desc.Type)
                {
                    continue;
                }

                // match the options from the rmt2 tag names
                int commonOptions = 0;
                for (int i = 0; i < sourceRmt2Desc.Options.Length; i++)
                {
                    if (sourceRmt2Desc.Options[i] == destRmt2Desc.Options[i])
                    {
                        commonOptions++;
                    }
                }

                // if we found an exact match, return it
                if (commonOptions == sourceRmt2Desc.Options.Length)
                {
                    return(rmt2Tag);
                }

                // add it to the list to be considered
                relevantRmt2s.Add(new Rmt2Pairing()
                {
                    CommonOptions = commonOptions,
                    DestTag       = rmt2Tag,
                    SourceTag     = sourceRmt2Tag
                });
            }

            // if we've reached here, we haven't found an extract match.
            // now we need to consider other factors such as which options they have, which parameters are missing etc..
            // whatever can be used to narrow it down.
            foreach (var pairing in relevantRmt2s)
            {
                var rmt2 = GetTemplate(pairing.DestTag);
                pairing.RealParams    = MatchParameterBlocks(sourceRmt2.RealParameterNames, rmt2.RealParameterNames);
                pairing.IntParams     = MatchParameterBlocks(sourceRmt2.IntegerParameterNames, rmt2.IntegerParameterNames);
                pairing.BoolParams    = MatchParameterBlocks(sourceRmt2.BooleanParameterNames, rmt2.BooleanParameterNames);
                pairing.TextureParams = MatchParameterBlocks(sourceRmt2.TextureParameterNames, rmt2.TextureParameterNames);
            }

            // finally order by some criteria
            var ordered = relevantRmt2s
                          .OrderBy(x => x.CommonOptions);
            //.ThenByDescending(x => x.MissingFromDest);


            // return the best rmt2 or the default if one could not be found (only when a template type is not in the base cache)
            var bestRmt2 = ordered.LastOrDefault()?.DestTag;

            if (bestRmt2 == null)
            {
                return(BaseCache.GetTag(DefaultTemplate));
            }

            return(bestRmt2);
        }
예제 #23
0
        public CachedTag FindEquivalentRmt2(Stream cacheStream, CachedTag 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.TagCache.GetTag(d.rmt2TagIndex);

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

                string edType       = "";
                var    edRmdfValues = SplitRenderMethodTemplateName(dInstance.Name, ref edType);

                string bmType       = "";
                var    bmRmdfValues = SplitRenderMethodTemplateName(blamRmt2Tag.Name, ref bmType);

                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.TagCache.GetTag(edRmt2BestStatsSorted.Last().rmt2TagIndex));
        }
        public static CommandContext Create(CommandContext parent, GameCacheContext cacheContext, CachedTagInstance tag, RenderMethodTemplate render_method_template)
        {
            var groupName      = cacheContext.GetString(tag.Group.Name);
            var commandContext = new CommandContext(parent, string.Format("{0:X8}.{1}", tag.Index, groupName));

            Populate(commandContext, cacheContext, tag, render_method_template);

            return(commandContext);
        }
예제 #25
0
        public override object Execute(List <string> args)
        {
            if (args.Count < 2 || args.Count > 5)
            {
                return(false);
            }

            var argumentName = args[0];
            var values       = new List <float>();

            while (args.Count > 1)
            {
                if (!float.TryParse(args[1], out var value))
                {
                    throw new FormatException(args[1]);
                }

                values.Add(value);
                args.RemoveAt(1);
            }

            RenderMethodTemplate template = null;
            var properties = Definition.ShaderProperties[0];

            using (var cacheStream = CacheContext.OpenTagCacheRead())
                template = CacheContext.Deserialize <RenderMethodTemplate>(cacheStream, properties.Template);

            var argumentIndex = -1;

            for (var i = 0; i < template.VectorArguments.Count; i++)
            {
                if (CacheContext.GetString(template.VectorArguments[i].Name) == argumentName)
                {
                    argumentIndex = i;
                    break;
                }
            }

            if (argumentIndex < 0 || argumentIndex >= properties.Arguments.Count)
            {
                throw new KeyNotFoundException($"Invalid argument name: {argumentName}");
            }

            var argument = properties.Arguments[argumentIndex];

            for (var i = 0; i < argument.Values.Length; i++)
            {
                if (i < values.Count)
                {
                    argument.Values[i] = values[i];
                }
                else
                {
                    argument.Values[i] = 0.0f;
                }
            }

            var argumentValue = new RealQuaternion(argument.Values);

            Console.WriteLine();
            Console.WriteLine(string.Format("{0}:", argumentName));

            if (argumentName.EndsWith("_map"))
            {
                Console.WriteLine(string.Format("\tX Scale: {0}", argumentValue.I));
                Console.WriteLine(string.Format("\tY Scale: {0}", argumentValue.J));
                Console.WriteLine(string.Format("\tX Offset: {0}", argumentValue.K));
                Console.WriteLine(string.Format("\tY Offset: {0}", argumentValue.W));
            }
            else
            {
                Console.WriteLine(string.Format("\tX: {0}", argumentValue.I));
                Console.WriteLine(string.Format("\tY: {0}", argumentValue.J));
                Console.WriteLine(string.Format("\tZ: {0}", argumentValue.K));
                Console.WriteLine(string.Format("\tW: {0}", argumentValue.W));
            }

            return(true);
        }