Video and DSP plugin management: Fixed Stop and Start again, it was necessary to call FreeLibrary() on Start instead of on Stop, I don't know why but that's how it works

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2139 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson 2009-02-08 10:09:26 +00:00
parent 54798713a0
commit f610f7e197
8 changed files with 280 additions and 177 deletions

View File

@ -16,9 +16,15 @@
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
//////////////////////////////////////////////////////////////////////////////////////////
// Include
/* ¯¯¯¯¯¯¯¯¯¯¯¯
File description: This is the common Plugin class that links to the functions that are
common to all plugins. This class is inherited by all plugin classes. But it's only created
directly in PluginManager.cpp when we check if a plugin is valid or not.
///////////////////////////////////////////////*/
/* This file is a simpler version of Plugin_...cpp found in Core. This file
only loads the config and debugging windows and works with all plugins. */
#include "Plugin.h" #include "Plugin.h"
@ -41,50 +47,52 @@ CPlugin::CPlugin(const char* _szName) : valid(false)
m_Shutdown = NULL; m_Shutdown = NULL;
m_DoState = NULL; m_DoState = NULL;
if (m_hInstLib.Load(_szName)) { if (m_hInstLib.Load(_szName))
{
m_GetDllInfo = reinterpret_cast<TGetDllInfo> m_GetDllInfo = reinterpret_cast<TGetDllInfo>
(m_hInstLib.Get("GetDllInfo")); (m_hInstLib.Get("GetDllInfo"));
m_DllConfig = reinterpret_cast<TDllConfig> m_DllConfig = reinterpret_cast<TDllConfig>
(m_hInstLib.Get("DllConfig")); (m_hInstLib.Get("DllConfig"));
m_DllDebugger = reinterpret_cast<TDllDebugger> m_DllDebugger = reinterpret_cast<TDllDebugger>
(m_hInstLib.Get("DllDebugger")); (m_hInstLib.Get("DllDebugger"));
m_SetDllGlobals = reinterpret_cast<TSetDllGlobals> m_SetDllGlobals = reinterpret_cast<TSetDllGlobals>
(m_hInstLib.Get("SetDllGlobals")); (m_hInstLib.Get("SetDllGlobals"));
m_Initialize = reinterpret_cast<TInitialize> m_Initialize = reinterpret_cast<TInitialize>
(m_hInstLib.Get("Initialize")); (m_hInstLib.Get("Initialize"));
m_Shutdown = reinterpret_cast<TShutdown> m_Shutdown = reinterpret_cast<TShutdown>
(m_hInstLib.Get("Shutdown")); (m_hInstLib.Get("Shutdown"));
m_DoState = reinterpret_cast<TDoState> m_DoState = reinterpret_cast<TDoState>
(m_hInstLib.Get("DoState")); (m_hInstLib.Get("DoState"));
} }
// Check if the plugin has all the functions it shold have
if (m_GetDllInfo != 0 && if (m_GetDllInfo != 0 &&
m_DllConfig != 0 && m_DllConfig != 0 &&
m_DllDebugger != 0 && m_DllDebugger != 0 &&
m_SetDllGlobals != 0 && m_SetDllGlobals != 0 &&
m_Initialize != 0 && m_Initialize != 0 &&
m_Shutdown != 0 && m_Shutdown != 0 &&
m_DoState != 0) m_DoState != 0)
valid = true; valid = true;
// Save the filename for this plugin // Save the filename for this plugin
Filename = _szName; Filename = _szName;
} }
void *CPlugin::LoadSymbol(const char *sym) { void *CPlugin::LoadSymbol(const char *sym)
{
return m_hInstLib.Get(sym); return m_hInstLib.Get(sym);
} }
// GetInfo: Get DLL info // GetInfo: Get DLL info
bool CPlugin::GetInfo(PLUGIN_INFO& _pluginInfo) { bool CPlugin::GetInfo(PLUGIN_INFO& _pluginInfo)
{
if (m_GetDllInfo != NULL) { if (m_GetDllInfo != NULL) {
m_GetDllInfo(&_pluginInfo); m_GetDllInfo(&_pluginInfo);
return(true); return(true);
} }
return(false); return(false);
} }

