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:
parent
54798713a0
commit
f610f7e197
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
///////////////////////////////////////////
|
|
@ -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);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue