summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorPokechu22 <Pokechu022@gmail.com>2022-01-11 11:17:47 -0800
committerPokechu22 <Pokechu022@gmail.com>2022-01-16 14:21:28 -0800
commit777bb4d82cc42da12799bfb7ab62617bb712671c (patch)
tree5f7f0895f2f685b18864ed5f345b308fabf1141a /Source/Core
parent3f0b23ed2bf431e7cd7262c60afebc293d8ff806 (diff)
Use Slot in EXI devices
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/BootManager.cpp7
-rw-r--r--Source/Core/Core/Config/MainSettings.cpp31
-rw-r--r--Source/Core/Core/Config/MainSettings.h3
-rw-r--r--Source/Core/Core/HW/EXI/EXI.cpp30
-rw-r--r--Source/Core/Core/HW/EXI/EXI.h12
-rw-r--r--Source/Core/Core/HW/EXI/EXI_Channel.cpp13
-rw-r--r--Source/Core/Core/HW/EXI/EXI_Channel.h1
-rw-r--r--Source/Core/Core/HW/EXI/EXI_Device.cpp12
-rw-r--r--Source/Core/Core/HW/EXI/EXI_Device.h2
-rw-r--r--Source/Core/Core/HW/EXI/EXI_DeviceAGP.cpp15
-rw-r--r--Source/Core/Core/HW/EXI/EXI_DeviceAGP.h6
-rw-r--r--Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp115
-rw-r--r--Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.h9
-rw-r--r--Source/Core/Core/HW/GCMemcard/GCMemcardBase.h7
-rw-r--r--Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp9
-rw-r--r--Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h6
-rw-r--r--Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp25
-rw-r--r--Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h5
-rw-r--r--Source/Core/Core/HW/Sram.cpp19
-rw-r--r--Source/Core/Core/HW/Sram.h8
-rw-r--r--Source/Core/Core/Movie.cpp21
-rw-r--r--Source/Core/Core/Movie.h7
-rw-r--r--Source/Core/Core/NetPlayServer.cpp5
-rw-r--r--Source/Core/DolphinQt/GameList/GameList.cpp7
-rw-r--r--Source/Core/DolphinQt/Settings/GameCubePane.cpp12
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<BootParameters> 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 <fmt/format.h>
#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<bool> MAIN_AUDIO_STRETCH{{System::Main, "Core", "AudioStretch"}, fals
const Info<int> MAIN_AUDIO_STRETCH_LATENCY{{System::Main, "Core", "AudioStretchMaxLatency"}, 80};
const Info<std::string> MAIN_MEMCARD_A_PATH{{System::Main, "Core", "MemcardAPath"}, ""};
const Info<std::string> MAIN_MEMCARD_B_PATH{{System::Main, "Core", "MemcardBPath"}, ""};
+const Info<std::string>& GetInfoForMemcardPath(ExpansionInterface::Slot slot)
+{
+ ASSERT(ExpansionInterface::IsMemcardSlot(slot));
+ static constexpr Common::EnumMap<const Info<std::string>*, ExpansionInterface::MAX_MEMCARD_SLOT>
+ infos{
+ &MAIN_MEMCARD_A_PATH,
+ &MAIN_MEMCARD_B_PATH,
+ };
+ return *infos[slot];
+}
const Info<std::string> MAIN_AGP_CART_A_PATH{{System::Main, "Core", "AgpCartAPath"}, ""};
const Info<std::string> MAIN_AGP_CART_B_PATH{{System::Main, "Core", "AgpCartBPath"}, ""};
+const Info<std::string>& GetInfoForAGPCartPath(ExpansionInterface::Slot slot)
+{
+ ASSERT(ExpansionInterface::IsMemcardSlot(slot));
+ static constexpr Common::EnumMap<const Info<std::string>*, ExpansionInterface::MAX_MEMCARD_SLOT>
+ infos{
+ &MAIN_AGP_CART_A_PATH,
+ &MAIN_AGP_CART_B_PATH,
+ };
+ return *infos[slot];
+}
const Info<std::string> MAIN_GCI_FOLDER_A_PATH_OVERRIDE{
{System::Main, "Core", "GCIFolderAPathOverride"}, ""};
const Info<std::string> MAIN_GCI_FOLDER_B_PATH_OVERRIDE{
{System::Main, "Core", "GCIFolderBPathOverride"}, ""};
+const Info<std::string>& GetInfoForGCIPathOverride(ExpansionInterface::Slot slot)
+{
+ ASSERT(ExpansionInterface::IsMemcardSlot(slot));
+ static constexpr Common::EnumMap<const Info<std::string>*, ExpansionInterface::MAX_MEMCARD_SLOT>
+ infos{
+ &MAIN_GCI_FOLDER_A_PATH_OVERRIDE,
+ &MAIN_GCI_FOLDER_B_PATH_OVERRIDE,
+ };
+ return *infos[slot];
+}
const Info<ExpansionInterface::EXIDeviceType> 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<bool> MAIN_AUDIO_STRETCH;
extern const Info<int> MAIN_AUDIO_STRETCH_LATENCY;
extern const Info<std::string> MAIN_MEMCARD_A_PATH;
extern const Info<std::string> MAIN_MEMCARD_B_PATH;
+const Info<std::string>& GetInfoForMemcardPath(ExpansionInterface::Slot slot);
extern const Info<std::string> MAIN_AGP_CART_A_PATH;
extern const Info<std::string> MAIN_AGP_CART_B_PATH;
+const Info<std::string>& GetInfoForAGPCartPath(ExpansionInterface::Slot slot);
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<ExpansionInterface::EXIDeviceType> MAIN_SLOT_A;
extern const Info<ExpansionInterface::EXIDeviceType> MAIN_SLOT_B;
extern const Info<ExpansionInterface::EXIDeviceType> 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<Slot>(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<Slot>(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<int>(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<EXIDeviceType>(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<IEXIDevice> EXIDevice_Create(const EXIDeviceType device_type, co
const Memcard::HeaderData& memcard_header_data)
{
std::unique_ptr<IEXIDevice> 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<Slot>(channel_num);
switch (device_type)
{
@@ -116,7 +114,7 @@ std::unique_ptr<IEXIDevice> EXIDevice_Create(const EXIDeviceType device_type, co
case EXIDeviceType::MemoryCardFolder:
{
bool gci_folder = (device_type == EXIDeviceType::MemoryCardFolder);
- result = std::make_unique<CEXIMemoryCard>(channel_num, gci_folder, memcard_header_data);
+ result = std::make_unique<CEXIMemoryCard>(slot, gci_folder, memcard_header_data);
break;
}
case EXIDeviceType::MaskROM:
@@ -150,7 +148,7 @@ std::unique_ptr<IEXIDevice> EXIDevice_Create(const EXIDeviceType device_type, co
break;
case EXIDeviceType::AGP:
- result = std::make_unique<CEXIAgp>(channel_num);
+ result = std::make_unique<CEXIAgp>(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 <string>
#include <vector>
+#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<u32>(96.125f * 1024.0f);
-static std::array<CoreTiming::EventType*, 2> s_et_cmd_done;
-static std::array<CoreTiming::EventType*, 2> s_et_transfer_complete;
+static Common::EnumMap<CoreTiming::EventType*, MAX_MEMCARD_SLOT> s_et_cmd_done;
+static Common::EnumMap<CoreTiming::EventType*, MAX_MEMCARD_SLOT> s_et_transfer_complete;
+static Common::EnumMap<char, MAX_MEMCARD_SLOT> 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<void(CEXIMemoryCard*)> callback)
{
- int card_index = (int)userdata;
- auto* self = static_cast<CEXIMemoryCard*>(
- ExpansionInterface::FindDevice(EXIDeviceType::MemoryCard, card_index));
- if (self == nullptr)
+ Slot card_slot = static_cast<Slot>(userdata);
+ IEXIDevice* self = ExpansionInterface::GetDevice(card_slot);
+ if (self != nullptr)
{
- self = static_cast<CEXIMemoryCard*>(
- 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<CEXIMemoryCard*>(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<char>('A' + i);
- s_et_cmd_done[i] = CoreTiming::RegisterEvent(name, CmdDoneCallback);
-
- name = TRANSFER_COMPLETE_PREFIX;
- name += static_cast<char>('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<std::size_t>(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<u8, 20> header{};
m_memory_card->Read(0, static_cast<s32>(header.size()), header.data());
- SetCardFlashID(header.data(), m_card_index);
+ SetCardFlashID(header.data(), m_card_slot);
}
std::pair<std::string /* path */, bool /* migrate */>
-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<GCMemcardDirectory>(dir_path + DIR_SEP, m_card_index,
- header_data, current_game_id);
+ m_memory_card = std::make_unique<GCMemcardDirectory>(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<MemoryCard>(filename, m_card_index, size_mb);
+ m_memory_card = std::make_unique<MemoryCard>(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<u64>(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<u64>(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<u64>(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<std::string /* path */, bool /* migrate */>
- 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<std::string> 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 <array>
+
#include "Common/CommonTypes.h"
#include "Common/Swap.h"
+namespace ExpansionInterface
+{
+enum class Slot : int;
+};
+
using CardFlashId = std::array<u8, 12>;
#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<ExpansionInterface::Slot>(i)),