PlugInManager.cpp (47542B)
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 // PlugInManager.cpp: implementation of the CPlugInManager class. 23 // 24 ////////////////////////////////////////////////////////////////////// 25 26 #include "stdafx.h" 27 #include "io.h" 28 #include "Radiant.h" 29 #include "PlugInManager.h" 30 #include "PlugIn.h" 31 #include "DialogInfo.h" 32 #include "pakstuff.h" 33 34 #ifdef _DEBUG 35 #undef THIS_FILE 36 static char THIS_FILE[]=__FILE__; 37 #define new DEBUG_NEW 38 #endif 39 40 ////////////////////////////////////////////////////////////////////// 41 // Construction/Destruction 42 ////////////////////////////////////////////////////////////////////// 43 44 CPlugInManager::CPlugInManager() 45 { 46 m_pTexturePlug = NULL; 47 m_pSurfaceListPlug = NULL; 48 PatchesMode = EActivePatches; 49 } 50 51 CPlugInManager::~CPlugInManager() 52 { 53 Cleanup(); 54 } 55 56 void CPlugInManager::Init(const char * pPath) 57 { 58 Cleanup(); 59 60 // set some globals 61 g_qeglobals.bSurfacePropertiesPlugin = false; 62 g_qeglobals.bBSPFrontendPlugin = false; 63 64 CString strPath(pPath); 65 strPath += "*.dll"; 66 67 bool bGo = true; 68 69 struct _finddata_t fileinfo; 70 int handle = _findfirst (strPath, &fileinfo); 71 if (handle != -1) 72 { 73 do 74 { 75 strPath.Format("%s\\%s", pPath, fileinfo.name); 76 CPlugIn *pPlug = new CPlugIn(); 77 if (pPlug->load(strPath)) 78 { 79 if(FillFuncTable(pPlug)) // PGM 80 { 81 m_PlugIns.Add(pPlug); 82 83 pPlug->RegisterPluginEntities(); 84 85 // if this thing handles surface properties 86 pPlug->InitSurfacePlugin(); 87 88 // will test and init if it's a BSP frontend 89 pPlug->InitBSPFrontendPlugin(); 90 91 g_pParentWnd->AddPlugInMenuItem(pPlug); 92 93 // if this thing handles textures 94 if (pPlug->getTextureInfo() != NULL) 95 { 96 this->m_pTexturePlug = pPlug; 97 98 // if this is a wad style texture extension, have it load everything now 99 if (pPlug->getTextureInfo()->m_bWadStyle) 100 { 101 CString strPath = ValueForKey(g_qeglobals.d_project_entity, "texturepath"); 102 pPlug->loadTexture(strPath); 103 } 104 } 105 106 if (pPlug->getSurfaceFlags() != NULL) 107 { 108 this->m_pSurfaceListPlug = pPlug; 109 } 110 } 111 else 112 { 113 delete pPlug; // PGM 114 } 115 } 116 else 117 { 118 delete pPlug; 119 } 120 } while (_findnext( handle, &fileinfo ) != -1); 121 _findclose (handle); 122 } 123 124 } 125 126 void CPlugInManager::Cleanup() 127 { 128 int i; 129 for (i = 0; i < m_PlugIns.GetSize(); i++) 130 { 131 CPlugIn *plug = reinterpret_cast<CPlugIn*>(m_PlugIns.GetAt(i)); 132 plug->free(); 133 delete plug; 134 } 135 m_PlugIns.RemoveAll(); 136 137 for (i = 0; i < m_BrushHandles.GetSize(); i++) 138 { 139 brush_t *pb = reinterpret_cast<brush_t*>(m_BrushHandles.GetAt(i)); 140 Brush_Free(pb); 141 } 142 m_BrushHandles.RemoveAll(); 143 144 for (i = 0; i < m_EntityHandles.GetSize(); i++) 145 { 146 entity_t *pe = reinterpret_cast<entity_t*>(m_EntityHandles.GetAt(i)); 147 Entity_Free(pe); 148 } 149 m_EntityHandles.RemoveAll(); 150 151 // patches 152 // these are linked into the map 153 m_PatchesHandles.RemoveAll(); 154 // these patches were allocated by Radiant on plugin request 155 // if the list is not empty, it means either the plugin asked for allocation and never commited them to the map 156 // in which case we are supposed to delete them 157 // or it commited them but never called m_pfnReleasePatchHandles, in case the patches may have already been 158 // erased and we are trying a second time, therefore crashing .. 159 //++timo FIXME: for now I leave a leak warning, we'd need a table to keep track of commited patches 160 #ifdef _DEBUG 161 if (m_PluginPatches.GetSize() != 0) 162 Sys_Printf("WARNING: m_PluginPatches.GetSize() != 0 in CPlugInManager::Cleanup, possible leak\n"); 163 #endif 164 /* for (i = 0; i < m_PluginPatches.GetSize(); i++) 165 { 166 patchMesh_t *pMesh = reinterpret_cast<patchMesh_t*>(m_PluginPatches.GetAt(i)); 167 if (pMesh->pSymbiot) 168 delete pMesh; 169 } 170 m_PluginPatches.RemoveAll(); */ 171 } 172 173 void CPlugInManager::Dispatch(int n, const char * p) 174 { 175 for (int i = 0; i < m_PlugIns.GetSize(); i++) 176 { 177 CPlugIn *plug = reinterpret_cast<CPlugIn*>(m_PlugIns.GetAt(i)); 178 if (plug->ownsCommandID(n)) 179 { 180 vec3_t vMin, vMax; 181 if (selected_brushes.next == &selected_brushes) 182 { 183 vMin[0] = vMin[1] = vMin[2] = 0; 184 VectorCopy(vMin, vMax); 185 } 186 else 187 { 188 Select_GetBounds (vMin, vMax); 189 } 190 plug->dispatchCommand(p, vMin, vMax, QE_SingleBrush(true)); // PGM -- added quiet 191 break; 192 } 193 } 194 } 195 196 // creates a dummy brush in the active brushes list 197 // FIXME : is this one really USED ? 198 void WINAPI QERApp_CreateBrush(vec3_t vMin, vec3_t vMax) 199 { 200 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 201 202 brush_t* pBrush = Brush_Create(vMin, vMax, &g_qeglobals.d_texturewin.texdef); 203 Entity_LinkBrush (world_entity, pBrush); 204 Brush_Build(pBrush); 205 Brush_AddToList (pBrush, &active_brushes); 206 Select_Brush(pBrush); 207 Sys_UpdateWindows(W_ALL); 208 } 209 210 LPVOID CPlugInManager::CreateBrushHandle() 211 { 212 brush_t *pb = Brush_Alloc(); 213 pb->numberId = g_nBrushId++; 214 m_BrushHandles.Add(pb); 215 return (LPVOID)pb; 216 } 217 218 void CPlugInManager::DeleteBrushHandle(void * vp) 219 { 220 CPtrArray* pHandles[3]; 221 pHandles[0] = &m_SelectedBrushHandles; 222 pHandles[1] = &m_ActiveBrushHandles; 223 pHandles[2] = &m_BrushHandles; 224 225 for (int j = 0; j < 3; j++) 226 { 227 for (int i = 0; i < pHandles[j]->GetSize(); i++) 228 { 229 brush_t *pb = reinterpret_cast<brush_t*>(pHandles[j]->GetAt(i)); 230 if (pb == reinterpret_cast<brush_t*>(vp)) 231 { 232 if (j == 2) 233 { 234 // only remove it from the list if it is work area 235 // this allows the selected and active list indexes to remain constant 236 // throughout a session (i.e. between an allocate and release) 237 pHandles[j]->RemoveAt(i); 238 } 239 Brush_Free(pb); 240 Sys_MarkMapModified(); // PGM 241 return; 242 } 243 } 244 } 245 } 246 247 void CPlugInManager::CommitBrushHandleToMap(void * vp) 248 { 249 g_bScreenUpdates = false; 250 for (int i = 0; i < m_BrushHandles.GetSize(); i++) 251 { 252 brush_t *pb = reinterpret_cast<brush_t*>(m_BrushHandles.GetAt(i)); 253 if (pb == reinterpret_cast<brush_t*>(vp)) 254 { 255 m_BrushHandles.RemoveAt(i); 256 Entity_LinkBrush (world_entity, pb); 257 Brush_Build(pb); 258 Brush_AddToList (pb, &active_brushes); 259 Select_Brush(pb); 260 } 261 } 262 g_bScreenUpdates = true; 263 Sys_UpdateWindows(W_ALL); 264 } 265 266 void CPlugInManager::AddFaceToBrushHandle(void * vp, vec3_t v1, vec3_t v2, vec3_t v3) 267 { 268 brush_t *bp = FindBrushHandle(vp); 269 if (bp != NULL) 270 { 271 face_t *f = Face_Alloc(); 272 f->texdef = g_qeglobals.d_texturewin.texdef; 273 f->texdef.flags &= ~SURF_KEEP; 274 f->texdef.contents &= ~CONTENTS_KEEP; 275 f->next = bp->brush_faces; 276 bp->brush_faces = f; 277 VectorCopy (v1, f->planepts[0]); 278 VectorCopy (v2, f->planepts[1]); 279 VectorCopy (v3, f->planepts[2]); 280 } 281 } 282 283 brush_t* CPlugInManager::FindBrushHandle(void * vp) 284 { 285 CPtrArray* pHandles[4]; 286 pHandles[0] = &m_SelectedBrushHandles; 287 pHandles[1] = &m_ActiveBrushHandles; 288 pHandles[2] = &m_BrushHandles; 289 pHandles[3] = &m_EntityBrushHandles; 290 291 for (int j = 0; j < 4; j++) 292 { 293 for (int i = 0; i < pHandles[j]->GetSize(); i++) 294 { 295 brush_t *pb = reinterpret_cast<brush_t*>(pHandles[j]->GetAt(i)); 296 if (pb == reinterpret_cast<brush_t*>(vp)) 297 { 298 return pb; 299 } 300 } 301 } 302 return NULL; 303 } 304 305 patchMesh_t* CPlugInManager::FindPatchHandle(int index) 306 { 307 switch (PatchesMode) 308 { 309 case EActivePatches: 310 case ESelectedPatches: 311 if ( index < m_PatchesHandles.GetSize() ) 312 { 313 brush_t *pb = reinterpret_cast<brush_t *>(m_PatchesHandles.GetAt(index)); 314 return pb->pPatch; 315 } 316 #ifdef _DEBUG 317 Sys_Printf("WARNING: out of bounds in CPlugInManager::FindPatchHandle\n"); 318 #endif 319 break; 320 case EAllocatedPatches: 321 if ( index < m_PluginPatches.GetSize() ) 322 { 323 patchMesh_t *pPatch = reinterpret_cast<patchMesh_t *>(m_PluginPatches.GetAt(index)); 324 return pPatch; 325 } 326 #ifdef _DEBUG 327 Sys_Printf("WARNING: out of bounds in CPlugInManager::FindPatchHandle\n"); 328 #endif 329 break; 330 } 331 return NULL; 332 } 333 334 LPVOID WINAPI QERApp_CreateBrushHandle() 335 { 336 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 337 return g_pParentWnd->GetPlugInMgr().CreateBrushHandle(); 338 } 339 340 void WINAPI QERApp_DeleteBrushHandle(LPVOID vp) 341 { 342 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 343 g_pParentWnd->GetPlugInMgr().DeleteBrushHandle(vp); 344 } 345 346 void WINAPI QERApp_CommitBrushHandleToMap(LPVOID vp) 347 { 348 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 349 g_pParentWnd->GetPlugInMgr().CommitBrushHandleToMap(vp); 350 } 351 352 void WINAPI QERApp_AddFace(LPVOID vp, vec3_t v1, vec3_t v2, vec3_t v3) 353 { 354 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 355 g_pParentWnd->GetPlugInMgr().AddFaceToBrushHandle(vp, v1, v2, v3); 356 } 357 358 void WINAPI QERApp_DeleteSelection() 359 { 360 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 361 Select_Delete(); 362 } 363 364 void WINAPI QERApp_SysMsg(LPCSTR pMsg) 365 { 366 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 367 CString str = pMsg; 368 Sys_Printf(str.GetBuffer(0)); 369 } 370 371 // NOTE: called only in case of plugin error. We can try a plugin refresh instead of a straight crash ? 372 void WINAPI QERApp_ErrorMsg(LPCSTR pMsg) 373 { 374 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 375 CString str = pMsg; 376 Error(str.GetBuffer(0)); 377 } 378 379 void WINAPI QERApp_InfoMsg(LPCSTR pMsg) 380 { 381 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 382 ShowInfoDialog(pMsg); 383 } 384 385 void WINAPI QERApp_HideInfoMsg() 386 { 387 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 388 HideInfoDialog(); 389 } 390 391 //===== 392 //PGM 393 void WINAPI QERApp_PositionView(vec3_t v1, vec3_t v2) 394 { 395 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 396 g_pParentWnd->ActiveXY()->SetOrigin(v1); 397 // FIXME - implement this! 398 Sys_UpdateWindows(W_ALL); 399 } 400 //PGM 401 //===== 402 403 //FIXME: this AcquirePath stuff is pretty much a mess and needs cleaned up 404 bool g_bPlugWait = false; 405 bool g_bPlugOK = false; 406 int g_nPlugCount = 0; 407 408 void _PlugDone(bool b, int n) 409 { 410 g_bPlugWait = false; 411 g_bPlugOK = b; 412 g_nPlugCount = n; 413 } 414 415 void WINAPI QERApp_GetPoints(int nMax, _QERPointData *pData, LPCSTR pMsg) 416 { 417 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 418 ShowInfoDialog(pMsg); 419 g_bPlugWait = true; 420 g_bPlugOK = false; 421 g_nPlugCount = 0; 422 // g_nPlugCount=nMax-1; 423 AcquirePath(nMax, &_PlugDone); 424 while (g_bPlugWait) 425 { 426 MSG msg; 427 if (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )) 428 { 429 TranslateMessage(&msg); 430 DispatchMessage(&msg); 431 } 432 } 433 HideInfoDialog(); 434 435 pData->m_nCount = 0; 436 pData->m_pVectors = NULL; 437 438 if (g_bPlugOK && g_nPlugCount > 0) 439 { 440 pData->m_nCount = g_nPlugCount; 441 pData->m_pVectors = reinterpret_cast<vec3_t*>(qmalloc(g_nPlugCount * sizeof(vec3_t))); 442 vec3_t *pOut = pData->m_pVectors; 443 for (int i = 0; i < g_nPlugCount; i++) 444 { 445 memcpy(pOut, &g_PathPoints[i],sizeof(vec3_t)); 446 pOut++; 447 } 448 } 449 } 450 451 void WINAPI QERApp_AddFaceData(LPVOID pv, _QERFaceData *pData) 452 { 453 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 454 455 brush_t* pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); 456 if (pBrush != NULL) 457 { 458 face_t *f = Face_Alloc(); 459 f->texdef = g_qeglobals.d_texturewin.texdef; 460 f->texdef.flags = pData->m_nFlags; 461 f->texdef.contents = pData->m_nContents; 462 f->texdef.value = pData->m_nValue; 463 f->texdef.rotate = pData->m_fRotate; 464 f->texdef.shift[0] = pData->m_fShift[0]; 465 f->texdef.shift[1] = pData->m_fShift[1]; 466 f->texdef.scale[0] = pData->m_fScale[0]; 467 f->texdef.scale[1] = pData->m_fScale[1]; 468 //strcpy(f->texdef.name, pData->m_TextureName); 469 f->texdef.SetName(pData->m_TextureName); 470 f->next = pBrush->brush_faces; 471 pBrush->brush_faces = f; 472 VectorCopy (pData->m_v1, f->planepts[0]); 473 VectorCopy (pData->m_v2, f->planepts[1]); 474 VectorCopy (pData->m_v3, f->planepts[2]); 475 Sys_MarkMapModified(); // PGM 476 } 477 } 478 479 int WINAPI QERApp_GetFaceCount(LPVOID pv) 480 { 481 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 482 int n = 0; 483 brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); 484 if (pBrush != NULL) 485 { 486 for (face_t *f = pBrush->brush_faces ; f; f = f->next) 487 { 488 n++; 489 } 490 } 491 return n; 492 } 493 494 _QERFaceData* WINAPI QERApp_GetFaceData(LPVOID pv, int nFaceIndex) 495 { 496 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 497 static _QERFaceData face; 498 int n = 0; 499 brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); 500 501 if (pBrush != NULL) 502 { 503 for (face_t *f = pBrush->brush_faces ; f; f = f->next) 504 { 505 506 #ifdef _DEBUG 507 if (!pBrush->brush_faces) 508 { 509 Sys_Printf( "Warning : pBrush->brush_faces is NULL in QERApp_GetFaceData\n" ); 510 return NULL; 511 } 512 #endif 513 514 if (n == nFaceIndex) 515 { 516 face.m_nContents = f->texdef.contents; 517 face.m_nFlags = f->texdef.flags; 518 face.m_fRotate = f->texdef.rotate; 519 face.m_fScale[0] = f->texdef.scale[0]; 520 face.m_fScale[1] = f->texdef.scale[1]; 521 face.m_fShift[0] = f->texdef.shift[0]; 522 face.m_fShift[1] = f->texdef.shift[1]; 523 face.m_nValue = f->texdef.value; 524 strcpy(face.m_TextureName, f->texdef.name); 525 VectorCopy(f->planepts[0], face.m_v1); 526 VectorCopy(f->planepts[1], face.m_v2); 527 VectorCopy(f->planepts[2], face.m_v3); 528 return &face; 529 } 530 n++; 531 } 532 } 533 return NULL; 534 } 535 536 void WINAPI QERApp_SetFaceData(LPVOID pv, int nFaceIndex, _QERFaceData *pData) 537 { 538 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 539 int n = 0; 540 brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); 541 542 if (pBrush != NULL) 543 { 544 for (face_t *f = pBrush->brush_faces ; f; f = f->next) 545 { 546 if (n == nFaceIndex) 547 { 548 f->texdef.flags = pData->m_nFlags; 549 f->texdef.contents = pData->m_nContents; 550 f->texdef.value = pData->m_nValue; 551 f->texdef.rotate = pData->m_fRotate; 552 f->texdef.shift[0] = pData->m_fShift[0]; 553 f->texdef.shift[1] = pData->m_fShift[1]; 554 f->texdef.scale[0] = pData->m_fScale[0]; 555 f->texdef.scale[1] = pData->m_fScale[1]; 556 //strcpy(f->texdef.name, pData->m_TextureName); 557 f->texdef.SetName(pData->m_TextureName); 558 VectorCopy(pData->m_v1, f->planepts[0]); 559 VectorCopy(pData->m_v2, f->planepts[1]); 560 VectorCopy(pData->m_v3, f->planepts[2]); 561 Sys_MarkMapModified(); // PGM 562 return; // PGM 563 } 564 n++; 565 } 566 } 567 } 568 569 void WINAPI QERApp_DeleteFace(LPVOID pv, int nFaceIndex) 570 { 571 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 572 int n = 0; 573 brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); 574 if (pBrush != NULL) 575 { 576 face_t *pPrev = pBrush->brush_faces; 577 for (face_t *f = pBrush->brush_faces; f; f = f->next) 578 { 579 if (n == nFaceIndex) 580 { 581 pPrev->next = f->next; 582 Face_Free (f); 583 Sys_MarkMapModified(); // PGM 584 return; 585 } 586 n++; 587 pPrev = f; 588 } 589 } 590 } 591 592 //========== 593 //PGM 594 void WINAPI QERApp_BuildBrush (LPVOID pv) 595 { 596 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 597 brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); 598 if (pBrush != NULL) 599 { 600 Brush_Build(pBrush); 601 Sys_UpdateWindows(W_ALL); 602 } 603 } 604 605 //Timo : another version with bConvert flag 606 //++timo since 1.7 is not compatible with earlier plugin versions, remove this one and update QERApp_BuildBrush 607 void WINAPI QERApp_BuildBrush2 (LPVOID pv, int bConvert) 608 { 609 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 610 brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); 611 if (pBrush != NULL) 612 { 613 Brush_Build( pBrush, true, true, bConvert ); 614 Sys_UpdateWindows(W_ALL); 615 } 616 } 617 618 void WINAPI QERApp_SelectBrush (LPVOID pv) 619 { 620 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 621 brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); 622 if (pBrush != NULL) 623 { 624 Select_Brush(pBrush, false); 625 Sys_UpdateWindows(W_ALL); 626 } 627 628 } 629 630 void WINAPI QERApp_DeselectBrush (LPVOID pv) 631 { 632 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 633 // FIXME - implement this! 634 } 635 636 void WINAPI QERApp_ResetPlugins() 637 { 638 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 639 g_pParentWnd->OnPluginsRefresh(); 640 } 641 642 void WINAPI QERApp_DeselectAllBrushes () 643 { 644 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 645 Select_Deselect(); 646 Sys_UpdateWindows(W_ALL); 647 } 648 //PGM 649 //========== 650 651 void WINAPI QERApp_TextureBrush(LPVOID pv, LPCSTR pName) 652 { 653 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 654 brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); 655 if (pBrush != NULL) 656 { 657 for (face_t *f = pBrush->brush_faces ; f; f = f->next) 658 { 659 //strcpy(f->texdef.name, pName); 660 f->texdef.SetName(pName); 661 } 662 Sys_MarkMapModified(); // PGM 663 } 664 } 665 666 int WINAPI QERApp_SelectedBrushCount() 667 { 668 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 669 int n = 0; 670 for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next) 671 { 672 n++; 673 } 674 return n; 675 } 676 677 int WINAPI QERApp_ActiveBrushCount() 678 { 679 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 680 int n = 0; 681 for (brush_t *pb = active_brushes.next ; pb != &active_brushes ; pb = pb->next) 682 { 683 n++; 684 } 685 return n; 686 } 687 688 int WINAPI QERApp_AllocateSelectedBrushHandles() 689 { 690 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 691 int n = 0; 692 for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next) 693 { 694 n++; 695 g_pParentWnd->GetPlugInMgr().GetSelectedHandles().Add(pb); 696 } 697 return n; 698 } 699 700 int WINAPI QERApp_AllocateActiveBrushHandles() 701 { 702 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 703 int n = 0; 704 for (brush_t *pb = active_brushes.next ; pb != &active_brushes ; pb = pb->next) 705 { 706 n++; 707 g_pParentWnd->GetPlugInMgr().GetActiveHandles().Add(pb); 708 } 709 return n; 710 } 711 712 void WINAPI QERApp_ReleaseSelectedBrushHandles() 713 { 714 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 715 g_pParentWnd->GetPlugInMgr().GetSelectedHandles().RemoveAll(); 716 Sys_UpdateWindows(W_ALL); 717 } 718 719 void WINAPI QERApp_ReleaseActiveBrushHandles() 720 { 721 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 722 g_pParentWnd->GetPlugInMgr().GetActiveHandles().RemoveAll(); 723 Sys_UpdateWindows(W_ALL); 724 } 725 726 LPVOID WINAPI QERApp_GetActiveBrushHandle(int nIndex) 727 { 728 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 729 if (nIndex < g_pParentWnd->GetPlugInMgr().GetActiveHandles().GetSize()) 730 { 731 return reinterpret_cast<LPVOID>(g_pParentWnd->GetPlugInMgr().GetActiveHandles().GetAt(nIndex)); 732 } 733 return NULL; 734 } 735 736 LPVOID WINAPI QERApp_GetSelectedBrushHandle(int nIndex) 737 { 738 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 739 if (nIndex < g_pParentWnd->GetPlugInMgr().GetSelectedHandles().GetSize()) 740 { 741 return reinterpret_cast<LPVOID>(g_pParentWnd->GetPlugInMgr().GetSelectedHandles().GetAt(nIndex)); 742 } 743 return NULL; 744 } 745 746 int WINAPI QERApp_TextureCount() 747 { 748 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 749 Texture_StartPos (); 750 int x, y; 751 int n = 0; 752 while (1) 753 { 754 qtexture_t *q = Texture_NextPos (&x, &y); 755 if (!q) 756 break; 757 n++; 758 } 759 return n; 760 } 761 762 LPCSTR WINAPI QERApp_GetTexture(int nIndex) 763 { 764 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 765 static char name[QER_MAX_NAMELEN]; 766 Texture_StartPos (); 767 int x, y; 768 int n = 0; 769 while (1) 770 { 771 qtexture_t *q = Texture_NextPos (&x, &y); 772 if (!q) 773 break; 774 if (n == nIndex) 775 { 776 strcpy(name, q->name); 777 return name; 778 } 779 n++; 780 } 781 return NULL; 782 } 783 784 LPCSTR WINAPI QERApp_GetCurrentTexture() 785 { 786 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 787 return g_qeglobals.d_texturewin.texdef.name; 788 } 789 790 void WINAPI QERApp_SetCurrentTexture(LPCSTR strName) 791 { 792 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 793 //++timo hu ?? tex is not initialized ?? can be any value .. 794 texdef_t tex; 795 //++timo added a brushprimit_texdef .. 796 // smthg to be done here 797 brushprimit_texdef_t brushprimit_tex; 798 //strcpy(tex.name, strName); 799 tex.SetName(strName); 800 Texture_SetTexture(&tex,&brushprimit_tex); 801 } 802 803 int WINAPI QERApp_GetEClassCount() 804 { 805 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 806 int n = 0; 807 for (eclass_t *e = eclass ; e ; e = e->next) 808 { 809 n++; 810 } 811 return n; 812 } 813 814 LPCSTR WINAPI QERApp_GetEClass(int nIndex) 815 { 816 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 817 int n = 0; 818 for (eclass_t *e = eclass ; e ; e = e->next) 819 { 820 if (n == nIndex) 821 { 822 return e->name; 823 } 824 } 825 return NULL; 826 } 827 828 void WINAPI QERApp_LoadTextureRGBA(LPVOID vp) 829 { 830 Texture_LoadFromPlugIn(vp); 831 } 832 833 // v1.70 code 834 // world_entity holds the worldspawn and is indexed as 0 835 // other entities are in the entities doubly linked list 836 // QERApp_GetEntityCount counts the entities like in any C array: [0..length-1] 837 int WINAPI QERApp_GetEntityCount() 838 { 839 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 840 int n = 1; 841 for (entity_t *pe = entities.next ; pe != &entities ; pe = pe->next) 842 { 843 n++; 844 } 845 return n; 846 } 847 848 // We don't store entities in CPtrArray, we need to walk the list 849 LPVOID WINAPI QERApp_GetEntityHandle(int nIndex) 850 { 851 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 852 if (nIndex==0) 853 // looks for the worldspawn 854 return static_cast<LPVOID>(world_entity); 855 entity_t *pe = &entities; 856 int n = 0; 857 while ( n < nIndex ) 858 { 859 pe = pe->next; 860 n++; 861 } 862 return static_cast<LPVOID>(pe); 863 } 864 865 epair_t** WINAPI QERApp_GetEntityKeyValList(LPVOID vp) 866 { 867 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 868 entity_t *pe = static_cast<entity_t *>(vp); 869 return &pe->epairs; 870 } 871 872 epair_t* WINAPI QERApp_AllocateEpair( char *key, char *val ) 873 { 874 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 875 epair_t *e = (epair_t*)qmalloc (sizeof(*e)); 876 e->key = (char*)qmalloc(strlen(key)+1); 877 strcpy (e->key, key); 878 e->value = (char*)qmalloc(strlen(val)+1); 879 strcpy (e->value, val); 880 return e; 881 } 882 883 void WINAPI QERApp_SetEntityKeyValList(LPVOID vp, epair_t* ep) 884 { 885 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 886 entity_t *pe = static_cast<entity_t *>(vp); 887 if (pe->epairs) 888 Sys_Printf( "Warning : pe->epairs != NULL in QERApp_SetEntityKeyValList, will not set\n" ); 889 else 890 pe->epairs = ep; 891 } 892 893 int WINAPI QERApp_AllocateEntityBrushHandles(LPVOID vp) 894 { 895 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 896 entity_t *pe = static_cast<entity_t *>(vp); 897 int n = 0; 898 if (!pe->brushes.onext) 899 return 0; 900 g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().RemoveAll(); 901 for (brush_t *pb = pe->brushes.onext ; pb != &pe->brushes ; pb=pb->onext) 902 { 903 n++; 904 g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().Add(pb); 905 } 906 return n; 907 } 908 909 void WINAPI QERApp_ReleaseEntityBrushHandles() 910 { 911 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 912 g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().RemoveAll(); 913 } 914 915 LPVOID WINAPI QERApp_GetEntityBrushHandle(int nIndex) 916 { 917 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 918 if (nIndex < g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().GetSize()) 919 return g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().GetAt(nIndex); 920 return NULL; 921 } 922 923 LPVOID WINAPI QERApp_CreateEntityHandle() 924 { 925 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 926 entity_t *pe = reinterpret_cast<entity_t*>(qmalloc(sizeof(entity_t))); 927 pe->brushes.onext = pe->brushes.oprev = &pe->brushes; 928 g_pParentWnd->GetPlugInMgr().GetEntityHandles().Add(static_cast<LPVOID>(pe)); 929 return static_cast<LPVOID>(pe); 930 } 931 932 // the vpBrush needs to be in m_BrushHandles 933 //++timo we don't have allocation nor storage for vpEntity, no checks for this one 934 void WINAPI QERApp_CommitBrushHandleToEntity(LPVOID vpBrush, LPVOID vpEntity) 935 { 936 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 937 g_pParentWnd->GetPlugInMgr().CommitBrushHandleToEntity(vpBrush, vpEntity); 938 return; 939 } 940 941 char* WINAPI QERApp_ReadProjectKey(char* key) 942 { 943 return ValueForKey(g_qeglobals.d_project_entity, key); 944 } 945 946 int WINAPI QERApp_ScanFileForEClass(char *filename ) 947 { 948 // set single class parsing 949 parsing_single = true; 950 Eclass_ScanFile(filename); 951 if (eclass_found) 952 { 953 eclass_e->nShowFlags |= ECLASS_PLUGINENTITY; 954 return 1; 955 } 956 return 0; 957 } 958 959 // the vpBrush needs to be in m_BrushHandles 960 //++timo add a debug check to see if we found the brush handle 961 // NOTE : seems there's no way to check vpEntity is valid .. this is dangerous 962 // links the brush to its entity, everything else is done when commiting the entity to the map 963 void CPlugInManager::CommitBrushHandleToEntity(LPVOID vpBrush, LPVOID vpEntity) 964 { 965 brush_t* pb; 966 entity_t* pe; 967 for (int i=0 ; i < m_BrushHandles.GetSize() ; i++) 968 { 969 if (vpBrush == m_BrushHandles.GetAt(i)) 970 { 971 m_BrushHandles.RemoveAt(i); 972 pb = reinterpret_cast<brush_t*>(vpBrush); 973 pe = reinterpret_cast<entity_t *>(vpEntity); 974 Entity_LinkBrush (pe, pb); 975 } 976 } 977 Sys_UpdateWindows(W_ALL); 978 } 979 980 // the vpEntity must be in m_EntityHandles 981 void WINAPI QERApp_CommitEntityHandleToMap(LPVOID vpEntity) 982 { 983 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 984 g_pParentWnd->GetPlugInMgr().CommitEntityHandleToMap(vpEntity); 985 return; 986 } 987 988 int WINAPI QERApp_LoadFile( const char *pLocation, void ** buffer ) 989 { 990 char cPath[1024]; 991 sprintf( cPath, "%s/%s", ValueForKey(g_qeglobals.d_project_entity, "basepath"), pLocation); 992 int nSize = LoadFile( cPath, buffer); 993 if (nSize == -1) 994 { 995 nSize = PakLoadAnyFile(cPath, buffer); 996 } 997 return nSize; 998 } 999 1000 char * WINAPI QERApp_ExpandReletivePath (char *p) 1001 { 1002 return ExpandReletivePath(p); 1003 } 1004 1005 // NOTE: this is a simplified version 1006 int WINAPI QERApp_HasShader( const char *pName ) 1007 { 1008 CShaderInfo *pInfo = hasShader( pName ); 1009 if (pInfo) 1010 return 1; 1011 return 0; 1012 } 1013 1014 qtexture_t* WINAPI QERApp_Texture_ForName (const char *name) 1015 { 1016 // if the texture is not loaded yet, this call will get it loaded 1017 // but: when we assign a GL bind number, we need to be in the g_qeglobals.d_hdcBase , g_qeglobals.d_hglrcBase GL context 1018 // the plugin may set the GL context to whatever he likes, but then load would fail 1019 // NOTE: is context switching time-consuming? then maybe the plugin could handle the context switch and only add a 1020 // sanity check in debug mode here 1021 // read current context 1022 HDC pluginHDC = qwglGetCurrentDC(); 1023 HGLRC pluginHGLRC = qwglGetCurrentContext(); 1024 qwglMakeCurrent( g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase ); 1025 qtexture_t* qtex = Texture_ForName( name ); 1026 return qtex; 1027 qwglMakeCurrent( pluginHDC, pluginHGLRC ); 1028 } 1029 1030 void WINAPI QERApp_RadiantFree( void * buf ) 1031 { 1032 free( buf ); 1033 } 1034 1035 char* WINAPI QERApp_Token() 1036 { 1037 return token; 1038 } 1039 1040 char* WINAPI QERApp_GetMapName() 1041 { 1042 return currentmap; 1043 } 1044 1045 void CPlugInManager::CommitEntityHandleToMap(LPVOID vpEntity) 1046 { 1047 entity_t *pe; 1048 eclass_t *e; 1049 brush_t *b; 1050 vec3_t mins,maxs; 1051 bool has_brushes; 1052 for (int i=0 ; i < m_EntityHandles.GetSize() ; i++ ) 1053 { 1054 if (vpEntity == m_EntityHandles.GetAt(i)) 1055 { 1056 m_EntityHandles.RemoveAt(i); 1057 pe = reinterpret_cast<entity_t*>(vpEntity); 1058 // fill additional fields 1059 // straight copy from Entity_Parse 1060 // entity_t::origin 1061 GetVectorForKey (pe, "origin", pe->origin); 1062 // entity_t::eclass 1063 if (pe->brushes.onext == &pe->brushes) 1064 has_brushes = false; 1065 else 1066 has_brushes = true; 1067 e = Eclass_ForName (ValueForKey (pe, "classname"), has_brushes); 1068 pe->eclass = e; 1069 // fixedsize 1070 if (e->fixedsize) 1071 { 1072 if (pe->brushes.onext != &pe->brushes) 1073 { 1074 Sys_Printf("Warning : Fixed size entity with brushes in CPlugInManager::CommitEntityHandleToMap\n"); 1075 } 1076 // create a custom brush 1077 VectorAdd(e->mins, pe->origin, mins); 1078 VectorAdd(e->maxs, pe->origin, maxs); 1079 float a = 0; 1080 if (e->nShowFlags & ECLASS_MISCMODEL) 1081 { 1082 char* p = ValueForKey(pe, "model"); 1083 if (p != NULL && strlen(p) > 0) 1084 { 1085 vec3_t vMin, vMax; 1086 a = FloatForKey (pe, "angle"); 1087 if (GetCachedModel(pe, p, vMin, vMax)) 1088 { 1089 // create a custom brush 1090 VectorAdd (pe->md3Class->mins, pe->origin, mins); 1091 VectorAdd (pe->md3Class->maxs, pe->origin, maxs); 1092 } 1093 } 1094 } 1095 1096 b = Brush_Create (mins, maxs, &e->texdef); 1097 1098 if (a) 1099 { 1100 vec3_t vAngle; 1101 vAngle[0] = vAngle[1] = 0; 1102 vAngle[2] = a; 1103 Brush_Rotate(b, vAngle, pe->origin, false); 1104 } 1105 1106 b->owner = pe; 1107 1108 b->onext = pe->brushes.onext; 1109 b->oprev = &pe->brushes; 1110 pe->brushes.onext->oprev = b; 1111 pe->brushes.onext = b; 1112 } 1113 else 1114 { // brush entity 1115 if (pe->brushes.next == &pe->brushes) 1116 Sys_Printf ("Warning: Brush entity with no brushes in CPlugInManager::CommitEntityHandleToMap\n"); 1117 } 1118 1119 // add brushes to the active brushes list 1120 // and build them along the way 1121 for (b=pe->brushes.onext ; b != &pe->brushes ; b=b->onext) 1122 { 1123 // convert between old brushes and brush primitive 1124 if (g_qeglobals.m_bBrushPrimitMode) 1125 { 1126 // we only filled the shift scale rot fields, needs conversion 1127 Brush_Build( b, true, true, true ); 1128 } 1129 else 1130 { 1131 // we are using old brushes 1132 Brush_Build( b ); 1133 } 1134 b->next = active_brushes.next; 1135 active_brushes.next->prev = b; 1136 b->prev = &active_brushes; 1137 active_brushes.next = b; 1138 } 1139 1140 // handle worldspawn entities 1141 // if worldspawn has no brushes, use the new one 1142 if (!strcmp(ValueForKey (pe, "classname"), "worldspawn")) 1143 { 1144 if ( world_entity && ( world_entity->brushes.onext != &world_entity->brushes ) ) 1145 { 1146 // worldspawn already has brushes 1147 Sys_Printf ("Commiting worldspawn as func_group\n"); 1148 SetKeyValue(pe, "classname", "func_group"); 1149 // add the entity to the end of the entity list 1150 pe->next = &entities; 1151 pe->prev = entities.prev; 1152 entities.prev->next = pe; 1153 entities.prev = pe; 1154 g_qeglobals.d_num_entities++; 1155 } 1156 else 1157 { 1158 // there's a worldspawn with no brushes, we assume the map is empty 1159 if ( world_entity ) 1160 { 1161 Entity_Free( world_entity ); 1162 world_entity = pe; 1163 } 1164 else 1165 Sys_Printf("Warning : unexpected world_entity == NULL in CommitEntityHandleToMap\n"); 1166 } 1167 } 1168 else 1169 { 1170 // add the entity to the end of the entity list 1171 pe->next = &entities; 1172 pe->prev = entities.prev; 1173 entities.prev->next = pe; 1174 entities.prev = pe; 1175 g_qeglobals.d_num_entities++; 1176 } 1177 } 1178 } 1179 } 1180 1181 void WINAPI QERApp_SetScreenUpdate(int bScreenUpdates) 1182 { 1183 g_bScreenUpdates = bScreenUpdates; 1184 } 1185 1186 texturewin_t* WINAPI QERApp_QeglobalsTexturewin() 1187 { 1188 return &g_qeglobals.d_texturewin; 1189 } 1190 1191 _QERTextureInfo* CPlugInManager::GetTextureInfo() 1192 { 1193 if (m_pTexturePlug != NULL) 1194 { 1195 return m_pTexturePlug->getTextureInfo(); 1196 } 1197 else 1198 { 1199 return NULL; 1200 } 1201 } 1202 1203 LPVOID CPlugInManager::GetSurfaceFlags() 1204 { 1205 if (m_pSurfaceListPlug != NULL) 1206 { 1207 return m_pSurfaceListPlug->getSurfaceFlags(); 1208 } 1209 else 1210 { 1211 return NULL; 1212 } 1213 } 1214 1215 void CPlugInManager::LoadTexture(const char *pFilename) 1216 { 1217 if (m_pTexturePlug != NULL) 1218 { 1219 m_pTexturePlug->loadTexture(pFilename); 1220 } 1221 } 1222 1223 patchMesh_t* WINAPI QERApp_GetSelectedPatch( ) 1224 { 1225 for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next) 1226 { 1227 if (pb->patchBrush) 1228 { 1229 return pb->pPatch; 1230 } 1231 } 1232 #ifdef _DEBUG 1233 Sys_Printf("WARNING: QERApp_GetSelectedPatchTexdef called with no patch selected\n"); 1234 #endif 1235 return NULL; 1236 } 1237 1238 char* WINAPI QERApp_GetGamePath() 1239 { 1240 return g_PrefsDlg.m_strQuake2.GetBuffer(0); 1241 } 1242 1243 char* WINAPI QERApp_GetQERPath() 1244 { 1245 return g_strAppPath.GetBuffer(0); 1246 } 1247 1248 // patches in/out ----------------------------------- 1249 int WINAPI QERApp_AllocateActivePatchHandles() 1250 { 1251 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 1252 return g_pParentWnd->GetPlugInMgr().AllocateActivePatchHandles(); 1253 } 1254 1255 int CPlugInManager::AllocateActivePatchHandles() 1256 { 1257 int n = 0; 1258 for (brush_t *pb = active_brushes.next ; pb != &active_brushes ; pb = pb->next) 1259 { 1260 if (pb->patchBrush) 1261 { 1262 n++; 1263 m_PatchesHandles.Add(pb); 1264 } 1265 } 1266 return n; 1267 } 1268 1269 int WINAPI QERApp_AllocateSelectedPatchHandles() 1270 { 1271 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 1272 return g_pParentWnd->GetPlugInMgr().AllocateSelectedPatchHandles(); 1273 } 1274 1275 int CPlugInManager::AllocateSelectedPatchHandles() 1276 { 1277 int n = 0; 1278 for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next) 1279 { 1280 if (pb->patchBrush) 1281 { 1282 n++; 1283 m_PatchesHandles.Add(pb); 1284 } 1285 } 1286 return n; 1287 } 1288 1289 void WINAPI QERApp_ReleasePatchHandles() 1290 { 1291 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 1292 g_pParentWnd->GetPlugInMgr().ReleasePatchesHandles(); 1293 } 1294 1295 patchMesh_t* WINAPI QERApp_GetPatchData(int index) 1296 { 1297 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 1298 static patchMesh_t patch; 1299 patchMesh_t *pPatch = g_pParentWnd->GetPlugInMgr().FindPatchHandle(index); 1300 if (pPatch) 1301 { 1302 memcpy( &patch, pPatch, sizeof(patchMesh_t) ); 1303 return &patch; 1304 } 1305 return NULL; 1306 } 1307 1308 void WINAPI QERApp_DeletePatch(int index) 1309 { 1310 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 1311 patchMesh_t *pPatch = g_pParentWnd->GetPlugInMgr().FindPatchHandle(index); 1312 if (pPatch) 1313 { 1314 brush_t *pb = pPatch->pSymbiot; 1315 Patch_Delete( pPatch ); 1316 if (pb) 1317 Brush_Free( pb ); 1318 } 1319 #ifdef _DEBUG 1320 Sys_Printf("Warning: QERApp_DeletePatch: FindPatchHandle failed\n"); 1321 #endif 1322 } 1323 1324 int WINAPI QERApp_CreatePatchHandle() 1325 { 1326 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 1327 return g_pParentWnd->GetPlugInMgr().CreatePatchHandle(); 1328 } 1329 1330 int CPlugInManager::CreatePatchHandle() 1331 { 1332 // NOTE: we can't call the AddBrushForPatch until we have filled the patchMesh_t structure 1333 patchMesh_t *pPatch = MakeNewPatch(); 1334 m_PluginPatches.Add( pPatch ); 1335 // change mode 1336 PatchesMode = EAllocatedPatches; 1337 return m_PluginPatches.GetSize()-1; 1338 } 1339 1340 void WINAPI QERApp_CommitPatchHandleToMap(int index, patchMesh_t *pMesh, char *texName) 1341 { 1342 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 1343 g_pParentWnd->GetPlugInMgr().CommitPatchHandleToMap(index, pMesh, texName); 1344 } 1345 1346 void CPlugInManager::CommitPatchHandleToMap(int index, patchMesh_t *pMesh, char *texName) 1347 { 1348 if (PatchesMode==EAllocatedPatches) 1349 { 1350 patchMesh_t *pPatch = reinterpret_cast<patchMesh_t *>( m_PluginPatches.GetAt(index) ); 1351 memcpy( pPatch, pMesh, sizeof( patchMesh_t ) ); 1352 // patch texturing, if none given use current texture 1353 if (texName) 1354 pPatch->d_texture = Texture_ForName(texName); 1355 if ( !pPatch->d_texture ) 1356 { 1357 pPatch->d_texture = Texture_ForName(g_qeglobals.d_texturewin.texdef.name); 1358 // checking .. just in case 1359 if (!pPatch->d_texture) 1360 { 1361 #ifdef _DEBUG 1362 Sys_Printf("WARNING: failed to set patch to current texture in CPlugInManager::CommitPatchHandleToMap\n"); 1363 #endif 1364 pPatch->d_texture = notexture; 1365 } 1366 } 1367 g_bScreenUpdates = false; 1368 // the bLinkToWorld flag in AddBrushForPatch takes care of Brush_AddToList Entity_linkBrush and Brush_Build 1369 brush_t *pb = AddBrushForPatch( pPatch, true ); 1370 Select_Brush( pb ); 1371 g_bScreenUpdates = true; 1372 Sys_UpdateWindows(W_ALL); 1373 } 1374 else 1375 { 1376 brush_t *pBrush = reinterpret_cast<brush_t *>( m_PatchesHandles.GetAt(index) ); 1377 patchMesh_t *pPatch = pBrush->pPatch; 1378 pPatch->width = pMesh->width; 1379 pPatch->height = pMesh->height; 1380 pPatch->contents = pMesh->contents; 1381 pPatch->flags = pMesh->flags; 1382 pPatch->value = pMesh->value; 1383 pPatch->type = pMesh->type; 1384 memcpy( pPatch->ctrl, pMesh->ctrl, sizeof(drawVert_t)*MAX_PATCH_HEIGHT*MAX_PATCH_WIDTH ); 1385 pPatch->bDirty = true; 1386 } 1387 } 1388 1389 // this gets called when the plugin needs specific services, for example the OpenGL drawing interface 1390 //++timo plugins should be able to dynamically register their own interfaces in there 1391 int WINAPI QERApp_RequestInterface( REFGUID refGUID, LPVOID pInterface ) 1392 { 1393 if (IsEqualGUID( refGUID, QERQglTable_GUID )) 1394 { 1395 _QERQglTable *pQglTable = static_cast<_QERQglTable *>(pInterface); 1396 if ( pQglTable->m_nSize != sizeof(_QERQglTable) ) 1397 { 1398 Sys_Printf("wrong m_nSize in plugin-requested _QERQglTable interface\n"); 1399 return 0; 1400 } 1401 pQglTable->m_pfn_qglAlphaFunc = qglAlphaFunc; 1402 pQglTable->m_pfn_qglBegin = qglBegin; 1403 pQglTable->m_pfn_qglBindTexture = qglBindTexture; 1404 pQglTable->m_pfn_qglBlendFunc = qglBlendFunc; 1405 pQglTable->m_pfn_qglCallList = qglCallList; 1406 pQglTable->m_pfn_qglCallLists = qglCallLists; 1407 pQglTable->m_pfn_qglClear = qglClear; 1408 pQglTable->m_pfn_qglClearColor = qglClearColor; 1409 pQglTable->m_pfn_qglClearDepth = qglClearDepth; 1410 pQglTable->m_pfn_qglColor3f = qglColor3f; 1411 pQglTable->m_pfn_qglColor4f = qglColor4f; 1412 pQglTable->m_pfn_qglCullFace = qglCullFace; 1413 pQglTable->m_pfn_qglDisable = qglDisable; 1414 pQglTable->m_pfn_qglDeleteLists = qglDeleteLists; 1415 pQglTable->m_pfn_qglEnable = qglEnable; 1416 pQglTable->m_pfn_qglEnd = qglEnd; 1417 pQglTable->m_pfn_qglEndList = qglEndList; 1418 pQglTable->m_pfn_qglGenLists = qglGenLists; 1419 pQglTable->m_pfn_qglListBase = qglListBase; 1420 pQglTable->m_pfn_qglLoadIdentity = qglLoadIdentity; 1421 pQglTable->m_pfn_qglMatrixMode = qglMatrixMode; 1422 pQglTable->m_pfn_qglNewList = qglNewList; 1423 pQglTable->m_pfn_qglNormal3f = qglNormal3f; 1424 pQglTable->m_pfn_qglOrtho = qglOrtho; 1425 pQglTable->m_pfn_qglPointSize = qglPointSize; 1426 pQglTable->m_pfn_qglPolygonMode = qglPolygonMode; 1427 pQglTable->m_pfn_qglPopMatrix = qglPopMatrix; 1428 pQglTable->m_pfn_qglPushMatrix = qglPushMatrix; 1429 pQglTable->m_pfn_qglRotated = qglRotated; 1430 pQglTable->m_pfn_qglRotatef = qglRotatef; 1431 pQglTable->m_pfn_qglScalef = qglScalef; 1432 pQglTable->m_pfn_qglTexCoord2f = qglTexCoord2f; 1433 pQglTable->m_pfn_qglTexEnvf = qglTexEnvf; 1434 pQglTable->m_pfn_qglTexGenf = qglTexGenf; 1435 pQglTable->m_pfn_qglTexParameterf = qglTexParameterf; 1436 pQglTable->m_pfn_qglTranslated = qglTranslated; 1437 pQglTable->m_pfn_qglTranslatef = qglTranslatef; 1438 pQglTable->m_pfn_qglVertex2f = qglVertex2f; 1439 pQglTable->m_pfn_qglVertex3f = qglVertex3f; 1440 pQglTable->m_pfn_qglViewport = qglViewport; 1441 pQglTable->m_pfn_QE_CheckOpenGLForErrors = &QE_CheckOpenGLForErrors; 1442 pQglTable->m_pfn_QEW_SetupPixelFormat = &QEW_SetupPixelFormat; 1443 pQglTable->m_pfn_qwglCreateContext = qwglCreateContext; 1444 pQglTable->m_pfn_qwglDeleteContext = qwglDeleteContext; 1445 pQglTable->m_pfn_qwglMakeCurrent = qwglMakeCurrent; 1446 pQglTable->m_pfn_qwglShareLists = qwglShareLists; 1447 pQglTable->m_pfn_qwglSwapBuffers = qwglSwapBuffers; 1448 pQglTable->m_pfn_qwglUseFontBitmaps = qwglUseFontBitmaps; 1449 pQglTable->m_pfnGetQeglobalsHGLRC = &QERApp_GetQeglobalsHGLRC; 1450 pQglTable->m_pfn_qgluPerspective = qgluPerspective; 1451 pQglTable->m_pfn_qgluLookAt = qgluLookAt; 1452 pQglTable->m_pfnHookXYGLWindow = QERApp_HookXYGLWindow; 1453 pQglTable->m_pfnUnHookGLWindow = QERApp_UnHookGLWindow; 1454 1455 return 1; 1456 } 1457 else if (IsEqualGUID( refGUID, QERSelectedFaceTable_GUID )) 1458 { 1459 _QERSelectedFaceTable *pSelectedFaceTable = static_cast<_QERSelectedFaceTable *>(pInterface); 1460 if ( pSelectedFaceTable->m_nSize != sizeof(_QERSelectedFaceTable) ) 1461 { 1462 Sys_Printf("wrong m_nSize in plugin-requested _QERSelectedFaceTable interface\n"); 1463 return 0; 1464 } 1465 pSelectedFaceTable->m_pfnGetTextureNumber = &QERApp_ISelectedFace_GetTextureNumber; 1466 pSelectedFaceTable->m_pfnGetFaceInfo = &QERApp_GetFaceInfo; 1467 pSelectedFaceTable->m_pfnSetFaceInfo = &QERApp_SetFaceInfo; 1468 pSelectedFaceTable->m_pfnGetTextureSize = &QERApp_GetTextureSize; 1469 pSelectedFaceTable->m_pfnTextureForName = &QERApp_Texture_ForName; 1470 pSelectedFaceTable->m_pfnSelect_SetTexture = &Select_SetTexture; 1471 return 1; 1472 } 1473 else if (IsEqualGUID( refGUID, QERPluginEntitiesTable_GUID )) 1474 { 1475 _QERPluginEntitiesTable *pPluginEntitiesTable = static_cast<_QERPluginEntitiesTable *>(pInterface); 1476 if ( pPluginEntitiesTable->m_nSize != sizeof(_QERPluginEntitiesTable) ) 1477 { 1478 Sys_Printf("wrong m_nSize in plugin-requested _QERPluginEntitiesTable interface\n"); 1479 return 0; 1480 } 1481 pPluginEntitiesTable->m_pfnEClassScanDir = &QERApp_EClassScanDir; 1482 return 1; 1483 } 1484 else if (IsEqualGUID( refGUID, QERScripLibTable_GUID )) 1485 { 1486 _QERScripLibTable *pScripLibTable = static_cast<_QERScripLibTable *>(pInterface); 1487 if ( pScripLibTable->m_nSize != sizeof( _QERScripLibTable ) ) 1488 { 1489 Sys_Printf("wrong m_nSize in plugin-requested _QERScripLibTable\n"); 1490 return 0; 1491 } 1492 pScripLibTable->m_pfnGetToken = &GetToken; 1493 pScripLibTable->m_pfnToken = &QERApp_Token; 1494 pScripLibTable->m_pfnUnGetToken = &UngetToken; 1495 return 1; 1496 } 1497 else if (IsEqualGUID( refGUID, QERAppSurfaceTable_GUID )) 1498 { 1499 _QERAppSurfaceTable *pSurfaceTable = static_cast<_QERAppSurfaceTable *>(pInterface); 1500 if ( pSurfaceTable->m_nSize != sizeof( _QERAppSurfaceTable ) ) 1501 { 1502 Sys_Printf("wrong m_nSize in plugin-requested _QERAppSurfaceTable\n"); 1503 return 0; 1504 } 1505 pSurfaceTable->m_pfnAnyPatchesSelected = &AnyPatchesSelected; 1506 pSurfaceTable->m_pfnOnlyPatchesSelected = &OnlyPatchesSelected; 1507 pSurfaceTable->m_pfnQeglobalsTexturewin = &QERApp_QeglobalsTexturewin; 1508 pSurfaceTable->m_pfnGetSelectedPatch = &QERApp_GetSelectedPatch; 1509 pSurfaceTable->m_pfnPatchRebuild = &Patch_Rebuild; 1510 pSurfaceTable->m_pfnGetTwoSelectedPatch = &QERApp_GetTwoSelectedPatch; 1511 return 1; 1512 } 1513 else if (IsEqualGUID( refGUID, QERAppBSPFrontendTable_GUID )) 1514 { 1515 _QERAppBSPFrontendTable *pBSPFrontendTable = static_cast<_QERAppBSPFrontendTable *>(pInterface); 1516 if ( pBSPFrontendTable->m_nSize != sizeof( _QERAppBSPFrontendTable ) ) 1517 { 1518 Sys_Printf("wrong m_nSize in plugin-requested _QERAppBSPFrontendTable\n"); 1519 return 0; 1520 } 1521 pBSPFrontendTable->m_pfnGetMapName = &QERApp_GetMapName; 1522 pBSPFrontendTable->m_pfnLoadPointFile = &Pointfile_Check; 1523 return 1; 1524 } 1525 else if (IsEqualGUID( refGUID, QERMessaging_GUID )) 1526 { 1527 _QERMessagingTable *pMessagingTable = static_cast<_QERMessagingTable *>(pInterface); 1528 if ( pMessagingTable->m_nSize != sizeof( _QERMessagingTable ) ) 1529 { 1530 Sys_Printf("wrong m_nSize in plugin-requested _QERMessagingTable\n"); 1531 return 0; 1532 } 1533 pMessagingTable->m_pfnHookWindow = QERApp_HookWindow; 1534 pMessagingTable->m_pfnUnHookWindow = QERApp_UnHookWindow; 1535 pMessagingTable->m_pfnGetXYWndWrapper = QERApp_GetXYWndWrapper; 1536 pMessagingTable->m_pfnHookListener = QERApp_HookListener; 1537 pMessagingTable->m_pfnUnHookListener = QERApp_UnHookListener; 1538 return 1; 1539 } 1540 else if (IsEqualGUID( refGUID, QERShadersTable_GUID )) 1541 { 1542 _QERShadersTable *pShadersTable = static_cast<_QERShadersTable *>(pInterface); 1543 if ( pShadersTable->m_nSize != sizeof( _QERShadersTable ) ) 1544 { 1545 Sys_Printf("wring m_nSize in plugin-requested _QERShadersTable\n"); 1546 return 0; 1547 } 1548 pShadersTable->m_pfnTryTextureForName = QERApp_TryTextureForName; 1549 return 1; 1550 } 1551 return 0; 1552 } 1553 1554 int CPlugInManager::FillFuncTable(CPlugIn *pPlug) 1555 { 1556 _QERFuncTable_1 *pTable = reinterpret_cast<_QERFuncTable_1*>(pPlug->getFuncTable()); 1557 if (pTable != NULL) 1558 { 1559 if (pTable->m_fVersion != QER_PLUG_VERSION) 1560 { 1561 Sys_Printf("Radiant plugin manager was built with version %.2f, Plugin %s is version %.2f\n", QER_PLUG_VERSION, pPlug->getVersionStr() , pTable->m_fVersion); 1562 } 1563 if (pTable->m_fVersion >= QER_PLUG_VERSION_1) 1564 { 1565 pTable->m_pfnCreateBrush = &QERApp_CreateBrush; 1566 pTable->m_pfnCreateBrushHandle = &QERApp_CreateBrushHandle; 1567 pTable->m_pfnDeleteBrushHandle = &QERApp_DeleteBrushHandle; 1568 pTable->m_pfnCommitBrushHandle = &QERApp_CommitBrushHandleToMap; 1569 pTable->m_pfnAddFace = &QERApp_AddFace; 1570 pTable->m_pfnAddFaceData = &QERApp_AddFaceData; 1571 pTable->m_pfnGetFaceData = &QERApp_GetFaceData; 1572 pTable->m_pfnGetFaceCount = &QERApp_GetFaceCount; 1573 pTable->m_pfnSetFaceData = &QERApp_SetFaceData; 1574 pTable->m_pfnDeleteFace = &QERApp_DeleteFace; 1575 pTable->m_pfnTextureBrush = &QERApp_TextureBrush; 1576 pTable->m_pfnBuildBrush = &QERApp_BuildBrush; // PGM 1577 pTable->m_pfnSelectBrush = &QERApp_SelectBrush; // PGM 1578 pTable->m_pfnDeselectBrush = &QERApp_DeselectBrush; // PGM 1579 pTable->m_pfnDeselectAllBrushes = &QERApp_DeselectAllBrushes; // PGM 1580 pTable->m_pfnDeleteSelection = &QERApp_DeleteSelection; 1581 pTable->m_pfnGetPoints = &QERApp_GetPoints; 1582 pTable->m_pfnSysMsg = &QERApp_SysMsg; 1583 pTable->m_pfnInfoMsg = &QERApp_InfoMsg; 1584 pTable->m_pfnHideInfoMsg = &QERApp_HideInfoMsg; 1585 pTable->m_pfnPositionView = &QERApp_PositionView; // PGM 1586 pTable->m_pfnSelectedBrushCount = &QERApp_SelectedBrushCount; 1587 pTable->m_pfnAllocateSelectedBrushHandles = &QERApp_AllocateSelectedBrushHandles; 1588 pTable->m_pfnReleaseSelectedBrushHandles = &QERApp_ReleaseSelectedBrushHandles; 1589 pTable->m_pfnGetSelectedBrushHandle = &QERApp_GetSelectedBrushHandle; 1590 pTable->m_pfnActiveBrushCount = &QERApp_ActiveBrushCount; 1591 pTable->m_pfnAllocateActiveBrushHandles = &QERApp_AllocateActiveBrushHandles; 1592 pTable->m_pfnReleaseActiveBrushHandles = &QERApp_ReleaseActiveBrushHandles; 1593 pTable->m_pfnGetActiveBrushHandle = &QERApp_GetActiveBrushHandle; 1594 pTable->m_pfnTextureCount = &QERApp_TextureCount; 1595 pTable->m_pfnGetTexture = &QERApp_GetTexture; 1596 pTable->m_pfnGetCurrentTexture = &QERApp_GetCurrentTexture; 1597 pTable->m_pfnSetCurrentTexture = &QERApp_SetCurrentTexture; 1598 pTable->m_pfnGetEClassCount = &QERApp_GetEClassCount; 1599 pTable->m_pfnGetEClass = &QERApp_GetEClass; 1600 pTable->m_pfnResetPlugins = &QERApp_ResetPlugins; 1601 } 1602 // end of v1.00 1603 if (pTable->m_fVersion >= 1.5f) 1604 { 1605 // v1.50 starts 1606 pTable->m_pfnLoadTextureRGBA = &QERApp_LoadTextureRGBA; 1607 // end of v1.50 1608 } 1609 if (pTable->m_fVersion >= 1.7f) 1610 { 1611 pTable->m_pfnGetEntityCount = &QERApp_GetEntityCount; 1612 pTable->m_pfnGetEntityHandle = &QERApp_GetEntityHandle; 1613 pTable->m_pfnGetEntityKeyValList = &QERApp_GetEntityKeyValList; 1614 pTable->m_pfnAllocateEpair = &QERApp_AllocateEpair; 1615 pTable->m_pfnSetEntityKeyValList = &QERApp_SetEntityKeyValList; 1616 pTable->m_pfnAllocateEntityBrushHandles = &QERApp_AllocateEntityBrushHandles; 1617 pTable->m_pfnReleaseEntityBrushHandles = &QERApp_ReleaseEntityBrushHandles; 1618 pTable->m_pfnGetEntityBrushHandle = &QERApp_GetEntityBrushHandle; 1619 pTable->m_pfnCreateEntityHandle = &QERApp_CreateEntityHandle; 1620 pTable->m_pfnCommitBrushHandleToEntity = &QERApp_CommitBrushHandleToEntity; 1621 pTable->m_pfnCommitEntityHandleToMap = &QERApp_CommitEntityHandleToMap; 1622 pTable->m_pfnSetScreenUpdate = &QERApp_SetScreenUpdate; 1623 pTable->m_pfnSysUpdateWindows = &Sys_UpdateWindows; 1624 pTable->m_pfnBuildBrush2 = &QERApp_BuildBrush2; 1625 pTable->m_pfnReadProjectKey = &QERApp_ReadProjectKey; 1626 pTable->m_pfnScanFileForEClass = &QERApp_ScanFileForEClass; 1627 pTable->m_pfnRequestInterface = &QERApp_RequestInterface; 1628 pTable->m_pfnErrorMsg = &QERApp_ErrorMsg; 1629 pTable->m_pfnLoadFile = &QERApp_LoadFile; 1630 pTable->m_pfnExpandReletivePath = &QERApp_ExpandReletivePath; 1631 pTable->m_pfnQE_ConvertDOSToUnixName = &QE_ConvertDOSToUnixName; 1632 pTable->m_pfnHasShader = &QERApp_HasShader; 1633 pTable->m_pfnTexture_LoadSkin = &Texture_LoadSkin; 1634 pTable->m_pfnRadiantFree = &QERApp_RadiantFree; 1635 pTable->m_pfnGetGamePath = &QERApp_GetGamePath; 1636 pTable->m_pfnGetQERPath = &QERApp_GetQERPath; 1637 // patches 1638 pTable->m_pfnAllocateActivePatchHandles = &QERApp_AllocateActivePatchHandles; 1639 pTable->m_pfnAllocateSelectedPatchHandles = &QERApp_AllocateSelectedPatchHandles; 1640 pTable->m_pfnReleasePatchHandles = &QERApp_ReleasePatchHandles; 1641 pTable->m_pfnGetPatchData = &QERApp_GetPatchData; 1642 pTable->m_pfnDeletePatch = &QERApp_DeletePatch; 1643 pTable->m_pfnCreatePatchHandle = &QERApp_CreatePatchHandle; 1644 pTable->m_pfnCommitPatchHandleToMap = &QERApp_CommitPatchHandleToMap; 1645 } 1646 return true; 1647 } 1648 else 1649 { 1650 Sys_Printf("Unable to load %s because the function tables are not the same size\n", pPlug->getVersionStr()); 1651 } 1652 return false; 1653 } 1654 1655 CPlugIn * CPlugInManager::PluginForModule(HMODULE hPlug) 1656 { 1657 int i; 1658 for( i=0; i!=m_PlugIns.GetSize(); i++ ) 1659 { 1660 if ( reinterpret_cast<CPlugIn *>(m_PlugIns[i])->GetDLLModule() == hPlug ) 1661 return reinterpret_cast<CPlugIn *>(m_PlugIns[i]); 1662 } 1663 return NULL; 1664 } 1665