Skip to content
Permalink
Browse files
Merge pull request #10364 from Pokechu22/exi-device-refactor
Create enum classes for EXI devices and slots
  • Loading branch information
Pokechu22 committed Jan 16, 2022
2 parents e8bbfc2 + 6578829 commit b7ac110
Show file tree
Hide file tree
Showing 33 changed files with 712 additions and 520 deletions.
@@ -95,7 +95,6 @@ class EnumFormatter

constexpr explicit EnumFormatter(const array_type names) : m_names(std::move(names)) {}

private:
const array_type m_names;
char format_type = 'u';
};
@@ -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);

@@ -8,13 +8,16 @@
#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"
#include "Common/Logging/Log.h"
#include "Common/MathUtil.h"
#include "Common/StringUtil.h"
#include "Common/Version.h"
#include "Core/Config/DefaultLocale.h"
#include "Core/HW/EXI/EXI.h"
#include "Core/HW/EXI/EXI_Device.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/SI/SI_Device.h"
@@ -48,28 +51,60 @@ 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::TEXIDevices> MAIN_SLOT_A{
{System::Main, "Core", "SlotA"}, ExpansionInterface::EXIDEVICE_MEMORYCARDFOLDER};
const Info<ExpansionInterface::TEXIDevices> MAIN_SLOT_B{{System::Main, "Core", "SlotB"},
ExpansionInterface::EXIDEVICE_NONE};
const Info<ExpansionInterface::TEXIDevices> MAIN_SERIAL_PORT_1{
{System::Main, "Core", "SerialPort1"}, ExpansionInterface::EXIDEVICE_NONE};
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"},
ExpansionInterface::EXIDeviceType::None};
const Info<ExpansionInterface::EXIDeviceType> MAIN_SERIAL_PORT_1{
{System::Main, "Core", "SerialPort1"}, ExpansionInterface::EXIDeviceType::None};

const Info<ExpansionInterface::TEXIDevices>& GetInfoForEXIDevice(int channel)
const Info<ExpansionInterface::EXIDeviceType>& GetInfoForEXIDevice(ExpansionInterface::Slot slot)
{
static constexpr std::array<const Info<ExpansionInterface::TEXIDevices>*, 3> infos{
&MAIN_SLOT_A,
&MAIN_SLOT_B,
&MAIN_SERIAL_PORT_1,
};
return *infos[channel];
static constexpr Common::EnumMap<const Info<ExpansionInterface::EXIDeviceType>*,
ExpansionInterface::MAX_SLOT>
infos{
&MAIN_SLOT_A,
&MAIN_SLOT_B,
&MAIN_SERIAL_PORT_1,
};
return *infos[slot];
}

const Info<std::string> MAIN_BBA_MAC{{System::Main, "Core", "BBA_MAC"}, ""};
@@ -33,8 +33,9 @@ enum class DPL2Quality;

namespace ExpansionInterface
{
enum TEXIDevices : int;
}
enum class EXIDeviceType : int;
enum class Slot : int;
} // namespace ExpansionInterface

namespace SerialInterface
{
@@ -65,14 +66,17 @@ 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;
extern const Info<ExpansionInterface::TEXIDevices> MAIN_SLOT_A;
extern const Info<ExpansionInterface::TEXIDevices> MAIN_SLOT_B;
extern const Info<ExpansionInterface::TEXIDevices> MAIN_SERIAL_PORT_1;
const Info<ExpansionInterface::TEXIDevices>& GetInfoForEXIDevice(int channel);
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;
const Info<ExpansionInterface::EXIDeviceType>& GetInfoForEXIDevice(ExpansionInterface::Slot slot);
extern const Info<std::string> MAIN_BBA_MAC;
extern const Info<std::string> MAIN_BBA_XLINK_IP;
extern const Info<bool> MAIN_BBA_XLINK_CHAT_OSD;
@@ -15,6 +15,7 @@
#include "Core/Config/MainSettings.h"
#include "Core/Config/SYSCONFSettings.h"
#include "Core/Config/SessionSettings.h"
#include "Core/HW/EXI/EXI.h"
#include "Core/NetPlayProto.h"

namespace ConfigLoaders
@@ -37,9 +38,8 @@ class NetPlayConfigLayerLoader final : public Config::ConfigLayerLoader
layer->Set(Config::MAIN_DSP_HLE, m_settings.m_DSPHLE);
layer->Set(Config::MAIN_OVERCLOCK_ENABLE, m_settings.m_OCEnable);
layer->Set(Config::MAIN_OVERCLOCK, m_settings.m_OCFactor);
layer->Set(Config::MAIN_SLOT_A, m_settings.m_EXIDevice[0]);
layer->Set(Config::MAIN_SLOT_B, m_settings.m_EXIDevice[1]);
layer->Set(Config::MAIN_SERIAL_PORT_1, m_settings.m_EXIDevice[2]);
for (ExpansionInterface::Slot slot : ExpansionInterface::SLOTS)
layer->Set(Config::GetInfoForEXIDevice(slot), m_settings.m_EXIDevice[slot]);
layer->Set(Config::SESSION_SAVE_DATA_WRITABLE, m_settings.m_WriteToMemcard);
layer->Set(Config::MAIN_RAM_OVERRIDE_ENABLE, m_settings.m_RAMOverrideEnable);
layer->Set(Config::MAIN_MEM1_SIZE, m_settings.m_Mem1Size);
@@ -25,26 +25,11 @@ struct Partition;
class Volume;
} // namespace DiscIO

namespace ExpansionInterface
{
enum TEXIDevices : int;
} // namespace ExpansionInterface

namespace IOS::ES
{
class TMDReader;
} // namespace IOS::ES

namespace PowerPC
{
enum class CPUCore;
} // namespace PowerPC

namespace SerialInterface
{
enum SIDevices : int;
} // namespace SerialInterface

struct BootParameters;

struct SConfig
@@ -39,32 +39,70 @@ static void UpdateInterruptsCallback(u64 userdata, s64 cycles_late);

namespace
{
void AddMemoryCards(int i)
void AddMemoryCard(Slot slot)
{
TEXIDevices memorycard_device;
EXIDeviceType memorycard_device;
if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
{
if (Movie::IsUsingMemcard(i))
if (Movie::IsUsingMemcard(slot))
{
if (Config::Get(Config::GetInfoForEXIDevice(i)) == EXIDEVICE_MEMORYCARDFOLDER)
memorycard_device = EXIDEVICE_MEMORYCARDFOLDER;
else
memorycard_device = EXIDEVICE_MEMORYCARD;
memorycard_device = Config::Get(Config::GetInfoForEXIDevice(slot));
if (memorycard_device != EXIDeviceType::MemoryCardFolder &&
memorycard_device != EXIDeviceType::MemoryCard)
{
PanicAlertFmtT(
"The movie indicates that a memory card should be inserted into {0:n}, but one is not "
"currently inserted (instead, {1} is inserted). For the movie to sync properly, "
"please change the selected device to Memory Card or GCI Folder.",
slot, Common::GetStringT(fmt::format("{:n}", memorycard_device).c_str()));
}
}
else
{
memorycard_device = EXIDEVICE_NONE;
memorycard_device = EXIDeviceType::None;
}
}
else
{
memorycard_device = Config::Get(Config::GetInfoForEXIDevice(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

u8 SlotToEXIChannel(Slot slot)
{
switch (slot)
{
case Slot::A:
return 0;
case Slot::B:
return 1;
case Slot::SP1:
return 0;
default:
PanicAlertFmt("Unhandled slot {}", slot);
return 0;
}
}

u8 SlotToEXIDevice(Slot slot)
{
switch (slot)
{
case Slot::A:
return 0;
case Slot::B:
return 0;
case Slot::SP1:
return 2;
default:
PanicAlertFmt("Unhandled slot {}", slot);
return 0;
}
}

void Init()
{
if (!g_SRAM_netplay_initialized)
@@ -98,12 +136,13 @@ void Init()
}
}

for (int i = 0; i < MAX_MEMORYCARD_SLOTS; i++)
AddMemoryCards(i);
for (Slot slot : MEMCARD_SLOTS)
AddMemoryCard(slot);

g_Channels[0]->AddDevice(EXIDEVICE_MASKROM, 1);
g_Channels[0]->AddDevice(Config::Get(Config::MAIN_SERIAL_PORT_1), 2);
g_Channels[2]->AddDevice(EXIDEVICE_AD16, 0);
g_Channels[0]->AddDevice(EXIDeviceType::MaskROM, 1);
g_Channels[SlotToEXIChannel(Slot::SP1)]->AddDevice(Config::Get(Config::MAIN_SERIAL_PORT_1),
SlotToEXIDevice(Slot::SP1));
g_Channels[2]->AddDevice(EXIDeviceType::AD16, 0);

changeDevice = CoreTiming::RegisterEvent("ChangeEXIDevice", ChangeDeviceCallback);
updateInterrupts = CoreTiming::RegisterEvent("EXIUpdateInterrupts", UpdateInterruptsCallback);
@@ -149,15 +188,20 @@ static void ChangeDeviceCallback(u64 userdata, s64 cyclesLate)
u8 type = (u8)(userdata >> 16);
u8 num = (u8)userdata;

g_Channels.at(channel)->AddDevice((TEXIDevices)type, num);
g_Channels.at(channel)->AddDevice(static_cast<EXIDeviceType>(type), num);
}

void ChangeDevice(Slot slot, EXIDeviceType device_type, CoreTiming::FromThread from_thread)
{
ChangeDevice(SlotToEXIChannel(slot), SlotToEXIDevice(slot), device_type, from_thread);
}

void ChangeDevice(const u8 channel, const TEXIDevices device_type, const u8 device_num,
void ChangeDevice(u8 channel, u8 device_num, EXIDeviceType device_type,
CoreTiming::FromThread from_thread)
{
// Let the hardware see no device for 1 second
CoreTiming::ScheduleEvent(0, changeDevice,
((u64)channel << 32) | ((u64)EXIDEVICE_NONE << 16) | device_num,
((u64)channel << 32) | ((u64)EXIDeviceType::None << 16) | device_num,
from_thread);
CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), changeDevice,
((u64)channel << 32) | ((u64)device_type << 16) | device_num,
@@ -169,15 +213,9 @@ CEXIChannel* GetChannel(u32 index)
return g_Channels.at(index).get();
}

IEXIDevice* FindDevice(TEXIDevices 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()

0 comments on commit b7ac110

Please sign in to comment.