From 49c0766b734e0ed63cd375ed92754d5e55116362 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Me=CC=81ndez?= <daniel.mendez@edreamsodigeo.com>
Date: Thu, 8 Apr 2021 00:20:52 +0200
Subject: [PATCH 1/7] settings: Save and load NAND/SD dirs from config

---
 src/citra/config.cpp                  |  4 ++++
 src/citra_qt/configuration/config.cpp | 12 ++++++++++++
 src/core/settings.h                   |  2 ++
 3 files changed, 18 insertions(+)

diff --git a/src/citra/config.cpp b/src/citra/config.cpp
index 88a36ed66..3364b791e 100644
--- a/src/citra/config.cpp
+++ b/src/citra/config.cpp
@@ -201,6 +201,10 @@ void Config::ReadValues() {
     // Data Storage
     Settings::values.use_virtual_sd =
         sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
+    Settings::values.nand_dir =
+        sdl2_config->Get("Data Storage", "nand_directory", FileUtil::GetUserPath(FileUtil::UserPath::NANDDir));
+    Settings::values.sdmc_dir =
+        sdl2_config->Get("Data Storage", "sdmc_directory", FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir));
 
     // System
     Settings::values.is_new_3ds = sdl2_config->GetBoolean("System", "is_new_3ds", true);
diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp
index 8901c47c2..e14d01e0b 100644
--- a/src/citra_qt/configuration/config.cpp
+++ b/src/citra_qt/configuration/config.cpp
@@ -302,6 +302,14 @@ void Config::ReadDataStorageValues() {
     qt_config->beginGroup(QStringLiteral("Data Storage"));
 
     Settings::values.use_virtual_sd = ReadSetting(QStringLiteral("use_virtual_sd"), true).toBool();
+    std::string nan_dir = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
+    Settings::values.nand_dir = ReadSetting(QStringLiteral("nand_directory"), QString::fromStdString(nan_dir))
+                                    .toString()
+                                    .toStdString();
+        std::string sdmc_dir = FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir);
+    Settings::values.sdmc_dir = ReadSetting(QStringLiteral("sdmc_directory"), QString::fromStdString(sdmc_dir))
+                                    .toString()
+                                    .toStdString();
 
     qt_config->endGroup();
 }
@@ -852,6 +860,10 @@ void Config::SaveDataStorageValues() {
     qt_config->beginGroup(QStringLiteral("Data Storage"));
 
     WriteSetting(QStringLiteral("use_virtual_sd"), Settings::values.use_virtual_sd, true);
+    WriteSetting(QStringLiteral("nand_directory"),
+                                QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)));
+    WriteSetting(QStringLiteral("sdmc_directory"),
+                                QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)));
 
     qt_config->endGroup();
 }
diff --git a/src/core/settings.h b/src/core/settings.h
index 0876d312f..af41b9a02 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -140,6 +140,8 @@ struct Values {
 
     // Data Storage
     bool use_virtual_sd;
+    std::string nand_dir;
+    std::string sdmc_dir;
 
     // System
     int region_value;

From 3be52f818a0a8d32bcc800ed8349dc43cac479cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Me=CC=81ndez?= <daniel.mendez@edreamsodigeo.com>
Date: Sat, 10 Apr 2021 20:48:28 +0200
Subject: [PATCH 2/7] file_util: Add a function to update the user path

	Added a default value when sdmc and nand are empty
---
 src/citra_qt/configuration/config.cpp |  2 +-
 src/common/file_util.cpp              | 15 +++++++++++++--
 src/common/file_util.h                |  3 +++
 src/core/settings.cpp                 |  2 ++
 4 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp
index e14d01e0b..65071e251 100644
--- a/src/citra_qt/configuration/config.cpp
+++ b/src/citra_qt/configuration/config.cpp
@@ -306,7 +306,7 @@ void Config::ReadDataStorageValues() {
     Settings::values.nand_dir = ReadSetting(QStringLiteral("nand_directory"), QString::fromStdString(nan_dir))
                                     .toString()
                                     .toStdString();
-        std::string sdmc_dir = FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir);
+    std::string sdmc_dir = FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir);
     Settings::values.sdmc_dir = ReadSetting(QStringLiteral("sdmc_directory"), QString::fromStdString(sdmc_dir))
                                     .toString()
                                     .toStdString();
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index 9901141b3..b7576c208 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -12,6 +12,7 @@
 #include "common/common_paths.h"
 #include "common/file_util.h"
 #include "common/logging/log.h"
