summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2022-09-08 21:12:21 +0200
committerGitHub <noreply@github.com>2022-09-08 21:12:21 +0200
commitd4fe54147e65eb41ba85eb6a3bcfa252c0530be9 (patch)
tree7e333587ee72ff48652b3cee3013869003e5b8dc /Source
parent329d279c059f9c1bfc75cea1f350135f0e48c48c (diff)
parent650f1726373250e2e3a91ccb4f934cdc4a68280b (diff)
Merge pull request #10757 from AdmiralCurtiss/show-memcard-path-in-gui
Qt: Show currently configured Memory Card path in the config window.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/Config/MainSettings.cpp31
-rw-r--r--Source/Core/Core/Config/MainSettings.h8
-rw-r--r--Source/Core/DolphinQt/Settings/GameCubePane.cpp111
-rw-r--r--Source/Core/DolphinQt/Settings/GameCubePane.h13
4 files changed, 140 insertions, 23 deletions
diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp
index 01fd799846..7ed4be23ad 100644
--- a/Source/Core/Core/Config/MainSettings.cpp
+++ b/Source/Core/Core/Config/MainSettings.cpp
@@ -583,15 +583,15 @@ std::string GetBootROMPath(const std::string& region_directory)
return path;
}
-std::string GetMemcardPath(ExpansionInterface::Slot slot, DiscIO::Region region, u16 size_mb)
+std::string GetMemcardPath(ExpansionInterface::Slot slot, std::optional<DiscIO::Region> region,
+ u16 size_mb)
{
return GetMemcardPath(Config::Get(GetInfoForMemcardPath(slot)), slot, region, size_mb);
}
std::string GetMemcardPath(std::string configured_filename, ExpansionInterface::Slot slot,
- DiscIO::Region region, u16 size_mb)
+ std::optional<DiscIO::Region> region, u16 size_mb)
{
- const std::string region_dir = Config::GetDirectoryForRegion(Config::ToGameCubeRegion(region));
const std::string blocks_string = size_mb < Memcard::MBIT_SIZE_MEMORY_CARD_2043 ?
fmt::format(".{}", Memcard::MbitToFreeBlocks(size_mb)) :
"";
@@ -600,8 +600,10 @@ std::string GetMemcardPath(std::string configured_filename, ExpansionInterface::
{
// Use default memcard path if there is no user defined one.
const bool is_slot_a = slot == ExpansionInterface::Slot::A;
+ const std::string region_string = Config::GetDirectoryForRegion(
+ Config::ToGameCubeRegion(region ? *region : Config::Get(Config::MAIN_FALLBACK_REGION)));
return fmt::format("{}{}.{}{}.raw", File::GetUserPath(D_GCUSER_IDX),
- is_slot_a ? GC_MEMCARDA : GC_MEMCARDB, region_dir, blocks_string);
+ is_slot_a ? GC_MEMCARDA : GC_MEMCARDB, region_string, blocks_string);
}
// Custom path is expected to be stored in the form of
@@ -619,13 +621,32 @@ std::string GetMemcardPath(std::string configured_filename, ExpansionInterface::
constexpr std::string_view us_region = "." USA_DIR;
constexpr std::string_view jp_region = "." JAP_DIR;
constexpr std::string_view eu_region = "." EUR_DIR;
+ std::optional<DiscIO::Region> path_region = std::nullopt;
if (StringEndsWith(name, us_region))
+ {
name = name.substr(0, name.size() - us_region.size());
+ path_region = DiscIO::Region::NTSC_U;
+ }
else if (StringEndsWith(name, jp_region))
+ {
name = name.substr(0, name.size() - jp_region.size());
+ path_region = DiscIO::Region::NTSC_J;
+ }
else if (StringEndsWith(name, eu_region))
+ {
name = name.substr(0, name.size() - eu_region.size());
+ path_region = DiscIO::Region::PAL;
+ }
+
+ const DiscIO::Region used_region =
+ region ? *region : (path_region ? *path_region : Config::Get(Config::MAIN_FALLBACK_REGION));
+ return fmt::format("{}{}.{}{}{}", dir, name,
+ Config::GetDirectoryForRegion(Config::ToGameCubeRegion(used_region)),
+ blocks_string, ext);
+}
- return fmt::format("{}{}.{}{}{}", dir, name, region_dir, blocks_string, ext);
+bool IsDefaultMemcardPathConfigured(ExpansionInterface::Slot slot)
+{
+ return Config::Get(GetInfoForMemcardPath(slot)).empty();
}
} // namespace Config
diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h
index e731e891b7..197ae29688 100644
--- a/Source/Core/Core/Config/MainSettings.h
+++ b/Source/Core/Core/Config/MainSettings.h
@@ -343,8 +343,12 @@ DiscIO::Region ToGameCubeRegion(DiscIO::Region region);
// The region argument must be valid for GameCube (i.e. must not be NTSC-K)
const char* GetDirectoryForRegion(DiscIO::Region region);
std::string GetBootROMPath(const std::string& region_directory);
-std::string GetMemcardPath(ExpansionInterface::Slot slot, DiscIO::Region region,
+// Builds the memory card according to the configuration with the given region and size. If the
+// given region is std::nullopt, the region in the configured path is used if there is one, or the
+// fallback region otherwise.
+std::string GetMemcardPath(ExpansionInterface::Slot slot, std::optional<DiscIO::Region> region,
u16 size_mb = 0x80);
std::string GetMemcardPath(std::string configured_filename, ExpansionInterface::Slot slot,
- DiscIO::Region region, u16 size_mb = 0x80);
+ std::optional<DiscIO::Region> region, u16 size_mb = 0x80);
+bool IsDefaultMemcardPathConfigured(ExpansionInterface::Slot slot);
} // namespace Config
diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.cpp b/Source/Core/DolphinQt/Settings/GameCubePane.cpp
index cd5cd258df..cc2b8fbe5f 100644
--- a/Source/Core/DolphinQt/Settings/GameCubePane.cpp
+++ b/Source/Core/DolphinQt/Settings/GameCubePane.cpp
@@ -10,6 +10,7 @@
#include <QFormLayout>
#include <QGridLayout>
#include <QGroupBox>
+#include <QHBoxLayout>
#include <QInputDialog>
#include <QLabel>
#include <QLineEdit>
@@ -100,6 +101,21 @@ void GameCubePane::CreateWidgets()
m_slot_buttons[slot]->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
}
+ for (ExpansionInterface::Slot slot : ExpansionInterface::MEMCARD_SLOTS)
+ {
+ m_memcard_path_layouts[slot] = new QHBoxLayout();
+ m_memcard_path_labels[slot] = new QLabel(tr("Memory Card Path:"));
+ m_memcard_paths[slot] = new QLineEdit();
+ m_memcard_path_layouts[slot]->addWidget(m_memcard_path_labels[slot]);
+ m_memcard_path_layouts[slot]->addWidget(m_memcard_paths[slot]);
+
+ m_agp_path_layouts[slot] = new QHBoxLayout();
+ m_agp_path_labels[slot] = new QLabel(tr("GBA Cartridge Path:"));
+ m_agp_paths[slot] = new QLineEdit();
+ m_agp_path_layouts[slot]->addWidget(m_agp_path_labels[slot]);
+ m_agp_path_layouts[slot]->addWidget(m_agp_paths[slot]);
+ }
+
// Add slot devices
for (const auto device : {EXIDeviceType::None, EXIDeviceType::Dummy, EXIDeviceType::MemoryCard,
EXIDeviceType::MemoryCardFolder, EXIDeviceType::Gecko,
@@ -127,15 +143,34 @@ void GameCubePane::CreateWidgets()
static_cast<int>(device));
}
- device_layout->addWidget(new QLabel(tr("Slot A:")), 0, 0);
- device_layout->addWidget(m_slot_combos[ExpansionInterface::Slot::A], 0, 1);
- device_layout->addWidget(m_slot_buttons[ExpansionInterface::Slot::A], 0, 2);
- device_layout->addWidget(new QLabel(tr("Slot B:")), 1, 0);
- device_layout->addWidget(m_slot_combos[ExpansionInterface::Slot::B], 1, 1);
- device_layout->addWidget(m_slot_buttons[ExpansionInterface::Slot::B], 1, 2);
- device_layout->addWidget(new QLabel(tr("SP1:")), 2, 0);
- device_layout->addWidget(m_slot_combos[ExpansionInterface::Slot::SP1], 2, 1);
- device_layout->addWidget(m_slot_buttons[ExpansionInterface::Slot::SP1], 2, 2);
+ {
+ int row = 0;
+ device_layout->addWidget(new QLabel(tr("Slot A:")), row, 0);
+ device_layout->addWidget(m_slot_combos[ExpansionInterface::Slot::A], row, 1);
+ device_layout->addWidget(m_slot_buttons[ExpansionInterface::Slot::A], row, 2);
+
+ ++row;
+ device_layout->addLayout(m_memcard_path_layouts[ExpansionInterface::Slot::A], row, 0, 1, 3);
+
+ ++row;
+ device_layout->addLayout(m_agp_path_layouts[ExpansionInterface::Slot::A], row, 0, 1, 3);
+
+ ++row;
+ device_layout->addWidget(new QLabel(tr("Slot B:")), row, 0);
+ device_layout->addWidget(m_slot_combos[ExpansionInterface::Slot::B], row, 1);
+ device_layout->addWidget(m_slot_buttons[ExpansionInterface::Slot::B], row, 2);
+
+ ++row;
+ device_layout->addLayout(m_memcard_path_layouts[ExpansionInterface::Slot::B], row, 0, 1, 3);
+
+ ++row;
+ device_layout->addLayout(m_agp_path_layouts[ExpansionInterface::Slot::B], row, 0, 1, 3);
+
+ ++row;
+ device_layout->addWidget(new QLabel(tr("SP1:")), row, 0);
+ device_layout->addWidget(m_slot_combos[ExpansionInterface::Slot::SP1], row, 1);
+ device_layout->addWidget(m_slot_buttons[ExpansionInterface::Slot::SP1], row, 2);
+ }
#ifdef HAS_LIBMGBA
// GBA Settings
@@ -205,6 +240,17 @@ void GameCubePane::ConnectWidgets()
connect(m_slot_buttons[slot], &QPushButton::clicked, [this, slot] { OnConfigPressed(slot); });
}
+ for (ExpansionInterface::Slot slot : ExpansionInterface::MEMCARD_SLOTS)
+ {
+ connect(m_memcard_paths[slot], &QLineEdit::editingFinished, [this, slot] {
+ // revert path change on failure
+ if (!SetMemcard(slot, m_memcard_paths[slot]->text()))
+ LoadSettings();
+ });
+ connect(m_agp_paths[slot], &QLineEdit::editingFinished,
+ [this, slot] { SetAGPRom(slot, m_agp_paths[slot]->text()); });
+ }
+
#ifdef HAS_LIBMGBA
// GBA Settings
connect(m_gba_threads, &QCheckBox::stateChanged, this, &GameCubePane::SaveSettings);
@@ -254,10 +300,18 @@ void GameCubePane::UpdateButton(ExpansionInterface::Slot slot)
{
case ExpansionInterface::Slot::A:
case ExpansionInterface::Slot::B:
+ {
has_config = (device == ExpansionInterface::EXIDeviceType::MemoryCard ||
device == ExpansionInterface::EXIDeviceType::AGP ||
device == ExpansionInterface::EXIDeviceType::Microphone);
+ const bool hide_memory_card = device != ExpansionInterface::EXIDeviceType::MemoryCard ||
+ Config::IsDefaultMemcardPathConfigured(slot);
+ m_memcard_path_labels[slot]->setHidden(hide_memory_card);
+ m_memcard_paths[slot]->setHidden(hide_memory_card);
+ m_agp_path_labels[slot]->setHidden(device != ExpansionInterface::EXIDeviceType::AGP);
+ m_agp_paths[slot]->setHidden(device != ExpansionInterface::EXIDeviceType::AGP);
break;
+ }
case ExpansionInterface::Slot::SP1:
has_config = (device == ExpansionInterface::EXIDeviceType::Ethernet ||
device == ExpansionInterface::EXIDeviceType::EthernetXLink ||
@@ -315,8 +369,17 @@ void GameCubePane::BrowseMemcard(ExpansionInterface::Slot slot)
QString::fromStdString(File::GetUserPath(D_GCUSER_IDX)),
tr("GameCube Memory Cards (*.raw *.gcp)"), 0, QFileDialog::DontConfirmOverwrite);
+ if (!filename.isEmpty())
+ SetMemcard(slot, filename);
+}
+
+bool GameCubePane::SetMemcard(ExpansionInterface::Slot slot, const QString& filename)
+{
if (filename.isEmpty())
- return;
+ {
+ ModalMessageBox::critical(this, tr("Error"), tr("Cannot set memory card to an empty path."));
+ return false;
+ }
const std::string raw_path =
WithUnifiedPathSeparators(QFileInfo(filename).absoluteFilePath().toStdString());
@@ -338,7 +401,7 @@ void GameCubePane::BrowseMemcard(ExpansionInterface::Slot slot)
.arg(QString::fromStdString(PathToFileName(us_path)))
.arg(QString::fromStdString(PathToFileName(eu_path)))
.arg(QString::fromStdString(PathToFileName(jp_path))));
- return;
+ return false;
}
// Memcard validity checks
@@ -355,7 +418,7 @@ void GameCubePane::BrowseMemcard(ExpansionInterface::Slot slot)
tr("The file\n%1\nis either corrupted or not a GameCube memory card file.\n%2")
.arg(QString::fromStdString(path))
.arg(GCMemcardManager::GetErrorMessagesForErrorCode(error_code)));
- return;
+ return false;
}
}
}
@@ -375,7 +438,7 @@ void GameCubePane::BrowseMemcard(ExpansionInterface::Slot slot)
this, tr("Error"),
tr("The same file can't be used in multiple slots; it is already used by %1.")
.arg(QString::fromStdString(fmt::to_string(other_slot))));
- return;
+ return false;
}
}
@@ -394,6 +457,9 @@ void GameCubePane::BrowseMemcard(ExpansionInterface::Slot slot)
ExpansionInterface::ChangeDevice(slot, ExpansionInterface::EXIDeviceType::MemoryCard);
}
}
+
+ LoadSettings();
+ return true;
}
void GameCubePane::BrowseAGPRom(ExpansionInterface::Slot slot)
@@ -404,10 +470,13 @@ void GameCubePane::BrowseAGPRom(ExpansionInterface::Slot slot)
this, tr("Choose a file to open"), QString::fromStdString(File::GetUserPath(D_GCUSER_IDX)),
tr("Game Boy Advance Carts (*.gba)"), 0, QFileDialog::DontConfirmOverwrite);
- if (filename.isEmpty())
- return;
+ if (!filename.isEmpty())
+ SetAGPRom(slot, filename);
+}
- QString path_abs = QFileInfo(filename).absoluteFilePath();
+void GameCubePane::SetAGPRom(ExpansionInterface::Slot slot, const QString& filename)
+{
+ QString path_abs = filename.isEmpty() ? QString() : QFileInfo(filename).absoluteFilePath();
QString path_old =
QFileInfo(QString::fromStdString(Config::Get(Config::GetInfoForAGPCartPath(slot))))
@@ -423,6 +492,8 @@ void GameCubePane::BrowseAGPRom(ExpansionInterface::Slot slot)
// we might as well do it for the AGP too.
ExpansionInterface::ChangeDevice(slot, ExpansionInterface::EXIDeviceType::AGP);
}
+
+ LoadSettings();
}
void GameCubePane::BrowseGBABios()
@@ -499,6 +570,14 @@ void GameCubePane::LoadSettings()
UpdateButton(slot);
}
+ for (ExpansionInterface::Slot slot : ExpansionInterface::MEMCARD_SLOTS)
+ {
+ SignalBlocking(m_memcard_paths[slot])
+ ->setText(QString::fromStdString(Config::GetMemcardPath(slot, std::nullopt)));
+ SignalBlocking(m_agp_paths[slot])
+ ->setText(QString::fromStdString(Config::Get(Config::GetInfoForAGPCartPath(slot))));
+ }
+
#ifdef HAS_LIBMGBA
// GBA Settings
SignalBlocking(m_gba_threads)->setChecked(Config::Get(Config::MAIN_GBA_THREADS));
diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.h b/Source/Core/DolphinQt/Settings/GameCubePane.h
index 2bffc02bde..4ed1934e1c 100644
--- a/Source/Core/DolphinQt/Settings/GameCubePane.h
+++ b/Source/Core/DolphinQt/Settings/GameCubePane.h
@@ -14,8 +14,11 @@
class QCheckBox;
class QComboBox;
+class QHBoxLayout;
+class QLabel;
class QLineEdit;
class QPushButton;
+class QString;
class GameCubePane : public QWidget
{
@@ -38,7 +41,9 @@ private:
void OnConfigPressed(ExpansionInterface::Slot slot);
void BrowseMemcard(ExpansionInterface::Slot slot);
+ bool SetMemcard(ExpansionInterface::Slot slot, const QString& filename);
void BrowseAGPRom(ExpansionInterface::Slot slot);
+ void SetAGPRom(ExpansionInterface::Slot slot, const QString& filename);
void BrowseGBABios();
void BrowseGBARom(size_t index);
void SaveRomPathChanged();
@@ -50,6 +55,14 @@ private:
Common::EnumMap<QPushButton*, ExpansionInterface::MAX_SLOT> m_slot_buttons;
Common::EnumMap<QComboBox*, ExpansionInterface::MAX_SLOT> m_slot_combos;
+ Common::EnumMap<QHBoxLayout*, ExpansionInterface::MAX_MEMCARD_SLOT> m_memcard_path_layouts;
+ Common::EnumMap<QLabel*, ExpansionInterface::MAX_MEMCARD_SLOT> m_memcard_path_labels;
+ Common::EnumMap<QLineEdit*, ExpansionInterface::MAX_MEMCARD_SLOT> m_memcard_paths;
+
+ Common::EnumMap<QHBoxLayout*, ExpansionInterface::MAX_MEMCARD_SLOT> m_agp_path_layouts;
+ Common::EnumMap<QLabel*, ExpansionInterface::MAX_MEMCARD_SLOT> m_agp_path_labels;
+ Common::EnumMap<QLineEdit*, ExpansionInterface::MAX_MEMCARD_SLOT> m_agp_paths;
+
QCheckBox* m_gba_threads;
QCheckBox* m_gba_save_rom_path;
QPushButton* m_gba_browse_bios;