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); }
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>(); }
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); }
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); }
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); } } }
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); }
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); } } }
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); }
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); }
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); }
/// <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); }
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(); }
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(); }
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)); }
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); }
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; } }
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)); }
/// <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); }
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); }
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); }