View File

@ -36,37 +36,39 @@ class CPlugin
{ {
public: public:
CPlugin(const char* _szName); CPlugin(const char* _szName);
~CPlugin(); ~CPlugin();
virtual bool IsValid() {return valid;}; // This functions is only used when CPlugin is called directly, when a parent class like PluginVideo
virtual std::string GetFilename() {return Filename;}; // is called its own IsValid() will be called.
virtual bool IsValid() {return valid;};
std::string GetFilename() {return Filename;};
bool GetInfo(PLUGIN_INFO& _pluginInfo); bool GetInfo(PLUGIN_INFO& _pluginInfo);
void SetGlobals(PLUGIN_GLOBALS* _PluginGlobals); void SetGlobals(PLUGIN_GLOBALS* _PluginGlobals);
void *LoadSymbol(const char *sym); void *LoadSymbol(const char *sym);
void Config(HWND _hwnd); void Config(HWND _hwnd);
void About(HWND _hwnd); void About(HWND _hwnd);
void Debug(HWND _hwnd, bool Show); void Debug(HWND _hwnd, bool Show);
void DoState(unsigned char **ptr, int mode); void DoState(unsigned char **ptr, int mode);
void Initialize(void *init); void Initialize(void *init);
void Shutdown(); void Shutdown();
private: private:
DynamicLibrary m_hInstLib; DynamicLibrary m_hInstLib;
bool valid; bool valid;
std::string Filename; std::string Filename;
// Functions // Functions
TGetDllInfo m_GetDllInfo; TGetDllInfo m_GetDllInfo;
TDllConfig m_DllConfig; TDllConfig m_DllConfig;
TDllDebugger m_DllDebugger; TDllDebugger m_DllDebugger;
TSetDllGlobals m_SetDllGlobals; TSetDllGlobals m_SetDllGlobals;
TInitialize m_Initialize; TInitialize m_Initialize;
TShutdown m_Shutdown; TShutdown m_Shutdown;
TDoState m_DoState; TDoState m_DoState;
}; };
} // end of namespace Common } // end of namespace Common

View File

@ -1,7 +1,9 @@
#include "PluginVideo.h" #include "PluginVideo.h"
namespace Common { namespace Common
PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo(false) { {
PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo(false)
{
Video_Prepare = 0; Video_Prepare = 0;
Video_SendFifoData = 0; Video_SendFifoData = 0;

View File

@ -158,16 +158,15 @@ void ReconnectWiimote()
// ----------------- // -----------------
bool Init() bool Init()
{ {
//Console::Open();
if (g_pThread != NULL) if (g_pThread != NULL)
{ {
PanicAlert("ERROR: Emu Thread already running. Report this bug."); PanicAlert("ERROR: Emu Thread already running. Report this bug.");
return false; return false;
} }
CPluginManager &pManager = CPluginManager::GetInstance(); // Get a handle to the current instance of the plugin manager
SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter; CPluginManager &pManager = CPluginManager::GetInstance();
SCoreStartupParameter &_CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter;
g_CoreStartupParameter = _CoreParameter; g_CoreStartupParameter = _CoreParameter;
LogManager::Init(); LogManager::Init();
@ -176,9 +175,8 @@ bool Init()
// Start the thread again // Start the thread again
_dbg_assert_(HLE, g_pThread == NULL); _dbg_assert_(HLE, g_pThread == NULL);
// LoadLibrary() // Check that all plugins exist, potentially call LoadLibrary() for unloaded plugins
if (!pManager.InitPlugins()) if (!pManager.InitPlugins()) return false;
return false;
emuThreadGoing.Init(); emuThreadGoing.Init();
// This will execute EmuThread() further down in this file // This will execute EmuThread() further down in this file
@ -322,6 +320,8 @@ THREAD_RETURN EmuThread(void *pArg)
VideoInitialize.pKeyPress = Callback_KeyPress; VideoInitialize.pKeyPress = Callback_KeyPress;
VideoInitialize.bWii = _CoreParameter.bWii; VideoInitialize.bWii = _CoreParameter.bWii;
VideoInitialize.bUseDualCore = _CoreParameter.bUseDualCore; VideoInitialize.bUseDualCore = _CoreParameter.bUseDualCore;
// Needed for Stop and Start
Plugins.FreeVideo();
Plugins.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!
@ -342,6 +342,8 @@ THREAD_RETURN EmuThread(void *pArg)
dspInit.pGetAudioStreaming = AudioInterface::Callback_GetStreaming; dspInit.pGetAudioStreaming = AudioInterface::Callback_GetStreaming;
dspInit.pEmulatorState = (int *)&PowerPC::state; dspInit.pEmulatorState = (int *)&PowerPC::state;
dspInit.bWii = _CoreParameter.bWii; dspInit.bWii = _CoreParameter.bWii;
// Needed for Stop and Start
Plugins.FreeDSP();
Plugins.GetDSP()->Initialize((void *)&dspInit); Plugins.GetDSP()->Initialize((void *)&dspInit);
// Load and Init PadPlugin // Load and Init PadPlugin

View File

@ -15,6 +15,48 @@
// 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/
//////////////////////////////////////////////////////////////////////////////////////////
// File description
/* ¯¯¯¯¯¯¯¯¯¯¯¯
This file controls when plugins are loaded and unloaded from memory. Its functions scan for valid
plugins when Dolphin is booted, and open the debugging and config windows. The PluginManager is
created once when Dolphin starts and is closed when Dolphin is closed.
When plugins are freed and loaded:
In an attempt to avoid the crash that occurs when the use LoadLibrary() and FreeLibrary() often
(every tiem a game is stopped and started) these functions will only be used when
1. Dolphin is started
2. A plugin is changed
3. Dolphin is closed
it will not be used when we Start and Stop games. With these exceptions:
1. Video plugin: If FreeLibrary() is not called between Stop and Start it will fail for
several games on the next Start, but not for all games.
2. Sond plugin: If FreeLibrary() is not called between Stop and Start I got the "Tried to
"get pointer for unknown address ffffffff" message for all games I tried.
For some reason the time when the FreeLibrary() is placed produce different results. If it's placed
after ShutDown() I don't get a black screen when I start SSBM (PAL) again, if I have stopped the game
before the first 3D appears (on the start screen), if I show the start screen and then Stop and Start
I get the same error again (a black screen) (with the default OpenGL settings, copy EFB to texture, no
hack). I also get the "Tried to get pointer ..." error then to (if DSP HLE sound has been enabled, if
"Enable HLE Audio" has been disabled I don't get that error message). For this reason I have to place
FreeVideo() and FreeDSP() before it's initialized on the next Start instead, then it works.
If it was not for the crash I always got earlier after several (perhaps as many as twenty) Stop and Start
I would be indifferent about how often FreeLibrary() i used, but since it seems like it can fail
infrequently, at least for nJoy, I'd rather use FreeLibrary() more sparingly. However, I could not
reproduce any crash now after several Stop and Start so maybe it has gone away or I was lucky. In any case
if it works I'd rather be without FreeLibrary() between Start and Stop.
//////////////////////////////////////*/
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯¯¯
#include <string> // System #include <string> // System
#include <vector> #include <vector>
@ -29,9 +71,14 @@
#include "StringUtil.h" #include "StringUtil.h"
#include "ConsoleWindow.h" #include "ConsoleWindow.h"
// Create the plugin manager class
CPluginManager CPluginManager::m_Instance; CPluginManager CPluginManager::m_Instance;
/////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// The Plugin Manager Class // The Plugin Manager Class
// ¯¯¯¯¯¯¯¯¯¯¯¯
CPluginManager::CPluginManager() : CPluginManager::CPluginManager() :
m_params(SConfig::GetInstance().m_LocalCoreStartupParameter) m_params(SConfig::GetInstance().m_LocalCoreStartupParameter)
{ {
@ -40,34 +87,14 @@ CPluginManager::CPluginManager() :
m_PluginGlobals->config = (void *)&SConfig::GetInstance(); m_PluginGlobals->config = (void *)&SConfig::GetInstance();
m_PluginGlobals->messageLogger = NULL; m_PluginGlobals->messageLogger = NULL;
// Set initial values to NULL, this is only done when Dolphin is started
m_video = NULL; m_video = NULL;
m_dsp = NULL; m_dsp = NULL;
for (int i = 0; i < MAXPADS; i++) for (int i = 0; i < MAXPADS; i++) m_pad[i] = NULL;
m_pad[i] = NULL; for (int i = 0; i < MAXWIIMOTES; i++) m_wiimote[i] = NULL;
for (int i = 0; i < MAXWIIMOTES; i++)
m_wiimote[i] = NULL;
} }
/* Function: // This will call FreeLibrary() for all plugins
FreeLibrary() Called from: In an attempt to avoid the crash that occurs when
the use LoadLibrary() and FreeLibrary() often (every game a game is stopped
and started) these functions will only be used when
1. Dolphin is started
2. A plugin is changed
3. Dolphin is closed
it will not be used when we Start and Stop games. With these exceptions:
1. Video plugin: If FreeLibrary() is not called between Stop and Start it will fail for
several games on the next Start, but not for all games.
2. Sond plugin: If FreeLibrary() is not called between Stop and Start I got the "Tried to
"get pointer for unknown address ffffffff" message for all games I tried.
If it was not for the crash I always got earlier after several (perhaps as many as twenty) Stop and Start
I would be indifferent about how often FreeLibrary() i used, but since it seems like it can fail
infrequently, at least for nJoy, I'd rather use FreeLibrary() more sparingly. However, I could not
reproduce any crash now after several Stop and Start so maybe it has gone away or I was lucky. In any case
if it works I'd rather be without FreeLibrary() between Start and Stop.
*/
CPluginManager::~CPluginManager() CPluginManager::~CPluginManager()
{ {
Console::Print("Delete CPluginManager\n"); Console::Print("Delete CPluginManager\n");
@ -90,32 +117,41 @@ CPluginManager::~CPluginManager()
delete m_video; delete m_video;
} }
//////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Init and Shutdown Plugins // Init and Shutdown Plugins
// Point the m_pad[] and other variables to a certain plugin // ¯¯¯¯¯¯¯¯¯¯¯¯
// Function: Point the m_pad[] and other variables to a certain plugin
bool CPluginManager::InitPlugins() bool CPluginManager::InitPlugins()
{ {
if (! GetDSP()) { if (! GetDSP()) {
PanicAlert("Can't init DSP Plugin"); PanicAlert("Can't init DSP Plugin");
return false; return false;
} }
Console::Print("Before GetVideo\n");
if (! GetVideo()) { if (! GetVideo()) {
PanicAlert("Can't init Video Plugin"); PanicAlert("Can't init Video Plugin");
return false; return false;
} }
Console::Print("After GetVideo\n");
// Check if we get at least one pad or wiimote // Check if we get at least one pad or wiimote
bool pad = false; bool pad = false;
bool wiimote = false; bool wiimote = false;
// Init pad // Init pad
for (int i = 0; i < MAXPADS; i++) { for (int i = 0; i < MAXPADS; i++)
if (! m_params.m_strPadPlugin[i].empty()) {
GetPad(i); // Check that the plugin has a name
if (m_pad[i] != NULL) if (! m_params.m_strPadPlugin[i].empty()) GetPad(i);
pad = true; // Check that GetPad succeeded
if (m_pad[i] != NULL) pad = true;
} }
if (! pad) { if (! pad)
{
PanicAlert("Can't init any PAD Plugins"); PanicAlert("Can't init any PAD Plugins");
return false; return false;
} }
@ -138,68 +174,120 @@ bool CPluginManager::InitPlugins()
return true; return true;
} }
// FreeLibrary() after ShutDown() is disabled for some plugins. See the comment in the file description
// for an explanation about the current LoadLibrary() and FreeLibrary() behavior.
void CPluginManager::ShutdownPlugins() void CPluginManager::ShutdownPlugins()
{ {
for (int i = 0; i < MAXPADS; i++) { for (int i = 0; i < MAXPADS; i++) {
if (m_pad[i] && OkayToInitPlugin(i)) { if (m_pad[i] && OkayToInitPlugin(i)) {
m_pad[i]->Shutdown(); m_pad[i]->Shutdown();
//delete m_pad[i];
} }
//m_pad[i] = NULL;
} }
for (int i = 0; i < MAXWIIMOTES; i++) { for (int i = 0; i < MAXWIIMOTES; i++)
{
if (m_wiimote[i]) m_wiimote[i]->Shutdown(); if (m_wiimote[i]) m_wiimote[i]->Shutdown();
//delete m_wiimote[i];
//m_wiimote[i] = NULL;
} }
if (m_video) if (m_video)
{ {
m_video->Shutdown(); m_video->Shutdown();
// This is needed for Stop and Start to work // This is needed for Stop and Start to work
delete m_video; //delete m_video;
m_video = NULL; //m_video = NULL;
} }
if (m_dsp) if (m_dsp)
{ {
m_dsp->Shutdown(); m_dsp->Shutdown();
// This is needed for Stop and Start to work // This is needed for Stop and Start to work
delete m_dsp; //delete m_dsp;
m_dsp = NULL; //m_dsp = NULL;
}
}
//////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The PluginInfo class: Find Valid Plugins
// ¯¯¯¯¯¯¯¯¯¯¯¯
/* Function: This info is used in ScanForPlugins() to check for valid plugins and and in LoadPlugin() to
check that the filename we want to use is a good DLL. */
CPluginInfo::CPluginInfo(const char *_rFilename)
: m_Filename(_rFilename)
, m_Valid(false)
{
if (! File::Exists(_rFilename))
{
PanicAlert("Can't find plugin %s", _rFilename);
return;
} }
// Disabled FreeLibrary() for these plugins. See comment above PluginManager::~CPluginManager() // Check if the functions that are common to all plugins are present
// for an explanation about the current LoadLibrary() and FreeLibrary() behavior. Common::CPlugin *plugin = new Common::CPlugin(_rFilename);
/* if (plugin->IsValid())
for (int i = 0; i < MAXPADS; i++)
{ {
if (m_pad[i] && OkayToInitPlugin(i)) { if (plugin->GetInfo(m_PluginInfo))
Console::Print("Delete: %i\n", i); m_Valid = true;
delete m_pad[i]; else
PanicAlert("Could not get info about plugin %s", _rFilename);
// We are now done with this plugin and will call FreeLibrary()
delete plugin;
}
}
///////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Supporting functions
// ¯¯¯¯¯¯¯¯¯¯¯¯
/* Return the plugin info we saved when Dolphin was started. We don't even add a function to try load a
plugin name that was not found because in that case it must have been deleted while Dolphin was running.
If the user has done that he will instead get the "Can't open %s, it's missing" message. */
void CPluginManager::GetPluginInfo(CPluginInfo *&info, std::string Filename)
{
for (int i = 0; i < m_PluginInfos.size(); i++)
{
if (m_PluginInfos.at(i).GetFilename() == Filename)
{
info = &m_PluginInfos.at(i);
return;
} }
m_pad[i] = NULL;
} }
for (int i = 0; i < MAXWIIMOTES; i++)
{
delete m_wiimote[i];
m_wiimote[i] = NULL;
}*/
} }
// Supporting functions
/* Called from: Get__() functions in this file only (not from anywhere else), /* Called from: Get__() functions in this file only (not from anywhere else),
therefore we can leave all condition checks in the Get__() functions therefore we can leave all condition checks in the Get__() functions
below. */ below. */
void *CPluginManager::LoadPlugin(const char *_rFilename, int Number) void *CPluginManager::LoadPlugin(const char *_rFilename, int Number)
{ {
CPluginInfo info(_rFilename); // Create a string of the filename
PLUGIN_TYPE type = info.GetPluginInfo().Type;
std::string Filename = _rFilename; std::string Filename = _rFilename;
/* Avoid calling LoadLibrary() again and instead point to the plugin info that we found when
Dolphin was started */
CPluginInfo *info = NULL;
GetPluginInfo(info, Filename);
if (info == NULL)
{
PanicAlert("Can't open %s, it's missing", _rFilename);
return NULL;
}
PLUGIN_TYPE type = info->GetPluginInfo().Type;
Common::CPlugin *plugin = NULL; Common::CPlugin *plugin = NULL;
if (! File::Exists(_rFilename)) // Check again that the file exists, the first check is when CPluginInfo info is created
return NULL; if (! File::Exists(_rFilename)) return NULL;
switch (type) { switch (type)
{
case PLUGIN_TYPE_VIDEO: case PLUGIN_TYPE_VIDEO:
plugin = new Common::PluginVideo(_rFilename); plugin = new Common::PluginVideo(_rFilename);
break; break;
@ -220,11 +308,14 @@ void *CPluginManager::LoadPlugin(const char *_rFilename, int Number)
PanicAlert("Trying to load unsupported type %d", type); PanicAlert("Trying to load unsupported type %d", type);
} }
if (!plugin->IsValid()) { // Check that the plugin has both all the common and all the type specific functions
PanicAlert("Can't open %s", _rFilename); if (!plugin->IsValid())
{
PanicAlert("Can't open %s, it has a missing function", _rFilename);
return NULL; return NULL;
} }
// Call the DLL function SetGlobals
plugin->SetGlobals(m_PluginGlobals); plugin->SetGlobals(m_PluginGlobals);
return plugin; return plugin;
} }
@ -253,18 +344,20 @@ PLUGIN_GLOBALS* CPluginManager::GetGlobals()
void CPluginManager::ScanForPlugins() void CPluginManager::ScanForPlugins()
{ {
m_PluginInfos.clear(); m_PluginInfos.clear();
// Get plugins dir
CFileSearch::XStringVector Directories; CFileSearch::XStringVector Directories;
Directories.push_back(std::string(PLUGINS_DIR)); Directories.push_back(std::string(PLUGINS_DIR));
CFileSearch::XStringVector Extensions; CFileSearch::XStringVector Extensions;
Extensions.push_back("*" PLUGIN_SUFFIX); Extensions.push_back("*" PLUGIN_SUFFIX);
// Get all DLL files in the plugins dir
CFileSearch FileSearch(Extensions, Directories); CFileSearch FileSearch(Extensions, Directories);
const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames(); const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames();
if (rFilenames.size() > 0) { if (rFilenames.size() > 0)
for (size_t i = 0; i < rFilenames.size(); i++) { {
for (size_t i = 0; i < rFilenames.size(); i++)
{
std::string orig_name = rFilenames[i]; std::string orig_name = rFilenames[i];
std::string Filename; std::string Filename;
@ -274,16 +367,26 @@ void CPluginManager::ScanForPlugins()
} }
CPluginInfo PluginInfo(orig_name.c_str()); CPluginInfo PluginInfo(orig_name.c_str());
if (PluginInfo.IsValid()) { if (PluginInfo.IsValid())
{
// Save the PluginInfo
m_PluginInfos.push_back(PluginInfo); m_PluginInfos.push_back(PluginInfo);
} }
} }
} }
} }
/////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
/* Create or return the already created plugin pointers. This will be called /* Create or return the already created plugin pointers. This will be called
often for the Pad and Wiimote from the SI_.cpp files. And often for the DSP often for the Pad and Wiimote from the SI_.cpp files. And often for the DSP
from the DSP files. */ from the DSP files.
We don't need to check if [Plugin]->IsValid() here because it will not be set by LoadPlugin()
if it's not valid.
*/
// ¯¯¯¯¯¯¯¯¯¯¯¯
Common::PluginPAD *CPluginManager::GetPad(int controller) Common::PluginPAD *CPluginManager::GetPad(int controller)
{ {
if (m_pad[controller] != NULL) if (m_pad[controller] != NULL)
@ -325,14 +428,19 @@ Common::PluginDSP *CPluginManager::GetDSP()
Common::PluginVideo *CPluginManager::GetVideo() Common::PluginVideo *CPluginManager::GetVideo()
{ {
if (m_video != NULL && m_video->IsValid()) { /* We don't need to check if m_video->IsValid() here, because m_video will not be set by LoadPlugin()
if it's not valid */
if (m_video != NULL)
{
// Check if the video plugin has been changed
if (m_video->GetFilename() == m_params.m_strVideoPlugin) if (m_video->GetFilename() == m_params.m_strVideoPlugin)
return m_video; return m_video;
// Then free the current video plugin,
else else
FreeVideo(); FreeVideo();
} }
// Else load a new plugin // and load a new plugin
m_video = (Common::PluginVideo*)LoadPlugin(m_params.m_strVideoPlugin.c_str()); m_video = (Common::PluginVideo*)LoadPlugin(m_params.m_strVideoPlugin.c_str());
return m_video; return m_video;
} }
@ -344,7 +452,11 @@ void CPluginManager::FreeVideo()
delete m_video; delete m_video;
m_video = NULL; m_video = NULL;
} }
void CPluginManager::FreeDSP()
{
delete m_dsp;
m_dsp = NULL;
}
void CPluginManager::FreePad(u32 pad) void CPluginManager::FreePad(u32 pad)
{ {
if (pad < MAXPADS) { if (pad < MAXPADS) {
@ -352,9 +464,12 @@ void CPluginManager::FreePad(u32 pad)
m_pad[pad] = NULL; m_pad[pad] = NULL;
} }
} }
/////////////////////////////////////////// ///////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Call DLL functions // Call DLL functions
// ¯¯¯¯¯¯¯¯¯¯¯¯
// Open config window. Input: _rFilename = Plugin filename , Type = Plugin type // Open config window. Input: _rFilename = Plugin filename , Type = Plugin type
void CPluginManager::OpenConfig(void* _Parent, const char *_rFilename, PLUGIN_TYPE Type) void CPluginManager::OpenConfig(void* _Parent, const char *_rFilename, PLUGIN_TYPE Type)
@ -364,7 +479,8 @@ void CPluginManager::OpenConfig(void* _Parent, const char *_rFilename, PLUGIN_TY
return; return;
} }
switch(Type) { switch(Type)
{
case PLUGIN_TYPE_VIDEO: case PLUGIN_TYPE_VIDEO:
GetVideo()->Config((HWND)_Parent); GetVideo()->Config((HWND)_Parent);
break; break;
@ -385,41 +501,22 @@ void CPluginManager::OpenConfig(void* _Parent, const char *_rFilename, PLUGIN_TY
// Open debugging window. Type = Video or DSP. Show = Show or hide window. // Open debugging window. Type = Video or DSP. Show = Show or hide window.
void CPluginManager::OpenDebug(void* _Parent, const char *_rFilename, PLUGIN_TYPE Type, bool Show) void CPluginManager::OpenDebug(void* _Parent, const char *_rFilename, PLUGIN_TYPE Type, bool Show)
{ {
if (! File::Exists(_rFilename)) { if (! File::Exists(_rFilename))
PanicAlert("Can't find plugin %s", _rFilename); {
return;
}
switch(Type) {
case PLUGIN_TYPE_VIDEO:
GetVideo()->Debug((HWND)_Parent, Show);
break;
case PLUGIN_TYPE_DSP:
GetDSP()->Debug((HWND)_Parent, Show);
break;
default:
PanicAlert("Type %d debug not supported in plugin %s", Type, _rFilename);
}
}
// Get dll info
CPluginInfo::CPluginInfo(const char *_rFilename)
: m_Filename(_rFilename)
, m_Valid(false)
{
if (! File::Exists(_rFilename)) {
PanicAlert("Can't find plugin %s", _rFilename); PanicAlert("Can't find plugin %s", _rFilename);
return; return;
} }
Common::CPlugin *plugin = new Common::CPlugin(_rFilename);
if (plugin->IsValid()) {
if (plugin->GetInfo(m_PluginInfo))
m_Valid = true;
else
PanicAlert("Could not get info about plugin %s", _rFilename);
delete plugin; switch(Type)
{
case PLUGIN_TYPE_VIDEO:
GetVideo()->Debug((HWND)_Parent, Show);
break;
case PLUGIN_TYPE_DSP:
GetDSP()->Debug((HWND)_Parent, Show);
break;
default:
PanicAlert("Type %d debug not supported in plugin %s", Type, _rFilename);
} }
} }
///////////////////////////////////////////

View File

@ -42,17 +42,19 @@ private:
typedef std::vector<CPluginInfo>CPluginInfos; typedef std::vector<CPluginInfo>CPluginInfos;
class CPluginManager class CPluginManager
{ {
public: public:
static CPluginManager& GetInstance() {return(m_Instance);} static CPluginManager& GetInstance() {return(m_Instance);}
Common::PluginVideo *GetVideo();
Common::PluginDSP *GetDSP();
Common::PluginPAD *GetPad(int controller); Common::PluginPAD *GetPad(int controller);
Common::PluginWiimote *GetWiimote(int controller); Common::PluginWiimote *GetWiimote(int controller);
Common::PluginDSP *GetDSP();
Common::PluginVideo *GetVideo();
void FreePad(u32 pad);
void FreeVideo(); void FreeVideo();
void FreeDSP();
void FreePad(u32 pad);
bool InitPlugins(); bool InitPlugins();
void ShutdownPlugins(); void ShutdownPlugins();
@ -76,6 +78,7 @@ private:
SCoreStartupParameter& m_params; SCoreStartupParameter& m_params;
CPluginManager(); CPluginManager();
~CPluginManager(); ~CPluginManager();
void GetPluginInfo(CPluginInfo *&info, std::string Filename);
void *LoadPlugin(const char *_rFilename, int Number = 0); void *LoadPlugin(const char *_rFilename, int Number = 0);
}; };

View File

@ -78,18 +78,6 @@ extern "C" // Bitmaps
/////////////////////////////////// ///////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Declarations and definitions
// ¯¯¯¯¯¯¯¯¯¯
// and here are the classes
class CPluginInfo;
class CPluginManager;
//extern DynamicLibrary Common::CPlugin;
//extern CPluginManager CPluginManager::m_Instance;
///////////////////////////////////
void CCodeWindow::CreateSymbolsMenu() void CCodeWindow::CreateSymbolsMenu()
{ {

View File

@ -319,6 +319,7 @@ CFrame::CFrame(wxFrame* parent,
Show(); // Show the window Show(); // Show the window
// Create list of available plugins for the configuration window
CPluginManager::GetInstance().ScanForPlugins(); CPluginManager::GetInstance().ScanForPlugins();
//if we are ever going back to optional iso caching: //if we are ever going back to optional iso caching: