Partially implement configuring the SD card path

This doesn't work (changes aren't saved to disk), and I don't fully understand why...
This commit is contained in:
Pokechu22 2020-09-04 15:58:43 -07:00
parent 8d7d7ab5e9
commit f8e57a9de3
9 changed files with 125 additions and 8 deletions

View File

@ -111,6 +111,21 @@ const Info<std::string>& GetInfoForGCIPathOverride(ExpansionInterface::Slot slot
const Info<int> MAIN_MEMORY_CARD_SIZE{{System::Main, "Core", "MemoryCardSize"}, -1};
const Info<std::string> MAIN_SLOT_A_SD_CARD_PATH{{System::Main, "Core", "SlotASDCardPath"}, ""};
const Info<std::string> MAIN_SLOT_B_SD_CARD_PATH{{System::Main, "Core", "SlotBSDCardPath"}, ""};
const Info<std::string> MAIN_SP2_SD_CARD_PATH{{System::Main, "Core", "SP2SDCardPath"}, ""};
const Info<std::string>& GetInfoForSDCardPath(ExpansionInterface::Slot slot)
{
ASSERT(slot != ExpansionInterface::Slot::SP1);
static constexpr Common::EnumMap<const Info<std::string>*, ExpansionInterface::MAX_SLOT> infos{
&MAIN_SLOT_A_SD_CARD_PATH,
&MAIN_SLOT_B_SD_CARD_PATH,
nullptr,
&MAIN_SP2_SD_CARD_PATH,
};
return *infos[slot];
}
const Info<ExpansionInterface::EXIDeviceType> MAIN_SLOT_A{
{System::Main, "Core", "SlotA"}, ExpansionInterface::EXIDeviceType::MemoryCardFolder};
const Info<ExpansionInterface::EXIDeviceType> MAIN_SLOT_B{{System::Main, "Core", "SlotB"},

View File

@ -87,6 +87,10 @@ extern const Info<std::string> MAIN_GCI_FOLDER_A_PATH_OVERRIDE;
extern const Info<std::string> MAIN_GCI_FOLDER_B_PATH_OVERRIDE;
const Info<std::string>& GetInfoForGCIPathOverride(ExpansionInterface::Slot slot);
extern const Info<int> MAIN_MEMORY_CARD_SIZE;
extern const Info<std::string> MAIN_SLOT_A_SD_CARD_PATH;
extern const Info<std::string> MAIN_SLOT_B_SD_CARD_PATH;
extern const Info<std::string> MAIN_SP2_SD_CARD_PATH;
const Info<std::string>& GetInfoForSDCardPath(ExpansionInterface::Slot slot);
extern const Info<ExpansionInterface::EXIDeviceType> MAIN_SLOT_A;
extern const Info<ExpansionInterface::EXIDeviceType> MAIN_SLOT_B;
extern const Info<ExpansionInterface::EXIDeviceType> MAIN_SERIAL_PORT_1;

View File

@ -164,7 +164,7 @@ std::unique_ptr<IEXIDevice> EXIDevice_Create(Core::System& system, const EXIDevi
break;
case EXIDeviceType::SD:
result = std::make_unique<CEXISD>(system);
result = std::make_unique<CEXISD>(system, channel_num);
break;
case EXIDeviceType::AMBaseboard:

View File

@ -9,16 +9,30 @@
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "Common/Config/Config.h"
#include "Common/FileUtil.h"
#include "Common/Hash.h"
#include "Common/IOFile.h"
#include "Common/Logging/Log.h"
#include "Core/Config/MainSettings.h"
namespace ExpansionInterface
{
CEXISD::CEXISD(Core::System& system) : IEXIDevice(system)
CEXISD::CEXISD(Core::System& system, int channel_num) : IEXIDevice(system)
{
const std::string filename = File::GetUserPath(D_GCUSER_IDX) + "sdcard.bin";
ASSERT_MSG(EXPANSIONINTERFACE, 0 <= channel_num && channel_num <= 2,
"Trying to create invalid SD card index {}.", channel_num);
// TODO: I don't like using channel_num here; Slot would be better
std::string filename;
if (channel_num == 0)
filename = Config::Get(Config::MAIN_SLOT_A_SD_CARD_PATH);
else if (channel_num == 1)
filename = Config::Get(Config::MAIN_SLOT_B_SD_CARD_PATH);
else
filename = Config::Get(Config::MAIN_SP2_SD_CARD_PATH);
m_card.Open(filename, "r+b");
if (!m_card)
{

View File

@ -21,7 +21,7 @@ namespace ExpansionInterface
class CEXISD final : public IEXIDevice
{
public:
explicit CEXISD(Core::System& system);
explicit CEXISD(Core::System& system, int channel_num);
void ImmWrite(u32 data, u32 size) override;
u32 ImmRead(u32 size) override;

View File

@ -342,7 +342,8 @@ void GameCubePane::UpdateButton(ExpansionInterface::Slot slot)
has_config = (device == ExpansionInterface::EXIDeviceType::MemoryCard ||
device == ExpansionInterface::EXIDeviceType::MemoryCardFolder ||
device == ExpansionInterface::EXIDeviceType::AGP ||
device == ExpansionInterface::EXIDeviceType::Microphone);
device == ExpansionInterface::EXIDeviceType::Microphone ||
device == ExpansionInterface::EXIDeviceType::SD);
const bool hide_memory_card = device != ExpansionInterface::EXIDeviceType::MemoryCard ||
Config::IsDefaultMemcardPathConfigured(slot);
const bool hide_gci_path = device != ExpansionInterface::EXIDeviceType::MemoryCardFolder ||
@ -372,7 +373,7 @@ void GameCubePane::UpdateButton(ExpansionInterface::Slot slot)
device == ExpansionInterface::EXIDeviceType::ModemTapServer);
break;
case ExpansionInterface::Slot::SP2:
has_config = false; // TODO
has_config = (device == ExpansionInterface::EXIDeviceType::SD);
break;
}
@ -395,6 +396,9 @@ void GameCubePane::OnConfigPressed(ExpansionInterface::Slot slot)
case ExpansionInterface::EXIDeviceType::AGP:
BrowseAGPRom(slot);
return;
case ExpansionInterface::EXIDeviceType::SD:
BrowseSDCard(slot);
return;
case ExpansionInterface::EXIDeviceType::Microphone:
{
// TODO: convert MappingWindow to use Slot?
@ -690,6 +694,71 @@ void GameCubePane::SetAGPRom(ExpansionInterface::Slot slot, const QString& filen
LoadSettings();
}
void GameCubePane::BrowseSDCard(ExpansionInterface::Slot slot)
{
ASSERT(slot != ExpansionInterface::Slot::SP1);
QString filename = DolphinFileDialog::getSaveFileName(
this, tr("Choose a file to open"), QString::fromStdString(File::GetUserPath(D_GCUSER_IDX)),
tr("SD Card Image (*.raw)"), 0, QFileDialog::DontConfirmOverwrite);
if (filename.isEmpty())
return;
QString path_abs = QFileInfo(filename).absoluteFilePath();
for (ExpansionInterface::Slot other_slot : ExpansionInterface::SLOTS)
{
if (other_slot == slot || other_slot == ExpansionInterface::Slot::SP1)
continue;
bool other_slot_sd = m_slot_combos[other_slot]->currentData().toInt() ==
static_cast<int>(ExpansionInterface::EXIDeviceType::SD);
if (other_slot_sd)
{
QString path_other =
QFileInfo(QString::fromStdString(Config::Get(Config::GetInfoForSDCardPath(other_slot))))
.absoluteFilePath();
if (path_abs == path_other)
{
ModalMessageBox::critical(
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;
}
}
}
QString path_wii =
QFileInfo(QString::fromStdString(Config::Get(Config::MAIN_WII_SD_CARD_IMAGE_PATH)))
.absoluteFilePath();
if (path_abs == path_wii)
{
ModalMessageBox::critical(this, tr("Error"),
tr("The same file can't be used in multiple slots; it is already "
"used by the Wii SD slot."));
return;
}
QString path_old =
QFileInfo(QString::fromStdString(Config::Get(Config::GetInfoForSDCardPath(slot))))
.absoluteFilePath();
Config::SetBase(Config::GetInfoForSDCardPath(slot), path_abs.toStdString());
auto& system = Core::System::GetInstance();
if (Core::IsRunning(system) && path_abs != path_old)
{
// ChangeDevice unplugs the device for 1 second, which means that games should notice that
// the path has changed and thus the sd card contents have changed
// (not sure if anything actually checks for this)
Core::System::GetInstance().GetExpansionInterface().ChangeDevice(
slot, ExpansionInterface::EXIDeviceType::SD);
}
}
void GameCubePane::BrowseGBABios()
{
QString file = QDir::toNativeSeparators(DolphinFileDialog::getOpenFileName(

View File

@ -47,6 +47,7 @@ private:
bool SetGCIFolder(ExpansionInterface::Slot slot, const QString& path);
void BrowseAGPRom(ExpansionInterface::Slot slot);
void SetAGPRom(ExpansionInterface::Slot slot, const QString& filename);
void BrowseSDCard(ExpansionInterface::Slot slot);
void BrowseGBABios();
void BrowseGBARom(size_t index);
void SaveRomPathChanged();

View File

@ -19,6 +19,7 @@
#include "Core/Config/UISettings.h"
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/Settings.h"

View File

@ -513,8 +513,21 @@ void WiiPane::BrowseSDRaw()
void WiiPane::SetSDRaw(const QString& path)
{
Config::SetBase(Config::MAIN_WII_SD_CARD_IMAGE_PATH, path.toStdString());
SignalBlocking(m_sd_raw_edit)->setText(path);
const auto str = path.toStdString();
if (str == Config::Get(Config::MAIN_SLOT_A_SD_CARD_PATH) ||
str == Config::Get(Config::MAIN_SLOT_B_SD_CARD_PATH) ||
str == Config::Get(Config::MAIN_SP2_SD_CARD_PATH))
{
ModalMessageBox::critical(this, tr("Error"),
tr("The same file can't be used in multiple slots."));
SignalBlocking(m_sd_raw_edit)
->setText(QString::fromStdString(Config::Get(Config::MAIN_WII_SD_CARD_IMAGE_PATH)));
}
else
{
Config::SetBase(Config::MAIN_WII_SD_CARD_IMAGE_PATH, str);
SignalBlocking(m_sd_raw_edit)->setText(path);
}
}
void WiiPane::BrowseSDSyncFolder()