From 777bb4d82cc42da12799bfb7ab62617bb712671c Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 11 Jan 2022 11:17:47 -0800 Subject: [PATCH] Use Slot in EXI devices --- Source/Core/Core/BootManager.cpp | 7 +- Source/Core/Core/Config/MainSettings.cpp | 31 +++++ Source/Core/Core/Config/MainSettings.h | 3 + Source/Core/Core/HW/EXI/EXI.cpp | 30 +++-- Source/Core/Core/HW/EXI/EXI.h | 12 +- Source/Core/Core/HW/EXI/EXI_Channel.cpp | 13 +- Source/Core/Core/HW/EXI/EXI_Channel.h | 1 - Source/Core/Core/HW/EXI/EXI_Device.cpp | 12 +- Source/Core/Core/HW/EXI/EXI_Device.h | 2 - Source/Core/Core/HW/EXI/EXI_DeviceAGP.cpp | 15 ++- Source/Core/Core/HW/EXI/EXI_DeviceAGP.h | 6 +- .../Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp | 115 ++++++++---------- .../Core/Core/HW/EXI/EXI_DeviceMemoryCard.h | 9 +- Source/Core/Core/HW/GCMemcard/GCMemcardBase.h | 7 +- .../Core/HW/GCMemcard/GCMemcardDirectory.cpp | 9 +- .../Core/HW/GCMemcard/GCMemcardDirectory.h | 6 +- .../Core/Core/HW/GCMemcard/GCMemcardRaw.cpp | 25 ++-- Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h | 5 +- Source/Core/Core/HW/Sram.cpp | 19 ++- Source/Core/Core/HW/Sram.h | 8 +- Source/Core/Core/Movie.cpp | 21 +++- Source/Core/Core/Movie.h | 7 +- Source/Core/Core/NetPlayServer.cpp | 5 +- Source/Core/DolphinQt/GameList/GameList.cpp | 7 +- .../Core/DolphinQt/Settings/GameCubePane.cpp | 12 +- 25 files changed, 219 insertions(+), 168 deletions(-) diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp index 1a16b7e95a..7ca13a7729 100644 --- a/Source/Core/Core/BootManager.cpp +++ b/Source/Core/Core/BootManager.cpp @@ -156,12 +156,13 @@ bool BootCore(std::unique_ptr boot, const WindowSystemInfo& wsi) // Movie settings if (Movie::IsPlayingInput() && Movie::IsConfigSaved()) { - for (int i = 0; i < 2; ++i) + for (ExpansionInterface::Slot slot : ExpansionInterface::MEMCARD_SLOTS) { - if (Movie::IsUsingMemcard(i) && Movie::IsStartingFromClearSave() && !StartUp.bWii) + if (Movie::IsUsingMemcard(slot) && Movie::IsStartingFromClearSave() && !StartUp.bWii) { const auto raw_path = - File::GetUserPath(D_GCUSER_IDX) + fmt::format("Movie{}.raw", (i == 0) ? 'A' : 'B'); + File::GetUserPath(D_GCUSER_IDX) + + fmt::format("Movie{}.raw", slot == ExpansionInterface::Slot::A ? 'A' : 'B'); if (File::Exists(raw_path)) File::Delete(raw_path); diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp index 023f0ebf5b..650592f1da 100644 --- a/Source/Core/Core/Config/MainSettings.cpp +++ b/Source/Core/Core/Config/MainSettings.cpp @@ -8,6 +8,7 @@ #include #include "AudioCommon/AudioCommon.h" +#include "Common/Assert.h" #include "Common/CommonPaths.h" #include "Common/Config/Config.h" #include "Common/EnumMap.h" @@ -50,12 +51,42 @@ const Info MAIN_AUDIO_STRETCH{{System::Main, "Core", "AudioStretch"}, fals const Info MAIN_AUDIO_STRETCH_LATENCY{{System::Main, "Core", "AudioStretchMaxLatency"}, 80}; const Info MAIN_MEMCARD_A_PATH{{System::Main, "Core", "MemcardAPath"}, ""}; const Info MAIN_MEMCARD_B_PATH{{System::Main, "Core", "MemcardBPath"}, ""}; +const Info& GetInfoForMemcardPath(ExpansionInterface::Slot slot) +{ + ASSERT(ExpansionInterface::IsMemcardSlot(slot)); + static constexpr Common::EnumMap*, ExpansionInterface::MAX_MEMCARD_SLOT> + infos{ + &MAIN_MEMCARD_A_PATH, + &MAIN_MEMCARD_B_PATH, + }; + return *infos[slot]; +} const Info MAIN_AGP_CART_A_PATH{{System::Main, "Core", "AgpCartAPath"}, ""}; const Info MAIN_AGP_CART_B_PATH{{System::Main, "Core", "AgpCartBPath"}, ""}; +const Info& GetInfoForAGPCartPath(ExpansionInterface::Slot slot) +{ + ASSERT(ExpansionInterface::IsMemcardSlot(slot)); + static constexpr Common::EnumMap*, ExpansionInterface::MAX_MEMCARD_SLOT> + infos{ + &MAIN_AGP_CART_A_PATH, + &MAIN_AGP_CART_B_PATH, + }; + return *infos[slot]; +} const Info MAIN_GCI_FOLDER_A_PATH_OVERRIDE{ {System::Main, "Core", "GCIFolderAPathOverride"}, ""}; const Info MAIN_GCI_FOLDER_B_PATH_OVERRIDE{ {System::Main, "Core", "GCIFolderBPathOverride"}, ""}; +const Info& GetInfoForGCIPathOverride(ExpansionInterface::Slot slot) +{ + ASSERT(ExpansionInterface::IsMemcardSlot(slot)); + static constexpr Common::EnumMap*, ExpansionInterface::MAX_MEMCARD_SLOT> + infos{ + &MAIN_GCI_FOLDER_A_PATH_OVERRIDE, + &MAIN_GCI_FOLDER_B_PATH_OVERRIDE, + }; + return *infos[slot]; +} const Info MAIN_SLOT_A{ {System::Main, "Core", "SlotA"}, ExpansionInterface::EXIDeviceType::MemoryCardFolder}; diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h index 23c3017c68..8a2b8be500 100644 --- a/Source/Core/Core/Config/MainSettings.h +++ b/Source/Core/Core/Config/MainSettings.h @@ -66,10 +66,13 @@ extern const Info MAIN_AUDIO_STRETCH; extern const Info MAIN_AUDIO_STRETCH_LATENCY; extern const Info MAIN_MEMCARD_A_PATH; extern const Info MAIN_MEMCARD_B_PATH; +const Info& GetInfoForMemcardPath(ExpansionInterface::Slot slot); extern const Info MAIN_AGP_CART_A_PATH; extern const Info MAIN_AGP_CART_B_PATH; +const Info& GetInfoForAGPCartPath(ExpansionInterface::Slot slot); extern const Info MAIN_GCI_FOLDER_A_PATH_OVERRIDE; extern const Info MAIN_GCI_FOLDER_B_PATH_OVERRIDE; +const Info& GetInfoForGCIPathOverride(ExpansionInterface::Slot slot); extern const Info MAIN_SLOT_A; extern const Info MAIN_SLOT_B; extern const Info MAIN_SERIAL_PORT_1; diff --git a/Source/Core/Core/HW/EXI/EXI.cpp b/Source/Core/Core/HW/EXI/EXI.cpp index 7ffd639b2d..9e1a03e08f 100644 --- a/Source/Core/Core/HW/EXI/EXI.cpp +++ b/Source/Core/Core/HW/EXI/EXI.cpp @@ -39,15 +39,14 @@ static void UpdateInterruptsCallback(u64 userdata, s64 cycles_late); namespace { -void AddMemoryCards(int i) +void AddMemoryCard(Slot slot) { EXIDeviceType memorycard_device; if (Movie::IsPlayingInput() && Movie::IsConfigSaved()) { - if (Movie::IsUsingMemcard(i)) + if (Movie::IsUsingMemcard(slot)) { - if (Config::Get(Config::GetInfoForEXIDevice(static_cast(i))) == - EXIDeviceType::MemoryCardFolder) + if (Config::Get(Config::GetInfoForEXIDevice(slot)) == EXIDeviceType::MemoryCardFolder) memorycard_device = EXIDeviceType::MemoryCardFolder; else memorycard_device = EXIDeviceType::MemoryCard; @@ -59,10 +58,10 @@ void AddMemoryCards(int i) } else { - memorycard_device = Config::Get(Config::GetInfoForEXIDevice(static_cast(i))); + memorycard_device = Config::Get(Config::GetInfoForEXIDevice(slot)); } - g_Channels[i]->AddDevice(memorycard_device, 0); + g_Channels[SlotToEXIChannel(slot)]->AddDevice(memorycard_device, SlotToEXIDevice(slot)); } } // namespace @@ -132,7 +131,7 @@ void Init() } for (Slot slot : MEMCARD_SLOTS) - AddMemoryCards(static_cast(slot)); + AddMemoryCard(slot); g_Channels[0]->AddDevice(EXIDeviceType::MaskROM, 1); g_Channels[SlotToEXIChannel(Slot::SP1)]->AddDevice(Config::Get(Config::MAIN_SERIAL_PORT_1), @@ -186,7 +185,12 @@ static void ChangeDeviceCallback(u64 userdata, s64 cyclesLate) g_Channels.at(channel)->AddDevice(static_cast(type), num); } -void ChangeDevice(const u8 channel, const EXIDeviceType device_type, const u8 device_num, +void ChangeDevice(Slot slot, EXIDeviceType device_type, CoreTiming::FromThread from_thread) +{ + ChangeDevice(SlotToEXIChannel(slot), SlotToEXIDevice(slot), device_type, from_thread); +} + +void ChangeDevice(u8 channel, u8 device_num, EXIDeviceType device_type, CoreTiming::FromThread from_thread) { // Let the hardware see no device for 1 second @@ -203,15 +207,9 @@ CEXIChannel* GetChannel(u32 index) return g_Channels.at(index).get(); } -IEXIDevice* FindDevice(EXIDeviceType device_type, int customIndex) +IEXIDevice* GetDevice(Slot slot) { - for (auto& channel : g_Channels) - { - IEXIDevice* device = channel->FindDevice(device_type, customIndex); - if (device) - return device; - } - return nullptr; + return g_Channels.at(SlotToEXIChannel(slot))->GetDevice(1 << SlotToEXIDevice(slot)); } void UpdateInterrupts() diff --git a/Source/Core/Core/HW/EXI/EXI.h b/Source/Core/Core/HW/EXI/EXI.h index 4484205044..f466b0428b 100644 --- a/Source/Core/Core/HW/EXI/EXI.h +++ b/Source/Core/Core/HW/EXI/EXI.h @@ -40,6 +40,11 @@ enum class Slot : int static constexpr auto SLOTS = {Slot::A, Slot::B, Slot::SP1}; static constexpr auto MAX_SLOT = Slot::SP1; static constexpr auto MEMCARD_SLOTS = {Slot::A, Slot::B}; +static constexpr auto MAX_MEMCARD_SLOT = Slot::B; +constexpr bool IsMemcardSlot(Slot slot) +{ + return slot == Slot::A || slot == Slot::B; +} u8 SlotToEXIChannel(Slot slot); u8 SlotToEXIDevice(Slot slot); @@ -54,12 +59,13 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base); void UpdateInterrupts(); void ScheduleUpdateInterrupts(CoreTiming::FromThread from, int cycles_late); -void ChangeDevice(const u8 channel, const EXIDeviceType device_type, const u8 device_num, +void ChangeDevice(Slot slot, EXIDeviceType device_type, + CoreTiming::FromThread from_thread = CoreTiming::FromThread::NON_CPU); +void ChangeDevice(u8 channel, u8 device_num, EXIDeviceType device_type, CoreTiming::FromThread from_thread = CoreTiming::FromThread::NON_CPU); CEXIChannel* GetChannel(u32 index); - -IEXIDevice* FindDevice(EXIDeviceType device_type, int customIndex = -1); +IEXIDevice* GetDevice(Slot slot); } // namespace ExpansionInterface diff --git a/Source/Core/Core/HW/EXI/EXI_Channel.cpp b/Source/Core/Core/HW/EXI/EXI_Channel.cpp index c7a0de6ebb..ccc85a42aa 100644 --- a/Source/Core/Core/HW/EXI/EXI_Channel.cpp +++ b/Source/Core/Core/HW/EXI/EXI_Channel.cpp @@ -278,7 +278,7 @@ void CEXIChannel::DoState(PointerWrap& p) // the new device type are identical in this case. I assume there is a reason we have this // grace period when switching in the GUI. AddDevice(EXIDeviceType::None, device_index); - ExpansionInterface::ChangeDevice(m_channel_id, EXIDeviceType::MemoryCardFolder, device_index, + ExpansionInterface::ChangeDevice(m_channel_id, device_index, EXIDeviceType::MemoryCardFolder, CoreTiming::FromThread::CPU); } } @@ -294,15 +294,4 @@ void CEXIChannel::SetEXIINT(bool exiint) { m_status.EXIINT = !!exiint; } - -IEXIDevice* CEXIChannel::FindDevice(EXIDeviceType device_type, int custom_index) -{ - for (auto& sup : m_devices) - { - IEXIDevice* device = sup->FindDevice(device_type, custom_index); - if (device) - return device; - } - return nullptr; -} } // namespace ExpansionInterface diff --git a/Source/Core/Core/HW/EXI/EXI_Channel.h b/Source/Core/Core/HW/EXI/EXI_Channel.h index 11c25ad348..96596a4db6 100644 --- a/Source/Core/Core/HW/EXI/EXI_Channel.h +++ b/Source/Core/Core/HW/EXI/EXI_Channel.h @@ -30,7 +30,6 @@ public: // get device IEXIDevice* GetDevice(u8 chip_select); - IEXIDevice* FindDevice(EXIDeviceType device_type, int custom_index = -1); void RegisterMMIO(MMIO::Mapping* mmio, u32 base); diff --git a/Source/Core/Core/HW/EXI/EXI_Device.cpp b/Source/Core/Core/HW/EXI/EXI_Device.cpp index ce25067934..e43d47a8b3 100644 --- a/Source/Core/Core/HW/EXI/EXI_Device.cpp +++ b/Source/Core/Core/HW/EXI/EXI_Device.cpp @@ -64,11 +64,6 @@ void IEXIDevice::DMARead(u32 address, u32 size) } } -IEXIDevice* IEXIDevice::FindDevice(EXIDeviceType device_type, int custom_index) -{ - return (device_type == m_device_type) ? this : nullptr; -} - bool IEXIDevice::UseDelayedTransferCompletion() const { return false; @@ -105,6 +100,9 @@ std::unique_ptr EXIDevice_Create(const EXIDeviceType device_type, co const Memcard::HeaderData& memcard_header_data) { std::unique_ptr result; + // XXX This computation isn't necessarily right (it holds for A/B, but not SP1) + // However, the devices that care about slots currently only go in A/B. + const Slot slot = static_cast(channel_num); switch (device_type) { @@ -116,7 +114,7 @@ std::unique_ptr EXIDevice_Create(const EXIDeviceType device_type, co case EXIDeviceType::MemoryCardFolder: { bool gci_folder = (device_type == EXIDeviceType::MemoryCardFolder); - result = std::make_unique(channel_num, gci_folder, memcard_header_data); + result = std::make_unique(slot, gci_folder, memcard_header_data); break; } case EXIDeviceType::MaskROM: @@ -150,7 +148,7 @@ std::unique_ptr EXIDevice_Create(const EXIDeviceType device_type, co break; case EXIDeviceType::AGP: - result = std::make_unique(channel_num); + result = std::make_unique(slot); break; case EXIDeviceType::AMBaseboard: diff --git a/Source/Core/Core/HW/EXI/EXI_Device.h b/Source/Core/Core/HW/EXI/EXI_Device.h index 4425a652c4..232f260166 100644 --- a/Source/Core/Core/HW/EXI/EXI_Device.h +++ b/Source/Core/Core/HW/EXI/EXI_Device.h @@ -54,8 +54,6 @@ public: virtual void DMAWrite(u32 address, u32 size); virtual void DMARead(u32 address, u32 size); - virtual IEXIDevice* FindDevice(EXIDeviceType device_type, int custom_index = -1); - virtual bool UseDelayedTransferCompletion() const; virtual bool IsPresent() const; virtual void SetCS(int cs); diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceAGP.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceAGP.cpp index c0a5f843a4..8b2ae443d2 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceAGP.cpp +++ b/Source/Core/Core/HW/EXI/EXI_DeviceAGP.cpp @@ -8,18 +8,21 @@ #include #include +#include "Common/Assert.h" #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" #include "Common/IOFile.h" #include "Common/Logging/Log.h" #include "Common/StringUtil.h" #include "Core/Config/MainSettings.h" +#include "Core/HW/EXI/EXI.h" namespace ExpansionInterface { -CEXIAgp::CEXIAgp(int index) +CEXIAgp::CEXIAgp(Slot slot) { - m_slot = index; + ASSERT(IsMemcardSlot(slot)); + m_slot = slot; // Create the ROM m_rom_size = 0; @@ -35,9 +38,7 @@ CEXIAgp::~CEXIAgp() std::string filename; std::string ext; std::string gbapath; - SplitPath(m_slot == 0 ? Config::Get(Config::MAIN_AGP_CART_A_PATH) : - Config::Get(Config::MAIN_AGP_CART_B_PATH), - &path, &filename, &ext); + SplitPath(Config::Get(Config::GetInfoForAGPCartPath(m_slot)), &path, &filename, &ext); gbapath = path + filename; SaveFileFromEEPROM(gbapath + ".sav"); @@ -75,9 +76,7 @@ void CEXIAgp::LoadRom() std::string path; std::string filename; std::string ext; - SplitPath(m_slot == 0 ? Config::Get(Config::MAIN_AGP_CART_A_PATH) : - Config::Get(Config::MAIN_AGP_CART_B_PATH), - &path, &filename, &ext); + SplitPath(Config::Get(Config::GetInfoForAGPCartPath(m_slot)), &path, &filename, &ext); const std::string gbapath = path + filename; LoadFileToROM(gbapath + ext); INFO_LOG_FMT(EXPANSIONINTERFACE, "Loaded GBA rom: {} card: {}", gbapath, m_slot); diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceAGP.h b/Source/Core/Core/HW/EXI/EXI_DeviceAGP.h index ca2d21f1a4..65fa55f1c9 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceAGP.h +++ b/Source/Core/Core/HW/EXI/EXI_DeviceAGP.h @@ -12,10 +12,12 @@ class PointerWrap; namespace ExpansionInterface { +enum class Slot : int; + class CEXIAgp : public IEXIDevice { public: - CEXIAgp(const int index); + CEXIAgp(const Slot slot); virtual ~CEXIAgp() override; bool IsPresent() const override { return true; } void ImmWrite(u32 _uData, u32 _uSize) override; @@ -31,7 +33,7 @@ private: EE_READ_TRUE = 0xB, }; - int m_slot; + Slot m_slot; //! ROM u32 m_rom_size = 0; diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp index 0a12b36118..3d11c3de00 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp @@ -16,6 +16,7 @@ #include "Common/CommonPaths.h" #include "Common/CommonTypes.h" #include "Common/Config/Config.h" +#include "Common/EnumMap.h" #include "Common/FileUtil.h" #include "Common/IniFile.h" #include "Common/Logging/Log.h" @@ -48,25 +49,24 @@ namespace ExpansionInterface static const u32 MC_TRANSFER_RATE_READ = 512 * 1024; static const auto MC_TRANSFER_RATE_WRITE = static_cast(96.125f * 1024.0f); -static std::array s_et_cmd_done; -static std::array s_et_transfer_complete; +static Common::EnumMap s_et_cmd_done; +static Common::EnumMap s_et_transfer_complete; +static Common::EnumMap s_card_short_names{'A', 'B'}; -// Takes care of the nasty recovery of the 'this' pointer from card_index, +// Takes care of the nasty recovery of the 'this' pointer from card_slot, // stored in the userdata parameter of the CoreTiming event. void CEXIMemoryCard::EventCompleteFindInstance(u64 userdata, std::function callback) { - int card_index = (int)userdata; - auto* self = static_cast( - ExpansionInterface::FindDevice(EXIDeviceType::MemoryCard, card_index)); - if (self == nullptr) + Slot card_slot = static_cast(userdata); + IEXIDevice* self = ExpansionInterface::GetDevice(card_slot); + if (self != nullptr) { - self = static_cast( - ExpansionInterface::FindDevice(EXIDeviceType::MemoryCardFolder, card_index)); - } - if (self) - { - callback(self); + if (self->m_device_type == EXIDeviceType::MemoryCard || + self->m_device_type == EXIDeviceType::MemoryCardFolder) + { + callback(static_cast(self)); + } } } @@ -83,19 +83,15 @@ void CEXIMemoryCard::TransferCompleteCallback(u64 userdata, s64) void CEXIMemoryCard::Init() { - static constexpr char DONE_PREFIX[] = "memcardDone"; - static constexpr char TRANSFER_COMPLETE_PREFIX[] = "memcardTransferComplete"; - static_assert(s_et_cmd_done.size() == s_et_transfer_complete.size(), "Event array size differs"); - for (unsigned int i = 0; i < s_et_cmd_done.size(); ++i) + static_assert(s_et_cmd_done.size() == MEMCARD_SLOTS.size(), "Event array size differs"); + for (Slot slot : MEMCARD_SLOTS) { - std::string name = DONE_PREFIX; - name += static_cast('A' + i); - s_et_cmd_done[i] = CoreTiming::RegisterEvent(name, CmdDoneCallback); - - name = TRANSFER_COMPLETE_PREFIX; - name += static_cast('A' + i); - s_et_transfer_complete[i] = CoreTiming::RegisterEvent(name, TransferCompleteCallback); + s_et_cmd_done[slot] = CoreTiming::RegisterEvent( + fmt::format("memcardDone{}", s_card_short_names[slot]), CmdDoneCallback); + s_et_transfer_complete[slot] = CoreTiming::RegisterEvent( + fmt::format("memcardTransferComplete{}", s_card_short_names[slot]), + TransferCompleteCallback); } } @@ -105,12 +101,12 @@ void CEXIMemoryCard::Shutdown() s_et_transfer_complete.fill(nullptr); } -CEXIMemoryCard::CEXIMemoryCard(const int index, bool gci_folder, +CEXIMemoryCard::CEXIMemoryCard(const Slot slot, bool gci_folder, const Memcard::HeaderData& header_data) - : m_card_index(index) + : m_card_slot(slot) { - ASSERT_MSG(EXPANSIONINTERFACE, static_cast(index) < s_et_cmd_done.size(), - "Trying to create invalid memory card index {}.", index); + ASSERT_MSG(EXPANSIONINTERFACE, IsMemcardSlot(slot), "Trying to create invalid memory card in {}.", + slot); // NOTE: When loading a save state, DMA completion callbacks (s_et_transfer_complete) and such // may have been restored, we need to anticipate those arriving. @@ -145,15 +141,13 @@ CEXIMemoryCard::CEXIMemoryCard(const int index, bool gci_folder, m_memory_card_size = m_memory_card->GetCardId() * SIZE_TO_Mb; std::array header{}; m_memory_card->Read(0, static_cast(header.size()), header.data()); - SetCardFlashID(header.data(), m_card_index); + SetCardFlashID(header.data(), m_card_slot); } std::pair -CEXIMemoryCard::GetGCIFolderPath(int card_index, AllowMovieFolder allow_movie_folder) +CEXIMemoryCard::GetGCIFolderPath(Slot card_slot, AllowMovieFolder allow_movie_folder) { - std::string path_override = - Config::Get(card_index == 0 ? Config::MAIN_GCI_FOLDER_A_PATH_OVERRIDE : - Config::MAIN_GCI_FOLDER_B_PATH_OVERRIDE); + std::string path_override = Config::Get(Config::GetInfoForGCIPathOverride(card_slot)); if (!path_override.empty()) return {std::move(path_override), false}; @@ -162,7 +156,7 @@ CEXIMemoryCard::GetGCIFolderPath(int card_index, AllowMovieFolder allow_movie_fo const bool use_movie_folder = allow_movie_folder == AllowMovieFolder::Yes && Movie::IsPlayingInput() && Movie::IsConfigSaved() && - Movie::IsUsingMemcard(card_index) && + Movie::IsUsingMemcard(card_slot) && Movie::IsStartingFromClearSave(); if (use_movie_folder) @@ -170,7 +164,7 @@ CEXIMemoryCard::GetGCIFolderPath(int card_index, AllowMovieFolder allow_movie_fo const DiscIO::Region region = SConfig::ToGameCubeRegion(SConfig::GetInstance().m_region); path = path + SConfig::GetDirectoryForRegion(region) + DIR_SEP + - fmt::format("Card {}", char('A' + card_index)); + fmt::format("Card {}", s_card_short_names[card_slot]); return {std::move(path), !use_movie_folder}; } @@ -186,7 +180,7 @@ void CEXIMemoryCard::SetupGciFolder(const Memcard::HeaderData& header_data) // TODO(C++20): Use structured bindings when we can use C++20 and refer to structured bindings // in lambda captures - const auto folder_path_pair = GetGCIFolderPath(m_card_index, AllowMovieFolder::Yes); + const auto folder_path_pair = GetGCIFolderPath(m_card_slot, AllowMovieFolder::Yes); const std::string& dir_path = folder_path_pair.first; const bool migrate = folder_path_pair.second; @@ -194,7 +188,7 @@ void CEXIMemoryCard::SetupGciFolder(const Memcard::HeaderData& header_data) if (!file_info.Exists()) { if (migrate) // first use of memcard folder, migrate automatically - MigrateFromMemcardFile(dir_path + DIR_SEP, m_card_index); + MigrateFromMemcardFile(dir_path + DIR_SEP, m_card_slot); else File::CreateFullPath(dir_path + DIR_SEP); } @@ -204,7 +198,7 @@ void CEXIMemoryCard::SetupGciFolder(const Memcard::HeaderData& header_data) { PanicAlertFmtT("{0} was not a directory, moved to *.original", dir_path); if (migrate) - MigrateFromMemcardFile(dir_path + DIR_SEP, m_card_index); + MigrateFromMemcardFile(dir_path + DIR_SEP, m_card_slot); else File::CreateFullPath(dir_path + DIR_SEP); } @@ -218,22 +212,23 @@ void CEXIMemoryCard::SetupGciFolder(const Memcard::HeaderData& header_data) } } - m_memory_card = std::make_unique(dir_path + DIR_SEP, m_card_index, - header_data, current_game_id); + m_memory_card = std::make_unique(dir_path + DIR_SEP, m_card_slot, header_data, + current_game_id); } void CEXIMemoryCard::SetupRawMemcard(u16 size_mb) { - const bool is_slot_a = m_card_index == 0; - std::string filename = is_slot_a ? Config::Get(Config::MAIN_MEMCARD_A_PATH) : - Config::Get(Config::MAIN_MEMCARD_B_PATH); - if (Movie::IsPlayingInput() && Movie::IsConfigSaved() && Movie::IsUsingMemcard(m_card_index) && + std::string filename = Config::Get(Config::GetInfoForMemcardPath(m_card_slot)); + if (Movie::IsPlayingInput() && Movie::IsConfigSaved() && Movie::IsUsingMemcard(m_card_slot) && Movie::IsStartingFromClearSave()) - filename = File::GetUserPath(D_GCUSER_IDX) + fmt::format("Movie{}.raw", is_slot_a ? 'A' : 'B'); + { + filename = File::GetUserPath(D_GCUSER_IDX) + + fmt::format("Movie{}.raw", s_card_short_names[m_card_slot]); + } const std::string region_dir = SConfig::GetDirectoryForRegion(SConfig::ToGameCubeRegion(SConfig::GetInstance().m_region)); - MemoryCard::CheckPath(filename, region_dir, is_slot_a); + MemoryCard::CheckPath(filename, region_dir, m_card_slot); if (size_mb < Memcard::MBIT_SIZE_MEMORY_CARD_2043) { @@ -241,13 +236,13 @@ void CEXIMemoryCard::SetupRawMemcard(u16 size_mb) fmt::format(".{}", Memcard::MbitToFreeBlocks(size_mb))); } - m_memory_card = std::make_unique(filename, m_card_index, size_mb); + m_memory_card = std::make_unique(filename, m_card_slot, size_mb); } CEXIMemoryCard::~CEXIMemoryCard() { - CoreTiming::RemoveEvent(s_et_cmd_done[m_card_index]); - CoreTiming::RemoveEvent(s_et_transfer_complete[m_card_index]); + CoreTiming::RemoveEvent(s_et_cmd_done[m_card_slot]); + CoreTiming::RemoveEvent(s_et_transfer_complete[m_card_slot]); } bool CEXIMemoryCard::UseDelayedTransferCompletion() const @@ -272,13 +267,14 @@ void CEXIMemoryCard::CmdDone() void CEXIMemoryCard::TransferComplete() { // Transfer complete, send interrupt - ExpansionInterface::GetChannel(m_card_index)->SendTransferComplete(); + ExpansionInterface::GetChannel(ExpansionInterface::SlotToEXIChannel(m_card_slot)) + ->SendTransferComplete(); } void CEXIMemoryCard::CmdDoneLater(u64 cycles) { - CoreTiming::RemoveEvent(s_et_cmd_done[m_card_index]); - CoreTiming::ScheduleEvent(cycles, s_et_cmd_done[m_card_index], m_card_index); + CoreTiming::RemoveEvent(s_et_cmd_done[m_card_slot]); + CoreTiming::ScheduleEvent(cycles, s_et_cmd_done[m_card_slot], static_cast(m_card_slot)); } void CEXIMemoryCard::SetCS(int cs) @@ -522,19 +518,10 @@ void CEXIMemoryCard::DoState(PointerWrap& p) p.Do(m_programming_buffer); p.Do(m_address); m_memory_card->DoState(p); - p.Do(m_card_index); + p.Do(m_card_slot); } } -IEXIDevice* CEXIMemoryCard::FindDevice(EXIDeviceType device_type, int custom_index) -{ - if (device_type != m_device_type) - return nullptr; - if (custom_index != m_card_index) - return nullptr; - return this; -} - // DMA reads are preceded by all of the necessary setup via IMMRead // read all at once instead of single byte at a time as done by IEXIDevice::DMARead void CEXIMemoryCard::DMARead(u32 addr, u32 size) @@ -548,7 +535,7 @@ void CEXIMemoryCard::DMARead(u32 addr, u32 size) // Schedule transfer complete later based on read speed CoreTiming::ScheduleEvent(size * (SystemTimers::GetTicksPerSecond() / MC_TRANSFER_RATE_READ), - s_et_transfer_complete[m_card_index], m_card_index); + s_et_transfer_complete[m_card_slot], static_cast(m_card_slot)); } // DMA write are preceded by all of the necessary setup via IMMWrite @@ -564,6 +551,6 @@ void CEXIMemoryCard::DMAWrite(u32 addr, u32 size) // Schedule transfer complete later based on write speed CoreTiming::ScheduleEvent(size * (SystemTimers::GetTicksPerSecond() / MC_TRANSFER_RATE_WRITE), - s_et_transfer_complete[m_card_index], m_card_index); + s_et_transfer_complete[m_card_slot], static_cast(m_card_slot)); } } // namespace ExpansionInterface diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.h b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.h index 7075c00234..c472448d09 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.h +++ b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.h @@ -21,6 +21,8 @@ struct HeaderData; namespace ExpansionInterface { +enum class Slot : int; + enum class AllowMovieFolder { Yes, @@ -30,14 +32,13 @@ enum class AllowMovieFolder class CEXIMemoryCard : public IEXIDevice { public: - CEXIMemoryCard(int index, bool gci_folder, const Memcard::HeaderData& header_data); + CEXIMemoryCard(Slot slot, bool gci_folder, const Memcard::HeaderData& header_data); ~CEXIMemoryCard() override; void SetCS(int cs) override; bool IsInterruptSet() override; bool UseDelayedTransferCompletion() const override; bool IsPresent() const override; void DoState(PointerWrap& p) override; - IEXIDevice* FindDevice(EXIDeviceType device_type, int custom_index) override; void DMARead(u32 addr, u32 size) override; void DMAWrite(u32 addr, u32 size) override; @@ -48,7 +49,7 @@ public: static void Shutdown(); static std::pair - GetGCIFolderPath(int card_index, AllowMovieFolder allow_movie_folder); + GetGCIFolderPath(Slot card_slot, AllowMovieFolder allow_movie_folder); private: void SetupGciFolder(const Memcard::HeaderData& header_data); @@ -90,7 +91,7 @@ private: ChipErase = 0xF4, }; - int m_card_index; + Slot m_card_slot; //! memory card state // STATE_TO_SAVE diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardBase.h b/Source/Core/Core/HW/GCMemcard/GCMemcardBase.h index 6990148587..5805b90560 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardBase.h +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardBase.h @@ -12,8 +12,9 @@ class PointerWrap; class MemoryCardBase { public: - explicit MemoryCardBase(int card_index = 0, int size_mbits = Memcard::MBIT_SIZE_MEMORY_CARD_2043) - : m_card_index(card_index), m_nintendo_card_id(size_mbits) + explicit MemoryCardBase(ExpansionInterface::Slot card_slot, + int size_mbits = Memcard::MBIT_SIZE_MEMORY_CARD_2043) + : m_card_slot(card_slot), m_nintendo_card_id(size_mbits) { } virtual ~MemoryCardBase() = default; @@ -25,6 +26,6 @@ public: u32 GetCardId() const { return m_nintendo_card_id; } protected: - int m_card_index; + ExpansionInterface::Slot m_card_slot; u16 m_nintendo_card_id; }; diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp index b907e0b698..b65d7f0d03 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp @@ -152,7 +152,7 @@ std::vector GCMemcardDirectory::GetFileNamesForGameID(const std::st return filenames; } -GCMemcardDirectory::GCMemcardDirectory(const std::string& directory, int slot, +GCMemcardDirectory::GCMemcardDirectory(const std::string& directory, ExpansionInterface::Slot slot, const Memcard::HeaderData& header_data, u32 game_id) : MemoryCardBase(slot, header_data.m_size_mb), m_game_id(game_id), m_last_block(-1), m_hdr(header_data), m_bat1(header_data.m_size_mb), m_saves(0), m_save_directory(directory), @@ -240,7 +240,7 @@ void GCMemcardDirectory::FlushThread() return; } - Common::SetCurrentThreadName(fmt::format("Memcard {} flushing thread", m_card_index).c_str()); + Common::SetCurrentThreadName(fmt::format("Memcard {} flushing thread", m_card_slot).c_str()); constexpr std::chrono::seconds flush_interval{1}; while (true) @@ -705,11 +705,10 @@ void GCMemcardDirectory::DoState(PointerWrap& p) } } -void MigrateFromMemcardFile(const std::string& directory_name, int card_index) +void MigrateFromMemcardFile(const std::string& directory_name, ExpansionInterface::Slot card_slot) { File::CreateFullPath(directory_name); - std::string ini_memcard = (card_index == 0) ? Config::Get(Config::MAIN_MEMCARD_A_PATH) : - Config::Get(Config::MAIN_MEMCARD_B_PATH); + std::string ini_memcard = Config::Get(Config::GetInfoForMemcardPath(card_slot)); if (File::Exists(ini_memcard)) { auto [error_code, memcard] = Memcard::GCMemcard::Open(ini_memcard.c_str()); diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h index b146b9681f..fa9ae44110 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h @@ -15,13 +15,13 @@ // Uncomment this to write the system data of the memorycard from directory to disc //#define _WRITE_MC_HEADER 1 -void MigrateFromMemcardFile(const std::string& directory_name, int card_index); +void MigrateFromMemcardFile(const std::string& directory_name, ExpansionInterface::Slot card_slot); class GCMemcardDirectory : public MemoryCardBase { public: - GCMemcardDirectory(const std::string& directory, int slot, const Memcard::HeaderData& header_data, - u32 game_id); + GCMemcardDirectory(const std::string& directory, ExpansionInterface::Slot slot, + const Memcard::HeaderData& header_data, u32 game_id); ~GCMemcardDirectory(); GCMemcardDirectory(const GCMemcardDirectory&) = delete; diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp index 5a6d25324a..923f88bc69 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp @@ -26,6 +26,7 @@ #include "Core/Config/SessionSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" +#include "Core/HW/EXI/EXI.h" #include "Core/HW/EXI/EXI_DeviceIPL.h" #include "Core/HW/GCMemcard/GCMemcard.h" #include "Core/HW/Sram.h" @@ -33,8 +34,9 @@ #define SIZE_TO_Mb (1024 * 8 * 16) #define MC_HDR_SIZE 0xA000 -MemoryCard::MemoryCard(const std::string& filename, int card_index, u16 size_mbits) - : MemoryCardBase(card_index, size_mbits), m_filename(filename) +MemoryCard::MemoryCard(const std::string& filename, ExpansionInterface::Slot card_slot, + u16 size_mbits) + : MemoryCardBase(card_slot, size_mbits), m_filename(filename) { File::IOFile file(m_filename, "rb"); if (file) @@ -88,13 +90,15 @@ MemoryCard::~MemoryCard() } } -void MemoryCard::CheckPath(std::string& memcardPath, const std::string& gameRegion, bool isSlotA) +void MemoryCard::CheckPath(std::string& memcardPath, const std::string& gameRegion, + ExpansionInterface::Slot card_slot) { + bool is_slot_a = card_slot == ExpansionInterface::Slot::A; std::string ext("." + gameRegion + ".raw"); if (memcardPath.empty()) { // Use default memcard path if there is no user defined name - std::string defaultFilename = isSlotA ? GC_MEMCARDA : GC_MEMCARDB; + std::string defaultFilename = is_slot_a ? GC_MEMCARDA : GC_MEMCARDB; memcardPath = File::GetUserPath(D_GCUSER_IDX) + defaultFilename + ext; } else @@ -118,7 +122,7 @@ void MemoryCard::CheckPath(std::string& memcardPath, const std::string& gameRegi "Slot {1} path was changed to\n" "{2}\n" "Would you like to copy the old file to this new location?\n", - isSlotA ? 'A' : 'B', isSlotA ? 'A' : 'B', filename)) + is_slot_a ? 'A' : 'B', is_slot_a ? 'A' : 'B', filename)) { if (!File::Copy(oldFilename, filename)) PanicAlertFmtT("Copy failed"); @@ -142,7 +146,7 @@ void MemoryCard::FlushThread() return; } - Common::SetCurrentThreadName(fmt::format("Memcard {} flushing thread", m_card_index).c_str()); + Common::SetCurrentThreadName(fmt::format("Memcard {} flushing thread", m_card_slot).c_str()); const auto flush_interval = std::chrono::seconds(15); @@ -199,9 +203,10 @@ void MemoryCard::FlushThread() if (do_exit) return; - Core::DisplayMessage( - fmt::format("Wrote memory card {} contents to {}", m_card_index ? 'B' : 'A', m_filename), - 4000); + Core::DisplayMessage(fmt::format("Wrote memory card {} contents to {}", + m_card_slot == ExpansionInterface::Slot::A ? 'A' : 'B', + m_filename), + 4000); } } @@ -265,7 +270,7 @@ void MemoryCard::ClearAll() void MemoryCard::DoState(PointerWrap& p) { - p.Do(m_card_index); + p.Do(m_card_slot); p.Do(m_memory_card_size); p.DoArray(&m_memcard_data[0], m_memory_card_size); } diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h index a8624b64eb..b8486c13a3 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h @@ -17,10 +17,11 @@ class PointerWrap; class MemoryCard : public MemoryCardBase { public: - MemoryCard(const std::string& filename, int card_index, + MemoryCard(const std::string& filename, ExpansionInterface::Slot card_slot, u16 size_mbits = Memcard::MBIT_SIZE_MEMORY_CARD_2043); ~MemoryCard(); - static void CheckPath(std::string& memcardPath, const std::string& gameRegion, bool isSlotA); + static void CheckPath(std::string& memcardPath, const std::string& gameRegion, + ExpansionInterface::Slot slot); void FlushThread(); void MakeDirty(); diff --git a/Source/Core/Core/HW/Sram.cpp b/Source/Core/Core/HW/Sram.cpp index 16d28c85a2..1f8b29116a 100644 --- a/Source/Core/Core/HW/Sram.cpp +++ b/Source/Core/Core/HW/Sram.cpp @@ -6,8 +6,11 @@ #include "Common/CommonTypes.h" #include "Common/IOFile.h" #include "Common/Logging/Log.h" +#include "Common/MsgHandler.h" #include "Common/Swap.h" + #include "Core/ConfigManager.h" +#include "Core/HW/EXI/EXI.h" // English // This is just a template. Most/all fields are updated with sane(r) values at runtime. @@ -72,8 +75,22 @@ void InitSRAM() } } -void SetCardFlashID(const u8* buffer, u8 card_index) +void SetCardFlashID(const u8* buffer, ExpansionInterface::Slot card_slot) { + u8 card_index; + switch (card_slot) + { + case ExpansionInterface::Slot::A: + card_index = 0; + break; + case ExpansionInterface::Slot::B: + card_index = 1; + break; + default: + PanicAlertFmt("Invalid memcard slot {}", card_slot); + return; + } + u64 rand = Common::swap64(&buffer[12]); u8 csum = 0; for (int i = 0; i < 12; i++) diff --git a/Source/Core/Core/HW/Sram.h b/Source/Core/Core/HW/Sram.h index 7b99f17141..92262ca331 100644 --- a/Source/Core/Core/HW/Sram.h +++ b/Source/Core/Core/HW/Sram.h @@ -34,9 +34,15 @@ distribution. #pragma once #include + #include "Common/CommonTypes.h" #include "Common/Swap.h" +namespace ExpansionInterface +{ +enum class Slot : int; +}; + using CardFlashId = std::array; #pragma pack(push, 1) @@ -128,7 +134,7 @@ static_assert(sizeof(Sram) == 0x44); #pragma pack(pop) void InitSRAM(); -void SetCardFlashID(const u8* buffer, u8 card_index); +void SetCardFlashID(const u8* buffer, ExpansionInterface::Slot card_slot); void FixSRAMChecksums(); extern Sram g_SRAM; diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp index f6bd914aed..9b1c83ff89 100644 --- a/Source/Core/Core/Movie.cpp +++ b/Source/Core/Core/Movie.cpp @@ -43,6 +43,7 @@ #include "Core/DSP/DSPCore.h" #include "Core/HW/CPU.h" #include "Core/HW/DVD/DVDInterface.h" +#include "Core/HW/EXI/EXI.h" #include "Core/HW/EXI/EXI_DeviceIPL.h" #include "Core/HW/EXI/EXI_DeviceMemoryCard.h" #include "Core/HW/ProcessorInterface.h" @@ -433,9 +434,17 @@ bool IsStartingFromClearSave() return s_bClearSave; } -bool IsUsingMemcard(int memcard) +bool IsUsingMemcard(ExpansionInterface::Slot slot) { - return (s_memcards & (1 << memcard)) != 0; + switch (slot) + { + case ExpansionInterface::Slot::A: + return (s_memcards & 1) != 0; + case ExpansionInterface::Slot::B: + return (s_memcards & 2) != 0; + default: + return false; + } } bool IsNetPlayRecording() @@ -1456,9 +1465,9 @@ void GetSettings() } else { - const auto gci_folder_has_saves = [](int card_index) { + const auto gci_folder_has_saves = [](ExpansionInterface::Slot card_slot) { const auto [path, migrate] = ExpansionInterface::CEXIMemoryCard::GetGCIFolderPath( - card_index, ExpansionInterface::AllowMovieFolder::No); + card_slot, ExpansionInterface::AllowMovieFolder::No); const u64 number_of_saves = File::ScanDirectoryTree(path, false).size; return number_of_saves > 0; }; @@ -1466,8 +1475,8 @@ void GetSettings() s_bClearSave = !(slot_a_has_raw_memcard && File::Exists(Config::Get(Config::MAIN_MEMCARD_A_PATH))) && !(slot_b_has_raw_memcard && File::Exists(Config::Get(Config::MAIN_MEMCARD_B_PATH))) && - !(slot_a_has_gci_folder && gci_folder_has_saves(0)) && - !(slot_b_has_gci_folder && gci_folder_has_saves(1)); + !(slot_a_has_gci_folder && gci_folder_has_saves(ExpansionInterface::Slot::A)) && + !(slot_b_has_gci_folder && gci_folder_has_saves(ExpansionInterface::Slot::B)); } s_memcards |= (slot_a_has_raw_memcard || slot_a_has_gci_folder) << 0; s_memcards |= (slot_b_has_raw_memcard || slot_b_has_gci_folder) << 1; diff --git a/Source/Core/Core/Movie.h b/Source/Core/Core/Movie.h index be95ebca69..a774f7ad4e 100644 --- a/Source/Core/Core/Movie.h +++ b/Source/Core/Core/Movie.h @@ -17,6 +17,11 @@ struct BootParameters; struct GCPadStatus; class PointerWrap; +namespace ExpansionInterface +{ +enum class Slot : int; +} + namespace WiimoteCommon { class DataReportBuilder; @@ -166,7 +171,7 @@ void SetReset(bool reset); bool IsConfigSaved(); bool IsStartingFromClearSave(); -bool IsUsingMemcard(int memcard); +bool IsUsingMemcard(ExpansionInterface::Slot slot); void SetGraphicsConfig(); bool IsNetPlayRecording(); diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp index 40e480f6a1..73132a4c7d 100644 --- a/Source/Core/Core/NetPlayServer.cpp +++ b/Source/Core/Core/NetPlayServer.cpp @@ -1670,10 +1670,9 @@ bool NetPlayServer::SyncSaveData() if (m_settings.m_EXIDevice[slot] == ExpansionInterface::EXIDeviceType::MemoryCard) { - std::string path = is_slot_a ? Config::Get(Config::MAIN_MEMCARD_A_PATH) : - Config::Get(Config::MAIN_MEMCARD_B_PATH); + std::string path = Config::Get(Config::GetInfoForMemcardPath(slot)); - MemoryCard::CheckPath(path, region, is_slot_a); + MemoryCard::CheckPath(path, region, slot); int size_override; IniFile gameIni = SConfig::LoadGameIni(game->GetGameID(), game->GetRevision()); diff --git a/Source/Core/DolphinQt/GameList/GameList.cpp b/Source/Core/DolphinQt/GameList/GameList.cpp index e5170fc938..cc5b1ebb43 100644 --- a/Source/Core/DolphinQt/GameList/GameList.cpp +++ b/Source/Core/DolphinQt/GameList/GameList.cpp @@ -677,9 +677,7 @@ void GameList::OpenGCSaveFolder() SConfig::GetDirectoryForRegion(game->GetRegion()), slot == Slot::A ? "Card A" : "Card B"); - std::string override_path = slot == Slot::A ? - Config::Get(Config::MAIN_GCI_FOLDER_A_PATH_OVERRIDE) : - Config::Get(Config::MAIN_GCI_FOLDER_B_PATH_OVERRIDE); + std::string override_path = Config::Get(Config::GetInfoForGCIPathOverride(slot)); if (!override_path.empty()) path = override_path; @@ -697,8 +695,7 @@ void GameList::OpenGCSaveFolder() } case ExpansionInterface::EXIDeviceType::MemoryCard: { - std::string memcard_path = slot == Slot::A ? Config::Get(Config::MAIN_MEMCARD_A_PATH) : - Config::Get(Config::MAIN_MEMCARD_B_PATH); + std::string memcard_path = Config::Get(Config::GetInfoForMemcardPath(slot)); std::string memcard_dir; diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.cpp b/Source/Core/DolphinQt/Settings/GameCubePane.cpp index d3ee4b3055..ad2b39c8ec 100644 --- a/Source/Core/DolphinQt/Settings/GameCubePane.cpp +++ b/Source/Core/DolphinQt/Settings/GameCubePane.cpp @@ -387,11 +387,11 @@ void GameCubePane::OnConfigPressed(int slot) ExpansionInterface::ChangeDevice( // SlotB is on channel 1, slotA and SP1 are on 0 slot, + // SP1 is device 2, slots are device 0 + 0, // The device enum to change to memcard ? ExpansionInterface::EXIDeviceType::MemoryCard : - ExpansionInterface::EXIDeviceType::AGP, - // SP1 is device 2, slots are device 0 - 0); + ExpansionInterface::EXIDeviceType::AGP); } } @@ -501,10 +501,10 @@ void GameCubePane::SaveSettings() ExpansionInterface::ChangeDevice( // SlotB is on channel 1, slotA and SP1 are on 0 (i == 1) ? 1 : 0, - // The device enum to change to - dev, // SP1 is device 2, slots are device 0 - (i == 2) ? 2 : 0); + (i == 2) ? 2 : 0, + // The device enum to change to + dev); } Config::SetBaseOrCurrent(Config::GetInfoForEXIDevice(static_cast(i)),