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

            CacheBase.IndexItem item = null;

            Console.WriteLine("Verifying blam shader tag...");

            var shaderName = args[0];

            foreach (var tag in BlamCache.IndexItems)
            {
                if ((tag.ParentClass == "rm") && tag.Filename == shaderName)
                {
                    item = tag;
                    break;
                }
            }

            if (item == null)
            {
                Console.WriteLine("Blam shader tag does not exist: " + shaderName);
                return(false);
            }

            var renderMethod = DefinitionsManager.rmsh(BlamCache, item);

            var templateItem = BlamCache.IndexItems.Find(i =>
                                                         i.ID == renderMethod.Properties[0].TemplateTagID);

            var template = DefinitionsManager.rmt2(BlamCache, templateItem);

            for (var i = 0; i < template.UsageBlocks.Count; i++)
            {
                var bitmItem = BlamCache.IndexItems.Find(j =>
                                                         j.ID == renderMethod.Properties[0].ShaderMaps[i].BitmapTagID);
                Console.WriteLine(bitmItem);
            }

            return(true);
        }
Beispiel #2
0
        private void LoadShaders(bool spec)
        {
            var errMat = GetErrorMaterial();

            if (mode.Shaders.Count == 0)
            {
                var matGroup = new MaterialGroup();
                matGroup.Children.Add(errMat);
                shaders.Add(matGroup);
            }

            foreach (render_model.Shader s in mode.Shaders)
            {
                #region Skip Unused
                bool found = false;
                foreach (var sec in mode.ModelSections)
                {
                    foreach (var sub in sec.Submeshes)
                    {
                        if (sub.ShaderIndex == mode.Shaders.IndexOf(s))
                        {
                            found = true;
                            break;
                        }
                    }
                    if (found)
                    {
                        break;
                    }
                }

                if (!found)
                {
                    shaders.Add(null);
                    continue;
                }
                #endregion

                var matGroup = new MaterialGroup();

                try
                {
                    var rmshTag = cache.IndexItems.GetItemByID(s.tagID);
                    var rmsh    = DefinitionsManager.rmsh(cache, rmshTag);

                    int mapIndex = 0;
                    if (cache.Version >= DefinitionSet.Halo3Beta && cache.Version <= DefinitionSet.HaloReachRetail)
                    {
                        var rmt2Tag = cache.IndexItems.GetItemByID(rmsh.Properties[0].TemplateTagID);
                        var rmt2    = DefinitionsManager.rmt2(cache, rmt2Tag);

                        for (int i = 0; i < rmt2.UsageBlocks.Count; i++)
                        {
                            if (rmt2.UsageBlocks[i].Usage == "base_map")
                            {
                                mapIndex = i;
                                break;
                            }
                        }
                    }

                    var bitmTag = cache.IndexItems.GetItemByID(rmsh.Properties[0].ShaderMaps[mapIndex].BitmapTagID);
                    var image   = BitmapExtractor.GetBitmapByTag(cache, bitmTag, 0, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                    if (image == null)
                    {
                        matGroup.Children.Add(errMat);
                        shaders.Add(matGroup);
                        continue;
                    }

                    int   tileIndex = rmsh.Properties[0].ShaderMaps[mapIndex].TilingIndex;
                    float uTiling;
                    try { uTiling = rmsh.Properties[0].Tilings[tileIndex].UTiling; }
                    catch { uTiling = 1; }

                    float vTiling;
                    try { vTiling = rmsh.Properties[0].Tilings[tileIndex].VTiling; }
                    catch { vTiling = 1; }

                    MemoryStream stream = new MemoryStream();                                                        //PNG for transparency
                    image.Save(stream, (rmshTag.ClassCode == "rmsh" || rmshTag.ClassCode == "mat") ? ImageFormat.Bmp : ImageFormat.Bmp);

                    var diffuse = new BitmapImage();

                    diffuse.BeginInit();
                    diffuse.StreamSource = new MemoryStream(stream.ToArray());
                    diffuse.EndInit();

                    matGroup.Children.Add(new DiffuseMaterial()
                    {
                        Brush = new ImageBrush(diffuse)
                        {
                            ViewportUnits = BrushMappingMode.Absolute,
                            TileMode      = TileMode.Tile,
                            Viewport      = new System.Windows.Rect(0, 0, 1f / Math.Abs(uTiling), 1f / Math.Abs(vTiling))
                        }
                    });

                    if (spec && rmshTag.ClassCode == "rmsh")
                    {
                        stream = new MemoryStream();
                        image.Save(stream, ImageFormat.Png);

                        var specular = new BitmapImage();

                        specular.BeginInit();
                        specular.StreamSource = new MemoryStream(stream.ToArray());
                        specular.EndInit();

                        matGroup.Children.Add(new SpecularMaterial()
                        {
                            SpecularPower = 10,
                            Brush         = new ImageBrush(specular)
                            {
                                ViewportUnits = BrushMappingMode.Absolute,
                                TileMode      = TileMode.Tile,
                                Viewport      = new System.Windows.Rect(0, 0, 1f / Math.Abs(uTiling), 1f / Math.Abs(vTiling))
                            }
                        });
                    }

                    shaders.Add(matGroup);
                }
                catch
                {
                    matGroup.Children.Add(errMat);
                    shaders.Add(matGroup);
                }
            }
        }
        public override bool Execute(List <string> args)
        {
            if (args.Count != 1)
            {
                return(false);
            }

            //
            // Verify and load the blam shader
            //

            var shaderName = args[0];

            CacheBase.IndexItem item = null;

            Console.WriteLine("Verifying blam shader tag...");

            foreach (var tag in BlamCache.IndexItems)
            {
                if ((tag.ParentClass == "rm") && tag.Filename == shaderName)
                {
                    item = tag;
                    break;
                }
            }

            if (item == null)
            {
                Console.WriteLine("Blam shader tag does not exist: " + shaderName);
                return(false);
            }

            var renderMethod = DefinitionsManager.rmsh(BlamCache, item);

            var templateItem = BlamCache.IndexItems.Find(i =>
                                                         i.ID == renderMethod.Properties[0].TemplateTagID);

            var template = DefinitionsManager.rmt2(BlamCache, templateItem);

            //
            // Determine the blam shader's base bitmap
            //

            var bitmapIndex   = -1;
            var bitmapArgName = "";

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

                if (entry.Usage.StartsWith("base_map") ||
                    entry.Usage.StartsWith("diffuse_map") ||
                    entry.Usage == "foam_texture")
                {
                    bitmapIndex   = i;
                    bitmapArgName = entry.Usage;
                    break;
                }
            }

            //
            // Load and decode the blam shader's base bitmap
            //

            var bitmItem = BlamCache.IndexItems.Find(i =>
                                                     i.ID == renderMethod.Properties[0].ShaderMaps[bitmapIndex].BitmapTagID);

            var bitm   = DefinitionsManager.bitm(BlamCache, bitmItem);
            var submap = bitm.Bitmaps[0];

            byte[] raw;

            if (BlamCache.Version <= DefinitionSet.Halo2Vista)
            {
                raw = BlamCache.GetRawFromID(submap.PixelsOffset, submap.RawSize);
            }
            else
            {
                if (bitm.RawChunkBs.Count > 0)
                {
                    int    rawID  = bitm.RawChunkBs[submap.InterleavedIndex].RawID;
                    byte[] buffer = BlamCache.GetRawFromID(rawID);
                    raw = new byte[submap.RawSize];
                    Array.Copy(buffer, submap.Index2 * submap.RawSize, raw, 0, submap.RawSize);
                }
                else
                {
                    int rawID = bitm.RawChunkAs[0].RawID;
                    raw = BlamCache.GetRawFromID(rawID, submap.RawSize);
                }
            }

            var vHeight = submap.VirtualHeight;
            var vWidth  = submap.VirtualWidth;

            var ms = new MemoryStream();
            var bw = new BinaryWriter(ms);

            if (submap.Flags.Values[3])
            {
                raw = DXTDecoder.ConvertToLinearTexture(raw, vWidth, vHeight, submap.Format);
            }

            if (submap.Format != BitmapFormat.A8R8G8B8)
            {
                for (int i = 0; i < raw.Length; i += 2)
                {
                    Array.Reverse(raw, i, 2);
                }
            }
            else
            {
                for (int i = 0; i < (raw.Length); i += 4)
                {
                    Array.Reverse(raw, i, 4);
                }
            }

            new DDS(submap).Write(bw);
            bw.Write(raw);

            raw = ms.ToArray();

            bw.Close();
            bw.Dispose();

            //
            // ElDorado Serialization
            //

            using (var cacheStream = Info.CacheFile.Open(FileMode.Open, FileAccess.ReadWrite))
            {
                //
                // Create the new eldorado bitmap
                //

                var resourceManager = new ResourceDataManager();
                resourceManager.LoadCachesFromDirectory(Info.CacheFile.DirectoryName);

                var newBitm = Info.Cache.DuplicateTag(cacheStream, Info.Cache.Tags[0x101F]);

                var bitmap = new TagDefinitions.Bitmap
                {
                    Flags     = TagDefinitions.Bitmap.RuntimeFlags.UseResource,
                    Sequences = new List <TagDefinitions.Bitmap.Sequence>
                    {
                        new TagDefinitions.Bitmap.Sequence
                        {
                            Name             = "",
                            FirstBitmapIndex = 0,
                            BitmapCount      = 1
                        }
                    },
                    Images = new List <TagDefinitions.Bitmap.Image>
                    {
                        new TagDefinitions.Bitmap.Image
                        {
                            Signature = new Tag("bitm").Value,
                            Unknown28 = -1
                        }
                    },
                    Resources = new List <TagDefinitions.Bitmap.BitmapResource>
                    {
                        new TagDefinitions.Bitmap.BitmapResource()
                    }
                };

                using (var imageStream = new MemoryStream(raw))
                {
                    var injector = new BitmapDdsInjector(resourceManager);
                    imageStream.Seek(0, SeekOrigin.Begin);
                    injector.InjectDds(Info.Serializer, Info.Deserializer, bitmap, 0, imageStream);
                }

                var context = new TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, newBitm);
                Info.Serializer.Serialize(context, bitmap);

                //
                // Create the new eldorado shader
                //

                var newRmsh = Info.Cache.DuplicateTag(cacheStream, Info.Cache.Tags[0x331A]);
                context = new TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, newRmsh);
                var shader = Info.Deserializer.Deserialize <TagDefinitions.Shader>(context);

                shader.ShaderProperties[0].ShaderMaps[0].Bitmap = newBitm;

                Info.Serializer.Serialize(context, shader);

                Console.WriteLine("Done! New shader tag is 0x" + newRmsh.Index.ToString("X8"));
            }

            return(true);
        }