+#include "core/settings.h"
 
 #ifdef _WIN32
 #include <windows.h>
@@ -716,8 +717,13 @@ void SetUserPath(const std::string& path) {
         }
 #endif
     }
-    g_paths.emplace(UserPath::SDMCDir, user_path + SDMC_DIR DIR_SEP);
-    g_paths.emplace(UserPath::NANDDir, user_path + NAND_DIR DIR_SEP);
+
+    g_paths.emplace(UserPath::SDMCDir, !Settings::values.sdmc_dir.empty()
+                                           ? Settings::values.sdmc_dir
+                                           : user_path + SDMC_DIR DIR_SEP);
+    g_paths.emplace(UserPath::NANDDir, !Settings::values.nand_dir.empty()
+                                           ? Settings::values.nand_dir
+                                           : user_path + NAND_DIR DIR_SEP);
     g_paths.emplace(UserPath::SysDataDir, user_path + SYSDATA_DIR DIR_SEP);
     // TODO: Put the logs in a better location for each OS
     g_paths.emplace(UserPath::LogDir, user_path + LOG_DIR DIR_SEP);
@@ -762,6 +768,11 @@ const std::string& GetUserPath(UserPath path) {
         SetUserPath();
     return g_paths[path];
 }
+
+const void UpdateUserPath(UserPath path, const std::string& filename) {
+    g_paths[path] = filename + DIR_SEP;
+}
+
 std::size_t WriteStringToFile(bool text_file, const std::string& filename, std::string_view str) {
     return IOFile(filename, text_file ? "w" : "wb").WriteString(str);
 }
diff --git a/src/common/file_util.h b/src/common/file_util.h
index 6fa14315c..0f0e862c3 100644
--- a/src/common/file_util.h
+++ b/src/common/file_util.h
@@ -186,6 +186,9 @@ void SetCurrentRomPath(const std::string& path);
 // directory. To be used in "multi-user" mode (that is, installed).
 [[nodiscard]] const std::string& GetUserPath(UserPath path);
 
+// Update the Global Path with the new value
+const void UpdateUserPath(UserPath path, const std::string& filename);
+
 // Returns the path to where the sys file are
 [[nodiscard]] std::string GetSysDirectory();
 
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index ba2a170eb..855307ba5 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -118,6 +118,8 @@ void LogSettings() {
     log_setting("Camera_OuterLeftConfig", values.camera_config[OuterLeftCamera]);
     log_setting("Camera_OuterLeftFlip", values.camera_flip[OuterLeftCamera]);
     log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd);
+    log_setting("DataStorage_SdmcDir", values.sdmc_dir);
+    log_setting("DataStorage_NandDir", values.nand_dir);
     log_setting("System_IsNew3ds", values.is_new_3ds);
     log_setting("System_RegionValue", values.region_value);
     log_setting("Debugging_UseGdbstub", values.use_gdbstub);

From 7f20d8bb889ce621e0ddb5d0d34149739a714d0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Me=CC=81ndez?= <daniel.mendez@edreamsodigeo.com>
Date: Sat, 17 Apr 2021 15:29:12 +0200
Subject: [PATCH 3/7] config: Added nand_directory and sdmc_directory to
 Settings

	Added settings to the ini
---
 src/citra/config.cpp                  |  8 ++++----
 src/citra/default_ini.h               |  8 ++++++++
 src/citra_qt/configuration/config.cpp | 18 ++++++++++--------
 3 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/src/citra/config.cpp b/src/citra/config.cpp
