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 }