@@ -62,7 +62,7 @@ void CEXIChannel::RegisterMMIO(MMIO::Mapping* mmio, u32 base)

return m_status.Hex;
}),
MMIO::ComplexWrite<u32>([this](Core::System&, u32, u32 val) {
MMIO::ComplexWrite<u32>([this](Core::System& system, u32, u32 val) {
UEXI_STATUS new_status(val);

m_status.EXIINTMASK = new_status.EXIINTMASK;
@@ -91,7 +91,7 @@ void CEXIChannel::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
if (device != nullptr)
device->SetCS(m_status.CHIP_SELECT);

ExpansionInterface::UpdateInterrupts();
system.GetExpansionInterface().UpdateInterrupts();
}));

mmio->Register(base + EXI_DMA_ADDRESS, MMIO::DirectRead<u32>(&m_dma_memory_address),
@@ -160,7 +160,7 @@ void CEXIChannel::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
void CEXIChannel::SendTransferComplete()
{
m_status.TCINT = 1;
ExpansionInterface::UpdateInterrupts();
m_system.GetExpansionInterface().UpdateInterrupts();
}

void CEXIChannel::RemoveDevices()
@@ -195,7 +195,7 @@ void CEXIChannel::AddDevice(std::unique_ptr<IEXIDevice> device, const int device
if (m_channel_id != 2)
{
m_status.EXTINT = 1;
ExpansionInterface::UpdateInterrupts();
m_system.GetExpansionInterface().UpdateInterrupts();
}
}
}
@@ -280,8 +280,8 @@ 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, device_index, EXIDeviceType::MemoryCardFolder,
CoreTiming::FromThread::CPU);
m_system.GetExpansionInterface().ChangeDevice(
m_channel_id, device_index, EXIDeviceType::MemoryCardFolder, CoreTiming::FromThread::CPU);
}
}
}
@@ -178,7 +178,7 @@ void CEXIETHERNET::ImmWrite(u32 data, u32 size)
exi_status.interrupt_mask = data;
break;
}
ExpansionInterface::UpdateInterrupts();
m_system.GetExpansionInterface().UpdateInterrupts();
}
else
{
@@ -466,7 +466,7 @@ void CEXIETHERNET::SendComplete()
mBbaMem[BBA_IR] |= INT_T;

exi_status.interrupt |= exi_status.TRANSFER;
ExpansionInterface::ScheduleUpdateInterrupts(CoreTiming::FromThread::CPU, 0);
m_system.GetExpansionInterface().ScheduleUpdateInterrupts(CoreTiming::FromThread::CPU, 0);
}

mBbaMem[BBA_LTPS] = 0;
@@ -637,7 +637,7 @@ bool CEXIETHERNET::RecvHandlePacket()
mBbaMem[BBA_IR] |= INT_R;

