Example #1
0
        /// <summary>
        /// Gets the redengine texture format from the compression method
        /// Used when creating a dds from an xbm
        /// TODO: TEST THIS!!!
        /// </summary>
        /// <param name="compression"></param>
        /// <returns></returns>
        public static EFormat GetEFormatFromCompression(ETextureCompression compression)
        {
            switch (compression)
            {
            // missing:  0xFD
            // missing:  0x0    //EFormat.R8G8B8A8_UNORM
            case ETextureCompression.TCM_None:
                return(EFormat.R8G8B8A8_UNORM);


            //0x07 // exception: characters\models\animals\goose\model\t_01__goose_d01.xbm has 0x07 but TCM_DXTAlpha
            case ETextureCompression.TCM_DXTNoAlpha:
            case ETextureCompression.TCM_Normals:
                return(EFormat.BC1_UNORM);

            //0x08 // exception: characters\models\animals\goose\model\t_01__goose_d01.xbm has 0x07 but TCM_DXTAlpha
            case ETextureCompression.TCM_DXTAlpha:
            case ETextureCompression.TCM_NormalsHigh:
            case ETextureCompression.TCM_NormalsGloss:
                return(EFormat.BC3_UNORM);


            case ETextureCompression.TCM_QualityColor:
                return(EFormat.BC7_UNORM);    //0x0A

            // missing:  0x0D   //EFormat.BC2_UNORM // used for not imported dds files in texturecache therefore will never come up here

            case ETextureCompression.TCM_QualityR:
                return(EFormat.BC4_UNORM);    //0x0E

            case ETextureCompression.TCM_QualityRG:
                return(EFormat.BC5_UNORM);               //0x0F

            case ETextureCompression.TCM_DXTAlphaLinear: // unused
            case ETextureCompression.TCM_RGBE:           // unused
            default:
                throw new NotImplementedException();
            }
        }
Example #2
0
        /// <summary>
        /// Generate DDSMetadata from a Redengine CBitmapTexture
        /// </summary>
        /// <param name="xbm"></param>
        /// <returns></returns>
        private static DDSMetadata GetDDSMetadata(CBitmapTexture xbm)
        {
            int residentMipIndex = xbm.ResidentMipIndex?.val ?? 0;

            int mipcount = xbm.Mipdata.elements.Count - residentMipIndex;

            uint width  = xbm.Mipdata.elements[residentMipIndex].Width.val;
            uint height = xbm.Mipdata.elements[residentMipIndex].Height.val;

            ETextureCompression compression = xbm.Compression.WrappedEnum;

            var ddsformat = ImageUtility.GetEFormatFromCompression(compression);


            // TODO: TEST THIS
            if (ddsformat == EFormat.R8G8B8A8_UNORM)
            {
                ETextureRawFormat format = xbm.Format.WrappedEnum;
                switch (format)
                {
                case ETextureRawFormat.TRF_Grayscale:       // only this is ever used
                    break;

                case ETextureRawFormat.TRF_TrueColor:       // this is set if format is NULL
                case ETextureRawFormat.TRF_HDR:
                case ETextureRawFormat.TRF_AlphaGrayscale:
                case ETextureRawFormat.TRF_HDRGrayscale:
                default:
                    ddsformat = EFormat.R8G8B8A8_UNORM;
                    //throw new Exception("Invalid texture format type! [" + format + "]");
                    break;
                }
            }

            return(new DDSMetadata(width, height, (uint)mipcount, ddsformat));
        }
