From a7299a7ffff9180a3414c5da48c27aa08571e66c Mon Sep 17 00:00:00 2001 From: skidau Date: Tue, 20 Jan 2015 23:41:46 +1100 Subject: [PATCH] Added support for AGP. Original patch by GreyRogue. --- Source/Core/Core/CMakeLists.txt | 1 + Source/Core/Core/ConfigManager.cpp | 4 + Source/Core/Core/ConfigManager.h | 2 + Source/Core/Core/Core.vcxproj | 2 + Source/Core/Core/Core.vcxproj.filters | 8 +- Source/Core/Core/HW/EXI_Device.cpp | 6 + Source/Core/Core/HW/EXI_Device.h | 1 + Source/Core/Core/HW/EXI_DeviceAGP.cpp | 253 ++++++++++++++++++++++++++ Source/Core/Core/HW/EXI_DeviceAGP.h | 61 +++++++ Source/Core/DolphinWX/ConfigMain.cpp | 107 +++++++---- Source/Core/DolphinWX/ConfigMain.h | 2 +- 11 files changed, 410 insertions(+), 37 deletions(-) create mode 100644 Source/Core/Core/HW/EXI_DeviceAGP.cpp create mode 100644 Source/Core/Core/HW/EXI_DeviceAGP.h diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index ab0eff73f3..dad625101b 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -91,6 +91,7 @@ set(SRCS ActionReplay.cpp HW/EXI.cpp HW/EXI_Device.cpp HW/EXI_DeviceAD16.cpp + HW/EXI_DeviceAGP.cpp HW/EXI_DeviceAMBaseboard.cpp HW/EXI_DeviceEthernet.cpp HW/EXI_DeviceGecko.cpp diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 1ad45b2083..3080610cbb 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -329,6 +329,8 @@ void SConfig::SaveCoreSettings(IniFile& ini) core->Set("Latency", m_LocalCoreStartupParameter.iLatency); core->Set("MemcardAPath", m_strMemoryCardA); core->Set("MemcardBPath", m_strMemoryCardB); + core->Set("AgpCartAPath", m_strGbaCartA); + core->Set("AgpCartBPath", m_strGbaCartB); core->Set("SlotA", m_EXIDevice[0]); core->Set("SlotB", m_EXIDevice[1]); core->Set("SerialPort1", m_EXIDevice[2]); @@ -559,6 +561,8 @@ void SConfig::LoadCoreSettings(IniFile& ini) core->Get("Latency", &m_LocalCoreStartupParameter.iLatency, 2); core->Get("MemcardAPath", &m_strMemoryCardA); core->Get("MemcardBPath", &m_strMemoryCardB); + core->Get("AgpCartAPath", &m_strGbaCartA); + core->Get("AgpCartBPath", &m_strGbaCartB); core->Get("SlotA", (int*)&m_EXIDevice[0], EXIDEVICE_MEMORYCARD); core->Get("SlotB", (int*)&m_EXIDevice[1], EXIDEVICE_NONE); core->Get("SerialPort1", (int*)&m_EXIDevice[2], EXIDEVICE_NONE); diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h index 5341ec61e0..a65aca6b05 100644 --- a/Source/Core/Core/ConfigManager.h +++ b/Source/Core/Core/ConfigManager.h @@ -41,6 +41,8 @@ struct SConfig : NonCopyable std::string m_strMemoryCardA; std::string m_strMemoryCardB; + std::string m_strGbaCartA; + std::string m_strGbaCartB; TEXIDevices m_EXIDevice[3]; SIDevices m_SIDevice[4]; std::string m_bba_mac; diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index bf34fbabbe..6a64d89a5a 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -122,6 +122,7 @@ + @@ -330,6 +331,7 @@ + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index d8213794ae..39f1aea85b 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -385,6 +385,9 @@ HW %28Flipper/Hollywood%29\EXI - Expansion Interface + + HW %28Flipper/Hollywood%29\EXI - Expansion Interface + HW %28Flipper/Hollywood%29\EXI - Expansion Interface @@ -914,6 +917,9 @@ HW %28Flipper/Hollywood%29\EXI - Expansion Interface + + HW %28Flipper/Hollywood%29\EXI - Expansion Interface + HW %28Flipper/Hollywood%29\EXI - Expansion Interface @@ -1229,4 +1235,4 @@ - \ No newline at end of file + diff --git a/Source/Core/Core/HW/EXI_Device.cpp b/Source/Core/Core/HW/EXI_Device.cpp index ccc1fbb968..611534921e 100644 --- a/Source/Core/Core/HW/EXI_Device.cpp +++ b/Source/Core/Core/HW/EXI_Device.cpp @@ -7,6 +7,7 @@ #include "Core/Core.h" #include "Core/HW/EXI_Device.h" #include "Core/HW/EXI_DeviceAD16.h" +#include "Core/HW/EXI_DeviceAGP.h" #include "Core/HW/EXI_DeviceAMBaseboard.h" #include "Core/HW/EXI_DeviceEthernet.h" #include "Core/HW/EXI_DeviceGecko.h" @@ -84,6 +85,7 @@ public: u32 ImmRead (u32 size) override {INFO_LOG(EXPANSIONINTERFACE, "EXI DUMMY %s ImmRead", m_strName.c_str()); return 0;} void DMAWrite(u32 addr, u32 size) override {INFO_LOG(EXPANSIONINTERFACE, "EXI DUMMY %s DMAWrite: %08x bytes, from %08x to device", m_strName.c_str(), size, addr);} void DMARead (u32 addr, u32 size) override {INFO_LOG(EXPANSIONINTERFACE, "EXI DUMMY %s DMARead: %08x bytes, from device to %08x", m_strName.c_str(), size, addr);} + bool IsPresent() override { return true; } }; @@ -129,6 +131,10 @@ IEXIDevice* EXIDevice_Create(TEXIDevices device_type, const int channel_num) result = new CEXIGecko(); break; + case EXIDEVICE_AGP: + result = new CEXIAgp(channel_num); + break; + case EXIDEVICE_NONE: default: result = new IEXIDevice(); diff --git a/Source/Core/Core/HW/EXI_Device.h b/Source/Core/Core/HW/EXI_Device.h index b09732eb06..faea05dd42 100644 --- a/Source/Core/Core/HW/EXI_Device.h +++ b/Source/Core/Core/HW/EXI_Device.h @@ -19,6 +19,7 @@ enum TEXIDevices EXIDEVICE_GECKO, EXIDEVICE_MEMORYCARDFOLDER, // Only used when creating a device by EXIDevice_Create // Converted to EXIDEVICE_MEMORYCARD internally + EXIDEVICE_AGP, EXIDEVICE_NONE = (u8)-1 }; diff --git a/Source/Core/Core/HW/EXI_DeviceAGP.cpp b/Source/Core/Core/HW/EXI_DeviceAGP.cpp new file mode 100644 index 0000000000..bcd3027a93 --- /dev/null +++ b/Source/Core/Core/HW/EXI_DeviceAGP.cpp @@ -0,0 +1,253 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "Common/FileUtil.h" +#include "Common/MemoryUtil.h" +#include "Common/StdMakeUnique.h" +#include "Core/ConfigManager.h" +#include "Core/Core.h" +#include "Core/HW/EXI_Device.h" +#include "Core/HW/EXI_DeviceAGP.h" +#include "Core/HW/Memmap.h" + +CEXIAgp::CEXIAgp(int index) : + m_slot(index) +{ + // Create the ROM + m_pHashArray = (u8*)AllocateMemoryPages(HASH_SIZE); + m_rom_size = 0; + + LoadRom(); + + m_address = 0; + m_rom_hash_loaded = false; +} + +CEXIAgp::~CEXIAgp() +{ + m_pROM = nullptr; + m_pHashArray = nullptr; +} + +void CEXIAgp::DoHash(u8* data, u32 size) +{ + for (u32 it = 0; it < size; it++) + { + m_hash = m_hash ^ data[it]; + m_hash = m_pHashArray[m_hash]; + } +} + +void CEXIAgp::LoadRom() +{ + // Load whole ROM dump + std::string path; + std::string filename; + std::string ext; + std::string gbapath; + SplitPath(m_slot == 0 ? SConfig::GetInstance().m_strGbaCartA : SConfig::GetInstance().m_strGbaCartB, &path, &filename, &ext); + gbapath = path + filename; + LoadFileToROM(gbapath + ext); + INFO_LOG(EXPANSIONINTERFACE, "Loaded gba rom: %s card: %d", gbapath.c_str(), m_slot); + LoadFileToEEPROM(gbapath + ".sav"); + INFO_LOG(EXPANSIONINTERFACE, "Loaded gba sav: %s card: %d", gbapath.c_str(), m_slot); +} + +void CEXIAgp::LoadFileToROM(std::string filename) +{ + File::IOFile pStream(filename, "rb"); + if (pStream) + { + u64 filesize = pStream.GetSize(); + m_rom_size = filesize & 0xFFFFFFFF; + m_rom_mask = (m_rom_size - 1); + + m_pROM = (u8*)AllocateMemoryPages(m_rom_size); + + pStream.ReadBytes(m_pROM, filesize); + } + else + { + // dummy rom data + m_pROM = (u8*)AllocateMemoryPages(0x2000); + } +} + +void CEXIAgp::LoadFileToEEPROM(std::string filename) +{ + File::IOFile pStream(filename, "rb"); + if (pStream) + { + u64 filesize = pStream.GetSize(); + m_eeprom_size = filesize & 0xFFFFFFFF; + m_eeprom_mask = (m_eeprom_size - 1); + + m_pEEPROM = (u8*)AllocateMemoryPages(m_eeprom_size); + + pStream.ReadBytes(m_pEEPROM, filesize); + } +} + +void CEXIAgp::LoadHash() +{ + if (!m_rom_hash_loaded && m_rom_size > 0) + { + for (int i = 0; i < 0x100; i++) + { + m_pHashArray[i] = Memory::ReadUnchecked_U8(0x0017e908 + i); + } + m_rom_hash_loaded = true; + } +} + +u32 CEXIAgp::ImmRead(u32 _uSize) +{ + // We don't really care about _uSize + (void)_uSize; + u32 uData = 0; + u8 RomVal1, RomVal2, RomVal3, RomVal4; + + switch (m_currrent_cmd) + { + case 0xAE000000: + uData = 0x5AAA5517; // 17 is precalculated hash + m_currrent_cmd = 0; + break; + case 0xAE010000: + uData = (m_return_pos == 0) ? 0x01020304 : 0xF0020304; // F0 is precalculated hash, 020304 is left over + if (m_return_pos == 1) + m_currrent_cmd = 0; + else + m_return_pos = 1; + break; + case 0xAE020000: + if (m_rw_offset == 0x8000000) + { + RomVal1 = 0x0; + RomVal2 = 0x1; + } + else + { + RomVal1 = m_pROM[m_rw_offset++]; + RomVal2 = m_pROM[m_rw_offset++]; + LoadHash(); + } + DoHash(&RomVal2, 1); + DoHash(&RomVal1, 1); + uData = (RomVal2 << 24) | (RomVal1 << 16) | (m_hash << 8); + m_currrent_cmd = 0; + break; + case 0xAE030000: + if (_uSize == 1) + { + uData = 0xFF000000; + m_currrent_cmd = 0; + } + else + { + RomVal1 = m_pROM[m_rw_offset++]; + RomVal2 = m_pROM[m_rw_offset++]; + RomVal3 = m_pROM[m_rw_offset++]; + RomVal4 = m_pROM[m_rw_offset++]; + LoadHash(); + DoHash(&RomVal2, 1); + DoHash(&RomVal1, 1); + DoHash(&RomVal4, 1); + DoHash(&RomVal3, 1); + uData = (RomVal2 << 24) | (RomVal1 << 16) | (RomVal4 << 8) | (RomVal3); + } + break; + case 0xAE0B0000: + RomVal1 = m_eeprom_pos < 4 ? 0xA : (((u64*)m_pEEPROM)[(m_eeprom_cmd >> 1) & 0x3F] >> (m_eeprom_pos - 4)) & 0x1; + RomVal2 = 0; + DoHash(&RomVal2, 1); + DoHash(&RomVal1, 1); + uData = (RomVal2 << 24) | (RomVal1 << 16) | (m_hash << 8); + m_eeprom_pos++; + m_currrent_cmd = 0; + break; + case 0xAE0C0000: + uData = m_hash << 24; + m_currrent_cmd = 0; + break; + default: + uData = 0x0; + m_currrent_cmd = 0; + break; + } + INFO_LOG(EXPANSIONINTERFACE, "AGP read %x", uData); + return uData; +} + +void CEXIAgp::ImmWrite(u32 _uData, u32 _uSize) +{ + if ((_uSize == 1) && ((_uData & 0xFF000000) == 0)) + return; + + u8 HashCmd; + u64 Mask; + INFO_LOG(EXPANSIONINTERFACE, "AGP command %x", _uData); + switch (m_currrent_cmd) + { + case 0xAE020000: + case 0xAE030000: + m_rw_offset = ((_uData & 0xFFFFFF00) >> 7) & m_rom_mask; + m_return_pos = 0; + HashCmd = (_uData & 0xFF000000) >> 24; + DoHash(&HashCmd, 1); + HashCmd = (_uData & 0x00FF0000) >> 16; + DoHash(&HashCmd, 1); + HashCmd = (_uData & 0x0000FF00) >> 8; + DoHash(&HashCmd, 1); + break; + case 0xAE0C0000: + if ((m_eeprom_pos < 0x8) || (m_eeprom_pos == ((m_eeprom_cmd & EE_READ) ? 0x8 : 0x48))) + { + Mask = (u64)(1 << (0x8-(m_eeprom_pos > 0x8 ? 0x8 : m_eeprom_pos))); + if ((_uData >> 16) & 0x1) + m_eeprom_cmd |= Mask; + else + m_eeprom_cmd &= ~Mask; + if (m_eeprom_pos == 0x48) + ((u64*)(m_pEEPROM))[(m_eeprom_cmd >> 1) & 0x3F] = m_eeprom_data; + } + else + { + Mask = (u64)(1 << (0x47 - m_eeprom_pos)); + if ((_uData >> 16) & 0x1) + m_eeprom_data |= Mask; + else + m_eeprom_data &= ~Mask; + } + m_eeprom_pos++; + m_return_pos = 0; + HashCmd = (_uData & 0xFF000000) >> 24; + DoHash(&HashCmd, 1); + HashCmd = (_uData & 0x00FF0000) >> 16; + DoHash(&HashCmd, 1); + break; + case 0xAE0B0000: + break; + case 0xAE000000: + case 0xAE010000: + case 0xAE090000: + case 0xAE0A0000: + default: + m_eeprom_pos = 0; + m_currrent_cmd = _uData; + m_return_pos = 0; + m_hash = 0xFF; + HashCmd = (_uData & 0x00FF0000) >> 16; + DoHash(&HashCmd, 1); + break; + } +} + +void CEXIAgp::DoState(PointerWrap &p) +{ + p.Do(m_position); + p.Do(m_address); + p.Do(m_rw_offset); + p.Do(m_hash); +} diff --git a/Source/Core/Core/HW/EXI_DeviceAGP.h b/Source/Core/Core/HW/EXI_DeviceAGP.h new file mode 100644 index 0000000000..1b6f10052d --- /dev/null +++ b/Source/Core/Core/HW/EXI_DeviceAGP.h @@ -0,0 +1,61 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include +#include + +#include "Core/HW/EXI_Device.h" + +class CEXIAgp + : public IEXIDevice +{ +public: + CEXIAgp(const int index); + virtual ~CEXIAgp() override; + bool IsPresent() override { return true; } + void ImmWrite(u32 _uData, u32 _uSize) override; + u32 ImmRead(u32 _uSize) override; + void DoState(PointerWrap &p) override; + +private: + enum + { + HASH_SIZE = 256, + HASH_MASK = (HASH_SIZE - 1), + EE_READ = 0x80 + }; + + int m_slot; + + //! ROM + u32 m_rom_size = 0; + u32 m_rom_mask = 0; + u32 m_eeprom_size = 0; + u32 m_eeprom_mask = 0; + u8* m_pROM; + u8* m_pEEPROM; + u8* m_pHashArray; + + //! Helper + u32 m_position = 0; + u32 m_address = 0; + u32 m_rw_offset = 0; + u64 m_eeprom_data = 0; + u8 m_eeprom_pos = 0; + u16 m_eeprom_cmd = 0; + + void LoadFileToROM(std::string filename); + void LoadFileToEEPROM(std::string filename); + void LoadHash(); + void LoadRom(); + void DoHash(u8* data, u32 size); + + u8 m_hash = 0; + u32 m_currrent_cmd = 0; + u32 m_return_pos = 0; + + bool m_rom_hash_loaded = false; +}; diff --git a/Source/Core/DolphinWX/ConfigMain.cpp b/Source/Core/DolphinWX/ConfigMain.cpp index 3c2f775723..1f5d4b1913 100644 --- a/Source/Core/DolphinWX/ConfigMain.cpp +++ b/Source/Core/DolphinWX/ConfigMain.cpp @@ -111,6 +111,7 @@ static const wxLanguage langIds[] = #define EXIDEV_MEMDIR_STR _trans("GCI Folder") #define EXIDEV_MIC_STR _trans("Mic") #define EXIDEV_BBA_STR "BBA" +#define EXIDEV_AGP_STR "Advance Game Port" #define EXIDEV_AM_BB_STR _trans("AM-Baseboard") #define EXIDEV_GECKO_STR "USBGecko" @@ -382,8 +383,9 @@ void CConfigMain::InitializeGUIValues() SlotDevices.Add(_(DEV_NONE_STR)); SlotDevices.Add(_(DEV_DUMMY_STR)); SlotDevices.Add(_(EXIDEV_MEMCARD_STR)); - SlotDevices.Add(_(EXIDEV_GECKO_STR)); SlotDevices.Add(_(EXIDEV_MEMDIR_STR)); + SlotDevices.Add(_(EXIDEV_GECKO_STR)); + SlotDevices.Add(_(EXIDEV_AGP_STR)); #if HAVE_PORTAUDIO SlotDevices.Add(_(EXIDEV_MIC_STR)); @@ -415,10 +417,16 @@ void CConfigMain::InitializeGUIValues() isMemcard = GCEXIDevice[i]->SetStringSelection(SlotDevices[2]); break; case EXIDEVICE_MEMORYCARDFOLDER: + GCEXIDevice[i]->SetStringSelection(SlotDevices[3]); + break; + case EXIDEVICE_GECKO: GCEXIDevice[i]->SetStringSelection(SlotDevices[4]); break; + case EXIDEVICE_AGP: + isMemcard = GCEXIDevice[i]->SetStringSelection(SlotDevices[5]); + break; case EXIDEVICE_MIC: - GCEXIDevice[i]->SetStringSelection(SlotDevices[5]); + GCEXIDevice[i]->SetStringSelection(SlotDevices[6]); break; case EXIDEVICE_ETH: GCEXIDevice[i]->SetStringSelection(SP1Devices[2]); @@ -426,9 +434,6 @@ void CConfigMain::InitializeGUIValues() case EXIDEVICE_AM_BASEBOARD: GCEXIDevice[i]->SetStringSelection(SP1Devices[3]); break; - case EXIDEVICE_GECKO: - GCEXIDevice[i]->SetStringSelection(SlotDevices[3]); - break; case EXIDEVICE_DUMMY: default: GCEXIDevice[i]->SetStringSelection(SlotDevices[1]); @@ -1015,68 +1020,98 @@ void CConfigMain::GCSettingsChanged(wxCommandEvent& event) ChooseEXIDevice(event.GetString(), exidevice); break; case ID_GC_EXIDEVICE_SLOTA_PATH: - ChooseMemcardPath(SConfig::GetInstance().m_strMemoryCardA, true); + ChooseSlotPath(true, SConfig::GetInstance().m_EXIDevice[0]); break; case ID_GC_EXIDEVICE_SLOTB_PATH: - ChooseMemcardPath(SConfig::GetInstance().m_strMemoryCardB, false); + ChooseSlotPath(false, SConfig::GetInstance().m_EXIDevice[0]); break; } } -void CConfigMain::ChooseMemcardPath(std::string& strMemcard, bool isSlotA) +void CConfigMain::ChooseSlotPath(bool isSlotA, TEXIDevices device_type) { + bool memcard = (device_type == EXIDEVICE_MEMORYCARD); + std::string path; + std::string cardname; + std::string ext; + std::string pathA = SConfig::GetInstance().m_strMemoryCardA; + std::string pathB = SConfig::GetInstance().m_strMemoryCardB; + if (!memcard) + { + pathA = SConfig::GetInstance().m_strGbaCartA; + pathB = SConfig::GetInstance().m_strGbaCartB; + } + SplitPath(isSlotA ? pathA : pathB, &path, &cardname, &ext); std::string filename = WxStrToStr(wxFileSelector( _("Choose a file to open"), - StrToWxStr(File::GetUserPath(D_GCUSER_IDX)), - isSlotA ? GC_MEMCARDA : GC_MEMCARDB, - wxEmptyString, - _("GameCube Memory Cards (*.raw,*.gcp)") + "|*.raw;*.gcp")); + StrToWxStr(path), + StrToWxStr(cardname), + StrToWxStr(ext), + memcard ? _("GameCube Memory Cards (*.raw,*.gcp)") + "|*.raw;*.gcp" : _("Game Boy Advance Carts (*.gba)") + "|*.gba")); if (!filename.empty()) { if (File::Exists(filename)) { - GCMemcard memorycard(filename); - if (!memorycard.IsValid()) + if (memcard) + { + GCMemcard memorycard(filename); + if (!memorycard.IsValid()) + { + WxUtils::ShowErrorDialog(wxString::Format(_("Cannot use that file as a memory card.\n%s\n" \ + "is not a valid gamecube memory card file"), filename.c_str())); + return; + } + } + else { - WxUtils::ShowErrorDialog(wxString::Format(_("Cannot use that file as a memory card.\n%s\n" \ - "is not a valid gamecube memory card file"), filename.c_str())); return; } } - #ifdef _WIN32 - if (!strncmp(File::GetExeDirectory().c_str(), filename.c_str(), File::GetExeDirectory().size())) +#ifdef _WIN32 + if (!strncmp(File::GetExeDirectory().c_str(), filename.c_str(), File::GetExeDirectory().size())) + { + // If the Exe Directory Matches the prefix of the filename, we still need to verify + // that the next character is a directory separator character, otherwise we may create an invalid path + char next_char = filename.at(File::GetExeDirectory().size()) + 1; + if (next_char == '/' || next_char == '\\') { - // If the Exe Directory Matches the prefix of the filename, we still need to verify - // that the next character is a directory separator character, otherwise we may create an invalid path - char next_char = filename.at(File::GetExeDirectory().size())+1; - if (next_char == '/' || next_char == '\\') - { - filename.erase(0, File::GetExeDirectory().size() +1); - filename = "./" + filename; - } + filename.erase(0, File::GetExeDirectory().size() + 1); + filename = "./" + filename; } - #endif + } +#endif // also check that the path isn't used for the other memcard... - if (filename.compare(isSlotA ? SConfig::GetInstance().m_strMemoryCardB - : SConfig::GetInstance().m_strMemoryCardA) != 0) + if (filename.compare(isSlotA ? pathB : pathA) != 0) { - strMemcard = filename; + if (memcard) + { + if (isSlotA) + SConfig::GetInstance().m_strMemoryCardA = filename; + else + SConfig::GetInstance().m_strMemoryCardB = filename; + } + else + { + if (isSlotA) + SConfig::GetInstance().m_strGbaCartA = filename; + else + SConfig::GetInstance().m_strGbaCartB = filename; + } if (Core::IsRunning()) { // Change memcard to the new file ExpansionInterface::ChangeDevice( isSlotA ? 0 : 1, // SlotA: channel 0, SlotB channel 1 - EXIDEVICE_MEMORYCARD, + device_type, 0); // SP1 is device 2, slots are device 0 } } else { - WxUtils::ShowErrorDialog(_("Cannot use that file as a memory card.\n" - "Are you trying to use the same file in both slots?")); + WxUtils::ShowErrorDialog(_("Are you trying to use the same file in both slots?")); } } } @@ -1093,6 +1128,8 @@ void CConfigMain::ChooseEXIDevice(wxString deviceName, int deviceNum) tempType = EXIDEVICE_MIC; else if (!deviceName.compare(EXIDEV_BBA_STR)) tempType = EXIDEVICE_ETH; + else if (!deviceName.compare(EXIDEV_AGP_STR)) + tempType = EXIDEVICE_AGP; else if (!deviceName.compare(_(EXIDEV_AM_BB_STR))) tempType = EXIDEVICE_AM_BASEBOARD; else if (!deviceName.compare(EXIDEV_GECKO_STR)) @@ -1102,8 +1139,8 @@ void CConfigMain::ChooseEXIDevice(wxString deviceName, int deviceNum) else tempType = EXIDEVICE_DUMMY; - // Gray out the memcard path button if we're not on a memcard - if (tempType == EXIDEVICE_MEMORYCARD) + // Gray out the memcard path button if we're not on a memcard or AGP + if (tempType == EXIDEVICE_MEMORYCARD || tempType == EXIDEVICE_AGP) GCMemcardPath[deviceNum]->Enable(); else if (deviceNum == 0 || deviceNum == 1) GCMemcardPath[deviceNum]->Disable(); diff --git a/Source/Core/DolphinWX/ConfigMain.h b/Source/Core/DolphinWX/ConfigMain.h index 85e4b67c27..08f69fec40 100644 --- a/Source/Core/DolphinWX/ConfigMain.h +++ b/Source/Core/DolphinWX/ConfigMain.h @@ -254,7 +254,7 @@ private: void AddAudioBackends(); void GCSettingsChanged(wxCommandEvent& event); - void ChooseMemcardPath(std::string& strMemcard, bool isSlotA); + void ChooseSlotPath(bool isSlotA, TEXIDevices device_type); void ChooseEXIDevice(wxString deviceName, int deviceNum); void WiiSettingsChanged(wxCommandEvent& event);