exi_status.interrupt |= exi_status.TRANSFER;
ExpansionInterface::ScheduleUpdateInterrupts(CoreTiming::FromThread::NON_CPU, 0);
m_system.GetExpansionInterface().ScheduleUpdateInterrupts(CoreTiming::FromThread::NON_CPU, 0);
}
else
{
@@ -56,11 +56,11 @@ 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_slot,
// stored in the userdata parameter of the CoreTiming event.
void CEXIMemoryCard::EventCompleteFindInstance(u64 userdata,
void CEXIMemoryCard::EventCompleteFindInstance(Core::System& system, u64 userdata,
std::function<void(CEXIMemoryCard*)> callback)
{
Slot card_slot = static_cast<Slot>(userdata);
IEXIDevice* self = ExpansionInterface::GetDevice(card_slot);
IEXIDevice* self = system.GetExpansionInterface().GetDevice(card_slot);
if (self != nullptr)
{
if (self->m_device_type == EXIDeviceType::MemoryCard ||
@@ -73,12 +73,13 @@ void CEXIMemoryCard::EventCompleteFindInstance(u64 userdata,

void CEXIMemoryCard::CmdDoneCallback(Core::System& system, u64 userdata, s64)
{
EventCompleteFindInstance(userdata, [](CEXIMemoryCard* instance) { instance->CmdDone(); });
EventCompleteFindInstance(system, userdata,
[](CEXIMemoryCard* instance) { instance->CmdDone(); });
}

void CEXIMemoryCard::TransferCompleteCallback(Core::System& system, u64 userdata, s64)
{
EventCompleteFindInstance(userdata,
EventCompleteFindInstance(system, userdata,
[](CEXIMemoryCard* instance) { instance->TransferComplete(); });
}

@@ -256,13 +257,14 @@ void CEXIMemoryCard::CmdDone()
m_status &= ~MC_STATUS_BUSY;

m_interrupt_set = true;
ExpansionInterface::UpdateInterrupts();
m_system.GetExpansionInterface().UpdateInterrupts();
}

void CEXIMemoryCard::TransferComplete()
{
// Transfer complete, send interrupt
ExpansionInterface::GetChannel(ExpansionInterface::SlotToEXIChannel(m_card_slot))
m_system.GetExpansionInterface()
.GetChannel(ExpansionInterface::SlotToEXIChannel(m_card_slot))
->SendTransferComplete();
}

@@ -59,7 +59,7 @@ class CEXIMemoryCard : public IEXIDevice
private:
void SetupGciFolder(const Memcard::HeaderData& header_data);
void SetupRawMemcard(u16 size_mb);
static void EventCompleteFindInstance(u64 userdata,
static void EventCompleteFindInstance(Core::System& system, u64 userdata,
std::function<void(CEXIMemoryCard*)> callback);

// Scheduled when a command that required delayed end signaling is done.
@@ -266,7 +266,7 @@ void CEXIMic::UpdateNextInterruptTicks()
{
int diff = (SystemTimers::GetTicksPerSecond() / sample_rate) * buff_size_samples;
next_int_ticks = m_system.GetCoreTiming().GetTicks() + diff;
ExpansionInterface::ScheduleUpdateInterrupts(CoreTiming::FromThread::CPU, diff);
m_system.GetExpansionInterface().ScheduleUpdateInterrupts(CoreTiming::FromThread::CPU, diff);
}

bool CEXIMic::IsInterruptSet()
@@ -44,11 +44,11 @@ void Init(const Sram* override_sram)
VideoInterface::Init();
SerialInterface::Init();
system.GetProcessorInterface().Init();
ExpansionInterface::Init(override_sram); // Needs to be initialized before Memory
system.GetExpansionInterface().Init(override_sram); // Needs to be initialized before Memory
system.GetHSP().Init();
system.GetMemory().Init(); // Needs to be initialized before AddressSpace
AddressSpace::Init();
MemoryInterface::Init();
system.GetMemoryInterface().Init();
system.GetDSP().Init(Config::Get(Config::MAIN_DSP_HLE));
system.GetDVDInterface().Init();
system.GetGPFifo().Init();
@@ -74,11 +74,11 @@ void Shutdown()
system.GetCPU().Shutdown();
system.GetDVDInterface().Shutdown();
system.GetDSP().Shutdown();
MemoryInterface::Shutdown();
system.GetMemoryInterface().Shutdown();
AddressSpace::Shutdown();
system.GetMemory().Shutdown();
system.GetHSP().Shutdown();
ExpansionInterface::Shutdown();
system.GetExpansionInterface().Shutdown();
SerialInterface::Shutdown();
system.GetAudioInterface().Shutdown();

@@ -91,7 +91,7 @@ void DoState(PointerWrap& p)
auto& system = Core::System::GetInstance();
system.GetMemory().DoState(p);
p.DoMarker("Memory");
MemoryInterface::DoState(p);
system.GetMemoryInterface().DoState(p);
p.DoMarker("MemoryInterface");
VideoInterface::DoState(p);
p.DoMarker("VideoInterface");
@@ -105,7 +105,7 @@ void DoState(PointerWrap& p)
p.DoMarker("DVDInterface");
system.GetGPFifo().DoState(p);
p.DoMarker("GPFifo");
ExpansionInterface::DoState(p);
system.GetExpansionInterface().DoState(p);
p.DoMarker("ExpansionInterface");
system.GetAudioInterface().DoState(p);
p.DoMarker("AudioInterface");
@@ -53,18 +53,18 @@ void MemoryManager::InitMMIO(bool is_wii)
system.GetPixelEngine().RegisterMMIO(m_mmio_mapping.get(), 0x0C001000);
VideoInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C002000);
system.GetProcessorInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C003000);
MemoryInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C004000);
system.GetMemoryInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C004000);
system.GetDSP().RegisterMMIO(m_mmio_mapping.get(), 0x0C005000);
system.GetDVDInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C006000, false);
SerialInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006400);
ExpansionInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006800);
system.GetExpansionInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C006800);
system.GetAudioInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C006C00);
if (is_wii)
{
IOS::RegisterMMIO(m_mmio_mapping.get(), 0x0D000000);
system.GetDVDInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0D006000, true);
SerialInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0D006400);
ExpansionInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0D006800);
system.GetExpansionInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0D006800);
system.GetAudioInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0D006C00);
}
}
@@ -11,7 +11,6 @@
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "Core/HW/MMIO.h"
#include "Core/System.h"

namespace MemoryInterface
{
@@ -55,166 +54,75 @@ enum
MI_UNKNOWN2 = 0x05A,
};

union MIRegion
{
u32 hex = 0;
struct
{
u16 first_page;
u16 last_page;
};
};

union MIProtType
{
u16 hex = 0;

BitField<0, 2, u16> reg0;
BitField<2, 2, u16> reg1;
BitField<4, 2, u16> reg2;
BitField<6, 2, u16> reg3;
BitField<8, 8, u16> reserved;
};

union MIIRQMask
{
u16 hex = 0;

BitField<0, 1, u16> reg0;
BitField<1, 1, u16> reg1;
BitField<2, 1, u16> reg2;
BitField<3, 1, u16> reg3;
BitField<4, 1, u16> all_regs;
BitField<5, 11, u16> reserved;
};

union MIIRQFlag
{
u16 hex = 0;

BitField<0, 1, u16> reg0;
BitField<1, 1, u16> reg1;
BitField<2, 1, u16> reg2;
BitField<3, 1, u16> reg3;
BitField<4, 1, u16> all_regs;
BitField<5, 11, u16> reserved;
};
MemoryInterfaceManager::MemoryInterfaceManager() = default;

union MIProtAddr
{
u32 hex = 0;
struct
{
u16 lo;
u16 hi;
};
BitField<0, 5, u32> reserved_1;
BitField<5, 25, u32> addr;
BitField<30, 2, u32> reserved_2;
};
MemoryInterfaceManager::~MemoryInterfaceManager() = default;

union MITimer
void MemoryInterfaceManager::Init()
{
u32 hex = 0;
struct
{
u16 lo;
u16 hi;
};
};

struct MIMemStruct
{
std::array<MIRegion, 4> regions;
MIProtType prot_type;
MIIRQMask irq_mask;
MIIRQFlag irq_flag;
u16 unknown1 = 0;
MIProtAddr prot_addr;
std::array<MITimer, 10> timers;
u16 unknown2 = 0;
};

struct MemoryInterfaceState::Data
{
MIMemStruct mi_mem;
};

MemoryInterfaceState::MemoryInterfaceState() : m_data(std::make_unique<Data>())
{
}

MemoryInterfaceState::~MemoryInterfaceState() = default;

void Init()
{
auto& state = Core::System::GetInstance().GetMemoryInterfaceState().GetData();
static_assert(std::is_trivially_copyable_v<MIMemStruct>);
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#endif
std::memset(&state.mi_mem, 0, sizeof(MIMemStruct));
std::memset(&m_mi_mem, 0, sizeof(MIMemStruct));
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
}

void Shutdown()
void MemoryInterfaceManager::Shutdown()
{
Init();
}

void DoState(PointerWrap& p)
void MemoryInterfaceManager::DoState(PointerWrap& p)
{
auto& state = Core::System::GetInstance().GetMemoryInterfaceState().GetData();
p.Do(state.mi_mem);
p.Do(m_mi_mem);
}

void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
void MemoryInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
{
auto& state = Core::System::GetInstance().GetMemoryInterfaceState().GetData();

for (u32 i = MI_REGION0_FIRST; i <= MI_REGION3_LAST; i += 4)
{
auto& region = state.mi_mem.regions[i / 4];
auto& region = m_mi_mem.regions[i / 4];
mmio->Register(base | i, MMIO::DirectRead<u16>(&region.first_page),
MMIO::DirectWrite<u16>(&region.first_page));
mmio->Register(base | (i + 2), MMIO::DirectRead<u16>(&region.last_page),
MMIO::DirectWrite<u16>(&region.last_page));
}

mmio->Register(base | MI_PROT_TYPE, MMIO::DirectRead<u16>(&state.mi_mem.prot_type.hex),
MMIO::DirectWrite<u16>(&state.mi_mem.prot_type.hex));
mmio->Register(base | MI_PROT_TYPE, MMIO::DirectRead<u16>(&m_mi_mem.prot_type.hex),
MMIO::DirectWrite<u16>(&m_mi_mem.prot_type.hex));

mmio->Register(base | MI_IRQMASK, MMIO::DirectRead<u16>(&state.mi_mem.irq_mask.hex),
MMIO::DirectWrite<u16>(&state.mi_mem.irq_mask.hex));
mmio->Register(base | MI_IRQMASK, MMIO::DirectRead<u16>(&m_mi_mem.irq_mask.hex),
MMIO::DirectWrite<u16>(&m_mi_mem.irq_mask.hex));

mmio->Register(base | MI_IRQFLAG, MMIO::DirectRead<u16>(&state.mi_mem.irq_flag.hex),
MMIO::DirectWrite<u16>(&state.mi_mem.irq_flag.hex));
mmio->Register(base | MI_IRQFLAG, MMIO::DirectRead<u16>(&m_mi_mem.irq_flag.hex),
MMIO::DirectWrite<u16>(&m_mi_mem.irq_flag.hex));

mmio->Register(base | MI_UNKNOWN1, MMIO::DirectRead<u16>(&state.mi_mem.unknown1),
MMIO::DirectWrite<u16>(&state.mi_mem.unknown1));
mmio->Register(base | MI_UNKNOWN1, MMIO::DirectRead<u16>(&m_mi_mem.unknown1),
MMIO::DirectWrite<u16>(&m_mi_mem.unknown1));

// The naming is confusing here: the register contains the lower part of
// the address (hence MI_..._LO but this is still the high part of the
// overall register.
mmio->Register(base | MI_PROT_ADDR_LO, MMIO::DirectRead<u16>(&state.mi_mem.prot_addr.hi),
MMIO::DirectWrite<u16>(&state.mi_mem.prot_addr.hi));
mmio->Register(base | MI_PROT_ADDR_HI, MMIO::DirectRead<u16>(&state.mi_mem.prot_addr.lo),
MMIO::DirectWrite<u16>(&state.mi_mem.prot_addr.lo));
mmio->Register(base | MI_PROT_ADDR_LO, MMIO::DirectRead<u16>(&m_mi_mem.prot_addr.hi),
MMIO::DirectWrite<u16>(&m_mi_mem.prot_addr.hi));
mmio->Register(base | MI_PROT_ADDR_HI, MMIO::DirectRead<u16>(&m_mi_mem.prot_addr.lo),
MMIO::DirectWrite<u16>(&m_mi_mem.prot_addr.lo));

for (u32 i = 0; i < state.mi_mem.timers.size(); ++i)
for (u32 i = 0; i < m_mi_mem.timers.size(); ++i)
{
auto& timer = state.mi_mem.timers[i];
auto& timer = m_mi_mem.timers[i];
mmio->Register(base | (MI_TIMER0_HI + 4 * i), MMIO::DirectRead<u16>(&timer.hi),
MMIO::DirectWrite<u16>(&timer.hi));
mmio->Register(base | (MI_TIMER0_LO + 4 * i), MMIO::DirectRead<u16>(&timer.lo),
MMIO::DirectWrite<u16>(&timer.lo));
}

mmio->Register(base | MI_UNKNOWN2, MMIO::DirectRead<u16>(&state.mi_mem.unknown2),
MMIO::DirectWrite<u16>(&state.mi_mem.unknown2));
mmio->Register(base | MI_UNKNOWN2, MMIO::DirectRead<u16>(&m_mi_mem.unknown2),
MMIO::DirectWrite<u16>(&m_mi_mem.unknown2));

for (u32 i = 0; i < 0x1000; i += 4)
{
@@ -3,10 +3,16 @@

#pragma once

#include <array>
#include <memory>

#include "Common/BitField.h"
#include "Common/CommonTypes.h"

namespace Core
{
class System;
}
namespace MMIO
{
class Mapping;
@@ -15,26 +21,103 @@ class PointerWrap;

namespace MemoryInterface
{
class MemoryInterfaceState
class MemoryInterfaceManager
{
public:
MemoryInterfaceState();
MemoryInterfaceState(const MemoryInterfaceState&) = delete;
MemoryInterfaceState(MemoryInterfaceState&&) = delete;
MemoryInterfaceState& operator=(const MemoryInterfaceState&) = delete;
MemoryInterfaceState& operator=(MemoryInterfaceState&&) = delete;
~MemoryInterfaceState();
MemoryInterfaceManager();
MemoryInterfaceManager(const MemoryInterfaceManager&) = delete;
MemoryInterfaceManager(MemoryInterfaceManager&&) = delete;
MemoryInterfaceManager& operator=(const MemoryInterfaceManager&) = delete;
MemoryInterfaceManager& operator=(MemoryInterfaceManager&&) = delete;
~MemoryInterfaceManager();

struct Data;
Data& GetData() { return *m_data; }
void Init();
void Shutdown();

void DoState(PointerWrap& p);
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);

private:
std::unique_ptr<Data> m_data;
};
union MIRegion
{
u32 hex = 0;
struct
{
u16 first_page;
u16 last_page;
};
};

union MIProtType
{
u16 hex = 0;

BitField<0, 2, u16> reg0;
BitField<2, 2, u16> reg1;
BitField<4, 2, u16> reg2;
BitField<6, 2, u16> reg3;
BitField<8, 8, u16> reserved;
};

union MIIRQMask
{
u16 hex = 0;

void Init();
void Shutdown();
BitField<0, 1, u16> reg0;
BitField<1, 1, u16> reg1;
BitField<2, 1, u16> reg2;
BitField<3, 1, u16> reg3;
BitField<4, 1, u16> all_regs;
BitField<5, 11, u16> reserved;
};

void DoState(PointerWrap& p);
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
union MIIRQFlag
{
u16 hex = 0;

BitField<0, 1, u16> reg0;
BitField<1, 1, u16> reg1;
BitField<2, 1, u16> reg2;
BitField<3, 1, u16> reg3;
BitField<4, 1, u16> all_regs;
BitField<5, 11, u16> reserved;
};

union MIProtAddr
{
u32 hex = 0;
struct
{
u16 lo;
u16 hi;
};
BitField<0, 5, u32> reserved_1;
BitField<5, 25, u32> addr;
BitField<30, 2, u32> reserved_2;
};

union MITimer
{
u32 hex = 0;
struct
{
u16 lo;
u16 hi;
};
};

struct MIMemStruct
{
std::array<MIRegion, 4> regions;
MIProtType prot_type;
MIIRQMask irq_mask;
MIIRQFlag irq_flag;
u16 unknown1 = 0;
MIProtAddr prot_addr;
std::array<MITimer, 10> timers;
u16 unknown2 = 0;
};

MIMemStruct m_mi_mem;
};
} // namespace MemoryInterface
@@ -37,7 +37,8 @@ struct System::Impl
{
explicit Impl(System& system)
: m_audio_interface(system), m_core_timing(system), m_dsp(system), m_dvd_interface(system),
m_dvd_thread(system), m_gp_fifo(system), m_ppc_state(PowerPC::ppcState)
m_dvd_thread(system), m_expansion_interface(system), m_gp_fifo(system),
m_ppc_state(PowerPC::ppcState)
{
}

@@ -52,14 +53,14 @@ struct System::Impl
DSP::DSPManager m_dsp;
DVD::DVDInterface m_dvd_interface;
DVD::DVDThread m_dvd_thread;
ExpansionInterface::ExpansionInterfaceState m_expansion_interface_state;
ExpansionInterface::ExpansionInterfaceManager m_expansion_interface;
Fifo::FifoManager m_fifo;
GeometryShaderManager m_geometry_shader_manager;
GPFifo::GPFifoManager m_gp_fifo;
HSP::HSPManager m_hsp;
IOS::HLE::USB::SkylanderPortal m_skylander_portal;
Memory::MemoryManager m_memory;
MemoryInterface::MemoryInterfaceState m_memory_interface_state;
MemoryInterface::MemoryInterfaceManager m_memory_interface;
PixelEngine::PixelEngineManager m_pixel_engine;
PixelShaderManager m_pixel_shader_manager;
PowerPC::PowerPCState& m_ppc_state;
@@ -148,9 +149,9 @@ DVD::DVDThread& System::GetDVDThread() const
return m_impl->m_dvd_thread;
}

ExpansionInterface::ExpansionInterfaceState& System::GetExpansionInterfaceState() const
ExpansionInterface::ExpansionInterfaceManager& System::GetExpansionInterface() const
{
return m_impl->m_expansion_interface_state;
return m_impl->m_expansion_interface;
}

Fifo::FifoManager& System::GetFifo() const
@@ -183,9 +184,9 @@ Memory::MemoryManager& System::GetMemory() const
return m_impl->m_memory;
}