index 3364b791e..6f747fcf5 100644
--- a/src/citra/config.cpp
+++ b/src/citra/config.cpp
@@ -201,10 +201,10 @@ void Config::ReadValues() {
     // Data Storage
     Settings::values.use_virtual_sd =
         sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
-    Settings::values.nand_dir =
-        sdl2_config->Get("Data Storage", "nand_directory", FileUtil::GetUserPath(FileUtil::UserPath::NANDDir));
-    Settings::values.sdmc_dir =
-        sdl2_config->Get("Data Storage", "sdmc_directory", FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir));
+    Settings::values.nand_dir = sdl2_config->GetString(
+        "Data Storage", "nand_directory", FileUtil::GetUserPath(FileUtil::UserPath::NANDDir));
+    Settings::values.sdmc_dir = sdl2_config->GetString(
+        "Data Storage", "sdmc_directory", FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir));
 
     // System
     Settings::values.is_new_3ds = sdl2_config->GetBoolean("System", "is_new_3ds", true);
diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h
index 4646d5fd3..55d8da8f5 100644
--- a/src/citra/default_ini.h
+++ b/src/citra/default_ini.h
@@ -250,6 +250,14 @@ volume =
 # 1 (default): Yes, 0: No
 use_virtual_sd =
 
+# The path of the virtual SD card directory.
+# empty (default) will use the user_path
+sdmc_directory =
+
+# The path of NAND directory.
+# empty (default) will use the user_path
+nand_directory =
+
 [System]
 # The system model that Citra will try to emulate
 # 0: Old 3DS, 1: New 3DS (default)
diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp
index 65071e251..eac0c9990 100644
--- a/src/citra_qt/configuration/config.cpp
+++ b/src/citra_qt/configuration/config.cpp
@@ -303,13 +303,15 @@ void Config::ReadDataStorageValues() {
 
     Settings::values.use_virtual_sd = ReadSetting(QStringLiteral("use_virtual_sd"), true).toBool();
     std::string nan_dir = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
-    Settings::values.nand_dir = ReadSetting(QStringLiteral("nand_directory"), QString::fromStdString(nan_dir))
-                                    .toString()
-                                    .toStdString();
+    Settings::values.nand_dir =
+        ReadSetting(QStringLiteral("nand_directory"), QString::fromStdString(nan_dir))
+            .toString()
+            .toStdString();
     std::string sdmc_dir = FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir);
-    Settings::values.sdmc_dir = ReadSetting(QStringLiteral("sdmc_directory"), QString::fromStdString(sdmc_dir))
-                                    .toString()
-                                    .toStdString();
+    Settings::values.sdmc_dir =
+        ReadSetting(QStringLiteral("sdmc_directory"), QString::fromStdString(sdmc_dir))
+            .toString()
+            .toStdString();
 
     qt_config->endGroup();
 }
@@ -861,9 +863,9 @@ void Config::SaveDataStorageValues() {
 
     WriteSetting(QStringLiteral("use_virtual_sd"), Settings::values.use_virtual_sd, true);
     WriteSetting(QStringLiteral("nand_directory"),
-                                QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)));
+                 QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)));
     WriteSetting(QStringLiteral("sdmc_directory"),
-                                QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)));
+                 QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)));
 
     qt_config->endGroup();
 }

From d21b8fb1b10472c465c3b0189974ea1d46365d0b Mon Sep 17 00:00:00 2001
From: Daniel Mendez <nieldm@gmail.com>
Date: Tue, 13 Apr 2021 22:32:36 +0200
Subject: [PATCH 4/7] config: better variable naming
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
---
 src/citra_qt/configuration/config.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp
index eac0c9990..2b5ab6cd3 100644
--- a/src/citra_qt/configuration/config.cpp
+++ b/src/citra_qt/configuration/config.cpp
@@ -302,9 +302,9 @@ void Config::ReadDataStorageValues() {
     qt_config->beginGroup(QStringLiteral("Data Storage"));
 
     Settings::values.use_virtual_sd = ReadSetting(QStringLiteral("use_virtual_sd"), true).toBool();
-    std::string nan_dir = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
+    std::string nand_dir = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
     Settings::values.nand_dir =
-        ReadSetting(QStringLiteral("nand_directory"), QString::fromStdString(nan_dir))
+        ReadSetting(QStringLiteral("nand_directory"), QString::fromStdString(nand_dir))
             .toString()
             .toStdString();
     std::string sdmc_dir = FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir);

From 95529a8b1d3e2daba3a5e4325472e9ba3ba4bcbd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Me=CC=81ndez?= <daniel.mendez@edreamsodigeo.com>
Date: Sat, 17 Apr 2021 15:16:48 +0200
Subject: [PATCH 5/7] citra-qt: Added configure storage to handle NAND and SDMC
 dir location

---
 src/citra_qt/CMakeLists.txt                   |   3 +
 src/citra_qt/configuration/config.cpp         |   2 +
 src/citra_qt/configuration/configure.ui       |  11 +
 .../configuration/configure_dialog.cpp        |   6 +-
 .../configuration/configure_storage.cpp       |  78 ++++++++
 .../configuration/configure_storage.h         |  26 +++
 .../configuration/configure_storage.ui        | 188 ++++++++++++++++++
 7 files changed, 313 insertions(+), 1 deletion(-)
 create mode 100644 src/citra_qt/configuration/configure_storage.cpp
 create mode 100644 src/citra_qt/configuration/configure_storage.h
 create mode 100644 src/citra_qt/configuration/configure_storage.ui

diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt
index 24c2ca601..4f64f7be6 100644
--- a/src/citra_qt/CMakeLists.txt
+++ b/src/citra_qt/CMakeLists.txt
@@ -66,6 +66,9 @@ add_executable(citra-qt
     configuration/configure_motion_touch.cpp
     configuration/configure_motion_touch.h
     configuration/configure_motion_touch.ui
+    configuration/configure_storage.cpp
+    configuration/configure_storage.h
+    configuration/configure_storage.ui
     configuration/configure_system.cpp
     configuration/configure_system.h
     configuration/configure_system.ui
diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp
index 2b5ab6cd3..28612bbd0 100644
--- a/src/citra_qt/configuration/config.cpp
+++ b/src/citra_qt/configuration/config.cpp
@@ -863,8 +863,10 @@ void Config::SaveDataStorageValues() {
 
     WriteSetting(QStringLiteral("use_virtual_sd"), Settings::values.use_virtual_sd, true);
     WriteSetting(QStringLiteral("nand_directory"),
+                 QString::fromStdString(Settings::values.nand_dir),
                  QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)));
     WriteSetting(QStringLiteral("sdmc_directory"),
+                 QString::fromStdString(Settings::values.sdmc_dir),
                  QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)));
 
     qt_config->endGroup();
diff --git a/src/citra_qt/configuration/configure.ui b/src/citra_qt/configuration/configure.ui
index efe53606e..1774ccbc1 100644
--- a/src/citra_qt/configuration/configure.ui
+++ b/src/citra_qt/configuration/configure.ui
@@ -68,6 +68,11 @@
          <string>Debug</string>
         </attribute>
        </widget>
+       <widget class="ConfigureStorage" name="storageTab">
+        <attribute name="title">
+         <string>Storage</string>
+        </attribute>
+       </widget>
        <widget class="ConfigureWeb" name="webTab">
         <attribute name="title">
          <string>Web</string>
@@ -121,6 +126,12 @@
    <extends>QWidget</extends>
    <header>configuration/configure_debug.h</header>
    <container>1</container>
+  </customwidget>
+    <customwidget>
+   <class>ConfigureStorage</class>
+   <extends>QWidget</extends>
+   <header>configuration/configure_storage.h</header>
+   <container>1</container>
   </customwidget>
   <customwidget>
    <class>ConfigureInput</class>
