Esempio n. 1
0
            public void Write(Stream stream)
            {
                using (BinaryWriter writer = new BinaryWriter(stream)) {
                    FindLogic.Combo.MaterialDataAsset materialDataInfo = Info.m_materialData[MaterialInfo.m_materialDataGUID];
                    writer.Write(VersionMajor);
                    writer.Write(VersionMinor);
                    if (materialDataInfo.m_textureMap != null)
                    {
                        writer.Write(materialDataInfo.m_textureMap.LongCount());
                    }
                    else
                    {
                        writer.Write(0L);
                    }

                    writer.Write((uint)OWMatType.Material);
                    writer.Write(teResourceGUID.Index(MaterialInfo.m_shaderSourceGUID));
                    writer.Write(MaterialInfo.m_materialIDs.Count);
                    foreach (ulong id in MaterialInfo.m_materialIDs)
                    {
                        writer.Write(id);
                    }

                    if (materialDataInfo.m_textureMap != null)
                    {
                        foreach (KeyValuePair <ulong, uint> texture in materialDataInfo.m_textureMap)
                        {
                            FindLogic.Combo.TextureAsset textureInfo = Info.m_textures[texture.Key];
                            if (stream is FileStream fs)
                            {
                                writer.Write(Combo.GetScratchRelative(textureInfo.m_GUID, Path.GetDirectoryName(fs.Name), $@"..\Textures\{textureInfo.GetNameIndex()}.dds"));
                            }
                            else
                            {
                                writer.Write($@"..\Textures\{textureInfo.GetNameIndex()}.dds");
                            }

                            writer.Write(texture.Value);
                        }
                    }
                }
            }
Esempio n. 2
0
        private static async Task SaveTextureTask(ICLIFlags flags, string path, SaveContext info, ulong textureGUID, string name = null)
        {
            bool   convertTextures         = true;
            string convertType             = "tif";
            string multiSurfaceConvertType = "tif";
            bool   createMultiSurfaceSheet = false;
            bool   lossless = false;
            int    maxMips  = 1;

            if (flags is ExtractFlags extractFlags)
            {
                if (extractFlags.SkipTextures)
                {
                    return;
                }
                createMultiSurfaceSheet = extractFlags.SheetMultiSurface;
                convertTextures         = !extractFlags.RawTextures && !extractFlags.Raw;
                convertType             = extractFlags.ConvertTexturesType.ToLowerInvariant();
                lossless = extractFlags.ConvertTexturesLossless;

                multiSurfaceConvertType = convertType;
                if (extractFlags.ForceDDSMultiSurface)
                {
                    multiSurfaceConvertType = "dds";
                }

                if (convertType == "dds" && extractFlags.SaveMips)
                {
                    maxMips = 0xF;
                }
            }

            if (!path.EndsWith(Path.DirectorySeparatorChar.ToString()))
            {
                path += Path.DirectorySeparatorChar;
            }


            FindLogic.Combo.TextureAsset textureInfo = info.m_info.m_textures[textureGUID];
            string filePath = Path.Combine(path, name ?? $"{textureInfo.GetNameIndex()}");

            if (teResourceGUID.Type(textureGUID) != 0x4)
            {
                filePath += $".{teResourceGUID.Type(textureGUID):X3}";
            }

            if (Program.Flags != null && Program.Flags.Deduplicate)
            {
                if (ScratchDBInstance.HasRecord(textureGUID))
                {
                    return;
                }

                ScratchDBInstance[textureGUID] = new ScratchDB.ScratchPath($"{filePath}.{convertType}", true);
            }

            CreateDirectoryFromFile(path);

            await s_texurePrepareSemaphore.WaitAsync();

            try {
                if (!convertTextures)
                {
                    teTexture texture;
                    using (Stream textureStream = OpenFile(textureGUID)) {
                        texture = new teTexture(textureStream, true);
                        textureStream.Position = 0;
                        WriteFile(textureStream, $"{filePath}.004");
                    }

                    if (!texture.PayloadRequired)
                    {
                        return;
                    }
                    for (int i = 0; i < texture.Payloads.Length; ++i)
                    {
                        using (Stream texturePayloadStream = OpenFile(texture.GetPayloadGUID(textureGUID, i)))
                            WriteFile(texturePayloadStream, $"{filePath}_{i}.04D");
                    }
                }
                else
                {
                    teTexture texture;
                    using (Stream textureStream = OpenFile(textureGUID)) {
                        if (textureStream == null)
                        {
                            return;
                        }

                        texture = new teTexture(textureStream);
                    }

                    //if (texture.Header.Flags.HasFlag(teTexture.Flags.CUBEMAP)) return;
                    // for diffing when they add/regen loads of cubemaps

                    if (texture.PayloadRequired)
                    {
                        for (int i = 0; i < texture.Payloads.Length; ++i)
                        {
                            using (var payloadStream = OpenFile(texture.GetPayloadGUID(textureGUID, i)))
                                texture.LoadPayload(payloadStream, i);
                            if (maxMips == 1)
                            {
                                break;
                            }
                        }
                    }

                    uint?width    = null;
                    uint?height   = null;
                    uint?surfaces = null;
                    if (texture.Header.IsCubemap || texture.Header.IsArray || texture.HasMultipleSurfaces)
                    {
                        if (createMultiSurfaceSheet)
                        {
                            Logger.Debug("Combo", $"Saving {Path.GetFileName(filePath)} as a sheet because it has more than one surface");
                            height               = (uint)(texture.Header.Height * texture.Header.Surfaces);
                            surfaces             = 1;
                            texture.Header.Flags = 0;
                        }
                        else if (convertType != "tif" && convertType != "dds")
                        {
                            Logger.Debug("Combo", $"Saving {Path.GetFileName(filePath)} as {multiSurfaceConvertType} because it has more than one surface");
                            convertType = multiSurfaceConvertType;
                        }
                    }


                    WICCodecs?imageFormat = null;
                    switch (convertType)
                    {
                    case "tif":
                        imageFormat = WICCodecs.TIFF;
                        break;

                    case "png":
                        imageFormat = WICCodecs.PNG;
                        break;

                    case "jpg":
                        imageFormat = WICCodecs.JPEG;
                        break;
                    }

                    // if (convertType == "tga") imageFormat = Im.... oh
                    // so there is no TGA image format.
                    // sucks to be them

                    if (convertType == "dds")
                    {
                        using (Stream convertedStream = texture.SaveToDDS(maxMips == 1 ? 1 : texture.Header.MipCount, width, height, surfaces)) {
                            WriteFile(convertedStream, $"{filePath}.dds");
                        }

                        return;
                    }

                    Process pProcess;

                    using (Stream convertedStream = texture.SaveToDDS(maxMips == 1 ? 1 : texture.Header.MipCount, width, height, surfaces)) {
                        var data = DDSConverter.ConvertDDS(convertedStream, DXGI_FORMAT.R8G8B8A8_UNORM, imageFormat.Value, 0);
                        if (data != null)
                        {
                            WriteFile(data, $"{filePath}.{convertType}");
                        }
                        else
                        {
                            convertedStream.Position = 0;
                            WriteFile(convertedStream, $"{filePath}.dds");
                            Logger.Error("Combo", $"Unable to save {Path.GetFileName(filePath)} as {convertType} because DirectXTex failed.");
                        }
                    }
                }
            } finally {
                s_texurePrepareSemaphore.Release();
            }
        }