pluginmanager.cpp
来自「quake3工具源码。包括生成bsp文件」· C++ 代码 · 共 1,645 行 · 第 1/4 页
CPP
1,645 行
// PlugInManager.cpp: implementation of the CPlugInManager class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "io.h"
#include "Radiant.h"
#include "PlugInManager.h"
#include "PlugIn.h"
#include "DialogInfo.h"
#include "pakstuff.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPlugInManager::CPlugInManager()
{
m_pTexturePlug = NULL;
m_pSurfaceListPlug = NULL;
PatchesMode = EActivePatches;
}
CPlugInManager::~CPlugInManager()
{
Cleanup();
}
void CPlugInManager::Init(const char * pPath)
{
Cleanup();
// set some globals
g_qeglobals.bSurfacePropertiesPlugin = false;
g_qeglobals.bBSPFrontendPlugin = false;
CString strPath(pPath);
strPath += "*.dll";
bool bGo = true;
struct _finddata_t fileinfo;
int handle = _findfirst (strPath, &fileinfo);
if (handle != -1)
{
do
{
strPath.Format("%s\\%s", pPath, fileinfo.name);
CPlugIn *pPlug = new CPlugIn();
if (pPlug->load(strPath))
{
if(FillFuncTable(pPlug)) // PGM
{
m_PlugIns.Add(pPlug);
pPlug->RegisterPluginEntities();
// if this thing handles surface properties
pPlug->InitSurfacePlugin();
// will test and init if it's a BSP frontend
pPlug->InitBSPFrontendPlugin();
g_pParentWnd->AddPlugInMenuItem(pPlug);
// if this thing handles textures
if (pPlug->getTextureInfo() != NULL)
{
this->m_pTexturePlug = pPlug;
// if this is a wad style texture extension, have it load everything now
if (pPlug->getTextureInfo()->m_bWadStyle)
{
CString strPath = ValueForKey(g_qeglobals.d_project_entity, "texturepath");
pPlug->loadTexture(strPath);
}
}
if (pPlug->getSurfaceFlags() != NULL)
{
this->m_pSurfaceListPlug = pPlug;
}
}
else
{
delete pPlug; // PGM
}
}
else
{
delete pPlug;
}
} while (_findnext( handle, &fileinfo ) != -1);
_findclose (handle);
}
}
void CPlugInManager::Cleanup()
{
int i;
for (i = 0; i < m_PlugIns.GetSize(); i++)
{
CPlugIn *plug = reinterpret_cast<CPlugIn*>(m_PlugIns.GetAt(i));
plug->free();
delete plug;
}
m_PlugIns.RemoveAll();
for (i = 0; i < m_BrushHandles.GetSize(); i++)
{
brush_t *pb = reinterpret_cast<brush_t*>(m_BrushHandles.GetAt(i));
Brush_Free(pb);
}
m_BrushHandles.RemoveAll();
for (i = 0; i < m_EntityHandles.GetSize(); i++)
{
entity_t *pe = reinterpret_cast<entity_t*>(m_EntityHandles.GetAt(i));
Entity_Free(pe);
}
m_EntityHandles.RemoveAll();
// patches
// these are linked into the map
m_PatchesHandles.RemoveAll();
// these patches were allocated by Radiant on plugin request
// if the list is not empty, it means either the plugin asked for allocation and never commited them to the map
// in which case we are supposed to delete them
// or it commited them but never called m_pfnReleasePatchHandles, in case the patches may have already been
// erased and we are trying a second time, therefore crashing ..
//++timo FIXME: for now I leave a leak warning, we'd need a table to keep track of commited patches
#ifdef _DEBUG
if (m_PluginPatches.GetSize() != 0)
Sys_Printf("WARNING: m_PluginPatches.GetSize() != 0 in CPlugInManager::Cleanup, possible leak\n");
#endif
/* for (i = 0; i < m_PluginPatches.GetSize(); i++)
{
patchMesh_t *pMesh = reinterpret_cast<patchMesh_t*>(m_PluginPatches.GetAt(i));
if (pMesh->pSymbiot)
delete pMesh;
}
m_PluginPatches.RemoveAll(); */
}
void CPlugInManager::Dispatch(int n, const char * p)
{
for (int i = 0; i < m_PlugIns.GetSize(); i++)
{
CPlugIn *plug = reinterpret_cast<CPlugIn*>(m_PlugIns.GetAt(i));
if (plug->ownsCommandID(n))
{
vec3_t vMin, vMax;
if (selected_brushes.next == &selected_brushes)
{
vMin[0] = vMin[1] = vMin[2] = 0;
VectorCopy(vMin, vMax);
}
else
{
Select_GetBounds (vMin, vMax);
}
plug->dispatchCommand(p, vMin, vMax, QE_SingleBrush(true)); // PGM -- added quiet
break;
}
}
}
// creates a dummy brush in the active brushes list
// FIXME : is this one really USED ?
void WINAPI QERApp_CreateBrush(vec3_t vMin, vec3_t vMax)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
brush_t* pBrush = Brush_Create(vMin, vMax, &g_qeglobals.d_texturewin.texdef);
Entity_LinkBrush (world_entity, pBrush);
Brush_Build(pBrush);
Brush_AddToList (pBrush, &active_brushes);
Select_Brush(pBrush);
Sys_UpdateWindows(W_ALL);
}
LPVOID CPlugInManager::CreateBrushHandle()
{
brush_t *pb = Brush_Alloc();
pb->numberId = g_nBrushId++;
m_BrushHandles.Add(pb);
return (LPVOID)pb;
}
void CPlugInManager::DeleteBrushHandle(void * vp)
{
CPtrArray* pHandles[3];
pHandles[0] = &m_SelectedBrushHandles;
pHandles[1] = &m_ActiveBrushHandles;
pHandles[2] = &m_BrushHandles;
for (int j = 0; j < 3; j++)
{
for (int i = 0; i < pHandles[j]->GetSize(); i++)
{
brush_t *pb = reinterpret_cast<brush_t*>(pHandles[j]->GetAt(i));
if (pb == reinterpret_cast<brush_t*>(vp))
{
if (j == 2)
{
// only remove it from the list if it is work area
// this allows the selected and active list indexes to remain constant
// throughout a session (i.e. between an allocate and release)
pHandles[j]->RemoveAt(i);
}
Brush_Free(pb);
Sys_MarkMapModified(); // PGM
return;
}
}
}
}
void CPlugInManager::CommitBrushHandleToMap(void * vp)
{
g_bScreenUpdates = false;
for (int i = 0; i < m_BrushHandles.GetSize(); i++)
{
brush_t *pb = reinterpret_cast<brush_t*>(m_BrushHandles.GetAt(i));
if (pb == reinterpret_cast<brush_t*>(vp))
{
m_BrushHandles.RemoveAt(i);
Entity_LinkBrush (world_entity, pb);
Brush_Build(pb);
Brush_AddToList (pb, &active_brushes);
Select_Brush(pb);
}
}
g_bScreenUpdates = true;
Sys_UpdateWindows(W_ALL);
}
void CPlugInManager::AddFaceToBrushHandle(void * vp, vec3_t v1, vec3_t v2, vec3_t v3)
{
brush_t *bp = FindBrushHandle(vp);
if (bp != NULL)
{
face_t *f = Face_Alloc();
f->texdef = g_qeglobals.d_texturewin.texdef;
f->texdef.flags &= ~SURF_KEEP;
f->texdef.contents &= ~CONTENTS_KEEP;
f->next = bp->brush_faces;
bp->brush_faces = f;
VectorCopy (v1, f->planepts[0]);
VectorCopy (v2, f->planepts[1]);
VectorCopy (v3, f->planepts[2]);
}
}
brush_t* CPlugInManager::FindBrushHandle(void * vp)
{
CPtrArray* pHandles[4];
pHandles[0] = &m_SelectedBrushHandles;
pHandles[1] = &m_ActiveBrushHandles;
pHandles[2] = &m_BrushHandles;
pHandles[3] = &m_EntityBrushHandles;
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < pHandles[j]->GetSize(); i++)
{
brush_t *pb = reinterpret_cast<brush_t*>(pHandles[j]->GetAt(i));
if (pb == reinterpret_cast<brush_t*>(vp))
{
return pb;
}
}
}
return NULL;
}
patchMesh_t* CPlugInManager::FindPatchHandle(int index)
{
switch (PatchesMode)
{
case EActivePatches:
case ESelectedPatches:
if ( index < m_PatchesHandles.GetSize() )
{
brush_t *pb = reinterpret_cast<brush_t *>(m_PatchesHandles.GetAt(index));
return pb->pPatch;
}
#ifdef _DEBUG
Sys_Printf("WARNING: out of bounds in CPlugInManager::FindPatchHandle\n");
#endif
break;
case EAllocatedPatches:
if ( index < m_PluginPatches.GetSize() )
{
patchMesh_t *pPatch = reinterpret_cast<patchMesh_t *>(m_PluginPatches.GetAt(index));
return pPatch;
}
#ifdef _DEBUG
Sys_Printf("WARNING: out of bounds in CPlugInManager::FindPatchHandle\n");
#endif
break;
}
return NULL;
}
LPVOID WINAPI QERApp_CreateBrushHandle()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return g_pParentWnd->GetPlugInMgr().CreateBrushHandle();
}
void WINAPI QERApp_DeleteBrushHandle(LPVOID vp)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
g_pParentWnd->GetPlugInMgr().DeleteBrushHandle(vp);
}
void WINAPI QERApp_CommitBrushHandleToMap(LPVOID vp)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
g_pParentWnd->GetPlugInMgr().CommitBrushHandleToMap(vp);
}
void WINAPI QERApp_AddFace(LPVOID vp, vec3_t v1, vec3_t v2, vec3_t v3)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
g_pParentWnd->GetPlugInMgr().AddFaceToBrushHandle(vp, v1, v2, v3);
}
void WINAPI QERApp_DeleteSelection()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
Select_Delete();
}
void WINAPI QERApp_SysMsg(LPCSTR pMsg)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString str = pMsg;
Sys_Printf(str.GetBuffer(0));
}
// NOTE: called only in case of plugin error. We can try a plugin refresh instead of a straight crash ?
void WINAPI QERApp_ErrorMsg(LPCSTR pMsg)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString str = pMsg;
Error(str.GetBuffer(0));
}
void WINAPI QERApp_InfoMsg(LPCSTR pMsg)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ShowInfoDialog(pMsg);
}
void WINAPI QERApp_HideInfoMsg()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HideInfoDialog();
}
//=====
//PGM
void WINAPI QERApp_PositionView(vec3_t v1, vec3_t v2)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
g_pParentWnd->ActiveXY()->SetOrigin(v1);
// FIXME - implement this!
Sys_UpdateWindows(W_ALL);
}
//PGM
//=====
//FIXME: this AcquirePath stuff is pretty much a mess and needs cleaned up
bool g_bPlugWait = false;
bool g_bPlugOK = false;
int g_nPlugCount = 0;
void _PlugDone(bool b, int n)
{
g_bPlugWait = false;
g_bPlugOK = b;
g_nPlugCount = n;
}
void WINAPI QERApp_GetPoints(int nMax, _QERPointData *pData, LPCSTR pMsg)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ShowInfoDialog(pMsg);
g_bPlugWait = true;
g_bPlugOK = false;
g_nPlugCount = 0;
// g_nPlugCount=nMax-1;
AcquirePath(nMax, &_PlugDone);
while (g_bPlugWait)
{
MSG msg;
if (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
HideInfoDialog();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?