MemoryInterface::MemoryInterfaceState& System::GetMemoryInterfaceState() const
MemoryInterface::MemoryInterfaceManager& System::GetMemoryInterface() const
{
return m_impl->m_memory_interface_state;
return m_impl->m_memory_interface;
}

PixelEngine::PixelEngineManager& System::GetPixelEngine() const
@@ -38,7 +38,7 @@ class DVDThread;
} // namespace DVD
namespace ExpansionInterface
{
class ExpansionInterfaceState;
class ExpansionInterfaceManager;
};
namespace Fifo
{
@@ -62,7 +62,7 @@ class MemoryManager;
};
namespace MemoryInterface
{
class MemoryInterfaceState;
class MemoryInterfaceManager;
};
namespace PixelEngine
{
@@ -126,14 +126,14 @@ class System
DSP::DSPManager& GetDSP() const;
DVD::DVDInterface& GetDVDInterface() const;
DVD::DVDThread& GetDVDThread() const;
ExpansionInterface::ExpansionInterfaceState& GetExpansionInterfaceState() const;
ExpansionInterface::ExpansionInterfaceManager& GetExpansionInterface() const;
Fifo::FifoManager& GetFifo() const;
GeometryShaderManager& GetGeometryShaderManager() const;
GPFifo::GPFifoManager& GetGPFifo() const;
HSP::HSPManager& GetHSP() const;
IOS::HLE::USB::SkylanderPortal& GetSkylanderPortal() const;
Memory::MemoryManager& GetMemory() const;
MemoryInterface::MemoryInterfaceState& GetMemoryInterfaceState() const;
MemoryInterface::MemoryInterfaceManager& GetMemoryInterface() const;
PixelEngine::PixelEngineManager& GetPixelEngine() const;
PixelShaderManager& GetPixelShaderManager() const;
PowerPC::PowerPCState& GetPPCState() const;
@@ -32,6 +32,7 @@
#include "Core/HW/EXI/EXI.h"
#include "Core/HW/GCMemcard/GCMemcard.h"
#include "Core/NetPlayServer.h"
#include "Core/System.h"

#include "DolphinQt/Config/Mapping/MappingWindow.h"
#include "DolphinQt/GCMemcardManager.h"
@@ -496,7 +497,8 @@ bool GameCubePane::SetMemcard(ExpansionInterface::Slot slot, const QString& file
{
// ChangeDevice unplugs the device for 1 second, which means that games should notice that
// the path has changed and thus the memory card contents have changed
ExpansionInterface::ChangeDevice(slot, ExpansionInterface::EXIDeviceType::MemoryCard);
Core::System::GetInstance().GetExpansionInterface().ChangeDevice(
slot, ExpansionInterface::EXIDeviceType::MemoryCard);
}
}

@@ -601,7 +603,8 @@ bool GameCubePane::SetGCIFolder(ExpansionInterface::Slot slot, const QString& pa
{
// ChangeDevice unplugs the device for 1 second, which means that games should notice that
// the path has changed and thus the memory card contents have changed
ExpansionInterface::ChangeDevice(slot, ExpansionInterface::EXIDeviceType::MemoryCardFolder);
Core::System::GetInstance().GetExpansionInterface().ChangeDevice(
slot, ExpansionInterface::EXIDeviceType::MemoryCardFolder);
}
}

@@ -637,7 +640,8 @@ void GameCubePane::SetAGPRom(ExpansionInterface::Slot slot, const QString& filen
// cartridge without unplugging it, and it's not clear if the AGP software actually notices
// that it's been unplugged or the cartridge has changed, but this was done for memcards so
// we might as well do it for the AGP too.
ExpansionInterface::ChangeDevice(slot, ExpansionInterface::EXIDeviceType::AGP);
Core::System::GetInstance().GetExpansionInterface().ChangeDevice(
slot, ExpansionInterface::EXIDeviceType::AGP);
}

LoadSettings();
@@ -761,7 +765,7 @@ void GameCubePane::SaveSettings()

if (Core::IsRunning() && current_exi_device != dev)
{
ExpansionInterface::ChangeDevice(slot, dev);
Core::System::GetInstance().GetExpansionInterface().ChangeDevice(slot, dev);
}

Config::SetBaseOrCurrent(Config::GetInfoForEXIDevice(slot), dev);