mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 16:19:28 +01:00
allow hotplugging of exi devices. memcard_a seems to have some bug which convinces the hw there is a 0mb device there when it's really a dummy device...
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2481 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
c83a034d12
commit
9a93928e3e
@ -18,15 +18,18 @@
|
|||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "ChunkFile.h"
|
#include "ChunkFile.h"
|
||||||
#include "../ConfigManager.h"
|
#include "../ConfigManager.h"
|
||||||
|
#include "../CoreTiming.h"
|
||||||
|
|
||||||
#include "PeripheralInterface.h"
|
#include "PeripheralInterface.h"
|
||||||
#include "../PowerPC/PowerPC.h"
|
#include "../PowerPC/PowerPC.h"
|
||||||
|
|
||||||
#include "EXI_Channel.h"
|
#include "EXI.h"
|
||||||
|
|
||||||
namespace ExpansionInterface
|
namespace ExpansionInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static int changeDevice;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
NUM_CHANNELS = 3
|
NUM_CHANNELS = 3
|
||||||
@ -49,6 +52,8 @@ void Init()
|
|||||||
g_Channels[0].AddDevice(SConfig::GetInstance().m_EXIDevice[2], 2);
|
g_Channels[0].AddDevice(SConfig::GetInstance().m_EXIDevice[2], 2);
|
||||||
g_Channels[1].AddDevice(SConfig::GetInstance().m_EXIDevice[1], 0);
|
g_Channels[1].AddDevice(SConfig::GetInstance().m_EXIDevice[1], 0);
|
||||||
g_Channels[2].AddDevice(EXIDEVICE_AD16, 0);
|
g_Channels[2].AddDevice(EXIDEVICE_AD16, 0);
|
||||||
|
|
||||||
|
changeDevice = CoreTiming::RegisterEvent("ChangeEXIDevice", ChangeDeviceCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
@ -62,6 +67,23 @@ void DoState(PointerWrap &p)
|
|||||||
// TODO: descend all the devices recursively.
|
// TODO: descend all the devices recursively.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChangeDeviceCallback(u64 userdata, int cyclesLate)
|
||||||
|
{
|
||||||
|
u8 channel = (u8)(userdata >> 32);
|
||||||
|
u8 device = (u8)(userdata >> 16);
|
||||||
|
u8 slot = (u8)userdata;
|
||||||
|
|
||||||
|
g_Channels[channel].AddDevice((TEXIDevices)device, slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChangeDevice(u8 channel, TEXIDevices device, u8 slot)
|
||||||
|
{
|
||||||
|
// Called from GUI, so we need to make it thread safe.
|
||||||
|
// Let the hardware see no device for .5b cycles
|
||||||
|
CoreTiming::ScheduleEvent_Threadsafe(0, changeDevice, ((u64)channel << 32) | ((u64)EXIDEVICE_DUMMY << 16) | slot);
|
||||||
|
CoreTiming::ScheduleEvent_Threadsafe(500000000, changeDevice, ((u64)channel << 32) | ((u64)device << 16) | slot);
|
||||||
|
}
|
||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
g_Channels[0].Update();
|
g_Channels[0].Update();
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#define _EXIINTERFACE_H
|
#define _EXIINTERFACE_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "EXI_Channel.h"
|
||||||
|
#include "Thread.h"
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
|
|
||||||
namespace ExpansionInterface
|
namespace ExpansionInterface
|
||||||
@ -30,6 +32,9 @@ void DoState(PointerWrap &p);
|
|||||||
void Update();
|
void Update();
|
||||||
void UpdateInterrupts();
|
void UpdateInterrupts();
|
||||||
|
|
||||||
|
void ChangeDeviceCallback(u64 userdata, int cyclesLate);
|
||||||
|
void ChangeDevice(u8 channel, TEXIDevices device, u8 slot);
|
||||||
|
|
||||||
void Read32(u32& _uReturnValue, const u32 _iAddress);
|
void Read32(u32& _uReturnValue, const u32 _iAddress);
|
||||||
void Write32(const u32 _iValue, const u32 _iAddress);
|
void Write32(const u32 _iValue, const u32 _iAddress);
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Core.h" // Core
|
#include "Core.h" // Core
|
||||||
|
#include "HW/EXI.h"
|
||||||
#include "ConsoleWindow.h"
|
#include "ConsoleWindow.h"
|
||||||
|
|
||||||
#include "Globals.h" // Local
|
#include "Globals.h" // Local
|
||||||
@ -135,10 +136,9 @@ void CConfigMain::UpdateGUI()
|
|||||||
OptimizeQuantizers->Disable();
|
OptimizeQuantizers->Disable();
|
||||||
SkipIdle->Disable();
|
SkipIdle->Disable();
|
||||||
EnableCheats->Disable();
|
EnableCheats->Disable();
|
||||||
// Disable GC Stuff, but devices should be dynamic soon
|
|
||||||
GCSystemLang->Disable();
|
GCSystemLang->Disable();
|
||||||
GCEXIDevice[0]->Disable(); GCEXIDevice[1]->Disable(); GCEXIDevice[2]->Disable();
|
|
||||||
GCMemcardPath[0]->Disable(); GCMemcardPath[1]->Disable();
|
GCMemcardPath[0]->Disable(); GCMemcardPath[1]->Disable();
|
||||||
|
// Disable GC SI Stuff, but devices should be dynamic soon
|
||||||
GCSIDevice[0]->Disable(); GCSIDevice[1]->Disable(); GCSIDevice[2]->Disable(); GCSIDevice[3]->Disable();
|
GCSIDevice[0]->Disable(); GCSIDevice[1]->Disable(); GCSIDevice[2]->Disable(); GCSIDevice[3]->Disable();
|
||||||
WiiPage->Disable();
|
WiiPage->Disable();
|
||||||
PathsPage->Disable();
|
PathsPage->Disable();
|
||||||
@ -628,51 +628,26 @@ void CConfigMain::CoreSettingsChanged(wxCommandEvent& event)
|
|||||||
void CConfigMain::GCSettingsChanged(wxCommandEvent& event)
|
void CConfigMain::GCSettingsChanged(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
int sidevice = 0;
|
int sidevice = 0;
|
||||||
|
int exidevice = 0;
|
||||||
switch (event.GetId())
|
switch (event.GetId())
|
||||||
{
|
{
|
||||||
case ID_GC_SRAM_LNG:
|
case ID_GC_SRAM_LNG:
|
||||||
SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage = GCSystemLang->GetSelection();
|
SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage = GCSystemLang->GetSelection();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ID_GC_EXIDEVICE_SP1: // The only thing we emulate on SP1 is the BBA
|
||||||
|
exidevice++;
|
||||||
|
case ID_GC_EXIDEVICE_SLOTB:
|
||||||
|
exidevice++;
|
||||||
case ID_GC_EXIDEVICE_SLOTA:
|
case ID_GC_EXIDEVICE_SLOTA:
|
||||||
switch (event.GetSelection())
|
ChooseEXIDevice(std::string(event.GetString().mb_str()), exidevice);
|
||||||
{
|
|
||||||
case 1: // memcard
|
|
||||||
SConfig::GetInstance().m_EXIDevice[0] = EXIDEVICE_MEMORYCARD_A;
|
|
||||||
break;
|
|
||||||
case 2: // mic
|
|
||||||
SConfig::GetInstance().m_EXIDevice[0] = EXIDEVICE_MIC;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
SConfig::GetInstance().m_EXIDevice[0] = EXIDEVICE_DUMMY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
GCMemcardPath[0]->Enable(event.GetSelection() == 1);
|
|
||||||
break;
|
break;
|
||||||
case ID_GC_EXIDEVICE_SLOTA_PATH:
|
case ID_GC_EXIDEVICE_SLOTA_PATH:
|
||||||
ChooseMemcardPath(SConfig::GetInstance().m_strMemoryCardA, true);
|
ChooseMemcardPath(SConfig::GetInstance().m_strMemoryCardA, true);
|
||||||
break;
|
break;
|
||||||
case ID_GC_EXIDEVICE_SLOTB:
|
|
||||||
switch (event.GetSelection())
|
|
||||||
{
|
|
||||||
case 1: // memcard
|
|
||||||
SConfig::GetInstance().m_EXIDevice[1] = EXIDEVICE_MEMORYCARD_B;
|
|
||||||
break;
|
|
||||||
case 2: // mic
|
|
||||||
SConfig::GetInstance().m_EXIDevice[1] = EXIDEVICE_MIC;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
SConfig::GetInstance().m_EXIDevice[1] = EXIDEVICE_DUMMY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
GCMemcardPath[1]->Enable(event.GetSelection() == 1);
|
|
||||||
break;
|
|
||||||
case ID_GC_EXIDEVICE_SLOTB_PATH:
|
case ID_GC_EXIDEVICE_SLOTB_PATH:
|
||||||
ChooseMemcardPath(SConfig::GetInstance().m_strMemoryCardB, false);
|
ChooseMemcardPath(SConfig::GetInstance().m_strMemoryCardB, false);
|
||||||
break;
|
break;
|
||||||
case ID_GC_EXIDEVICE_SP1: // The only thing we emulate on SP1 is the BBA
|
|
||||||
SConfig::GetInstance().m_EXIDevice[2] = event.GetSelection() ? EXIDEVICE_ETH : EXIDEVICE_DUMMY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_GC_SIDEVICE3:
|
case ID_GC_SIDEVICE3:
|
||||||
sidevice++;
|
sidevice++;
|
||||||
@ -688,11 +663,13 @@ void CConfigMain::GCSettingsChanged(wxCommandEvent& event)
|
|||||||
|
|
||||||
void CConfigMain::ChooseMemcardPath(std::string& strMemcard, bool isSlotA)
|
void CConfigMain::ChooseMemcardPath(std::string& strMemcard, bool isSlotA)
|
||||||
{
|
{
|
||||||
std::string filename = std::string(wxFileSelector
|
std::string filename = std::string(wxFileSelector(
|
||||||
(wxT("Choose a file to open"),
|
wxT("Choose a file to open"),
|
||||||
wxT(FULL_GC_USER_DIR), isSlotA ? wxT(GC_MEMCARDA):wxT(GC_MEMCARDB),
|
wxT(FULL_GC_USER_DIR),
|
||||||
|
isSlotA ? wxT(GC_MEMCARDA) : wxT(GC_MEMCARDB),
|
||||||
wxEmptyString,
|
wxEmptyString,
|
||||||
wxT("Gamecube Memory Cards (*.raw,*.gcp)|*.raw;*.gcp")).mb_str());
|
wxT("Gamecube Memory Cards (*.raw,*.gcp)|*.raw;*.gcp")).mb_str());
|
||||||
|
|
||||||
if (!filename.empty())
|
if (!filename.empty())
|
||||||
strMemcard = filename;
|
strMemcard = filename;
|
||||||
}
|
}
|
||||||
@ -709,6 +686,37 @@ void CConfigMain::ChooseSIDevice(std::string deviceName, int deviceNum)
|
|||||||
|
|
||||||
SConfig::GetInstance().m_SIDevice[deviceNum] = tempType;
|
SConfig::GetInstance().m_SIDevice[deviceNum] = tempType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CConfigMain::ChooseEXIDevice(std::string deviceName, int deviceNum)
|
||||||
|
{
|
||||||
|
TEXIDevices tempType;
|
||||||
|
|
||||||
|
if (deviceName.compare("Memory Card") == 0)
|
||||||
|
tempType = deviceNum ? EXIDEVICE_MEMORYCARD_B : EXIDEVICE_MEMORYCARD_A;
|
||||||
|
else if (deviceName.compare("Mic") == 0)
|
||||||
|
tempType = EXIDEVICE_MIC;
|
||||||
|
else if (deviceName.compare("BBA") == 0)
|
||||||
|
tempType = EXIDEVICE_ETH;
|
||||||
|
else
|
||||||
|
tempType = EXIDEVICE_DUMMY;
|
||||||
|
|
||||||
|
// Gray out the memcard path button if we're not on a memcard
|
||||||
|
if (tempType == EXIDEVICE_MEMORYCARD_A || tempType == EXIDEVICE_MEMORYCARD_B)
|
||||||
|
GCMemcardPath[deviceNum]->Enable();
|
||||||
|
else if (deviceNum == 0 || deviceNum == 1)
|
||||||
|
GCMemcardPath[deviceNum]->Disable();
|
||||||
|
|
||||||
|
SConfig::GetInstance().m_EXIDevice[deviceNum] = tempType;
|
||||||
|
|
||||||
|
if (Core::GetState() != Core::CORE_UNINITIALIZED)
|
||||||
|
{
|
||||||
|
// Change plugged device! :D
|
||||||
|
ExpansionInterface::ChangeDevice(
|
||||||
|
(deviceNum == 1) ? 1 : 0, // SlotB is on channel 1, slotA and SP1 are on 0
|
||||||
|
tempType, // The device enum to change to
|
||||||
|
(deviceNum == 2) ? 2 : 0); // SP1 is device 2, slots are device 0
|
||||||
|
}
|
||||||
|
}
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@ -281,6 +281,7 @@ class CConfigMain
|
|||||||
void GCSettingsChanged(wxCommandEvent& event);
|
void GCSettingsChanged(wxCommandEvent& event);
|
||||||
void ChooseMemcardPath(std::string& strMemcard, bool isSlotA);
|
void ChooseMemcardPath(std::string& strMemcard, bool isSlotA);
|
||||||
void ChooseSIDevice(std::string deviceName, int deviceNum);
|
void ChooseSIDevice(std::string deviceName, int deviceNum);
|
||||||
|
void ChooseEXIDevice(std::string deviceName, int deviceNum);
|
||||||
void WiiSettingsChanged(wxCommandEvent& event);
|
void WiiSettingsChanged(wxCommandEvent& event);
|
||||||
void ISOPathsSelectionChanged(wxCommandEvent& event);
|
void ISOPathsSelectionChanged(wxCommandEvent& event);
|
||||||
void AddRemoveISOPaths(wxCommandEvent& event);
|
void AddRemoveISOPaths(wxCommandEvent& event);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user