SerialInterface and pads: Allow MAXPADS lower than 4

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1923 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson 2009-01-19 03:45:28 +00:00
parent 5708e14a0e
commit d60fea1d99
8 changed files with 136 additions and 98 deletions

View File

@ -27,7 +27,7 @@ and stopped.
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Includes // Includes
// // -----------
#include <string.h> #include <string.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
@ -79,11 +79,14 @@ std::string GetLastErrorAsString()
#endif #endif
} }
// Loading means loading the dll with LoadLibrary() to get an instance to the dll. //////////////////////////////////////////////////////////////////////////////////////////
// This is done when Dolphin is started to determine which dlls are good, and // Includes
// before opening the Config and Debugging windows from Plugin.cpp and // -----------
// before opening the dll for running the emulation in Video_...cpp in Core. /* Function: Loading means loading the dll with LoadLibrary() to get an instance to the dll.
// Since this is fairly slow, TODO: think about implementing some sort of cache. This is done when Dolphin is started to determine which dlls are good, and before opening
the Config and Debugging windows from Plugin.cpp and before opening the dll for running
the emulation in Video_...cpp in Core. Since this is fairly slow, TODO: think about
implementing some sort of cache. */
int DynamicLibrary::Load(const char* filename) int DynamicLibrary::Load(const char* filename)
{ {
if (!filename || strlen(filename) == 0) if (!filename || strlen(filename) == 0)
@ -147,11 +150,12 @@ void* DynamicLibrary::Get(const char* funcname) const
PanicAlert("Can't find function %s - Library not loaded."); PanicAlert("Can't find function %s - Library not loaded.");
return NULL; return NULL;
} }
#ifdef _WIN32
retval = GetProcAddress(library, funcname); #ifdef _WIN32
#else retval = GetProcAddress(library, funcname);
retval = dlsym(library, funcname); #else
#endif retval = dlsym(library, funcname);
#endif
if (!retval) if (!retval)
{ {

View File

@ -30,11 +30,13 @@
namespace Common namespace Common
{ {
CPlugin::~CPlugin() { CPlugin::~CPlugin()
{
m_hInstLib.Unload(); m_hInstLib.Unload();
} }
CPlugin::CPlugin(const char* _szName) : valid(false) { CPlugin::CPlugin(const char* _szName) : valid(false)
{
if (m_hInstLib.Load(_szName)) { if (m_hInstLib.Load(_szName)) {
m_GetDllInfo = reinterpret_cast<TGetDllInfo> m_GetDllInfo = reinterpret_cast<TGetDllInfo>
@ -101,14 +103,17 @@ void CPlugin::DoState(unsigned char **ptr, int mode) {
m_DoState(ptr, mode); m_DoState(ptr, mode);
} }
void CPlugin::Initialize(void *init) { // Run Initialize() in the plugin
if (m_Initialize != 0) void CPlugin::Initialize(void *init)
m_Initialize(init); {
/* We first check that we have found the Initialize() function, but there is no
restriction on running this several times */
if (m_Initialize != 0) m_Initialize(init);
} }
void CPlugin::Shutdown() { void CPlugin::Shutdown()
if (m_Shutdown != 0) {
m_Shutdown(); if (m_Shutdown != 0) m_Shutdown();
} }
} // end of namespace Common } // end of namespace Common

View File

@ -192,13 +192,15 @@ void SConfig::LoadSettings()
// Plugins // Plugins
ini.Get("Core", "GFXPlugin", &m_LocalCoreStartupParameter.m_strVideoPlugin, m_DefaultGFXPlugin.c_str()); ini.Get("Core", "GFXPlugin", &m_LocalCoreStartupParameter.m_strVideoPlugin, m_DefaultGFXPlugin.c_str());
ini.Get("Core", "DSPPlugin", &m_LocalCoreStartupParameter.m_strDSPPlugin, m_DefaultDSPPlugin.c_str()); ini.Get("Core", "DSPPlugin", &m_LocalCoreStartupParameter.m_strDSPPlugin, m_DefaultDSPPlugin.c_str());
ini.Get("Core", "Pad1Plugin", &m_LocalCoreStartupParameter.m_strPadPlugin[0], m_DefaultPADPlugin.c_str()); for (int i = 0; i < MAXPADS; i++)
ini.Get("Core", "Pad2Plugin", &m_LocalCoreStartupParameter.m_strPadPlugin[1], m_DefaultPADPlugin.c_str()); {
ini.Get("Core", "Pad3Plugin", &m_LocalCoreStartupParameter.m_strPadPlugin[2], m_DefaultPADPlugin.c_str()); std::string TmpName = StringFromFormat("Pad%iPlugin", (i + 1));
ini.Get("Core", "Pad4Plugin", &m_LocalCoreStartupParameter.m_strPadPlugin[3], m_DefaultPADPlugin.c_str()); ini.Get("Core", TmpName.c_str(), &m_LocalCoreStartupParameter.m_strPadPlugin[i], m_DefaultPADPlugin.c_str());
ini.Get("Core", "WiiMote1Plugin", &m_LocalCoreStartupParameter.m_strWiimotePlugin[0], m_DefaultWiiMotePlugin.c_str()); }
ini.Get("Core", "WiiMote2Plugin", &m_LocalCoreStartupParameter.m_strWiimotePlugin[1], m_DefaultWiiMotePlugin.c_str()); for (int i = 0; i < MAXWIIMOTES; i++)
ini.Get("Core", "WiiMote3Plugin", &m_LocalCoreStartupParameter.m_strWiimotePlugin[2], m_DefaultWiiMotePlugin.c_str()); {
ini.Get("Core", "WiiMote4Plugin", &m_LocalCoreStartupParameter.m_strWiimotePlugin[3], m_DefaultWiiMotePlugin.c_str()); std::string TmpName = StringFromFormat("WiiMote%iPlugin", (i + 1));
ini.Get("Core", "WiiMote1Plugin", &m_LocalCoreStartupParameter.m_strWiimotePlugin[i], m_DefaultWiiMotePlugin.c_str());
}
} }
} }

View File

@ -20,12 +20,11 @@
// Include // Include
// //
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#else #else
#endif #endif
#include "Thread.h" #include "Thread.h" // Common
#include "Timer.h" #include "Timer.h"
#include "Common.h" #include "Common.h"
@ -283,7 +282,7 @@ THREAD_RETURN EmuThread(void *pArg)
Common::SetCurrentThreadName("Emuthread - starting"); Common::SetCurrentThreadName("Emuthread - starting");
const SCoreStartupParameter _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter; const SCoreStartupParameter _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter;
CPluginManager &pm = CPluginManager::GetInstance(); CPluginManager &Plugins = CPluginManager::GetInstance();
if (_CoreParameter.bLockThreads) if (_CoreParameter.bLockThreads)
Common::Thread::SetCurrentThreadAffinity(2); // Force to second core Common::Thread::SetCurrentThreadAffinity(2); // Force to second core
@ -313,13 +312,15 @@ THREAD_RETURN EmuThread(void *pArg)
VideoInitialize.pMemoryBase = Memory::base; VideoInitialize.pMemoryBase = Memory::base;
VideoInitialize.pKeyPress = Callback_KeyPress; VideoInitialize.pKeyPress = Callback_KeyPress;
VideoInitialize.bWii = _CoreParameter.bWii; VideoInitialize.bWii = _CoreParameter.bWii;
pm.GetVideo()->Initialize(&VideoInitialize); // Call the dll Plugins.GetVideo()->Initialize(&VideoInitialize); // Call the dll
// Under linux, this is an X11 Display, not an HWND! // Under linux, this is an X11 Display, not an HWND!
g_pWindowHandle = (HWND)VideoInitialize.pWindowHandle; g_pWindowHandle = (HWND)VideoInitialize.pWindowHandle;
Callback_PeekMessages = VideoInitialize.pPeekMessages; Callback_PeekMessages = VideoInitialize.pPeekMessages;
g_pUpdateFPSDisplay = VideoInitialize.pUpdateFPSDisplay; g_pUpdateFPSDisplay = VideoInitialize.pUpdateFPSDisplay;
// Load and init DSPPlugin // Load and init DSPPlugin
DSPInitialize dspInit; DSPInitialize dspInit;
dspInit.hWnd = g_pWindowHandle; dspInit.hWnd = g_pWindowHandle;
@ -331,28 +332,27 @@ THREAD_RETURN EmuThread(void *pArg)
dspInit.pDebuggerBreak = Callback_DebuggerBreak; dspInit.pDebuggerBreak = Callback_DebuggerBreak;
dspInit.pGenerateDSPInterrupt = Callback_DSPInterrupt; dspInit.pGenerateDSPInterrupt = Callback_DSPInterrupt;
dspInit.pGetAudioStreaming = AudioInterface::Callback_GetStreaming; dspInit.pGetAudioStreaming = AudioInterface::Callback_GetStreaming;
pm.GetDSP()->Initialize((void *)&dspInit); Plugins.GetDSP()->Initialize((void *)&dspInit);
for (int i=0;i<MAXPADS;i++) { // Load and Init PadPlugin
for (int i = 0; i < MAXPADS; i++)
// Load and Init PadPlugin {
SPADInitialize PADInitialize; SPADInitialize PADInitialize;
PADInitialize.hWnd = g_pWindowHandle; PADInitialize.hWnd = g_pWindowHandle;
PADInitialize.pLog = Callback_PADLog; PADInitialize.pLog = Callback_PADLog;
PADInitialize.padNumber = i; PADInitialize.padNumber = i;
pm.GetPAD(i)->Initialize((void *)&PADInitialize); Plugins.GetPAD(i)->Initialize((void *)&PADInitialize);
} }
// Load and Init WiimotePlugin - only if we are booting in wii mode // Load and Init WiimotePlugin - only if we are booting in wii mode
if (_CoreParameter.bWii) { if (_CoreParameter.bWii)
{
SWiimoteInitialize WiimoteInitialize; SWiimoteInitialize WiimoteInitialize;
WiimoteInitialize.hWnd = g_pWindowHandle; WiimoteInitialize.hWnd = g_pWindowHandle;
WiimoteInitialize.pLog = Callback_WiimoteLog; WiimoteInitialize.pLog = Callback_WiimoteLog;
WiimoteInitialize.pWiimoteInput = Callback_WiimoteInput; WiimoteInitialize.pWiimoteInput = Callback_WiimoteInput;
// Wait for Wiiuse to find the number of connected Wiimotes // Wait for Wiiuse to find the number of connected Wiimotes
pm.GetWiimote(0)->Initialize((void *)&WiimoteInitialize); Plugins.GetWiimote(0)->Initialize((void *)&WiimoteInitialize);
} }
// The hardware is initialized. // The hardware is initialized.
@ -410,9 +410,9 @@ THREAD_RETURN EmuThread(void *pArg)
else else
{ {
cpuThread = new Common::Thread(CpuThread, pArg); cpuThread = new Common::Thread(CpuThread, pArg);
pm.GetVideo()->Video_Prepare(); //wglMakeCurrent Plugins.GetVideo()->Video_Prepare(); //wglMakeCurrent
Common::SetCurrentThreadName("Video thread"); Common::SetCurrentThreadName("Video thread");
pm.GetVideo()->Video_EnterLoop(); Plugins.GetVideo()->Video_EnterLoop();
} }
// Wait for CPU thread to exit - it should have been signaled to do so by now // Wait for CPU thread to exit - it should have been signaled to do so by now
@ -429,7 +429,7 @@ THREAD_RETURN EmuThread(void *pArg)
} }
g_bHwInit = false; g_bHwInit = false;
pm.ShutdownPlugins(); Plugins.ShutdownPlugins();
HW::Shutdown(); HW::Shutdown();

