home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 58 / pcpp58a.iso / extras / quake 3 source / Q3A_ToolSource.exe / Main / XYWnd.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-02  |  89.1 KB  |  3,582 lines

  1. // XYWnd.cpp : implementation file
  2. //
  3. // QERadiant
  4. //
  5. // 
  6.  
  7. #include "stdafx.h"
  8. #include "Radiant.h"
  9. #include "XYWnd.h"
  10. #include "qe3.h"
  11. #include "PrefsDlg.h"
  12. #include "DialogInfo.h"
  13.  
  14. #ifdef _DEBUG
  15. #define new DEBUG_NEW
  16. #undef THIS_FILE
  17. static char THIS_FILE[] = __FILE__;
  18. #endif
  19.  
  20. #define    PAGEFLIPS    2
  21.  
  22.  
  23. const char* g_pDimStrings[] = {"x:%.f", "y:%.f", "z:%.f"};
  24. const char* g_pOrgStrings[] = {"(x:%.f  y:%.f)", "(x:%.f  z:%.f)", "(y:%.f  z:%.f)"};
  25. CString g_strDim;
  26. CString g_strStatus;
  27.  
  28. bool g_bCrossHairs = false;
  29. bool g_bScaleMode;
  30. int g_nScaleHow;
  31. bool g_bRotateMode;
  32. bool g_bClipMode;
  33. bool g_bRogueClipMode;
  34. bool g_bSwitch;
  35. CClipPoint g_Clip1;
  36. CClipPoint g_Clip2;
  37. CClipPoint g_Clip3;
  38. CClipPoint* g_pMovingClip;
  39. brush_t g_brFrontSplits;
  40. brush_t g_brBackSplits;
  41.  
  42. brush_t g_brClipboard;
  43. brush_t g_brUndo;
  44. entity_t    g_enClipboard;
  45.  
  46. vec3_t g_vRotateOrigin;
  47. vec3_t g_vRotation;
  48.  
  49. bool g_bPathMode;
  50. CClipPoint g_PathPoints[256];
  51. CClipPoint* g_pMovingPath;
  52. int g_nPathCount;
  53. int g_nPathLimit;
  54.  
  55. bool g_bSmartGo;
  56.  
  57. bool g_bPointMode;
  58. CClipPoint g_PointPoints[512];
  59. CClipPoint* g_pMovingPoint;
  60. int g_nPointCount;
  61. int g_nPointLimit;
  62.  
  63.  
  64. const int XY_LEFT = 0x01;
  65. const int XY_RIGHT = 0x02;
  66. const int XY_UP = 0x04;
  67. const int XY_DOWN = 0x08;
  68.  
  69. PFNPathCallback* g_pPathFunc = NULL;
  70.  
  71. void AcquirePath(int nCount, PFNPathCallback* pFunc)
  72. {
  73.   g_nPathCount = 0;
  74.   g_nPathLimit = nCount;
  75.   g_pPathFunc = pFunc;
  76.   g_bPathMode = true;
  77. }
  78.  
  79.  
  80. CPtrArray g_ptrMenus;
  81.  
  82. CMemFile g_Clipboard(4096);
  83. CMemFile g_PatchClipboard(4096);
  84.  
  85. extern int pressx;
  86. extern int pressy;
  87.  
  88.  
  89. /////////////////////////////////////////////////////////////////////////////
  90. // CXYWnd
  91.  
  92. IMPLEMENT_DYNCREATE(CXYWnd, CWnd);
  93.  
  94. CXYWnd::CXYWnd()
  95. {
  96.   g_brClipboard.next = &g_brClipboard;
  97.   g_brUndo.next = &g_brUndo;
  98.   g_nScaleHow = 0;
  99.   g_bRotateMode = false;
  100.   g_bClipMode = false;
  101.   g_bRogueClipMode = false;
  102.   g_bSwitch = true;
  103.   g_pMovingClip = NULL;
  104.   g_pMovingPath = NULL;
  105.   g_brFrontSplits.next = &g_brFrontSplits;
  106.   g_brBackSplits.next = &g_brBackSplits;
  107.   m_bActive = false;
  108.   //m_bTiming = true;
  109.   m_bTiming = false;
  110.   m_bRButtonDown = false;
  111.   m_nUpdateBits = W_XY;
  112.   g_bPathMode = false;
  113.   g_nPathCount = 0;
  114.   g_nPathLimit = 0;
  115.   m_nTimerID = -1;
  116.   XY_Init();
  117. }
  118.  
  119. CXYWnd::~CXYWnd()
  120. {
  121.   int nSize = g_ptrMenus.GetSize();
  122.   while (nSize > 0)
  123.   {
  124.     CMenu* pMenu = reinterpret_cast<CMenu*>(g_ptrMenus.GetAt(nSize-1));
  125.     ASSERT(pMenu);
  126.     pMenu->DestroyMenu();
  127.     delete pMenu;
  128.     nSize--;
  129.   }
  130.   g_ptrMenus.RemoveAll();
  131.   m_mnuDrop.DestroyMenu();
  132. }
  133.  
  134.  
  135. BEGIN_MESSAGE_MAP(CXYWnd, CWnd)
  136.     //{{AFX_MSG_MAP(CXYWnd)
  137.     ON_WM_CREATE()
  138.     ON_WM_LBUTTONDOWN()
  139.     ON_WM_MBUTTONDOWN()
  140.     ON_WM_RBUTTONDOWN()
  141.     ON_WM_LBUTTONUP()
  142.     ON_WM_MBUTTONUP()
  143.     ON_WM_RBUTTONUP()
  144.     ON_WM_MOUSEMOVE()
  145.     ON_WM_PAINT()
  146.     ON_WM_KEYDOWN()
  147.     ON_WM_SIZE()
  148.     ON_WM_DESTROY()
  149.     ON_COMMAND(ID_SELECT_MOUSEROTATE, OnSelectMouserotate)
  150.     ON_WM_TIMER()
  151.     ON_WM_KEYUP()
  152.     ON_WM_NCCALCSIZE()
  153.     ON_WM_KILLFOCUS()
  154.     ON_WM_SETFOCUS()
  155.     ON_WM_CLOSE()
  156.     ON_COMMAND(ID_SELECTION_MAKE_DETAIL, CMainFrame::OnSelectionMakeDetail)
  157.     ON_COMMAND(ID_SELECTION_MAKE_STRUCTURAL, CMainFrame::OnSelectionMakeStructural)
  158.     ON_COMMAND(ID_SELECTION_SELECTCOMPLETETALL, CMainFrame::OnSelectionSelectcompletetall)
  159.     ON_COMMAND(ID_SELECTION_SELECTINSIDE, CMainFrame::OnSelectionSelectinside)
  160.     ON_COMMAND(ID_SELECTION_SELECTPARTIALTALL, CMainFrame::OnSelectionSelectpartialtall)
  161.     ON_COMMAND(ID_SELECTION_SELECTTOUCHING, CMainFrame::OnSelectionSelecttouching)
  162.     ON_COMMAND(ID_SELECTION_UNGROUPENTITY, CMainFrame::OnSelectionUngroupentity)
  163.     //}}AFX_MSG_MAP
  164.   ON_COMMAND_RANGE(ID_ENTITY_START, ID_ENTITY_END, OnEntityCreate)
  165. END_MESSAGE_MAP()
  166.  
  167.  
  168. /////////////////////////////////////////////////////////////////////////////
  169. // CXYWnd message handlers
  170. LONG WINAPI XYWndProc(HWND, UINT, WPARAM, LPARAM);
  171. BOOL CXYWnd::PreCreateWindow(CREATESTRUCT& cs) 
  172. {
  173.   WNDCLASS wc;
  174.   HINSTANCE hInstance = AfxGetInstanceHandle();
  175.   if (::GetClassInfo(hInstance, XY_WINDOW_CLASS, &wc) == FALSE)
  176.   {
  177.     // Register a new class
  178.       memset (&wc, 0, sizeof(wc));
  179.     wc.style         = CS_NOCLOSE | CS_OWNDC;
  180.     wc.lpszClassName = XY_WINDOW_CLASS;
  181.     wc.hCursor       = NULL; //LoadCursor (NULL,IDC_ARROW);
  182.     wc.lpfnWndProc   = ::DefWindowProc;
  183.     if (AfxRegisterClass(&wc) == FALSE)
  184.       Error ("CCamWnd RegisterClass: failed");
  185.   }
  186.  
  187.   cs.lpszClass = XY_WINDOW_CLASS;
  188.   cs.lpszName = "VIEW";
  189.   if (cs.style != QE3_CHILDSTYLE)
  190.     cs.style = QE3_SPLITTER_STYLE;
  191.  
  192.     return CWnd::PreCreateWindow(cs);
  193. }
  194.  
  195. HDC   s_hdcXY;
  196. HGLRC s_hglrcXY;
  197.  
  198. static unsigned s_stipple[32] =
  199. {
  200.     0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
  201.     0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
  202.     0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
  203.     0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
  204.     0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
  205.     0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
  206.     0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
  207.     0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
  208. };
  209.  
  210. /*
  211. ============
  212. WXY_WndProc
  213. ============
  214. */
  215. LONG WINAPI XYWndProc (
  216.     HWND    hWnd,
  217.     UINT    uMsg,
  218.     WPARAM  wParam,
  219.     LPARAM  lParam)
  220. {
  221.     switch (uMsg)
  222.     {
  223.     case WM_DESTROY:
  224.         QEW_StopGL( hWnd, s_hglrcXY, s_hdcXY );
  225.         return 0;
  226.  
  227.     case WM_NCCALCSIZE:// don't let windows copy pixels
  228.         DefWindowProc (hWnd, uMsg, wParam, lParam);
  229.         return WVR_REDRAW;
  230.  
  231.     case WM_KILLFOCUS:
  232.     case WM_SETFOCUS:
  233.         SendMessage( hWnd, WM_NCACTIVATE, uMsg == WM_SETFOCUS, 0 );
  234.         return 0;
  235.  
  236.        case WM_CLOSE:
  237.         DestroyWindow (hWnd);
  238.         return 0;
  239.     }
  240.  
  241.     return DefWindowProc (hWnd, uMsg, wParam, lParam);
  242. }
  243.  
  244.  
  245. static void WXY_InitPixelFormat( PIXELFORMATDESCRIPTOR *pPFD )
  246. {
  247.     memset( pPFD, 0, sizeof( *pPFD ) );
  248.  
  249.     pPFD->nSize    = sizeof( PIXELFORMATDESCRIPTOR );
  250.     pPFD->nVersion = 1;
  251.     pPFD->dwFlags  = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
  252.     pPFD->iPixelType = PFD_TYPE_RGBA;
  253.     pPFD->cColorBits = 24;
  254.     pPFD->cDepthBits = 32;
  255.     pPFD->iLayerType = PFD_MAIN_PLANE;
  256.  
  257. }
  258.  
  259. void WXY_Print( void )
  260. {
  261.     DOCINFO di;
  262.  
  263.     PRINTDLG pd;
  264.  
  265.     /*
  266.     ** initialize the PRINTDLG struct and execute it
  267.     */
  268.     memset( &pd, 0, sizeof( pd ) );
  269.     pd.lStructSize = sizeof( pd );
  270.     pd.hwndOwner = g_qeglobals.d_hwndXY;
  271.     pd.Flags = PD_RETURNDC;
  272.     pd.hInstance = 0;
  273.     if ( !PrintDlg( &pd ) || !pd.hDC )
  274.     {
  275.         MessageBox( g_qeglobals.d_hwndMain, "Could not PrintDlg()", "QE4 Print Error", MB_OK | MB_ICONERROR );
  276.         return;
  277.     }
  278.  
  279.     /*
  280.     ** StartDoc
  281.     */
  282.     memset( &di, 0, sizeof( di ) );
  283.     di.cbSize = sizeof( di );
  284.     di.lpszDocName = "QE4";
  285.     if ( StartDoc( pd.hDC, &di ) <= 0 )
  286.     {
  287.         MessageBox( g_qeglobals.d_hwndMain, "Could not StartDoc()", "QE4 Print Error", MB_OK | MB_ICONERROR );
  288.         return;
  289.     }
  290.  
  291.     /*
  292.     ** StartPage
  293.     */
  294.     if ( StartPage( pd.hDC ) <= 0 )
  295.     {
  296.         MessageBox( g_qeglobals.d_hwndMain, "Could not StartPage()", "QE4 Print Error", MB_OK | MB_ICONERROR );
  297.         return;
  298.     }
  299.  
  300.     /*
  301.     ** read pixels from the XY window
  302.     */
  303.     {
  304.         int bmwidth = 320, bmheight = 320;
  305.         int pwidth, pheight;
  306.  
  307.         RECT r;
  308.  
  309.         GetWindowRect( g_qeglobals.d_hwndXY, &r );
  310.  
  311.         bmwidth  = r.right - r.left;
  312.         bmheight = r.bottom - r.top;
  313.  
  314.         pwidth  = GetDeviceCaps( pd.hDC, PHYSICALWIDTH ) - GetDeviceCaps( pd.hDC, PHYSICALOFFSETX );
  315.         pheight = GetDeviceCaps( pd.hDC, PHYSICALHEIGHT ) - GetDeviceCaps( pd.hDC, PHYSICALOFFSETY );
  316.  
  317.         StretchBlt( pd.hDC,
  318.             0, 0,
  319.             pwidth, pheight,
  320.             s_hdcXY,
  321.             0, 0,
  322.             bmwidth, bmheight,
  323.             SRCCOPY );
  324.     }
  325.  
  326.     /*
  327.     ** EndPage and EndDoc
  328.     */
  329.     if ( EndPage( pd.hDC ) <= 0 )
  330.     {
  331.         MessageBox( g_qeglobals.d_hwndMain, "QE4 Print Error", "Could not EndPage()", MB_OK | MB_ICONERROR );
  332.         return;
  333.     }
  334.  
  335.     if ( EndDoc( pd.hDC ) <= 0 )
  336.     {
  337.         MessageBox( g_qeglobals.d_hwndMain, "QE4 Print Error", "Could not EndDoc()", MB_OK | MB_ICONERROR );
  338.         return;
  339.     }
  340. }
  341.  
  342. int CXYWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  343. {
  344.     if (CWnd::OnCreate(lpCreateStruct) == -1)
  345.         return -1;
  346.  
  347.   s_hdcXY = ::GetDC(GetSafeHwnd());
  348.     QEW_SetupPixelFormat(s_hdcXY, false);
  349.     if ( ( s_hglrcXY = qwglCreateContext( s_hdcXY ) ) == 0 )
  350.       Error( "wglCreateContext in WXY_WndProc failed" );
  351.  
  352.     if (!qwglShareLists( g_qeglobals.d_hglrcBase, s_hglrcXY ) )
  353.       Error( "wglShareLists in WXY_WndProc failed" );
  354.  
  355.   if (!qwglMakeCurrent( s_hdcXY, s_hglrcXY ))
  356.       Error ("wglMakeCurrent failed");
  357.  
  358.     qglPolygonStipple ((unsigned char *)s_stipple);
  359.     qglLineStipple (3, 0xaaaa);
  360.   g_qeglobals.d_hwndXY = GetSafeHwnd();
  361.     return 0;
  362. }
  363.  
  364. float ptSum(vec3_t pt)
  365. {
  366.   return pt[0] + pt[1] + pt[2];
  367. }
  368.  
  369. void CXYWnd::DropClipPoint(UINT nFlags, CPoint point)
  370. {
  371.   CRect rctZ;
  372.   GetClientRect(rctZ);
  373.   if (g_pMovingClip)
  374.   {
  375.     SetCapture();
  376.     SnapToPoint (point.x, rctZ.Height() - 1 - point.y , *g_pMovingClip);
  377.   }
  378.   else
  379.   {
  380.     vec3_t* pPt = NULL;
  381.     if (g_Clip1.Set() == false)
  382.     {
  383.       pPt = g_Clip1;
  384.       g_Clip1.Set(true);
  385.       g_Clip1.m_ptScreen = point;
  386.     }
  387.     else 
  388.     if (g_Clip2.Set() == false)
  389.     {
  390.       pPt = g_Clip2;
  391.       g_Clip2.Set(true);
  392.       g_Clip2.m_ptScreen = point;
  393.     }
  394.     else 
  395.     if (g_Clip3.Set() == false)
  396.     {
  397.       pPt = g_Clip3;
  398.       g_Clip3.Set(true);
  399.       g_Clip3.m_ptScreen = point;
  400.     }
  401.     else 
  402.     {
  403.       RetainClipMode(true);
  404.       pPt = g_Clip1;
  405.       g_Clip1.Set(true);
  406.       g_Clip1.m_ptScreen = point;
  407.     }
  408.     SnapToPoint (point.x, rctZ.Height() - 1 - point.y , *pPt);
  409.   }
  410.   Sys_UpdateWindows(XY | W_CAMERA_IFON);
  411. }
  412.  
  413.  
  414. void CXYWnd::DropPathPoint(UINT nFlags, CPoint point)
  415. {
  416.   CRect rctZ;
  417.   GetClientRect(rctZ);
  418.   if (g_pMovingPath)
  419.   {
  420.     SetCapture();
  421.     SnapToPoint (point.x, rctZ.Height() - 1 - point.y , *g_pMovingPath);
  422.   }
  423.   else
  424.   {
  425.     g_PathPoints[g_nPathCount].Set(true);
  426.     g_PathPoints[g_nPathCount].m_ptScreen = point;
  427.     SnapToPoint(point.x, rctZ.Height() - 1 - point.y, g_PathPoints[g_nPathCount]);
  428.     g_nPathCount++;
  429.     if (g_nPathCount == g_nPathLimit)
  430.     {
  431.       if (g_pPathFunc)
  432.         g_pPathFunc(true, g_nPathCount);
  433.       g_nPathCount = 0;
  434.       g_bPathMode = false;
  435.       g_pPathFunc = NULL;
  436.     }
  437.   }
  438.   Sys_UpdateWindows(XY | W_CAMERA_IFON);
  439. }
  440.  
  441. void CXYWnd::AddPointPoint(UINT nFlags, vec3_t* pVec)
  442. {
  443.   g_PointPoints[g_nPointCount].Set(true);
  444.   //g_PointPoints[g_nPointCount].m_ptScreen = point;
  445.   _VectorCopy(*pVec, g_PointPoints[g_nPointCount]);
  446.   g_PointPoints[g_nPointCount].SetPointPtr(pVec);
  447.   g_nPointCount++;
  448.   Sys_UpdateWindows(XY | W_CAMERA_IFON);
  449. }
  450.  
  451.  
  452. void CXYWnd::OnLButtonDown(UINT nFlags, CPoint point) 
  453. {
  454.   g_pParentWnd->SetActiveXY(this);
  455.   UndoCopy();
  456.  
  457.     // plugin entities
  458.     if (DispatchOnLButtonDown(nFlags, point.x, point.y ))
  459.         return;
  460.  
  461.   if (ClipMode() && !RogueClipMode())
  462.   {
  463.     DropClipPoint(nFlags, point);
  464.   }
  465.   else if (PathMode())
  466.   {
  467.     DropPathPoint(nFlags, point);
  468.   }
  469.   else OriginalButtonDown(nFlags, point);
  470. }
  471.  
  472. void CXYWnd::OnMButtonDown(UINT nFlags, CPoint point) 
  473. {
  474.   OriginalButtonDown(nFlags, point);
  475. }
  476.  
  477.  
  478. float Betwixt(float f1, float f2)
  479. {
  480.   if (f1 > f2)
  481.     return f2 + ((f1 - f2) / 2);
  482.   else
  483.     return f1 + ((f2 - f1) / 2);
  484. }
  485.  
  486. void CXYWnd::ProduceSplits(brush_t** pFront, brush_t** pBack)
  487. {
  488.   *pFront = NULL;
  489.   *pBack = NULL;
  490.   if (ClipMode())
  491.   {
  492.     if (g_Clip1.Set() && g_Clip2.Set())
  493.     {
  494.       face_t face;
  495.       VectorCopy(g_Clip1.m_ptClip,face.planepts[0]);
  496.       VectorCopy(g_Clip2.m_ptClip,face.planepts[1]);
  497.       VectorCopy(g_Clip3.m_ptClip,face.planepts[2]);
  498.       if (selected_brushes.next && (selected_brushes.next->next == &selected_brushes))
  499.       {
  500.         if (g_Clip3.Set() == false)
  501.         {
  502.           if (m_nViewType == XY)
  503.           {
  504.             face.planepts[0][2] = selected_brushes.next->mins[2];
  505.             face.planepts[1][2] = selected_brushes.next->mins[2];
  506.             face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]);
  507.             face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);
  508.             face.planepts[2][2] = selected_brushes.next->maxs[2];
  509.           }
  510.           else if (m_nViewType == YZ)
  511.           {
  512.             face.planepts[0][0] = selected_brushes.next->mins[0];
  513.             face.planepts[1][0] = selected_brushes.next->mins[0];
  514.             face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);
  515.             face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]);
  516.             face.planepts[2][0] = selected_brushes.next->maxs[0];
  517.           }
  518.           else
  519.           {
  520.             face.planepts[0][1] = selected_brushes.next->mins[1];
  521.             face.planepts[1][1] = selected_brushes.next->mins[1];
  522.             face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]);
  523.             face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]);
  524.             face.planepts[2][1] = selected_brushes.next->maxs[1];
  525.           }
  526.         }
  527.  
  528.         Brush_SplitBrushByFace (selected_brushes.next, &face, pFront, pBack);
  529.       }
  530.  
  531.     }
  532.   }
  533. }
  534.  
  535. void CleanList(brush_t* pList)
  536. {
  537.   brush_t* pBrush = pList->next; 
  538.   while (pBrush != NULL && pBrush != pList)
  539.   {
  540.     brush_t* pNext = pBrush->next;
  541.     Brush_Free(pBrush);
  542.     pBrush = pNext;
  543.   }
  544. }
  545.  
  546. void CXYWnd::ProduceSplitLists()
  547. {
  548.   if (AnyPatchesSelected())
  549.   {
  550.     Sys_Printf("Deslecting patches for clip operation.\n");
  551.     brush_t *next;
  552.       for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = next)
  553.       {
  554.       next = pb->next;
  555.       if (pb->patchBrush)
  556.       {
  557.             Brush_RemoveFromList (pb);
  558.             Brush_AddToList (pb, &active_brushes);
  559.         UpdatePatchInspector();
  560.       }
  561.     }
  562.   }
  563.  
  564.   CleanList(&g_brFrontSplits);
  565.   CleanList(&g_brBackSplits);
  566.   g_brFrontSplits.next = &g_brFrontSplits;
  567.   g_brBackSplits.next = &g_brBackSplits;
  568.   brush_t* pBrush;
  569.     for (pBrush = selected_brushes.next ; pBrush != NULL && pBrush != &selected_brushes ; pBrush=pBrush->next)
  570.   {
  571.     brush_t* pFront = NULL;
  572.     brush_t* pBack = NULL;
  573.     if (ClipMode())
  574.     {
  575.       if (g_Clip1.Set() && g_Clip2.Set())
  576.       {
  577.         face_t face;
  578.         VectorCopy(g_Clip1.m_ptClip,face.planepts[0]);
  579.         VectorCopy(g_Clip2.m_ptClip,face.planepts[1]);
  580.         VectorCopy(g_Clip3.m_ptClip,face.planepts[2]);
  581.         if (g_Clip3.Set() == false)
  582.         {
  583.           if (g_pParentWnd->ActiveXY()->GetViewType() == XY)
  584.           {
  585.             face.planepts[0][2] = pBrush->mins[2];
  586.             face.planepts[1][2] = pBrush->mins[2];
  587.             face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]);
  588.             face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);
  589.             face.planepts[2][2] = pBrush->maxs[2];
  590.           }
  591.           else if (g_pParentWnd->ActiveXY()->GetViewType() == YZ)
  592.           {
  593.             face.planepts[0][0] = pBrush->mins[0];
  594.             face.planepts[1][0] = pBrush->mins[0];
  595.             face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);
  596.             face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]);
  597.             face.planepts[2][0] = pBrush->maxs[0];
  598.           }
  599.           else
  600.           {
  601.             face.planepts[0][1] = pBrush->mins[1];
  602.             face.planepts[1][1] = pBrush->mins[1];
  603.             face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]);
  604.             face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]);
  605.             face.planepts[2][1] = pBrush->maxs[1];
  606.           }
  607.         }
  608.         Brush_SplitBrushByFace (pBrush, &face, &pFront, &pBack);
  609.         if (pBack)
  610.           Brush_AddToList(pBack, &g_brBackSplits);
  611.         if (pFront)
  612.           Brush_AddToList(pFront, &g_brFrontSplits);
  613.       }
  614.     }
  615.   }
  616. }
  617.  
  618. void Brush_CopyList (brush_t* pFrom, brush_t* pTo)
  619. {
  620.     brush_t* pBrush = pFrom->next; 
  621.     while (pBrush != NULL && pBrush != pFrom)
  622.     {
  623.         brush_t* pNext = pBrush->next;
  624.         Brush_RemoveFromList(pBrush);
  625.         Brush_AddToList(pBrush, pTo);
  626.         pBrush = pNext;
  627.     }
  628. }
  629.  
  630. void CXYWnd::OnRButtonDown(UINT nFlags, CPoint point) 
  631. {
  632.   g_pParentWnd->SetActiveXY(this);
  633.   m_ptDown = point;
  634.   m_bRButtonDown = true;
  635.  
  636.   if (g_PrefsDlg.m_nMouseButtons == 3) // 3 button mouse 
  637.   {
  638.     if ((GetKeyState(VK_CONTROL) & 0x8000))
  639.     {
  640.       if (ClipMode()) // already there?
  641.         DropClipPoint(nFlags, point);
  642.       else
  643.       {
  644.         SetClipMode(true);
  645.         g_bRogueClipMode = true;
  646.         DropClipPoint(nFlags, point);
  647.       }
  648.       return;
  649.     }
  650.   }
  651.   OriginalButtonDown(nFlags, point);
  652. }
  653.  
  654. void CXYWnd::OnLButtonUp(UINT nFlags, CPoint point) 
  655. {
  656.     // plugin entities
  657.     if (DispatchOnLButtonUp(nFlags, point.x, point.y ))
  658.         return;
  659.  
  660.     if (ClipMode())
  661.   {
  662.     if (g_pMovingClip)
  663.     {
  664.       ReleaseCapture();
  665.       g_pMovingClip = NULL;
  666.     }
  667.   }
  668.   OriginalButtonUp(nFlags, point);
  669. }
  670.  
  671. void CXYWnd::OnMButtonUp(UINT nFlags, CPoint point) 
  672. {
  673.   OriginalButtonUp(nFlags, point);
  674. }
  675.  
  676. void CXYWnd::OnRButtonUp(UINT nFlags, CPoint point) 
  677. {
  678.   m_bRButtonDown = false;
  679.   if (point == m_ptDown)    // mouse didn't move
  680.   {
  681.     bool bGo = true;
  682.     if ((GetKeyState(VK_MENU) & 0x8000))
  683.       bGo = false;
  684.     if ((GetKeyState(VK_CONTROL) & 0x8000))
  685.       bGo = false;
  686.     if ((GetKeyState(VK_SHIFT) & 0x8000))
  687.       bGo = false;
  688.     if (bGo)
  689.       HandleDrop();
  690.   }
  691.   OriginalButtonUp(nFlags, point);
  692. }
  693.  
  694. void CXYWnd::OriginalButtonDown(UINT nFlags, CPoint point)
  695. {
  696.   CRect rctZ;
  697.   GetClientRect(rctZ);
  698.   SetWindowPos(&wndTop, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
  699.   if (::GetTopWindow( g_qeglobals.d_hwndMain ) != GetSafeHwnd())
  700.     ::BringWindowToTop(GetSafeHwnd());
  701.     SetFocus();
  702.     SetCapture();
  703.     XY_MouseDown (point.x, rctZ.Height() - 1 - point.y , nFlags);
  704.   m_nScrollFlags = nFlags;
  705. }          
  706.  
  707. void CXYWnd::OriginalButtonUp(UINT nFlags, CPoint point)
  708. {
  709.   CRect rctZ;
  710.   GetClientRect(rctZ);
  711.   XY_MouseUp (point.x, rctZ.Height() - 1 - point.y , nFlags);
  712.     if (! (nFlags & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON)))
  713.         ReleaseCapture ();
  714. }
  715.  
  716.  
  717. float fDiff(float f1, float f2)
  718. {
  719.   if (f1 > f2)
  720.     return f1 - f2;
  721.   else
  722.     return f2 - f1;
  723. }
  724.  
  725.  
  726. vec3_t tdp;
  727. void CXYWnd::OnMouseMove(UINT nFlags, CPoint point) 
  728. {
  729.     // plugin entities
  730.     //++timo TODO: handle return code
  731.     DispatchOnMouseMove( nFlags, point.x, point.y );
  732.  
  733.   m_ptDown.x = 0;
  734.   m_ptDown.y = 0;
  735.  
  736.   if ( g_PrefsDlg.m_bChaseMouse == TRUE &&
  737.        (point.x < 0 || point.y < 0 || 
  738.        point.x > m_nWidth || point.y > m_nHeight) &&
  739.        GetCapture() == this)
  740.   {
  741.     float fAdjustment = (g_qeglobals.d_gridsize / 8 * 64) / m_fScale;
  742.     //m_ptDrag = point;
  743.     m_ptDragAdj.x = 0;
  744.     m_ptDragAdj.y = 0;
  745.     if (point.x < 0)
  746.     {
  747.       m_ptDragAdj.x = -fAdjustment;
  748.     }
  749.     else 
  750.     if (point.x > m_nWidth)
  751.     {
  752.       m_ptDragAdj.x = fAdjustment;
  753.     }
  754.     if (point.y < 0)
  755.     {
  756.       m_ptDragAdj.y = -fAdjustment;
  757.     }
  758.     else
  759.     if (point.y > m_nHeight)
  760.     {
  761.       m_ptDragAdj.y = fAdjustment;
  762.     }
  763.     if (m_nTimerID == -1)
  764.     {
  765.       m_nTimerID = SetTimer(100, 50, NULL);
  766.       m_ptDrag = point;
  767.       m_ptDragTotal = 0;
  768.     }
  769.     return;
  770.   }
  771.   //else if (m_nTimerID != -1)
  772.   if (m_nTimerID != -1)
  773.   {
  774.     KillTimer(m_nTimerID);
  775.     pressx -= m_ptDragTotal.x;
  776.     pressy += m_ptDragTotal.y;
  777.     m_nTimerID = -1;
  778.     //return;
  779.   }
  780.  
  781.   bool bCrossHair = false;
  782.   if (!m_bRButtonDown)
  783.   {
  784.     tdp[0] = tdp[1] = tdp[2] = 0.0;
  785.     SnapToPoint (point.x, m_nHeight - 1 - point.y , tdp);
  786.  
  787.     g_strStatus.Format("x:: %.1f  y:: %.1f  z:: %.1f", tdp[0], tdp[1], tdp[2]);
  788.     g_pParentWnd->SetStatusText(1, g_strStatus);
  789.  
  790.     // i need to generalize the point code.. having 3 flavors pretty much sucks.. 
  791.     // once the new curve stuff looks like it is going to stick i will 
  792.     // rationalize this down to a single interface.. 
  793.     if (PointMode())
  794.     {
  795.       if (g_pMovingPoint && GetCapture() == this)
  796.       {
  797.         bCrossHair = true;
  798.         SnapToPoint (point.x, m_nHeight - 1 - point.y , g_pMovingPoint->m_ptClip);
  799.         g_pMovingPoint->UpdatePointPtr();
  800.         Sys_UpdateWindows(XY | W_CAMERA_IFON);
  801.       }
  802.       else
  803.       {
  804.         g_pMovingPoint = NULL;
  805.         int nDim1 = (m_nViewType == YZ) ? 1 : 0;
  806.         int nDim2 = (m_nViewType == XY) ? 1 : 2;
  807.         for (int n = 0; n < g_nPointCount; n++)
  808.         {
  809.           if ( fDiff(g_PointPoints[n].m_ptClip[nDim1], tdp[nDim1]) < 3 &&
  810.                fDiff(g_PointPoints[n].m_ptClip[nDim2], tdp[nDim2]) < 3 )
  811.           {
  812.             bCrossHair = true;
  813.             g_pMovingPoint = &g_PointPoints[n];
  814.           }
  815.         }
  816.       }
  817.     }
  818.     else if (ClipMode())
  819.     {
  820.       if (g_pMovingClip && GetCapture() == this)
  821.       {
  822.         bCrossHair = true;
  823.         SnapToPoint (point.x, m_nHeight - 1 - point.y , g_pMovingClip->m_ptClip);
  824.         Sys_UpdateWindows(XY | W_CAMERA_IFON);
  825.       }
  826.       else
  827.       {
  828.         g_pMovingClip = NULL;
  829.         int nDim1 = (m_nViewType == YZ) ? 1 : 0;
  830.         int nDim2 = (m_nViewType == XY) ? 1 : 2;
  831.         if (g_Clip1.Set())
  832.         {
  833.           if ( fDiff(g_Clip1.m_ptClip[nDim1], tdp[nDim1]) < 3 &&
  834.                fDiff(g_Clip1.m_ptClip[nDim2], tdp[nDim2]) < 3 )
  835.           {
  836.             bCrossHair = true;
  837.             g_pMovingClip = &g_Clip1;
  838.           }
  839.         }
  840.         if (g_Clip2.Set())
  841.         {
  842.           if ( fDiff(g_Clip2.m_ptClip[nDim1], tdp[nDim1]) < 3 &&
  843.                fDiff(g_Clip2.m_ptClip[nDim2], tdp[nDim2]) < 3 )
  844.           {
  845.             bCrossHair = true;
  846.             g_pMovingClip = &g_Clip2;
  847.           }
  848.         }
  849.         if (g_Clip3.Set())
  850.         {
  851.           if ( fDiff(g_Clip3.m_ptClip[nDim1], tdp[nDim1]) < 3 &&
  852.                fDiff(g_Clip3.m_ptClip[nDim2], tdp[nDim2]) < 3 )
  853.           {
  854.             bCrossHair = true;
  855.             g_pMovingClip = &g_Clip3;
  856.           }
  857.         }
  858.       }
  859.       if (bCrossHair == false)
  860.         XY_MouseMoved (point.x, m_nHeight - 1 - point.y , nFlags);
  861.     }
  862.     else if (PathMode())
  863.     {
  864.       if (g_pMovingPath && GetCapture() == this)
  865.       {
  866.         bCrossHair = true;
  867.         SnapToPoint (point.x, m_nHeight - 1 - point.y , g_pMovingPath->m_ptClip);
  868.         Sys_UpdateWindows(XY | W_CAMERA_IFON);
  869.       }
  870.       else
  871.       {
  872.         g_pMovingPath = NULL;
  873.         int nDim1 = (m_nViewType == YZ) ? 1 : 0;
  874.         int nDim2 = (m_nViewType == XY) ? 1 : 2;
  875.         for (int n = 0; n < g_nPathCount; n++)
  876.         {
  877.           if ( fDiff(g_PathPoints[n].m_ptClip[nDim1], tdp[nDim1]) < 3 &&
  878.                fDiff(g_PathPoints[n].m_ptClip[nDim2], tdp[nDim2]) < 3 )
  879.           {
  880.             bCrossHair = true;
  881.             g_pMovingPath = &g_PathPoints[n];
  882.           }
  883.         }
  884.       }
  885.     }
  886.     else
  887.     {
  888.       XY_MouseMoved (point.x, m_nHeight - 1 - point.y , nFlags);
  889.     }
  890.   }
  891.   else 
  892.   {
  893.     XY_MouseMoved (point.x, m_nHeight - 1 - point.y , nFlags);
  894.   }
  895.   if (bCrossHair)
  896.     SetCursor(::LoadCursor(NULL, IDC_CROSS));
  897.   else
  898.     SetCursor(::LoadCursor(NULL, IDC_ARROW));
  899. }
  900.  
  901. void CXYWnd::RetainClipMode(bool bMode)
  902. {
  903.   bool bSave = g_bRogueClipMode;
  904.   SetClipMode(bMode);
  905.   if (bMode == true)
  906.     g_bRogueClipMode = bSave;
  907.   else
  908.     g_bRogueClipMode = false;
  909. }
  910.  
  911. void CXYWnd::SetClipMode(bool bMode)
  912. {
  913.   g_bClipMode = bMode;
  914.   g_bRogueClipMode = false;
  915.   if (bMode)
  916.   {
  917.     g_Clip1.Reset();
  918.     g_Clip2.Reset();
  919.     g_Clip3.Reset();
  920.     CleanList(&g_brFrontSplits);
  921.     CleanList(&g_brBackSplits);
  922.     g_brFrontSplits.next = &g_brFrontSplits;
  923.     g_brBackSplits.next = &g_brBackSplits;
  924.   }
  925.   else
  926.   {
  927.     if (g_pMovingClip)
  928.     {
  929.       ReleaseCapture();
  930.       g_pMovingClip = NULL;
  931.     }
  932.     CleanList(&g_brFrontSplits);
  933.     CleanList(&g_brBackSplits);
  934.     g_brFrontSplits.next = &g_brFrontSplits;
  935.     g_brBackSplits.next = &g_brBackSplits;
  936.     Sys_UpdateWindows(XY | W_CAMERA_IFON);
  937.   }
  938. }
  939.  
  940. bool CXYWnd::ClipMode()
  941. {
  942.   return g_bClipMode;
  943. }
  944.  
  945. bool CXYWnd::RogueClipMode()
  946. {
  947.   return g_bRogueClipMode;
  948. }
  949.  
  950. bool CXYWnd::PathMode()
  951. {
  952.   return g_bPathMode;
  953. }
  954.  
  955.  
  956. bool CXYWnd::PointMode()
  957. {
  958.   return g_bPointMode;
  959. }
  960.  
  961. void CXYWnd::SetPointMode(bool b)
  962. {
  963.   g_bPointMode = b;
  964.   if (!b)
  965.     g_nPointCount = 0;
  966. }
  967.  
  968.  
  969. void CXYWnd::OnPaint() 
  970. {
  971.     CPaintDC dc(this); // device context for painting
  972.   bool bPaint = true;
  973.   if (!qwglMakeCurrent(dc.m_hDC, s_hglrcXY))
  974.   {
  975.     Sys_Printf("ERROR: wglMakeCurrent failed.. Error:%i\n",qglGetError());
  976.     Sys_Printf("Please restart Q3Radiant if the Map view is not working\n");
  977.     bPaint = false;
  978.   }
  979.   if (bPaint)
  980.   {
  981.     QE_CheckOpenGLForErrors();
  982.         XY_Draw ();
  983.     QE_CheckOpenGLForErrors();
  984.  
  985.     if (m_nViewType != XY)
  986.     {
  987.       qglPushMatrix();
  988.       if (m_nViewType == YZ)
  989.         qglRotatef (-90,  0, 1, 0);        // put Z going up
  990.       qglRotatef (-90,  1, 0, 0);        // put Z going up
  991.     }
  992.  
  993.     if (g_bCrossHairs)
  994.     {
  995.         qglColor4f(0.2, 0.9, 0.2, 0.8);
  996.           qglBegin (GL_LINES);
  997.       if (m_nViewType == XY)
  998.       {
  999.         qglVertex2f(-16384, tdp[1]);
  1000.         qglVertex2f(16384, tdp[1]);
  1001.         qglVertex2f(tdp[0], -16384);
  1002.         qglVertex2f(tdp[0], 16384);
  1003.       }
  1004.       else if (m_nViewType == YZ)
  1005.       {
  1006.         qglVertex3f(tdp[0], -16384, tdp[2]);
  1007.         qglVertex3f(tdp[0], 16384, tdp[2]);
  1008.         qglVertex3f(tdp[0], tdp[1], -16384);
  1009.         qglVertex3f(tdp[0], tdp[1], 16384);
  1010.       }
  1011.       else
  1012.       {
  1013.         qglVertex3f(-16384, tdp[1], tdp[2]);
  1014.         qglVertex3f( 16384, tdp[1], tdp[2]);
  1015.         qglVertex3f(tdp[0], tdp[1], -16384);
  1016.         qglVertex3f(tdp[0], tdp[1], 16384);
  1017.       }
  1018.           qglEnd();
  1019.     }
  1020.  
  1021.     if (ClipMode())
  1022.     {
  1023.       qglPointSize (4);
  1024.           qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER]);
  1025.           qglBegin (GL_POINTS);
  1026.       if (g_Clip1.Set())
  1027.               qglVertex3fv (g_Clip1);
  1028.       if (g_Clip2.Set())
  1029.               qglVertex3fv (g_Clip2);
  1030.       if (g_Clip3.Set())
  1031.               qglVertex3fv (g_Clip3);
  1032.           qglEnd ();
  1033.           qglPointSize (1);
  1034.  
  1035.       CString strMsg;
  1036.       if (g_Clip1.Set())
  1037.       {
  1038.         qglRasterPos3f (g_Clip1.m_ptClip[0]+2, g_Clip1.m_ptClip[1]+2, g_Clip1.m_ptClip[2]+2);
  1039.         strMsg = "1";
  1040.         //strMsg.Format("1 (%f, %f, %f)", g_Clip1[0], g_Clip1[1], g_Clip1[2]);
  1041.           qglCallLists (strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg);
  1042.       }
  1043.       if (g_Clip2.Set())
  1044.       {
  1045.         qglRasterPos3f (g_Clip2.m_ptClip[0]+2, g_Clip2.m_ptClip[1]+2, g_Clip2.m_ptClip[2]+2);
  1046.         strMsg = "2";
  1047.         //strMsg.Format("2 (%f, %f, %f)", g_Clip2[0], g_Clip2[1], g_Clip2[2]);
  1048.           qglCallLists (strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg);
  1049.       }
  1050.       if (g_Clip3.Set())
  1051.       {
  1052.         qglRasterPos3f (g_Clip3.m_ptClip[0]+2, g_Clip3.m_ptClip[1]+2, g_Clip3.m_ptClip[2]+2);
  1053.         strMsg = "3";
  1054.         //strMsg.Format("3 (%f, %f, %f)", g_Clip3[0], g_Clip3[1], g_Clip3[2]);
  1055.           qglCallLists (strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg);
  1056.       }
  1057.       if (g_Clip1.Set() && g_Clip2.Set())
  1058.       {
  1059.         ProduceSplitLists();
  1060.         brush_t* pBrush;
  1061.         brush_t* pList = ( (m_nViewType == XZ) ? !g_bSwitch : g_bSwitch) ? &g_brBackSplits : &g_brFrontSplits;
  1062.           for (pBrush = pList->next ; pBrush != NULL && pBrush != pList ; pBrush=pBrush->next)
  1063.         {
  1064.               qglColor3f (1,1,0);
  1065.             face_t *face;
  1066.             int order;
  1067.             for (face = pBrush->brush_faces,order = 0 ; face ; face=face->next, order++)
  1068.             {
  1069.                 winding_t* w = face->face_winding;
  1070.                 if (!w)
  1071.                     continue;
  1072.                 // draw the polygon
  1073.                 qglBegin(GL_LINE_LOOP);
  1074.             for (int i=0 ; i<w->numpoints ; i++)
  1075.                   qglVertex3fv(w->points[i]);
  1076.                 qglEnd();
  1077.             }
  1078.         }
  1079.       }
  1080.  
  1081.     }
  1082.  
  1083.  
  1084.  
  1085.     if (PathMode())
  1086.     {
  1087.       qglPointSize (4);
  1088.           qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER]);
  1089.           qglBegin (GL_POINTS);
  1090.  
  1091.       for (int n = 0; n < g_nPathCount; n++)
  1092.         qglVertex3fv(g_PathPoints[n]);
  1093.           qglEnd ();
  1094.           qglPointSize (1);
  1095.  
  1096.       CString strMsg;
  1097.       for (n = 0; n < g_nPathCount; n++)
  1098.       {
  1099.         qglRasterPos3f (g_PathPoints[n].m_ptClip[0]+2, g_PathPoints[n].m_ptClip[1]+2, g_PathPoints[n].m_ptClip[2]+2);
  1100.         strMsg.Format("%i", n+1);
  1101.           qglCallLists (strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg);
  1102.       }
  1103.  
  1104.     }
  1105.     if (m_nViewType != XY)
  1106.       qglPopMatrix();
  1107.  
  1108.         qwglSwapBuffers(dc.m_hDC);
  1109.     TRACE("XY Paint\n");
  1110.   }
  1111.  }
  1112.  
  1113. void CXYWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  1114. {
  1115.   g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags);
  1116. }
  1117.  
  1118.  
  1119.  
  1120. // FIXME: the brush_t *pBrush is never used. ( Entity_Create uses selected_brushes )
  1121. void CreateEntityFromName(char* pName, brush_t* pBrush)
  1122. {
  1123.     eclass_t *pecNew;
  1124.     entity_t *petNew;
  1125.     if (stricmp(pName, "worldspawn") == 0)
  1126.     {
  1127.         MessageBox(g_qeglobals.d_hwndMain, "Can't create an entity with worldspawn.", "info", 0);
  1128.         return;
  1129.     }
  1130.     
  1131.     pecNew = Eclass_ForName(pName, false);
  1132.     
  1133.     // create it
  1134.     petNew = Entity_Create(pecNew);
  1135.     if (petNew == NULL)
  1136.     {
  1137.         if (!((selected_brushes.next == &selected_brushes)||(selected_brushes.next->next != &selected_brushes)))
  1138.         {
  1139.             brush_t* b = selected_brushes.next;
  1140.             if (b->owner != world_entity && b->owner->eclass->fixedsize && pecNew->fixedsize)
  1141.             {
  1142.                 vec3_t mins, maxs;
  1143.                 vec3_t origin;
  1144.                 for (int i=0 ; i<3 ; i++)
  1145.                     origin[i] = b->mins[i] - pecNew->mins[i];
  1146.                 
  1147.                 VectorAdd (pecNew->mins, origin, mins);
  1148.                 VectorAdd (pecNew->maxs, origin, maxs);
  1149.                 brush_t* nb = Brush_Create (mins, maxs, &pecNew->texdef);
  1150.                 Entity_LinkBrush (b->owner, nb);
  1151.                 nb->owner->eclass = pecNew;
  1152.                 SetKeyValue (nb->owner, "classname", pName);
  1153.                 Brush_Free(b);
  1154.                 Brush_Build(nb);
  1155.                 Brush_AddToList (nb, &active_brushes);
  1156.                 Select_Brush(nb);
  1157.                 return;
  1158.             }
  1159.         }
  1160.         MessageBox(g_qeglobals.d_hwndMain, "Failed to create entity.", "info", 0);
  1161.         return;
  1162.     }
  1163.     
  1164.     Select_Deselect ();
  1165.     //entity_t* pEntity = world_entity;
  1166.     //if (selected_brushes.next != &selected_brushes)
  1167.     //    pEntity = selected_brushes.next->owner;
  1168.     Select_Brush (petNew->brushes.onext);
  1169.     
  1170.     if (stricmp(pName, "misc_model") == 0)
  1171.     {
  1172.         SetInspectorMode(W_ENTITY);
  1173.         PostMessage(g_qeglobals.d_hwndEntity, WM_COMMAND, IDC_BTN_ASSIGNMODEL, 0);
  1174.     }
  1175.     
  1176. }
  1177.  
  1178.  
  1179. brush_t* CreateEntityBrush(int x, int y, CXYWnd* pWnd)
  1180. {
  1181.     vec3_t    mins, maxs;
  1182.     int        i;
  1183.     float    temp;
  1184.     brush_t    *n;
  1185.  
  1186.     pWnd->SnapToPoint (x, y, mins);
  1187.   x += 32;
  1188.   y += 32;
  1189.     pWnd->SnapToPoint (x, y, maxs);
  1190.  
  1191.   int nDim = (pWnd->GetViewType() == XY) ? 2 : (pWnd->GetViewType() == YZ) ? 0 : 1;
  1192.     mins[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_bottom_z/g_qeglobals.d_gridsize));
  1193.     maxs[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_top_z/g_qeglobals.d_gridsize));
  1194.  
  1195.   if (maxs[nDim] <= mins[nDim])
  1196.         maxs[nDim] = mins[nDim] + g_qeglobals.d_gridsize;
  1197.  
  1198.     for (i=0 ; i<3 ; i++)
  1199.     {
  1200.         if (mins[i] == maxs[i])
  1201.             maxs[i] += 16;    // don't create a degenerate brush
  1202.         if (mins[i] > maxs[i])
  1203.         {
  1204.             temp = mins[i];
  1205.             mins[i] = maxs[i];
  1206.             maxs[i] = temp;
  1207.         }
  1208.     }
  1209.  
  1210.     n = Brush_Create (mins, maxs, &g_qeglobals.d_texturewin.texdef);
  1211.     if (!n)
  1212.         return NULL;
  1213.  
  1214.     Brush_AddToList (n, &selected_brushes);
  1215.     Entity_LinkBrush (world_entity, n);
  1216.     Brush_Build( n );
  1217.   return n;
  1218. }
  1219.  
  1220. void CreateRightClickEntity(CXYWnd* pWnd, int x, int y, char* pName)
  1221. {
  1222.   CRect rctZ;
  1223.   pWnd->GetClientRect(rctZ);
  1224.   brush_t* pBrush = (selected_brushes.next == &selected_brushes) ? CreateEntityBrush(x, rctZ.Height() - 1 - y, pWnd) : selected_brushes.next;
  1225.   CreateEntityFromName(pName, pBrush);
  1226.   //Select_Brush(pBrush);
  1227. }
  1228.  
  1229. brush_t* CreateSmartBrush(vec3_t v)
  1230. {
  1231.     vec3_t    mins, maxs;
  1232.     int        i;
  1233.     brush_t    *n;
  1234.  
  1235.     for (i=0 ; i<3 ; i++)
  1236.     {
  1237.     mins[i] = v[i] - 16;
  1238.     maxs[i] = v[i] + 16;
  1239.   }
  1240.  
  1241.     n = Brush_Create (mins, maxs, &g_qeglobals.d_texturewin.texdef);
  1242.     if (!n)
  1243.         return NULL;
  1244.  
  1245.     Brush_AddToList(n, &selected_brushes);
  1246.     //Entity_LinkBrush(world_entity, n);
  1247.     Brush_Build(n);
  1248.   return n;
  1249. }
  1250.  
  1251.  
  1252.  
  1253.  
  1254. CString g_strSmartEntity;
  1255. int g_nSmartX;
  1256. int g_nSmartY;
  1257. bool g_bSmartWaiting;
  1258. void _SmartPointDone(bool b, int n)
  1259. {
  1260.   g_bSmartWaiting = false;
  1261. }
  1262.  
  1263. void CreateSmartEntity(CXYWnd* pWnd, int x, int y, const char* pName)
  1264. {
  1265.   g_nSmartX = x;
  1266.   g_nSmartY = y;
  1267.   g_strSmartEntity = pName;
  1268.   if (g_strSmartEntity.Find("Smart_Train") >= 0)
  1269.   {
  1270.     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");
  1271.     g_bPathMode = true;
  1272.     g_nPathLimit = 0;
  1273.     g_nPathCount = 0;
  1274.     g_bSmartGo = true;
  1275.   }
  1276.   else
  1277.   if (g_strSmartEntity.Find("Smart_Monster...") >= 0)
  1278.   {
  1279.     g_bPathMode = true;
  1280.     g_nPathLimit = 0;
  1281.     g_nPathCount = 0;
  1282.   }
  1283.   else
  1284.   if (g_strSmartEntity.Find("Smart_Rotating") >= 0)
  1285.   {
  1286.     g_bSmartWaiting = true;
  1287.     ShowInfoDialog("Left click to specify the rotation origin");
  1288.     AcquirePath(1, &_SmartPointDone);
  1289.     while (g_bSmartWaiting)
  1290.     {
  1291.       MSG msg;
  1292.       if (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )) 
  1293.       { 
  1294.         TranslateMessage(&msg);
  1295.         DispatchMessage(&msg);
  1296.       }
  1297.     }
  1298.     HideInfoDialog();
  1299.     CPtrArray array;
  1300.     g_bScreenUpdates = false;
  1301.     CreateRightClickEntity(g_pParentWnd->ActiveXY(), g_nSmartX, g_nSmartY, "func_rotating");
  1302.     array.Add(reinterpret_cast<void*>(selected_brushes.next));
  1303.     Select_Deselect();
  1304.     brush_t* pBrush = CreateSmartBrush(g_PathPoints[0]);
  1305.     array.Add(pBrush);
  1306.     Select_Deselect();
  1307.     Select_Brush(reinterpret_cast<brush_t*>(array.GetAt(0)));
  1308.     Select_Brush(reinterpret_cast<brush_t*>(array.GetAt(1)));
  1309.     ConnectEntities();
  1310.     g_bScreenUpdates = true;
  1311.   }
  1312. }
  1313.  
  1314.  
  1315. void FinishSmartCreation()
  1316. {
  1317.   CPtrArray array;
  1318.   HideInfoDialog();
  1319.   brush_t* pEntities = NULL;
  1320.   if (g_strSmartEntity.Find("Smart_Train") >= 0)
  1321.   {
  1322.     g_bScreenUpdates = false;
  1323.     CreateRightClickEntity(g_pParentWnd->ActiveXY(), g_nSmartX, g_nSmartY, "func_train");
  1324.     array.Add(reinterpret_cast<void*>(selected_brushes.next));
  1325.     for (int n = 0; n < g_nPathCount; n++)
  1326.     {
  1327.       Select_Deselect();
  1328.       CreateRightClickEntity(g_pParentWnd->ActiveXY(), g_PathPoints[n].m_ptScreen.x,g_PathPoints[n].m_ptScreen.y, "path_corner");
  1329.       array.Add(reinterpret_cast<void*>(selected_brushes.next));
  1330.     }
  1331.  
  1332.     for (n = 0; n < g_nPathCount; n++)
  1333.     {
  1334.       Select_Deselect();
  1335.       Select_Brush(reinterpret_cast<brush_t*>(array.GetAt(n)));
  1336.       Select_Brush(reinterpret_cast<brush_t*>(array.GetAt(n+1)));
  1337.       ConnectEntities();
  1338.     }
  1339.     g_bScreenUpdates = true;
  1340.  
  1341.   }
  1342.   g_nPathCount = 0;
  1343.   g_bPathMode = false;
  1344.   Sys_UpdateWindows(W_ALL);
  1345. }
  1346.  
  1347. void CXYWnd::KillPathMode()
  1348. {
  1349.   g_bSmartGo = false;
  1350.   g_bPathMode = false;
  1351.   if (g_pPathFunc)
  1352.     g_pPathFunc(false, g_nPathCount);
  1353.   g_nPathCount = 0;
  1354.   g_pPathFunc = NULL;
  1355.   Sys_UpdateWindows(W_ALL);
  1356. }
  1357.  
  1358. // gets called for drop down menu messages
  1359. // TIP: it's not always about EntityCreate
  1360. void CXYWnd::OnEntityCreate(unsigned int nID) 
  1361. {
  1362.   if (m_mnuDrop.GetSafeHmenu())
  1363.   {
  1364.     CString strItem;
  1365.     m_mnuDrop.GetMenuString(nID, strItem, MF_BYCOMMAND);
  1366.  
  1367.         if (strItem.CompareNoCase("Add to...") == 0)
  1368.         {
  1369.             //++timo TODO: fill the menu with current groups?
  1370.             // this one is for adding to existing groups only
  1371.             Sys_Printf("TODO: Add to... in CXYWnd::OnEntityCreate\n");
  1372.         }
  1373.         else if (strItem.CompareNoCase("Remove") == 0)
  1374.         {
  1375.             // remove selected brushes from their current group
  1376.             brush_t *b;
  1377.             for( b = selected_brushes.next; b != &selected_brushes; b = b->next )
  1378.             {
  1379.                 
  1380.             }
  1381.         }
  1382.  
  1383.         //++timo FIXME: remove when all hooks are in
  1384.         if (strItem.CompareNoCase("Add to...") == 0
  1385.             || strItem.CompareNoCase("Remove") == 0
  1386.             || strItem.CompareNoCase("Name...") == 0
  1387.             || strItem.CompareNoCase("New group...") == 0)
  1388.         {
  1389.             Sys_Printf("TODO: hook drop down group menu\n");
  1390.             return;
  1391.         }
  1392.         
  1393.     if (strItem.Find("Smart_") >= 0)
  1394.     {
  1395.       CreateSmartEntity(this, m_ptDown.x, m_ptDown.y, strItem);
  1396.     }
  1397.     else
  1398.     {
  1399.       CreateRightClickEntity(this, m_ptDown.x, m_ptDown.y, strItem.GetBuffer(0));
  1400.     }
  1401.         
  1402.     Sys_UpdateWindows(W_ALL);
  1403.     //OnLButtonDown((MK_LBUTTON | MK_SHIFT), CPoint(m_ptDown.x+2, m_ptDown.y+2));
  1404.   }
  1405. }
  1406.  
  1407.  
  1408. void CXYWnd::HandleDrop()
  1409. {
  1410.   if (g_PrefsDlg.m_bRightClick == false)
  1411.     return;
  1412.   if (!m_mnuDrop.GetSafeHmenu()) // first time, load it up
  1413.   {
  1414.     m_mnuDrop.CreatePopupMenu();
  1415.     int nID = ID_ENTITY_START;
  1416.  
  1417.     CMenu* pChild2 = new CMenu;
  1418.     pChild2->CreateMenu();
  1419.     pChild2->AppendMenu(MF_STRING, ID_SELECTION_SELECTCOMPLETETALL, "Select Complete Tall");
  1420.     pChild2->AppendMenu(MF_STRING, ID_SELECTION_SELECTTOUCHING, "Select Touching");
  1421.     pChild2->AppendMenu(MF_STRING, ID_SELECTION_SELECTPARTIALTALL, "Select Partial Tall");
  1422.     pChild2->AppendMenu(MF_STRING, ID_SELECTION_SELECTINSIDE, "Select Inside");
  1423.     m_mnuDrop.AppendMenu(MF_POPUP, reinterpret_cast<unsigned int>(pChild2->GetSafeHmenu()), "Select");
  1424.     m_mnuDrop.AppendMenu(MF_SEPARATOR, nID++, "");
  1425.  
  1426.     CMenu* pChild3 = new CMenu;
  1427.     pChild3->CreateMenu();
  1428.     pChild3->AppendMenu(MF_STRING, ID_DROP_GROUP_ADDTO, "Add to...");
  1429.     pChild3->AppendMenu(MF_STRING, ID_DROP_GROUP_REMOVE, "Remove");
  1430.     pChild3->AppendMenu(MF_STRING, ID_DROP_GROUP_NAME, "Name...");
  1431.     pChild3->AppendMenu(MF_SEPARATOR, nID++, "");
  1432.     pChild3->AppendMenu(MF_STRING, ID_DROP_GROUP_NEWGROUP, "New Group...");
  1433.     m_mnuDrop.AppendMenu(MF_POPUP, reinterpret_cast<unsigned int>(pChild3->GetSafeHmenu()), "Group");
  1434.     m_mnuDrop.AppendMenu(MF_SEPARATOR, nID++, "");
  1435.  
  1436.     m_mnuDrop.AppendMenu(MF_STRING, ID_SELECTION_UNGROUPENTITY, "Ungroup Entity");
  1437.     m_mnuDrop.AppendMenu(MF_STRING, ID_SELECTION_MAKE_DETAIL, "Make Detail");
  1438.     m_mnuDrop.AppendMenu(MF_STRING, ID_SELECTION_MAKE_STRUCTURAL, "Make Structural");
  1439.     m_mnuDrop.AppendMenu(MF_SEPARATOR, nID++, "");
  1440.  
  1441.     CMenu* pChild = new CMenu;
  1442.     pChild->CreateMenu();
  1443.     pChild->AppendMenu(MF_STRING, nID++, "Smart_Train");
  1444.     //pChild->AppendMenu(MF_STRING, nID++, "Smart_Rotating");
  1445.     m_mnuDrop.AppendMenu(MF_POPUP, reinterpret_cast<unsigned int>(pChild->GetSafeHmenu()), "Smart Entities");
  1446.     m_mnuDrop.AppendMenu(MF_SEPARATOR, nID++, "");
  1447.  
  1448.     pChild = NULL;
  1449.       eclass_t    *e;
  1450.     CString strActive;
  1451.     CString strLast;
  1452.     CString strName;
  1453.       for (e=eclass ; e ; e=e->next)
  1454.     {
  1455.       strLast = strName;
  1456.       strName = e->name;
  1457.       int n_ = strName.Find("_");
  1458.       if (n_ > 0)
  1459.       {
  1460.         CString strLeft = strName.Left(n_);
  1461.         CString strRight = strName.Right(strName.GetLength() - n_ - 1);
  1462.         if (strLeft == strActive) // this is a child
  1463.         {
  1464.           ASSERT(pChild);
  1465.           pChild->AppendMenu(MF_STRING, nID++, strName);
  1466.         }
  1467.         else
  1468.         {
  1469.           if (pChild)
  1470.           {
  1471.             m_mnuDrop.AppendMenu(MF_POPUP, reinterpret_cast<unsigned int>(pChild->GetSafeHmenu()), strActive);
  1472.             g_ptrMenus.Add(pChild);
  1473.             //pChild->DestroyMenu();
  1474.             //delete pChild;
  1475.             pChild = NULL;
  1476.           }
  1477.           strActive = strLeft;
  1478.           pChild = new CMenu;
  1479.           pChild->CreateMenu();
  1480.           pChild->AppendMenu(MF_STRING, nID++, strName);
  1481.         }
  1482.       }
  1483.       else
  1484.       {
  1485.         if (pChild)
  1486.         {
  1487.           m_mnuDrop.AppendMenu(MF_POPUP, reinterpret_cast<unsigned int>(pChild->GetSafeHmenu()), strActive);
  1488.           g_ptrMenus.Add(pChild);
  1489.           //pChild->DestroyMenu();
  1490.           //delete pChild;
  1491.           pChild = NULL;
  1492.         }
  1493.         strActive = "";
  1494.         m_mnuDrop.AppendMenu(MF_STRING, nID++, strName);
  1495.       }
  1496.     }
  1497.   }
  1498.  
  1499.   CPoint ptMouse;
  1500.   GetCursorPos(&ptMouse);
  1501.   m_mnuDrop.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, ptMouse.x, ptMouse.y, this);
  1502. }
  1503.  
  1504. void CXYWnd::XY_Init()
  1505. {
  1506.     m_vOrigin[0] = 0;
  1507.     m_vOrigin[1] = 20;
  1508.   m_vOrigin[2] = 46;
  1509.   m_fScale = 1;
  1510. }
  1511.  
  1512. void CXYWnd::SnapToPoint (int x, int y, vec3_t point)
  1513. {
  1514.   if (g_PrefsDlg.m_bNoClamp)
  1515.   {
  1516.     XY_ToPoint(x, y, point);
  1517.   }
  1518.   else
  1519.   {
  1520.     XY_ToGridPoint(x, y, point);
  1521.   }
  1522. //--  else
  1523. //--    XY_ToPoint(x, y, point);
  1524. //--    //XY_ToPoint(x, y, point);
  1525. }
  1526.  
  1527.  
  1528. void CXYWnd::XY_ToPoint (int x, int y, vec3_t point)
  1529. {
  1530.   float fx = x;
  1531.   float fy = y;
  1532.   float fw = m_nWidth;
  1533.   float fh = m_nHeight;
  1534.   if (m_nViewType == XY)
  1535.   {
  1536.       point[0] = m_vOrigin[0] + (fx - fw / 2) / m_fScale;
  1537.       point[1] = m_vOrigin[1] + (fy - fh / 2) / m_fScale;
  1538.       //point[2] = 0;
  1539.   }
  1540.   else if (m_nViewType == YZ)
  1541.   {
  1542.     ////point[0] = 0;
  1543.       //point[1] = m_vOrigin[0] + (fx - fw / 2) / m_fScale;
  1544.       //point[2] = m_vOrigin[1] + (fy - fh / 2 ) / m_fScale;
  1545.       point[1] = m_vOrigin[1] + (fx - fw / 2) / m_fScale;
  1546.       point[2] = m_vOrigin[2] + (fy - fh / 2 ) / m_fScale;
  1547.   }
  1548.   else
  1549.   {
  1550.       //point[0] = m_vOrigin[0] + (fx - fw / 2) / m_fScale;
  1551.       ////point[1] = 0;
  1552.       //point[2] = m_vOrigin[1] + (fy - fh / 2) / m_fScale;
  1553.       point[0] = m_vOrigin[0] + (fx - fw / 2) / m_fScale;
  1554.       //point[1] = 0;
  1555.       point[2] = m_vOrigin[2] + (fy - fh / 2) / m_fScale;
  1556.   }
  1557. }
  1558.  
  1559.  
  1560. void CXYWnd::XY_ToGridPoint (int x, int y, vec3_t point)
  1561. {
  1562.   if (m_nViewType == XY)
  1563.   {
  1564.       point[0] = m_vOrigin[0] + (x - m_nWidth / 2) / m_fScale;
  1565.       point[1] = m_vOrigin[1] + (y - m_nHeight / 2) / m_fScale;
  1566.       //point[2] = 0;
  1567.       point[0] = floor(point[0] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  1568.       point[1] = floor(point[1] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  1569.   }
  1570.   else if (m_nViewType == YZ)
  1571.   {
  1572.       //point[0] = 0;
  1573.       //point[1] = m_vOrigin[0] + (x - m_nWidth / 2) / m_fScale;
  1574.       //point[2] = m_vOrigin[1] + (y - m_nHeight / 2) / m_fScale;
  1575.       point[1] = m_vOrigin[1] + (x - m_nWidth / 2) / m_fScale;
  1576.       point[2] = m_vOrigin[2] + (y - m_nHeight / 2) / m_fScale;
  1577.       point[1] = floor(point[1] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  1578.       point[2] = floor(point[2] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  1579.   }
  1580.   else
  1581.   {
  1582.       //point[1] = 0;
  1583.       //point[0] = m_vOrigin[0] + (x - m_nWidth / 2) / m_fScale;
  1584.       //point[2] = m_vOrigin[1] + (y - m_nHeight / 2) / m_fScale;
  1585.       point[0] = m_vOrigin[0] + (x - m_nWidth / 2) / m_fScale;
  1586.       point[2] = m_vOrigin[2] + (y - m_nHeight / 2) / m_fScale;
  1587.       point[0] = floor(point[0] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  1588.       point[2] = floor(point[2] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  1589.   }
  1590. }
  1591.  
  1592.  
  1593. void CXYWnd::XY_MouseDown (int x, int y, int buttons)
  1594. {
  1595.  
  1596.     vec3_t    point;
  1597.     vec3_t    origin, dir, right, up;
  1598.  
  1599.     m_nButtonstate = buttons;
  1600.   m_nPressx = x;
  1601.     m_nPressy = y;
  1602.     VectorCopy (vec3_origin, m_vPressdelta);
  1603.  
  1604.     XY_ToPoint (x, y, point);
  1605.     
  1606.   VectorCopy (point, origin);
  1607.  
  1608.     dir[0] = 0; dir[1] = 0; dir[2] = 0;
  1609.   if (m_nViewType == XY)
  1610.   {
  1611.       origin[2] = 8192;
  1612.     dir[2] = -1;
  1613.       right[0] = 1 / m_fScale; 
  1614.     right[1] = 0; 
  1615.     right[2] = 0;
  1616.       up[0] = 0; 
  1617.     up[1] = 1 / m_fScale;
  1618.     up[2] = 0;
  1619.   }
  1620.   else if (m_nViewType == YZ)
  1621.   {
  1622.     origin[0] = 8192;
  1623.     dir[0] = -1;
  1624.       right[1] = 1 / m_fScale; 
  1625.     right[2] = 0; 
  1626.     right[0] = 0;
  1627.        up[0] = 0; 
  1628.     up[2] = 1 / m_fScale;
  1629.     up[1] = 0;
  1630.   }
  1631.   else
  1632.   {
  1633.     origin[1] = 8192;
  1634.     dir[1] = -1;
  1635.       right[0] = 1 / m_fScale;
  1636.     right[2] = 0; 
  1637.     right[1] = 0;
  1638.       up[0] = 0; 
  1639.     up[2] = 1 / m_fScale;
  1640.     up[1] = 0;
  1641.   }
  1642.  
  1643.  
  1644.     m_bPress_selection = (selected_brushes.next != &selected_brushes);
  1645.  
  1646.   GetCursorPos(&m_ptCursor);
  1647.     //Sys_GetCursorPos (&m_ptCursor.x, &m_ptCursor.y);
  1648.  
  1649.     // lbutton = manipulate selection
  1650.     // shift-LBUTTON = select
  1651.     if ( (buttons == MK_LBUTTON)
  1652.         || (buttons == (MK_LBUTTON | MK_SHIFT))
  1653.         || (buttons == (MK_LBUTTON | MK_CONTROL))
  1654.         || (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) )
  1655.     {    
  1656.     Patch_SetView( (m_nViewType == XY) ? W_XY : (m_nViewType == YZ) ? W_YZ : W_XZ);
  1657.         Drag_Begin (x, y, buttons, right, up,    origin, dir);
  1658.         return;
  1659.     }
  1660.  
  1661.   int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON;
  1662.  
  1663.     // control mbutton = move camera
  1664.     if (m_nButtonstate == (MK_CONTROL|nMouseButton) )
  1665.     {    
  1666.       VectorCopyXY(point, g_pParentWnd->GetCamera()->Camera().origin);
  1667.         Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY);
  1668.     }
  1669.  
  1670.     // mbutton = angle camera
  1671.     if ((g_PrefsDlg.m_nMouseButtons == 3 && m_nButtonstate == MK_MBUTTON) ||
  1672.       (g_PrefsDlg.m_nMouseButtons == 2 && m_nButtonstate == (MK_SHIFT|MK_CONTROL|MK_RBUTTON)))
  1673.     {    
  1674.         VectorSubtract (point, g_pParentWnd->GetCamera()->Camera().origin, point);
  1675.  
  1676.     int n1 = (m_nViewType == XY) ? 1 : 2;
  1677.     int n2 = (m_nViewType == YZ) ? 1 : 0;
  1678.     int nAngle = (m_nViewType == XY) ? YAW : PITCH;
  1679.     if (point[n1] || point[n2])
  1680.     {
  1681.           g_pParentWnd->GetCamera()->Camera().angles[nAngle] = 180/Q_PI*atan2 (point[n1], point[n2]);
  1682.           Sys_UpdateWindows (W_CAMERA_IFON|W_XY_OVERLAY);
  1683.     }
  1684.     }
  1685.  
  1686.     // shift mbutton = move z checker
  1687.     if (m_nButtonstate == (MK_SHIFT | nMouseButton))
  1688.     {
  1689.     if (RotateMode() || g_bPatchBendMode)
  1690.     {
  1691.           SnapToPoint (x, y, point);
  1692.         VectorCopyXY(point, g_vRotateOrigin);
  1693.       if (g_bPatchBendMode)
  1694.       {
  1695.         VectorCopy(point, g_vBendOrigin);
  1696.       }
  1697.           Sys_UpdateWindows (W_XY);
  1698.       return;
  1699.     }
  1700.     else
  1701.     {
  1702.           SnapToPoint (x, y, point);
  1703.       if (m_nViewType == XY)
  1704.       {
  1705.             z.origin[0] = point[0];
  1706.             z.origin[1] = point[1];
  1707.       }
  1708.       else if (m_nViewType == YZ)
  1709.       {
  1710.             z.origin[0] = point[1];
  1711.             z.origin[1] = point[2];
  1712.       }
  1713.       else
  1714.       {
  1715.             z.origin[0] = point[0];
  1716.             z.origin[1] = point[2];
  1717.       }
  1718.           Sys_UpdateWindows (W_XY_OVERLAY|W_Z);
  1719.           return;
  1720.     }
  1721.     }
  1722. }
  1723.  
  1724.  
  1725. void CXYWnd::XY_MouseUp(int x, int y, int buttons)
  1726. {
  1727.     Drag_MouseUp (buttons);
  1728.     if (!m_bPress_selection)
  1729.         Sys_UpdateWindows (W_ALL);
  1730.     m_nButtonstate = 0;
  1731.   while (::ShowCursor(TRUE) < 0)
  1732.     ;
  1733. }
  1734.  
  1735. qboolean CXYWnd::DragDelta (int x, int y, vec3_t move)
  1736. {
  1737.     vec3_t    xvec, yvec, delta;
  1738.     int        i;
  1739.  
  1740.     xvec[0] = 1 / m_fScale;
  1741.     xvec[1] = xvec[2] = 0;
  1742.     yvec[1] = 1 / m_fScale;
  1743.     yvec[0] = yvec[2] = 0;
  1744.  
  1745.     for (i=0 ; i<3 ; i++)
  1746.     {
  1747.         delta[i] = xvec[i] * (x - m_nPressx) + yvec[i] * (y - m_nPressy);
  1748.     if (!g_PrefsDlg.m_bNoClamp)
  1749.     {
  1750.           delta[i] = floor(delta[i] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  1751.     }
  1752.     }
  1753.     VectorSubtract (delta, m_vPressdelta, move);
  1754.     VectorCopy (delta, m_vPressdelta);
  1755.  
  1756.     if (move[0] || move[1] || move[2])
  1757.         return true;
  1758.     return false;
  1759. }
  1760.  
  1761.  
  1762. /*
  1763. ==============
  1764. NewBrushDrag
  1765. ==============
  1766. */
  1767. void CXYWnd::NewBrushDrag (int x, int y)
  1768. {
  1769.     vec3_t    mins, maxs, junk;
  1770.     int        i;
  1771.     float    temp;
  1772.     brush_t    *n;
  1773.  
  1774.     if (!DragDelta (x,y, junk))
  1775.         return;
  1776.  
  1777.   // delete the current selection
  1778.     if (selected_brushes.next != &selected_brushes)
  1779.         Brush_Free (selected_brushes.next);
  1780.     
  1781.   SnapToPoint (m_nPressx, m_nPressy, mins);
  1782.  
  1783.   int nDim = (m_nViewType == XY) ? 2 : (m_nViewType == YZ) ? 0 : 1;
  1784.  
  1785.     mins[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_bottom_z / g_qeglobals.d_gridsize));
  1786.     SnapToPoint (x, y, maxs);
  1787.     maxs[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_top_z / g_qeglobals.d_gridsize));
  1788.     if (maxs[nDim] <= mins[nDim])
  1789.         maxs[nDim] = mins[nDim] + g_qeglobals.d_gridsize;
  1790.  
  1791.     for (i=0 ; i<3 ; i++)
  1792.     {
  1793.         if (mins[i] == maxs[i])
  1794.             return;    // don't create a degenerate brush
  1795.         if (mins[i] > maxs[i])
  1796.         {
  1797.             temp = mins[i];
  1798.             mins[i] = maxs[i];
  1799.             maxs[i] = temp;
  1800.         }
  1801.     }
  1802.  
  1803.     n = Brush_Create (mins, maxs, &g_qeglobals.d_texturewin.texdef);
  1804.     if (!n)
  1805.         return;
  1806.  
  1807.   vec3_t vSize;
  1808.   VectorSubtract(maxs, mins, vSize);
  1809.   g_strStatus.Format("Size X:: %.1f  Y:: %.1f  Z:: %.1f", vSize[0], vSize[1], vSize[2]);
  1810.   g_pParentWnd->SetStatusText(2, g_strStatus);
  1811.  
  1812.     Brush_AddToList (n, &selected_brushes);
  1813.  
  1814.     Entity_LinkBrush (world_entity, n);
  1815.  
  1816.     Brush_Build( n );
  1817.  
  1818.   //    Sys_UpdateWindows (W_ALL);
  1819.     Sys_UpdateWindows (W_XY| W_CAMERA);
  1820.  
  1821. }
  1822.  
  1823. /*
  1824. ==============
  1825. XY_MouseMoved
  1826. ==============
  1827. */
  1828. void CXYWnd::XY_MouseMoved (int x, int y, int buttons)
  1829. {
  1830.     vec3_t    point;
  1831.  
  1832.  
  1833.     if (!m_nButtonstate)
  1834.   {
  1835.     if (g_bCrossHairs)
  1836.     {
  1837.       ::ShowCursor(FALSE);
  1838.           Sys_UpdateWindows (W_XY | W_XY_OVERLAY);
  1839.       ::ShowCursor(TRUE);
  1840.     }
  1841.         return;
  1842.   }
  1843.  
  1844.     // lbutton without selection = drag new brush
  1845.     if (m_nButtonstate == MK_LBUTTON && !m_bPress_selection && g_qeglobals.d_select_mode != sel_curvepoint)
  1846.     {
  1847.         NewBrushDrag (x, y);
  1848.         return;
  1849.     }
  1850.  
  1851.     // lbutton (possibly with control and or shift)
  1852.     // with selection = drag selection
  1853.     if (m_nButtonstate & MK_LBUTTON)
  1854.     {
  1855.         Drag_MouseMoved (x, y, buttons);
  1856.         Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA_IFON | W_Z);
  1857.         return;
  1858.     }
  1859.  
  1860.   int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON;
  1861.     // control mbutton = move camera
  1862.     if (m_nButtonstate == (MK_CONTROL|nMouseButton) )
  1863.     {
  1864.         SnapToPoint (x, y, point);
  1865.       VectorCopyXY(point, g_pParentWnd->GetCamera()->Camera().origin);
  1866.         Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA);
  1867.         return;
  1868.     }
  1869.  
  1870.     // shift mbutton = move z checker
  1871.     if (m_nButtonstate == (MK_SHIFT|nMouseButton) )
  1872.     {
  1873.     if (RotateMode() || g_bPatchBendMode)
  1874.     {
  1875.           SnapToPoint (x, y, point);
  1876.         VectorCopyXY(point, g_vRotateOrigin);
  1877.       if (g_bPatchBendMode)
  1878.       {
  1879.         VectorCopy(point, g_vBendOrigin);
  1880.       }
  1881.           Sys_UpdateWindows (W_XY);
  1882.       return;
  1883.     }
  1884.     else
  1885.     {
  1886.           SnapToPoint (x, y, point);
  1887.       if (m_nViewType == XY)
  1888.       {
  1889.             z.origin[0] = point[0];
  1890.             z.origin[1] = point[1];
  1891.       }
  1892.       else if (m_nViewType == YZ)
  1893.       {
  1894.             z.origin[0] = point[1];
  1895.             z.origin[1] = point[2];
  1896.       }
  1897.       else
  1898.       {
  1899.             z.origin[0] = point[0];
  1900.             z.origin[1] = point[2];
  1901.       }
  1902.     }
  1903.         Sys_UpdateWindows (W_XY_OVERLAY|W_Z);
  1904.         return;
  1905.     }
  1906.  
  1907.     // mbutton = angle camera
  1908.     if ((g_PrefsDlg.m_nMouseButtons == 3 && m_nButtonstate == MK_MBUTTON) ||
  1909.       (g_PrefsDlg.m_nMouseButtons == 2 && m_nButtonstate == (MK_SHIFT|MK_CONTROL|MK_RBUTTON)))
  1910.     {    
  1911.         SnapToPoint (x, y, point);
  1912.         VectorSubtract (point, g_pParentWnd->GetCamera()->Camera().origin, point);
  1913.  
  1914.     int n1 = (m_nViewType == XY) ? 1 : 2;
  1915.     int n2 = (m_nViewType == YZ) ? 1 : 0;
  1916.     int nAngle = (m_nViewType == XY) ? YAW : PITCH;
  1917.     if (point[n1] || point[n2])
  1918.     {
  1919.           g_pParentWnd->GetCamera()->Camera().angles[nAngle] = 180/Q_PI*atan2 (point[n1], point[n2]);
  1920.           Sys_UpdateWindows (W_CAMERA_IFON|W_XY_OVERLAY);
  1921.     }
  1922.         return;
  1923.     }
  1924.  
  1925.  
  1926.     // rbutton = drag xy origin
  1927.     if (m_nButtonstate == MK_RBUTTON)
  1928.     {
  1929.         Sys_GetCursorPos (&x, &y);
  1930.         if (x != m_ptCursor.x || y != m_ptCursor.y)
  1931.         {
  1932.       int nDim1 = (m_nViewType == YZ) ? 1 : 0;
  1933.       int nDim2 = (m_nViewType == XY) ? 1 : 2;
  1934.             m_vOrigin[nDim1] -= (x - m_ptCursor.x) / m_fScale;
  1935.             m_vOrigin[nDim2] += (y - m_ptCursor.y) / m_fScale;
  1936.         SetCursorPos (m_ptCursor.x, m_ptCursor.y);
  1937.       ::ShowCursor(FALSE);
  1938.       //XY_Draw();
  1939.       //RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
  1940.             Sys_UpdateWindows (W_XY | W_XY_OVERLAY);
  1941.       //::ShowCursor(TRUE);
  1942.         }
  1943.         return;
  1944.     }
  1945.  
  1946. }
  1947.  
  1948.  
  1949. /*
  1950. ============================================================================
  1951.  
  1952. DRAWING
  1953.  
  1954. ============================================================================
  1955. */
  1956.  
  1957.  
  1958. /*
  1959. ==============
  1960. XY_DrawGrid
  1961. ==============
  1962. */
  1963. void CXYWnd::XY_DrawGrid()
  1964. {
  1965.     float    x, y, xb, xe, yb, ye;
  1966.     int        w, h;
  1967.     char    text[32];
  1968.  
  1969.     qglDisable(GL_TEXTURE_2D);
  1970.     qglDisable(GL_TEXTURE_1D);
  1971.     qglDisable(GL_DEPTH_TEST);
  1972.     qglDisable(GL_BLEND);
  1973.  
  1974.     w = m_nWidth / 2 / m_fScale;
  1975.     h = m_nHeight / 2 / m_fScale;
  1976.  
  1977.  
  1978.   int nDim1 = (m_nViewType == YZ) ? 1 : 0;
  1979.   int nDim2 = (m_nViewType == XY) ? 1 : 2;
  1980.   //int nDim1 = 0;
  1981.   //int nDim2 = 1;
  1982.  
  1983.  
  1984.     xb = m_vOrigin[nDim1] - w;
  1985.     if (xb < region_mins[nDim1])
  1986.         xb = region_mins[nDim1];
  1987.     xb = 64 * floor (xb/64);
  1988.  
  1989.     xe = m_vOrigin[nDim1] + w;
  1990.     if (xe > region_maxs[nDim1])
  1991.         xe = region_maxs[nDim1];
  1992.     xe = 64 * ceil (xe/64);
  1993.  
  1994.     yb = m_vOrigin[nDim2] - h;
  1995.     if (yb < region_mins[nDim2])
  1996.         yb = region_mins[nDim2];
  1997.     yb = 64 * floor (yb/64);
  1998.  
  1999.     ye = m_vOrigin[nDim2] + h;
  2000.     if (ye > region_maxs[nDim2])
  2001.         ye = region_maxs[nDim2];
  2002.     ye = 64 * ceil (ye/64);
  2003.  
  2004.     // draw major blocks
  2005.  
  2006.     qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR]);
  2007.  
  2008.     int stepSize = 64 * 0.1 / m_fScale;
  2009.     if (stepSize < 64) {
  2010.         stepSize = 64;
  2011.     } else {
  2012.         int i;
  2013.         for (i = 1; i < stepSize; i <<= 1) {
  2014.         }
  2015.         stepSize = i;
  2016.     }
  2017.  
  2018.     if ( g_qeglobals.d_showgrid )
  2019.     {
  2020.         
  2021.         qglBegin (GL_LINES);
  2022.         
  2023.         for (x=xb ; x<=xe ; x+=stepSize)
  2024.         {
  2025.             qglVertex2f (x, yb);
  2026.             qglVertex2f (x, ye);
  2027.         }
  2028.         for (y=yb ; y<=ye ; y+=stepSize)
  2029.         {
  2030.             qglVertex2f (xb, y);
  2031.             qglVertex2f (xe, y);
  2032.         }
  2033.         
  2034.         qglEnd ();
  2035.         
  2036.     }
  2037.  
  2038.     // draw minor blocks
  2039.     if ( m_fScale > .1 && g_qeglobals.d_showgrid && g_qeglobals.d_gridsize * m_fScale >= 4 && 
  2040.        g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR] != g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK])
  2041.     {
  2042.         qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR]);
  2043.  
  2044.         qglBegin (GL_LINES);
  2045.         for (x=xb ; x<xe ; x += g_qeglobals.d_gridsize)
  2046.         {
  2047.             if ( ! ((int)x & 63) )
  2048.                 continue;
  2049.             qglVertex2f (x, yb);
  2050.             qglVertex2f (x, ye);
  2051.         }
  2052.         for (y=yb ; y<ye ; y+=g_qeglobals.d_gridsize)
  2053.         {
  2054.             if ( ! ((int)y & 63) )
  2055.                 continue;
  2056.             qglVertex2f (xb, y);
  2057.             qglVertex2f (xe, y);
  2058.         }
  2059.         qglEnd ();
  2060.     }
  2061.  
  2062.     // draw coordinate text if needed
  2063.  
  2064.     if ( g_qeglobals.d_savedinfo.show_coordinates)
  2065.     {
  2066.         //glColor4f(0, 0, 0, 0);
  2067.         qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT]);
  2068.  
  2069.         for (x=xb ; x<xe ; x+=stepSize)
  2070.         {
  2071.             qglRasterPos2f (x, m_vOrigin[nDim2] + h - 6 / m_fScale);
  2072.             sprintf (text, "%i",(int)x);
  2073.             qglCallLists (strlen(text), GL_UNSIGNED_BYTE, text);
  2074.         }
  2075.         for (y=yb ; y<ye ; y+=stepSize)
  2076.         {
  2077.             qglRasterPos2f (m_vOrigin[nDim1] - w + 1, y);
  2078.             sprintf (text, "%i",(int)y);
  2079.             qglCallLists (strlen(text), GL_UNSIGNED_BYTE, text);
  2080.         }
  2081.  
  2082.  
  2083.     if (Active())
  2084.           qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME]);
  2085.  
  2086.     qglRasterPos2f ( m_vOrigin[nDim1] - w + 35 / m_fScale, m_vOrigin[nDim2] + h - 20 / m_fScale );
  2087.  
  2088.     char cView[20];
  2089.     if (m_nViewType == XY)
  2090.       strcpy(cView, "XY Top");
  2091.     else 
  2092.     if (m_nViewType == XZ)
  2093.       strcpy(cView, "XZ Front");
  2094.     else
  2095.       strcpy(cView, "YZ Side");
  2096.  
  2097.         qglCallLists (strlen(cView), GL_UNSIGNED_BYTE, cView);
  2098.     
  2099.  
  2100.   }
  2101.  
  2102.  
  2103. /*
  2104.   if (true)
  2105.   {
  2106.         qglColor3f(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR]);
  2107.         qglBegin (GL_LINES);
  2108.       qglVertex2f (x, yb);
  2109.         qglVertex2f (x, ye);
  2110.     qglEnd();
  2111.   }
  2112.   */
  2113.  
  2114. }
  2115.  
  2116. /*
  2117. ==============
  2118. XY_DrawBlockGrid
  2119. ==============
  2120. */
  2121. void CXYWnd::XY_DrawBlockGrid()
  2122. {
  2123.     float    x, y, xb, xe, yb, ye;
  2124.     int        w, h;
  2125.     char    text[32];
  2126.  
  2127.     qglDisable(GL_TEXTURE_2D);
  2128.     qglDisable(GL_TEXTURE_1D);
  2129.     qglDisable(GL_DEPTH_TEST);
  2130.     qglDisable(GL_BLEND);
  2131.  
  2132.     w = m_nWidth / 2 / m_fScale;
  2133.     h = m_nHeight / 2 / m_fScale;
  2134.  
  2135.   int nDim1 = (m_nViewType == YZ) ? 1 : 0;
  2136.   int nDim2 = (m_nViewType == XY) ? 1 : 2;
  2137.  
  2138.   xb = m_vOrigin[nDim1] - w;
  2139.     if (xb < region_mins[nDim1])
  2140.         xb = region_mins[nDim1];
  2141.     xb = 1024 * floor (xb/1024);
  2142.  
  2143.     xe = m_vOrigin[nDim1] + w;
  2144.     if (xe > region_maxs[nDim1])
  2145.         xe = region_maxs[nDim1];
  2146.     xe = 1024 * ceil (xe/1024);
  2147.  
  2148.     yb = m_vOrigin[nDim2] - h;
  2149.     if (yb < region_mins[nDim2])
  2150.         yb = region_mins[nDim2];
  2151.     yb = 1024 * floor (yb/1024);
  2152.  
  2153.     ye = m_vOrigin[nDim2] + h;
  2154.     if (ye > region_maxs[nDim2])
  2155.         ye = region_maxs[nDim2];
  2156.     ye = 1024 * ceil (ye/1024);
  2157.  
  2158.     // draw major blocks
  2159.  
  2160.   qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK]);
  2161.     qglLineWidth (2);
  2162.  
  2163.     qglBegin (GL_LINES);
  2164.     
  2165.     for (x=xb ; x<=xe ; x+=1024)
  2166.     {
  2167.         qglVertex2f (x, yb);
  2168.         qglVertex2f (x, ye);
  2169.     }
  2170.     for (y=yb ; y<=ye ; y+=1024)
  2171.     {
  2172.         qglVertex2f (xb, y);
  2173.         qglVertex2f (xe, y);
  2174.     }
  2175.     
  2176.     qglEnd ();
  2177.     qglLineWidth (1);
  2178.  
  2179.     // draw coordinate text if needed
  2180.  
  2181.     for (x=xb ; x<xe ; x+=1024)
  2182.         for (y=yb ; y<ye ; y+=1024)
  2183.         {
  2184.             qglRasterPos2f (x+512, y+512);
  2185.             sprintf (text, "%i,%i",(int)floor(x/1024), (int)floor(y/1024) );
  2186.             qglCallLists (strlen(text), GL_UNSIGNED_BYTE, text);
  2187.         }
  2188.  
  2189.     qglColor4f(0, 0, 0, 0);
  2190. }
  2191.  
  2192. void CXYWnd::DrawRotateIcon()
  2193. {
  2194.     float    x, y;
  2195.  
  2196.   if (m_nViewType == XY)
  2197.   {
  2198.     x = g_vRotateOrigin[0];
  2199.     y = g_vRotateOrigin[1];
  2200.   }
  2201.   else if (m_nViewType == YZ)
  2202.   {
  2203.     x = g_vRotateOrigin[1];
  2204.     y = g_vRotateOrigin[2];
  2205.   }
  2206.   else
  2207.   {
  2208.     x = g_vRotateOrigin[0];
  2209.     y = g_vRotateOrigin[2];
  2210.   }
  2211.  
  2212.     qglEnable (GL_BLEND);
  2213.     qglDisable (GL_TEXTURE_2D);
  2214.     qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  2215.     qglDisable (GL_CULL_FACE);
  2216.     qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  2217.     qglColor4f (0.8, 0.1, 0.9, 0.25);
  2218.  
  2219.   qglBegin(GL_QUADS);
  2220.     qglVertex3f (x-4,y-4,0);
  2221.     qglVertex3f (x+4,y-4,0);
  2222.     qglVertex3f (x+4,y+4,0);
  2223.     qglVertex3f (x-4,y+4,0);
  2224.     qglEnd ();
  2225.     qglDisable (GL_BLEND);
  2226.  
  2227.     qglColor4f (1.0, 0.2, 1.0, 1);
  2228.     qglBegin(GL_POINTS);
  2229.     qglVertex3f (x,y,0);
  2230.     qglEnd ();
  2231.  
  2232. #if 0
  2233.     qglBegin(GL_LINES);
  2234.     qglVertex3f (x-6,y+6,0);
  2235.     qglVertex3f (x+6,y+6,0);
  2236.     qglVertex3f (x-6,y-6,0);
  2237.     qglVertex3f (x+6,y-6,0);
  2238.     qglEnd ();
  2239. #endif
  2240.  
  2241. }
  2242.  
  2243. void CXYWnd::DrawCameraIcon()
  2244. {
  2245.     float    x, y, a;
  2246.  
  2247.   if (m_nViewType == XY)
  2248.   {
  2249.     x = g_pParentWnd->GetCamera()->Camera().origin[0];
  2250.         y = g_pParentWnd->GetCamera()->Camera().origin[1];
  2251.       a = g_pParentWnd->GetCamera()->Camera().angles[YAW]/180*Q_PI;
  2252.   }
  2253.   else if (m_nViewType == YZ)
  2254.   {
  2255.       x = g_pParentWnd->GetCamera()->Camera().origin[1];
  2256.         y = g_pParentWnd->GetCamera()->Camera().origin[2];
  2257.       a = g_pParentWnd->GetCamera()->Camera().angles[PITCH]/180*Q_PI;
  2258.   }
  2259.   else
  2260.   {
  2261.       x = g_pParentWnd->GetCamera()->Camera().origin[0];
  2262.         y = g_pParentWnd->GetCamera()->Camera().origin[2];
  2263.       a = g_pParentWnd->GetCamera()->Camera().angles[PITCH]/180*Q_PI;
  2264.   }
  2265.  
  2266.     qglColor3f (0.0, 0.0, 1.0);
  2267.     qglBegin(GL_LINE_STRIP);
  2268.     qglVertex3f (x-16,y,0);
  2269.     qglVertex3f (x,y+8,0);
  2270.     qglVertex3f (x+16,y,0);
  2271.     qglVertex3f (x,y-8,0);
  2272.     qglVertex3f (x-16,y,0);
  2273.     qglVertex3f (x+16,y,0);
  2274.     qglEnd ();
  2275.     
  2276.     qglBegin(GL_LINE_STRIP);
  2277.     qglVertex3f (x+48*cos(a+Q_PI/4), y+48*sin(a+Q_PI/4), 0);
  2278.     qglVertex3f (x, y, 0);
  2279.     qglVertex3f (x+48*cos(a-Q_PI/4), y+48*sin(a-Q_PI/4), 0);
  2280.     qglEnd ();
  2281.  
  2282. #if 0
  2283.   char text[128];
  2284.     qglRasterPos2f (x+64, y+64);
  2285.     sprintf (text, "%f",g_pParentWnd->GetCamera()->Camera().angles[YAW]);
  2286.     qglCallLists (strlen(text), GL_UNSIGNED_BYTE, text);
  2287. #endif
  2288.  
  2289. }
  2290.  
  2291. void CXYWnd::DrawZIcon (void)
  2292. {
  2293.   if (m_nViewType == XY)
  2294.   {
  2295.       float x = z.origin[0];
  2296.       float y = z.origin[1];
  2297.       qglEnable (GL_BLEND);
  2298.       qglDisable (GL_TEXTURE_2D);
  2299.       qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  2300.       qglDisable (GL_CULL_FACE);
  2301.       qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  2302.       qglColor4f (0.0, 0.0, 1.0, 0.25);
  2303.       qglBegin(GL_QUADS);
  2304.       qglVertex3f (x-8,y-8,0);
  2305.       qglVertex3f (x+8,y-8,0);
  2306.       qglVertex3f (x+8,y+8,0);
  2307.       qglVertex3f (x-8,y+8,0);
  2308.       qglEnd ();
  2309.       qglDisable (GL_BLEND);
  2310.  
  2311.       qglColor4f (0.0, 0.0, 1.0, 1);
  2312.  
  2313.       qglBegin(GL_LINE_LOOP);
  2314.       qglVertex3f (x-8,y-8,0);
  2315.       qglVertex3f (x+8,y-8,0);
  2316.       qglVertex3f (x+8,y+8,0);
  2317.       qglVertex3f (x-8,y+8,0);
  2318.       qglEnd ();
  2319.  
  2320.     qglBegin(GL_LINE_STRIP);
  2321.       qglVertex3f (x-4,y+4,0);
  2322.       qglVertex3f (x+4,y+4,0);
  2323.       qglVertex3f (x-4,y-4,0);
  2324.       qglVertex3f (x+4,y-4,0);
  2325.       qglEnd ();
  2326.   }
  2327. }
  2328.  
  2329.  
  2330. /*
  2331. ==================
  2332. FilterBrush
  2333. ==================
  2334. */
  2335. BOOL FilterBrush(brush_t *pb)
  2336. {
  2337.     if (!pb->owner)
  2338.         return FALSE;        // during construction
  2339.  
  2340.   if (pb->hiddenBrush)
  2341.   {
  2342.     return TRUE;
  2343.   }
  2344.  
  2345.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK)
  2346.   {
  2347.     // filter out the brush only if all faces are caulk
  2348.     // if not don't hide the whole brush, proceed on a per-face basis (Cam_Draw)
  2349.     //++timo TODO: set this as a preference .. show caulk: hide any brush with caulk // don't draw caulk faces
  2350.     face_t *f;
  2351.     f=pb->brush_faces;
  2352.     while (f)
  2353.     {
  2354.       if (!strstr(f->texdef.name, "caulk"))
  2355.         break;
  2356.       f = f->next;
  2357.     }
  2358.     if (!f)
  2359.       return TRUE;
  2360.  
  2361. #if 0
  2362.     if (strstr(pb->brush_faces->texdef.name, "caulk"))
  2363.       return TRUE;
  2364. #endif
  2365.  
  2366.     //++timo FIXME: .. same deal here?
  2367.     if (strstr(pb->brush_faces->texdef.name, "donotenter"))
  2368.       return TRUE;
  2369.   }
  2370.  
  2371.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_HINT)
  2372.   {
  2373.     if (strstr(pb->brush_faces->texdef.name, "hint"))
  2374.       return TRUE;
  2375.   }
  2376.  
  2377.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP)
  2378.     {
  2379.     if (strstr(pb->brush_faces->texdef.name, "clip"))
  2380.       return TRUE;
  2381.  
  2382.     if (strstr(pb->brush_faces->texdef.name, "skip"))
  2383.       return TRUE;
  2384.  
  2385.         //if (!strncmp(pb->brush_faces->texdef.name, "clip", 4))
  2386.         //    return TRUE;
  2387.     }
  2388.  
  2389.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WATER)
  2390.     {
  2391.         for (face_t* f = pb->brush_faces ; f ; f=f->next)
  2392.     {
  2393.       if (f->texdef.contents & (CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA))
  2394.         return TRUE;
  2395.     }
  2396.     }
  2397.  
  2398.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_DETAIL)
  2399.     {
  2400.         if (pb->brush_faces->texdef.contents & CONTENTS_DETAIL)
  2401.             return TRUE;
  2402.     }
  2403.  
  2404.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CURVES)
  2405.     {
  2406.         if (pb->patchBrush)
  2407.             return TRUE;
  2408.     }
  2409.  
  2410.     if (pb->owner == world_entity)
  2411.     {
  2412.         if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD)
  2413.             return TRUE;
  2414.         return FALSE;
  2415.     }
  2416.     else 
  2417.   {
  2418.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT)
  2419.     {
  2420.           return (strncmp(pb->owner->eclass->name, "func_group", 10));
  2421.     }
  2422.   }
  2423.  
  2424.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS)
  2425.     {
  2426.     return (pb->owner->eclass->nShowFlags & ECLASS_LIGHT);
  2427.         //if (!strncmp(pb->owner->eclass->name, "light", 5))
  2428.         //    return TRUE;
  2429.     }
  2430.  
  2431.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS)
  2432.     {
  2433.     return (pb->owner->eclass->nShowFlags & ECLASS_PATH);
  2434.         //if (!strncmp(pb->owner->eclass->name, "path", 4))
  2435.         //    return TRUE;
  2436.     }
  2437.  
  2438.     return FALSE;
  2439. }
  2440.  
  2441. /*
  2442. =============================================================
  2443.  
  2444.   PATH LINES
  2445.  
  2446. =============================================================
  2447. */
  2448.  
  2449. /*
  2450. ==================
  2451. DrawPathLines
  2452.  
  2453. Draws connections between entities.
  2454. Needs to consider all entities, not just ones on screen,
  2455. because the lines can be visible when neither end is.
  2456. Called for both camera view and xy view.
  2457. ==================
  2458. */
  2459. void DrawPathLines (void)
  2460. {
  2461.     int        i, j, k;
  2462.     vec3_t    mid, mid1;
  2463.     entity_t *se, *te;
  2464.     brush_t    *sb, *tb;
  2465.     char    *psz;
  2466.     vec3_t    dir, s1, s2;
  2467.     vec_t    len, f;
  2468.     int        arrows;
  2469.     int            num_entities;
  2470.     char        *ent_target[MAX_MAP_ENTITIES];
  2471.     entity_t    *ent_entity[MAX_MAP_ENTITIES];
  2472.  
  2473.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS)
  2474.     return;
  2475.  
  2476.     num_entities = 0;
  2477.     for (te = entities.next ; te != &entities && num_entities != MAX_MAP_ENTITIES ; te = te->next)
  2478.     {
  2479.         ent_target[num_entities] = ValueForKey (te, "target");
  2480.         if (ent_target[num_entities][0])
  2481.         {
  2482.             ent_entity[num_entities] = te;
  2483.             num_entities++;
  2484.         }
  2485.     }
  2486.  
  2487.     for (se = entities.next ; se != &entities ; se = se->next)
  2488.     {
  2489.         psz = ValueForKey(se, "targetname");
  2490.     
  2491.         if (psz == NULL || psz[0] == '\0')
  2492.             continue;
  2493.         
  2494.         sb = se->brushes.onext;
  2495.         if (sb == &se->brushes)
  2496.             continue;
  2497.  
  2498.         for (k=0 ; k<num_entities ; k++)
  2499.         {
  2500.         if (strcmp (ent_target[k], psz))
  2501.                 continue;
  2502.  
  2503.             te = ent_entity[k];
  2504.             tb = te->brushes.onext;
  2505.             if (tb == &te->brushes)
  2506.                 continue;
  2507.  
  2508.             for (i=0 ; i<3 ; i++)
  2509.                 mid[i] = (sb->mins[i] + sb->maxs[i])*0.5; 
  2510.  
  2511.             for (i=0 ; i<3 ; i++)
  2512.                 mid1[i] = (tb->mins[i] + tb->maxs[i])*0.5; 
  2513.  
  2514.             VectorSubtract (mid1, mid, dir);
  2515.             len = VectorNormalize (dir);
  2516.             s1[0] = -dir[1]*8 + dir[0]*8;
  2517.             s2[0] = dir[1]*8 + dir[0]*8;
  2518.             s1[1] = dir[0]*8 + dir[1]*8;
  2519.             s2[1] = -dir[0]*8 + dir[1]*8;
  2520.  
  2521.             qglColor3f (se->eclass->color[0], se->eclass->color[1], se->eclass->color[2]);
  2522.  
  2523.             qglBegin(GL_LINES);
  2524.             qglVertex3fv(mid);
  2525.             qglVertex3fv(mid1);
  2526.  
  2527.             arrows = (int)(len / 256) + 1;
  2528.  
  2529.             for (i=0 ; i<arrows ; i++)
  2530.             {
  2531.                 f = len * (i + 0.5) / arrows;
  2532.  
  2533.                 for (j=0 ; j<3 ; j++)
  2534.                     mid1[j] = mid[j] + f*dir[j];
  2535.                 qglVertex3fv (mid1);
  2536.                 qglVertex3f (mid1[0] + s1[0], mid1[1] + s1[1], mid1[2]);
  2537.                 qglVertex3fv (mid1);
  2538.                 qglVertex3f (mid1[0] + s2[0], mid1[1] + s2[1], mid1[2]);
  2539.             }
  2540.  
  2541.             qglEnd();
  2542.         }
  2543.     }
  2544.  
  2545.     return;
  2546. }
  2547.  
  2548. //=============================================================
  2549.  
  2550. // can be greatly simplified but per usual i am in a hurry 
  2551. // which is not an excuse, just a fact
  2552. void CXYWnd::PaintSizeInfo(int nDim1, int nDim2, vec3_t vMinBounds, vec3_t vMaxBounds)
  2553. {
  2554.  
  2555.   vec3_t vSize;
  2556.   VectorSubtract(vMaxBounds, vMinBounds, vSize);
  2557.  
  2558.   qglColor3f(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] * .65, 
  2559.             g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] * .65,
  2560.             g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] * .65);
  2561.  
  2562.   if (m_nViewType == XY)
  2563.   {
  2564.         qglBegin (GL_LINES);
  2565.  
  2566.     qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f  / m_fScale, 0.0f);
  2567.     qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f);
  2568.  
  2569.     qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f  / m_fScale, 0.0f);
  2570.     qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f  / m_fScale, 0.0f);
  2571.  
  2572.     qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f  / m_fScale, 0.0f);
  2573.     qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f);
  2574.   
  2575.  
  2576.     qglVertex3f(vMaxBounds[nDim1] + 6.0f  / m_fScale, vMinBounds[nDim2], 0.0f);
  2577.     qglVertex3f(vMaxBounds[nDim1] + 10.0f  / m_fScale, vMinBounds[nDim2], 0.0f);
  2578.  
  2579.     qglVertex3f(vMaxBounds[nDim1] + 10.0f  / m_fScale, vMinBounds[nDim2], 0.0f);
  2580.     qglVertex3f(vMaxBounds[nDim1] + 10.0f  / m_fScale, vMaxBounds[nDim2], 0.0f);
  2581.   
  2582.     qglVertex3f(vMaxBounds[nDim1] + 6.0f  / m_fScale, vMaxBounds[nDim2], 0.0f);
  2583.     qglVertex3f(vMaxBounds[nDim1] + 10.0f  / m_fScale, vMaxBounds[nDim2], 0.0f);
  2584.  
  2585.     qglEnd();
  2586.  
  2587.     qglRasterPos3f (Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]),  vMinBounds[nDim2] - 20.0  / m_fScale, 0.0f);
  2588.     g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]);
  2589.       qglCallLists (g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
  2590.     
  2591.     qglRasterPos3f (vMaxBounds[nDim1] + 16.0  / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2]), 0.0f);
  2592.     g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]);
  2593.       qglCallLists (g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
  2594.  
  2595.     qglRasterPos3f (vMinBounds[nDim1] + 4, vMaxBounds[nDim2] + 8 / m_fScale, 0.0f);
  2596.     g_strDim.Format(g_pOrgStrings[0], vMinBounds[nDim1], vMaxBounds[nDim2]);
  2597.       qglCallLists (g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
  2598.  
  2599.   }
  2600.   else
  2601.   if (m_nViewType == XZ)
  2602.   {
  2603.         qglBegin (GL_LINES);
  2604.  
  2605.     qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 6.0f  / m_fScale);
  2606.     qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale);
  2607.  
  2608.     qglVertex3f(vMinBounds[nDim1], 0,vMinBounds[nDim2] - 10.0f  / m_fScale);
  2609.     qglVertex3f(vMaxBounds[nDim1], 0,vMinBounds[nDim2] - 10.0f  / m_fScale);
  2610.  
  2611.     qglVertex3f(vMaxBounds[nDim1], 0,vMinBounds[nDim2] - 6.0f  / m_fScale);
  2612.     qglVertex3f(vMaxBounds[nDim1], 0,vMinBounds[nDim2] - 10.0f / m_fScale);
  2613.   
  2614.  
  2615.     qglVertex3f(vMaxBounds[nDim1] + 6.0f  / m_fScale, 0,vMinBounds[nDim2]);
  2616.     qglVertex3f(vMaxBounds[nDim1] + 10.0f  / m_fScale, 0,vMinBounds[nDim2]);
  2617.  
  2618.     qglVertex3f(vMaxBounds[nDim1] + 10.0f  / m_fScale, 0,vMinBounds[nDim2]);
  2619.     qglVertex3f(vMaxBounds[nDim1] + 10.0f  / m_fScale, 0,vMaxBounds[nDim2]);
  2620.   
  2621.     qglVertex3f(vMaxBounds[nDim1] + 6.0f  / m_fScale, 0,vMaxBounds[nDim2]);
  2622.     qglVertex3f(vMaxBounds[nDim1] + 10.0f  / m_fScale, 0,vMaxBounds[nDim2]);
  2623.  
  2624.     qglEnd();
  2625.  
  2626.     qglRasterPos3f (Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), 0, vMinBounds[nDim2] - 20.0  / m_fScale);
  2627.     g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]);
  2628.       qglCallLists (g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
  2629.     
  2630.     qglRasterPos3f (vMaxBounds[nDim1] + 16.0  / m_fScale, 0, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2]));
  2631.     g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]);
  2632.       qglCallLists (g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
  2633.  
  2634.     qglRasterPos3f (vMinBounds[nDim1] + 4, 0, vMaxBounds[nDim2] + 8 / m_fScale);
  2635.     g_strDim.Format(g_pOrgStrings[1], vMinBounds[nDim1], vMaxBounds[nDim2]);
  2636.       qglCallLists (g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
  2637.  
  2638.   }
  2639.   else
  2640.   {
  2641.         qglBegin (GL_LINES);
  2642.  
  2643.     qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f  / m_fScale);
  2644.     qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale);
  2645.  
  2646.     qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f  / m_fScale);
  2647.     qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f  / m_fScale);
  2648.  
  2649.     qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f  / m_fScale);
  2650.     qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale);
  2651.   
  2652.  
  2653.     qglVertex3f(0, vMaxBounds[nDim1] + 6.0f  / m_fScale, vMinBounds[nDim2]);
  2654.     qglVertex3f(0, vMaxBounds[nDim1] + 10.0f  / m_fScale, vMinBounds[nDim2]);
  2655.  
  2656.     qglVertex3f(0, vMaxBounds[nDim1] + 10.0f  / m_fScale, vMinBounds[nDim2]);
  2657.     qglVertex3f(0, vMaxBounds[nDim1] + 10.0f  / m_fScale, vMaxBounds[nDim2]);
  2658.   
  2659.     qglVertex3f(0, vMaxBounds[nDim1] + 6.0f  / m_fScale, vMaxBounds[nDim2]);
  2660.     qglVertex3f(0, vMaxBounds[nDim1] + 10.0f  / m_fScale, vMaxBounds[nDim2]);
  2661.  
  2662.     qglEnd();
  2663.  
  2664.     qglRasterPos3f (0, Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]),  vMinBounds[nDim2] - 20.0  / m_fScale);
  2665.     g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]);
  2666.       qglCallLists (g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
  2667.     
  2668.     qglRasterPos3f (0, vMaxBounds[nDim1] + 16.0  / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2]));
  2669.     g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]);
  2670.       qglCallLists (g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
  2671.  
  2672.     qglRasterPos3f (0, vMinBounds[nDim1] + 4.0, vMaxBounds[nDim2] + 8 / m_fScale);
  2673.     g_strDim.Format(g_pOrgStrings[2], vMinBounds[nDim1], vMaxBounds[nDim2]);
  2674.       qglCallLists (g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
  2675.  
  2676.   }
  2677. }
  2678.  
  2679.  
  2680.  
  2681. /*
  2682. ==============
  2683. XY_Draw
  2684. ==============
  2685. */
  2686. long g_lCount = 0;
  2687. long g_lTotal = 0;
  2688. extern void DrawBrushEntityName (brush_t *b);
  2689.  
  2690. void CXYWnd::XY_Draw()
  2691. {
  2692.   brush_t    *brush;
  2693.     float    w, h;
  2694.     entity_t    *e;
  2695.     double    start, end;
  2696.     double    start2, end2;
  2697.     vec3_t    mins, maxs;
  2698.     int        drawn, culled;
  2699.     int        i;
  2700.  
  2701.     if (!active_brushes.next)
  2702.         return;    // not valid yet
  2703.  
  2704.     if (m_bTiming)
  2705.         start = Sys_DoubleTime();
  2706.     //
  2707.     // clear
  2708.     //
  2709.     m_bDirty = false;
  2710.  
  2711.     qglViewport(0, 0, m_nWidth, m_nHeight);
  2712.     qglClearColor (g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0],
  2713.                     g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1],
  2714.                     g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2],0);
  2715.  
  2716.   qglClear(GL_COLOR_BUFFER_BIT);
  2717.  
  2718.     //
  2719.     // set up viewpoint
  2720.     //
  2721.     qglMatrixMode(GL_PROJECTION);
  2722.   qglLoadIdentity ();
  2723.  
  2724.     w = m_nWidth / 2 / m_fScale;
  2725.     h = m_nHeight / 2/ m_fScale;
  2726.   int nDim1 = (m_nViewType == YZ) ? 1 : 0;
  2727.   int nDim2 = (m_nViewType == XY) ? 1 : 2;
  2728.     mins[0] = m_vOrigin[nDim1] - w;
  2729.     maxs[0] = m_vOrigin[nDim1] + w;
  2730.     mins[1] = m_vOrigin[nDim2] - h;
  2731.     maxs[1] = m_vOrigin[nDim2] + h;
  2732.  
  2733.  
  2734.     qglOrtho (mins[0], maxs[0], mins[1], maxs[1], -8192, 8192);
  2735.   //glRotatef
  2736.     //
  2737.     // now draw the grid
  2738.     //
  2739.     XY_DrawGrid ();
  2740.  
  2741.     //
  2742.     // draw stuff
  2743.     //
  2744.   qglShadeModel (GL_FLAT);
  2745.     qglDisable(GL_TEXTURE_2D);
  2746.     qglDisable(GL_TEXTURE_1D);
  2747.     qglDisable(GL_DEPTH_TEST);
  2748.     qglDisable(GL_BLEND);
  2749.     qglColor3f(0, 0, 0);
  2750.  
  2751.   //glEnable (GL_LINE_SMOOTH);
  2752.  
  2753.     drawn = culled = 0;
  2754.  
  2755.   if (m_nViewType != XY)
  2756.   {
  2757.     qglPushMatrix();
  2758.     if (m_nViewType == YZ)
  2759.       qglRotatef (-90,  0, 1, 0);        // put Z going up
  2760.     //else
  2761.       qglRotatef (-90,  1, 0, 0);        // put Z going up
  2762.   }
  2763.  
  2764.     e = world_entity;
  2765.     
  2766.   if (m_bTiming)
  2767.         start2 = Sys_DoubleTime();
  2768.  
  2769.     for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
  2770.     {
  2771.         if (brush->mins[nDim1] > maxs[0] || 
  2772.         brush->mins[nDim2] > maxs[1] || 
  2773.         brush->maxs[nDim1] < mins[0] || 
  2774.         brush->maxs[nDim2] < mins[1])
  2775.         {
  2776.           culled++;
  2777.           continue;        // off screen
  2778.         }
  2779.  
  2780.          if (FilterBrush (brush))
  2781.              continue;
  2782.  
  2783.     drawn++;
  2784.  
  2785.     if (brush->owner != e && brush->owner)
  2786.         {
  2787.  
  2788.             qglColor3fv(brush->owner->eclass->color);
  2789.         }
  2790.     else
  2791.     {
  2792.           qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES]);
  2793.     }
  2794.  
  2795.     Brush_DrawXY(brush, m_nViewType);
  2796.     }
  2797.   
  2798.   
  2799.   if (m_bTiming)
  2800.         end2 = Sys_DoubleTime();
  2801.  
  2802.  
  2803.   DrawPathLines ();
  2804.  
  2805.     //
  2806.     // draw pointfile
  2807.     //
  2808.     if ( g_qeglobals.d_pointfile_display_list)
  2809.         qglCallList (g_qeglobals.d_pointfile_display_list);
  2810.  
  2811.  
  2812.   if (!(m_nViewType == XY))
  2813.     qglPopMatrix();
  2814.  
  2815.   //
  2816.     // draw block grid
  2817.     //
  2818.     if ( g_qeglobals.show_blocks)
  2819.         XY_DrawBlockGrid ();
  2820.  
  2821.     //
  2822.     // now draw selected brushes
  2823.     //
  2824.   if (m_nViewType != XY)
  2825.   {
  2826.     qglPushMatrix();
  2827.     if (m_nViewType == YZ)
  2828.       qglRotatef (-90,  0, 1, 0);        // put Z going up
  2829.     //else
  2830.       qglRotatef (-90,  1, 0, 0);        // put Z going up
  2831.   }
  2832.  
  2833.  
  2834.   qglPushMatrix();
  2835.     qglTranslatef( g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]);
  2836.  
  2837.   if (RotateMode())
  2838.     qglColor3f(0.8, 0.1, 0.9);
  2839.   else
  2840.   if (ScaleMode())
  2841.     qglColor3f(0.1, 0.8, 0.1);
  2842.   else
  2843.     qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES]);
  2844.  
  2845.  
  2846.   if (g_PrefsDlg.m_bNoStipple == FALSE)
  2847.   {
  2848.     qglEnable (GL_LINE_STIPPLE);
  2849.       qglLineStipple (3, 0xaaaa);
  2850.   }
  2851.     qglLineWidth (2);
  2852.  
  2853.   vec3_t vMinBounds;
  2854.   vec3_t vMaxBounds;
  2855.   vMinBounds[0] = vMinBounds[1] = vMinBounds[2] = 9999.9f;
  2856.   vMaxBounds[0] = vMaxBounds[1] = vMaxBounds[2] = -9999.9f;
  2857.  
  2858.   int nSaveDrawn = drawn;
  2859.   bool bFixedSize = false;
  2860.     for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
  2861.     {
  2862.         drawn++;
  2863.         Brush_DrawXY(brush, m_nViewType);
  2864.  
  2865.     if (!bFixedSize)
  2866.     {
  2867.       if (brush->owner->eclass->fixedsize)
  2868.         bFixedSize = true;
  2869.       if (g_PrefsDlg.m_bSizePaint)
  2870.       {
  2871.         for (i = 0; i < 3; i ++)
  2872.         {
  2873.           if (brush->mins[i] < vMinBounds[i])
  2874.             vMinBounds[i] = brush->mins[i];
  2875.           if (brush->maxs[i] > vMaxBounds[i])
  2876.             vMaxBounds[i] = brush->maxs[i];
  2877.         }
  2878.       }
  2879.     }
  2880.     }
  2881.  
  2882.   if (g_PrefsDlg.m_bNoStipple == FALSE)
  2883.   {
  2884.       qglDisable (GL_LINE_STIPPLE);
  2885.   }
  2886.     qglLineWidth (1);
  2887.  
  2888.   if (!bFixedSize && !RotateMode() && !ScaleMode() && drawn - nSaveDrawn > 0 && g_PrefsDlg.m_bSizePaint)
  2889.     PaintSizeInfo(nDim1, nDim2, vMinBounds, vMaxBounds);
  2890.  
  2891.  
  2892.     // edge / vertex flags
  2893.  
  2894.     if (g_qeglobals.d_select_mode == sel_vertex)
  2895.     {
  2896.         qglPointSize (4);
  2897.         qglColor3f (0,1,0);
  2898.         qglBegin (GL_POINTS);
  2899.         for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
  2900.             qglVertex3fv (g_qeglobals.d_points[i]);
  2901.         qglEnd ();
  2902.         qglPointSize (1);
  2903.     }
  2904.     else if (g_qeglobals.d_select_mode == sel_edge)
  2905.     {
  2906.         float    *v1, *v2;
  2907.  
  2908.         qglPointSize (4);
  2909.         qglColor3f (0,0,1);
  2910.         qglBegin (GL_POINTS);
  2911.         for (i=0 ; i<g_qeglobals.d_numedges ; i++)
  2912.         {
  2913.             v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1];
  2914.             v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2];
  2915.             qglVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5);
  2916.         }
  2917.         qglEnd ();
  2918.         qglPointSize (1);
  2919.     }
  2920.  
  2921.   qglPopMatrix();
  2922.  
  2923.     qglTranslatef (-g_qeglobals.d_select_translate[0], -g_qeglobals.d_select_translate[1], -g_qeglobals.d_select_translate[2]);
  2924.  
  2925.  
  2926.   if (!(m_nViewType == XY))
  2927.     qglPopMatrix();
  2928.  
  2929.   // area selection hack
  2930.   if (g_qeglobals.d_select_mode == sel_area)
  2931.   {
  2932.       qglEnable (GL_BLEND);
  2933.       qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  2934.       qglColor4f(0.0, 0.0, 1.0, 0.25);
  2935.     qglRectf(g_qeglobals.d_vAreaTL[nDim1], g_qeglobals.d_vAreaTL[nDim2], g_qeglobals.d_vAreaBR[nDim1], g_qeglobals.d_vAreaBR[nDim2]);
  2936.       qglDisable (GL_BLEND);
  2937.   }
  2938.  
  2939.  
  2940.   //
  2941.     // now draw camera point
  2942.     //
  2943.     DrawCameraIcon ();
  2944.     DrawZIcon ();
  2945.  
  2946.   if (RotateMode())
  2947.   {
  2948.     DrawRotateIcon();
  2949.   }
  2950.  
  2951.   // plugin entities
  2952.   //++timo TODO: use an object for the 2D view
  2953.   DrawPluginEntities( (VIEWTYPE)m_nViewType );
  2954.  
  2955.   qglFinish();
  2956.     //QE_CheckOpenGLForErrors();
  2957.  
  2958.   if (m_bTiming)
  2959.     {
  2960.         end = Sys_DoubleTime ();
  2961.     i = (int)(1000*(end-start));
  2962.     int i3 = (int)(1000*(end2-start2));
  2963.     g_lCount++;
  2964.     g_lTotal += i;
  2965.     int i2 = g_lTotal / g_lCount;
  2966.         Sys_Printf ("xy: %i ab: %i  avg: %i\n", i, i3, i2);
  2967.     }
  2968. }
  2969.  
  2970. /*
  2971. ==============
  2972. XY_Overlay
  2973. ==============
  2974. */
  2975. void CXYWnd::XY_Overlay()
  2976. {
  2977.     int    w, h;
  2978.     int    r[4];
  2979.     static    vec3_t    lastz;
  2980.     static    vec3_t    lastcamera;
  2981.  
  2982.  
  2983.     qglViewport(0, 0, m_nWidth, m_nHeight);
  2984.  
  2985.     //
  2986.     // set up viewpoint
  2987.     //
  2988.     qglMatrixMode(GL_PROJECTION);
  2989.   qglLoadIdentity ();
  2990.  
  2991.     w = m_nWidth / 2 / m_fScale;
  2992.     h = m_nHeight / 2 / m_fScale;
  2993.  
  2994.   qglOrtho (m_vOrigin[0] - w, m_vOrigin[0] + w    , m_vOrigin[1] - h, m_vOrigin[1] + h, -8000, 8000);
  2995.     //
  2996.     // erase the old camera and z checker positions
  2997.     // if the entire xy hasn't been redrawn
  2998.     //
  2999.     if (m_bDirty)
  3000.     {
  3001.         qglReadBuffer (GL_BACK);
  3002.         qglDrawBuffer (GL_FRONT);
  3003.  
  3004.         qglRasterPos2f (lastz[0]-9, lastz[1]-9);
  3005.         qglGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
  3006.         qglCopyPixels(r[0], r[1], 18,18, GL_COLOR);
  3007.  
  3008.         qglRasterPos2f (lastcamera[0]-50, lastcamera[1]-50);
  3009.         qglGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
  3010.         qglCopyPixels(r[0], r[1], 100,100, GL_COLOR);
  3011.     }
  3012.     m_bDirty = true;
  3013.  
  3014.     //
  3015.     // save off underneath where we are about to draw
  3016.     //
  3017.     VectorCopy (z.origin, lastz);
  3018.     VectorCopy (g_pParentWnd->GetCamera()->Camera().origin, lastcamera);
  3019.  
  3020.     qglReadBuffer (GL_FRONT);
  3021.     qglDrawBuffer (GL_BACK);
  3022.  
  3023.     qglRasterPos2f (lastz[0]-9, lastz[1]-9);
  3024.     qglGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
  3025.     qglCopyPixels(r[0], r[1], 18,18, GL_COLOR);
  3026.  
  3027.     qglRasterPos2f (lastcamera[0]-50, lastcamera[1]-50);
  3028.     qglGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
  3029.     qglCopyPixels(r[0], r[1], 100,100, GL_COLOR);
  3030.  
  3031.     //
  3032.     // draw the new icons
  3033.     //
  3034.     qglDrawBuffer (GL_FRONT);
  3035.  
  3036.   qglShadeModel (GL_FLAT);
  3037.     qglDisable(GL_TEXTURE_2D);
  3038.     qglDisable(GL_TEXTURE_1D);
  3039.     qglDisable(GL_DEPTH_TEST);
  3040.     qglDisable(GL_BLEND);
  3041.     qglColor3f(0, 0, 0);
  3042.  
  3043.     DrawCameraIcon ();
  3044.     DrawZIcon ();
  3045.  
  3046.     qglDrawBuffer (GL_BACK);
  3047.   qglFinish();
  3048. }
  3049.  
  3050.  
  3051. vec3_t& CXYWnd::GetOrigin()
  3052. {
  3053.   return m_vOrigin;
  3054. }
  3055.  
  3056. void CXYWnd::SetOrigin(vec3_t org)
  3057. {
  3058.     m_vOrigin[0] = org[0];
  3059.     m_vOrigin[1] = org[1];
  3060.     m_vOrigin[2] = org[2];
  3061. }
  3062.  
  3063. void CXYWnd::OnSize(UINT nType, int cx, int cy) 
  3064. {
  3065.     CWnd::OnSize(nType, cx, cy);
  3066.   CRect rect;
  3067.   GetClientRect(rect);
  3068.   m_nWidth = rect.Width();
  3069.   m_nHeight = rect.Height();
  3070. }
  3071.  
  3072. brush_t hold_brushes;
  3073. void CXYWnd::Clip()
  3074. {
  3075.   if (ClipMode())
  3076.   {
  3077.     hold_brushes.next = &hold_brushes;
  3078.     ProduceSplitLists();
  3079.     //brush_t* pList = (g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits;
  3080.     brush_t* pList;
  3081.     if (g_PrefsDlg.m_bSwitchClip)
  3082.         pList = ( (m_nViewType == XZ) ? g_bSwitch: !g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits;
  3083.     else
  3084.         pList = ( (m_nViewType == XZ) ? !g_bSwitch: g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits;
  3085.  
  3086.     
  3087.     if (pList->next != pList)
  3088.     {
  3089.       Brush_CopyList(pList, &hold_brushes);
  3090.       CleanList(&g_brFrontSplits);
  3091.       CleanList(&g_brBackSplits);
  3092.       Select_Delete();
  3093.       Brush_CopyList(&hold_brushes, &selected_brushes);
  3094.       if (RogueClipMode())
  3095.         RetainClipMode(false);
  3096.       else
  3097.         RetainClipMode(true);
  3098.       Sys_UpdateWindows(W_ALL);
  3099.     }
  3100.   }
  3101.   else if (PathMode())
  3102.   {
  3103.     FinishSmartCreation();
  3104.     if (g_pPathFunc)
  3105.       g_pPathFunc(true, g_nPathCount);
  3106.     g_pPathFunc = NULL;
  3107.     g_nPathCount = 0;
  3108.     g_bPathMode = false;
  3109.   }
  3110. }
  3111.  
  3112. void CXYWnd::SplitClip()
  3113. {
  3114.     ProduceSplitLists();
  3115.     if ((g_brFrontSplits.next != &g_brFrontSplits) &&
  3116.         (g_brBackSplits.next != &g_brBackSplits))
  3117.     {
  3118.         Select_Delete();
  3119.         Brush_CopyList(&g_brFrontSplits, &selected_brushes);
  3120.         Brush_CopyList(&g_brBackSplits, &selected_brushes);
  3121.         CleanList(&g_brFrontSplits);
  3122.         CleanList(&g_brBackSplits);
  3123.         if (RogueClipMode())
  3124.             RetainClipMode(false);
  3125.         else
  3126.             RetainClipMode(true);
  3127.     }
  3128. }
  3129.  
  3130. void CXYWnd::FlipClip()
  3131. {
  3132.   g_bSwitch = !g_bSwitch;
  3133.   Sys_UpdateWindows(XY | W_CAMERA_IFON);
  3134. }
  3135.  
  3136.  
  3137. // makes sure the selected brush or camera is in view
  3138. void CXYWnd::PositionView()
  3139. {
  3140.   int nDim1 = (m_nViewType == YZ) ? 1 : 0;
  3141.   int nDim2 = (m_nViewType == XY) ? 1 : 2;
  3142.   brush_t* b = selected_brushes.next;
  3143.   if (b && b->next != b)
  3144.   {
  3145.       m_vOrigin[nDim1] = b->mins[nDim1];
  3146.       m_vOrigin[nDim2] = b->mins[nDim2];
  3147.   }
  3148.   else
  3149.   {
  3150.       m_vOrigin[nDim1] = g_pParentWnd->GetCamera()->Camera().origin[nDim1];
  3151.       m_vOrigin[nDim2] = g_pParentWnd->GetCamera()->Camera().origin[nDim2];
  3152.   }
  3153. }
  3154.  
  3155. void CXYWnd::VectorCopyXY(vec3_t in, vec3_t out)
  3156. {
  3157.   if (m_nViewType == XY)
  3158.   {
  3159.       out[0] = in[0];
  3160.       out[1] = in[1];
  3161.   }
  3162.   else
  3163.   if (m_nViewType == XZ)
  3164.   {
  3165.       out[0] = in[0];
  3166.       out[2] = in[2];
  3167.   }
  3168.   else
  3169.   {
  3170.       out[1] = in[1];
  3171.       out[2] = in[2];
  3172.   }
  3173. }
  3174.  
  3175.  
  3176. void CXYWnd::OnDestroy() 
  3177. {
  3178.     QEW_StopGL( GetSafeHwnd(), s_hglrcXY, s_hdcXY );
  3179.     CWnd::OnDestroy();
  3180.   // delete this;
  3181. }
  3182.  
  3183. void CXYWnd::SetViewType(int n) 
  3184.   m_nViewType = n; 
  3185.   if (g_pParentWnd->CurrentStyle() == QR_QE4)
  3186.   {
  3187.     CString str = "YZ Side";
  3188.     if (m_nViewType == XY)
  3189.       str = "XY Top";
  3190.     else if (m_nViewType == XZ)
  3191.       str = "XZ Front";
  3192.     SetWindowText(str);
  3193.   }
  3194. };
  3195.  
  3196. void CXYWnd::Redraw(unsigned int nBits)
  3197. {
  3198.   m_nUpdateBits = nBits;
  3199.   RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
  3200.   m_nUpdateBits = W_XY;
  3201. }
  3202.  
  3203. bool CXYWnd::RotateMode()
  3204. {
  3205.   return g_bRotateMode;
  3206. }
  3207.  
  3208. bool CXYWnd::ScaleMode()
  3209. {
  3210.   return g_bScaleMode;
  3211. }
  3212.  
  3213. bool CXYWnd::SetRotateMode(bool bMode)
  3214. {
  3215.   if (bMode && selected_brushes.next != &selected_brushes)
  3216.   {
  3217.     g_bRotateMode = true;
  3218.     Select_GetTrueMid(g_vRotateOrigin);
  3219.     g_vRotation[0] = g_vRotation[1] = g_vRotation[2] = 0.0;
  3220.   }
  3221.   else 
  3222.   {
  3223.     if (bMode)
  3224.       Sys_Printf("Need a brush selected to turn on Mouse Rotation mode\n");
  3225.     g_bRotateMode = false;
  3226.   }
  3227.   RedrawWindow();
  3228.   return g_bRotateMode;
  3229. }
  3230.  
  3231. void CXYWnd::SetScaleMode(bool bMode)
  3232. {
  3233.   g_bScaleMode = bMode;
  3234.   RedrawWindow();
  3235. }
  3236.  
  3237.  
  3238.  
  3239.  
  3240. // xy - z
  3241. // xz - y
  3242. // yz - x
  3243.  
  3244. void CXYWnd::OnSelectMouserotate() 
  3245. {
  3246.     // TODO: Add your command handler code here
  3247.     
  3248. }
  3249.  
  3250. void CleanCopyEntities()
  3251. {
  3252.     entity_t* pe = g_enClipboard.next;
  3253.   while (pe != NULL && pe != &g_enClipboard)
  3254.   {
  3255.     entity_t* next = pe->next;
  3256.     epair_t* enext = NULL;
  3257.       for (epair_t* ep = pe->epairs ; ep ; ep=enext)
  3258.     {
  3259.           enext = ep->next;
  3260.       free (ep->key);
  3261.       free (ep->value);
  3262.           free (ep);
  3263.     }
  3264.       free (pe);
  3265.     pe = next;
  3266.   }
  3267.   g_enClipboard.next = g_enClipboard.prev = &g_enClipboard;
  3268. }
  3269.  
  3270. entity_t    *Entity_CopyClone (entity_t *e)
  3271. {
  3272.     entity_t    *n;
  3273.     epair_t        *ep, *np;
  3274.  
  3275.     n = (entity_t*)qmalloc(sizeof(*n));
  3276.     n->brushes.onext = n->brushes.oprev = &n->brushes;
  3277.     n->eclass = e->eclass;
  3278.  
  3279.     // add the entity to the entity list
  3280.     n->next = g_enClipboard.next;
  3281.     g_enClipboard.next = n;
  3282.     n->next->prev = n;
  3283.     n->prev = &g_enClipboard;
  3284.  
  3285.     for (ep = e->epairs ; ep ; ep=ep->next)
  3286.     {
  3287.         np = (epair_t*)qmalloc(sizeof(*np));
  3288.         np->key = copystring(ep->key);
  3289.         np->value = copystring(ep->value);
  3290.         np->next = n->epairs;
  3291.         n->epairs = np;
  3292.     }
  3293.     return n;
  3294. }
  3295.  
  3296. bool OnList(entity_t* pFind, CPtrArray* pList)
  3297. {
  3298.   int nSize = pList->GetSize();
  3299.   while (nSize-- > 0)
  3300.   {
  3301.     entity_t* pEntity = reinterpret_cast<entity_t*>(pList->GetAt(nSize));
  3302.     if (pEntity == pFind)
  3303.       return true;
  3304.   }
  3305.   return false;
  3306. }
  3307.  
  3308. void CXYWnd::Copy()
  3309. {
  3310. #if 1
  3311.   CWaitCursor WaitCursor; 
  3312.   g_Clipboard.SetLength(0);
  3313.   g_PatchClipboard.SetLength(0);
  3314.   
  3315.   Map_SaveSelected(&g_Clipboard, &g_PatchClipboard);
  3316.   bool bClipped = false;
  3317.   UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings");
  3318.   if (nClipboard > 0)
  3319.   {
  3320.     if (OpenClipboard())
  3321.     {
  3322.       ::EmptyClipboard();
  3323.           long lSize = g_Clipboard.GetLength();
  3324.       HANDLE h = ::GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, lSize + sizeof(long));
  3325.       if (h != NULL)
  3326.       {
  3327.         unsigned char *cp = reinterpret_cast<unsigned char*>(::GlobalLock(h));
  3328.                 memcpy(cp, &lSize, sizeof(long));
  3329.                 cp += sizeof(long);
  3330.         g_Clipboard.SeekToBegin();
  3331.         g_Clipboard.Read(cp, lSize);
  3332.         ::GlobalUnlock(h);
  3333.         ::SetClipboardData(nClipboard, h);
  3334.         ::CloseClipboard();
  3335.         bClipped = true;
  3336.       }
  3337.     }
  3338.   }
  3339.  
  3340.   if (!bClipped)
  3341.   {
  3342.     Sys_Printf("Unable to register Windows clipboard formats, copy/paste between editors will not be possible");
  3343.   }
  3344.  
  3345. /*
  3346.   CString strOut;
  3347.   ::GetTempPath(1024, strOut.GetBuffer(1024));
  3348.   strOut.ReleaseBuffer();
  3349.   AddSlash(strOut);
  3350.   strOut += "RadiantClipboard.$$$";
  3351.   Map_SaveSelected(strOut.GetBuffer(0));
  3352. */
  3353.  
  3354. #else
  3355.   CPtrArray holdArray;
  3356.   CleanList(&g_brClipboard);
  3357.   CleanCopyEntities();
  3358.     for (brush_t* pBrush = selected_brushes.next ; pBrush != NULL && pBrush != &selected_brushes ; pBrush=pBrush->next)
  3359.   {
  3360.         if (pBrush->owner == world_entity)
  3361.     {
  3362.       brush_t* pClone = Brush_Clone(pBrush);
  3363.       pClone->owner = NULL;
  3364.         Brush_AddToList (pClone, &g_brClipboard);
  3365.     }
  3366.     else
  3367.     {
  3368.       if (!OnList(pBrush->owner, &holdArray))
  3369.       {
  3370.         entity_t* e = pBrush->owner;
  3371.         holdArray.Add(reinterpret_cast<void*>(e));
  3372.         entity_t* pEClone = Entity_CopyClone(e);
  3373.               for (brush_t* pEB = e->brushes.onext ; pEB != &e->brushes ; pEB=pEB->onext)
  3374.               {
  3375.           brush_t* pClone = Brush_Clone(pEB);
  3376.             //Brush_AddToList (pClone, &g_brClipboard);
  3377.           Entity_LinkBrush(pEClone, pClone);
  3378.           Brush_Build(pClone);
  3379.               }
  3380.       }
  3381.     }
  3382.   }
  3383. #endif
  3384. }
  3385.  
  3386. void CXYWnd::Undo()
  3387. {
  3388. /*
  3389.   if (g_brUndo.next != &g_brUndo)
  3390.   {
  3391.     g_bScreenUpdates = false; 
  3392.     Select_Delete();
  3393.       for (brush_t* pBrush = g_brUndo.next ; pBrush != NULL && pBrush != &g_brUndo ; pBrush=pBrush->next)
  3394.     {
  3395.       brush_t* pClone = Brush_Clone(pBrush);
  3396.         Brush_AddToList (pClone, &active_brushes);
  3397.             Entity_LinkBrush (pBrush->pUndoOwner, pClone);
  3398.       Brush_Build(pClone);
  3399.       Select_Brush(pClone);
  3400.     }
  3401.     CleanList(&g_brUndo);
  3402.     g_bScreenUpdates = true; 
  3403.     Sys_UpdateWindows(W_ALL);
  3404.   }
  3405.   else Sys_Printf("Nothing to undo.../n");
  3406. */
  3407. }
  3408.  
  3409. void CXYWnd::UndoClear()
  3410. {
  3411. /*  
  3412.   CleanList(&g_brUndo);
  3413. */
  3414. }
  3415.  
  3416. void CXYWnd::UndoCopy()
  3417. {
  3418. /*
  3419.   CleanList(&g_brUndo);
  3420.     for (brush_t* pBrush = selected_brushes.next ; pBrush != NULL && pBrush != &selected_brushes ; pBrush=pBrush->next)
  3421.   {
  3422.     brush_t* pClone = Brush_Clone(pBrush);
  3423.     pClone->pUndoOwner = pBrush->owner;
  3424.       Brush_AddToList (pClone, &g_brUndo);
  3425.   }
  3426. */
  3427. }
  3428.  
  3429. bool CXYWnd::UndoAvailable()
  3430. {
  3431.   return (g_brUndo.next != &g_brUndo);
  3432. }
  3433.  
  3434.  
  3435.  
  3436. void CXYWnd::Paste()
  3437. {
  3438. #if 1
  3439.  
  3440.   CWaitCursor WaitCursor; 
  3441.   bool bPasted = false;
  3442.   UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings");
  3443.   if (nClipboard > 0 && OpenClipboard() && ::IsClipboardFormatAvailable(nClipboard))
  3444.   {
  3445.     HANDLE h = ::GetClipboardData(nClipboard);
  3446.     if (h)
  3447.     {
  3448.       g_Clipboard.SetLength(0);
  3449.             unsigned char *cp = reinterpret_cast<unsigned char*>(::GlobalLock(h));
  3450.             long lSize = 0;
  3451.             memcpy(&lSize, cp, sizeof(long));
  3452.             cp += sizeof(long);
  3453.       g_Clipboard.Write(cp, lSize);
  3454.     }
  3455.     ::GlobalUnlock(h);
  3456.     ::CloseClipboard();
  3457.   }
  3458.  
  3459.   if (g_Clipboard.GetLength() > 0)
  3460.   {
  3461.     g_Clipboard.SeekToBegin();
  3462.     int nLen = g_Clipboard.GetLength();
  3463.     char* pBuffer = new char[nLen+1];
  3464.       memset( pBuffer, 0, sizeof(pBuffer) );
  3465.     g_Clipboard.Read(pBuffer, nLen);
  3466.     pBuffer[nLen] = '\0';
  3467.     Map_ImportBuffer(pBuffer);
  3468.     delete []pBuffer;
  3469.   }
  3470.  
  3471. #if 0
  3472.   if (g_PatchClipboard.GetLength() > 0)
  3473.   {
  3474.     g_PatchClipboard.SeekToBegin();
  3475.     int nLen = g_PatchClipboard.GetLength();
  3476.     char* pBuffer = new char[nLen+1];
  3477.     g_PatchClipboard.Read(pBuffer, nLen);
  3478.     pBuffer[nLen] = '\0';
  3479.     Patch_ReadBuffer(pBuffer, true);
  3480.     delete []pBuffer;
  3481.   }
  3482. #endif
  3483.  
  3484. #else
  3485.   if (g_brClipboard.next != &g_brClipboard || g_enClipboard.next != &g_enClipboard)
  3486.   {
  3487.     Select_Deselect();
  3488.  
  3489.       for (brush_t* pBrush = g_brClipboard.next ; pBrush != NULL && pBrush != &g_brClipboard ; pBrush=pBrush->next)
  3490.     {
  3491.       brush_t* pClone = Brush_Clone(pBrush);
  3492.         //pClone->owner = pBrush->owner;
  3493.       if (pClone->owner == NULL)
  3494.               Entity_LinkBrush (world_entity, pClone);
  3495.         
  3496.       Brush_AddToList (pClone, &selected_brushes);
  3497.       Brush_Build(pClone);
  3498.     }
  3499.  
  3500.     for (entity_t* pEntity = g_enClipboard.next; pEntity != NULL && pEntity != &g_enClipboard; pEntity = pEntity->next)
  3501.     {
  3502.       entity_t* pEClone = Entity_Clone(pEntity);
  3503.             for (brush_t* pEB = pEntity->brushes.onext ; pEB != &pEntity->brushes ; pEB=pEB->onext)
  3504.             {
  3505.         brush_t* pClone = Brush_Clone(pEB);
  3506.           Brush_AddToList (pClone, &selected_brushes);
  3507.         Entity_LinkBrush(pEClone, pClone);
  3508.         Brush_Build(pClone);
  3509.         if (pClone->owner && pClone->owner != world_entity)
  3510.         {
  3511.                 UpdateEntitySel(pClone->owner->eclass);
  3512.         }
  3513.             }
  3514.     }
  3515.  
  3516.     Sys_UpdateWindows(W_ALL);
  3517.   }
  3518.   else Sys_Printf("Nothing to paste.../n");
  3519. #endif
  3520. }
  3521.  
  3522.  
  3523. vec3_t& CXYWnd::Rotation()
  3524. {
  3525.   return g_vRotation;
  3526. }
  3527.  
  3528. vec3_t& CXYWnd::RotateOrigin()
  3529. {
  3530.   return g_vRotateOrigin;
  3531. }
  3532.  
  3533.  
  3534. void CXYWnd::OnTimer(UINT nIDEvent) 
  3535. {
  3536.   int nDim1 = (m_nViewType == YZ) ? 1 : 0;
  3537.   int nDim2 = (m_nViewType == XY) ? 1 : 2;
  3538.     m_vOrigin[nDim1] += m_ptDragAdj.x / m_fScale;
  3539.     m_vOrigin[nDim2] -= m_ptDragAdj.y / m_fScale;
  3540.   Sys_UpdateWindows(W_XY | W_CAMERA);
  3541.   //int nH = (m_ptDrag.y == 0) ? -1 : m_ptDrag.y;
  3542.   m_ptDrag += m_ptDragAdj;
  3543.   m_ptDragTotal += m_ptDragAdj;
  3544.   XY_MouseMoved (m_ptDrag.x, m_nHeight - 1 - m_ptDrag.y , m_nScrollFlags);
  3545.     //m_vOrigin[nDim1] -= m_ptDrag.x / m_fScale;
  3546.     //m_vOrigin[nDim1] -= m_ptDrag.x / m_fScale;
  3547. }
  3548.  
  3549. void CXYWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
  3550. {
  3551.   g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false);
  3552.   //CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
  3553. }
  3554.  
  3555. void CXYWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp) 
  3556. {
  3557.     CWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
  3558. }
  3559.  
  3560. void CXYWnd::OnKillFocus(CWnd* pNewWnd) 
  3561. {
  3562.     CWnd::OnKillFocus(pNewWnd);
  3563.     SendMessage(WM_NCACTIVATE, FALSE , 0 );
  3564. }
  3565.  
  3566. void CXYWnd::OnSetFocus(CWnd* pOldWnd) 
  3567. {
  3568.     CWnd::OnSetFocus(pOldWnd);
  3569.     SendMessage(WM_NCACTIVATE, TRUE , 0 );
  3570. }
  3571.  
  3572. void CXYWnd::OnClose() 
  3573. {
  3574.     CWnd::OnClose();
  3575. }
  3576.  
  3577. // should be static as should be the rotate scale stuff
  3578. bool CXYWnd::AreaSelectOK()
  3579. {
  3580.   return RotateMode() ? false : ScaleMode() ? false : true;
  3581. }