From df6aab2163c37435d66d5c088db28ddf6fe3b666 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 5 Jun 2021 22:20:23 +1000 Subject: [PATCH] Qt: Add texture replacement settings dialog --- src/duckstation-qt/CMakeLists.txt | 3 + src/duckstation-qt/advancedsettingswidget.cpp | 31 +- src/duckstation-qt/duckstation-qt.vcxproj | 8 +- .../duckstation-qt.vcxproj.filters | 10 +- src/duckstation-qt/settingsdialog.cpp | 6 + src/duckstation-qt/settingsdialog.h | 5 +- .../texturereplacementssettingswidget.cpp | 160 ++++++++ .../texturereplacementssettingswidget.h | 30 ++ .../texturereplacementssettingswidget.ui | 368 ++++++++++++++++++ 9 files changed, 588 insertions(+), 33 deletions(-) create mode 100644 src/duckstation-qt/texturereplacementssettingswidget.cpp create mode 100644 src/duckstation-qt/texturereplacementssettingswidget.h create mode 100644 src/duckstation-qt/texturereplacementssettingswidget.ui diff --git a/src/duckstation-qt/CMakeLists.txt b/src/duckstation-qt/CMakeLists.txt index 367f1dd93..50850315e 100644 --- a/src/duckstation-qt/CMakeLists.txt +++ b/src/duckstation-qt/CMakeLists.txt @@ -131,6 +131,9 @@ set(SRCS settingsdialog.h settingsdialog.ui settingwidgetbinder.h + texturereplacementssettingswidget.cpp + texturereplacementssettingswidget.h + texturereplacementssettingswidget.ui ) if(ENABLE_CHEEVOS) diff --git a/src/duckstation-qt/advancedsettingswidget.cpp b/src/duckstation-qt/advancedsettingswidget.cpp index f035d556b..a49ad887f 100644 --- a/src/duckstation-qt/advancedsettingswidget.cpp +++ b/src/duckstation-qt/advancedsettingswidget.cpp @@ -258,21 +258,6 @@ void AdvancedSettingsWidget::addTweakOptions() Settings::GetCPUFastmemModeDisplayName, "CPUFastmemMode", static_cast(CPUFastmemMode::Count), Settings::DEFAULT_CPU_FASTMEM_MODE); - addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Enable VRAM Write Texture Replacement"), - "TextureReplacements", "EnableVRAMWriteReplacements", false); - addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Preload Texture Replacements"), "TextureReplacements", - "PreloadTextures", false); - addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Dump Replaceable VRAM Writes"), "TextureReplacements", - "DumpVRAMWrites", false); - addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Set Dumped VRAM Write Alpha Channel"), - "TextureReplacements", "DumpVRAMWriteForceAlphaChannel", true); - addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Minimum Dumped VRAM Write Width"), "TextureReplacements", - "DumpVRAMWriteWidthThreshold", 1, VRAM_WIDTH, - Settings::DEFAULT_VRAM_WRITE_DUMP_WIDTH_THRESHOLD); - addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Minimum Dumped VRAM Write Height"), "TextureReplacements", - "DumpVRAMWriteHeightThreshold", 1, VRAM_HEIGHT, - Settings::DEFAULT_VRAM_WRITE_DUMP_HEIGHT_THRESHOLD); - addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("DMA Max Slice Ticks"), "Hacks", "DMAMaxSliceTicks", 100, 10000, Settings::DEFAULT_DMA_MAX_SLICE_TICKS); addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("DMA Halt Ticks"), "Hacks", "DMAHaltTicks", 100, 10000, @@ -313,14 +298,6 @@ void AdvancedSettingsWidget::onResetToDefaultClicked() setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Recompiler memory exceptions setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Recompiler block linking setChoiceTweakOption(m_ui.tweakOptionTable, i++, Settings::DEFAULT_CPU_FASTMEM_MODE); // Recompiler fastmem mode - setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // VRAM write texture replacement - setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Preload texture replacements - setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Dump replacable VRAM writes - setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Set dumped VRAM write alpha channel - setIntRangeTweakOption(m_ui.tweakOptionTable, i++, - Settings::DEFAULT_VRAM_WRITE_DUMP_WIDTH_THRESHOLD); // Minimum dumped VRAM width - setIntRangeTweakOption(m_ui.tweakOptionTable, i++, - Settings::DEFAULT_VRAM_WRITE_DUMP_HEIGHT_THRESHOLD); // Minimum dumped VRAm height setIntRangeTweakOption(m_ui.tweakOptionTable, i++, static_cast(Settings::DEFAULT_DMA_MAX_SLICE_TICKS)); // DMA max slice ticks setIntRangeTweakOption(m_ui.tweakOptionTable, i++, @@ -356,12 +333,6 @@ void AdvancedSettingsWidget::onResetToDefaultClicked() sif->DeleteValue("CPU", "RecompilerMemoryExceptions"); sif->DeleteValue("CPU", "RecompilerBlockLinking"); sif->DeleteValue("CPU", "FastmemMode"); - sif->DeleteValue("TextureReplacements", "EnableVRAMWriteReplacements"); - sif->DeleteValue("TextureReplacements", "PreloadTextures"); - sif->DeleteValue("TextureReplacements", "DumpVRAMWrites"); - sif->DeleteValue("TextureReplacements", "DumpVRAMWriteForceAlphaChannel"); - sif->DeleteValue("TextureReplacements", "DumpVRAMWriteWidthThreshold"); - sif->DeleteValue("TextureReplacements", "DumpVRAMWriteHeightThreshold"); sif->DeleteValue("Hacks", "DMAMaxSliceTicks"); sif->DeleteValue("Hacks", "DMAHaltTicks"); sif->DeleteValue("Hacks", "GPUFIFOSize"); @@ -374,4 +345,4 @@ void AdvancedSettingsWidget::onResetToDefaultClicked() while (m_ui.tweakOptionTable->rowCount() > 0) m_ui.tweakOptionTable->removeRow(m_ui.tweakOptionTable->rowCount() - 1); addTweakOptions(); -} \ No newline at end of file +} diff --git a/src/duckstation-qt/duckstation-qt.vcxproj b/src/duckstation-qt/duckstation-qt.vcxproj index 465ab924e..e55541a6c 100644 --- a/src/duckstation-qt/duckstation-qt.vcxproj +++ b/src/duckstation-qt/duckstation-qt.vcxproj @@ -49,6 +49,7 @@ + @@ -99,6 +100,7 @@ + @@ -215,6 +217,9 @@ Document + + Document + @@ -266,6 +271,7 @@ + @@ -348,4 +354,4 @@ - \ No newline at end of file + diff --git a/src/duckstation-qt/duckstation-qt.vcxproj.filters b/src/duckstation-qt/duckstation-qt.vcxproj.filters index a484f2ef8..c801b7713 100644 --- a/src/duckstation-qt/duckstation-qt.vcxproj.filters +++ b/src/duckstation-qt/duckstation-qt.vcxproj.filters @@ -91,6 +91,10 @@ + + + + @@ -150,6 +154,8 @@ + + @@ -189,6 +195,8 @@ + + @@ -253,4 +261,4 @@ translations - \ No newline at end of file + diff --git a/src/duckstation-qt/settingsdialog.cpp b/src/duckstation-qt/settingsdialog.cpp index b941d1574..844f184ad 100644 --- a/src/duckstation-qt/settingsdialog.cpp +++ b/src/duckstation-qt/settingsdialog.cpp @@ -18,6 +18,7 @@ #include "memorycardsettingswidget.h" #include "postprocessingsettingswidget.h" #include "qthost.h" +#include "texturereplacementssettingswidget.h" #include "util/ini_settings_interface.h" #include #include @@ -103,6 +104,11 @@ void SettingsDialog::addPages() QStringLiteral("paint-fill"), tr("Enhancement Settings
These options control enhancements which can improve visuals compared " "to the original console. Mouse over each option for additional information.")); + addWidget( + m_texture_replacement_settings = new TextureReplacementSettingsWidget(this, m_ui.settingsContainer), + tr("Texture Replacements"), QStringLiteral("pantone-line"), + tr( + "Texture Replacement Settings
WRITE ME! Mouse over each option for additional information.")); if (!isPerGameSettings()) { addWidget( diff --git a/src/duckstation-qt/settingsdialog.h b/src/duckstation-qt/settingsdialog.h index ab04fbd13..69921da37 100644 --- a/src/duckstation-qt/settingsdialog.h +++ b/src/duckstation-qt/settingsdialog.h @@ -22,6 +22,7 @@ class EmulationSettingsWidget; class MemoryCardSettingsWidget; class DisplaySettingsWidget; class EnhancementSettingsWidget; +class TextureReplacementSettingsWidget; class PostProcessingSettingsWidget; class AudioSettingsWidget; class AchievementSettingsWidget; @@ -51,6 +52,7 @@ public: ALWAYS_INLINE MemoryCardSettingsWidget* getMemoryCardSettingsWidget() const { return m_memory_card_settings; } ALWAYS_INLINE DisplaySettingsWidget* getDisplaySettingsWidget() const { return m_display_settings; } ALWAYS_INLINE EnhancementSettingsWidget* getEnhancementSettingsWidget() const { return m_enhancement_settings; } + ALWAYS_INLINE TextureReplacementSettingsWidget* getTextureReplacementSettingsWidget() const { return m_texture_replacement_settings; } ALWAYS_INLINE AudioSettingsWidget* getAudioSettingsWidget() const { return m_audio_settings; } ALWAYS_INLINE AchievementSettingsWidget* getAchievementSettingsWidget() const { return m_achievement_settings; } ALWAYS_INLINE AdvancedSettingsWidget* getAdvancedSettingsWidget() const { return m_advanced_settings; } @@ -92,7 +94,7 @@ private Q_SLOTS: private: enum : u32 { - MAX_SETTINGS_WIDGETS = 13 + MAX_SETTINGS_WIDGETS = 14 }; void addPages(); @@ -110,6 +112,7 @@ private: MemoryCardSettingsWidget* m_memory_card_settings = nullptr; DisplaySettingsWidget* m_display_settings = nullptr; EnhancementSettingsWidget* m_enhancement_settings = nullptr; + TextureReplacementSettingsWidget* m_texture_replacement_settings = nullptr; PostProcessingSettingsWidget* m_post_processing_settings = nullptr; AudioSettingsWidget* m_audio_settings = nullptr; AchievementSettingsWidget* m_achievement_settings = nullptr; diff --git a/src/duckstation-qt/texturereplacementssettingswidget.cpp b/src/duckstation-qt/texturereplacementssettingswidget.cpp new file mode 100644 index 000000000..69b09f39d --- /dev/null +++ b/src/duckstation-qt/texturereplacementssettingswidget.cpp @@ -0,0 +1,160 @@ +#include "texturereplacementssettingswidget.h" +#include "core/settings.h" +#include "core/texture_dumper.h" +#include "core/texture_replacements.h" +#include "qtutils.h" +#include "settingwidgetbinder.h" +#include +#include + +TextureReplacementSettingsWidget::TextureReplacementSettingsWidget(SettingsDialog* dialog, QWidget* parent) + : QWidget(parent), m_dialog(dialog) +{ + m_ui.setupUi(this); + connectUi(); + updateOptionsEnabled(); + updateVRAMUsage(); +} + +TextureReplacementSettingsWidget::~TextureReplacementSettingsWidget() = default; + +void TextureReplacementSettingsWidget::connectUi() +{ + SettingsInterface* sif = m_dialog->getSettingsInterface(); + + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableVRAMWriteReplacement, "TextureReplacements", + "EnableVRAMWriteReplacements", false); + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableTextureReplacement, "TextureReplacements", + "EnableTextureReplacements", false); + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.preloadTextureReplacements, "TextureReplacements", + "PreloadTextures", false); + + SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureReplacementScale, "TextureReplacements", + "TextureReplacementScale", 1); + + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableVRAMWriteDumping, "TextureReplacements", + "DumpVRAMWrites", false); + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.VRAMWriteDumpingClearMaskBit, "TextureReplacements", + "DumpVRAMWriteForceAlphaChannel", true); + SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.VRAMWriteDumpingWidthThreshold, "TextureReplacements", + "DumpVRAMWriteWidthThreshold", + Settings::DEFAULT_VRAM_WRITE_DUMP_WIDTH_THRESHOLD); + SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.VRAMWriteDumpingWidthThreshold, "TextureReplacements", + "DumpVRAMWriteHeightThreshold", + Settings::DEFAULT_VRAM_WRITE_DUMP_HEIGHT_THRESHOLD); + + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.textureDumpVRAMWriteGroups, "TextureReplacements", + "DumpTexturesByVRAMWrite", false); + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.textureDumpCLUTGroups, "TextureReplacements", + "DumpTexturesByPalette", false); + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.textureDumpForceOpaque, "TextureReplacements", + "DumpTexturesForceAlphaChannel", false); + SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureDumpMaxMergeWidth, "TextureReplacements", + "DumpTexturesMaxMergeWidth", + Settings::DEFAULT_TEXTURE_DUMP_MAX_MERGE_WIDTH); + SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureDumpMaxMergeHeight, "TextureReplacements", + "DumpTexturesMaxMergeHeight", + Settings::DEFAULT_TEXTURE_DUMP_MAX_MERGE_HEIGHT); + SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureDumpMaxMergeeWidth, "TextureReplacements", + "DumpTexturesMaxMergeeWidth", + Settings::DEFAULT_TEXTURE_DUMP_MAX_MERGEE_WIDTH); + SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureDumpMaxMergeeHeight, "TextureReplacements", + "DumpTexturesMaxMergeeHeight", + Settings::DEFAULT_TEXTURE_DUMP_MAX_MERGEE_HEIGHT); + + connect(m_ui.enableVRAMWriteReplacement, &QCheckBox::stateChanged, this, + &TextureReplacementSettingsWidget::updateOptionsEnabled); + connect(m_ui.enableTextureReplacement, &QCheckBox::stateChanged, this, + &TextureReplacementSettingsWidget::updateOptionsEnabled); + connect(m_ui.enableVRAMWriteDumping, &QCheckBox::stateChanged, this, + &TextureReplacementSettingsWidget::updateOptionsEnabled); + connect(m_ui.textureDumpVRAMWriteGroups, &QCheckBox::stateChanged, this, + &TextureReplacementSettingsWidget::updateOptionsEnabled); + connect(m_ui.textureDumpCLUTGroups, &QCheckBox::stateChanged, this, + &TextureReplacementSettingsWidget::updateOptionsEnabled); + connect(m_ui.enableTextureReplacement, &QCheckBox::stateChanged, this, + &TextureReplacementSettingsWidget::updateVRAMUsage); + connect(m_ui.textureReplacementScale, QOverload::of(&QComboBox::currentIndexChanged), this, + &TextureReplacementSettingsWidget::updateVRAMUsage); + + connect(m_ui.resetToDefaults, &QPushButton::clicked, this, &TextureReplacementSettingsWidget::setDefaults); + connect(m_ui.openDumpDirectory, &QPushButton::clicked, this, &TextureReplacementSettingsWidget::openDumpDirectory); +} + +void TextureReplacementSettingsWidget::setDefaults() +{ + m_ui.enableVRAMWriteReplacement->setChecked(false); + m_ui.enableTextureReplacement->setChecked(false); + m_ui.preloadTextureReplacements->setChecked(false); + + m_ui.textureReplacementScale->setCurrentIndex(0); + + m_ui.enableVRAMWriteDumping->setChecked(false); + m_ui.VRAMWriteDumpingClearMaskBit->setChecked(true); + m_ui.VRAMWriteDumpingWidthThreshold->setValue(Settings::DEFAULT_VRAM_WRITE_DUMP_WIDTH_THRESHOLD); + m_ui.VRAMWriteDumpingWidthThreshold->setValue(Settings::DEFAULT_VRAM_WRITE_DUMP_HEIGHT_THRESHOLD); + + m_ui.textureDumpVRAMWriteGroups->setChecked(false); + m_ui.textureDumpCLUTGroups->setChecked(false); + m_ui.textureDumpForceOpaque->setChecked(false); + m_ui.textureDumpMaxMergeWidth->setValue(Settings::DEFAULT_TEXTURE_DUMP_MAX_MERGE_WIDTH); + m_ui.textureDumpMaxMergeHeight->setValue(Settings::DEFAULT_TEXTURE_DUMP_MAX_MERGE_HEIGHT); + m_ui.textureDumpMaxMergeeWidth->setValue(Settings::DEFAULT_TEXTURE_DUMP_MAX_MERGEE_WIDTH); + m_ui.textureDumpMaxMergeeHeight->setValue(Settings::DEFAULT_TEXTURE_DUMP_MAX_MERGEE_HEIGHT); +} + +void TextureReplacementSettingsWidget::updateOptionsEnabled() +{ + m_ui.preloadTextureReplacements->setEnabled(m_ui.enableVRAMWriteReplacement->isChecked() || + m_ui.enableTextureReplacement->isChecked()); + m_ui.textureReplacementScale->setEnabled(m_ui.enableTextureReplacement->isChecked()); + + const bool vram_write_dumping_enabled = m_ui.enableVRAMWriteDumping->isChecked(); + m_ui.VRAMWriteDumpingClearMaskBit->setEnabled(vram_write_dumping_enabled); + m_ui.VRAMWriteDumpingWidthThreshold->setEnabled(vram_write_dumping_enabled); + m_ui.VRAMWriteDumpingHeightThreshold->setEnabled(vram_write_dumping_enabled); + m_ui.dumpingThreshold->setEnabled(vram_write_dumping_enabled); + + const bool texture_dumping_enabled = + (m_ui.textureDumpVRAMWriteGroups->isChecked() || m_ui.textureDumpCLUTGroups->isChecked()); + m_ui.textureDumpForceOpaque->setEnabled(texture_dumping_enabled); + m_ui.maxMergeSize->setEnabled(texture_dumping_enabled); + m_ui.textureDumpMaxMergeWidth->setEnabled(texture_dumping_enabled); + m_ui.textureDumpMaxMergeHeight->setEnabled(texture_dumping_enabled); + m_ui.maxMergeeSize->setEnabled(texture_dumping_enabled); + m_ui.textureDumpMaxMergeeWidth->setEnabled(texture_dumping_enabled); + m_ui.textureDumpMaxMergeeHeight->setEnabled(texture_dumping_enabled); +} + +void TextureReplacementSettingsWidget::openDumpDirectory() +{ + const std::string dump_directory(TextureDumper::GetDumpDirectory()); + if (dump_directory.empty()) + return; + + QtUtils::OpenURL(this, QUrl::fromLocalFile(QString::fromStdString(dump_directory))); +} + +void TextureReplacementSettingsWidget::updateVRAMUsage() +{ + if (!m_ui.enableTextureReplacement->isChecked()) + { + m_ui.vramUsage->setText(tr("Texture replacements are not enabled.")); + return; + } + + u32 scale = static_cast(m_dialog->getEffectiveIntValue("TextureReplacements", "TextureReplacementScale", 0)); + if (scale == 0) + scale = static_cast(m_dialog->getEffectiveIntValue("GPU", "ResolutionScale", 1)); + + const u32 replacement_width = TextureReplacements::TEXTURE_REPLACEMENT_PAGE_WIDTH * scale; + const u32 replacement_height = TextureReplacements::TEXTURE_REPLACEMENT_PAGE_HEIGHT * scale; + const u32 vram_usage = + (replacement_width * replacement_height * sizeof(u32)) * TextureReplacements::TEXTURE_REPLACEMENT_PAGE_COUNT; + + const u32 vram_usage_mb = static_cast(std::ceil(static_cast(vram_usage) / 1024576.0f)); + m_ui.vramUsage->setText(tr("Texture replacements will be up to %1x%2, and use %3MB of video memory.") + .arg(replacement_width) + .arg(replacement_height) + .arg(vram_usage_mb)); +} diff --git a/src/duckstation-qt/texturereplacementssettingswidget.h b/src/duckstation-qt/texturereplacementssettingswidget.h new file mode 100644 index 000000000..eb4a81c8a --- /dev/null +++ b/src/duckstation-qt/texturereplacementssettingswidget.h @@ -0,0 +1,30 @@ +#pragma once +#include "ui_texturereplacementssettingswidget.h" +#include +#include +#include +#include + +class SettingsDialog; + +class TextureReplacementSettingsWidget final : public QWidget +{ + Q_OBJECT + +public: + TextureReplacementSettingsWidget(SettingsDialog* dialog, QWidget* parent); + ~TextureReplacementSettingsWidget(); + +private Q_SLOTS: + void setDefaults(); + void updateOptionsEnabled(); + void openDumpDirectory(); + void updateVRAMUsage(); + +private: + void connectUi(); + + SettingsDialog* m_dialog; + + Ui::TextureReplacementSettingsWidget m_ui; +}; diff --git a/src/duckstation-qt/texturereplacementssettingswidget.ui b/src/duckstation-qt/texturereplacementssettingswidget.ui new file mode 100644 index 000000000..7b02828ae --- /dev/null +++ b/src/duckstation-qt/texturereplacementssettingswidget.ui @@ -0,0 +1,368 @@ + + + TextureReplacementSettingsWidget + + + + 0 + 0 + 442 + 500 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Texture Replacement + + + + + + Enable Texture Replacement + + + + + + + Enable VRAM Write Replacements (backgrounds in supported games) + + + + + + + Texture Replacement Resolution: + + + + + + + + Auto (Match Rendering Resolution) + + + + + 1x (256x256) + + + + + 2x (512x512) + + + + + 3x (768x768) + + + + + 4x (1024x1024) + + + + + 5x (1280x1280) + + + + + 6x (1536x1536) + + + + + 7x (1792x1792) + + + + + 8x (2048x2048) + + + + + 9x (2304x2304) + + + + + 10x (2560x2560) + + + + + + + + Texture replacements will be up to 1024x1024, and use 8MB of video memory. + + + true + + + + + + + Preload Texture Replacements + + + + + + + + + + VRAM Write Dumping + + + + + + Enable VRAM Write Dumping + + + + + + + Clear Mask Bit (make opaque) + + + + + + + Dumping Threshold: + + + + + + + + + 1 + + + 1024 + + + + + + + x + + + + + + + 1 + + + 512 + + + + + + + + + + + + Texture Dumping + + + + + + Clear Transparency (make opaque) + + + + + + + Dump Textures By Palette/CLUT + + + + + + + <b>WARNING: </b>Texture dumping can create a large number of files on your disk, slowing down emulation and increasing wear on SSDs. + + + Qt::RichText + + + true + + + + + + + Maximum VRAM Write Mergee Size: + + + + + + + Maximum VRAM Write Merge Size: + + + + + + + + + 1 + + + 1024 + + + + + + + x + + + + + + + 1 + + + 512 + + + + + + + + + + + 1 + + + 1024 + + + + + + + x + + + + + + + 1 + + + 512 + + + + + + + + + + + Open Dump Directory + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Reset to Defaults + + + + + + + + + Dump Merged Textures + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + +