diff --git a/Source/Core/Core/HW/EXI_Channel.cpp b/Source/Core/Core/HW/EXI_Channel.cpp index 1af7476566..627eaacc1c 100644 --- a/Source/Core/Core/HW/EXI_Channel.cpp +++ b/Source/Core/Core/HW/EXI_Channel.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include + #include "Common/ChunkFile.h" #include "Core/ConfigManager.h" #include "Core/CoreTiming.h" @@ -35,7 +37,7 @@ CEXIChannel::CEXIChannel(u32 ChannelId) : m_Status.CHIP_SELECT = 1; for (auto& device : m_pDevices) - device.reset(EXIDevice_Create(EXIDEVICE_NONE, m_ChannelId)); + device = EXIDevice_Create(EXIDEVICE_NONE, m_ChannelId); } CEXIChannel::~CEXIChannel() @@ -166,18 +168,17 @@ void CEXIChannel::RemoveDevices() void CEXIChannel::AddDevice(const TEXIDevices device_type, const int device_num) { - IEXIDevice* pNewDevice = EXIDevice_Create(device_type, m_ChannelId); - AddDevice(pNewDevice, device_num); + AddDevice(EXIDevice_Create(device_type, m_ChannelId), device_num); } -void CEXIChannel::AddDevice(IEXIDevice* pDevice, const int device_num, bool notifyPresenceChanged) +void CEXIChannel::AddDevice(std::unique_ptr device, const int device_num, bool notify_presence_changed) { _dbg_assert_(EXPANSIONINTERFACE, device_num < NUM_DEVICES); - // replace it with the new one - m_pDevices[device_num].reset(pDevice); + // Replace it with the new one + m_pDevices[device_num] = std::move(device); - if (notifyPresenceChanged) + if (notify_presence_changed) { // This means "device presence changed", software has to check // m_Status.EXT to see if it is now present or not @@ -228,27 +229,21 @@ void CEXIChannel::DoState(PointerWrap &p) p.Do(m_Control); p.Do(m_ImmData); - for (int d = 0; d < NUM_DEVICES; ++d) + for (int device_index = 0; device_index < NUM_DEVICES; ++device_index) { - IEXIDevice* pDevice = m_pDevices[d].get(); - TEXIDevices type = pDevice->m_deviceType; + std::unique_ptr& device = m_pDevices[device_index]; + TEXIDevices type = device->m_deviceType; p.Do(type); - IEXIDevice* pSaveDevice = (type == pDevice->m_deviceType) ? pDevice : EXIDevice_Create(type, m_ChannelId); - pSaveDevice->DoState(p); - if (pSaveDevice != pDevice) + + if (type == device->m_deviceType) { - // if we had to create a temporary device, discard it if we're not loading. - // also, if no movie is active, we'll assume the user wants to keep their current devices - // instead of the ones they had when the savestate was created, - // unless the device is NONE (since ChangeDevice sets that temporarily). - if (p.GetMode() != PointerWrap::MODE_READ) - { - delete pSaveDevice; - } - else - { - AddDevice(pSaveDevice, d, false); - } + device->DoState(p); + } + else + { + std::unique_ptr save_device = EXIDevice_Create(type, m_ChannelId); + save_device->DoState(p); + AddDevice(std::move(save_device), device_index, false); } } } diff --git a/Source/Core/Core/HW/EXI_Channel.h b/Source/Core/Core/HW/EXI_Channel.h index 0a41053eaf..4a512852fe 100644 --- a/Source/Core/Core/HW/EXI_Channel.h +++ b/Source/Core/Core/HW/EXI_Channel.h @@ -97,7 +97,7 @@ public: void SendTransferComplete(); void AddDevice(const TEXIDevices device_type, const int device_num); - void AddDevice(IEXIDevice* pDevice, const int device_num, bool notifyPresenceChanged = true); + void AddDevice(std::unique_ptr device, const int device_num, bool notify_presence_changed = true); // Remove all devices void RemoveDevices(); diff --git a/Source/Core/Core/HW/EXI_Device.cpp b/Source/Core/Core/HW/EXI_Device.cpp index 80fd585f36..4a660579e7 100644 --- a/Source/Core/Core/HW/EXI_Device.cpp +++ b/Source/Core/Core/HW/EXI_Device.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include + #include "Common/ChunkFile.h" #include "Core/ConfigManager.h" #include "Core/Core.h" @@ -89,54 +91,54 @@ public: // F A C T O R Y -IEXIDevice* EXIDevice_Create(TEXIDevices device_type, const int channel_num) +std::unique_ptr EXIDevice_Create(TEXIDevices device_type, const int channel_num) { - IEXIDevice* result = nullptr; + std::unique_ptr result; switch (device_type) { case EXIDEVICE_DUMMY: - result = new CEXIDummy("Dummy"); + result = std::make_unique("Dummy"); break; case EXIDEVICE_MEMORYCARD: case EXIDEVICE_MEMORYCARDFOLDER: { bool gci_folder = (device_type == EXIDEVICE_MEMORYCARDFOLDER); - result = new CEXIMemoryCard(channel_num, gci_folder); + result = std::make_unique(channel_num, gci_folder); break; } case EXIDEVICE_MASKROM: - result = new CEXIIPL(); + result = std::make_unique(); break; case EXIDEVICE_AD16: - result = new CEXIAD16(); + result = std::make_unique(); break; case EXIDEVICE_MIC: - result = new CEXIMic(channel_num); + result = std::make_unique(channel_num); break; case EXIDEVICE_ETH: - result = new CEXIETHERNET(); + result = std::make_unique(); break; case EXIDEVICE_AM_BASEBOARD: - result = new CEXIAMBaseboard(); + result = std::make_unique(); break; case EXIDEVICE_GECKO: - result = new CEXIGecko(); + result = std::make_unique(); break; case EXIDEVICE_AGP: - result = new CEXIAgp(channel_num); + result = std::make_unique(channel_num); break; case EXIDEVICE_NONE: default: - result = new IEXIDevice(); + result = std::make_unique(); break; } diff --git a/Source/Core/Core/HW/EXI_Device.h b/Source/Core/Core/HW/EXI_Device.h index 4cc547f27f..156f49edac 100644 --- a/Source/Core/Core/HW/EXI_Device.h +++ b/Source/Core/Core/HW/EXI_Device.h @@ -4,6 +4,7 @@ #pragma once +#include #include "Common/CommonTypes.h" class PointerWrap; @@ -57,4 +58,4 @@ public: TEXIDevices m_deviceType; }; -IEXIDevice* EXIDevice_Create(const TEXIDevices device_type, const int channel_num); +std::unique_ptr EXIDevice_Create(const TEXIDevices device_type, const int channel_num); diff --git a/Source/Core/Core/HW/SI.cpp b/Source/Core/Core/HW/SI.cpp index 4a87a9d837..08539aa63c 100644 --- a/Source/Core/Core/HW/SI.cpp +++ b/Source/Core/Core/HW/SI.cpp @@ -3,6 +3,8 @@ // Refer to the license.txt file included. #include +#include +#include #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" @@ -104,7 +106,7 @@ struct SSIChannel USIChannelOut m_Out; USIChannelIn_Hi m_InHi; USIChannelIn_Lo m_InLo; - ISIDevice* m_pDevice; + std::unique_ptr m_device; }; // SI Poll: Controls how often a device is polled @@ -206,7 +208,7 @@ union USIEXIClockCount }; // STATE_TO_SAVE -static SSIChannel g_Channel[MAX_SI_CHANNELS]; +static std::array g_Channel; static USIPoll g_Poll; static USIComCSR g_ComCSR; static USIStatusReg g_StatusReg; @@ -221,26 +223,27 @@ void DoState(PointerWrap &p) p.Do(g_Channel[i].m_InLo.Hex); p.Do(g_Channel[i].m_Out.Hex); - ISIDevice* pDevice = g_Channel[i].m_pDevice; - SIDevices type = pDevice->GetDeviceType(); + std::unique_ptr& device = g_Channel[i].m_device; + SIDevices type = device->GetDeviceType(); p.Do(type); - ISIDevice* pSaveDevice = (type == pDevice->GetDeviceType()) ? pDevice : SIDevice_Create(type, i); - pSaveDevice->DoState(p); - if (pSaveDevice != pDevice) + + if (type == device->GetDeviceType()) { - // if we had to create a temporary device, discard it if we're not loading. - // also, if no movie is active, we'll assume the user wants to keep their current devices + device->DoState(p); + } + else + { + // If no movie is active, we'll assume the user wants to keep their current devices // instead of the ones they had when the savestate was created. - if (p.GetMode() != PointerWrap::MODE_READ || !Movie::IsMovieActive()) - { - delete pSaveDevice; - } - else - { - AddDevice(pSaveDevice); - } + if (!Movie::IsMovieActive()) + return; + + std::unique_ptr save_device = SIDevice_Create(type, i); + save_device->DoState(p); + AddDevice(std::move(save_device)); } } + p.Do(g_Poll); p.DoPOD(g_ComCSR); p.DoPOD(g_StatusReg); @@ -392,10 +395,10 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) // send command to devices if (tmpStatus.WR) { - g_Channel[0].m_pDevice->SendCommand(g_Channel[0].m_Out.Hex, g_Poll.EN0); - g_Channel[1].m_pDevice->SendCommand(g_Channel[1].m_Out.Hex, g_Poll.EN1); - g_Channel[2].m_pDevice->SendCommand(g_Channel[2].m_Out.Hex, g_Poll.EN2); - g_Channel[3].m_pDevice->SendCommand(g_Channel[3].m_Out.Hex, g_Poll.EN3); + g_Channel[0].m_device->SendCommand(g_Channel[0].m_Out.Hex, g_Poll.EN0); + g_Channel[1].m_device->SendCommand(g_Channel[1].m_Out.Hex, g_Poll.EN1); + g_Channel[2].m_device->SendCommand(g_Channel[2].m_Out.Hex, g_Poll.EN2); + g_Channel[3].m_device->SendCommand(g_Channel[3].m_Out.Hex, g_Poll.EN3); g_StatusReg.WR = 0; g_StatusReg.WRST0 = 0; @@ -444,29 +447,25 @@ void GenerateSIInterrupt(SIInterruptType _SIInterrupt) UpdateInterrupts(); } -void RemoveDevice(int _iDeviceNumber) +void RemoveDevice(int device_number) { - delete g_Channel[_iDeviceNumber].m_pDevice; - g_Channel[_iDeviceNumber].m_pDevice = nullptr; + g_Channel.at(device_number).m_device.reset(); } -void AddDevice(ISIDevice* pDevice) +void AddDevice(std::unique_ptr device) { - int _iDeviceNumber = pDevice->GetDeviceNumber(); + int device_number = device->GetDeviceNumber(); - //_dbg_assert_(SERIALINTERFACE, _iDeviceNumber < MAX_SI_CHANNELS); + // Delete the old device + RemoveDevice(device_number); - // delete the old device - RemoveDevice(_iDeviceNumber); - - // create the new one - g_Channel[_iDeviceNumber].m_pDevice = pDevice; + // Set the new one + g_Channel.at(device_number).m_device = std::move(device); } -void AddDevice(const SIDevices _device, int _iDeviceNumber) +void AddDevice(const SIDevices device, int device_number) { - ISIDevice *pDevice = SIDevice_Create(_device, _iDeviceNumber); - AddDevice(pDevice); + AddDevice(SIDevice_Create(device, device_number)); } static void SetNoResponse(u32 channel) @@ -515,10 +514,10 @@ void ChangeDevice(SIDevices device, int channel) void UpdateDevices() { // Update channels and set the status bit if there's new data - g_StatusReg.RDST0 = !!g_Channel[0].m_pDevice->GetData(g_Channel[0].m_InHi.Hex, g_Channel[0].m_InLo.Hex); - g_StatusReg.RDST1 = !!g_Channel[1].m_pDevice->GetData(g_Channel[1].m_InHi.Hex, g_Channel[1].m_InLo.Hex); - g_StatusReg.RDST2 = !!g_Channel[2].m_pDevice->GetData(g_Channel[2].m_InHi.Hex, g_Channel[2].m_InLo.Hex); - g_StatusReg.RDST3 = !!g_Channel[3].m_pDevice->GetData(g_Channel[3].m_InHi.Hex, g_Channel[3].m_InLo.Hex); + g_StatusReg.RDST0 = !!g_Channel[0].m_device->GetData(g_Channel[0].m_InHi.Hex, g_Channel[0].m_InLo.Hex); + g_StatusReg.RDST1 = !!g_Channel[1].m_device->GetData(g_Channel[1].m_InHi.Hex, g_Channel[1].m_InLo.Hex); + g_StatusReg.RDST2 = !!g_Channel[2].m_device->GetData(g_Channel[2].m_InHi.Hex, g_Channel[2].m_InLo.Hex); + g_StatusReg.RDST3 = !!g_Channel[3].m_device->GetData(g_Channel[3].m_InHi.Hex, g_Channel[3].m_InLo.Hex); UpdateInterrupts(); } @@ -527,8 +526,8 @@ SIDevices GetDeviceType(int channel) { if (channel < 0 || channel > 3) return SIDEVICE_NONE; - else - return g_Channel[channel].m_pDevice->GetDeviceType(); + + return g_Channel[channel].m_device->GetDeviceType(); } void RunSIBuffer(u64 userdata, int cyclesLate) @@ -549,9 +548,8 @@ void RunSIBuffer(u64 userdata, int cyclesLate) else outLength++; - int numOutput = 0; - - numOutput = g_Channel[g_ComCSR.CHANNEL].m_pDevice->RunBuffer(g_SIBuffer, inLength); + std::unique_ptr& device = g_Channel[g_ComCSR.CHANNEL].m_device; + int numOutput = device->RunBuffer(g_SIBuffer, inLength); DEBUG_LOG(SERIALINTERFACE, "RunSIBuffer chan: %d inLen: %i outLen: %i processed: %i", g_ComCSR.CHANNEL, inLength, outLength, numOutput); @@ -562,7 +560,7 @@ void RunSIBuffer(u64 userdata, int cyclesLate) } else { - CoreTiming::ScheduleEvent(g_Channel[g_ComCSR.CHANNEL].m_pDevice->TransferInterval() - cyclesLate, et_transfer_pending); + CoreTiming::ScheduleEvent(device->TransferInterval() - cyclesLate, et_transfer_pending); } } } diff --git a/Source/Core/Core/HW/SI.h b/Source/Core/Core/HW/SI.h index 3601fc5714..c3078aa72a 100644 --- a/Source/Core/Core/HW/SI.h +++ b/Source/Core/Core/HW/SI.h @@ -4,6 +4,7 @@ #pragma once +#include #include "Common/CommonTypes.h" class PointerWrap; @@ -30,7 +31,7 @@ void UpdateDevices(); void RemoveDevice(int _iDeviceNumber); void AddDevice(const SIDevices _device, int _iDeviceNumber); -void AddDevice(ISIDevice* pDevice); +void AddDevice(std::unique_ptr device); void ChangeDeviceCallback(u64 userdata, int cyclesLate); void ChangeDevice(SIDevices device, int channel); diff --git a/Source/Core/Core/HW/SI_Device.cpp b/Source/Core/Core/HW/SI_Device.cpp index f125173c97..9546cba42f 100644 --- a/Source/Core/Core/HW/SI_Device.cpp +++ b/Source/Core/Core/HW/SI_Device.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include #include #include "Common/StringUtil.h" @@ -65,41 +66,33 @@ public: // F A C T O R Y -ISIDevice* SIDevice_Create(const SIDevices device, const int port_number) +std::unique_ptr SIDevice_Create(const SIDevices device, const int port_number) { switch (device) { case SIDEVICE_GC_CONTROLLER: - return new CSIDevice_GCController(device, port_number); - break; + return std::make_unique(device, port_number); case SIDEVICE_DANCEMAT: - return new CSIDevice_DanceMat(device, port_number); - break; + return std::make_unique(device, port_number); case SIDEVICE_GC_STEERING: - return new CSIDevice_GCSteeringWheel(device, port_number); - break; + return std::make_unique(device, port_number); case SIDEVICE_GC_TARUKONGA: - return new CSIDevice_TaruKonga(device, port_number); - break; + return std::make_unique(device, port_number); case SIDEVICE_GC_GBA: - return new CSIDevice_GBA(device, port_number); - break; + return std::make_unique(device, port_number); case SIDEVICE_GC_KEYBOARD: - return new CSIDevice_Keyboard(device, port_number); - break; + return std::make_unique(device, port_number); case SIDEVICE_AM_BASEBOARD: - return new CSIDevice_AMBaseboard(device, port_number); - break; + return std::make_unique(device, port_number); case SIDEVICE_NONE: default: - return new CSIDevice_Null(device, port_number); - break; + return std::make_unique(device, port_number); } } diff --git a/Source/Core/Core/HW/SI_Device.h b/Source/Core/Core/HW/SI_Device.h index c1e9cfa602..abaf25cbd3 100644 --- a/Source/Core/Core/HW/SI_Device.h +++ b/Source/Core/Core/HW/SI_Device.h @@ -4,6 +4,7 @@ #pragma once +#include #include "Common/CommonTypes.h" class PointerWrap; @@ -105,4 +106,4 @@ public: } }; -ISIDevice* SIDevice_Create(const SIDevices device, const int port_number); +std::unique_ptr SIDevice_Create(const SIDevices device, const int port_number);