Example #3
0
        /// <summary>
        ///  Gets the DXGI format for CP77 dds buffers from a given ETextureCompression and ETextureRawFormat
        /// </summary>
        /// <param name="compression"></param>
        /// <param name="rawFormat"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public static EFormat GetDXGIFormat(ETextureCompression compression, ETextureRawFormat rawFormat)
        {
            switch (compression)
            {
            case ETextureCompression.TCM_QualityR:
                return(EFormat.BC4_UNORM);

            case ETextureCompression.TCM_QualityRG:
            case ETextureCompression.TCM_Normalmap:
                return(EFormat.BC5_UNORM);

            case ETextureCompression.TCM_QualityColor:
                return(EFormat.BC7_UNORM);

            case ETextureCompression.TCM_DXTNoAlpha:
            case ETextureCompression.TCM_Normals_DEPRECATED:
                return(EFormat.BC1_UNORM);

            case ETextureCompression.TCM_DXTAlphaLinear:
            case ETextureCompression.TCM_DXTAlpha:
                return(EFormat.BC3_UNORM);

            case ETextureCompression.TCM_None:
            {
                switch (rawFormat)
                {
                case ETextureRawFormat.TRF_Invalid:
                case ETextureRawFormat.TRF_TrueColor:
                    return(EFormat.R8G8B8A8_UNORM);

                case ETextureRawFormat.TRF_DeepColor:
                    return(EFormat.R10G10B10A2_UNORM);

                case ETextureRawFormat.TRF_HDRFloat:
                    return(EFormat.R32G32B32A32_FLOAT);

                case ETextureRawFormat.TRF_HDRHalf:
                    return(EFormat.R16G16B16A16_FLOAT);

                case ETextureRawFormat.TRF_HDRFloatGrayscale:
                    return(EFormat.R16_FLOAT);

                case ETextureRawFormat.TRF_R8G8:
                    return(EFormat.R8G8_UNORM);

                case ETextureRawFormat.TRF_Grayscale:
                    return(EFormat.R8_UINT);

                case ETextureRawFormat.TRF_AlphaGrayscale:
                    return(EFormat.A8_UNORM);

                case ETextureRawFormat.TRF_Grayscale_Font:
                    throw new NotImplementedException();

                case ETextureRawFormat.TRF_R32UI:
                    //return EFormat.R32_UINT;
                    throw new NotImplementedException();

                default:
                    throw new ArgumentOutOfRangeException(nameof(rawFormat), rawFormat, null);
                }
            }

            case ETextureCompression.TCM_RGBE:
            case ETextureCompression.TCM_Normals:
            case ETextureCompression.TCM_NormalsHigh_DEPRECATED:
            case ETextureCompression.TCM_NormalsHigh:
            case ETextureCompression.TCM_NormalsGloss_DEPRECATED:
            case ETextureCompression.TCM_NormalsGloss:
            case ETextureCompression.TCM_TileMap:
            case ETextureCompression.TCM_HalfHDR_Unsigned:
            case ETextureCompression.TCM_HalfHDR:
            case ETextureCompression.TCM_HalfHDR_Signed:
            case ETextureCompression.TCM_Max:
                throw new NotImplementedException();

            default:
                throw new ArgumentOutOfRangeException(nameof(compression), compression, null);
            }
        }
Example #4
0
        private static DDSMetadata Xbm2Ddsheader(CBitmapTexture xbm)
        {
            try
            {
                int residentMipIndex = xbm.GetVariableByName("ResidentMipIndex") == null ? 0 : (int)((CUInt8)xbm.GetVariableByName("ResidentMipIndex")).val;

                int mipcount;
                // handle cooked xbms
                if (xbm.GetVariableByName("SourceData") == null)
                {
                    mipcount = xbm.Mipdata.elements.Count - residentMipIndex;
                }
                // handle imported xbms
                else
                {
                    mipcount = 0;
                }

                uint width  = xbm.Mipdata.elements[residentMipIndex].Width.val;
                uint height = xbm.Mipdata.elements[residentMipIndex].Height.val;

                var ecompression = (CName)xbm.GetVariableByName("compression");
                ETextureCompression compression = (ETextureCompression)Enum.Parse(typeof(ETextureCompression), ecompression.Value);
                var eformat = (CName)xbm.GetVariableByName("format");
                ETextureRawFormat format = ETextureRawFormat.TRF_TrueColor;
                if (eformat != null)
                {
                    format = (ETextureRawFormat)Enum.Parse(typeof(ETextureRawFormat), eformat.Value);
                }



                var ddsformat = ETextureFormat.TEXFMT_R8G8B8A8;
                switch (compression)
                {
                case ETextureCompression.TCM_DXTNoAlpha:
                    ddsformat = ETextureFormat.TEXFMT_BC1;
                    break;

                case ETextureCompression.TCM_DXTAlpha:
                    ddsformat = ETextureFormat.TEXFMT_BC3;
                    break;

                case ETextureCompression.TCM_Normals:
                    ddsformat = ETextureFormat.TEXFMT_BC1;
                    break;

                case ETextureCompression.TCM_NormalsHigh:
                    ddsformat = ETextureFormat.TEXFMT_BC3;
                    break;

                case ETextureCompression.TCM_NormalsGloss:
                    ddsformat = ETextureFormat.TEXFMT_BC3;
                    break;

                case ETextureCompression.TCM_QualityR:
                    ddsformat = ETextureFormat.TEXFMT_BC4;
                    break;

                case ETextureCompression.TCM_QualityRG:
                    ddsformat = ETextureFormat.TEXFMT_BC5;
                    break;

                case ETextureCompression.TCM_QualityColor:
                    ddsformat = ETextureFormat.TEXFMT_BC3;
                    break;

                case ETextureCompression.TCM_DXTAlphaLinear:
                case ETextureCompression.TCM_RGBE:
                case ETextureCompression.TCM_None:
                    switch (format)
                    {
                    case ETextureRawFormat.TRF_TrueColor:
                        ddsformat = ETextureFormat.TEXFMT_R8G8B8A8;
                        break;

                    case ETextureRawFormat.TRF_Grayscale:
                        break;

                    case ETextureRawFormat.TRF_HDR:
                    case ETextureRawFormat.TRF_AlphaGrayscale:
                    case ETextureRawFormat.TRF_HDRGrayscale:
                    default:
                        throw new Exception("Invalid compression type! [" + compression + "]");
                    }
                    break;

                default:
                    throw new Exception("Invalid compression type! [" + compression + "]");
                }

                return(new DDSMetadata(width, height, (uint)mipcount, ddsformat));
            }
            catch (Exception e)
            {
                //string message = e.Message;
                //string caption = "Error!";
                //MessageBoxButtons buttons = MessageBoxButtons.OK;
                //MessageBox.Show(message, caption, buttons);
                throw e;
            }
        }
Example #5
0
        private static async Task <int> DumpDDSInfo(DumpDDSOptions options)
        {
            var    dt     = DateTime.Now;
            string idx    = RED.CRC32.Crc32Algorithm.Compute(Encoding.ASCII.GetBytes($"{dt.Year}{dt.Month}{dt.Day}{dt.Hour}{dt.Minute}{dt.Second}")).ToString();
            var    outDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "DDSTest", $"ExtractedFiles_{idx}");

            using (var pb = new ProgressBar())
            {
                if (!Directory.Exists(outDir))
                {
                    Directory.CreateDirectory(outDir);
                }
                var txc = new TextureManager();
                //using (var p11 = pb.Progress.Fork(0.25, "Loading TextureManager"))
                {
                    txc.LoadAll("C:\\Steam\\steamapps\\common\\The Witcher 3\\bin\\x64");
                }
                System.Console.WriteLine($"Loaded TextureManager");

                //combined bundle dump
                // load xbm bundle infos
                var bundlexbmDict = new Dictionary <uint, XBMBundleInfo>();
                var mc            = new BundleManager();
                //using (var p12 = pb.Progress.Fork(0.25, "Loading BundleManager"))
                {
                    mc.LoadAll("C:\\Steam\\steamapps\\common\\The Witcher 3\\bin\\x64");
                }

                System.Console.WriteLine($"Loaded BundleManager");


                //using (var p2 = pb.Progress.Fork(0.5, "Loading Bundle Info"))
                using (var p2 = pb.Progress.Fork(0.5, "Bundle Info"))
                {
                    var filesb = mc.FileList.Where(x => x.Name.EndsWith("xbm")).ToList();
                    for (int i = 0; i < filesb.Count; i++)
                    {
                        var f = filesb[i];
                        try
                        {
                            var buff = new byte[f.Size];
                            using (var s = new MemoryStream())
                            {
                                f.Extract(s);

                                using (var ms = new MemoryStream(s.ToArray()))
                                    using (var br = new BinaryReader(ms))
                                    {
                                        var crw = new CR2WFile();
                                        crw.Read(br);

                                        foreach (var c in crw.chunks)
                                        {
                                            if (c.data is CBitmapTexture)
                                            {
                                                var x = c.data as CBitmapTexture;

                                                if (!bundlexbmDict.ContainsKey(((CUInt32)x.GetVariableByName("textureCacheKey")).val))
                                                {
                                                    var ecompression = (CName)x.GetVariableByName("compression");
                                                    ETextureCompression compression = (ETextureCompression)Enum.Parse(typeof(ETextureCompression), ecompression.Value);
                                                    var eformat = (CName)x.GetVariableByName("format");
                                                    ETextureRawFormat format = (ETextureRawFormat)Enum.Parse(typeof(ETextureRawFormat), eformat.Value);

                                                    bundlexbmDict.Add(((CUInt32)x.GetVariableByName("textureCacheKey")).val, new XBMBundleInfo()
                                                    {
                                                        Name         = f.Name,
                                                        Width        = (CUInt32)x.GetVariableByName("width") == null ? 0 : ((CUInt32)x.GetVariableByName("width")).val,
                                                        Height       = (CUInt32)x.GetVariableByName("width") == null ? 0 : ((CUInt32)x.GetVariableByName("height")).val,
                                                        Format       = format,
                                                        Compression  = compression,
                                                        TextureGroup = (CName)x.GetVariableByName("textureGroup") == null ? "" : ((CName)x.GetVariableByName("textureGroup")).Value,
                                                    }
                                                                      );
                                                }
                                                else
                                                {
                                                }
                                            }
                                        }
                                    }
                            }
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
                        p2.Report(i / (double)filesb.Count, $"Loading bundle entries: {i}/{filesb.Count}");
                    }
                }
                System.Console.WriteLine($"Loaded {bundlexbmDict.Values.Count} Bundle Entries");

                using (var p3 = pb.Progress.Fork(0.5, "Cache Info"))
                {
                    // Dump texture cache infos
                    using (StreamWriter writer = File.CreateText(Path.Combine(outDir, $"__ddsdump_{idx}.txt")))
                    {
                        string head = "Format1\t" +
                                      "Format2\t" +
                                      "BPP\t" +
                                      "Width\t" +
                                      "Height\t" +
                                      "Size\t" +
                                      "Mips\t" +
                                      "Slices\t" +
                                      "Cube\t" +
                                      "Unk1\t" +
                                      "Hash\t" +
                                      "Name\t";
                        head += "XBMFormat\t" +
                                "XBMCompression\t" +
                                "XBMTExtureGroup\t"
                        ;
                        writer.WriteLine(head);

                        //string ext = "xbm";
                        //var files = txc.FileList.Where(x => x.Name.EndsWith(ext)).ToList();
                        var files = txc.FileList;
                        for (int j = 0; j < files.Count; j++)
                        {
                            IWitcherFile     f = files[j];
                            TextureCacheItem x = f as TextureCacheItem;

                            string info = $"{x.Type1}/{x.Type1:X2}\t" +
                                          $"{x.Type2}/{x.Type2:X2}\t" +
                                          $"{x.BaseAlignment}\t" +
                                          $"{x.BaseWidth}\t" +
                                          $"{x.BaseHeight}\t" +
                                          $"{x.Size}\t" +
                                          $"{x.Mipcount}\t" +
                                          $"{x.SliceCount}\t" +
                                          $"{x.IsCube:X2}\t" +
                                          $"{x.Unk1}/{x.Unk1:X2}\t" +
                                          $"{x.Hash}\t" +
                                          $"{x.Name}\t"
                            ;

                            //info += "<";
                            //foreach (var y in x.MipMapInfo)
                            //{
                            //    info += $"<{y.Item1},{y.Item2}>";
                            //}
                            //info += ">";

                            if (bundlexbmDict.ContainsKey(x.Hash))
                            {
                                XBMBundleInfo bundleinfo = bundlexbmDict[x.Hash];
                                info +=
                                    //$"{bundleinfo.Width}\t" +
                                    //$"{bundleinfo.Height}\t" +
                                    $"{bundleinfo.Format}\t" +
                                    $"{bundleinfo.Compression}\t" +
                                    $"{bundleinfo.TextureGroup}\t"
                                ;
                            }
                            else
                            {
                            }



                            //System.Console.WriteLine(info);
                            writer.WriteLine(info);
                            p3.Report(j / (double)files.Count, $"Dumping cache entries: {j}/{files.Count}");
                        }
                        System.Console.WriteLine($"Finished dumping {files.Count} texture cache infos.\r\n");
                    }
                }
            }
            System.Console.WriteLine($"Finished.\r\n");
            System.Console.ReadLine();

            return(1);
        }