diff --git a/src/citra_qt/configuration/configure_dialog.cpp b/src/citra_qt/configuration/configure_dialog.cpp
index 7e84f83ad..66eb3ec83 100644
--- a/src/citra_qt/configuration/configure_dialog.cpp
+++ b/src/citra_qt/configuration/configure_dialog.cpp
@@ -51,6 +51,7 @@ void ConfigureDialog::SetConfiguration() {
     ui->debugTab->SetConfiguration();
     ui->webTab->SetConfiguration();
     ui->uiTab->SetConfiguration();
+    ui->storageTab->SetConfiguration();
 }
 
 void ConfigureDialog::ApplyConfiguration() {
@@ -66,6 +67,7 @@ void ConfigureDialog::ApplyConfiguration() {
     ui->debugTab->ApplyConfiguration();
     ui->webTab->ApplyConfiguration();
     ui->uiTab->ApplyConfiguration();
+    ui->storageTab->ApplyConfiguration();
     Settings::Apply();
     Settings::LogSettings();
 }
@@ -77,7 +79,7 @@ void ConfigureDialog::PopulateSelectionList() {
 
     const std::array<std::pair<QString, QList<QWidget*>>, 5> items{
         {{tr("General"), {ui->generalTab, ui->webTab, ui->debugTab, ui->uiTab}},
-         {tr("System"), {ui->systemTab, ui->cameraTab}},
+         {tr("System"), {ui->systemTab, ui->cameraTab, ui->storageTab}},
          {tr("Graphics"), {ui->enhancementsTab, ui->graphicsTab}},
          {tr("Audio"), {ui->audioTab}},
          {tr("Controls"), {ui->inputTab, ui->hotkeysTab}}}};
@@ -118,6 +120,7 @@ void ConfigureDialog::RetranslateUI() {
     ui->debugTab->RetranslateUI();
     ui->webTab->RetranslateUI();
     ui->uiTab->RetranslateUI();
+    ui->storageTab->RetranslateUI();
 }
 
 void ConfigureDialog::UpdateVisibleTabs() {
@@ -134,6 +137,7 @@ void ConfigureDialog::UpdateVisibleTabs() {
                                                  {ui->audioTab, tr("Audio")},
                                                  {ui->cameraTab, tr("Camera")},
                                                  {ui->debugTab, tr("Debug")},
+                                                 {ui->storageTab, tr("Storage")},
                                                  {ui->webTab, tr("Web")},
                                                  {ui->uiTab, tr("UI")}};
 
diff --git a/src/citra_qt/configuration/configure_storage.cpp b/src/citra_qt/configuration/configure_storage.cpp
new file mode 100644
index 000000000..f198f59f5
--- /dev/null
+++ b/src/citra_qt/configuration/configure_storage.cpp
@@ -0,0 +1,78 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <QDesktopServices>
+#include <QFileDialog>
+#include <QUrl>
+#include "citra_qt/configuration/configure_storage.h"
+#include "core/core.h"
+#include "core/settings.h"
+#include "ui_configure_storage.h"
+
+ConfigureStorage::ConfigureStorage(QWidget* parent)
+    : QWidget(parent), ui(std::make_unique<Ui::ConfigureStorage>()) {
+    ui->setupUi(this);
+    SetConfiguration();
+
+    connect(ui->open_nand_dir, &QPushButton::clicked, []() {
+        QString path = QString::fromStdString(Settings::values.nand_dir);
+        QDesktopServices::openUrl(QUrl::fromLocalFile(path));
+    });
+
+    connect(ui->change_nand_dir, &QPushButton::clicked, this, [this]() {
+        const QString dir_path = QFileDialog::getExistingDirectory(
+            this, tr("Select NAND Directory"), QString::fromStdString(Settings::values.nand_dir),
+            QFileDialog::ShowDirsOnly);
+        if (!dir_path.isEmpty()) {
+            Settings::values.nand_dir = dir_path.toStdString();
+            SetConfiguration();
+        }
+    });
+
+    connect(ui->open_sdmc_dir, &QPushButton::clicked, []() {
+        QString path = QString::fromStdString(Settings::values.sdmc_dir);
+        QDesktopServices::openUrl(QUrl::fromLocalFile(path));
+    });
+
+    connect(ui->change_sdmc_dir, &QPushButton::clicked, this, [this]() {
+        const QString dir_path = QFileDialog::getExistingDirectory(
+            this, tr("Select SDMC Directory"), QString::fromStdString(Settings::values.sdmc_dir),
+            QFileDialog::ShowDirsOnly);
+        if (!dir_path.isEmpty()) {
+            Settings::values.sdmc_dir = dir_path.toStdString();
+            SetConfiguration();
+        }
+    });
+
+    connect(ui->toggle_virtual_sd, &QCheckBox::clicked, this, [this]() {
+        ApplyConfiguration();
+        SetConfiguration();
+    });
+}
+
+ConfigureStorage::~ConfigureStorage() = default;
+
+void ConfigureStorage::SetConfiguration() {
+    ui->nand_group->setVisible(Settings::values.use_virtual_sd);
+    QString nand_path = QString::fromStdString(Settings::values.nand_dir);
+    ui->nand_dir_path->setText(nand_path);
+    ui->open_nand_dir->setEnabled(!Settings::values.nand_dir.empty());
+
+    ui->sdmc_group->setVisible(Settings::values.use_virtual_sd);
+    QString sdmc_path = QString::fromStdString(Settings::values.sdmc_dir);
+    ui->sdmc_dir_path->setText(sdmc_path);
+    ui->open_sdmc_dir->setEnabled(!Settings::values.sdmc_dir.empty());
+
+    ui->toggle_virtual_sd->setChecked(Settings::values.use_virtual_sd);
+
+    ui->storage_group->setEnabled(!Core::System::GetInstance().IsPoweredOn());
+}
+
+void ConfigureStorage::ApplyConfiguration() {
+    Settings::values.use_virtual_sd = ui->toggle_virtual_sd->isChecked();
+}
+
+void ConfigureStorage::RetranslateUI() {
+    ui->retranslateUi(this);
+}
\ No newline at end of file
diff --git a/src/citra_qt/configuration/configure_storage.h b/src/citra_qt/configuration/configure_storage.h
new file mode 100644
index 000000000..031ff926b
--- /dev/null
+++ b/src/citra_qt/configuration/configure_storage.h
@@ -0,0 +1,26 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <QWidget>
+
+namespace Ui {
+class ConfigureStorage;
+}
+
+class ConfigureStorage : public QWidget {
+    Q_OBJECT
+
+public:
+    explicit ConfigureStorage(QWidget* parent = nullptr);
+    ~ConfigureStorage() override;
+
+    void ApplyConfiguration();
+    void RetranslateUI();
+    void SetConfiguration();
+
+    std::unique_ptr<Ui::ConfigureStorage> ui;
+};
diff --git a/src/citra_qt/configuration/configure_storage.ui b/src/citra_qt/configuration/configure_storage.ui
new file mode 100644
index 000000000..c6f72dd5d
--- /dev/null
+++ b/src/citra_qt/configuration/configure_storage.ui
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ConfigureStorage</class>
+ <widget class="QWidget" name="ConfigureStorage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>681</width>
+    <height>375</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_1">
+   <item>
+    <layout class="QVBoxLayout" name="verticalLayout_2">
+     <item>
+      <widget class="QGroupBox" name="storage_group">
+       <property name="title">
+        <string>Storage</string>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout_3">
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_1">
+          <item>
+           <widget class="QCheckBox" name="toggle_virtual_sd">
+            <property name="text">
+             <string>Use Virtual SD</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <widget class="QGroupBox" name="nand_group">
+          <property name="title">
+           <string/>
+          </property>
+          <layout class="QVBoxLayout" name="verticalLayout">
+           <item>
+            <layout class="QHBoxLayout" name="horizontalLayout">
+             <item>
+              <widget class="QLabel" name="label">
+               <property name="text">
+                <string>NAND Directory</string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QLineEdit" name="nand_dir_path">
+               <property name="enabled">
+                <bool>false</bool>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QPushButton" name="open_nand_dir">
+               <property name="text">
+                <string>Open</string>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+           <item>
+            <layout class="QHBoxLayout" name="horizontalLayout_2">
+             <item>
+              <widget class="QLabel" name="label_4">
+               <property name="text">
+                <string>NOTE: this does not move the contents of the previous directory to the new one</string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <spacer name="horizontalSpacer_3">
+               <property name="orientation">
+                <enum>Qt::Horizontal</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>40</width>
+                 <height>20</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+             <item>
+              <widget class="QPushButton" name="change_nand_dir">
+               <property name="text">
+                <string>Change</string>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+          </layout>
+         </widget>
+        </item>
+        <item>
+         <widget class="QGroupBox" name="sdmc_group">
+          <property name="title">
+           <string/>
+          </property>
+          <layout class="QVBoxLayout" name="verticalLayout_4">
+           <item>
+            <layout class="QHBoxLayout" name="horizontalLayout_3">
+             <item>
+              <widget class="QLabel" name="label_2">
+               <property name="text">
+                <string>SDMC Directory</string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QLineEdit" name="sdmc_dir_path">
+               <property name="enabled">
+                <bool>false</bool>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QPushButton" name="open_sdmc_dir">
+               <property name="text">
+                <string>Open</string>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+           <item>
+            <layout class="QHBoxLayout" name="horizontalLayout_4">
+             <item>
+              <widget class="QLabel" name="label_3">
+               <property name="text">
+                <string>NOTE: this does not move the contents of the previous directory to the new one</string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <spacer name="horizontalSpacer_4">
+               <property name="orientation">
+                <enum>Qt::Horizontal</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>40</width>
+                 <height>20</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+             <item>
+              <widget class="QPushButton" name="change_sdmc_dir">
+               <property name="text">
+                <string>Change</string>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+          </layout>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>40</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

From b72e60a47f9b1bf784b9522a3d7dff6e31ef92d5 Mon Sep 17 00:00:00 2001
From: Daniel Mendez <nieldm@gmail.com>
Date: Sun, 18 Apr 2021 12:57:14 +0200
Subject: [PATCH 6/7] Update src/citra_qt/configuration/configure_storage.h

Co-authored-by: Ben <bene_thomas@web.de>
---
 src/citra_qt/configuration/configure_storage.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/citra_qt/configuration/configure_storage.h b/src/citra_qt/configuration/configure_storage.h
index 031ff926b..e79d3c008 100644
--- a/src/citra_qt/configuration/configure_storage.h
+++ b/src/citra_qt/configuration/configure_storage.h
@@ -1,4 +1,4 @@
-// Copyright 2016 Citra Emulator Project
+// Copyright 2021 Citra Emulator Project
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 

From 8981ca983f9464a8e48a68a0cccf097b01e3dac6 Mon Sep 17 00:00:00 2001
From: Daniel Mendez <nieldm@gmail.com>
Date: Sun, 18 Apr 2021 12:57:20 +0200
Subject: [PATCH 7/7] Update src/citra_qt/configuration/configure_storage.cpp

Co-authored-by: Ben <bene_thomas@web.de>
---
 src/citra_qt/configuration/configure_storage.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/citra_qt/configuration/configure_storage.cpp b/src/citra_qt/configuration/configure_storage.cpp
index f198f59f5..62e299a90 100644
--- a/src/citra_qt/configuration/configure_storage.cpp
+++ b/src/citra_qt/configuration/configure_storage.cpp
@@ -1,4 +1,4 @@
-// Copyright 2016 Citra Emulator Project
+// Copyright 2021 Citra Emulator Project
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
@@ -75,4 +75,4 @@ void ConfigureStorage::ApplyConfiguration() {
 
 void ConfigureStorage::RetranslateUI() {
     ui->retranslateUi(this);
-}
\ No newline at end of file
+}