00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "stdafx.h"
00029 #include "Radiant.h"
00030 #include "XYWnd.h"
00031 #include "qe3.h"
00032 #include "PrefsDlg.h"
00033 #include "DialogInfo.h"
00034 #include "splines/splines.h"
00035
00036 #ifdef _DEBUG
00037 #define new DEBUG_NEW
00038 #undef THIS_FILE
00039 static char THIS_FILE[] = __FILE__;
00040 #endif
00041
00042 #define PAGEFLIPS 2
00043
00044
00045 const char* g_pDimStrings[] = {"x:%.f", "y:%.f", "z:%.f"};
00046 const char* g_pOrgStrings[] = {"(x:%.f y:%.f)", "(x:%.f z:%.f)", "(y:%.f z:%.f)"};
00047 CString g_strDim;
00048 CString g_strStatus;
00049
00050 bool g_bCrossHairs = false;
00051 bool g_bScaleMode;
00052 int g_nScaleHow;
00053 bool g_bRotateMode;
00054 bool g_bClipMode;
00055 bool g_bRogueClipMode;
00056 bool g_bSwitch;
00057 CClipPoint g_Clip1;
00058 CClipPoint g_Clip2;
00059 CClipPoint g_Clip3;
00060 CClipPoint* g_pMovingClip;
00061 brush_t g_brFrontSplits;
00062 brush_t g_brBackSplits;
00063
00064 brush_t g_brClipboard;
00065 brush_t g_brUndo;
00066 entity_t g_enClipboard;
00067
00068 vec3_t g_vRotateOrigin;
00069 vec3_t g_vRotation;
00070
00071 bool g_bPathMode;
00072 CClipPoint g_PathPoints[256];
00073 CClipPoint* g_pMovingPath;
00074 int g_nPathCount;
00075 int g_nPathLimit;
00076
00077 bool g_bSmartGo;
00078
00079 bool g_bPointMode;
00080 CClipPoint g_PointPoints[512];
00081 CClipPoint* g_pMovingPoint;
00082 int g_nPointCount;
00083 int g_nPointLimit;
00084
00085
00086 const int XY_LEFT = 0x01;
00087 const int XY_RIGHT = 0x02;
00088 const int XY_UP = 0x04;
00089 const int XY_DOWN = 0x08;
00090
00091 PFNPathCallback* g_pPathFunc = NULL;
00092
00093 void AcquirePath(int nCount, PFNPathCallback* pFunc)
00094 {
00095 g_nPathCount = 0;
00096 g_nPathLimit = nCount;
00097 g_pPathFunc = pFunc;
00098 g_bPathMode = true;
00099 }
00100
00101
00102 CPtrArray g_ptrMenus;
00103
00104 CMemFile g_Clipboard(4096);
00105 CMemFile g_PatchClipboard(4096);
00106
00107 extern int pressx;
00108 extern int pressy;
00109
00110
00112
00113
00114 IMPLEMENT_DYNCREATE(CXYWnd, CWnd);
00115
00116 CXYWnd::CXYWnd()
00117 {
00118 g_brClipboard.next = &g_brClipboard;
00119 g_brUndo.next = &g_brUndo;
00120 g_nScaleHow = 0;
00121 g_bRotateMode = false;
00122 g_bClipMode = false;
00123 g_bRogueClipMode = false;
00124 g_bSwitch = true;
00125 g_pMovingClip = NULL;
00126 g_pMovingPath = NULL;
00127 g_brFrontSplits.next = &g_brFrontSplits;
00128 g_brBackSplits.next = &g_brBackSplits;
00129 m_bActive = false;
00130
00131 m_bTiming = false;
00132 m_bRButtonDown = false;
00133 m_nUpdateBits = W_XY;
00134 g_bPathMode = false;
00135 g_nPathCount = 0;
00136 g_nPathLimit = 0;
00137 m_nTimerID = -1;
00138 XY_Init();
00139 }
00140
00141 CXYWnd::~CXYWnd()
00142 {
00143 int nSize = g_ptrMenus.GetSize();
00144 while (nSize > 0)
00145 {
00146 CMenu* pMenu = reinterpret_cast<CMenu*>(g_ptrMenus.GetAt(nSize-1));
00147 ASSERT(pMenu);
00148 pMenu->DestroyMenu();
00149 delete pMenu;
00150 nSize--;
00151 }
00152 g_ptrMenus.RemoveAll();
00153 m_mnuDrop.DestroyMenu();
00154 }
00155
00156
00157 BEGIN_MESSAGE_MAP(CXYWnd, CWnd)
00158
00159 ON_WM_CREATE()
00160 ON_WM_LBUTTONDOWN()
00161 ON_WM_MBUTTONDOWN()
00162 ON_WM_RBUTTONDOWN()
00163 ON_WM_LBUTTONUP()
00164 ON_WM_MBUTTONUP()
00165 ON_WM_RBUTTONUP()
00166 ON_WM_MOUSEMOVE()
00167 ON_WM_PAINT()
00168 ON_WM_KEYDOWN()
00169 ON_WM_SIZE()
00170 ON_WM_DESTROY()
00171 ON_COMMAND(ID_SELECT_MOUSEROTATE, OnSelectMouserotate)
00172 ON_WM_TIMER()
00173 ON_WM_KEYUP()
00174 ON_WM_NCCALCSIZE()
00175 ON_WM_KILLFOCUS()
00176 ON_WM_SETFOCUS()
00177 ON_WM_CLOSE()
00178 ON_COMMAND(ID_SELECTION_MAKE_DETAIL, CMainFrame::OnSelectionMakeDetail)
00179 ON_COMMAND(ID_SELECTION_MAKE_STRUCTURAL, CMainFrame::OnSelectionMakeStructural)
00180 ON_COMMAND(ID_SELECTION_SELECTCOMPLETETALL, CMainFrame::OnSelectionSelectcompletetall)
00181 ON_COMMAND(ID_SELECTION_SELECTINSIDE, CMainFrame::OnSelectionSelectinside)
00182 ON_COMMAND(ID_SELECTION_SELECTPARTIALTALL, CMainFrame::OnSelectionSelectpartialtall)
00183 ON_COMMAND(ID_SELECTION_SELECTTOUCHING, CMainFrame::OnSelectionSelecttouching)
00184 ON_COMMAND(ID_SELECTION_UNGROUPENTITY, CMainFrame::OnSelectionUngroupentity)
00185
00186 ON_COMMAND_RANGE(ID_ENTITY_START, ID_ENTITY_END, OnEntityCreate)
00187 END_MESSAGE_MAP()
00188
00189
00191
00192 LONG WINAPI XYWndProc(HWND, UINT, WPARAM, LPARAM);
00193 BOOL CXYWnd::PreCreateWindow(CREATESTRUCT& cs)
00194 {
00195 WNDCLASS wc;
00196 HINSTANCE hInstance = AfxGetInstanceHandle();
00197 if (::GetClassInfo(hInstance, XY_WINDOW_CLASS, &wc) == FALSE)
00198 {
00199
00200 memset (&wc, 0, sizeof(wc));
00201 wc.style = CS_NOCLOSE | CS_OWNDC;
00202 wc.lpszClassName = XY_WINDOW_CLASS;
00203 wc.hCursor = NULL;
00204 wc.lpfnWndProc = ::DefWindowProc;
00205 if (AfxRegisterClass(&wc) == FALSE)
00206 Error ("CCamWnd RegisterClass: failed");
00207 }
00208
00209 cs.lpszClass = XY_WINDOW_CLASS;
00210 cs.lpszName = "VIEW";
00211 if (cs.style != QE3_CHILDSTYLE)
00212 cs.style = QE3_SPLITTER_STYLE;
00213
00214 return CWnd::PreCreateWindow(cs);
00215 }
00216
00217 HDC s_hdcXY;
00218 HGLRC s_hglrcXY;
00219
00220 static unsigned s_stipple[32] =
00221 {
00222 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
00223 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
00224 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
00225 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
00226 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
00227 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
00228 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
00229 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
00230 };
00231
00232
00233
00234
00235
00236
00237 LONG WINAPI XYWndProc (
00238 HWND hWnd,
00239 UINT uMsg,
00240 WPARAM wParam,
00241 LPARAM lParam)
00242 {
00243 switch (uMsg)
00244 {
00245 case WM_DESTROY:
00246 QEW_StopGL( hWnd, s_hglrcXY, s_hdcXY );
00247 return 0;
00248
00249 case WM_NCCALCSIZE:
00250 DefWindowProc (hWnd, uMsg, wParam, lParam);
00251 return WVR_REDRAW;
00252
00253 case WM_KILLFOCUS:
00254 case WM_SETFOCUS:
00255 SendMessage( hWnd, WM_NCACTIVATE, uMsg == WM_SETFOCUS, 0 );
00256 return 0;
00257
00258 case WM_CLOSE:
00259 DestroyWindow (hWnd);
00260 return 0;
00261 }
00262
00263 return DefWindowProc (hWnd, uMsg, wParam, lParam);
00264 }
00265
00266
00267 static void WXY_InitPixelFormat( PIXELFORMATDESCRIPTOR *pPFD )
00268 {
00269 memset( pPFD, 0, sizeof( *pPFD ) );
00270
00271 pPFD->nSize = sizeof( PIXELFORMATDESCRIPTOR );
00272 pPFD->nVersion = 1;
00273 pPFD->dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
00274 pPFD->iPixelType = PFD_TYPE_RGBA;
00275 pPFD->cColorBits = 24;
00276 pPFD->cDepthBits = 32;
00277 pPFD->iLayerType = PFD_MAIN_PLANE;
00278
00279 }
00280
00281 void WXY_Print( void )
00282 {
00283 DOCINFO di;
00284
00285 PRINTDLG pd;
00286
00287
00288
00289
00290 memset( &pd, 0, sizeof( pd ) );
00291 pd.lStructSize = sizeof( pd );
00292 pd.hwndOwner = g_qeglobals.d_hwndXY;
00293 pd.Flags = PD_RETURNDC;
00294 pd.hInstance = 0;
00295 if ( !PrintDlg( &pd ) || !pd.hDC )
00296 {
00297 MessageBox( g_qeglobals.d_hwndMain, "Could not PrintDlg()", "QE4 Print Error", MB_OK | MB_ICONERROR );
00298 return;
00299 }
00300
00301
00302
00303
00304 memset( &di, 0, sizeof( di ) );
00305 di.cbSize = sizeof( di );
00306 di.lpszDocName = "QE4";
00307 if ( StartDoc( pd.hDC, &di ) <= 0 )
00308 {
00309 MessageBox( g_qeglobals.d_hwndMain, "Could not StartDoc()", "QE4 Print Error", MB_OK | MB_ICONERROR );
00310 return;
00311 }
00312
00313
00314
00315
00316 if ( StartPage( pd.hDC ) <= 0 )
00317 {
00318 MessageBox( g_qeglobals.d_hwndMain, "Could not StartPage()", "QE4 Print Error", MB_OK | MB_ICONERROR );
00319 return;
00320 }
00321
00322
00323
00324
00325 {
00326 int bmwidth = 320, bmheight = 320;
00327 int pwidth, pheight;
00328
00329 RECT r;
00330
00331 GetWindowRect( g_qeglobals.d_hwndXY, &r );
00332
00333 bmwidth = r.right - r.left;
00334 bmheight = r.bottom - r.top;
00335
00336 pwidth = GetDeviceCaps( pd.hDC, PHYSICALWIDTH ) - GetDeviceCaps( pd.hDC, PHYSICALOFFSETX );
00337 pheight = GetDeviceCaps( pd.hDC, PHYSICALHEIGHT ) - GetDeviceCaps( pd.hDC, PHYSICALOFFSETY );
00338
00339 StretchBlt( pd.hDC,
00340 0, 0,
00341 pwidth, pheight,
00342 s_hdcXY,
00343 0, 0,
00344 bmwidth, bmheight,
00345 SRCCOPY );
00346 }
00347
00348
00349
00350
00351 if ( EndPage( pd.hDC ) <= 0 )
00352 {
00353 MessageBox( g_qeglobals.d_hwndMain, "QE4 Print Error", "Could not EndPage()", MB_OK | MB_ICONERROR );
00354 return;
00355 }
00356
00357 if ( EndDoc( pd.hDC ) <= 0 )
00358 {
00359 MessageBox( g_qeglobals.d_hwndMain, "QE4 Print Error", "Could not EndDoc()", MB_OK | MB_ICONERROR );
00360 return;
00361 }
00362 }
00363
00364 int CXYWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
00365 {
00366 if (CWnd::OnCreate(lpCreateStruct) == -1)
00367 return -1;
00368
00369 s_hdcXY = ::GetDC(GetSafeHwnd());
00370 QEW_SetupPixelFormat(s_hdcXY, false);
00371 if ( ( s_hglrcXY = qwglCreateContext( s_hdcXY ) ) == 0 )
00372 Error( "wglCreateContext in WXY_WndProc failed" );
00373
00374 if (!qwglShareLists( g_qeglobals.d_hglrcBase, s_hglrcXY ) )
00375 Error( "wglShareLists in WXY_WndProc failed" );
00376
00377 if (!qwglMakeCurrent( s_hdcXY, s_hglrcXY ))
00378 Error ("wglMakeCurrent failed");
00379
00380 qglPolygonStipple ((unsigned char *)s_stipple);
00381 qglLineStipple (3, 0xaaaa);
00382 g_qeglobals.d_hwndXY = GetSafeHwnd();
00383 return 0;
00384 }
00385
00386 float ptSum(vec3_t pt)
00387 {
00388 return pt[0] + pt[1] + pt[2];
00389 }
00390
00391 void CXYWnd::DropClipPoint(UINT nFlags, CPoint point)
00392 {
00393 CRect rctZ;
00394 GetClientRect(rctZ);
00395 if (g_pMovingClip)
00396 {
00397 SetCapture();
00398 SnapToPoint (point.x, rctZ.Height() - 1 - point.y , *g_pMovingClip);
00399 }
00400 else
00401 {
00402 vec3_t* pPt = NULL;
00403 if (g_Clip1.Set() == false)
00404 {
00405 pPt = g_Clip1;
00406 g_Clip1.Set(true);
00407 g_Clip1.m_ptScreen = point;
00408 }
00409 else
00410 if (g_Clip2.Set() == false)
00411 {
00412 pPt = g_Clip2;
00413 g_Clip2.Set(true);
00414 g_Clip2.m_ptScreen = point;
00415 }
00416 else
00417 if (g_Clip3.Set() == false)
00418 {
00419 pPt = g_Clip3;
00420 g_Clip3.Set(true);
00421 g_Clip3.m_ptScreen = point;
00422 }
00423 else
00424 {
00425 RetainClipMode(true);
00426 pPt = g_Clip1;
00427 g_Clip1.Set(true);
00428 g_Clip1.m_ptScreen = point;
00429 }
00430 SnapToPoint (point.x, rctZ.Height() - 1 - point.y , *pPt);
00431 }
00432 Sys_UpdateWindows(XY | W_CAMERA_IFON);
00433 }
00434
00435
00436 void CXYWnd::DropPathPoint(UINT nFlags, CPoint point)
00437 {
00438 CRect rctZ;
00439 GetClientRect(rctZ);
00440 if (g_pMovingPath)
00441 {
00442 SetCapture();
00443 SnapToPoint (point.x, rctZ.Height() - 1 - point.y , *g_pMovingPath);
00444 }
00445 else
00446 {
00447 g_PathPoints[g_nPathCount].Set(true);
00448 g_PathPoints[g_nPathCount].m_ptScreen = point;
00449 SnapToPoint(point.x, rctZ.Height() - 1 - point.y, g_PathPoints[g_nPathCount]);
00450 g_nPathCount++;
00451 if (g_nPathCount == g_nPathLimit)
00452 {
00453 if (g_pPathFunc)
00454 g_pPathFunc(true, g_nPathCount);
00455 g_nPathCount = 0;
00456 g_bPathMode = false;
00457 g_pPathFunc = NULL;
00458 }
00459 }
00460 Sys_UpdateWindows(XY | W_CAMERA_IFON);
00461 }
00462
00463 void CXYWnd::AddPointPoint(UINT nFlags, vec3_t* pVec)
00464 {
00465 g_PointPoints[g_nPointCount].Set(true);
00466
00467 _VectorCopy(*pVec, g_PointPoints[g_nPointCount]);
00468 g_PointPoints[g_nPointCount].SetPointPtr(pVec);
00469 g_nPointCount++;
00470 Sys_UpdateWindows(XY | W_CAMERA_IFON);
00471 }
00472
00473
00474 void CXYWnd::OnLButtonDown(UINT nFlags, CPoint point)
00475 {
00476 g_pParentWnd->SetActiveXY(this);
00477 UndoCopy();
00478
00479
00480 if (DispatchOnLButtonDown(nFlags, point.x, point.y ))
00481 return;
00482
00483 if (ClipMode() && !RogueClipMode())
00484 {
00485 DropClipPoint(nFlags, point);
00486 }
00487 else if (PathMode())
00488 {
00489 DropPathPoint(nFlags, point);
00490 }
00491 else OriginalButtonDown(nFlags, point);
00492 }
00493
00494 void CXYWnd::OnMButtonDown(UINT nFlags, CPoint point)
00495 {
00496 OriginalButtonDown(nFlags, point);
00497 }
00498
00499
00500 float Betwixt(float f1, float f2)
00501 {
00502 if (f1 > f2)
00503 return f2 + ((f1 - f2) / 2);
00504 else
00505 return f1 + ((f2 - f1) / 2);
00506 }
00507
00508 void CXYWnd::ProduceSplits(brush_t** pFront, brush_t** pBack)
00509 {
00510 *pFront = NULL;
00511 *pBack = NULL;
00512 if (ClipMode())
00513 {
00514 if (g_Clip1.Set() && g_Clip2.Set())
00515 {
00516 face_t face;
00517 VectorCopy(g_Clip1.m_ptClip,face.planepts[0]);
00518 VectorCopy(g_Clip2.m_ptClip,face.planepts[1]);
00519 VectorCopy(g_Clip3.m_ptClip,face.planepts[2]);
00520 if (selected_brushes.next && (selected_brushes.next->next == &selected_brushes))
00521 {
00522 if (g_Clip3.Set() == false)
00523 {
00524 if (m_nViewType == XY)
00525 {
00526 face.planepts[0][2] = selected_brushes.next->mins[2];
00527 face.planepts[1][2] = selected_brushes.next->mins[2];
00528 face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]);
00529 face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);
00530 face.planepts[2][2] = selected_brushes.next->maxs[2];
00531 }
00532 else if (m_nViewType == YZ)
00533 {
00534 face.planepts[0][0] = selected_brushes.next->mins[0];
00535 face.planepts[1][0] = selected_brushes.next->mins[0];
00536 face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);
00537 face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]);
00538 face.planepts[2][0] = selected_brushes.next->maxs[0];
00539 }
00540 else
00541 {
00542 face.planepts[0][1] = selected_brushes.next->mins[1];
00543 face.planepts[1][1] = selected_brushes.next->mins[1];
00544 face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]);
00545 face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]);
00546 face.planepts[2][1] = selected_brushes.next->maxs[1];
00547 }
00548 }
00549
00550 Brush_SplitBrushByFace (selected_brushes.next, &face, pFront, pBack);
00551 }
00552
00553 }
00554 }
00555 }
00556
00557 void CleanList(brush_t* pList)
00558 {
00559 brush_t* pBrush = pList->next;
00560 while (pBrush != NULL && pBrush != pList)
00561 {
00562 brush_t* pNext = pBrush->next;
00563 Brush_Free(pBrush);
00564 pBrush = pNext;
00565 }
00566 }
00567
00568 void CXYWnd::ProduceSplitLists()
00569 {
00570 if (AnyPatchesSelected())
00571 {
00572 Sys_Printf("Deslecting patches for clip operation.\n");
00573 brush_t *next;
00574 for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = next)
00575 {
00576 next = pb->next;
00577 if (pb->patchBrush)
00578 {
00579 Brush_RemoveFromList (pb);
00580 Brush_AddToList (pb, &active_brushes);
00581 UpdatePatchInspector();
00582 }
00583 if (pb->terrainBrush)
00584 {
00585 Brush_RemoveFromList (pb);
00586 Brush_AddToList (pb, &active_brushes);
00587 UpdateTerrainInspector();
00588 }
00589 }
00590 }
00591
00592 CleanList(&g_brFrontSplits);
00593 CleanList(&g_brBackSplits);
00594 g_brFrontSplits.next = &g_brFrontSplits;
00595 g_brBackSplits.next = &g_brBackSplits;
00596 brush_t* pBrush;
00597 for (pBrush = selected_brushes.next ; pBrush != NULL && pBrush != &selected_brushes ; pBrush=pBrush->next)
00598 {
00599 brush_t* pFront = NULL;
00600 brush_t* pBack = NULL;
00601 if (ClipMode())
00602 {
00603 if (g_Clip1.Set() && g_Clip2.Set())
00604 {
00605 face_t face;
00606 VectorCopy(g_Clip1.m_ptClip,face.planepts[0]);
00607 VectorCopy(g_Clip2.m_ptClip,face.planepts[1]);
00608 VectorCopy(g_Clip3.m_ptClip,face.planepts[2]);
00609 if (g_Clip3.Set() == false)
00610 {
00611 if (g_pParentWnd->ActiveXY()->GetViewType() == XY)
00612 {
00613 face.planepts[0][2] = pBrush->mins[2];
00614 face.planepts[1][2] = pBrush->mins[2];
00615 face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]);
00616 face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);
00617 face.planepts[2][2] = pBrush->maxs[2];
00618 }
00619 else if (g_pParentWnd->ActiveXY()->GetViewType() == YZ)
00620 {
00621 face.planepts[0][0] = pBrush->mins[0];
00622 face.planepts[1][0] = pBrush->mins[0];
00623 face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);
00624 face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]);
00625 face.planepts[2][0] = pBrush->maxs[0];
00626 }
00627 else
00628 {
00629 face.planepts[0][1] = pBrush->mins[1];
00630 face.planepts[1][1] = pBrush->mins[1];
00631 face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]);
00632 face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]);
00633 face.planepts[2][1] = pBrush->maxs[1];
00634 }
00635 }
00636 Brush_SplitBrushByFace (pBrush, &face, &pFront, &pBack);
00637 if (pBack)
00638 Brush_AddToList(pBack, &g_brBackSplits);
00639 if (pFront)
00640 Brush_AddToList(pFront, &g_brFrontSplits);
00641 }
00642 }
00643 }
00644 }
00645
00646 void Brush_CopyList (brush_t* pFrom, brush_t* pTo)
00647 {
00648 brush_t* pBrush = pFrom->next;
00649 while (pBrush != NULL && pBrush != pFrom)
00650 {
00651 brush_t* pNext = pBrush->next;
00652 Brush_RemoveFromList(pBrush);
00653 Brush_AddToList(pBrush, pTo);
00654 pBrush = pNext;
00655 }
00656 }
00657
00658 void CXYWnd::OnRButtonDown(UINT nFlags, CPoint point)
00659 {
00660 g_pParentWnd->SetActiveXY(this);
00661 m_ptDown = point;
00662 m_bRButtonDown = true;
00663
00664 if (g_PrefsDlg.m_nMouseButtons == 3)
00665 {
00666 if ((GetKeyState(VK_CONTROL) & 0x8000))
00667 {
00668 if (ClipMode())
00669 DropClipPoint(nFlags, point);
00670 else
00671 {
00672 SetClipMode(true);
00673 g_bRogueClipMode = true;
00674 DropClipPoint(nFlags, point);
00675 }
00676 return;
00677 }
00678 }
00679 OriginalButtonDown(nFlags, point);
00680 }
00681
00682 void CXYWnd::OnLButtonUp(UINT nFlags, CPoint point)
00683 {
00684
00685 if (DispatchOnLButtonUp(nFlags, point.x, point.y ))
00686 return;
00687
00688 if (ClipMode())
00689 {
00690 if (g_pMovingClip)
00691 {
00692 ReleaseCapture();
00693 g_pMovingClip = NULL;
00694 }
00695 }
00696 OriginalButtonUp(nFlags, point);
00697 }
00698
00699 void CXYWnd::OnMButtonUp(UINT nFlags, CPoint point)
00700 {
00701 OriginalButtonUp(nFlags, point);
00702 }
00703
00704 void CXYWnd::OnRButtonUp(UINT nFlags, CPoint point)
00705 {
00706 m_bRButtonDown = false;
00707 if (point == m_ptDown)
00708 {
00709 bool bGo = true;
00710 if ((GetKeyState(VK_MENU) & 0x8000))
00711 bGo = false;
00712 if ((GetKeyState(VK_CONTROL) & 0x8000))
00713 bGo = false;
00714 if ((GetKeyState(VK_SHIFT) & 0x8000))
00715 bGo = false;
00716 if (bGo)
00717 HandleDrop();
00718 }
00719 OriginalButtonUp(nFlags, point);
00720 }
00721
00722 void CXYWnd::OriginalButtonDown(UINT nFlags, CPoint point)
00723 {
00724 CRect rctZ;
00725 GetClientRect(rctZ);
00726 SetWindowPos(&wndTop, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
00727 if (::GetTopWindow( g_qeglobals.d_hwndMain ) != GetSafeHwnd())
00728 ::BringWindowToTop(GetSafeHwnd());
00729 SetFocus();
00730 SetCapture();
00731 XY_MouseDown (point.x, rctZ.Height() - 1 - point.y , nFlags);
00732 m_nScrollFlags = nFlags;
00733 }
00734
00735 void CXYWnd::OriginalButtonUp(UINT nFlags, CPoint point)
00736 {
00737 CRect rctZ;
00738 GetClientRect(rctZ);
00739 XY_MouseUp (point.x, rctZ.Height() - 1 - point.y , nFlags);
00740 if (! (nFlags & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON)))
00741 ReleaseCapture ();
00742 }
00743
00744
00745 float fDiff(float f1, float f2)
00746 {
00747 if (f1 > f2)
00748 return f1 - f2;
00749 else
00750 return f2 - f1;
00751 }
00752
00753
00754 vec3_t tdp;
00755 void CXYWnd::OnMouseMove(UINT nFlags, CPoint point)
00756 {
00757
00758
00759 DispatchOnMouseMove( nFlags, point.x, point.y );
00760
00761 m_ptDown.x = 0;
00762 m_ptDown.y = 0;
00763
00764 if ( g_PrefsDlg.m_bChaseMouse == TRUE &&
00765 (point.x < 0 || point.y < 0 ||
00766 point.x > m_nWidth || point.y > m_nHeight) &&
00767 GetCapture() == this)
00768 {
00769 float fAdjustment = (g_qeglobals.d_gridsize / 8 * 64) / m_fScale;
00770
00771 m_ptDragAdj.x = 0;
00772 m_ptDragAdj.y = 0;
00773 if (point.x < 0)
00774 {
00775 m_ptDragAdj.x = -fAdjustment;
00776 }
00777 else
00778 if (point.x > m_nWidth)
00779 {
00780 m_ptDragAdj.x = fAdjustment;
00781 }
00782 if (point.y < 0)
00783 {
00784 m_ptDragAdj.y = -fAdjustment;
00785 }
00786 else
00787 if (point.y > m_nHeight)
00788 {
00789 m_ptDragAdj.y = fAdjustment;
00790 }
00791 if (m_nTimerID == -1)
00792 {
00793 m_nTimerID = SetTimer(100, 50, NULL);
00794 m_ptDrag = point;
00795 m_ptDragTotal = 0;
00796 }
00797 return;
00798 }
00799
00800 if (m_nTimerID != -1)
00801 {
00802 KillTimer(m_nTimerID);
00803 pressx -= m_ptDragTotal.x;
00804 pressy += m_ptDragTotal.y;
00805 m_nTimerID = -1;
00806
00807 }
00808
00809 bool bCrossHair = false;
00810 if (!m_bRButtonDown)
00811 {
00812 tdp[0] = tdp[1] = tdp[2] = 0.0;
00813 SnapToPoint (point.x, m_nHeight - 1 - point.y , tdp);
00814
00815 g_strStatus.Format("x:: %.1f y:: %.1f z:: %.1f", tdp[0], tdp[1], tdp[2]);
00816 g_pParentWnd->SetStatusText(1, g_strStatus);
00817
00818
00819
00820
00821 if (PointMode())
00822 {
00823 if (g_pMovingPoint && GetCapture() == this)
00824 {
00825 bCrossHair = true;
00826 SnapToPoint (point.x, m_nHeight - 1 - point.y , g_pMovingPoint->m_ptClip);
00827 g_pMovingPoint->UpdatePointPtr();
00828 Sys_UpdateWindows(XY | W_CAMERA_IFON);
00829 }
00830 else
00831 {
00832 g_pMovingPoint = NULL;
00833 int nDim1 = (m_nViewType == YZ) ? 1 : 0;
00834 int nDim2 = (m_nViewType == XY) ? 1 : 2;
00835 for (int n = 0; n < g_nPointCount; n++)
00836 {
00837 if ( fDiff(g_PointPoints[n].m_ptClip[nDim1], tdp[nDim1]) < 3 &&
00838 fDiff(g_PointPoints[n].m_ptClip[nDim2], tdp[nDim2]) < 3 )
00839 {
00840 bCrossHair = true;
00841 g_pMovingPoint = &g_PointPoints[n];
00842 }
00843 }
00844 }
00845 }
00846 else if (ClipMode())
00847 {
00848 if (g_pMovingClip && GetCapture() == this)
00849 {
00850 bCrossHair = true;
00851 SnapToPoint (point.x, m_nHeight - 1 - point.y , g_pMovingClip->m_ptClip);
00852 Sys_UpdateWindows(XY | W_CAMERA_IFON);
00853 }
00854 else
00855 {
00856 g_pMovingClip = NULL;
00857 int nDim1 = (m_nViewType == YZ) ? 1 : 0;
00858 int nDim2 = (m_nViewType == XY) ? 1 : 2;
00859 if (g_Clip1.Set())
00860 {
00861 if ( fDiff(g_Clip1.m_ptClip[nDim1], tdp[nDim1]) < 3 &&
00862 fDiff(g_Clip1.m_ptClip[nDim2], tdp[nDim2]) < 3 )
00863 {
00864 bCrossHair = true;
00865 g_pMovingClip = &g_Clip1;
00866 }
00867 }
00868 if (g_Clip2.Set())
00869 {
00870 if ( fDiff(g_Clip2.m_ptClip[nDim1], tdp[nDim1]) < 3 &&
00871 fDiff(g_Clip2.m_ptClip[nDim2], tdp[nDim2]) < 3 )
00872 {
00873 bCrossHair = true;
00874 g_pMovingClip = &g_Clip2;
00875 }
00876 }
00877 if (g_Clip3.Set())
00878 {
00879 if ( fDiff(g_Clip3.m_ptClip[nDim1], tdp[nDim1]) < 3 &&
00880 fDiff(g_Clip3.m_ptClip[nDim2], tdp[nDim2]) < 3 )
00881 {
00882 bCrossHair = true;
00883 g_pMovingClip = &g_Clip3;
00884 }
00885 }
00886 }
00887 if (bCrossHair == false)
00888 XY_MouseMoved (point.x, m_nHeight - 1 - point.y , nFlags);
00889 }
00890 else if (PathMode())
00891 {
00892 if (g_pMovingPath && GetCapture() == this)
00893 {
00894 bCrossHair = true;
00895 SnapToPoint (point.x, m_nHeight - 1 - point.y , g_pMovingPath->m_ptClip);
00896 Sys_UpdateWindows(XY | W_CAMERA_IFON);
00897 }
00898 else
00899 {
00900 g_pMovingPath = NULL;
00901 int nDim1 = (m_nViewType == YZ) ? 1 : 0;
00902 int nDim2 = (m_nViewType == XY) ? 1 : 2;
00903 for (int n = 0; n < g_nPathCount; n++)
00904 {
00905 if ( fDiff(g_PathPoints[n].m_ptClip[nDim1], tdp[nDim1]) < 3 &&
00906 fDiff(g_PathPoints[n].m_ptClip[nDim2], tdp[nDim2]) < 3 )
00907 {
00908 bCrossHair = true;
00909 g_pMovingPath = &g_PathPoints[n];
00910 }
00911 }
00912 }
00913 }
00914 else
00915 {
00916 XY_MouseMoved (point.x, m_nHeight - 1 - point.y , nFlags);
00917 }
00918 }
00919 else
00920 {
00921 XY_MouseMoved (point.x, m_nHeight - 1 - point.y , nFlags);
00922 }
00923 if (bCrossHair)
00924 SetCursor(::LoadCursor(NULL, IDC_CROSS));
00925 else
00926 SetCursor(::LoadCursor(NULL, IDC_ARROW));
00927 }
00928
00929 void CXYWnd::RetainClipMode(bool bMode)
00930 {
00931 bool bSave = g_bRogueClipMode;
00932 SetClipMode(bMode);
00933 if (bMode == true)
00934 g_bRogueClipMode = bSave;
00935 else
00936 g_bRogueClipMode = false;
00937 }
00938
00939 void CXYWnd::SetClipMode(bool bMode)
00940 {
00941 g_bClipMode = bMode;
00942 g_bRogueClipMode = false;
00943 if (bMode)
00944 {
00945 g_Clip1.Reset();
00946 g_Clip2.Reset();
00947 g_Clip3.Reset();
00948 CleanList(&g_brFrontSplits);
00949 CleanList(&g_brBackSplits);
00950 g_brFrontSplits.next = &g_brFrontSplits;
00951 g_brBackSplits.next = &g_brBackSplits;
00952 }
00953 else
00954 {
00955 if (g_pMovingClip)
00956 {
00957 ReleaseCapture();
00958 g_pMovingClip = NULL;
00959 }
00960 CleanList(&g_brFrontSplits);
00961 CleanList(&g_brBackSplits);
00962 g_brFrontSplits.next = &g_brFrontSplits;
00963 g_brBackSplits.next = &g_brBackSplits;
00964 Sys_UpdateWindows(XY | W_CAMERA_IFON);
00965 }
00966 }
00967
00968 bool CXYWnd::ClipMode()
00969 {
00970 return g_bClipMode;
00971 }
00972
00973 bool CXYWnd::RogueClipMode()
00974 {
00975 return g_bRogueClipMode;
00976 }
00977
00978 bool CXYWnd::PathMode()
00979 {
00980 return g_bPathMode;
00981 }
00982
00983
00984 bool CXYWnd::PointMode()
00985 {
00986 return g_bPointMode;
00987 }
00988
00989 void CXYWnd::SetPointMode(bool b)
00990 {
00991 g_bPointMode = b;
00992 if (!b)
00993 g_nPointCount = 0;
00994 }
00995
00996
00997 void CXYWnd::OnPaint()
00998 {
00999 CPaintDC dc(this);
01000 bool bPaint = true;
01001 if (!qwglMakeCurrent(dc.m_hDC, s_hglrcXY))
01002 {
01003 Sys_Printf("ERROR: wglMakeCurrent failed.. Error:%i\n",qglGetError());
01004 Sys_Printf("Please restart Q3Radiant if the Map view is not working\n");
01005 bPaint = false;
01006 }
01007 if (bPaint)
01008 {
01009 QE_CheckOpenGLForErrors();
01010 XY_Draw ();
01011 QE_CheckOpenGLForErrors();
01012
01013 if (m_nViewType != XY)
01014 {
01015 qglPushMatrix();
01016 if (m_nViewType == YZ)
01017 qglRotatef (-90, 0, 1, 0);
01018 qglRotatef (-90, 1, 0, 0);
01019 }
01020
01021 if (g_bCrossHairs)
01022 {
01023 qglColor4f(0.2, 0.9, 0.2, 0.8);
01024 qglBegin (GL_LINES);
01025 if (m_nViewType == XY)
01026 {
01027 qglVertex2f(-16384, tdp[1]);
01028 qglVertex2f(16384, tdp[1]);
01029 qglVertex2f(tdp[0], -16384);
01030 qglVertex2f(tdp[0], 16384);
01031 }
01032 else if (m_nViewType == YZ)
01033 {
01034 qglVertex3f(tdp[0], -16384, tdp[2]);
01035 qglVertex3f(tdp[0], 16384, tdp[2]);
01036 qglVertex3f(tdp[0], tdp[1], -16384);
01037 qglVertex3f(tdp[0], tdp[1], 16384);
01038 }
01039 else
01040 {
01041 qglVertex3f(-16384, tdp[1], tdp[2]);
01042 qglVertex3f( 16384, tdp[1], tdp[2]);
01043 qglVertex3f(tdp[0], tdp[1], -16384);
01044 qglVertex3f(tdp[0], tdp[1], 16384);
01045 }
01046 qglEnd();
01047 }
01048
01049 if (ClipMode())
01050 {
01051 qglPointSize (4);
01052 qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER]);
01053 qglBegin (GL_POINTS);
01054 if (g_Clip1.Set())
01055 qglVertex3fv (g_Clip1);
01056 if (g_Clip2.Set())
01057 qglVertex3fv (g_Clip2);
01058 if (g_Clip3.Set())
01059 qglVertex3fv (g_Clip3);
01060 qglEnd ();
01061 qglPointSize (1);
01062
01063 CString strMsg;
01064 if (g_Clip1.Set())
01065 {
01066 qglRasterPos3f (g_Clip1.m_ptClip[0]+2, g_Clip1.m_ptClip[1]+2, g_Clip1.m_ptClip[2]+2);
01067 strMsg = "1";
01068
01069 qglCallLists (strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg);
01070 }
01071 if (g_Clip2.Set())
01072 {
01073 qglRasterPos3f (g_Clip2.m_ptClip[0]+2, g_Clip2.m_ptClip[1]+2, g_Clip2.m_ptClip[2]+2);
01074 strMsg = "2";
01075
01076 qglCallLists (strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg);
01077 }
01078 if (g_Clip3.Set())
01079 {
01080 qglRasterPos3f (g_Clip3.m_ptClip[0]+2, g_Clip3.m_ptClip[1]+2, g_Clip3.m_ptClip[2]+2);
01081 strMsg = "3";
01082
01083 qglCallLists (strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg);
01084 }
01085 if (g_Clip1.Set() && g_Clip2.Set())
01086 {
01087 ProduceSplitLists();
01088 brush_t* pBrush;
01089 brush_t* pList = ( (m_nViewType == XZ) ? !g_bSwitch : g_bSwitch) ? &g_brBackSplits : &g_brFrontSplits;
01090 for (pBrush = pList->next ; pBrush != NULL && pBrush != pList ; pBrush=pBrush->next)
01091 {
01092 qglColor3f (1,1,0);
01093 face_t *face;
01094 int order;
01095 for (face = pBrush->brush_faces,order = 0 ; face ; face=face->next, order++)
01096 {
01097 winding_t* w = face->face_winding;
01098 if (!w)
01099 continue;
01100
01101 qglBegin(GL_LINE_LOOP);
01102 for (int i=0 ; i<w->numpoints ; i++)
01103 qglVertex3fv(w->points[i]);
01104 qglEnd();
01105 }
01106 }
01107 }
01108
01109 }
01110
01111
01112
01113 if (PathMode())
01114 {
01115 qglPointSize (4);
01116 qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER]);
01117 qglBegin (GL_POINTS);
01118
01119 for (int n = 0; n < g_nPathCount; n++)
01120 qglVertex3fv(g_PathPoints[n]);
01121 qglEnd ();
01122 qglPointSize (1);
01123
01124 CString strMsg;
01125 for (n = 0; n < g_nPathCount; n++)
01126 {
01127 qglRasterPos3f (g_PathPoints[n].m_ptClip[0]+2, g_PathPoints[n].m_ptClip[1]+2, g_PathPoints[n].m_ptClip[2]+2);
01128 strMsg.Format("%i", n+1);
01129 qglCallLists (strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg);
01130 }
01131
01132 }
01133 if (m_nViewType != XY)
01134 qglPopMatrix();
01135
01136 qwglSwapBuffers(dc.m_hDC);
01137 TRACE("XY Paint\n");
01138 }
01139 }
01140
01141 void CXYWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
01142 {
01143 g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags);
01144 }
01145
01146
01147
01148
01149 void CreateEntityFromName(char* pName, brush_t* pBrush)
01150 {
01151 eclass_t *pecNew;
01152 entity_t *petNew;
01153 if (stricmp(pName, "worldspawn") == 0)
01154 {
01155 MessageBox(g_qeglobals.d_hwndMain, "Can't create an entity with worldspawn.", "info", 0);
01156 return;
01157 }
01158
01159 pecNew = Eclass_ForName(pName, false);
01160
01161
01162 petNew = Entity_Create(pecNew);
01163 if (petNew == NULL)
01164 {
01165 if (!((selected_brushes.next == &selected_brushes)||(selected_brushes.next->next != &selected_brushes)))
01166 {
01167 brush_t* b = selected_brushes.next;
01168 if (b->owner != world_entity && b->owner->eclass->fixedsize && pecNew->fixedsize)
01169 {
01170 vec3_t mins, maxs;
01171 vec3_t origin;
01172 for (int i=0 ; i<3 ; i++)
01173 origin[i] = b->mins[i] - pecNew->mins[i];
01174
01175 VectorAdd (pecNew->mins, origin, mins);
01176 VectorAdd (pecNew->maxs, origin, maxs);
01177 brush_t* nb = Brush_Create (mins, maxs, &pecNew->texdef);
01178 Entity_LinkBrush (b->owner, nb);
01179 nb->owner->eclass = pecNew;
01180 SetKeyValue (nb->owner, "classname", pName);
01181 Brush_Free(b);
01182 Brush_Build(nb);
01183 Brush_AddToList (nb, &active_brushes);
01184 Select_Brush(nb);
01185 return;
01186 }
01187 }
01188 MessageBox(g_qeglobals.d_hwndMain, "Failed to create entity.", "info", 0);
01189 return;
01190 }
01191
01192 Select_Deselect ();
01193
01194
01195
01196 Select_Brush (petNew->brushes.onext);
01197
01198 if (stricmp(pName, "misc_model") == 0)
01199 {
01200 SetInspectorMode(W_ENTITY);
01201 PostMessage(g_qeglobals.d_hwndEntity, WM_COMMAND, IDC_BTN_ASSIGNMODEL, 0);
01202 }
01203
01204 }
01205
01206
01207 brush_t* CreateEntityBrush(int x, int y, CXYWnd* pWnd)
01208 {
01209 vec3_t mins, maxs;
01210 int i;
01211 float temp;
01212 brush_t *n;
01213
01214 pWnd->SnapToPoint (x, y, mins);
01215 x += 32;
01216 y += 32;
01217 pWnd->SnapToPoint (x, y, maxs);
01218
01219 int nDim = (pWnd->GetViewType() == XY) ? 2 : (pWnd->GetViewType() == YZ) ? 0 : 1;
01220 mins[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_bottom_z/g_qeglobals.d_gridsize));
01221 maxs[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_top_z/g_qeglobals.d_gridsize));
01222
01223 if (maxs[nDim] <= mins[nDim])
01224 maxs[nDim] = mins[nDim] + g_qeglobals.d_gridsize;
01225
01226 for (i=0 ; i<3 ; i++)
01227 {
01228 if (mins[i] == maxs[i])
01229 maxs[i] += 16;
01230 if (mins[i] > maxs[i])
01231 {
01232 temp = mins[i];
01233 mins[i] = maxs[i];
01234 maxs[i] = temp;
01235 }
01236 }
01237
01238 n = Brush_Create (mins, maxs, &g_qeglobals.d_texturewin.texdef);
01239 if (!n)
01240 return NULL;
01241
01242 Brush_AddToList (n, &selected_brushes);
01243 Entity_LinkBrush (world_entity, n);
01244 Brush_Build( n );
01245 return n;
01246 }
01247
01248 void CreateRightClickEntity(CXYWnd* pWnd, int x, int y, char* pName)
01249 {
01250 CRect rctZ;
01251 pWnd->GetClientRect(rctZ);
01252 brush_t* pBrush = (selected_brushes.next == &selected_brushes) ? CreateEntityBrush(x, rctZ.Height() - 1 - y, pWnd) : selected_brushes.next;
01253 CreateEntityFromName(pName, pBrush);
01254
01255 }
01256
01257 brush_t* CreateSmartBrush(vec3_t v)
01258 {
01259 vec3_t mins, maxs;
01260 int i;
01261 brush_t *n;
01262
01263 for (i=0 ; i<3 ; i++)
01264 {
01265 mins[i] = v[i] - 16;
01266 maxs[i] = v[i] + 16;
01267 }
01268
01269 n = Brush_Create (mins, maxs, &g_qeglobals.d_texturewin.texdef);
01270 if (!n)
01271 return NULL;
01272
01273 Brush_AddToList(n, &selected_brushes);
01274
01275 Brush_Build(n);
01276 return n;
01277 }
01278
01279
01280
01281
01282 CString g_strSmartEntity;
01283 int g_nSmartX;
01284 int g_nSmartY;
01285 bool g_bSmartWaiting;
01286 void _SmartPointDone(bool b, int n)
01287 {
01288 g_bSmartWaiting = false;
01289 }
01290
01291 void CreateSmartEntity(CXYWnd* pWnd, int x, int y, const char* pName)
01292 {
01293 g_nSmartX = x;
01294 g_nSmartY = y;
01295 g_strSmartEntity = pName;
01296 if (g_strSmartEntity.Find("Smart_Train") >= 0)
01297 {
01298 ShowInfoDialog("Select the path of the train by left clicking in XY, YZ and/or XZ views. You can move an already dropped point by grabbing and moving it. When you are finished, press ENTER to accept and create the entity and path(s), press ESC to abandon the creation");
01299 g_bPathMode = true;
01300 g_nPathLimit = 0;
01301 g_nPathCount = 0;
01302 g_bSmartGo = true;
01303 }
01304 else
01305 if (g_strSmartEntity.Find("Smart_Monster...") >= 0)
01306 {
01307 g_bPathMode = true;
01308 g_nPathLimit = 0;
01309 g_nPathCount = 0;
01310 }
01311 else
01312 if (g_strSmartEntity.Find("Smart_Rotating") >= 0)
01313 {
01314 g_bSmartWaiting = true;
01315 ShowInfoDialog("Left click to specify the rotation origin");
01316 AcquirePath(1, &_SmartPointDone);
01317 while (g_bSmartWaiting)
01318 {
01319 MSG msg;
01320 if (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ))
01321 {
01322 TranslateMessage(&msg);
01323 DispatchMessage(&msg);
01324 }
01325 }
01326 HideInfoDialog();
01327 CPtrArray array;
01328 g_bScreenUpdates = false;
01329 CreateRightClickEntity(g_pParentWnd->ActiveXY(), g_nSmartX, g_nSmartY, "func_rotating");
01330 array.Add(reinterpret_cast<void*>(selected_brushes.next));
01331 Select_Deselect();
01332 brush_t* pBrush = CreateSmartBrush(g_PathPoints[0]);
01333 array.Add(pBrush);
01334 Select_Deselect();
01335 Select_Brush(reinterpret_cast<brush_t*>(array.GetAt(0)));
01336 Select_Brush(reinterpret_cast<brush_t*>(array.GetAt(1)));
01337 ConnectEntities();
01338 g_bScreenUpdates = true;
01339 }
01340 }
01341
01342
01343 void FinishSmartCreation()
01344 {
01345 CPtrArray array;
01346 HideInfoDialog();
01347 brush_t* pEntities = NULL;
01348 if (g_strSmartEntity.Find("Smart_Train") >= 0)
01349 {
01350 g_bScreenUpdates = false;
01351 CreateRightClickEntity(g_pParentWnd->ActiveXY(), g_nSmartX, g_nSmartY, "func_train");
01352 array.Add(reinterpret_cast<void*>(selected_brushes.next));
01353 for (int n = 0; n < g_nPathCount; n++)
01354 {
01355 Select_Deselect();
01356 CreateRightClickEntity(g_pParentWnd->ActiveXY(), g_PathPoints[n].m_ptScreen.x,g_PathPoints[n].m_ptScreen.y, "path_corner");
01357 array.Add(reinterpret_cast<void*>(selected_brushes.next));
01358 }
01359
01360 for (n = 0; n < g_nPathCount; n++)
01361 {
01362 Select_Deselect();
01363 Select_Brush(reinterpret_cast<brush_t*>(array.GetAt(n)));
01364 Select_Brush(reinterpret_cast<brush_t*>(array.GetAt(n+1)));
01365 ConnectEntities();
01366 }
01367 g_bScreenUpdates = true;
01368
01369 }
01370 g_nPathCount = 0;
01371 g_bPathMode = false;
01372 Sys_UpdateWindows(W_ALL);
01373 }
01374
01375 void CXYWnd::KillPathMode()
01376 {
01377 g_bSmartGo = false;
01378 g_bPathMode = false;
01379 if (g_pPathFunc)
01380 g_pPathFunc(false, g_nPathCount);
01381 g_nPathCount = 0;
01382 g_pPathFunc = NULL;
01383 Sys_UpdateWindows(W_ALL);
01384 }
01385
01386
01387