private async void ImportButton_Click(object sender, RoutedEventArgs e)
        {
            var path = PathBox.Text;

            if (String.IsNullOrWhiteSpace(path))
            {
                return;
            }

            var od     = new OpenFileDialog();
            var result = od.ShowDialog();

            if (result != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }

            byte[] data = null;

            var _dat   = new Dat(XivCache.GameInfo.GameDirectory);
            var _index = new Index(XivCache.GameInfo.GameDirectory);

            if (DecompressedType2.IsChecked == true)
            {
                var temp = File.ReadAllBytes(od.FileName);
                data = await _dat.CreateType2Data(temp);
            }
            else
            {
                data = File.ReadAllBytes(od.FileName);
            }

            var type = BitConverter.ToInt32(data, 4);

            if (type < 2 || type > 4)
            {
                FlexibleMessageBox.Show("Invalid Data Type.\nGeneric binary files should be imported as decompressed type 2 Data.", "Data Type Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            try
            {
                var dummyItem = new XivGenericItemModel();
                dummyItem.Name = Path.GetFileName(path);
                dummyItem.SecondaryCategory = "Raw File Imports";
                await _dat.WriteModFile(data, path, XivStrings.TexTools, dummyItem);
            }
            catch (Exception Ex)
            {
                FlexibleMessageBox.Show("Unable to import file.\n\nError: " + Ex.Message, "Import Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            FlexibleMessageBox.Show("File Imported Successfully.", "Import Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
            this.Close();
        }
Example #2
0
        private async void AddMetadataButton_Click(object sender, RoutedEventArgs e)
        {
            var path         = MetadataPathBox.Text;
            var selectedFile = new FileEntry()
            {
                Path = path,
                Name = MakeFriendlyFileName(path)
            };
            var addChildren = MetadataIncludeChildFilesBox.IsChecked == true ? true : false;

            var _dat = new Dat(_gameDirectory);
            var meta = await ItemMetadata.GetMetadata(path);

            var data = await _dat.CreateType2Data(await ItemMetadata.Serialize(meta));

            if (addChildren)
            {
                AddWithChildren(selectedFile.Path, SelectedItem, data);
            }
            else
            {
                AddFile(selectedFile, SelectedItem, data);
            }
        }
Example #3
0
        /// <summary>
        /// Creates texture data ready to be imported into the DATs from an external file.
        /// If format is not specified, either the incoming file's DDS format is used (DDS files),
        /// or the existing internal file's DDS format is used.
        /// </summary>
        /// <param name="internalPath"></param>
        /// <param name="externalPath"></param>
        /// <param name="texFormat"></param>
        /// <returns></returns>
        public async Task <byte[]> MakeTexData(string internalPath, string externalPath, XivTexFormat texFormat = XivTexFormat.INVALID)
        {
            // Ensure file exists.
            if (!File.Exists(externalPath))
            {
                throw new IOException($"Could not find file: {externalPath}");
            }

            var root = await XivCache.GetFirstRoot(internalPath);

            bool isDds = Path.GetExtension(externalPath).ToLower() == ".dds";

            var ddsContainer = new DDSContainer();

            try
            {
                // If no format was specified...
                if (texFormat == XivTexFormat.INVALID)
                {
                    if (isDds)
                    {
                        // If we're importing a DDS file, get the format from the incoming DDS file
                        using (var fs = new FileStream(externalPath, FileMode.Open))
                        {
                            using (var sr = new BinaryReader(fs))
                            {
                                texFormat = GetDDSTexFormat(sr);
                            }
                        }
                    }
                    else
                    {
                        // Otherwise use the current internal format.
                        var xivt = await _dat.GetType4Data(internalPath, false);

                        texFormat = xivt.TextureFormat;
                    }
                }

                // Check if the texture being imported has been imported before
                CompressionFormat compressionFormat = CompressionFormat.BGRA;

                switch (texFormat)
                {
                case XivTexFormat.DXT1:
                    compressionFormat = CompressionFormat.BC1a;
                    break;

                case XivTexFormat.DXT5:
                    compressionFormat = CompressionFormat.BC3;
                    break;

                case XivTexFormat.A8R8G8B8:
                    compressionFormat = CompressionFormat.BGRA;
                    break;

                default:
                    if (!isDds)
                    {
                        throw new Exception($"Format {texFormat} is not currently supported for BMP import\n\nPlease use the DDS import option instead.");
                    }
                    break;
                }

                if (!isDds)
                {
                    using (var surface = Surface.LoadFromFile(externalPath))
                    {
                        if (surface == null)
                        {
                            throw new FormatException($"Unsupported texture format");
                        }

                        surface.FlipVertically();

                        var maxMipCount = 1;
                        if (root != null)
                        {
                            // For things that have real roots (things that have actual models/aren't UI textures), we always want mipMaps, even if the existing texture only has one.
                            // (Ex. The Default Mat-Add textures)
                            maxMipCount = -1;
                        }

                        using (var compressor = new Compressor())
                        {
                            // UI/Paintings only have a single mipmap and will crash if more are generated, for everything else generate max levels
                            compressor.Input.SetMipmapGeneration(true, maxMipCount);
                            compressor.Input.SetData(surface);
                            compressor.Compression.Format = compressionFormat;
                            compressor.Compression.SetBGRAPixelFormat();

                            compressor.Process(out ddsContainer);
                        }
                    }
                }

                // If we're not a DDS, write the DDS to file temporarily.
                var ddsFilePath = externalPath;
                if (!isDds)
                {
                    var tempFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".dds");
                    ddsContainer.Write(tempFile, DDSFlags.None);
                    ddsFilePath = tempFile;
                }

                using (var br = new BinaryReader(File.OpenRead(ddsFilePath)))
                {
                    br.BaseStream.Seek(12, SeekOrigin.Begin);

                    var newHeight = br.ReadInt32();
                    var newWidth  = br.ReadInt32();
                    br.ReadBytes(8);
                    var newMipCount = br.ReadInt32();

                    if (newHeight % 2 != 0 || newWidth % 2 != 0)
                    {
                        throw new Exception("Resolution must be a multiple of 2");
                    }

                    br.BaseStream.Seek(80, SeekOrigin.Begin);

                    var textureFlags = br.ReadInt32();
                    var texType      = br.ReadInt32();

                    var uncompressedLength = (int)new FileInfo(ddsFilePath).Length - 128;
                    var newTex             = new List <byte>();

                    if (!internalPath.Contains(".atex"))
                    {
                        var DDSInfo = await DDS.ReadDDS(br, texFormat, newWidth, newHeight, newMipCount);

                        newTex.AddRange(_dat.MakeType4DatHeader(texFormat, DDSInfo.mipPartOffsets, DDSInfo.mipPartCounts, (int)uncompressedLength, newMipCount, newWidth, newHeight));
                        newTex.AddRange(MakeTextureInfoHeader(texFormat, newWidth, newHeight, newMipCount));
                        newTex.AddRange(DDSInfo.compressedDDS);

                        return(newTex.ToArray());
                    }
                    else
                    {
                        br.BaseStream.Seek(128, SeekOrigin.Begin);
                        newTex.AddRange(MakeTextureInfoHeader(texFormat, newWidth, newHeight, newMipCount));
                        newTex.AddRange(br.ReadBytes((int)uncompressedLength));
                        var data = await _dat.CreateType2Data(newTex.ToArray());

                        return(data);
                    }
                }
            }
            finally
            {
                ddsContainer.Dispose();
            }
        }
        /// <summary>
        /// The event handler for the add custom texture button clicked
        /// </summary>
        private async void AddCustomTextureButton_Click(object sender, RoutedEventArgs e)
        {
            var selectedItem = TextureMapComboBox.SelectedItem as ModComboBox;

            var mod = selectedItem.SelectedMod;

            byte[] modData;

            var includedMod = new IncludedMods
            {
                Name     = $"{Path.GetFileNameWithoutExtension(mod.fullPath)} ({((Category)ModListTreeView.SelectedItem).Name})",
                FullPath = mod.fullPath
            };

            var includedModsList = IncludedModsList.Items.Cast <IncludedMods>().ToList();

            var tex = new Tex(_gameDirectory);

            var ddsDirectory = new DirectoryInfo(CustomTextureTextBox.Text);

            if (selectedItem.TexTypePath.Type == XivTexType.ColorSet)
            {
                var mtrl = new Mtrl(_gameDirectory, XivDataFiles.GetXivDataFile(mod.datFile), GetLanguage());

                var xivMtrl = await mtrl.GetMtrlData(mod.data.modOffset, mod.fullPath, int.Parse(Settings.Default.DX_Version));

                modData = tex.DDStoMtrlData(xivMtrl, ddsDirectory, ((Category)ModListTreeView.SelectedItem).Item, GetLanguage());
                var dat = new Dat(_gameDirectory);
                modData = await dat.CreateType2Data(modData);
            }
            else
            {
                try
                {
                    var texData = await tex.GetTexData(selectedItem.TexTypePath);

                    modData = await tex.DDStoTexData(texData, ((Category)ModListTreeView.SelectedItem).Item, ddsDirectory);
                }
                catch (Exception ex)
                {
                    FlexibleMessageBox.Show(ex.Message);
                    return;
                }
            }

            if (includedModsList.Any(item => item.Name.Equals(includedMod.Name)))
            {
                if (FlexibleMessageBox.Show(
                        string.Format(UIMessages.ExistingOption, includedMod.Name),
                        UIMessages.OverwriteTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
                    System.Windows.Forms.DialogResult.Yes)
                {
                    _selectedModOption.Mods[mod.fullPath].ModDataBytes = modData;
                }
            }
            else
            {
                IncludedModsList.Items.Add(includedMod);
                _selectedModOption.Mods.Add(mod.fullPath, new ModData
                {
                    Name         = mod.name,
                    Category     = mod.category,
                    FullPath     = mod.fullPath,
                    ModDataBytes = modData,
                });
            }
        }