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);