Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

PlugIn.cpp (8421B)


      1 /*
      2 ===========================================================================
      3 Copyright (C) 1999-2005 Id Software, Inc.
      4 
      5 This file is part of Quake III Arena source code.
      6 
      7 Quake III Arena source code is free software; you can redistribute it
      8 and/or modify it under the terms of the GNU General Public License as
      9 published by the Free Software Foundation; either version 2 of the License,
     10 or (at your option) any later version.
     11 
     12 Quake III Arena source code is distributed in the hope that it will be
     13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with Foobar; if not, write to the Free Software
     19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     20 ===========================================================================
     21 */
     22 // PlugIn.cpp: implementation of the CPlugIn class.
     23 //
     24 //////////////////////////////////////////////////////////////////////
     25 
     26 #include "stdafx.h"
     27 #include "Radiant.h"
     28 #include "PlugIn.h"
     29 
     30 #ifdef _DEBUG
     31 #undef THIS_FILE
     32 static char THIS_FILE[]=__FILE__;
     33 #define new DEBUG_NEW
     34 #endif
     35 
     36 //////////////////////////////////////////////////////////////////////
     37 // Construction/Destruction
     38 //////////////////////////////////////////////////////////////////////
     39 
     40 CPlugIn::CPlugIn()
     41 {
     42   m_hDLL = NULL;
     43   m_pQERPlugEntitiesFactory = NULL;
     44 }
     45 
     46 CPlugIn::~CPlugIn()
     47 {
     48 	if (m_pQERPlugEntitiesFactory)
     49 		delete m_pQERPlugEntitiesFactory;
     50 	if (m_hDLL != NULL)
     51 		free();
     52 }
     53 
     54 bool CPlugIn::load(const char *p)
     55 {
     56 	m_hDLL = ::LoadLibrary(p);
     57 	if (m_hDLL != NULL)
     58 	{
     59 		m_pfnInit = reinterpret_cast<PFN_QERPLUG_INIT>(::GetProcAddress(m_hDLL, QERPLUG_INIT));
     60 		if (m_pfnInit != NULL)
     61 		{
     62 			m_strVersion = (*m_pfnInit)(AfxGetApp()->m_hInstance, g_pParentWnd->GetSafeHwnd());
     63 			Sys_Printf("Loaded plugin > %s\n", m_strVersion);
     64 			
     65 			m_pfnGetName = reinterpret_cast<PFN_QERPLUG_GETNAME>(::GetProcAddress(m_hDLL, QERPLUG_GETNAME));
     66 			if (m_pfnGetName != NULL)
     67 			{
     68 				m_strName = (*m_pfnGetName)();
     69 			}
     70 			
     71 			m_pfnGetCommandList = reinterpret_cast<PFN_QERPLUG_GETCOMMANDLIST>(::GetProcAddress(m_hDLL, QERPLUG_GETCOMMANDLIST));
     72 			if (m_pfnGetCommandList)
     73 			{
     74 				CString str = (*m_pfnGetCommandList)();
     75 				char cTemp[1024];
     76 				strcpy(cTemp, str);
     77 				char* token = strtok(cTemp, ",;");
     78 				if (token && *token == ' ')
     79 				{
     80 					while (*token == ' ')
     81 						token++;
     82 				}
     83 				while (token != NULL)
     84 				{
     85 					m_CommandStrings.Add(token);
     86 					token = strtok(NULL, ",;");
     87 				}
     88 			}
     89 			
     90 			m_pfnDispatch = reinterpret_cast<PFN_QERPLUG_DISPATCH>(::GetProcAddress(m_hDLL, QERPLUG_DISPATCH));
     91 			m_pfnGetFuncTable = reinterpret_cast<PFN_QERPLUG_GETFUNCTABLE>(::GetProcAddress(m_hDLL, QERPLUG_GETFUNCTABLE));
     92 			
     93 			m_pfnGetTextureInfo = reinterpret_cast<PFN_QERPLUG_GETTEXTUREINFO>(::GetProcAddress(m_hDLL, QERPLUG_GETTEXTUREINFO));
     94 			m_pfnLoadTexture = reinterpret_cast<PFN_QERPLUG_LOADTEXTURE>(::GetProcAddress(m_hDLL, QERPLUG_LOADTEXTURE));
     95 			
     96 			m_pfnGetSurfaceFlags = reinterpret_cast<PFN_QERPLUG_GETSURFACEFLAGS>(::GetProcAddress(m_hDLL, QERPLUG_GETSURFACEFLAGS));
     97 			
     98 			m_pfnRegisterPluginEntities = reinterpret_cast<PFN_QERPLUG_REGISTERPLUGINENTITIES>(::GetProcAddress(m_hDLL, QERPLUG_REGISTERPLUGINENTITIES));
     99 			
    100 			m_pfnInitSurfaceProperties = reinterpret_cast<PFN_QERPLUG_INITSURFACEPROPERTIES>(::GetProcAddress(m_hDLL, QERPLUG_INITSURFACEPROPERTIES));
    101 			
    102 			m_pfnRequestInterface = reinterpret_cast<PFN_QERPLUG_REQUESTINTERFACE>(::GetProcAddress(m_hDLL, QERPLUG_REQUESTINTERFACE));
    103 
    104 			return (m_pfnDispatch != NULL && m_pfnGetFuncTable != NULL);
    105 			//--return true;
    106 		}
    107 		Sys_Printf("FAILED to Load plugin > %s\n", p);
    108 	}
    109 	LPVOID lpMsgBuf;
    110 	FormatMessage( 
    111 	    FORMAT_MESSAGE_ALLOCATE_BUFFER | 
    112 	    FORMAT_MESSAGE_FROM_SYSTEM | 
    113 	    FORMAT_MESSAGE_IGNORE_INSERTS,
    114 	    NULL,
    115 	    GetLastError(),
    116 	    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    117 	    (LPTSTR) &lpMsgBuf,
    118 	    0,
    119 	    NULL 
    120 	);
    121 	Sys_Printf("LoadLibrary failed on %s: GetLastError: %s\n", p, lpMsgBuf );
    122 	// Free the buffer.
    123 	LocalFree( lpMsgBuf );
    124 	free();
    125 	return false;
    126 }
    127 
    128 _QERTextureInfo* CPlugIn::getTextureInfo()
    129 {
    130   if (m_pfnGetTextureInfo != NULL)
    131   {
    132     return reinterpret_cast<_QERTextureInfo*>((*m_pfnGetTextureInfo)());
    133   }
    134   return NULL;
    135 }
    136 
    137 void CPlugIn::loadTexture(LPCSTR pFilename)
    138 {
    139   if (m_pfnLoadTexture != NULL)
    140   {
    141     (*m_pfnLoadTexture)(pFilename);
    142   }
    143 }
    144 
    145 LPVOID CPlugIn::getSurfaceFlags()
    146 {
    147   if (m_pfnGetSurfaceFlags != NULL)
    148   {
    149     return reinterpret_cast<LPVOID>((*m_pfnGetSurfaceFlags)());
    150   }
    151   return NULL;
    152 }
    153 
    154 void CPlugIn::free()
    155 {
    156   if (m_hDLL != NULL)
    157     ::FreeLibrary(m_hDLL);
    158   m_hDLL = NULL;
    159 }
    160 
    161 const char* CPlugIn::getVersionStr()
    162 {
    163 	return m_pfnGetName();
    164 }
    165 
    166 const char* CPlugIn::getMenuName()
    167 {
    168   return m_strName;
    169 }
    170 
    171 int CPlugIn::getCommandCount()
    172 {
    173   return m_CommandStrings.GetSize();
    174 }
    175 
    176 const char* CPlugIn::getCommand(int n)
    177 {
    178   return m_CommandStrings.GetAt(n);
    179 }
    180 
    181 void CPlugIn::dispatchCommand(const char* p, vec3_t vMin, vec3_t vMax, BOOL bSingleBrush)
    182 {
    183   if (m_pfnDispatch)
    184   {
    185     (*m_pfnDispatch)(p, vMin, vMax, bSingleBrush);
    186   }
    187 }
    188 
    189 void CPlugIn::addMenuID(int n)
    190 {
    191   m_CommandIDs.Add(n);
    192 }
    193 
    194 bool CPlugIn::ownsCommandID(int n)
    195 {
    196   for (int i = 0; i < m_CommandIDs.GetSize(); i++)
    197   {
    198     if (m_CommandIDs.GetAt(i) == n)
    199       return true;
    200   }
    201   return false;
    202 }
    203 
    204 void* CPlugIn::getFuncTable()
    205 {
    206   if (m_pfnGetFuncTable)
    207   {
    208     return (*m_pfnGetFuncTable)();
    209   }
    210   return NULL;
    211 }
    212 
    213 void CPlugIn::RegisterPluginEntities()
    214 {
    215 	// if we found the QERPlug_RegisterPluginEntities export, it means this plugin provides his own entities
    216 	if (m_pfnRegisterPluginEntities)
    217 	{
    218 		// resquest a _QERPlugEntitiesFactory
    219 		if (m_pfnRequestInterface)
    220 		{
    221 			m_pQERPlugEntitiesFactory = new _QERPlugEntitiesFactory;
    222 			m_pQERPlugEntitiesFactory->m_nSize = sizeof(_QERPlugEntitiesFactory);
    223 			if (m_pfnRequestInterface( QERPlugEntitiesFactory_GUID, m_pQERPlugEntitiesFactory ))
    224 			{
    225 				// create an IEpair interface for the project settings
    226 				CEpairsWrapper *pProjectEp = new CEpairsWrapper( g_qeglobals.d_project_entity );
    227 				m_pfnRegisterPluginEntities( pProjectEp );
    228 			}
    229 			else
    230 				Sys_Printf( "WARNING: failed to request QERPlugEntitiesFactory from plugin %s\n", m_strName.GetBuffer(0) );
    231 		}
    232 		else
    233 			Sys_Printf( "WARNING: QERPlug_RequestInterface not found in %s\n", m_strName.GetBuffer(0) );
    234 	}
    235 }
    236 
    237 void CPlugIn::InitBSPFrontendPlugin()
    238 {
    239 	if (m_pfnRequestInterface)
    240 	{
    241 		// request a _QERPlugBSPFrontendTable
    242 		g_BSPFrontendTable.m_nSize = sizeof( _QERPlugBSPFrontendTable );
    243 		if ( m_pfnRequestInterface( QERPlugBSPFrontendTable_GUID, &g_BSPFrontendTable ) )
    244 		{
    245 			g_qeglobals.bBSPFrontendPlugin = true;
    246 		}
    247 	}
    248 }
    249 
    250 void CPlugIn::InitSurfacePlugin()
    251 {
    252 	// if we found the QERPlug_InitSurfaceProperties export, it means this plugin does surface properties
    253 	if (m_pfnInitSurfaceProperties)
    254 	{
    255 		if (g_qeglobals.bSurfacePropertiesPlugin)
    256 		{
    257 			Sys_Printf( "WARNING: conflict for surface properties plugins. %s ignored.\n", m_strName );
    258 			return;
    259 		}
    260 		if (m_pfnRequestInterface)
    261 		{
    262 			// call the plugin surface properties init
    263 			m_pfnInitSurfaceProperties();
    264 			// request filling of the global _QERPlugSurfaceTable
    265 			g_SurfaceTable.m_nSize = sizeof( g_SurfaceTable );
    266 			if ( m_pfnRequestInterface( QERPlugSurfaceTable_GUID, &g_SurfaceTable ) )
    267 			{
    268 				// update the global so we know we have a surface properties plugin
    269 				g_qeglobals.bSurfacePropertiesPlugin = true;
    270 			}
    271 			else
    272 				Sys_Printf( "WARNING: _QERPlugSurfaceTable interface request failed for surface plugin\n" );
    273 		}
    274 		else
    275 			Sys_Printf("WARNING: QERPlug_RequestInterface export not found in surface properties plugin.\n");
    276 	}
    277 }
    278 
    279 // create a plugin entity
    280 // e is the entity being created
    281 // e->eclass is the plugin eclass info
    282 // e->epairs will be accessed by the plugin entity through a IEpair interface
    283 IPluginEntity * CPlugIn::CreatePluginEntity(entity_t *e)
    284 {
    285 	if (m_pQERPlugEntitiesFactory)
    286 	{
    287 		// create an IEpair interface for e->epairs
    288 		CEpairsWrapper *pEp = new CEpairsWrapper( e );
    289 		IPluginEntity *pEnt = m_pQERPlugEntitiesFactory->m_pfnCreateEntity( e->eclass, pEp );
    290 		if ( pEnt )
    291 			return pEnt;
    292 		delete pEp;
    293 		return NULL;
    294 	}
    295 	Sys_Printf("WARNING: unexpected m_pQERPlugEntitiesFactory is NULL in CPlugin::CreatePluginEntity\n");
    296 	return NULL;
    297 }