mirror of https://github.com/PCSX2/pcsx2.git
plugins: add a dynamic/static loader
This commit is contained in:
parent
de24ce0a8f
commit
3a8164ac4e
|
@ -829,6 +829,87 @@ static void PS2E_CALLBACK pcsx2_OSD_WriteLn( int icon, const char* msg )
|
||||||
return; // not implemented...
|
return; // not implemented...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
// DynamicStaticLibrary
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
StaticLibrary::StaticLibrary(PluginsEnum_t _pid) : pid(_pid)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StaticLibrary::Load(const wxString& name)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* StaticLibrary::GetSymbol(const wxString &name)
|
||||||
|
{
|
||||||
|
#define RETURN_SYMBOL(s) if (name == #s) return (void*)&s;
|
||||||
|
|
||||||
|
#define RETURN_COMMON_SYMBOL(p) \
|
||||||
|
RETURN_SYMBOL(p##init) \
|
||||||
|
RETURN_SYMBOL(p##close) \
|
||||||
|
RETURN_SYMBOL(p##shutdown) \
|
||||||
|
RETURN_SYMBOL(p##keyEvent) \
|
||||||
|
RETURN_SYMBOL(p##setSettingsDir) \
|
||||||
|
RETURN_SYMBOL(p##setLogDir) \
|
||||||
|
RETURN_SYMBOL(p##freeze) \
|
||||||
|
RETURN_SYMBOL(p##test) \
|
||||||
|
RETURN_SYMBOL(p##configure) \
|
||||||
|
RETURN_SYMBOL(p##about)
|
||||||
|
|
||||||
|
#ifdef BUILTIN_GS_PLUGIN
|
||||||
|
RETURN_COMMON_SYMBOL(GS);
|
||||||
|
#endif
|
||||||
|
#ifdef BUILTIN_PAD_PLUGIN
|
||||||
|
RETURN_COMMON_SYMBOL(PAD);
|
||||||
|
#endif
|
||||||
|
#ifdef BUILTIN_SPU2_PLUGIN
|
||||||
|
RETURN_COMMON_SYMBOL(SPU2);
|
||||||
|
#endif
|
||||||
|
#ifdef BUILTIN_CDVD_PLUGIN
|
||||||
|
RETURN_COMMON_SYMBOL(CDVD);
|
||||||
|
#endif
|
||||||
|
#ifdef BUILTIN_DEV9_PLUGIN
|
||||||
|
RETURN_COMMON_SYMBOL(DEV9);
|
||||||
|
#endif
|
||||||
|
#ifdef BUILTIN_USB_PLUGIN
|
||||||
|
RETURN_COMMON_SYMBOL(USB);
|
||||||
|
#endif
|
||||||
|
#ifdef BUILTIN_FW_PLUGIN
|
||||||
|
RETURN_COMMON_SYMBOL(FW);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#undef RETURN_COMMON_SYMBOL
|
||||||
|
#undef RETURN_SYMBOL
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StaticLibrary::HasSymbol(const wxString &name)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicLibrary::DynamicLibrary() : Lib()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DynamicLibrary::Load(const wxString& name)
|
||||||
|
{
|
||||||
|
return Lib.Load(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* DynamicLibrary::GetSymbol(const wxString &name)
|
||||||
|
{
|
||||||
|
return Lib.GetSymbol(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DynamicLibrary::HasSymbol(const wxString &name)
|
||||||
|
{
|
||||||
|
return Lib.HasSymbol(name);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
// PluginStatus_t Implementations
|
// PluginStatus_t Implementations
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
|
@ -839,57 +920,65 @@ SysCorePlugins::PluginStatus_t::PluginStatus_t( PluginsEnum_t _pid, const wxStri
|
||||||
|
|
||||||
IsInitialized = false;
|
IsInitialized = false;
|
||||||
IsOpened = false;
|
IsOpened = false;
|
||||||
|
IsStatic = false;
|
||||||
if( Filename.IsEmpty() )
|
Lib = new DynamicLibrary();
|
||||||
throw Exception::PluginInitError( pid ).SetDiagMsg( L"Empty plugin filename" );
|
|
||||||
|
|
||||||
if( !wxFile::Exists( Filename ) )
|
|
||||||
throw Exception::PluginLoadError( pid ).SetStreamName(srcfile)
|
|
||||||
.SetBothMsgs(pxL("The configured %s plugin file was not found"));
|
|
||||||
|
|
||||||
if( !Lib.Load( Filename ) )
|
|
||||||
throw Exception::PluginLoadError( pid ).SetStreamName(Filename)
|
|
||||||
.SetBothMsgs(pxL("The configured %s plugin file is not a valid dynamic library"));
|
|
||||||
|
|
||||||
|
|
||||||
// Try to enumerate the new v2.0 plugin interface first.
|
if (IsStatic) {
|
||||||
// If that fails, fall back on the old style interface.
|
BindCommon( pid );
|
||||||
|
|
||||||
//m_libs[i].GetSymbol( L"PS2E_InitAPI" ); // on the TODO list!
|
} else {
|
||||||
|
if( Filename.IsEmpty() )
|
||||||
|
throw Exception::PluginInitError( pid ).SetDiagMsg( L"Empty plugin filename" );
|
||||||
|
|
||||||
|
if( !wxFile::Exists( Filename ) )
|
||||||
// 2.0 API Failed; Enumerate the Old Stuff! -->
|
throw Exception::PluginLoadError( pid ).SetStreamName(srcfile)
|
||||||
|
.SetBothMsgs(pxL("The configured %s plugin file was not found"));
|
||||||
|
|
||||||
_PS2EgetLibName GetLibName = (_PS2EgetLibName) Lib.GetSymbol( L"PS2EgetLibName" );
|
if( !Lib->Load( Filename ) )
|
||||||
_PS2EgetLibVersion2 GetLibVersion2 = (_PS2EgetLibVersion2) Lib.GetSymbol( L"PS2EgetLibVersion2" );
|
throw Exception::PluginLoadError( pid ).SetStreamName(Filename)
|
||||||
|
.SetBothMsgs(pxL("The configured %s plugin file is not a valid dynamic library"));
|
||||||
|
|
||||||
if( GetLibName == NULL || GetLibVersion2 == NULL )
|
|
||||||
throw Exception::PluginLoadError( pid ).SetStreamName(Filename)
|
|
||||||
.SetDiagMsg(L"%s plugin init failed: Method binding failure on GetLibName or GetLibVersion2.")
|
|
||||||
.SetUserMsg(_( "The configured %s plugin is not a PCSX2 plugin, or is for an older unsupported version of PCSX2."));
|
|
||||||
|
|
||||||
// Only Windows GSdx uses this. Should be removed in future after GSdx no longer relies on it to show the new config dialog.
|
// Try to enumerate the new v2.0 plugin interface first.
|
||||||
|
// If that fails, fall back on the old style interface.
|
||||||
|
|
||||||
|
//m_libs[i].GetSymbol( L"PS2E_InitAPI" ); // on the TODO list!
|
||||||
|
|
||||||
|
|
||||||
|
// 2.0 API Failed; Enumerate the Old Stuff! -->
|
||||||
|
|
||||||
|
_PS2EgetLibName GetLibName = (_PS2EgetLibName) Lib->GetSymbol( L"PS2EgetLibName" );
|
||||||
|
_PS2EgetLibVersion2 GetLibVersion2 = (_PS2EgetLibVersion2) Lib->GetSymbol( L"PS2EgetLibVersion2" );
|
||||||
|
|
||||||
|
if( GetLibName == NULL || GetLibVersion2 == NULL )
|
||||||
|
throw Exception::PluginLoadError( pid ).SetStreamName(Filename)
|
||||||
|
.SetDiagMsg(L"%s plugin init failed: Method binding failure on GetLibName or GetLibVersion2.")
|
||||||
|
.SetUserMsg(_( "The configured %s plugin is not a PCSX2 plugin, or is for an older unsupported version of PCSX2."));
|
||||||
|
|
||||||
|
// Only Windows GSdx uses this. Should be removed in future after GSdx no longer relies on it to show the new config dialog.
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Since only Windows Gsdx has this symbol, that means every other plugin is going to cause error messages to be logged.
|
// Since only Windows Gsdx has this symbol, that means every other plugin is going to cause error messages to be logged.
|
||||||
// Let's not do that for a hack function.
|
// Let's not do that for a hack function.
|
||||||
if (Lib.HasSymbol(L"PS2EsetEmuVersion")) {
|
if (Lib->HasSymbol(L"PS2EsetEmuVersion")) {
|
||||||
_PS2EsetEmuVersion SetEmuVersion = (_PS2EsetEmuVersion)Lib.GetSymbol(L"PS2EsetEmuVersion");
|
_PS2EsetEmuVersion SetEmuVersion = (_PS2EsetEmuVersion)Lib->GetSymbol(L"PS2EsetEmuVersion");
|
||||||
if (SetEmuVersion)
|
if (SetEmuVersion)
|
||||||
SetEmuVersion("PCSX2", (PCSX2_VersionHi << 24) | (PCSX2_VersionMid << 16) | (PCSX2_VersionLo << 8) | 0);
|
SetEmuVersion("PCSX2", (PCSX2_VersionHi << 24) | (PCSX2_VersionMid << 16) | (PCSX2_VersionLo << 8) | 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Name = fromUTF8( GetLibName() );
|
Name = fromUTF8( GetLibName() );
|
||||||
int version = GetLibVersion2( tbl_PluginInfo[pid].typemask );
|
int version = GetLibVersion2( tbl_PluginInfo[pid].typemask );
|
||||||
Version.Printf( L"%d.%d.%d", (version>>8)&0xff, version&0xff, (version>>24)&0xff );
|
Version.Printf( L"%d.%d.%d", (version>>8)&0xff, version&0xff, (version>>24)&0xff );
|
||||||
|
|
||||||
|
// Bind Required Functions
|
||||||
|
// (generate critical error if binding fails)
|
||||||
|
|
||||||
// Bind Required Functions
|
BindCommon( pid );
|
||||||
// (generate critical error if binding fails)
|
BindRequired( pid );
|
||||||
|
BindOptional( pid );
|
||||||
|
}
|
||||||
|
|
||||||
BindCommon( pid );
|
|
||||||
BindRequired( pid );
|
|
||||||
BindOptional( pid );
|
|
||||||
|
|
||||||
// Run Plugin's Functionality Test.
|
// Run Plugin's Functionality Test.
|
||||||
// A lot of plugins don't bother to implement this function and return 0 (success)
|
// A lot of plugins don't bother to implement this function and return 0 (success)
|
||||||
|
@ -911,7 +1000,7 @@ void SysCorePlugins::PluginStatus_t::BindCommon( PluginsEnum_t pid )
|
||||||
|
|
||||||
while( current->MethodName != NULL )
|
while( current->MethodName != NULL )
|
||||||
{
|
{
|
||||||
*target = (VoidMethod*)Lib.GetSymbol( current->GetMethodName( pid ) );
|
*target = (VoidMethod*)Lib->GetSymbol( current->GetMethodName( pid ) );
|
||||||
|
|
||||||
if( *target == NULL )
|
if( *target == NULL )
|
||||||
*target = current->Fallback;
|
*target = current->Fallback;
|
||||||
|
@ -931,13 +1020,12 @@ void SysCorePlugins::PluginStatus_t::BindCommon( PluginsEnum_t pid )
|
||||||
void SysCorePlugins::PluginStatus_t::BindRequired( PluginsEnum_t pid )
|
void SysCorePlugins::PluginStatus_t::BindRequired( PluginsEnum_t pid )
|
||||||
{
|
{
|
||||||
const LegacyApi_ReqMethod* current = s_MethMessReq[pid];
|
const LegacyApi_ReqMethod* current = s_MethMessReq[pid];
|
||||||
const wxDynamicLibrary& lib = Lib;
|
|
||||||
|
|
||||||
wxDoNotLogInThisScope please;
|
wxDoNotLogInThisScope please;
|
||||||
|
|
||||||
while( current->MethodName != NULL )
|
while( current->MethodName != NULL )
|
||||||
{
|
{
|
||||||
*(current->Dest) = (VoidMethod*)lib.GetSymbol( current->GetMethodName() );
|
*(current->Dest) = (VoidMethod*)Lib->GetSymbol( current->GetMethodName() );
|
||||||
|
|
||||||
if( *(current->Dest) == NULL )
|
if( *(current->Dest) == NULL )
|
||||||
*(current->Dest) = current->Fallback;
|
*(current->Dest) = current->Fallback;
|
||||||
|
@ -956,13 +1044,12 @@ void SysCorePlugins::PluginStatus_t::BindRequired( PluginsEnum_t pid )
|
||||||
void SysCorePlugins::PluginStatus_t::BindOptional( PluginsEnum_t pid )
|
void SysCorePlugins::PluginStatus_t::BindOptional( PluginsEnum_t pid )
|
||||||
{
|
{
|
||||||
const LegacyApi_OptMethod* current = s_MethMessOpt[pid];
|
const LegacyApi_OptMethod* current = s_MethMessOpt[pid];
|
||||||
const wxDynamicLibrary& lib = Lib;
|
|
||||||
|
|
||||||
wxDoNotLogInThisScope please;
|
wxDoNotLogInThisScope please;
|
||||||
|
|
||||||
while( current->MethodName != NULL )
|
while( current->MethodName != NULL )
|
||||||
{
|
{
|
||||||
*(current->Dest) = (VoidMethod*)lib.GetSymbol( current->GetMethodName() );
|
*(current->Dest) = (VoidMethod*)Lib->GetSymbol( current->GetMethodName() );
|
||||||
current++;
|
current++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,6 +253,46 @@ extern SysPluginBindings SysPlugins;
|
||||||
// SysCorePlugins Class
|
// SysCorePlugins Class
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
class DynamicStaticLibrary
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
DynamicStaticLibrary() {};
|
||||||
|
virtual ~DynamicStaticLibrary() {};
|
||||||
|
|
||||||
|
virtual bool Load(const wxString& name) = 0;
|
||||||
|
virtual void* GetSymbol(const wxString &name) = 0;
|
||||||
|
virtual bool HasSymbol(const wxString &name) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StaticLibrary : public DynamicStaticLibrary
|
||||||
|
{
|
||||||
|
PluginsEnum_t pid;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
StaticLibrary(PluginsEnum_t _pid);
|
||||||
|
virtual ~StaticLibrary() {};
|
||||||
|
|
||||||
|
bool Load(const wxString& name);
|
||||||
|
void* GetSymbol(const wxString &name);
|
||||||
|
bool HasSymbol(const wxString &name);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DynamicLibrary : public DynamicStaticLibrary
|
||||||
|
{
|
||||||
|
wxDynamicLibrary Lib;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DynamicLibrary();
|
||||||
|
virtual ~DynamicLibrary() {};
|
||||||
|
|
||||||
|
bool Load(const wxString& name);
|
||||||
|
void* GetSymbol(const wxString &name);
|
||||||
|
bool HasSymbol(const wxString &name);
|
||||||
|
};
|
||||||
|
|
||||||
class SysCorePlugins
|
class SysCorePlugins
|
||||||
{
|
{
|
||||||
DeclareNoncopyableObject( SysCorePlugins );
|
DeclareNoncopyableObject( SysCorePlugins );
|
||||||
|
@ -265,24 +305,27 @@ protected:
|
||||||
|
|
||||||
bool IsInitialized;
|
bool IsInitialized;
|
||||||
bool IsOpened;
|
bool IsOpened;
|
||||||
|
bool IsStatic;
|
||||||
|
|
||||||
wxString Filename;
|
wxString Filename;
|
||||||
wxString Name;
|
wxString Name;
|
||||||
wxString Version;
|
wxString Version;
|
||||||
|
|
||||||
LegacyPluginAPI_Common CommonBindings;
|
LegacyPluginAPI_Common CommonBindings;
|
||||||
wxDynamicLibrary Lib;
|
DynamicStaticLibrary* Lib;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PluginStatus_t()
|
PluginStatus_t()
|
||||||
{
|
{
|
||||||
IsInitialized = false;
|
IsInitialized = false;
|
||||||
IsOpened = false;
|
IsOpened = false;
|
||||||
|
IsStatic = false;
|
||||||
|
Lib = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginStatus_t( PluginsEnum_t _pid, const wxString& srcfile );
|
PluginStatus_t( PluginsEnum_t _pid, const wxString& srcfile );
|
||||||
virtual ~PluginStatus_t() throw() { }
|
virtual ~PluginStatus_t() throw() { delete Lib; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void BindCommon( PluginsEnum_t pid );
|
void BindCommon( PluginsEnum_t pid );
|
||||||
void BindRequired( PluginsEnum_t pid );
|
void BindRequired( PluginsEnum_t pid );
|
||||||
|
|
Loading…
Reference in New Issue