nJoy and SerialInterface: Fixed the crashes with MAXPADS more than 1, the downside is that it doesn't work well one the second boot

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1980 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson 2009-01-22 11:18:46 +00:00
parent 189285f071
commit e332e18ce6
9 changed files with 281 additions and 156 deletions

View File

@ -15,13 +15,21 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
/*
All plugins from Core > Plugins are loaded and unloaded with this class when Dolpin is started
and stopped.
//////////////////////////////////////////////////////////////////////////////////////////
// File description
/* ¯¯¯¯¯¯¯¯¯¯¯¯
All plugins from Core > Plugins are loaded and unloaded with this class when Dolpin is started
and stopped.
//////////////////////////////////////*/
#include <string.h>
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯¯¯
#include <string.h> // System
#ifdef _WIN32
#include <windows.h>
#else
@ -29,10 +37,13 @@ and stopped.
#include <stdio.h>
#endif
#include "Common.h"
#include "Common.h" // Local
#include "FileUtil.h"
#include "StringUtil.h"
#include "DynamicLibrary.h"
#include "ConsoleWindow.h"
////////////////////////////////////////
DynamicLibrary::DynamicLibrary()
{
@ -41,33 +52,33 @@ DynamicLibrary::DynamicLibrary()
std::string GetLastErrorAsString()
{
#ifdef _WIN32
LPVOID lpMsgBuf = 0;
DWORD error = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0, NULL);
std::string s;
if (lpMsgBuf)
{
s = ((char *)lpMsgBuf);
LocalFree(lpMsgBuf);
} else {
s = StringFromFormat("(unknown error %08x)", error);
}
return s;
#else
static std::string errstr;
char *tmp = dlerror();
if (tmp)
errstr = tmp;
return errstr;
#endif
#ifdef _WIN32
LPVOID lpMsgBuf = 0;
DWORD error = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0, NULL);
std::string s;
if (lpMsgBuf)
{
s = ((char *)lpMsgBuf);
LocalFree(lpMsgBuf);
} else {
s = StringFromFormat("(unknown error %08x)", error);
}
return s;
#else
static std::string errstr;
char *tmp = dlerror();
if (tmp)
errstr = tmp;
return errstr;
#endif
}
/* Function: Loading means loading the dll with LoadLibrary() to get an instance to the dll.
@ -93,6 +104,7 @@ int DynamicLibrary::Load(const char* filename)
}
#ifdef _WIN32
Console::Print("LoadLibrary: %s\n", filename);
library = LoadLibrary(filename);
#else
library = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
@ -118,6 +130,7 @@ int DynamicLibrary::Unload()
}
#ifdef _WIN32
Console::Print("FreeLibrary: %i\n", library);
retval = FreeLibrary(library);
#else
retval = dlclose(library)?0:1;

View File

@ -70,25 +70,32 @@ void *CPlugin::LoadSymbol(const char *sym) {
return m_hInstLib.Get(sym);
}
// ______________________________________________________________________________________
// GetInfo: Get DLL info
bool CPlugin::GetInfo(PLUGIN_INFO& _pluginInfo) {
if (m_GetDllInfo != 0) {
m_GetDllInfo(&_pluginInfo);
return(true);
if (m_GetDllInfo != 0)
{
m_GetDllInfo(&_pluginInfo);
return(true);
}
return(false);
}
void CPlugin::Config(HWND _hwnd) {
if (m_DllConfig != 0)
m_DllConfig(_hwnd);
// ______________________________________________________________________________________
// Config: Open the Config window
void CPlugin::Config(HWND _hwnd)
{
if (m_DllConfig != 0) m_DllConfig(_hwnd);
}
void CPlugin::Debug(HWND _hwnd, bool Show) {
if (m_DllDebugger != 0)
m_DllDebugger(_hwnd, Show);
// ______________________________________________________________________________________
// Debug: Open the Debugging window
void CPlugin::Debug(HWND _hwnd, bool Show)
{
if (m_DllDebugger != 0) m_DllDebugger(_hwnd, Show);
}

View File

@ -27,7 +27,8 @@
#include "Thread.h" // Common
#include "Timer.h"
#include "Common.h"
#include "ConsoleWindow.h"
#include "Console.h"
#include "Core.h"
#include "CPUDetect.h"
@ -94,6 +95,7 @@ void Callback_KeyPress(int key, bool shift, bool control);
TPeekMessages Callback_PeekMessages = NULL;
TUpdateFPSDisplay g_pUpdateFPSDisplay = NULL;
// Function declarations
#ifdef _WIN32
DWORD WINAPI EmuThread(void *pArg);
#else
@ -150,10 +152,13 @@ bool GetRealWiimote()
//////////////////////////////////////////////////////////////////////////////////////////
// This is called from the GUI thread. See the booting call schedule in BootManager.cpp
//
// -----------------
bool Init()
{
if (g_pThread != NULL) {
//Console::Open();
if (g_pThread != NULL)
{
PanicAlert("ERROR: Emu Thread already running. Report this bug.");
return false;
}
@ -165,9 +170,10 @@ bool Init()
LogManager::Init();
Host_SetWaitCursor(true);
// start the thread again
// Start the thread again
_dbg_assert_(HLE, g_pThread == NULL);
// LoadLibrary()
if (!pManager.InitPlugins())
return false;
@ -224,7 +230,7 @@ void Stop() // - Hammertime!
//////////////////////////////////////////////////////////////////////////////////////////
// Create the CPU thread
//
// ---------------
THREAD_RETURN CpuThread(void *pArg)
{
Common::SetCurrentThreadName("CPU thread");
@ -253,12 +259,12 @@ THREAD_RETURN CpuThread(void *pArg)
if (_CoreParameter.bUseFastMem)
{
#ifdef _M_X64
// Let's run under memory watch
EMM::InstallExceptionHandler();
#else
PanicAlert("32-bit platforms do not support fastmem yet. Report this bug.");
#endif
#ifdef _M_X64
// Let's run under memory watch
EMM::InstallExceptionHandler();
#else
PanicAlert("32-bit platforms do not support fastmem yet. Report this bug.");
#endif
}
CCPU::Run();
@ -274,7 +280,7 @@ THREAD_RETURN CpuThread(void *pArg)
//////////////////////////////////////////////////////////////////////////////////////////
// Initalize plugins and create emulation thread
//
// -------------
/* Call browser: Init():g_pThread(). See the BootManager.cpp file description for a complete
call schedule. */
THREAD_RETURN EmuThread(void *pArg)
@ -288,7 +294,7 @@ THREAD_RETURN EmuThread(void *pArg)
LOG(OSREPORT, "Starting core = %s mode", _CoreParameter.bWii ? "Wii" : "Gamecube");
LOG(OSREPORT, "Dualcore = %s", _CoreParameter.bUseDualCore ? "Yes" : "No");
HW::Init();
emuThreadGoing.Set();
@ -340,7 +346,8 @@ THREAD_RETURN EmuThread(void *pArg)
PADInitialize.hWnd = g_pWindowHandle;
PADInitialize.pLog = Callback_PADLog;
PADInitialize.padNumber = i;
Plugins.GetPAD(i)->Initialize((void *)&PADInitialize);
// Check if we should init the plugin
if(Plugins.OkayToInitPlugin(i)) Plugins.GetPAD(i)->Initialize((void *)&PADInitialize);
}
// Load and Init WiimotePlugin - only if we are booting in wii mode
@ -439,13 +446,15 @@ THREAD_RETURN EmuThread(void *pArg)
// so we can restart the plugins (or load new ones) for the next game.
if (_CoreParameter.hMainWindow == g_pWindowHandle)
Host_UpdateMainFrame();
//Console::Close();
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Set or get the running state
//
// --------------
bool SetState(EState _State)
{
switch(_State)
@ -485,7 +494,7 @@ EState GetState()
//////////////////////////////////////////////////////////////////////////////////////////
// Save or recreate the emulation state
//
// ----------
void SaveState() {
State_Save(0);
}

View File

@ -256,6 +256,7 @@ void Init()
// Access the pad and check the MAXPADS limit
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPAD((i >= MAXPADS) ? (MAXPADS - 1): i);
//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)))

View File

@ -120,6 +120,7 @@ CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
SPADStatus PadStatus;
memset(&PadStatus, 0 ,sizeof(PadStatus));
Common::PluginPAD* pad =
//CPluginManager::GetInstance().GetPAD(ISIDevice::m_iDeviceNumber);
CPluginManager::GetInstance().GetPAD((ISIDevice::m_iDeviceNumber >= MAXPADS) ? (MAXPADS - 1): ISIDevice::m_iDeviceNumber);
pad->PAD_GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus);

View File

@ -15,21 +15,31 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include <string>
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯¯¯
#include <string> // System
#include <vector>
//#include "Globals.h"
#include "FileSearch.h"
#include "FileUtil.h"
//#include "Globals.h" // Local
#include "PluginManager.h"
#include "ConfigManager.h"
#include "LogManager.h"
#include "StringUtil.h"
#include "Core.h"
#include "FileSearch.h" // Common
#include "FileUtil.h"
#include "StringUtil.h"
#include "ConsoleWindow.h"
CPluginManager CPluginManager::m_Instance;
//////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// The Plugin Manager Class
// ¯¯¯¯¯¯¯¯¯¯¯¯
CPluginManager::CPluginManager() :
m_params(SConfig::GetInstance().m_LocalCoreStartupParameter)
{
@ -40,71 +50,90 @@ CPluginManager::CPluginManager() :
}
// Function: FreeLibrary()
// Called from: This will be called when Dolphin is closed, not when we Stop a game
CPluginManager::~CPluginManager()
{
if (m_PluginGlobals)
delete m_PluginGlobals;
Console::Print("Delete CPluginManager\n");
if (m_dsp)
delete m_dsp;
if (m_PluginGlobals) delete m_PluginGlobals;
if (m_video)
delete m_video;
if (m_dsp) delete m_dsp;
if (m_video) delete m_video;
for (int i=0;i<MAXPADS;i++) {
if (m_pad[i])
delete m_pad[i];
}
/**/
for (int i = 0; i < MAXPADS; i++)
{
if (m_pad[i] && OkayToInitPlugin(i))
{
Console::Print("Delete: %i\n", i);
delete m_pad[i];
}
m_pad[i] = NULL;
}
for (int i=0;i<MAXWIIMOTES;i++) {
if (m_wiimote[i])
delete m_wiimote[i];
}
for (int i = 0; i < MAXWIIMOTES; i++)
if (m_wiimote[i]) delete m_wiimote[i];
}
//////////////////////////////////////////////
bool CPluginManager::InitPlugins() {
if (! GetVideo()) {
PanicAlert("Can't init Video Plugin");
return false;
//////////////////////////////////////////////////////////////////////////////////////////
// Init and ShutDown Plugins
// ¯¯¯¯¯¯¯¯¯¯¯¯
// Point the m_pad[] and other variables to a certain plugin
bool CPluginManager::InitPlugins()
{
if (! GetVideo())
{
PanicAlert("Can't init Video Plugin");
return false;
}
if (! GetDSP()) {
PanicAlert("Can't init DSP Plugin");
return false;
if (! GetDSP())
{
PanicAlert("Can't init DSP Plugin");
return false;
}
// Check if we get at least one pad or wiimote
bool pad = false;
bool wiimote = false;
// Init pad
for (int i = 0; i < MAXPADS; i++)
{
if (! m_params.m_strPadPlugin[i].empty())
GetPAD(i);
if (m_pad[i] != NULL)
pad = true;
if (! m_params.m_strPadPlugin[i].empty())
GetPAD(i);
if (m_pad[i] != NULL)
pad = true;
}
if (! pad) {
PanicAlert("Can't init any PAD Plugins");
return false;
}
if (m_params.bWii) {
for (int i = 0; i < MAXWIIMOTES; i++)
if (! pad)
{
if (! m_params.m_strWiimotePlugin[i].empty())
GetWiimote(i);
PanicAlert("Can't init any PAD Plugins");
return false;
}
if (m_wiimote[i] != NULL)
wiimote = true;
}
// Init wiimote
if (m_params.bWii)
{
for (int i = 0; i < MAXWIIMOTES; i++)
{
if (! m_params.m_strWiimotePlugin[i].empty())
GetWiimote(i);
if (! wiimote) {
PanicAlert("Can't init any Wiimote Plugins");
return false;
}
if (m_wiimote[i] != NULL)
wiimote = true;
}
if (! wiimote)
{
PanicAlert("Can't init any Wiimote Plugins");
return false;
}
}
return true;
@ -112,23 +141,95 @@ bool CPluginManager::InitPlugins() {
void CPluginManager::ShutdownPlugins()
{
for (int i = 0; i < MAXPADS; i++)
if (m_pad[i]) m_pad[i]->Shutdown();
// Check if we can shutdown the plugin
for (int i = 0; i < MAXPADS; i++)
{
if (m_pad[i] && OkayToInitPlugin(i))
{
//Console::Print("Shutdown: %i\n", i);
m_pad[i]->Shutdown();
}
//delete m_pad[i];
//m_pad[i] = NULL;
}
for (int i = 0; i < MAXWIIMOTES; i++)
if (m_wiimote[i]) m_wiimote[i]->Shutdown();
for (int i = 0; i < MAXWIIMOTES; i++)
if (m_wiimote[i]) m_wiimote[i]->Shutdown();
if (m_video)
m_video->Shutdown();
if (m_video)
m_video->Shutdown();
if (m_dsp)
m_dsp->Shutdown();
if (m_dsp)
m_dsp->Shutdown();
}
//////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Supporting functions
// ¯¯¯¯¯¯¯¯¯¯¯¯
void *CPluginManager::LoadPlugin(const char *_rFilename)//, PLUGIN_TYPE type)
{
CPluginInfo info(_rFilename);
PLUGIN_TYPE type = info.GetPluginInfo().Type;
Common::CPlugin *plugin = NULL;
switch (type)
{
case PLUGIN_TYPE_VIDEO:
plugin = new Common::PluginVideo(_rFilename);
break;
case PLUGIN_TYPE_PAD:
plugin = new Common::PluginPAD(_rFilename);
break;
case PLUGIN_TYPE_DSP:
plugin = new Common::PluginDSP(_rFilename);
break;
case PLUGIN_TYPE_WIIMOTE:
plugin = new Common::PluginWiimote(_rFilename);
break;
default:
PanicAlert("Trying to load unsupported type %d", type);
}
if (!plugin->IsValid())
{
PanicAlert("Can't open %s", _rFilename);
return NULL;
}
plugin->SetGlobals(m_PluginGlobals);
return plugin;
}
PLUGIN_GLOBALS* CPluginManager::GetGlobals() {
// ----------------------------------------
/* Check if the plugin has already been initialized. If so, return the Id of the duplicate pad
so we can point the new m_pad[] to that */
// -------------
int CPluginManager::OkayToInitPlugin(int Plugin)
{
//Console::Print("OkayToInitShutdown: %i", Plugin);
// Compare it to the earlier plugins
for(int i = 0; i < Plugin; i++)
if (m_params.m_strPadPlugin[Plugin] == m_params.m_strPadPlugin[i])
{
//Console::Print("(%i %i) %s\n", Plugin, i, g_CoreStartupParameter.m_strPadPlugin[Plugin].c_str());
return i;
}
return -1;
}
PLUGIN_GLOBALS* CPluginManager::GetGlobals()
{
return m_PluginGlobals;
}
// ----------------------------------------
// Create list of available plugins
// -------------
@ -166,12 +267,29 @@ void CPluginManager::ScanForPlugins()
}
}
}
/////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Create or return the already created plugin pointers
// ¯¯¯¯¯¯¯¯¯¯¯¯
Common::PluginPAD *CPluginManager::GetPAD(int controller)
{
if (m_pad[controller] == NULL)
m_pad[controller] = (Common::PluginPAD*)LoadPlugin(m_params.m_strPadPlugin[controller].c_str());
{
if(OkayToInitPlugin(controller) == -1)
{
m_pad[controller] = (Common::PluginPAD*)LoadPlugin(m_params.m_strPadPlugin[controller].c_str());
Console::Print("LoadPlugin: %i\n", controller);
}
else
{
Console::Print("Pointed: %i to %i\n", controller, OkayToInitPlugin(controller));
m_pad[controller] = m_pad[OkayToInitPlugin(controller)];
}
}
//Console::Print("Returned: %i\n", controller);
return m_pad[controller];
}
@ -199,45 +317,15 @@ Common::PluginVideo *CPluginManager::GetVideo() {
return m_video;
}
void *CPluginManager::LoadPlugin(const char *_rFilename)//, PLUGIN_TYPE type)
{
CPluginInfo info(_rFilename);
PLUGIN_TYPE type = info.GetPluginInfo().Type;
Common::CPlugin *plugin = NULL;
switch (type) {
case PLUGIN_TYPE_VIDEO:
plugin = new Common::PluginVideo(_rFilename);
break;
case PLUGIN_TYPE_PAD:
plugin = new Common::PluginPAD(_rFilename);
break;
case PLUGIN_TYPE_DSP:
plugin = new Common::PluginDSP(_rFilename);
break;
case PLUGIN_TYPE_WIIMOTE:
plugin = new Common::PluginWiimote(_rFilename);
break;
default:
PanicAlert("Trying to load unsupported type %d", type);
}
if (!plugin->IsValid()) {
PanicAlert("Can't open %s", _rFilename);
return NULL;
}
plugin->SetGlobals(m_PluginGlobals);
///////////////////////////////////////////
return plugin;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Call DLL functions
// ¯¯¯¯¯¯¯¯¯¯¯¯
// ----------------------------------------
// Open config window. _rFilename = plugin filename ,ret = the dll slot number
// Open config window. _rFilename = plugin filename , ret = the dll slot number
// -------------
void CPluginManager::OpenConfig(void* _Parent, const char *_rFilename)
{
@ -254,9 +342,9 @@ void CPluginManager::OpenConfig(void* _Parent, const char *_rFilename)
void CPluginManager::OpenDebug(void* _Parent, const char *_rFilename, PLUGIN_TYPE Type, bool Show)
{
if (Type == PLUGIN_TYPE_VIDEO) {
GetVideo()->Debug((HWND)_Parent, Show);
GetVideo()->Debug((HWND)_Parent, Show);
} else if (Type == PLUGIN_TYPE_DSP) {
GetDSP()->Debug((HWND)_Parent, Show);
GetDSP()->Debug((HWND)_Parent, Show);
}
}
@ -278,5 +366,5 @@ CPluginInfo::CPluginInfo(const char *_rFileName)
delete plugin;
}
}
///////////////////////////////////////////

View File

@ -53,6 +53,7 @@ public:
bool InitPlugins();
void ShutdownPlugins();
int OkayToInitPlugin(int Plugin);
void ScanForPlugins();
void OpenConfig(void* _Parent, const char *_rFilename);
void OpenDebug(void* _Parent, const char *_rFilename, PLUGIN_TYPE Type, bool Show);

View File

@ -241,6 +241,8 @@ void Initialize(void *init)
// Debugging
//Console::Open();
//Console::Print("Initialize: %i\n", SDL_WasInit(0));
SPADInitialize _PADInitialize = *(SPADInitialize*)init;
emulator_running = true;
#ifdef _DEBUG
@ -348,6 +350,8 @@ int Search_Devices()
Called from: The Dolphin Core, ConfigBox::OnClose() */
void Shutdown()
{
//Console::Print("Shutdown: %i\n", SDL_WasInit(0));
if (PadMapping[0].enabled && SDL_JoystickOpened(PadMapping[0].ID))
SDL_JoystickClose(joystate[0].joy);
if (PadMapping[1].enabled && SDL_JoystickOpened(PadMapping[1].ID))
@ -364,6 +368,7 @@ void Shutdown()
#endif
delete [] joyinfo;
joyinfo = NULL;
emulator_running = false;

View File

@ -50,7 +50,7 @@
#include "Common.h" // Common
#include "pluginspecs_pad.h"
#include "IniFile.h"
//#include "ConsoleWindow.h"
#include "ConsoleWindow.h"
//#include "Timer.h"
#include "Config.h" // Local