View File

@ -24,8 +24,8 @@
#include <string> #include <string>
#define MAXPADS 4 #define MAXPADS 1
#define MAXWIIMOTES 4 #define MAXWIIMOTES 1
struct SCoreStartupParameter struct SCoreStartupParameter
{ {

View File

@ -15,6 +15,10 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯
#include "Common.h" #include "Common.h"
#include "ChunkFile.h" #include "ChunkFile.h"
@ -25,16 +29,27 @@
#include "SI.h" #include "SI.h"
#include "SI_Device.h" #include "SI_Device.h"
#include "SI_DeviceGCController.h" #include "SI_DeviceGCController.h"
//////////////////////////////
namespace SerialInterface namespace SerialInterface
{ {
//////////////////////////////////////////////////////////////////////////////////////////
// Declarations
// ¯¯¯¯¯¯¯¯¯¯
void RunSIBuffer();
void UpdateInterrupts();
/////////////////////////////////////
// SI Interrupt Types // SI Interrupt Types
enum SIInterruptType enum SIInterruptType
{ {
INT_RDSTINT = 0, INT_RDSTINT = 0,
INT_TCINT = 1, INT_TCINT = 1,
}; };
static void GenerateSIInterrupt(SIInterruptType _SIInterrupt);
// SI number of channels // SI number of channels
enum enum
@ -223,37 +238,46 @@ void DoState(PointerWrap &p)
p.Do(g_StatusReg); p.Do(g_StatusReg);
p.Do(g_EXIClockCount); p.Do(g_EXIClockCount);
p.Do(g_SIBuffer); p.Do(g_SIBuffer);
} }
static void GenerateSIInterrupt(SIInterruptType _SIInterrupt);
void RunSIBuffer();
void UpdateInterrupts();
//////////////////////////////////////////////////////////////////////////////////////////
// Initialize the Serial Interface
// ¯¯¯¯¯¯¯¯¯¯
void Init() void Init()
{ {
for (int i = 0; i < NUMBER_OF_CHANNELS; i++) { for (int i = 0; i < NUMBER_OF_CHANNELS; i++)
{
g_Channel[i].m_Out.Hex = 0; g_Channel[i].m_Out.Hex = 0;
g_Channel[i].m_InHi.Hex = 0; g_Channel[i].m_InHi.Hex = 0;
g_Channel[i].m_InLo.Hex = 0; g_Channel[i].m_InLo.Hex = 0;
}
// First attach a dummy device to all channels
// TODO: allow dynamic attaching/detaching of plugins g_Channel[i].m_pDevice = new CSIDevice_Dummy(i);
// maybe this code should be in the pad plugin loader at all? }
for (int i = 0; i < MAXPADS; i++) {
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPAD(i); // TODO: allow dynamic attaching/detaching of plugins
if (pad != NULL && (pad->PAD_GetAttachedPads() & (1 << i))) // maybe this code should be in the pad plugin loader at all?
g_Channel[i].m_pDevice = new CSIDevice_GCController(i); for (int i = 0; i < MAXPADS; i++)
else {
g_Channel[i].m_pDevice = new CSIDevice_Dummy(i); // Get pad status
} Common::PluginPAD* pad = CPluginManager::GetInstance().GetPAD(i);
// Check if this pad is attached for the current plugin
if (pad != NULL && (pad->PAD_GetAttachedPads() & (1 << i)))
g_Channel[i].m_pDevice = new CSIDevice_GCController(i);
//else
// g_Channel[i].m_pDevice = new CSIDevice_Dummy(i);
}
g_Poll.Hex = 0; g_Poll.Hex = 0;
g_ComCSR.Hex = 0; g_ComCSR.Hex = 0;
g_StatusReg.Hex = 0; g_StatusReg.Hex = 0;
g_EXIClockCount.Hex = 0; g_EXIClockCount.Hex = 0;
memset(g_SIBuffer, 0xce, 128); memset(g_SIBuffer, 0xce, 128);
} }
//////////////////////////////////////
void Shutdown() void Shutdown()
{ {
@ -514,36 +538,37 @@ void GenerateSIInterrupt(SIInterruptType _SIInterrupt)
void UpdateDevices() void UpdateDevices()
{ {
// update channels // Update channels
g_StatusReg.RDST0 = g_Channel[0].m_pDevice->GetData(g_Channel[0].m_InHi.Hex, g_Channel[0].m_InLo.Hex) ? 1 : 0; g_StatusReg.RDST0 = g_Channel[0].m_pDevice->GetData(g_Channel[0].m_InHi.Hex, g_Channel[0].m_InLo.Hex) ? 1 : 0;
g_StatusReg.RDST1 = g_Channel[1].m_pDevice->GetData(g_Channel[1].m_InHi.Hex, g_Channel[1].m_InLo.Hex) ? 1 : 0; g_StatusReg.RDST1 = g_Channel[1].m_pDevice->GetData(g_Channel[1].m_InHi.Hex, g_Channel[1].m_InLo.Hex) ? 1 : 0;
g_StatusReg.RDST2 = g_Channel[2].m_pDevice->GetData(g_Channel[2].m_InHi.Hex, g_Channel[2].m_InLo.Hex) ? 1 : 0; g_StatusReg.RDST2 = g_Channel[2].m_pDevice->GetData(g_Channel[2].m_InHi.Hex, g_Channel[2].m_InLo.Hex) ? 1 : 0;
g_StatusReg.RDST3 = g_Channel[3].m_pDevice->GetData(g_Channel[3].m_InHi.Hex, g_Channel[3].m_InLo.Hex) ? 1 : 0; g_StatusReg.RDST3 = g_Channel[3].m_pDevice->GetData(g_Channel[3].m_InHi.Hex, g_Channel[3].m_InLo.Hex) ? 1 : 0;
// update interrupts // Update interrupts
UpdateInterrupts(); UpdateInterrupts();
} }
void RunSIBuffer() void RunSIBuffer()
{ {
// math inLength // Math inLength
int inLength = g_ComCSR.INLNGTH; int inLength = g_ComCSR.INLNGTH;
if (inLength == 0) if (inLength == 0)
inLength = 128; inLength = 128;
else else
inLength++; inLength++;
// math outLength // Math outLength
int outLength = g_ComCSR.OUTLNGTH; int outLength = g_ComCSR.OUTLNGTH;
if (outLength == 0) if (outLength == 0)
outLength = 128; outLength = 128;
else else
outLength++; outLength++;
#ifdef LOGGING #ifdef LOGGING
int numOutput = int numOutput =
#endif #endif
g_Channel[g_ComCSR.CHANNEL].m_pDevice->RunBuffer(g_SIBuffer, inLength); g_Channel[g_ComCSR.CHANNEL].m_pDevice->RunBuffer(g_SIBuffer, inLength);
LOGV(SERIALINTERFACE, 2, "RunSIBuffer (intLen: %i outLen: %i) (processed: %i)", inLength, outLength, numOutput); LOGV(SERIALINTERFACE, 2, "RunSIBuffer (intLen: %i outLen: %i) (processed: %i)", inLength, outLength, numOutput);
// Transfer completed // Transfer completed

View File

@ -78,7 +78,8 @@ bool CPluginManager::InitPlugins() {
bool pad = false; bool pad = false;
bool wiimote = false; bool wiimote = false;
for (int i=0;i<MAXPADS;i++) { for (int i = 0; i < MAXPADS; i++)
{
if (! m_params.m_strPadPlugin[i].empty()) if (! m_params.m_strPadPlugin[i].empty())
GetPAD(i); GetPAD(i);
@ -91,7 +92,8 @@ bool CPluginManager::InitPlugins() {
return false; return false;
} }
if (m_params.bWii) { if (m_params.bWii) {
for (int i=0;i<MAXWIIMOTES;i++) { for (int i = 0; i < MAXWIIMOTES; i++)
{
if (! m_params.m_strWiimotePlugin[i].empty()) if (! m_params.m_strWiimotePlugin[i].empty())
GetWiimote(i); GetWiimote(i);
@ -108,15 +110,13 @@ bool CPluginManager::InitPlugins() {
return true; return true;
} }
void CPluginManager::ShutdownPlugins() { void CPluginManager::ShutdownPlugins()
for (int i=0;i<MAXPADS;i++) { {
if (m_pad[i]) for (int i = 0; i < MAXPADS; i++)
m_pad[i]->Shutdown(); if (m_pad[i]) m_pad[i]->Shutdown();
}
for (int i=0;i<MAXWIIMOTES;i++) { for (int i = 0; i < MAXWIIMOTES; i++)
if (m_wiimote[i]) if (m_wiimote[i]) m_wiimote[i]->Shutdown();
m_wiimote[i]->Shutdown();
}
if (m_video) if (m_video)
m_video->Shutdown(); m_video->Shutdown();
@ -167,23 +167,25 @@ void CPluginManager::ScanForPlugins()
} }
} }
Common::PluginPAD *CPluginManager::GetPAD(int controller) { Common::PluginPAD *CPluginManager::GetPAD(int controller)
{
if (m_pad[controller] == NULL) if (m_pad[controller] == NULL)
m_pad[controller] = (Common::PluginPAD*)LoadPlugin m_pad[controller] = (Common::PluginPAD*)LoadPlugin(m_params.m_strPadPlugin[controller].c_str());
(m_params.m_strPadPlugin[controller].c_str());
return m_pad[controller]; return m_pad[controller];
} }
Common::PluginWiimote *CPluginManager::GetWiimote(int controller) { Common::PluginWiimote *CPluginManager::GetWiimote(int controller)
{
if (m_wiimote[controller] == NULL) if (m_wiimote[controller] == NULL)
m_wiimote[controller] = (Common::PluginWiimote*)LoadPlugin m_wiimote[controller] = (Common::PluginWiimote*)LoadPlugin
(m_params.m_strWiimotePlugin[controller].c_str()); (m_params.m_strWiimotePlugin[controller].c_str());
return m_wiimote[controller]; return m_wiimote[controller];
} }
Common::PluginDSP *CPluginManager::GetDSP() { Common::PluginDSP *CPluginManager::GetDSP()
{
if (m_dsp == NULL) if (m_dsp == NULL)
m_dsp = (Common::PluginDSP*)LoadPlugin(m_params.m_strDSPPlugin.c_str()); m_dsp = (Common::PluginDSP*)LoadPlugin(m_params.m_strDSPPlugin.c_str());

View File

@ -245,7 +245,7 @@ bool DolphinApp::OnInit()
if(UseDebugger) if(UseDebugger)
{ {
main_frame = new CFrame((wxFrame*) NULL, wxID_ANY, wxString::FromAscii(title), main_frame = new CFrame((wxFrame*) NULL, wxID_ANY, wxString::FromAscii(title),
wxPoint(x, y), wxSize(h, w)); wxPoint(x, y), wxSize(w, h));
} }
else else
{ {