PlugIn.cpp 8.2 KB

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