doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
XYWnd.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "qe3.h"
33 #include "Radiant.h"
34 #include "XYWnd.h"
35 #include "DialogInfo.h"
36 #include "splines.h"
37 #include "../../renderer/tr_local.h"
38 #include "../../renderer/model_local.h" // for idRenderModelLiquid
39 
40 #ifdef _DEBUG
41  #define new DEBUG_NEW
42  #undef THIS_FILE
43 static char THIS_FILE[] = __FILE__;
44 #endif
45 
46 const char *g_pDimStrings[] = { "x:%.f", "y:%.f", "z:%.f" };
47 const char *g_pOrgStrings[] = { "(x:%.f y:%.f)", "(x:%.f z:%.f)", "(y:%.f z:%.f)" };
48 CString g_strDim;
49 CString g_strStatus;
50 
51 bool g_bCrossHairs = false;
57 bool g_bSwitch;
64 
65 brush_t g_brClipboard;
66 brush_t g_brUndo;
68 
71 
77 
79 
85 
86 const int XY_LEFT = 0x01;
87 const int XY_RIGHT = 0x02;
88 const int XY_UP = 0x04;
89 const int XY_DOWN = 0x08;
90 
92 void Select_Ungroup();
93 
94 /*
95  =======================================================================================================================
96  =======================================================================================================================
97  */
98 void AcquirePath(int nCount, PFNPathCallback *pFunc) {
99  g_nPathCount = 0;
100  g_nPathLimit = nCount;
101  g_pPathFunc = pFunc;
102  g_bPathMode = true;
103 }
104 
105 CPtrArray g_ptrMenus;
106 
107 CMemFile g_Clipboard(4096);
108 CMemFile g_PatchClipboard(4096);
109 
110 extern int pressx;
111 extern int pressy;
112 
113 /*
114  =======================================================================================================================
115  =======================================================================================================================
116  */
117 float fDiff(float f1, float f2) {
118  if (f1 > f2) {
119  return f1 - f2;
120  }
121  else {
122  return f2 - f1;
123  }
124 }
125 
126 #define MAX_DRAG_POINTS 128
127 
128 CPtrArray dragPoints;
129 static CDragPoint *activeDrag = NULL;
130 static bool activeDragging = false;
131 
132 /*
133  =======================================================================================================================
134  =======================================================================================================================
135  */
136 bool CDragPoint::PointWithin(idVec3 p, int nView) {
137  if (nView == -1) {
138  if (fDiff(p[0], vec[0]) <= 3 && fDiff(p[1], vec[1]) <= 3 && fDiff(p[2], vec[2]) <= 3) {
139  return true;
140  }
141  }
142  else {
143  int nDim1 = (nView == YZ) ? 1 : 0;
144  int nDim2 = (nView == XY) ? 1 : 2;
145  if (fDiff(p[nDim1], vec[nDim1]) <= 3 && fDiff(p[nDim2], vec[nDim2]) <= 3) {
146  return true;
147  }
148  }
149 
150  return false;
151 }
152 
153 /*
154  =======================================================================================================================
155  =======================================================================================================================
156  */
157 CDragPoint *PointRay(const idVec3 &org, const idVec3 &dir, float *dist) {
158  int i, besti;
159  float d, bestd;
160  idVec3 temp;
161  CDragPoint *drag = NULL;
162  CDragPoint *priority = NULL;
163 
164  // find the point closest to the ray
165  float scale = g_pParentWnd->ActiveXY()->Scale();
166  besti = -1;
167  bestd = 12 / scale / 2;
168 
169  int count = dragPoints.GetSize();
170  for (i = 0; i < count; i++) {
171  drag = reinterpret_cast < CDragPoint * > (dragPoints[i]);
172  temp = drag->vec - org;
173  d = temp * dir;
174  temp = org + d * dir;
175  temp = drag->vec - temp;
176  d = temp.Length();
177  if ( d < bestd ) {
178  bestd = d;
179  besti = i;
180  if (priority == NULL) {
181  priority = reinterpret_cast < CDragPoint * > (dragPoints[besti]);
182  if (!priority->priority) {
183  priority = NULL;
184  }
185  }
186  }
187  }
188 
189  if (besti == -1) {
190  return NULL;
191  }
192 
193  drag = reinterpret_cast < CDragPoint * > (dragPoints[besti]);
194  if (priority && !drag->priority) {
195  drag = priority;
196  }
197 
198  return drag;
199 }
200 
201 /*
202  =======================================================================================================================
203  =======================================================================================================================
204  */
205 void ClearSelectablePoints(brush_t *b) {
206  if (b == NULL) {
207  dragPoints.RemoveAll();
208  }
209  else {
210  CPtrArray ptr;
211  ptr.Copy(dragPoints);
212  dragPoints.RemoveAll();
213 
214  int count = ptr.GetSize();
215  for (int i = 0; i < count; i++) {
216  if (b == reinterpret_cast < CDragPoint * > ( ptr.GetAt(i))->pBrush ) {
217  continue;
218  }
219  else {
220  dragPoints.Add(ptr.GetAt(i));
221  }
222  }
223  }
224 }
225 
226 /*
227  =======================================================================================================================
228  =======================================================================================================================
229  */
230 void AddSelectablePoint(brush_t *b, idVec3 v, int type, bool priority) {
231  dragPoints.Add(new CDragPoint(b, v, type, priority));
232 }
233 
234 /*
235  =======================================================================================================================
236  =======================================================================================================================
237  */
238 void UpdateSelectablePoint(brush_t *b, idVec3 v, int type) {
239  int count = dragPoints.GetSize();
240  for (int i = 0; i < count; i++) {
241  CDragPoint *drag = reinterpret_cast < CDragPoint * > (dragPoints.GetAt(i));
242  if (b == drag->pBrush && type == drag->nType) {
243  VectorCopy(v, drag->vec);
244  return;
245  }
246  }
247 }
248 
249 /*
250  =======================================================================================================================
251  =======================================================================================================================
252  */
253 void VectorToAngles(idVec3 vec, idVec3 angles) {
254  float forward;
255  float yaw, pitch;
256 
257  if ((vec[0] == 0) && (vec[1] == 0)) {
258  yaw = 0;
259  if (vec[2] > 0) {
260  pitch = 90;
261  }
262  else {
263  pitch = 270;
264  }
265  }
266  else {
267  yaw = RAD2DEG( atan2(vec[1], vec[0]) );
268  if (yaw < 0) {
269  yaw += 360;
270  }
271 
272  forward = (float)idMath::Sqrt(vec[0] * vec[0] + vec[1] * vec[1]);
273  pitch = RAD2DEG( atan2(vec[2], forward) );
274  if (pitch < 0) {
275  pitch += 360;
276  }
277  }
278 
279  angles[0] = pitch;
280  angles[1] = yaw;
281  angles[2] = 0;
282 }
283 
284 /*
285  =======================================================================================================================
286  RotateLight target is relative to the light origin up and right are relative to the target up and right are
287  perpendicular and are on a plane through the target with the target vector as normal delta is the movement of the
288  target relative to the light
289  =======================================================================================================================
290 */
292  v.x = floor(v.x / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
293  v.y = floor(v.y / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
294  v.z = floor(v.z / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
295 }
296 
297 /*
298  =======================================================================================================================
299  =======================================================================================================================
300 */
301 static void RotateLight(idVec3 &target, idVec3 &up, idVec3 &right, const idVec3 &delta) {
302  idVec3 newtarget, cross, dst;
303  idVec3 normal;
304  double angle, dist, d, len;
305  idMat3 rot;
306 
307  // calculate new target
308  newtarget = target + delta;
309 
310  // get the up and right vector relative to the light origin
311  up += target;
312  right += target;
313 
314  len = target.Length() * newtarget.Length();
315 
316  if (len > 0.1) {
317  // calculate the rotation angle between the vectors
318  double dp = target * newtarget;
319  double dv = dp / len;
320 
321  angle = RAD2DEG( idMath::ACos( dv ) );
322 
323  // get a vector orthogonal to the rotation plane
324  cross = target.Cross( newtarget );
325  cross.Normalize();
326 
327  if (cross[0] || cross[1] || cross[2]) {
328  // build the rotation matrix
329  rot = idRotation( vec3_origin, cross, angle ).ToMat3();
330 
331  rot.ProjectVector(target, dst);
332  target = dst;
333  rot.ProjectVector( up, dst );
334  up = dst;
335  rot.ProjectVector( right, dst);
336  right = dst;
337  }
338  }
339 
340  //
341  // project the up and right vectors onto a plane that goes through the target and
342  // has normal vector target.Normalize()
343  //
344  normal = target;
345  normal.Normalize();
346  dist = normal * target;
347 
348  d = (normal * up) - dist;
349  up -= d * normal;
350 
351  d = (normal * right) - dist;
352  right -= d * normal;
353 
354  //
355  // FIXME: maybe calculate the right vector with a cross product between the target
356  // and up vector, just to make sure the up and right vectors are perpendicular
357  // get the up and right vectors relative to the target
358  //
359  up -= target;
360  right -= target;
361 
362  // move the target in the (target - light_origin) direction
363  target = newtarget;
364  VectorSnapGrid(target);
365  VectorSnapGrid(up);
366  VectorSnapGrid(right);
367 }
368 
369 /*
370  =======================================================================================================================
371  =======================================================================================================================
372 */
373 extern idVec3 Brush_TransformedPoint(brush_t *b, const idVec3 &in);
374 extern idMat3 Brush_RotationMatrix(brush_t *b);
375 bool UpdateActiveDragPoint(const idVec3 &move) {
376  if (activeDrag) {
377  idMat3 mat = Brush_RotationMatrix(activeDrag->pBrush);
378  idMat3 invmat = mat.Transpose();
379  idVec3 target, up, right, start, end;
380  CString str;
381  if (activeDrag->nType == LIGHT_TARGET) {
382  GetVectorForKey(activeDrag->pBrush->owner, "light_target", target);
383  GetVectorForKey(activeDrag->pBrush->owner, "light_up", up);
384  GetVectorForKey(activeDrag->pBrush->owner, "light_right", right);
385  target *= mat;
386  up *= mat;
387  right *= mat;
388  RotateLight(target, up, right, move);
389  target *= invmat;
390  up *= invmat;
391  right *= invmat;
392  SetKeyVec3(activeDrag->pBrush->owner, "light_target", target);
393  SetKeyVec3(activeDrag->pBrush->owner, "light_up", up);
394  SetKeyVec3(activeDrag->pBrush->owner, "light_right", right);
395  target += (activeDrag->pBrush->trackLightOrigin) ? activeDrag->pBrush->owner->lightOrigin : activeDrag->pBrush->owner->origin;
396  UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush, target), LIGHT_TARGET);
397  up += target;
398  UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush,up), LIGHT_UP);
399  right += target;
400  UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush,right), LIGHT_RIGHT);
401  }
402  else if (activeDrag->nType == LIGHT_UP) {
403  GetVectorForKey(activeDrag->pBrush->owner, "light_up", up);
404  up *= mat;
405  up += move;
406  up *= invmat;
407  SetKeyVec3(activeDrag->pBrush->owner, "light_up", up);
408  GetVectorForKey(activeDrag->pBrush->owner, "light_target", target);
409  target += (activeDrag->pBrush->trackLightOrigin) ? activeDrag->pBrush->owner->lightOrigin : activeDrag->pBrush->owner->origin;
410  up += target;
411  UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush,up), LIGHT_UP);
412  }
413  else if (activeDrag->nType == LIGHT_RIGHT) {
414  GetVectorForKey(activeDrag->pBrush->owner, "light_right", right);
415  right *= mat;
416  right += move;
417  right *= invmat;
418  SetKeyVec3(activeDrag->pBrush->owner, "light_right", right);
419  GetVectorForKey(activeDrag->pBrush->owner, "light_target", target);
420  target += (activeDrag->pBrush->trackLightOrigin) ? activeDrag->pBrush->owner->lightOrigin : activeDrag->pBrush->owner->origin;
421  right += target;
422  UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush,right), LIGHT_RIGHT);
423  }
424  else if (activeDrag->nType == LIGHT_START) {
425  GetVectorForKey(activeDrag->pBrush->owner, "light_start", start);
426  start *= mat;
427  start += move;
428  start *= invmat;
429  SetKeyVec3(activeDrag->pBrush->owner, "light_start", start);
430  start += (activeDrag->pBrush->trackLightOrigin) ? activeDrag->pBrush->owner->lightOrigin : activeDrag->pBrush->owner->origin;
431  UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush,start), LIGHT_START);
432  }
433  else if (activeDrag->nType == LIGHT_END) {
434  GetVectorForKey(activeDrag->pBrush->owner, "light_end", end);
435  end *= mat;
436  end += move;
437  end *= invmat;
438  SetKeyVec3(activeDrag->pBrush->owner, "light_end", end);
439  end += (activeDrag->pBrush->trackLightOrigin) ? activeDrag->pBrush->owner->lightOrigin : activeDrag->pBrush->owner->origin;
440  UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush,end), LIGHT_END);
441  }
442  else if (activeDrag->nType == LIGHT_CENTER) {
443  GetVectorForKey(activeDrag->pBrush->owner, "light_center", end);
444  end *= mat;
445  end += move;
446  end *= invmat;
447  SetKeyVec3(activeDrag->pBrush->owner, "light_center", end);
448  end += (activeDrag->pBrush->trackLightOrigin) ? activeDrag->pBrush->owner->lightOrigin : activeDrag->pBrush->owner->origin;
449  UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush, end), LIGHT_CENTER);
450  }
451 
452  // FIXME: just build the frustrum values
453  Brush_Build(activeDrag->pBrush);
454  return true;
455  }
456 
457  return false;
458 }
459 
460 /*
461  =======================================================================================================================
462  =======================================================================================================================
463 */
464 bool SetDragPointCursor(idVec3 p, int nView) {
465  activeDrag = NULL;
466 
467  int numDragPoints = dragPoints.GetSize();
468  for (int i = 0; i < numDragPoints; i++) {
469  if (reinterpret_cast < CDragPoint * > (dragPoints[i])->PointWithin(p, nView)) {
470  activeDrag = reinterpret_cast < CDragPoint * > (dragPoints[i]);
471  return true;
472  }
473  }
474 
475  return false;
476 }
477 
478 /*
479  =======================================================================================================================
480  =======================================================================================================================
481  */
482 void SetActiveDrag(CDragPoint *p) {
483  activeDrag = p;
484 }
485 
486 /*
487  =======================================================================================================================
488  =======================================================================================================================
489  */
491  activeDrag = NULL;
492 }
493 
494 // CXYWnd
496 
497 /*
498  =======================================================================================================================
499  =======================================================================================================================
500  */
503  g_brUndo.next = &g_brUndo;
504  g_nScaleHow = 0;
505  g_bRotateMode = false;
506  g_bClipMode = false;
507  g_bRogueClipMode = false;
508  g_bSwitch = true;
509  g_pMovingClip = NULL;
510  g_pMovingPath = NULL;
513  m_bActive = false;
514 
515  m_bRButtonDown = false;
516  m_nUpdateBits = W_XY;
517  g_bPathMode = false;
518  g_nPathCount = 0;
519  g_nPathLimit = 0;
520  m_nTimerID = -1;
521  m_nButtonstate = 0;
522  XY_Init();
523 }
524 
525 /*
526  =======================================================================================================================
527  =======================================================================================================================
528  */
530  int nSize = g_ptrMenus.GetSize();
531  while (nSize > 0) {
532  CMenu *pMenu = reinterpret_cast < CMenu * > (g_ptrMenus.GetAt(nSize - 1));
533  ASSERT(pMenu);
534  pMenu->DestroyMenu();
535  delete pMenu;
536  nSize--;
537  }
538 
539  g_ptrMenus.RemoveAll();
540  m_mnuDrop.DestroyMenu();
541 }
542 
543 BEGIN_MESSAGE_MAP(CXYWnd, CWnd)
544 //{{AFX_MSG_MAP(CXYWnd)
545  ON_WM_CREATE()
546  ON_WM_LBUTTONDOWN()
547  ON_WM_MBUTTONDOWN()
548  ON_WM_RBUTTONDOWN()
549  ON_WM_LBUTTONUP()
550  ON_WM_MBUTTONUP()
551  ON_WM_RBUTTONUP()
552  ON_WM_MOUSEMOVE()
553  ON_WM_PAINT()
554  ON_WM_KEYDOWN()
555  ON_WM_SIZE()
556  ON_WM_DESTROY()
557  ON_COMMAND(ID_SELECT_MOUSEROTATE, OnSelectMouserotate)
558  ON_WM_TIMER()
559  ON_WM_KEYUP()
560  ON_WM_NCCALCSIZE()
561  ON_WM_KILLFOCUS()
562  ON_WM_SETFOCUS()
563  ON_WM_CLOSE()
564  ON_WM_ERASEBKGND()
565  ON_WM_MOUSEWHEEL()
566  ON_COMMAND(ID_DROP_NEWMODEL, OnDropNewmodel)
567  //}}AFX_MSG_MAP
568  ON_COMMAND_RANGE(ID_ENTITY_START, ID_ENTITY_END, OnEntityCreate)
569 END_MESSAGE_MAP()
570 // CXYWnd message handlers
571 LONG WINAPI XYWndProc(HWND, UINT, WPARAM, LPARAM);
572 
573 /*
574  =======================================================================================================================
575  =======================================================================================================================
576  */
577 BOOL CXYWnd::PreCreateWindow(CREATESTRUCT &cs) {
578  WNDCLASS wc;
579  HINSTANCE hInstance = AfxGetInstanceHandle();
580  if (::GetClassInfo(hInstance, XY_WINDOW_CLASS, &wc) == FALSE) {
581  // Register a new class
582  memset(&wc, 0, sizeof(wc));
583  wc.style = CS_NOCLOSE;
584  wc.lpszClassName = XY_WINDOW_CLASS;
585  wc.hCursor = NULL; // LoadCursor (NULL,IDC_ARROW);
586  wc.lpfnWndProc = ::DefWindowProc;
587  if (AfxRegisterClass(&wc) == FALSE) {
588  Error("CCamWnd RegisterClass: failed");
589  }
590  }
591 
592  cs.lpszClass = XY_WINDOW_CLASS;
593  cs.lpszName = "VIEW";
594  if (cs.style != QE3_CHILDSTYLE) {
595  cs.style = QE3_SPLITTER_STYLE;
596  }
597 
598  return CWnd::PreCreateWindow(cs);
599 }
600 
603 
604 static unsigned s_stipple[32] = {
605  0xaaaaaaaa,
606  0x55555555,
607  0xaaaaaaaa,
608  0x55555555,
609  0xaaaaaaaa,
610  0x55555555,
611  0xaaaaaaaa,
612  0x55555555,
613  0xaaaaaaaa,
614  0x55555555,
615  0xaaaaaaaa,
616  0x55555555,
617  0xaaaaaaaa,
618  0x55555555,
619  0xaaaaaaaa,
620  0x55555555,
621  0xaaaaaaaa,
622  0x55555555,
623  0xaaaaaaaa,
624  0x55555555,
625  0xaaaaaaaa,
626  0x55555555,
627  0xaaaaaaaa,
628  0x55555555,
629  0xaaaaaaaa,
630  0x55555555,
631  0xaaaaaaaa,
632  0x55555555,
633  0xaaaaaaaa,
634  0x55555555,
635  0xaaaaaaaa,
636  0x55555555,
637 };
638 
639 /*
640  =======================================================================================================================
641  WXY_WndProc
642  =======================================================================================================================
643  */
644 LONG WINAPI XYWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
645  switch (uMsg)
646  {
647  case WM_DESTROY:
648  return 0;
649 
650  case WM_NCCALCSIZE: // don't let windows copy pixels
651  DefWindowProc(hWnd, uMsg, wParam, lParam);
652  return WVR_REDRAW;
653 
654  case WM_KILLFOCUS:
655  case WM_SETFOCUS:
656  SendMessage(hWnd, WM_NCACTIVATE, uMsg == WM_SETFOCUS, 0);
657  return 0;
658 
659  case WM_CLOSE:
660  DestroyWindow(hWnd);
661  return 0;
662  }
663 
664  return DefWindowProc(hWnd, uMsg, wParam, lParam);
665 }
666 
667 /*
668  =======================================================================================================================
669  =======================================================================================================================
670  */
671 static void WXY_InitPixelFormat(PIXELFORMATDESCRIPTOR *pPFD) {
672  memset(pPFD, 0, sizeof(*pPFD));
673 
674  pPFD->nSize = sizeof(PIXELFORMATDESCRIPTOR);
675  pPFD->nVersion = 1;
676  pPFD->dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
677  pPFD->iPixelType = PFD_TYPE_RGBA;
678  pPFD->cColorBits = 24;
679  pPFD->cDepthBits = 32;
680  pPFD->iLayerType = PFD_MAIN_PLANE;
681 }
682 
683 /*
684  =======================================================================================================================
685  =======================================================================================================================
686  */
687 void WXY_Print(void) {
688  DOCINFO di;
689 
690  PRINTDLG pd;
691 
692  /* initialize the PRINTDLG struct and execute it */
693  memset(&pd, 0, sizeof(pd));
694  pd.lStructSize = sizeof(pd);
695  pd.hwndOwner = g_pParentWnd->GetXYWnd()->GetSafeHwnd();
696  pd.Flags = PD_RETURNDC;
697  pd.hInstance = 0;
698  if (!PrintDlg(&pd) || !pd.hDC) {
699  g_pParentWnd->MessageBox("Could not PrintDlg()", "QE4 Print Error", MB_OK | MB_ICONERROR);
700  return;
701  }
702 
703  /* StartDoc */
704  memset(&di, 0, sizeof(di));
705  di.cbSize = sizeof(di);
706  di.lpszDocName = "QE4";
707  if (StartDoc(pd.hDC, &di) <= 0) {
708  g_pParentWnd->MessageBox("Could not StartDoc()", "QE4 Print Error", MB_OK | MB_ICONERROR);
709  return;
710  }
711 
712  /* StartPage */
713  if (StartPage(pd.hDC) <= 0) {
714  g_pParentWnd->MessageBox("Could not StartPage()", "QE4 Print Error", MB_OK | MB_ICONERROR);
715  return;
716  } { /* read pixels from the XY window */
717  int bmwidth = 320, bmheight = 320;
718  int pwidth, pheight;
719 
720  RECT r;
721 
722  GetWindowRect(g_pParentWnd->GetXYWnd()->GetSafeHwnd(), &r);
723 
724  bmwidth = r.right - r.left;
725  bmheight = r.bottom - r.top;
726 
727  pwidth = GetDeviceCaps(pd.hDC, PHYSICALWIDTH) - GetDeviceCaps(pd.hDC, PHYSICALOFFSETX);
728  pheight = GetDeviceCaps(pd.hDC, PHYSICALHEIGHT) - GetDeviceCaps(pd.hDC, PHYSICALOFFSETY);
729 
730  StretchBlt(pd.hDC, 0, 0, pwidth, pheight, s_hdcXY, 0, 0, bmwidth, bmheight, SRCCOPY);
731  }
732 
733  /* EndPage and EndDoc */
734  if (EndPage(pd.hDC) <= 0) {
735  g_pParentWnd->MessageBox("QE4 Print Error", "Could not EndPage()", MB_OK | MB_ICONERROR);
736  return;
737  }
738 
739  if (EndDoc(pd.hDC) <= 0) {
740  g_pParentWnd->MessageBox("QE4 Print Error", "Could not EndDoc()", MB_OK | MB_ICONERROR);
741  return;
742  }
743 }
744 
745 /*
746  =======================================================================================================================
747  =======================================================================================================================
748  */
749 int CXYWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) {
750  if (CWnd::OnCreate(lpCreateStruct) == -1) {
751  return -1;
752  }
753 
754  s_hdcXY = ::GetDC(GetSafeHwnd());
755  QEW_SetupPixelFormat(s_hdcXY, false);
756 
757  qglPolygonStipple((unsigned char *)s_stipple);
758  qglLineStipple(3, 0xaaaa);
759  return 0;
760 }
761 
762 /*
763  =======================================================================================================================
764  =======================================================================================================================
765  */
766 float ptSum(idVec3 pt) {
767  return pt[0] + pt[1] + pt[2];
768 }
769 
770 /*
771  =======================================================================================================================
772  =======================================================================================================================
773  */
774 void CXYWnd::DropClipPoint(UINT nFlags, CPoint point) {
775  CRect rctZ;
776  GetClientRect(rctZ);
777  if (g_pMovingClip) {
778  SetCapture();
779  SnapToPoint(point.x, rctZ.Height() - 1 - point.y, *g_pMovingClip);
780  }
781  else {
782  idVec3 *pPt = NULL;
783  if (g_Clip1.Set() == false) {
784  pPt = g_Clip1;
785  g_Clip1.Set(true);
786  g_Clip1.m_ptScreen = point;
787  }
788  else if (g_Clip2.Set() == false) {
789  pPt = g_Clip2;
790  g_Clip2.Set(true);
791  g_Clip2.m_ptScreen = point;
792  }
793  else if (g_Clip3.Set() == false) {
794  pPt = g_Clip3;
795  g_Clip3.Set(true);
796  g_Clip3.m_ptScreen = point;
797  }
798  else {
799  RetainClipMode(true);
800  pPt = g_Clip1;
801  g_Clip1.Set(true);
802  g_Clip1.m_ptScreen = point;
803  }
804 
805  SnapToPoint(point.x, rctZ.Height() - 1 - point.y, *pPt);
806 
807  // Put the off-viewaxis coordinate at the top or bottom of selected brushes
808  if ( GetAsyncKeyState(VK_CONTROL) & 0x8000 ) {
809  if ( selected_brushes.next != &selected_brushes ) {
810  idVec3 smins, smaxs;
811  Select_GetBounds( smins, smaxs );
812 
813  if ( m_nViewType == XY ) {
814  if ( GetAsyncKeyState(VK_SHIFT) & 0x8000 ) {
815  pPt->z = smaxs.z;
816  } else {
817  pPt->z = smins.z;
818  }
819  } else if ( m_nViewType == YZ ) {
820  if ( GetAsyncKeyState(VK_SHIFT) & 0x8000 ) {
821  pPt->x = smaxs.x;
822  } else {
823  pPt->x = smins.x;
824  }
825  } else {
826  if ( GetAsyncKeyState(VK_SHIFT) & 0x8000 ) {
827  pPt->y = smaxs.y;
828  } else {
829  pPt->y = smins.y;
830  }
831  }
832  }
833  }
834  }
835 
836  Sys_UpdateWindows(XY | W_CAMERA_IFON);
837 }
838 
839 /*
840  =======================================================================================================================
841  =======================================================================================================================
842  */
843 void CXYWnd::DropPathPoint(UINT nFlags, CPoint point) {
844  CRect rctZ;
845  GetClientRect(rctZ);
846  if (g_pMovingPath) {
847  SetCapture();
848  SnapToPoint(point.x, rctZ.Height() - 1 - point.y, *g_pMovingPath);
849  }
850  else {
851  g_PathPoints[g_nPathCount].Set(true);
852  g_PathPoints[g_nPathCount].m_ptScreen = point;
853  SnapToPoint(point.x, rctZ.Height() - 1 - point.y, g_PathPoints[g_nPathCount]);
854  g_nPathCount++;
855  if (g_nPathCount == g_nPathLimit) {
856  if (g_pPathFunc) {
857  g_pPathFunc(true, g_nPathCount);
858  }
859 
860  g_nPathCount = 0;
861  g_bPathMode = false;
862  g_pPathFunc = NULL;
863  }
864  }
865 
866  Sys_UpdateWindows(XY | W_CAMERA_IFON);
867 }
868 
869 /*
870  =======================================================================================================================
871  =======================================================================================================================
872  */
873 void CXYWnd::AddPointPoint(UINT nFlags, idVec3 *pVec) {
874  g_PointPoints[g_nPointCount].Set(true);
875 
876  // g_PointPoints[g_nPointCount].m_ptScreen = point;
877  g_PointPoints[g_nPointCount].m_ptClip = *pVec;
878  g_PointPoints[g_nPointCount].SetPointPtr(pVec);
879  g_nPointCount++;
880  Sys_UpdateWindows(XY | W_CAMERA_IFON);
881 }
882 
883 /*
884  =======================================================================================================================
885  =======================================================================================================================
886  */
887 void CXYWnd::OnLButtonDown(UINT nFlags, CPoint point) {
888  g_pParentWnd->SetActiveXY(this);
889  UndoCopy();
890 
891  if (g_pParentWnd->GetNurbMode()) {
892  int i, num = g_pParentWnd->GetNurb()->GetNumValues();
893  idList<idVec2> temp;
894  for (i = 0; i < num; i++) {
895  temp.Append(g_pParentWnd->GetNurb()->GetValue(i));
896  }
897  CRect rctZ;
898  GetClientRect(rctZ);
899  idVec3 v3;
900  SnapToPoint(point.x, rctZ.Height() - 1 - point.y, v3);
901  temp.Append(idVec2(v3.x, v3.y));
902  num++;
903  g_pParentWnd->GetNurb()->Clear();
904  for (i = 0; i < num; i++) {
905  g_pParentWnd->GetNurb()->AddValue((1000 * i)/num, temp[i]);
906  }
907  }
908  if (ClipMode() && !RogueClipMode()) {
909  DropClipPoint(nFlags, point);
910  }
911  else if (PathMode()) {
912  DropPathPoint(nFlags, point);
913  }
914  else {
915  OriginalButtonDown(nFlags, point);
916  }
917 }
918 
919 /*
920  =======================================================================================================================
921  =======================================================================================================================
922  */
923 void CXYWnd::OnMButtonDown(UINT nFlags, CPoint point) {
924  OriginalButtonDown(nFlags, point);
925 }
926 
927 /*
928  =======================================================================================================================
929  =======================================================================================================================
930  */
931 float Betwixt(float f1, float f2) {
932  if (f1 > f2) {
933  return f2 + ((f1 - f2) / 2);
934  }
935  else {
936  return f1 + ((f2 - f1) / 2);
937  }
938 }
939 
940 /*
941  =======================================================================================================================
942  =======================================================================================================================
943  */
944 void CXYWnd::ProduceSplits(brush_t **pFront, brush_t **pBack) {
945  *pFront = NULL;
946  *pBack = NULL;
947  if (ClipMode()) {
948  if (g_Clip1.Set() && g_Clip2.Set()) {
949  face_t face;
950  VectorCopy(g_Clip1.m_ptClip, face.planepts[0]);
951  VectorCopy(g_Clip2.m_ptClip, face.planepts[1]);
952  VectorCopy(g_Clip3.m_ptClip, face.planepts[2]);
953  if (selected_brushes.next && (selected_brushes.next->next == &selected_brushes)) {
954  if (g_Clip3.Set() == false) {
955  if (m_nViewType == XY) {
956  face.planepts[0][2] = selected_brushes.next->mins[2];
957  face.planepts[1][2] = selected_brushes.next->mins[2];
958  face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]);
959  face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);
960  face.planepts[2][2] = selected_brushes.next->maxs[2];
961  }
962  else if (m_nViewType == YZ) {
963  face.planepts[0][0] = selected_brushes.next->mins[0];
964  face.planepts[1][0] = selected_brushes.next->mins[0];
965  face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);
966  face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]);
967  face.planepts[2][0] = selected_brushes.next->maxs[0];
968  }
969  else {
970  face.planepts[0][1] = selected_brushes.next->mins[1];
971  face.planepts[1][1] = selected_brushes.next->mins[1];
972  face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]);
973  face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]);
974  face.planepts[2][1] = selected_brushes.next->maxs[1];
975  }
976  }
977 
978  Brush_SplitBrushByFace(selected_brushes.next, &face, pFront, pBack);
979  }
980  }
981  }
982 }
983 
984 /*
985  =======================================================================================================================
986  =======================================================================================================================
987  */
988 void CleanList(brush_t *pList) {
989  brush_t *pBrush = pList->next;
990  while (pBrush != NULL && pBrush != pList) {
991  brush_t *pNext = pBrush->next;
992  Brush_Free(pBrush);
993  pBrush = pNext;
994  }
995 }
996 
997 /*
998  =======================================================================================================================
999  =======================================================================================================================
1000  */
1002  if (AnyPatchesSelected()) {
1003  Sys_Status("Deslecting patches for clip operation.\n");
1004 
1005  brush_t *next;
1006  for (brush_t * pb = selected_brushes.next; pb != &selected_brushes; pb = next) {
1007  next = pb->next;
1008  if (pb->pPatch) {
1012  }
1013  }
1014  }
1015 
1020 
1021  brush_t *pBrush;
1022  for (pBrush = selected_brushes.next; pBrush != NULL && pBrush != &selected_brushes; pBrush = pBrush->next) {
1023  brush_t *pFront = NULL;
1024  brush_t *pBack = NULL;
1025  if (ClipMode()) {
1026  if (g_Clip1.Set() && g_Clip2.Set()) {
1027  face_t face;
1028  VectorCopy(g_Clip1.m_ptClip, face.planepts[0]);
1029  VectorCopy(g_Clip2.m_ptClip, face.planepts[1]);
1030  VectorCopy(g_Clip3.m_ptClip, face.planepts[2]);
1031  if (g_Clip3.Set() == false) {
1032  if (g_pParentWnd->ActiveXY()->GetViewType() == XY) {
1033  face.planepts[0][2] = pBrush->mins[2];
1034  face.planepts[1][2] = pBrush->mins[2];
1035  face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]);
1036  face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);
1037  face.planepts[2][2] = pBrush->maxs[2];
1038  }
1039  else if (g_pParentWnd->ActiveXY()->GetViewType() == YZ) {
1040  face.planepts[0][0] = pBrush->mins[0];
1041  face.planepts[1][0] = pBrush->mins[0];
1042  face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);
1043  face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]);
1044  face.planepts[2][0] = pBrush->maxs[0];
1045  }
1046  else {
1047  face.planepts[0][1] = pBrush->mins[1];
1048  face.planepts[1][1] = pBrush->mins[1];
1049  face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]);
1050  face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]);
1051  face.planepts[2][1] = pBrush->maxs[1];
1052  }
1053  }
1054 
1055  Brush_SplitBrushByFace(pBrush, &face, &pFront, &pBack);
1056  if (pBack) {
1058  }
1059 
1060  if (pFront) {
1061  Brush_AddToList(pFront, &g_brFrontSplits);
1062  }
1063  }
1064  }
1065  }
1066 }
1067 
1068 /*
1069  =======================================================================================================================
1070  =======================================================================================================================
1071  */
1072 void Brush_CopyList(brush_t *pFrom, brush_t *pTo) {
1073  brush_t *pBrush = pFrom->next;
1074  while (pBrush != NULL && pBrush != pFrom) {
1075  brush_t *pNext = pBrush->next;
1076  Brush_RemoveFromList(pBrush);
1077  Brush_AddToList(pBrush, pTo);
1078  pBrush = pNext;
1079  }
1080 }
1081 
1082 /*
1083  =======================================================================================================================
1084  =======================================================================================================================
1085  */
1086 void CXYWnd::OnRButtonDown(UINT nFlags, CPoint point) {
1087  g_pParentWnd->SetActiveXY(this);
1088  m_ptDown = point;
1089  m_bRButtonDown = true;
1090 
1091  if (g_PrefsDlg.m_nMouseButtons == 3) { // 3 button mouse
1092  if ((GetAsyncKeyState(VK_CONTROL) & 0x8000)) {
1093  if (ClipMode()) { // already there?
1094  DropClipPoint(nFlags, point);
1095  }
1096  else {
1097  SetClipMode(true);
1098  g_bRogueClipMode = true;
1099  DropClipPoint(nFlags, point);
1100  }
1101 
1102  return;
1103  }
1104  }
1105 
1106  OriginalButtonDown(nFlags, point);
1107 }
1108 
1109 /*
1110  =======================================================================================================================
1111  =======================================================================================================================
1112  */
1113 void CXYWnd::OnLButtonUp(UINT nFlags, CPoint point) {
1114 
1115  if (ClipMode()) {
1116  if (g_pMovingClip) {
1117  ReleaseCapture();
1118  g_pMovingClip = NULL;
1119  }
1120  }
1121 
1122  OriginalButtonUp(nFlags, point);
1123 }
1124 
1125 /*
1126  =======================================================================================================================
1127  =======================================================================================================================
1128  */
1129 void CXYWnd::OnMButtonUp(UINT nFlags, CPoint point) {
1130  OriginalButtonUp(nFlags, point);
1131 }
1132 
1133 /*
1134  =======================================================================================================================
1135  =======================================================================================================================
1136  */
1137 void CXYWnd::OnRButtonUp(UINT nFlags, CPoint point) {
1138  m_bRButtonDown = false;
1139  if (point == m_ptDown) { // mouse didn't move
1140  bool bGo = true;
1141  if ((GetAsyncKeyState(VK_MENU) & 0x8000)) {
1142  bGo = false;
1143  }
1144 
1145  if ((GetAsyncKeyState(VK_CONTROL) & 0x8000)) {
1146  bGo = false;
1147  }
1148 
1149  if ((GetAsyncKeyState(VK_SHIFT) & 0x8000)) {
1150  bGo = false;
1151  }
1152 
1153  if (bGo) {
1154  HandleDrop();
1155  }
1156  }
1157 
1158  OriginalButtonUp(nFlags, point);
1159 }
1160 
1161 /*
1162  =======================================================================================================================
1163  =======================================================================================================================
1164  */
1165 void CXYWnd::OriginalButtonDown(UINT nFlags, CPoint point) {
1166  CRect rctZ;
1167  GetClientRect(rctZ);
1168  SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1169  if (g_pParentWnd->GetTopWindow() != this) {
1170  BringWindowToTop();
1171  }
1172 
1173  SetFocus();
1174  SetCapture();
1175  XY_MouseDown(point.x, rctZ.Height() - 1 - point.y, nFlags);
1176  m_nScrollFlags = nFlags;
1177 }
1178 
1179 /*
1180  =======================================================================================================================
1181  =======================================================================================================================
1182  */
1183 void CXYWnd::OriginalButtonUp(UINT nFlags, CPoint point) {
1184  CRect rctZ;
1185  GetClientRect(rctZ);
1186  XY_MouseUp(point.x, rctZ.Height() - 1 - point.y, nFlags);
1187  if (!(nFlags & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON))) {
1188  ReleaseCapture();
1189  }
1190 }
1191 
1193 
1194 /*
1195  =======================================================================================================================
1196  =======================================================================================================================
1197  */
1198 void CXYWnd::OnMouseMove(UINT nFlags, CPoint point) {
1199 
1200  m_ptDown.x = 0;
1201  m_ptDown.y = 0;
1202 
1203  if
1204  (
1206  (point.x < 0 || point.y < 0 || point.x > m_nWidth || point.y > m_nHeight) &&
1207  GetCapture() == this
1208  ) {
1209  float fAdjustment = (g_qeglobals.d_gridsize / 8 * 64) / m_fScale;
1210 
1211  // m_ptDrag = point;
1212  m_ptDragAdj.x = 0;
1213  m_ptDragAdj.y = 0;
1214  if (point.x < 0) {
1215  m_ptDragAdj.x = -fAdjustment;
1216  }
1217  else if (point.x > m_nWidth) {
1218  m_ptDragAdj.x = fAdjustment;
1219  }
1220 
1221  if (point.y < 0) {
1222  m_ptDragAdj.y = -fAdjustment;
1223  }
1224  else if (point.y > m_nHeight) {
1225  m_ptDragAdj.y = fAdjustment;
1226  }
1227 
1228  if (m_nTimerID == -1) {
1229  m_nTimerID = SetTimer(100, 50, NULL);
1230  m_ptDrag = point;
1231  m_ptDragTotal = 0;
1232  }
1233 
1234  return;
1235  }
1236 
1237  // else if (m_nTimerID != -1)
1238  if (m_nTimerID != -1) {
1239  KillTimer(m_nTimerID);
1240  pressx -= m_ptDragTotal.x;
1241  pressy += m_ptDragTotal.y;
1242  m_nTimerID = -1;
1243 
1244  // return;
1245  }
1246 
1247  bool bCrossHair = false;
1248  if (!m_bRButtonDown) {
1249  tdp[0] = tdp[1] = tdp[2] = 0.0;
1250  SnapToPoint(point.x, m_nHeight - 1 - point.y, tdp);
1251 
1252  g_strStatus.Format("x:: %.1f y:: %.1f z:: %.1f", tdp[0], tdp[1], tdp[2]);
1254 
1255  //
1256  // i need to generalize the point code.. having 3 flavors pretty much sucks.. once
1257  // the new curve stuff looks like it is going to stick i will rationalize this
1258  // down to a single interface..
1259  //
1260  if (PointMode()) {
1261  if (g_pMovingPoint && GetCapture() == this) {
1262  bCrossHair = true;
1263  SnapToPoint(point.x, m_nHeight - 1 - point.y, g_pMovingPoint->m_ptClip);
1264  g_pMovingPoint->UpdatePointPtr();
1265  Sys_UpdateWindows(XY | W_CAMERA_IFON);
1266  }
1267  else {
1268  g_pMovingPoint = NULL;
1269 
1270  int nDim1 = (m_nViewType == YZ) ? 1 : 0;
1271  int nDim2 = (m_nViewType == XY) ? 1 : 2;
1272  for (int n = 0; n < g_nPointCount; n++) {
1273  if
1274  (
1275  fDiff(g_PointPoints[n].m_ptClip[nDim1], tdp[nDim1]) < 3 &&
1276  fDiff(g_PointPoints[n].m_ptClip[nDim2], tdp[nDim2]) < 3
1277  ) {
1278  bCrossHair = true;
1279  g_pMovingPoint = &g_PointPoints[n];
1280  }
1281  }
1282  }
1283  }
1284  else if (ClipMode()) {
1285  if (g_pMovingClip && GetCapture() == this) {
1286  bCrossHair = true;
1287  SnapToPoint(point.x, m_nHeight - 1 - point.y, g_pMovingClip->m_ptClip);
1288  Sys_UpdateWindows(XY | W_CAMERA_IFON);
1289  }
1290  else {
1291  g_pMovingClip = NULL;
1292 
1293  int nDim1 = (m_nViewType == YZ) ? 1 : 0;
1294  int nDim2 = (m_nViewType == XY) ? 1 : 2;
1295  if (g_Clip1.Set()) {
1296  if
1297  (
1298  fDiff(g_Clip1.m_ptClip[nDim1], tdp[nDim1]) < 3 &&
1299  fDiff(g_Clip1.m_ptClip[nDim2], tdp[nDim2]) < 3
1300  ) {
1301  bCrossHair = true;
1302  g_pMovingClip = &g_Clip1;
1303  }
1304  }
1305 
1306  if (g_Clip2.Set()) {
1307  if
1308  (
1309  fDiff(g_Clip2.m_ptClip[nDim1], tdp[nDim1]) < 3 &&
1310  fDiff(g_Clip2.m_ptClip[nDim2], tdp[nDim2]) < 3
1311  ) {
1312  bCrossHair = true;
1313  g_pMovingClip = &g_Clip2;
1314  }
1315  }
1316 
1317  if (g_Clip3.Set()) {
1318  if
1319  (
1320  fDiff(g_Clip3.m_ptClip[nDim1], tdp[nDim1]) < 3 &&
1321  fDiff(g_Clip3.m_ptClip[nDim2], tdp[nDim2]) < 3
1322  ) {
1323  bCrossHair = true;
1324  g_pMovingClip = &g_Clip3;
1325  }
1326  }
1327  }
1328 
1329  if (bCrossHair == false) {
1330  XY_MouseMoved(point.x, m_nHeight - 1 - point.y, nFlags);
1331  }
1332  }
1333  else if (PathMode()) {
1334  if (g_pMovingPath && GetCapture() == this) {
1335  bCrossHair = true;
1336  SnapToPoint(point.x, m_nHeight - 1 - point.y, g_pMovingPath->m_ptClip);
1337  Sys_UpdateWindows(XY | W_CAMERA_IFON);
1338  }
1339  else {
1340  g_pMovingPath = NULL;
1341 
1342  int nDim1 = (m_nViewType == YZ) ? 1 : 0;
1343  int nDim2 = (m_nViewType == XY) ? 1 : 2;
1344  for (int n = 0; n < g_nPathCount; n++) {
1345  if
1346  (
1347  fDiff(g_PathPoints[n].m_ptClip[nDim1], tdp[nDim1]) < 3 &&
1348  fDiff(g_PathPoints[n].m_ptClip[nDim2], tdp[nDim2]) < 3
1349  ) {
1350  bCrossHair = true;
1351  g_pMovingPath = &g_PathPoints[n];
1352  }
1353  }
1354  }
1355  }
1356  else {
1357  bCrossHair = XY_MouseMoved(point.x, m_nHeight - 1 - point.y, nFlags);
1358  }
1359  }
1360  else {
1361  bCrossHair = XY_MouseMoved(point.x, m_nHeight - 1 - point.y, nFlags);
1362  }
1363 
1364  if (bCrossHair) {
1365  SetCursor(::LoadCursor(NULL, IDC_CROSS));
1366  }
1367  else {
1368  SetCursor(::LoadCursor(NULL, IDC_ARROW));
1369  }
1370 
1373  {
1375  Sys_UpdateWindows( W_XY );
1376  }
1377 }
1378 
1379 /*
1380  =======================================================================================================================
1381  =======================================================================================================================
1382  */
1383 void CXYWnd::RetainClipMode(bool bMode) {
1384  bool bSave = g_bRogueClipMode;
1385  SetClipMode(bMode);
1386  if (bMode == true) {
1387  g_bRogueClipMode = bSave;
1388  }
1389  else {
1390  g_bRogueClipMode = false;
1391  }
1392 }
1393 
1394 /*
1395  =======================================================================================================================
1396  =======================================================================================================================
1397  */
1398 void CXYWnd::SetClipMode(bool bMode) {
1399  g_bClipMode = bMode;
1400  g_bRogueClipMode = false;
1401  if (bMode) {
1402  g_Clip1.Reset();
1403  g_Clip2.Reset();
1404  g_Clip3.Reset();
1409  }
1410  else {
1411  if (g_pMovingClip) {
1412  ReleaseCapture();
1413  g_pMovingClip = NULL;
1414  }
1415 
1420  Sys_UpdateWindows(XY | W_CAMERA_IFON);
1421  }
1422 }
1423 
1424 /*
1425  =======================================================================================================================
1426  =======================================================================================================================
1427  */
1429  return g_bClipMode;
1430 }
1431 
1432 /*
1433  =======================================================================================================================
1434  =======================================================================================================================
1435  */
1437  return g_bRogueClipMode;
1438 }
1439 
1440 /*
1441  =======================================================================================================================
1442  =======================================================================================================================
1443  */
1445  return g_bPathMode;
1446 }
1447 
1448 /*
1449  =======================================================================================================================
1450  =======================================================================================================================
1451  */
1453  return g_bPointMode;
1454 }
1455 
1456 /*
1457  =======================================================================================================================
1458  =======================================================================================================================
1459  */
1461  g_bPointMode = b;
1462  if (!b) {
1463  g_nPointCount = 0;
1464  }
1465 }
1466 
1467 /*
1468  =======================================================================================================================
1469  =======================================================================================================================
1470  */
1472  CPaintDC dc(this); // device context for painting
1473  bool bPaint = true;
1474  if (!qwglMakeCurrent(dc.m_hDC, win32.hGLRC)) {
1475  common->Printf("ERROR: wglMakeCurrent failed.. Error:%i\n", qglGetError());
1476  common->Printf("Please restart Q3Radiant if the Map view is not working\n");
1477  bPaint = false;
1478  }
1479 
1480  if (bPaint) {
1481  QE_CheckOpenGLForErrors();
1482  XY_Draw();
1483  QE_CheckOpenGLForErrors();
1484 
1485  if (m_nViewType != XY) {
1486  qglPushMatrix();
1487  if (m_nViewType == YZ) {
1488  qglRotatef(-90, 0, 1, 0); // put Z going up
1489  }
1490 
1491  qglRotatef(-90, 1, 0, 0); // put Z going up
1492  }
1493 
1494  if ( g_bCrossHairs ) {
1495  qglColor4f( 0.2f, 0.9f, 0.2f, 0.8f );
1496  qglBegin(GL_LINES);
1497  if (m_nViewType == XY) {
1498  qglVertex2f(-16384, tdp[1]);
1499  qglVertex2f(16384, tdp[1]);
1500  qglVertex2f(tdp[0], -16384);
1501  qglVertex2f(tdp[0], 16384);
1502  }
1503  else if (m_nViewType == YZ) {
1504  qglVertex3f(tdp[0], -16384, tdp[2]);
1505  qglVertex3f(tdp[0], 16384, tdp[2]);
1506  qglVertex3f(tdp[0], tdp[1], -16384);
1507  qglVertex3f(tdp[0], tdp[1], 16384);
1508  }
1509  else {
1510  qglVertex3f(-16384, tdp[1], tdp[2]);
1511  qglVertex3f(16384, tdp[1], tdp[2]);
1512  qglVertex3f(tdp[0], tdp[1], -16384);
1513  qglVertex3f(tdp[0], tdp[1], 16384);
1514  }
1515 
1516  qglEnd();
1517  }
1518 
1519  if (ClipMode()) {
1520  qglPointSize(4);
1521  qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER].ToFloatPtr());
1522  qglBegin(GL_POINTS);
1523  if (g_Clip1.Set()) {
1524  qglVertex3fv(g_Clip1);
1525  }
1526 
1527  if (g_Clip2.Set()) {
1528  qglVertex3fv(g_Clip2);
1529  }
1530 
1531  if (g_Clip3.Set()) {
1532  qglVertex3fv(g_Clip3);
1533  }
1534 
1535  qglEnd();
1536  qglPointSize(1);
1537 
1538  CString strMsg;
1539  if (g_Clip1.Set()) {
1540  qglRasterPos3f(g_Clip1.m_ptClip[0] + 2, g_Clip1.m_ptClip[1] + 2, g_Clip1.m_ptClip[2] + 2);
1541  strMsg = "1";
1542 
1543  // strMsg.Format("1 (%f, %f, %f)", g_Clip1[0], g_Clip1[1], g_Clip1[2]);
1544  qglCallLists(strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg);
1545  }
1546 
1547  if (g_Clip2.Set()) {
1548  qglRasterPos3f(g_Clip2.m_ptClip[0] + 2, g_Clip2.m_ptClip[1] + 2, g_Clip2.m_ptClip[2] + 2);
1549  strMsg = "2";
1550 
1551  // strMsg.Format("2 (%f, %f, %f)", g_Clip2[0], g_Clip2[1], g_Clip2[2]);
1552  qglCallLists(strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg);
1553  }
1554 
1555  if (g_Clip3.Set()) {
1556  qglRasterPos3f(g_Clip3.m_ptClip[0] + 2, g_Clip3.m_ptClip[1] + 2, g_Clip3.m_ptClip[2] + 2);
1557  strMsg = "3";
1558 
1559  // strMsg.Format("3 (%f, %f, %f)", g_Clip3[0], g_Clip3[1], g_Clip3[2]);
1560  qglCallLists(strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg);
1561  }
1562 
1563  if (g_Clip1.Set() && g_Clip2.Set() && selected_brushes.next != &selected_brushes) {
1565 
1566  brush_t *pBrush;
1567  brush_t *pList = ((m_nViewType == XZ) ? !g_bSwitch : g_bSwitch) ? &g_brBackSplits : &g_brFrontSplits;
1568  for (pBrush = pList->next; pBrush != NULL && pBrush != pList; pBrush = pBrush->next) {
1569  qglColor3f(1, 1, 0);
1570 
1571  face_t *face;
1572  int order;
1573  for (face = pBrush->brush_faces, order = 0; face; face = face->next, order++) {
1574  idWinding *w = face->face_winding;
1575  if (!w) {
1576  continue;
1577  }
1578 
1579  // draw the polygon
1580  qglBegin(GL_LINE_LOOP);
1581  for (int i = 0; i < w->GetNumPoints(); i++) {
1582  qglVertex3fv( (*w)[i].ToFloatPtr() );
1583  }
1584 
1585  qglEnd();
1586  }
1587  }
1588  }
1589  }
1590 
1591  if (PathMode()) {
1592  qglPointSize(4);
1593  qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER].ToFloatPtr());
1594  qglBegin(GL_POINTS);
1595 
1596  int n;
1597  for ( n = 0; n < g_nPathCount; n++) {
1598  qglVertex3fv(g_PathPoints[n]);
1599  }
1600 
1601  qglEnd();
1602  qglPointSize(1);
1603 
1604  CString strMsg;
1605  for (n = 0; n < g_nPathCount; n++) {
1607  (
1608  g_PathPoints[n].m_ptClip[0] + 2,
1609  g_PathPoints[n].m_ptClip[1] + 2,
1610  g_PathPoints[n].m_ptClip[2] + 2
1611  );
1612  strMsg.Format("%i", n + 1);
1613  qglCallLists(strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg);
1614  }
1615  }
1616 
1617  if (m_nViewType != XY) {
1618  qglPopMatrix();
1619  }
1620 
1621  qwglSwapBuffers(dc.m_hDC);
1622  TRACE("XY Paint\n");
1623  }
1624 }
1625 
1626 /*
1627  =======================================================================================================================
1628  =======================================================================================================================
1629  */
1630 void CXYWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
1631  g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags);
1632 }
1633 
1634 //
1635 // =======================================================================================================================
1636 // FIXME: the brush_t *pBrush is never used. ( Entity_Create uses selected_brushes )
1637 // =======================================================================================================================
1638 //
1639 void CreateEntityFromName(char *pName, brush_t *pBrush, bool forceFixed, idVec3 min, idVec3 max, idVec3 org) {
1640  eclass_t *pecNew;
1641  entity_t *petNew;
1642  if (stricmp(pName, "worldspawn") == 0) {
1643  g_pParentWnd->MessageBox("Can't create an entity with worldspawn.", "info", 0);
1644  return;
1645  }
1646 
1647  pecNew = Eclass_ForName(pName, false);
1648 
1649  if ((GetAsyncKeyState(VK_SHIFT) & 0x8000)) {
1650  Select_Ungroup();
1651  }
1652 
1653  // create it
1654  petNew = Entity_Create(pecNew, forceFixed);
1655 
1656  if (petNew && idStr::Icmp(pName, "light") == 0 ) {
1657  idVec3 rad = max - min;
1658  rad *= 0.5;
1659  if (rad.x != 0 && rad.y != 0 && rad.z != 0) {
1660  SetKeyValue(petNew, "light_radius", va("%g %g %g", idMath::Fabs(rad.x), idMath::Fabs(rad.y), idMath::Fabs(rad.z)));
1661  DeleteKey(petNew, "light");
1662  }
1663  }
1664 
1665 
1666  if (petNew == NULL) {
1667  if (!((selected_brushes.next == &selected_brushes) || (selected_brushes.next->next != &selected_brushes))) {
1668  brush_t *b = selected_brushes.next;
1669  if (b->owner != world_entity && ((b->owner->eclass->fixedsize && pecNew->fixedsize) || forceFixed)) {
1670  idVec3 mins, maxs;
1671  idVec3 origin;
1672  for (int i = 0; i < 3; i++) {
1673  origin[i] = b->mins[i] - pecNew->mins[i];
1674  }
1675 
1676  VectorAdd(pecNew->mins, origin, mins);
1677  VectorAdd(pecNew->maxs, origin, maxs);
1678 
1679  brush_t *nb = Brush_Create(mins, maxs, &pecNew->texdef);
1680  Entity_LinkBrush(b->owner, nb);
1681  nb->owner->eclass = pecNew;
1682  SetKeyValue(nb->owner, "classname", pName);
1683  Brush_Free(b);
1684  Brush_Build(nb);
1686  Select_Brush(nb);
1687  return;
1688  }
1689  }
1690 
1691  g_pParentWnd->MessageBox("Failed to create entity.", "info", 0);
1692  return;
1693  }
1694 
1695  Select_Deselect();
1696 
1697  //
1698  // entity_t* pEntity = world_entity; if (selected_brushes.next !=
1699  // &selected_brushes) pEntity = selected_brushes.next->owner;
1700  //
1701  Select_Brush(petNew->brushes.onext);
1702  Brush_Build(petNew->brushes.onext);
1703 
1704 }
1705 
1706 /*
1707  =======================================================================================================================
1708  =======================================================================================================================
1709  */
1710 brush_t *CreateEntityBrush(int x, int y, CXYWnd *pWnd) {
1711  idVec3 mins, maxs;
1712  int i;
1713  float temp;
1714  brush_t *n;
1715 
1716  pWnd->SnapToPoint(x, y, mins);
1717  x += 32;
1718  y += 32;
1719  pWnd->SnapToPoint(x, y, maxs);
1720 
1721  int nDim = (pWnd->GetViewType() == XY) ? 2 : (pWnd->GetViewType() == YZ) ? 0 : 1;
1722  mins[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_bottom[nDim] / g_qeglobals.d_gridsize));
1723  maxs[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_top[nDim] / g_qeglobals.d_gridsize));
1724 
1725  if (maxs[nDim] <= mins[nDim]) {
1726  maxs[nDim] = mins[nDim] + g_qeglobals.d_gridsize;
1727  }
1728 
1729  for (i = 0; i < 3; i++) {
1730  if (mins[i] == maxs[i]) {
1731  maxs[i] += 16; // don't create a degenerate brush
1732  }
1733 
1734  if (mins[i] > maxs[i]) {
1735  temp = mins[i];
1736  mins[i] = maxs[i];
1737  maxs[i] = temp;
1738  }
1739  }
1740 
1741  n = Brush_Create(mins, maxs, &g_qeglobals.d_texturewin.texdef);
1742  if (!n) {
1743  return NULL;
1744  }
1745 
1748  Brush_Build(n);
1749  return n;
1750 }
1751 
1752 /*
1753  =======================================================================================================================
1754  =======================================================================================================================
1755  */
1756 void CreateRightClickEntity(CXYWnd *pWnd, int x, int y, char *pName) {
1757  idVec3 min, max, org;
1758  Select_GetBounds(min, max);
1759  Select_GetMid(org);
1760 
1761  CRect rctZ;
1762  pWnd->GetClientRect(rctZ);
1763 
1764  brush_t *pBrush;
1765  if (selected_brushes.next == &selected_brushes) {
1766  pBrush = CreateEntityBrush(x, rctZ.Height() - 1 - y, pWnd);
1767  min.Zero();
1768  max.Zero();
1769  CreateEntityFromName(pName, pBrush, true, min, max, org);
1770  }
1771  else {
1772  pBrush = selected_brushes.next;
1773  CreateEntityFromName(pName, pBrush, false, min, max, org);
1774  }
1775 }
1776 
1777 /*
1778  =======================================================================================================================
1779  =======================================================================================================================
1780  */
1782  idVec3 mins, maxs;
1783  int i;
1784  brush_t *n;
1785 
1786  for (i = 0; i < 3; i++) {
1787  mins[i] = v[i] - 16;
1788  maxs[i] = v[i] + 16;
1789  }
1790 
1791  n = Brush_Create(mins, maxs, &g_qeglobals.d_texturewin.texdef);
1792  if (!n) {
1793  return NULL;
1794  }
1795 
1797 
1798  // Entity_LinkBrush(world_entity, n);
1799  Brush_Build(n);
1800  return n;
1801 }
1802 
1807 
1808 /*
1809  =======================================================================================================================
1810  =======================================================================================================================
1811  */
1812 void _SmartPointDone(bool b, int n) {
1813  g_bSmartWaiting = false;
1814 }
1815 
1816 /*
1817  =======================================================================================================================
1818  =======================================================================================================================
1819  */
1820 void CreateSmartEntity(CXYWnd *pWnd, int x, int y, const char *pName) {
1821  g_nSmartX = x;
1822  g_nSmartY = y;
1823  g_strSmartEntity = pName;
1824  if (g_strSmartEntity.Find("Smart_Train") >= 0) {
1825  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");
1826  g_bPathMode = true;
1827  g_nPathLimit = 0;
1828  g_nPathCount = 0;
1829  g_bSmartGo = true;
1830  }
1831  else if (g_strSmartEntity.Find("Smart_Monster...") >= 0) {
1832  g_bPathMode = true;
1833  g_nPathLimit = 0;
1834  g_nPathCount = 0;
1835  }
1836  else if (g_strSmartEntity.Find("Smart_Rotating") >= 0) {
1837  g_bSmartWaiting = true;
1838  ShowInfoDialog("Left click to specify the rotation origin");
1840  while (g_bSmartWaiting) {
1841  MSG msg;
1842  if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
1843  TranslateMessage(&msg);
1844  DispatchMessage(&msg);
1845  }
1846  }
1847 
1848  HideInfoDialog();
1849 
1850  CPtrArray array;
1851  g_bScreenUpdates = false;
1853  array.Add(reinterpret_cast < void * > (selected_brushes.next));
1854  Select_Deselect();
1855 
1856  brush_t *pBrush = CreateSmartBrush(g_PathPoints[0]);
1857  array.Add(pBrush);
1858  Select_Deselect();
1859  Select_Brush(reinterpret_cast < brush_t * > (array.GetAt(0)));
1860  Select_Brush(reinterpret_cast < brush_t * > (array.GetAt(1)));
1861  ConnectEntities();
1862  g_bScreenUpdates = true;
1863  }
1864 }
1865 
1866 /*
1867  =======================================================================================================================
1868  =======================================================================================================================
1869  */
1871  CPtrArray array;
1872  HideInfoDialog();
1873 
1874  brush_t *pEntities = NULL;
1875  if (g_strSmartEntity.Find("Smart_Train") >= 0) {
1876  g_bScreenUpdates = false;
1878  array.Add(reinterpret_cast < void * > (selected_brushes.next));
1879  int n;
1880  for (n = 0; n < g_nPathCount; n++) {
1881  Select_Deselect();
1883  (
1885  g_PathPoints[n].m_ptScreen.x,
1886  g_PathPoints[n].m_ptScreen.y,
1887  "path_corner"
1888  );
1889  array.Add(reinterpret_cast < void * > (selected_brushes.next));
1890  }
1891 
1892  for (n = 0; n < g_nPathCount; n++) {
1893  Select_Deselect();
1894  Select_Brush(reinterpret_cast < brush_t * > (array.GetAt(n)));
1895  Select_Brush(reinterpret_cast < brush_t * > (array.GetAt(n + 1)));
1896  ConnectEntities();
1897  }
1898 
1899  g_bScreenUpdates = true;
1900  }
1901 
1902  g_nPathCount = 0;
1903  g_bPathMode = false;
1904  Sys_UpdateWindows(W_ALL);
1905 }
1906 
1907 /*
1908  =======================================================================================================================
1909  =======================================================================================================================
1910  */
1912  g_bSmartGo = false;
1913  g_bPathMode = false;
1914  if (g_pPathFunc) {
1915  g_pPathFunc(false, g_nPathCount);
1916  }
1917 
1918  g_nPathCount = 0;
1919  g_pPathFunc = NULL;
1920  Sys_UpdateWindows(W_ALL);
1921 }
1922 
1923 //
1924 // =======================================================================================================================
1925 // gets called for drop down menu messages TIP: it's not always about EntityCreate
1926 // =======================================================================================================================
1927 //
1928 void CXYWnd::OnEntityCreate(unsigned int nID) {
1929  if (m_mnuDrop.GetSafeHmenu()) {
1930  CString strItem;
1931  m_mnuDrop.GetMenuString(nID, strItem, MF_BYCOMMAND);
1932 
1933  if (strItem.CompareNoCase("Add to...") == 0) {
1934  //
1935  // ++timo TODO: fill the menu with current groups? this one is for adding to
1936  // existing groups only
1937  //
1938  common->Printf("TODO: Add to... in CXYWnd::OnEntityCreate\n");
1939  }
1940  else if (strItem.CompareNoCase("Remove") == 0) {
1941  // remove selected brushes from their current group
1942  brush_t *b;
1943  for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
1944  }
1945  }
1946 
1947  // ++timo FIXME: remove when all hooks are in
1948  if
1949  (
1950  strItem.CompareNoCase("Add to...") == 0 ||
1951  strItem.CompareNoCase("Remove") == 0 ||
1952  strItem.CompareNoCase("Name...") == 0 ||
1953  strItem.CompareNoCase("New group...") == 0
1954  ) {
1955  common->Printf("TODO: hook drop down group menu\n");
1956  return;
1957  }
1958 
1959  if (strItem.Find("Smart_") >= 0) {
1960  CreateSmartEntity(this, m_ptDown.x, m_ptDown.y, strItem);
1961  }
1962  else {
1963  CreateRightClickEntity(this, m_ptDown.x, m_ptDown.y, strItem.GetBuffer(0));
1964  }
1965 
1966  Sys_UpdateWindows(W_ALL);
1967 
1968  // OnLButtonDown((MK_LBUTTON | MK_SHIFT), CPoint(m_ptDown.x+2, m_ptDown.y+2));
1969  }
1970 }
1971 
1972 BOOL CXYWnd::OnCmdMsg( UINT nID, int nCode, void *pExtra, AFX_CMDHANDLERINFO *pHandlerInfo )
1973 {
1974  if ( CWnd::OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ) ) {
1975  return TRUE;
1976  }
1977  return AfxGetMainWnd()->OnCmdMsg( nID, nCode, pExtra, pHandlerInfo );
1978 }
1979 
1980 bool MergeMenu(CMenu * pMenuDestination, const CMenu * pMenuAdd, bool bTopLevel /*=false*/)
1981 {
1982  // get the number menu items in the menus
1983  int iMenuAddItemCount = pMenuAdd->GetMenuItemCount();
1984  int iMenuDestItemCount = pMenuDestination->GetMenuItemCount();
1985 
1986  // if there are no items return
1987  if (iMenuAddItemCount == 0)
1988  return true;
1989 
1990  // if we are not at top level and the destination menu is not empty
1991  // -> we append a seperator
1992  if (!bTopLevel && iMenuDestItemCount > 0)
1993  pMenuDestination->AppendMenu(MF_SEPARATOR);
1994 
1995  // iterate through the top level of <pMenuAdd>
1996  for(int iLoop = 0; iLoop < iMenuAddItemCount; iLoop++)
1997  {
1998  // get the menu string from the add menu
1999  CString sMenuAddString;
2000  pMenuAdd->GetMenuString(iLoop, sMenuAddString, MF_BYPOSITION);
2001 
2002  // try to get the submenu of the current menu item
2003  CMenu* pSubMenu = pMenuAdd->GetSubMenu(iLoop);
2004 
2005  // check if we have a sub menu
2006  if (!pSubMenu)
2007  {
2008  // normal menu item
2009  // read the source and append at the destination
2010  UINT nState = pMenuAdd->GetMenuState(iLoop, MF_BYPOSITION);
2011  UINT nItemID = pMenuAdd->GetMenuItemID(iLoop);
2012  if (pMenuDestination->AppendMenu(nState, nItemID, sMenuAddString))
2013  {
2014  // menu item added, don't forget to correct the item count
2015  iMenuDestItemCount++;
2016  }
2017  else
2018  {
2019  TRACE("MergeMenu: AppendMenu failed!\n");
2020  return false;
2021  }
2022  }
2023  else
2024  {
2025  // create or insert a new popup menu item
2026 
2027  // default insert pos is like ap
2028  int iInsertPosDefault = -1;
2029 
2030  // if we are at top level merge into existing popups rather than
2031  // creating new ones
2032  if(bTopLevel)
2033  {
2034  ASSERT(sMenuAddString != "&?" && sMenuAddString !=
2035  "?");
2036  CString csAdd(sMenuAddString);
2037  csAdd.Remove('&'); // for comparison of menu items supress '&'
2038  bool bAdded = false;
2039 
2040  // try to find existing popup
2041  for( int iLoop1 = 0; iLoop1 < iMenuDestItemCount; iLoop1++ )
2042  {
2043  // get the menu string from the destination menu
2044  CString sDest;
2045  pMenuDestination->GetMenuString(iLoop1, sDest, MF_BYPOSITION);
2046  sDest.Remove('&'); // for a better compare (s.a.)
2047 
2048  if (csAdd == sDest)
2049  {
2050  // we got a hit -> merge the two popups
2051  // try to get the submenu of the desired destination menu item
2052  CMenu* pSubMenuDest =
2053  pMenuDestination->GetSubMenu(iLoop1);
2054 
2055  if (pSubMenuDest)
2056  {
2057  // merge the popup recursivly and continue with outer for loop
2058  if (!MergeMenu(pSubMenuDest, pSubMenu, false))
2059  return false;
2060  bAdded = true;
2061  break;
2062  }
2063  }
2064 
2065  // alternativ insert before <Window> or <Help>
2066  if (iInsertPosDefault == -1 && (sDest == "Window"
2067  || sDest == "?" || sDest == "Help"))
2068  {
2069  iInsertPosDefault = iLoop1;
2070  }
2071  } // for (iLoop1)
2072  if (bAdded)
2073  {
2074  // menu added, so go on with loop over pMenuAdd's top level
2075  continue;
2076  }
2077  } // if (bTopLevel)
2078 
2079  // if the top level search did not find a position append the menu
2080  if( iInsertPosDefault == -1 )
2081  {
2082  iInsertPosDefault = pMenuDestination->GetMenuItemCount();
2083  }
2084 
2085  // create a new popup and insert before <Window> or <Help>
2086  CMenu NewPopupMenu;
2087  if (!NewPopupMenu.CreatePopupMenu())
2088  {
2089  TRACE("MergeMenu: CreatePopupMenu failed!\n");
2090  return false;
2091  }
2092 
2093  // merge the new popup recursivly
2094  if (!MergeMenu(&NewPopupMenu, pSubMenu, false))
2095  return false;
2096 
2097  // insert the new popup menu into the destination menu
2098  HMENU hNewMenu = NewPopupMenu.GetSafeHmenu();
2099  if (pMenuDestination->InsertMenu(iInsertPosDefault,
2100  MF_BYPOSITION | MF_POPUP | MF_ENABLED,
2101  (UINT)hNewMenu, sMenuAddString ))
2102  {
2103  // don't forget to correct the item count
2104  iMenuDestItemCount++;
2105  }
2106  else
2107  {
2108  TRACE("MergeMenu: InsertMenu failed!\n");
2109  return false;
2110  }
2111 
2112  // don't destroy the new menu
2113  NewPopupMenu.Detach();
2114  } // if (pSubMenu)
2115  } // for (iLoop)
2116  return true;
2117 }
2118 
2119 
2120 
2121 
2122 /*
2123  =======================================================================================================================
2124  =======================================================================================================================
2125  */
2127  if (g_PrefsDlg.m_bRightClick == false) {
2128  return;
2129  }
2130 
2131  if (!m_mnuDrop.GetSafeHmenu()) { // first time, load it up
2132  m_mnuDrop.CreatePopupMenu();
2133 
2134  CMenu *drop = new CMenu;
2135  drop->LoadMenu( IDR_MENU_DROP );
2136 
2137  MergeMenu( &m_mnuDrop, drop, false );
2138 
2139  int nID = ID_ENTITY_START;
2140 
2141  CMenu *pMakeEntityPop = &m_mnuDrop;
2142 
2143  // Todo: Make this a config option maybe?
2144  const int entitiesOnSubMenu = false;
2145  if ( entitiesOnSubMenu ) {
2146  pMakeEntityPop = new CMenu;
2147  pMakeEntityPop->CreateMenu();
2148  }
2149 
2150  CMenu *pChild = NULL;
2151 
2152  eclass_t *e;
2153  CString strActive;
2154  CString strLast;
2155  CString strName;
2156  for (e = eclass; e; e = e->next) {
2157  strLast = strName;
2158  strName = e->name;
2159 
2160  int n_ = strName.Find("_");
2161  if (n_ > 0) {
2162  CString strLeft = strName.Left(n_);
2163  CString strRight = strName.Right(strName.GetLength() - n_ - 1);
2164  if (strLeft == strActive) { // this is a child
2165  ASSERT(pChild);
2166  pChild->AppendMenu(MF_STRING, nID++, strName);
2167  }
2168  else {
2169  if (pChild) {
2170  pMakeEntityPop->AppendMenu (
2171  MF_POPUP,
2172  reinterpret_cast < unsigned int > (pChild->GetSafeHmenu()),
2173  strActive
2174  );
2175  g_ptrMenus.Add(pChild);
2176 
2177  // pChild->DestroyMenu(); delete pChild;
2178  pChild = NULL;
2179  }
2180 
2181  strActive = strLeft;
2182  pChild = new CMenu;
2183  pChild->CreateMenu();
2184  pChild->AppendMenu(MF_STRING, nID++, strName);
2185  }
2186  }
2187  else {
2188  if (pChild) {
2189  pMakeEntityPop->AppendMenu (
2190  MF_POPUP,
2191  reinterpret_cast < unsigned int > (pChild->GetSafeHmenu()),
2192  strActive
2193  );
2194  g_ptrMenus.Add(pChild);
2195 
2196  // pChild->DestroyMenu(); delete pChild;
2197  pChild = NULL;
2198  }
2199 
2200  strActive = "";
2201  pMakeEntityPop->AppendMenu(MF_STRING, nID++, strName);
2202  }
2203  }
2204  if ( pMakeEntityPop != &m_mnuDrop ) {
2205  m_mnuDrop.AppendMenu (
2206  MF_POPUP,
2207  reinterpret_cast < unsigned int > (pMakeEntityPop->GetSafeHmenu()),
2208  "Make Entity"
2209  );
2210  }
2211  }
2212 
2213  CPoint ptMouse;
2214  GetCursorPos(&ptMouse);
2215  m_mnuDrop.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, ptMouse.x, ptMouse.y, this);
2216 }
2217 
2218 /*
2219  =======================================================================================================================
2220  =======================================================================================================================
2221  */
2223  m_vOrigin[0] = 0;
2224  m_vOrigin[1] = 20;
2225  m_vOrigin[2] = 46;
2226  m_fScale = 1;
2228 }
2229 
2230 /*
2231  =======================================================================================================================
2232  =======================================================================================================================
2233  */
2234 void CXYWnd::SnapToPoint(int x, int y, idVec3 &point) {
2235  if (g_PrefsDlg.m_bNoClamp) {
2236  XY_ToPoint(x, y, point);
2237  }
2238  else {
2239  XY_ToGridPoint(x, y, point);
2240  }
2241 
2242  // -- else -- XY_ToPoint(x, y, point); -- //XY_ToPoint(x, y, point);
2243 }
2244 
2245 /*
2246  =======================================================================================================================
2247  =======================================================================================================================
2248  */
2249 void CXYWnd::XY_ToPoint(int x, int y, idVec3 &point) {
2250  float fx = x;
2251  float fy = y;
2252  float fw = m_nWidth;
2253  float fh = m_nHeight;
2254  if (m_nViewType == XY) {
2255  point[0] = m_vOrigin[0] + (fx - fw / 2) / m_fScale;
2256  point[1] = m_vOrigin[1] + (fy - fh / 2) / m_fScale;
2257 
2258  // point[2] = 0;
2259  }
2260  else if (m_nViewType == YZ) {
2261  //
2262  // //point[0] = 0; point[1] = m_vOrigin[0] + (fx - fw / 2) / m_fScale; point[2] =
2263  // m_vOrigin[1] + (fy - fh / 2 ) / m_fScale;
2264  //
2265  point[1] = m_vOrigin[1] + (fx - fw / 2) / m_fScale;
2266  point[2] = m_vOrigin[2] + (fy - fh / 2) / m_fScale;
2267  }
2268  else {
2269  //
2270  // point[0] = m_vOrigin[0] + (fx - fw / 2) / m_fScale; /point[1] = 0; point[2] =
2271  // m_vOrigin[1] + (fy - fh / 2) / m_fScale;
2272  //
2273  point[0] = m_vOrigin[0] + (fx - fw / 2) / m_fScale;
2274 
2275  // point[1] = 0;
2276  point[2] = m_vOrigin[2] + (fy - fh / 2) / m_fScale;
2277  }
2278 }
2279 
2280 /*
2281  =======================================================================================================================
2282  =======================================================================================================================
2283  */
2284 void CXYWnd::XY_ToGridPoint(int x, int y, idVec3 &point) {
2285  if (m_nViewType == XY) {
2286  point[0] = m_vOrigin[0] + (x - m_nWidth / 2) / m_fScale;
2287  point[1] = m_vOrigin[1] + (y - m_nHeight / 2) / m_fScale;
2288 
2289  // point[2] = 0;
2290  point[0] = floor(point[0] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
2291  point[1] = floor(point[1] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
2292  }
2293  else if (m_nViewType == YZ) {
2294  //
2295  // point[0] = 0; point[1] = m_vOrigin[0] + (x - m_nWidth / 2) / m_fScale; point[2]
2296  // = m_vOrigin[1] + (y - m_nHeight / 2) / m_fScale;
2297  //
2298  point[1] = m_vOrigin[1] + (x - m_nWidth / 2) / m_fScale;
2299  point[2] = m_vOrigin[2] + (y - m_nHeight / 2) / m_fScale;
2300  point[1] = floor(point[1] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
2301  point[2] = floor(point[2] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
2302  }
2303  else {
2304  //
2305  // point[1] = 0; point[0] = m_vOrigin[0] + (x - m_nWidth / 2) / m_fScale; point[2]
2306  // = m_vOrigin[1] + (y - m_nHeight / 2) / m_fScale;
2307  //
2308  point[0] = m_vOrigin[0] + (x - m_nWidth / 2) / m_fScale;
2309  point[2] = m_vOrigin[2] + (y - m_nHeight / 2) / m_fScale;
2310  point[0] = floor(point[0] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
2311  point[2] = floor(point[2] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
2312  }
2313 }
2314 
2315 /*
2316  =======================================================================================================================
2317  =======================================================================================================================
2318  */
2323 
2324 void CXYWnd::XY_MouseDown(int x, int y, int buttons) {
2325  idVec3 point,center;
2326  idVec3 origin, dir, right, up;
2327 
2328  m_nButtonstate = buttons;
2329  m_nPressx = x;
2330  m_nPressy = y;
2332 
2333  point.Zero();
2334 
2335  XY_ToPoint(x, y, point);
2336 
2337  VectorCopy(point, origin);
2338 
2339  dir.Zero();
2340  if (m_nViewType == XY) {
2341  origin[2] = HUGE_DISTANCE;
2342  dir[2] = -1;
2343  right[0] = 1 / m_fScale;
2344  right[1] = 0;
2345  right[2] = 0;
2346  up[0] = 0;
2347  up[1] = 1 / m_fScale;
2348  up[2] = 0;
2349  point[2] = g_pParentWnd->GetCamera()->Camera().origin[2];
2350  }
2351  else if (m_nViewType == YZ) {
2352  origin[0] = HUGE_DISTANCE;
2353  dir[0] = -1;
2354  right[1] = 1 / m_fScale;
2355  right[2] = 0;
2356  right[0] = 0;
2357  up[0] = 0;
2358  up[2] = 1 / m_fScale;
2359  up[1] = 0;
2360  point[0] = g_pParentWnd->GetCamera()->Camera().origin[0];
2361  }
2362  else {
2363  origin[1] = HUGE_DISTANCE;
2364  dir[1] = -1;
2365  right[0] = 1 / m_fScale;
2366  right[2] = 0;
2367  right[1] = 0;
2368  up[0] = 0;
2369  up[2] = 1 / m_fScale;
2370  up[1] = 0;
2371  point[1] = g_pParentWnd->GetCamera()->Camera().origin[1];
2372  }
2373 
2374  dragOrigin = m_vOrigin;
2375  dragDir = dir;
2376  dragX = right;
2377  dragY = up;
2378 
2380 
2381  GetCursorPos(&m_ptCursor);
2382 
2383  // Sys_GetCursorPos (&m_ptCursor.x, &m_ptCursor.y);
2384  if (buttons == MK_LBUTTON && activeDrag) {
2385  activeDragging = true;
2386  }
2387  else {
2388  activeDragging = false;
2389  }
2390 
2391  // lbutton = manipulate selection shift-LBUTTON = select
2392  if
2393  (
2394  (buttons == MK_LBUTTON) ||
2395  (buttons == (MK_LBUTTON | MK_SHIFT)) ||
2396  (buttons == (MK_LBUTTON | MK_CONTROL)) ||
2397  (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT))
2398  ) {
2399  if (g_qeglobals.d_select_mode == sel_addpoint) {
2400  XY_ToGridPoint(x, y, point);
2401  if (g_qeglobals.selectObject) {
2402  g_qeglobals.selectObject->addPoint(point);
2403  }
2404 
2405  return;
2406  }
2407 
2408  Patch_SetView((m_nViewType == XY) ? W_XY : (m_nViewType == YZ) ? W_YZ : W_XZ);
2409  Drag_Begin(x, y, buttons, right, up, origin, dir);
2410  return;
2411  }
2412 
2413  int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON;
2414 
2415  // control mbutton = move camera
2416  if (m_nButtonstate == (MK_CONTROL | nMouseButton)) {
2418  Sys_UpdateWindows(W_CAMERA | W_XY_OVERLAY);
2419  }
2420 
2421  // mbutton = angle camera
2422  if
2423  (
2424  (g_PrefsDlg.m_nMouseButtons == 3 && m_nButtonstate == MK_MBUTTON) ||
2425  (g_PrefsDlg.m_nMouseButtons == 2 && m_nButtonstate == (MK_SHIFT | MK_CONTROL | MK_RBUTTON))
2426  ) {
2427  VectorSubtract(point, g_pParentWnd->GetCamera()->Camera().origin, point);
2428 
2429  int n1 = (m_nViewType == XY) ? 1 : 2;
2430  int n2 = (m_nViewType == YZ) ? 1 : 0;
2431  int nAngle = (m_nViewType == XY) ? YAW : PITCH;
2432  if (point[n1] || point[n2]) {
2433  g_pParentWnd->GetCamera()->Camera().angles[nAngle] = RAD2DEG( atan2(point[n1], point[n2]) );
2434  Sys_UpdateWindows(W_CAMERA_IFON | W_XY_OVERLAY);
2435  }
2436  }
2437 
2438  // shift mbutton = move z checker
2439  if (m_nButtonstate == (MK_SHIFT | nMouseButton)) {
2440  if (RotateMode() || g_bPatchBendMode) {
2441  SnapToPoint(x, y, point);
2442  VectorCopyXY(point, g_vRotateOrigin);
2443  if (g_bPatchBendMode) {
2444  VectorCopy(point, g_vBendOrigin);
2445  }
2446 
2447  Sys_UpdateWindows(W_XY);
2448  return;
2449  }
2450  else {
2451  SnapToPoint(x, y, point);
2452  if (m_nViewType == XY) {
2453  z.origin[0] = point[0];
2454  z.origin[1] = point[1];
2455  }
2456  else if (m_nViewType == YZ) {
2457  z.origin[0] = point[1];
2458  z.origin[1] = point[2];
2459  }
2460  else {
2461  z.origin[0] = point[0];
2462  z.origin[1] = point[2];
2463  }
2464 
2465  Sys_UpdateWindows(W_XY_OVERLAY | W_Z);
2466  return;
2467  }
2468  }
2469 }
2470 
2471 /*
2472  =======================================================================================================================
2473  =======================================================================================================================
2474  */
2475 void CXYWnd::XY_MouseUp(int x, int y, int buttons) {
2476  activeDragging = false;
2477  Drag_MouseUp(buttons);
2478  if (!m_bPress_selection) {
2479  Sys_UpdateWindows(W_ALL);
2480  }
2481 
2482  m_nButtonstate = 0;
2483  while (::ShowCursor(TRUE) < 0)
2484  ;
2485 }
2486 
2487 /*
2488  =======================================================================================================================
2489  =======================================================================================================================
2490  */
2491 bool CXYWnd::DragDelta(int x, int y, idVec3 &move) {
2492  idVec3 xvec, yvec, delta;
2493  int i;
2494 
2495  xvec[0] = 1 / m_fScale;
2496  xvec[1] = xvec[2] = 0;
2497  yvec[1] = 1 / m_fScale;
2498  yvec[0] = yvec[2] = 0;
2499 
2500  for (i = 0; i < 3; i++) {
2501  delta[i] = xvec[i] * (x - m_nPressx) + yvec[i] * (y - m_nPressy);
2502  if (!g_PrefsDlg.m_bNoClamp) {
2503  delta[i] = floor(delta[i] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
2504  }
2505  }
2506 
2507  VectorSubtract(delta, m_vPressdelta, move);
2508  VectorCopy(delta, m_vPressdelta);
2509 
2510 
2511  if (move[0] || move[1] || move[2]) {
2512  return true;
2513  }
2514 
2515  return false;
2516 }
2517 
2518 /*
2519  =======================================================================================================================
2520  NewBrushDrag
2521  =======================================================================================================================
2522  */
2523 void CXYWnd::NewBrushDrag(int x, int y) {
2524  idVec3 mins, maxs, junk;
2525  int i;
2526  float temp;
2527  brush_t *n;
2528 
2529  if ( radiant_entityMode.GetBool() ) {
2530  return;
2531  }
2532 
2533  if (!DragDelta(x, y, junk)) {
2534  return;
2535  }
2536 
2537  // delete the current selection
2538  if (selected_brushes.next != &selected_brushes) {
2540  }
2541 
2543 
2544  int nDim = (m_nViewType == XY) ? 2 : (m_nViewType == YZ) ? 0 : 1;
2545 
2546  mins[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_bottom[nDim] / g_qeglobals.d_gridsize));
2547  SnapToPoint(x, y, maxs);
2548  maxs[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_top[nDim] / g_qeglobals.d_gridsize));
2549  if (maxs[nDim] <= mins[nDim]) {
2550  maxs[nDim] = mins[nDim] + g_qeglobals.d_gridsize;
2551  }
2552 
2553  for (i = 0; i < 3; i++) {
2554  if (mins[i] == maxs[i]) {
2555  return; // don't create a degenerate brush
2556  }
2557 
2558  if (mins[i] > maxs[i]) {
2559  temp = mins[i];
2560  mins[i] = maxs[i];
2561  maxs[i] = temp;
2562  }
2563  }
2564 
2565  n = Brush_Create(mins, maxs, &g_qeglobals.d_texturewin.texdef);
2566  if (!n) {
2567  return;
2568  }
2569 
2570  idVec3 vSize;
2571  VectorSubtract(maxs, mins, vSize);
2572  g_strStatus.Format("Size X:: %.1f Y:: %.1f Z:: %.1f", vSize[0], vSize[1], vSize[2]);
2574 
2576 
2578 
2579  Brush_Build(n);
2580 
2581  // Sys_UpdateWindows (W_ALL);
2582  Sys_UpdateWindows(W_XY | W_CAMERA);
2583 }
2584 
2585 /*
2586  =======================================================================================================================
2587  XY_MouseMoved
2588  =======================================================================================================================
2589  */
2590 bool CXYWnd::XY_MouseMoved(int x, int y, int buttons) {
2591  idVec3 point;
2592 
2593  if (!m_nButtonstate) {
2594  if (g_bCrossHairs) {
2595  ::ShowCursor(FALSE);
2596  Sys_UpdateWindows(W_XY | W_XY_OVERLAY);
2597  ::ShowCursor(TRUE);
2598  }
2599 
2600  return false;
2601  }
2602 
2603  //
2604  // lbutton without selection = drag new brush if (m_nButtonstate == MK_LBUTTON &&
2605  // !m_bPress_selection && g_qeglobals.d_select_mode != sel_curvepoint &&
2606  // g_qeglobals.d_select_mode != sel_splineedit)
2607  //
2608  if (m_nButtonstate == MK_LBUTTON && !m_bPress_selection && g_qeglobals.d_select_mode == sel_brush) {
2609  NewBrushDrag(x, y);
2610  return false;
2611  }
2612 
2613  // lbutton (possibly with control and or shift) with selection = drag selection
2614  if (m_nButtonstate & MK_LBUTTON) {
2615  Drag_MouseMoved(x, y, buttons);
2616  Sys_UpdateWindows(W_XY_OVERLAY | W_CAMERA_IFON | W_Z);
2617  return false;
2618  }
2619 
2620  int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON;
2621 
2622  // control mbutton = move camera
2623  if (m_nButtonstate == (MK_CONTROL | nMouseButton)) {
2624  SnapToPoint(x, y, point);
2626  Sys_UpdateWindows(W_XY_OVERLAY | W_CAMERA);
2627  return false;
2628  }
2629 
2630  // shift mbutton = move z checker
2631  if (m_nButtonstate == (MK_SHIFT | nMouseButton)) {
2632  if (RotateMode() || g_bPatchBendMode) {
2633  SnapToPoint(x, y, point);
2634  VectorCopyXY(point, g_vRotateOrigin);
2635  if (g_bPatchBendMode) {
2636  VectorCopy(point, g_vBendOrigin);
2637  }
2638 
2639  Sys_UpdateWindows(W_XY);
2640  return false;
2641  }
2642  else {
2643  SnapToPoint(x, y, point);
2644  if (m_nViewType == XY) {
2645  z.origin[0] = point[0];
2646  z.origin[1] = point[1];
2647  }
2648  else if (m_nViewType == YZ) {
2649  z.origin[0] = point[1];
2650  z.origin[1] = point[2];
2651  }
2652  else {
2653  z.origin[0] = point[0];
2654  z.origin[1] = point[2];
2655  }
2656  }
2657 
2658  Sys_UpdateWindows(W_XY_OVERLAY | W_Z);
2659  return false;
2660  }
2661 
2662  // mbutton = angle camera
2663  if
2664  (
2665  (g_PrefsDlg.m_nMouseButtons == 3 && m_nButtonstate == MK_MBUTTON) ||
2666  (g_PrefsDlg.m_nMouseButtons == 2 && m_nButtonstate == (MK_SHIFT | MK_CONTROL | MK_RBUTTON))
2667  ) {
2668  SnapToPoint(x, y, point);
2669  VectorSubtract(point, g_pParentWnd->GetCamera()->Camera().origin, point);
2670 
2671  int n1 = (m_nViewType == XY) ? 1 : 2;
2672  int n2 = (m_nViewType == YZ) ? 1 : 0;
2673  int nAngle = (m_nViewType == XY) ? YAW : PITCH;
2674  if (point[n1] || point[n2]) {
2675  g_pParentWnd->GetCamera()->Camera().angles[nAngle] = RAD2DEG( atan2(point[n1], point[n2]) );
2676  Sys_UpdateWindows(W_CAMERA_IFON | W_XY_OVERLAY);
2677  }
2678 
2679  return false;
2680  }
2681 
2682  // rbutton = drag xy origin
2683  if (m_nButtonstate == MK_RBUTTON) {
2684  Sys_GetCursorPos(&x, &y);
2685 
2686  if (x != m_ptCursor.x || y != m_ptCursor.y) {
2687  if ((GetAsyncKeyState(VK_MENU) & 0x8000)) {
2688  int *px = &x;
2689  long *px2 = &m_ptCursor.x;
2690 
2691  if (fDiff(y, m_ptCursor.y) > fDiff(x, m_ptCursor.x)) {
2692  px = &y;
2693  px2 = &m_ptCursor.y;
2694  }
2695 
2696  if (*px > *px2) {
2697  // zoom in
2698  SetScale( Scale() * 1.1f );
2699  if ( Scale() < 0.1f ) {
2700  SetScale( 0.1f );
2701  }
2702  }
2703  else if (*px < *px2) {
2704  // zoom out
2705  SetScale( Scale() * 0.9f );
2706  if ( Scale() > 16.0f ) {
2707  SetScale( 16.0f );
2708  }
2709  }
2710 
2711  *px2 = *px;
2712  Sys_UpdateWindows(W_XY | W_XY_OVERLAY);
2713  }
2714  else {
2715  int nDim1 = (m_nViewType == YZ) ? 1 : 0;
2716  int nDim2 = (m_nViewType == XY) ? 1 : 2;
2717  m_vOrigin[nDim1] -= (x - m_ptCursor.x) / m_fScale;
2718  m_vOrigin[nDim2] += (y - m_ptCursor.y) / m_fScale;
2719  SetCursorPos(m_ptCursor.x, m_ptCursor.y);
2720  ::ShowCursor(FALSE);
2721 
2722  // XY_Draw(); RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
2723  Sys_UpdateWindows(W_XY | W_XY_OVERLAY);
2724 
2725  // ::ShowCursor(TRUE);
2726  }
2727  }
2728 
2729  return false;
2730  }
2731 
2732  return false;
2733 }
2734 
2735 /*
2736  =======================================================================================================================
2737  DRAWING £ XY_DrawGrid ======================================================================================================================= */ void CXYWnd::XY_DrawGrid() { float x, y, xb, xe, yb, ye; int w, h; char text[32]; int startPos = max ( 64 , g_qeglobals.d_gridsize ); w = m_nWidth / 2 / m_fScale; h = m_nHeight / 2 / m_fScale; int nDim1 = (m_nViewType == YZ) ? 1 : 0; int nDim2 = (m_nViewType == XY) ? 1 : 2; // int nDim1 = 0; int nDim2 = 1; xb = m_vOrigin[nDim1] - w; if (xb < region_mins[nDim1]) { xb = region_mins[nDim1]; } xb = startPos * floor(xb / startPos); xe = m_vOrigin[nDim1] + w; if (xe > region_maxs[nDim1]) { xe = region_maxs[nDim1]; } xe = startPos * ceil(xe / startPos); yb = m_vOrigin[nDim2] - h; if (yb < region_mins[nDim2]) { yb = region_mins[nDim2]; } yb = startPos * floor(yb / startPos); ye = m_vOrigin[nDim2] + h; if (ye > region_maxs[nDim2]) { ye = region_maxs[nDim2]; } ye = startPos * ceil(ye / startPos); // draw major blocks qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR].ToFloatPtr()); int stepSize = 64 * 0.1 / m_fScale; if (stepSize < 64) { stepSize = max ( 64 , g_qeglobals.d_gridsize ); } else { int i; for (i = 1; i < stepSize; i <<= 1) { } stepSize = i; } if (g_qeglobals.d_showgrid) { qglBegin(GL_LINES); for (x = xb; x <= xe; x += stepSize) { qglVertex2f(x, yb); qglVertex2f(x, ye); } for (y = yb; y <= ye; y += stepSize) { qglVertex2f(xb, y); qglVertex2f(xe, y); } qglEnd(); } // draw minor blocks if ( m_fScale > .1 && g_qeglobals.d_showgrid && g_qeglobals.d_gridsize * m_fScale >= 4 && !g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR].Compare( g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK] ) ) { qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR].ToFloatPtr()); qglBegin(GL_LINES); for (x = xb; x < xe; x += g_qeglobals.d_gridsize) { if (!((int)x & (startPos - 1))) { continue; } qglVertex2f(x, yb); qglVertex2f(x, ye); } for (y = yb; y < ye; y += g_qeglobals.d_gridsize) { if (!((int)y & (startPos - 1))) { continue; } qglVertex2f(xb, y); qglVertex2f(xe, y); } qglEnd(); } // draw ZClip boundaries (if applicable)... // if (m_nViewType == XZ || m_nViewType == YZ) { if (g_pParentWnd->GetZWnd()->m_pZClip) // should always be the case at this point I think, but this is safer { if (g_pParentWnd->GetZWnd()->m_pZClip->IsEnabled()) { qglColor3f(ZCLIP_COLOUR); qglLineWidth(2); qglBegin (GL_LINES); qglVertex2f (xb, g_pParentWnd->GetZWnd()->m_pZClip->GetTop()); qglVertex2f (xe, g_pParentWnd->GetZWnd()->m_pZClip->GetTop()); qglVertex2f (xb, g_pParentWnd->GetZWnd()->m_pZClip->GetBottom()); qglVertex2f (xe, g_pParentWnd->GetZWnd()->m_pZClip->GetBottom()); qglEnd (); qglLineWidth(1); } } } // draw coordinate text if needed if (g_qeglobals.d_savedinfo.show_coordinates) { // glColor4f(0, 0, 0, 0); qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT].ToFloatPtr()); float lastRaster = xb; for (x = xb; x < xe; x += stepSize) { qglRasterPos2f(x, m_vOrigin[nDim2] + h - 10 / m_fScale); sprintf(text, "%i", (int)x); qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text); } for (y = yb; y < ye; y += stepSize) { qglRasterPos2f(m_vOrigin[nDim1] - w + 1, y); sprintf(text, "%i", (int)y); qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text); } if (Active()) { qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME].ToFloatPtr()); } qglRasterPos2f(m_vOrigin[nDim1] - w + 35 / m_fScale, m_vOrigin[nDim2] + h - 20 / m_fScale); char cView[20]; if (m_nViewType == XY) { strcpy(cView, "XY Top"); } else if (m_nViewType == XZ) { strcpy(cView, "XZ Front"); } else { strcpy(cView, "YZ Side"); } qglCallLists(strlen(cView), GL_UNSIGNED_BYTE, cView); } /* * if (true) { qglColor3f(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR]); * qglBegin (GL_LINES); qglVertex2f (x, yb); qglVertex2f (x, ye); qglEnd(); } */ } /* ======================================================================================================================= XY_DrawBlockGrid ======================================================================================================================= */ void CXYWnd::XY_DrawBlockGrid() { float x, y, xb, xe, yb, ye; int w, h; char text[32]; w = m_nWidth / 2 / m_fScale; h = m_nHeight / 2 / m_fScale; int nDim1 = (m_nViewType == YZ) ? 1 : 0; int nDim2 = (m_nViewType == XY) ? 1 : 2; xb = m_vOrigin[nDim1] - w; if (xb < region_mins[nDim1]) { xb = region_mins[nDim1]; } xb = 1024 * floor(xb / 1024); xe = m_vOrigin[nDim1] + w; if (xe > region_maxs[nDim1]) { xe = region_maxs[nDim1]; } xe = 1024 * ceil(xe / 1024); yb = m_vOrigin[nDim2] - h; if (yb < region_mins[nDim2]) { yb = region_mins[nDim2]; } yb = 1024 * floor(yb / 1024); ye = m_vOrigin[nDim2] + h; if (ye > region_maxs[nDim2]) { ye = region_maxs[nDim2]; } ye = 1024 * ceil(ye / 1024); // draw major blocks qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK].ToFloatPtr()); qglLineWidth(0.5); qglBegin(GL_LINES); for (x = xb; x <= xe; x += 1024) { qglVertex2f(x, yb); qglVertex2f(x, ye); } for (y = yb; y <= ye; y += 1024) { qglVertex2f(xb, y); qglVertex2f(xe, y); } qglEnd(); qglLineWidth(0.25); // draw coordinate text if needed for (x = xb; x < xe; x += 1024) { for (y = yb; y < ye; y += 1024) { qglRasterPos2f(x + 512, y + 512); sprintf(text, "%i,%i", (int)floor(x / 1024), (int)floor(y / 1024)); qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text); } } qglColor4f(0, 0, 0, 0); } void GLColoredBoxWithLabel(float x, float y, float size, idVec4 color, const char *text, idVec4 textColor, float xofs, float yofs, float lineSize) { globalImages->BindNull(); qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); qglDisable(GL_CULL_FACE); qglDisable(GL_BLEND); qglColor4f(color[0], color[1], color[2], color[3]); qglBegin(GL_QUADS); qglVertex3f(x - size, y - size, 0); qglVertex3f(x + size, y - size, 0); qglVertex3f(x + size, y + size, 0); qglVertex3f(x - size, y + size, 0); qglEnd(); qglColor4f(textColor[0], textColor[1], textColor[2], textColor[3]); qglLineWidth(lineSize); qglRasterPos2f(x + xofs, y + yofs); qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text); } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::DrawRotateIcon() { float x, y; if (m_nViewType == XY) { x = g_vRotateOrigin[0]; y = g_vRotateOrigin[1]; } else if (m_nViewType == YZ) { x = g_vRotateOrigin[1]; y = g_vRotateOrigin[2]; } else { x = g_vRotateOrigin[0]; y = g_vRotateOrigin[2]; } qglEnable(GL_BLEND); globalImages->BindNull(); qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); qglDisable(GL_CULL_FACE); qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglColor4f( 0.8f, 0.1f, 0.9f, 0.25f ); qglBegin(GL_QUADS); qglVertex3f(x - 4, y - 4, 0); qglVertex3f(x + 4, y - 4, 0); qglVertex3f(x + 4, y + 4, 0); qglVertex3f(x - 4, y + 4, 0); qglEnd(); qglDisable(GL_BLEND); qglColor4f( 1.0f, 0.2f, 1.0f, 1.0f ); qglBegin(GL_POINTS); qglVertex3f(x, y, 0); qglEnd(); int w = m_nWidth / 2 / m_fScale; int h = m_nHeight / 2 / m_fScale; int nDim1 = (m_nViewType == YZ) ? 1 : 0; int nDim2 = (m_nViewType == XY) ? 1 : 2; x = m_vOrigin[nDim1] - w + 35 / m_fScale; y = m_vOrigin[nDim2] + h - 40 / m_fScale; const char *p = "Rotate Z Axis"; if (g_qeglobals.rotateAxis == 1) { p = "Rotate Y Axis"; } else if (g_qeglobals.rotateAxis == 0) { p = "Rotate X Axis"; } idStr str = p; if (g_qeglobals.flatRotation) { str += g_qeglobals.flatRotation == 2 ? " Flat [center] " : " Flat [ rot origin ] "; } qglRasterPos2f(x, y); qglCallLists(str.Length(), GL_UNSIGNED_BYTE, str.c_str()); } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::DrawCameraIcon() { float x, y, a; if (m_nViewType == XY) { x = g_pParentWnd->GetCamera()->Camera().origin[0]; y = g_pParentWnd->GetCamera()->Camera().origin[1]; a = g_pParentWnd->GetCamera()->Camera().angles[YAW] * idMath::M_DEG2RAD; } else if (m_nViewType == YZ) { x = g_pParentWnd->GetCamera()->Camera().origin[1]; y = g_pParentWnd->GetCamera()->Camera().origin[2]; a = g_pParentWnd->GetCamera()->Camera().angles[PITCH] * idMath::M_DEG2RAD; } else { x = g_pParentWnd->GetCamera()->Camera().origin[0]; y = g_pParentWnd->GetCamera()->Camera().origin[2]; a = g_pParentWnd->GetCamera()->Camera().angles[PITCH] * idMath::M_DEG2RAD; } float scale = 1.0/m_fScale; //jhefty - keep the camera icon proportionally the same size qglColor3f(0.0, 0.0, 1.0); qglBegin(GL_LINE_STRIP); qglVertex3f(x - 16*scale, y, 0); qglVertex3f(x, y + 8*scale, 0); qglVertex3f(x + 16*scale, y, 0); qglVertex3f(x, y - 8*scale, 0); qglVertex3f(x - 16*scale, y, 0); qglVertex3f(x + 16*scale, y, 0); qglEnd(); qglBegin(GL_LINE_STRIP); qglVertex3f(x + (48 * cos( a + idMath::PI * 0.25f )*scale), y + (48 * sin( a + idMath::PI * 0.25f )*scale), 0); qglVertex3f(x, y, 0); qglVertex3f(x + (48 * cos( a - idMath::PI * 0.25f )*scale), y + (48 * sin( a - idMath::PI * 0.25f )*scale), 0); qglEnd(); #if 0 char text[128]; qglRasterPos2f(x + 64, y + 64); sprintf(text, "%f", g_pParentWnd->GetCamera()->Camera().angles[YAW]); qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text); #endif } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::DrawZIcon(void) { if (m_nViewType == XY) { float x = z.origin[0]; float y = z.origin[1]; qglEnable(GL_BLEND); globalImages->BindNull(); qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); qglDisable(GL_CULL_FACE); qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglColor4f(0.0, 0.0, 1.0, 0.25); qglBegin(GL_QUADS); qglVertex3f(x - 8, y - 8, 0); qglVertex3f(x + 8, y - 8, 0); qglVertex3f(x + 8, y + 8, 0); qglVertex3f(x - 8, y + 8, 0); qglEnd(); qglDisable(GL_BLEND); qglColor4f(0.0, 0.0, 1.0, 1); qglBegin(GL_LINE_LOOP); qglVertex3f(x - 8, y - 8, 0); qglVertex3f(x + 8, y - 8, 0); qglVertex3f(x + 8, y + 8, 0); qglVertex3f(x - 8, y + 8, 0); qglEnd(); qglBegin(GL_LINE_STRIP); qglVertex3f(x - 4, y + 4, 0); qglVertex3f(x + 4, y + 4, 0); qglVertex3f(x - 4, y - 4, 0); qglVertex3f(x + 4, y - 4, 0); qglEnd(); } } /* ======================================================================================================================= FilterBrush ======================================================================================================================= */ bool FilterBrush(brush_t *pb) { if (!pb->owner) { return false; // during construction } if (pb->hiddenBrush) { return true; } if ( pb->forceVisibile ) { return false; } if (g_pParentWnd->GetZWnd()->m_pZClip) // ZClip class up and running? (and hence Z window built) { if (g_pParentWnd->GetZWnd()->m_pZClip->IsEnabled()) { // ZClipping active... // if (pb->mins[2] > g_pParentWnd->GetZWnd()->m_pZClip->GetTop() // brush bottom edge is above clip top || pb->maxs[2] < g_pParentWnd->GetZWnd()->m_pZClip->GetBottom()// brush top edge is below clip bottom ) { return TRUE; } } } if (g_qeglobals.d_savedinfo.exclude & (EXCLUDE_CAULK | EXCLUDE_VISPORTALS)) { // // filter out the brush only if all faces are caulk if not don't hide the whole // brush, proceed on a per-face basis (Cam_Draw) ++timo TODO: set this as a // preference .. show caulk: hide any brush with caulk // don't draw caulk faces // face_t *f; f = pb->brush_faces; while (f) { if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK) { if (!strstr(f->texdef.name, "caulk")) { break; } } else { if (strstr(f->texdef.name, "visportal")) { return true; } } f = f->next; } if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK) { if (!f) { return true; } } // ++timo FIXME: .. same deal here? if (strstr(pb->brush_faces->texdef.name, "donotenter")) { return true; } } if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_HINT) { if (strstr(pb->brush_faces->texdef.name, "hint")) { return true; } } if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP) { if (strstr(pb->brush_faces->texdef.name, "clip")) { return true; } } if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_TRIGGERS) { if (strstr(pb->brush_faces->texdef.name, "trig")) { return true; } } if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_NODRAW) { if (strstr(pb->brush_faces->texdef.name, "nodraw")) { return true; } } if (strstr(pb->brush_faces->texdef.name, "skip")) { return true; } if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_DYNAMICS) { if (pb->modelHandle > 0) { idRenderModel *model = pb->modelHandle; if ( dynamic_cast<idRenderModelLiquid*>(model) ) { return true; } } } if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CURVES) { if (pb->pPatch) { return true; } } if (pb->owner == world_entity) { if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD) { return true; } return false; } else { if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT ) { return ( idStr::Cmpn( pb->owner->eclass->name, "func_static", 10 ) != 0 ); } } if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS && pb->owner->eclass->nShowFlags & ECLASS_LIGHT ) { return true; } if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_COMBATNODES && pb->owner->eclass->nShowFlags & ECLASS_COMBATNODE ) { return true; } if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS && pb->owner->eclass->nShowFlags & ECLASS_PATH) { return true; } if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_MODELS && ( pb->owner->eclass->entityModel != NULL || pb->modelHandle > 0 ) ) { return true; } return false; } /* ======================================================================================================================= PATH LINES £ DrawPathLines Draws connections between entities. Needs to consider all entities, not just ones on screen, because the lines can be visible when neither end is. Called for both camera view and xy view. ======================================================================================================================= */ void DrawPathLines(void) { int i, k; idVec3 mid, mid1; entity_t *se, *te; brush_t *sb, *tb; const char *psz; idVec3 dir, s1, s2; float len, f; int arrows; int num_entities; const char *ent_target[MAX_MAP_ENTITIES]; entity_t *ent_entity[MAX_MAP_ENTITIES]; if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS) { return; } num_entities = 0; for (te = entities.next; te != &entities && num_entities != MAX_MAP_ENTITIES; te = te->next) { for (int i = 0; i < 2048; i++) { if (i == 0) { ent_target[num_entities] = ValueForKey(te, "target"); } else { ent_target[num_entities] = ValueForKey(te, va("target%i", i)); } if (ent_target[num_entities][0]) { ent_entity[num_entities] = te; num_entities++; } else if (i > 16) { break; } } } for (se = entities.next; se != &entities; se = se->next) { psz = ValueForKey(se, "name"); if (psz == NULL || psz[0] == '\0') { continue; } sb = se->brushes.onext; if (sb == &se->brushes) { continue; } for (k = 0; k < num_entities; k++) { if (strcmp(ent_target[k], psz)) { continue; } te = ent_entity[k]; tb = te->brushes.onext; if (tb == &te->brushes) { continue; } mid = sb->owner->origin; mid1 = tb->owner->origin; VectorSubtract(mid1, mid, dir); len = dir.Normalize(); s1[0] = -dir[1] * 8 + dir[0] * 8; s2[0] = dir[1] * 8 + dir[0] * 8; s1[1] = dir[0] * 8 + dir[1] * 8; s2[1] = -dir[0] * 8 + dir[1] * 8; qglColor3f(se->eclass->color[0], se->eclass->color[1], se->eclass->color[2]); qglBegin(GL_LINES); qglVertex3fv(mid.ToFloatPtr()); qglVertex3fv(mid1.ToFloatPtr()); arrows = (int)(len / 256) + 1; for (i = 0; i < arrows; i++) { f = len * (i + 0.5) / arrows; mid1 = mid + (f * dir); qglVertex3fv(mid1.ToFloatPtr()); qglVertex3f(mid1[0] + s1[0], mid1[1] + s1[1], mid1[2]); qglVertex3fv(mid1.ToFloatPtr()); qglVertex3f(mid1[0] + s2[0], mid1[1] + s2[1], mid1[2]); } qglEnd(); } } return; } // // ======================================================================================================================= // can be greatly simplified but per usual i am in a hurry which is not an excuse, just a fact // ======================================================================================================================= // void CXYWnd::PaintSizeInfo(int nDim1, int nDim2, idVec3 vMinBounds, idVec3 vMaxBounds) { idVec3 vSize; VectorSubtract(vMaxBounds, vMinBounds, vSize); qglColor3f ( g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] * .65, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] * .65, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] * .65 ); if (m_nViewType == XY) { qglBegin(GL_LINES); qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale, 0.0f); qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale, 0.0f); qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, vMinBounds[nDim2], 0.0f); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2], 0.0f); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2], 0.0f); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2], 0.0f); qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, vMaxBounds[nDim2], 0.0f); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2], 0.0f); qglEnd(); qglRasterPos3f(Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), vMinBounds[nDim2] - 20.0 / m_fScale, 0.0f); g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); qglRasterPos3f(vMaxBounds[nDim1] + 16.0 / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2]), 0.0f); g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); qglRasterPos3f(vMinBounds[nDim1] + 4, vMaxBounds[nDim2] + 8 / m_fScale, 0.0f); g_strDim.Format(g_pOrgStrings[0], vMinBounds[nDim1], vMaxBounds[nDim2]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); } else if (m_nViewType == XZ) { qglBegin(GL_LINES); qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 6.0f / m_fScale); qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 6.0f / m_fScale); qglVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, 0, vMinBounds[nDim2]); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMinBounds[nDim2]); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMinBounds[nDim2]); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMaxBounds[nDim2]); qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, 0, vMaxBounds[nDim2]); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMaxBounds[nDim2]); qglEnd(); qglRasterPos3f(Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), 0, vMinBounds[nDim2] - 20.0 / m_fScale); g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); qglRasterPos3f(vMaxBounds[nDim1] + 16.0 / m_fScale, 0, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2])); g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); qglRasterPos3f(vMinBounds[nDim1] + 4, 0, vMaxBounds[nDim2] + 8 / m_fScale); g_strDim.Format(g_pOrgStrings[1], vMinBounds[nDim1], vMaxBounds[nDim2]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); } else { qglBegin(GL_LINES); qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale); qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale); qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(0, vMaxBounds[nDim1] + 6.0f / m_fScale, vMinBounds[nDim2]); qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2]); qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2]); qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2]); qglVertex3f(0, vMaxBounds[nDim1] + 6.0f / m_fScale, vMaxBounds[nDim2]); qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2]); qglEnd(); qglRasterPos3f(0, Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), vMinBounds[nDim2] - 20.0 / m_fScale); g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); qglRasterPos3f(0, vMaxBounds[nDim1] + 16.0 / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2])); g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); qglRasterPos3f(0, vMinBounds[nDim1] + 4.0, vMaxBounds[nDim2] + 8 / m_fScale); g_strDim.Format(g_pOrgStrings[2], vMinBounds[nDim1], vMaxBounds[nDim2]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); } } /* XY_Draw */ long g_lCount = 0; long g_lTotal = 0; extern void DrawBrushEntityName(brush_t *b); /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::XY_Draw() { brush_t *brush; float w, h; entity_t *e; idVec3 mins, maxs; int drawn, culled; int i; if (!active_brushes.next) { return; // not valid yet } // clear m_bDirty = false; GL_State( GLS_DEFAULT ); qglViewport(0, 0, m_nWidth, m_nHeight); qglScissor(0, 0, m_nWidth, m_nHeight); qglClearColor ( g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0], g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1], g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2], 0 ); qglDisable(GL_DEPTH_TEST); qglDisable(GL_CULL_FACE); qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // set up viewpoint qglMatrixMode(GL_PROJECTION); qglLoadIdentity(); w = m_nWidth / 2 / m_fScale; h = m_nHeight / 2 / m_fScale; int nDim1 = (m_nViewType == YZ) ? 1 : 0; int nDim2 = (m_nViewType == XY) ? 1 : 2; mins[0] = m_vOrigin[nDim1] - w; maxs[0] = m_vOrigin[nDim1] + w; mins[1] = m_vOrigin[nDim2] - h; maxs[1] = m_vOrigin[nDim2] + h; idBounds viewBounds( mins, maxs ); viewBounds[0].z = -99999; viewBounds[1].z = 99999; qglOrtho(mins[0], maxs[0], mins[1], maxs[1], MIN_WORLD_COORD, MAX_WORLD_COORD); // draw stuff globalImages->BindNull(); // now draw the grid qglLineWidth(0.25); XY_DrawGrid(); qglLineWidth(0.5); drawn = culled = 0; if (m_nViewType != XY) { qglPushMatrix(); if (m_nViewType == YZ) { qglRotatef(-90, 0, 1, 0); // put Z going up } // else qglRotatef(-90, 1, 0, 0); // put Z going up } e = world_entity; for ( brush = active_brushes.next; brush != &active_brushes; brush = brush->next ) { if ( brush->forceVisibile || ( brush->owner->eclass->nShowFlags & ( ECLASS_LIGHT | ECLASS_PROJECTEDLIGHT ) ) ) { } else if ( brush->mins[nDim1] > maxs[0] || brush->mins[nDim2] > maxs[1] || brush->maxs[nDim1] < mins[0] || brush->maxs[nDim2] < mins[1] ) { culled++; continue; // off screen } if ( FilterBrush(brush) ) { continue; } drawn++; if (brush->owner != e && brush->owner) { qglColor3fv(brush->owner->eclass->color.ToFloatPtr()); } else { qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES].ToFloatPtr()); } Brush_DrawXY( brush, m_nViewType ); } DrawPathLines(); // draw pointfile if (g_qeglobals.d_pointfile_display_list) { qglCallList(g_qeglobals.d_pointfile_display_list); } if (!(m_nViewType == XY)) { qglPopMatrix(); } // draw block grid if (g_qeglobals.show_blocks) { XY_DrawBlockGrid(); } // now draw selected brushes if (m_nViewType != XY) { qglPushMatrix(); if (m_nViewType == YZ) { qglRotatef(-90, 0, 1, 0); // put Z going up } // else qglRotatef(-90, 1, 0, 0); // put Z going up } qglPushMatrix(); qglTranslatef ( g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2] ); if (RotateMode()) { qglColor3f( 0.8f, 0.1f, 0.9f ); } else if (ScaleMode()) { qglColor3f( 0.1f, 0.8f, 0.1f ); } else { qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].ToFloatPtr()); } if (g_PrefsDlg.m_bNoStipple == FALSE) { qglEnable(GL_LINE_STIPPLE); qglLineStipple(3, 0xaaaa); } qglLineWidth(1); idVec3 vMinBounds; idVec3 vMaxBounds; vMinBounds[0] = vMinBounds[1] = vMinBounds[2] = 999999.9f; vMaxBounds[0] = vMaxBounds[1] = vMaxBounds[2] = -999999.9f; int nSaveDrawn = drawn; bool bFixedSize = false; for (brush = selected_brushes.next; brush != &selected_brushes; brush = brush->next) { drawn++; Brush_DrawXY(brush, m_nViewType, true); if (!bFixedSize) { if (brush->owner->eclass->fixedsize) { bFixedSize = true; } if (g_PrefsDlg.m_bSizePaint) { for (i = 0; i < 3; i++) { if (brush->mins[i] < vMinBounds[i]) { vMinBounds[i] = brush->mins[i]; } if (brush->maxs[i] > vMaxBounds[i]) { vMaxBounds[i] = brush->maxs[i]; } } } } } if (g_PrefsDlg.m_bNoStipple == FALSE) { qglDisable(GL_LINE_STIPPLE); } qglLineWidth(0.5); if (!bFixedSize && !RotateMode() && !ScaleMode() && drawn - nSaveDrawn > 0 && g_PrefsDlg.m_bSizePaint) { PaintSizeInfo(nDim1, nDim2, vMinBounds, vMaxBounds); } // edge / vertex flags if (g_qeglobals.d_select_mode == sel_vertex) { qglPointSize(4); qglColor3f(0, 1, 0); qglBegin(GL_POINTS); for (i = 0; i < g_qeglobals.d_numpoints; i++) { qglVertex3fv(g_qeglobals.d_points[i].ToFloatPtr()); } qglEnd(); qglPointSize(1); } else if (g_qeglobals.d_select_mode == sel_edge) { float *v1, *v2; qglPointSize(4); qglColor3f(0, 0, 1); qglBegin(GL_POINTS); for (i = 0; i < g_qeglobals.d_numedges; i++) { v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1].ToFloatPtr(); v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2].ToFloatPtr(); qglVertex3f((v1[0] + v2[0]) * 0.5, (v1[1] + v2[1]) * 0.5, (v1[2] + v2[2]) * 0.5); } qglEnd(); qglPointSize(1); } g_splineList->draw (static_cast<bool>(g_qeglobals.d_select_mode == sel_editpoint || g_qeglobals.d_select_mode == sel_addpoint)); if (g_pParentWnd->GetNurbMode() && g_pParentWnd->GetNurb()->GetNumValues()) { int maxage = g_pParentWnd->GetNurb()->GetNumValues(); int time = 0; qglColor3f(0, 0, 1); qglPointSize(1); qglBegin(GL_POINTS); g_pParentWnd->GetNurb()->SetOrder(3); for (i = 0; i < 100; i++) { idVec2 v = g_pParentWnd->GetNurb()->GetCurrentValue(time); qglVertex3f(v.x, v.y, 0.0f); time += 10; } qglEnd(); qglPointSize(4); qglColor3f(0, 0, 1); qglBegin(GL_POINTS); for (i = 0; i < maxage; i++) { idVec2 v = g_pParentWnd->GetNurb()->GetValue(i); qglVertex3f(v.x, v.y, 0.0f); } qglEnd(); qglPointSize(1); } qglPopMatrix(); qglTranslatef ( -g_qeglobals.d_select_translate[0], -g_qeglobals.d_select_translate[1], -g_qeglobals.d_select_translate[2] ); if (!(m_nViewType == XY)) { qglPopMatrix(); } // area selection hack if (g_qeglobals.d_select_mode == sel_area) { qglEnable(GL_BLEND); qglPolygonMode ( GL_FRONT_AND_BACK , GL_FILL ); qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglColor4f(0.0, 0.0, 1.0, 0.25); qglRectf ( g_qeglobals.d_vAreaTL[nDim1], g_qeglobals.d_vAreaTL[nDim2], g_qeglobals.d_vAreaBR[nDim1], g_qeglobals.d_vAreaBR[nDim2] ); qglDisable(GL_BLEND); qglPolygonMode ( GL_FRONT_AND_BACK , GL_LINE ); qglColor3f(1.0f, 1.0f, 1.0f); qglRectf ( g_qeglobals.d_vAreaTL[nDim1], g_qeglobals.d_vAreaTL[nDim2], g_qeglobals.d_vAreaBR[nDim1], g_qeglobals.d_vAreaBR[nDim2] ); } // now draw camera point DrawCameraIcon(); DrawZIcon(); if (RotateMode()) { DrawRotateIcon(); } /// Draw a "precision crosshair" if enabled if( m_precisionCrosshairMode != PRECISION_CROSSHAIR_NONE ) DrawPrecisionCrosshair(); qglFlush(); // QE_CheckOpenGLForErrors(); } /* ======================================================================================================================= ======================================================================================================================= */ idVec3 &CXYWnd::GetOrigin() { return m_vOrigin; } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::SetOrigin(idVec3 org) { m_vOrigin[0] = org[0]; m_vOrigin[1] = org[1]; m_vOrigin[2] = org[2]; } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); CRect rect; GetClientRect(rect); m_nWidth = rect.Width(); m_nHeight = rect.Height(); InvalidateRect(NULL, false); } brush_t hold_brushes; /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::Clip() { if (ClipMode()) { hold_brushes.next = &hold_brushes; ProduceSplitLists(); // brush_t* pList = (g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits; brush_t *pList; if (g_PrefsDlg.m_bSwitchClip) { pList = ((m_nViewType == XZ) ? g_bSwitch : !g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits; } else { pList = ((m_nViewType == XZ) ? !g_bSwitch : g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits; } if (pList->next != pList) { Brush_CopyList(pList, &hold_brushes); CleanList(&g_brFrontSplits); CleanList(&g_brBackSplits); Select_Delete(); Brush_CopyList(&hold_brushes, &selected_brushes); if (RogueClipMode()) { RetainClipMode(false); } else { RetainClipMode(true); } Sys_UpdateWindows(W_ALL); } } else if (PathMode()) { FinishSmartCreation(); if (g_pPathFunc) { g_pPathFunc(true, g_nPathCount); } g_pPathFunc = NULL; g_nPathCount = 0; g_bPathMode = false; } } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::SplitClip() { ProduceSplitLists(); if ((g_brFrontSplits.next != &g_brFrontSplits) && (g_brBackSplits.next != &g_brBackSplits)) { Select_Delete(); Brush_CopyList(&g_brFrontSplits, &selected_brushes); Brush_CopyList(&g_brBackSplits, &selected_brushes); CleanList(&g_brFrontSplits); CleanList(&g_brBackSplits); if (RogueClipMode()) { RetainClipMode(false); } else { RetainClipMode(true); } } } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::FlipClip() { g_bSwitch = !g_bSwitch; Sys_UpdateWindows(XY | W_CAMERA_IFON); } // // ======================================================================================================================= // makes sure the selected brush or camera is in view // ======================================================================================================================= // void CXYWnd::PositionView() { int nDim1 = (m_nViewType == YZ) ? 1 : 0; int nDim2 = (m_nViewType == XY) ? 1 : 2; brush_t *b = selected_brushes.next; if (b && b->next != b) { m_vOrigin[nDim1] = b->mins[nDim1]; m_vOrigin[nDim2] = b->mins[nDim2]; } else { m_vOrigin[nDim1] = g_pParentWnd->GetCamera()->Camera().origin[nDim1]; m_vOrigin[nDim2] = g_pParentWnd->GetCamera()->Camera().origin[nDim2]; } } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::VectorCopyXY(const idVec3 &in, idVec3 &out) { if (m_nViewType == XY) { out[0] = in[0]; out[1] = in[1]; } else if (m_nViewType == XZ) { out[0] = in[0]; out[2] = in[2]; } else { out[1] = in[1]; out[2] = in[2]; } } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnDestroy() { CWnd::OnDestroy(); // delete this; } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::SetViewType(int n) { m_nViewType = n; char *p = "YZ Side"; if (m_nViewType == XY) { p = "XY Top"; } else if (m_nViewType == XZ) { p = "XZ Front"; } SetWindowText(p); }; /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::Redraw(unsigned int nBits) { m_nUpdateBits = nBits; RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); m_nUpdateBits = W_XY; } /* ======================================================================================================================= ======================================================================================================================= */ bool CXYWnd::RotateMode() { return g_bRotateMode; } /* ======================================================================================================================= ======================================================================================================================= */ bool CXYWnd::ScaleMode() { return g_bScaleMode; } /* ======================================================================================================================= ======================================================================================================================= */ extern bool Select_OnlyModelsSelected(); bool CXYWnd::SetRotateMode(bool bMode) { if (bMode && selected_brushes.next != &selected_brushes) { g_bRotateMode = true; if (Select_OnlyModelsSelected()) { Select_GetTrueMid(g_vRotateOrigin); } else { Select_GetMid(g_vRotateOrigin); } g_vRotation.Zero(); Select_InitializeRotation(); } else { if (bMode) { Sys_Status("Need a brush selected to turn on Mouse Rotation mode\n"); } g_bRotateMode = false; Select_FinalizeRotation(); } RedrawWindow(); return g_bRotateMode; } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::SetScaleMode(bool bMode) { g_bScaleMode = bMode; RedrawWindow(); } // // ======================================================================================================================= // xy - z xz - y yz - x // ======================================================================================================================= // void CXYWnd::OnSelectMouserotate() { // TODO: Add your command handler code here } /* ======================================================================================================================= ======================================================================================================================= */ void CleanCopyEntities() { entity_t *pe = g_enClipboard.next; while (pe != NULL && pe != &g_enClipboard) { entity_t *next = pe->next; pe->epairs.Clear(); Entity_Free(pe); pe = next; } g_enClipboard.next = g_enClipboard.prev = &g_enClipboard; } /* ======================================================================================================================= ======================================================================================================================= */ entity_t *Entity_CopyClone(entity_t *e) { entity_t *n; n = Entity_New(); n->brushes.onext = n->brushes.oprev = &n->brushes; n->eclass = e->eclass; n->rotation = e->rotation; // add the entity to the entity list n->next = g_enClipboard.next; g_enClipboard.next = n; n->next->prev = n; n->prev = &g_enClipboard; n->epairs = e->epairs; return n; } /* ======================================================================================================================= ======================================================================================================================= */ bool OnList(entity_t *pFind, CPtrArray *pList) { int nSize = pList->GetSize(); while (nSize-- > 0) { entity_t *pEntity = reinterpret_cast < entity_t * > (pList->GetAt(nSize)); if (pEntity == pFind) { return true; } } return false; } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::Copy() { #if 1 CWaitCursor WaitCursor; g_Clipboard.SetLength(0); g_PatchClipboard.SetLength(0); Map_SaveSelected(&g_Clipboard, &g_PatchClipboard); bool bClipped = false; UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings"); if (nClipboard > 0) { if (OpenClipboard()) { ::EmptyClipboard(); long lSize = g_Clipboard.GetLength(); HANDLE h = ::GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, lSize + sizeof (long)); if (h != NULL) { unsigned char *cp = reinterpret_cast < unsigned char * > (::GlobalLock(h)); memcpy(cp, &lSize, sizeof (long)); cp += sizeof (long); g_Clipboard.SeekToBegin(); g_Clipboard.Read(cp, lSize); ::GlobalUnlock(h); ::SetClipboardData(nClipboard, h); ::CloseClipboard(); bClipped = true; } } } if (!bClipped) { common->Printf("Unable to register Windows clipboard formats, copy/paste between editors will not be possible"); } /* * CString strOut; ::GetTempPath(1024, strOut.GetBuffer(1024)); * strOut.ReleaseBuffer(); AddSlash(strOut); strOut += "RadiantClipboard.$$$"; * Map_SaveSelected(strOut.GetBuffer(0)); */ #else CPtrArray holdArray; CleanList(&g_brClipboard); CleanCopyEntities(); for (brush_t * pBrush = selected_brushes.next; pBrush != NULL && pBrush != &selected_brushes; pBrush = pBrush->next) { if (pBrush->owner == world_entity) { brush_t *pClone = Brush_Clone(pBrush); pClone->owner = NULL; Brush_AddToList(pClone, &g_brClipboard); } else { if (!OnList(pBrush->owner, &holdArray)) { entity_t *e = pBrush->owner; holdArray.Add(reinterpret_cast < void * > (e)); entity_t *pEClone = Entity_CopyClone(e); for (brush_t * pEB = e->brushes.onext; pEB != &e->brushes; pEB = pEB->onext) { brush_t *pClone = Brush_Clone(pEB); // Brush_AddToList (pClone, &g_brClipboard); Entity_LinkBrush(pEClone, pClone); Brush_Build(pClone); } } } } #endif } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::Undo() { /* * if (g_brUndo.next != &g_brUndo) { g_bScreenUpdates = false; Select_Delete(); * for (brush_t* pBrush = g_brUndo.next ; pBrush != NULL && pBrush != &g_brUndo ; * pBrush=pBrush->next) { brush_t* pClone = Brush_Clone(pBrush); Brush_AddToList * (pClone, &active_brushes); Entity_LinkBrush (pBrush->pUndoOwner, pClone); * Brush_Build(pClone); Select_Brush(pClone); } CleanList(&g_brUndo); * g_bScreenUpdates = true; Sys_UpdateWindows(W_ALL); } else common->Printf("Nothing * to undo.../n"); */ } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::UndoClear() { /* CleanList(&g_brUndo); */ } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::UndoCopy() { /* * CleanList(&g_brUndo); for (brush_t* pBrush = selected_brushes.next ; pBrush != * NULL && pBrush != &selected_brushes ; pBrush=pBrush->next) { brush_t* pClone = * Brush_Clone(pBrush); pClone->pUndoOwner = pBrush->owner; Brush_AddToList * (pClone, &g_brUndo); } */ } /* ======================================================================================================================= ======================================================================================================================= */ bool CXYWnd::UndoAvailable() { return(g_brUndo.next != &g_brUndo); } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::Paste() { #if 1 CWaitCursor WaitCursor; bool bPasted = false; UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings"); if (nClipboard > 0 && OpenClipboard() && ::IsClipboardFormatAvailable(nClipboard)) { HANDLE h = ::GetClipboardData(nClipboard); if (h) { g_Clipboard.SetLength(0); unsigned char *cp = reinterpret_cast < unsigned char * > (::GlobalLock(h)); long lSize = 0; memcpy(&lSize, cp, sizeof (long)); cp += sizeof (long); g_Clipboard.Write(cp, lSize); } ::GlobalUnlock(h); ::CloseClipboard(); } if (g_Clipboard.GetLength() > 0) { g_Clipboard.SeekToBegin(); int nLen = g_Clipboard.GetLength(); char *pBuffer = new char[nLen + 1]; memset(pBuffer, 0, sizeof(pBuffer)); g_Clipboard.Read(pBuffer, nLen); pBuffer[nLen] = '\0'; Map_ImportBuffer(pBuffer, !(GetAsyncKeyState(VK_SHIFT) & 0x8000)); delete[] pBuffer; } #if 0 if (g_PatchClipboard.GetLength() > 0) { g_PatchClipboard.SeekToBegin(); int nLen = g_PatchClipboard.GetLength(); char *pBuffer = new char[nLen + 1]; g_PatchClipboard.Read(pBuffer, nLen); pBuffer[nLen] = '\0'; Patch_ReadBuffer(pBuffer, true); delete[] pBuffer; } #endif #else if (g_brClipboard.next != &g_brClipboard || g_enClipboard.next != &g_enClipboard) { Select_Deselect(); for (brush_t * pBrush = g_brClipboard.next; pBrush != NULL && pBrush != &g_brClipboard; pBrush = pBrush->next) { brush_t *pClone = Brush_Clone(pBrush); // pClone->owner = pBrush->owner; if (pClone->owner == NULL) { Entity_LinkBrush(world_entity, pClone); } Brush_AddToList(pClone, &selected_brushes); Brush_Build(pClone); } for ( entity_t * pEntity = g_enClipboard.next; pEntity != NULL && pEntity != &g_enClipboard; pEntity = pEntity->next ) { entity_t *pEClone = Entity_Clone(pEntity); for (brush_t * pEB = pEntity->brushes.onext; pEB != &pEntity->brushes; pEB = pEB->onext) { brush_t *pClone = Brush_Clone(pEB); Brush_AddToList(pClone, &selected_brushes); Entity_LinkBrush(pEClone, pClone); Brush_Build(pClone); if (pClone->owner && pClone->owner != world_entity) { g_Inspectors->UpdateEntitySel(pClone->owner->eclass); } } } Sys_UpdateWindows(W_ALL); } else { common->Printf("Nothing to paste.../n"); } #endif } /* ======================================================================================================================= ======================================================================================================================= */ idVec3 &CXYWnd::Rotation() { return g_vRotation; } /* ======================================================================================================================= ======================================================================================================================= */ idVec3 &CXYWnd::RotateOrigin() { return g_vRotateOrigin; } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnTimer(UINT nIDEvent) { if (nIDEvent == 100) { int nDim1 = (m_nViewType == YZ) ? 1 : 0; int nDim2 = (m_nViewType == XY) ? 1 : 2; m_vOrigin[nDim1] += m_ptDragAdj.x / m_fScale; m_vOrigin[nDim2] -= m_ptDragAdj.y / m_fScale; Sys_UpdateWindows(W_XY | W_CAMERA); // int nH = (m_ptDrag.y == 0) ? -1 : m_ptDrag.y; m_ptDrag += m_ptDragAdj; m_ptDragTotal += m_ptDragAdj; XY_MouseMoved(m_ptDrag.x, m_nHeight - 1 - m_ptDrag.y, m_nScrollFlags); // // m_vOrigin[nDim1] -= m_ptDrag.x / m_fScale; m_vOrigin[nDim1] -= m_ptDrag.x / // m_fScale; // } } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false); // CWnd::OnKeyUp(nChar, nRepCnt, nFlags); } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR *lpncsp) { CWnd::OnNcCalcSize(bCalcValidRects, lpncsp); } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnKillFocus(CWnd *pNewWnd) { CWnd::OnKillFocus(pNewWnd); SendMessage(WM_NCACTIVATE, FALSE, 0); } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnSetFocus(CWnd *pOldWnd) { CWnd::OnSetFocus(pOldWnd); SendMessage(WM_NCACTIVATE, TRUE, 0); } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnClose() { CWnd::OnClose(); } // // ======================================================================================================================= // should be static as should be the rotate scale stuff // ======================================================================================================================= // bool CXYWnd::AreaSelectOK() { return RotateMode() ? false : ScaleMode() ? false : true; } /* ======================================================================================================================= ======================================================================================================================= */ BOOL CXYWnd::OnEraseBkgnd(CDC *pDC) { return TRUE; // return CWnd::OnEraseBkgnd(pDC); } extern void AssignModel(); void CXYWnd::OnDropNewmodel() { CPoint point; GetCursorPos(&point); CreateRightClickEntity(this, m_ptDown.x, m_ptDown.y, "func_static"); g_Inspectors->SetMode(W_ENTITY); g_Inspectors->AssignModel(); } BOOL CXYWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { if (zDelta > 0) { g_pParentWnd->OnViewZoomin(); } else { g_pParentWnd->OnViewZoomout(); } return TRUE; } //--------------------------------------------------------------------------- // CyclePrecisionCrosshairMode // // Called when the user presses the "cycle precision cursor mode" key. // Cycles the precision cursor among the following three modes: // PRECISION_CURSOR_NONE // PRECISION_CURSOR_SNAP // PRECISION_CURSOR_FREE //--------------------------------------------------------------------------- void CXYWnd::CyclePrecisionCrosshairMode( void ) { common->Printf("TODO: Make DrawPrecisionCrosshair work..." ); /// Cycle to next mode, wrap if necessary m_precisionCrosshairMode ++; if( m_precisionCrosshairMode >= PRECISION_CROSSHAIR_MAX ) m_precisionCrosshairMode = PRECISION_CROSSHAIR_NONE; Sys_UpdateWindows( W_XY ); } //--------------------------------------------------------------------------- // DrawPrecisionCrosshair // // Draws a precision crosshair beneath the cursor in the 2d (XY) view, // depending on one of the following values for m_precisionCrosshairMode: // // PRECISION_CROSSHAIR_NONE No crosshair is drawn. Do not force refresh of XY view. // PRECISION_CROSSHAIR_SNAP Crosshair snaps to grid size. Force refresh of XY view. // PRECISION_CROSSHAIR_FREE Crosshair does not snap to grid. Force refresh of XY view. //--------------------------------------------------------------------------- void CXYWnd::DrawPrecisionCrosshair( void ) { // FIXME: m_mouseX, m_mouseY, m_axisHoriz, m_axisVert, etc... are never set return; idVec3 mouse3dPos (0.0f, 0.0f, 0.0f); float x, y; idVec4 crossEndColor (1.0f, 0.0f, 1.0f, 1.0f); // the RGBA color of the precision crosshair at its ends idVec4 crossMidColor; // the RGBA color of the precision crosshair at the crossing point /// Transform the mouse coordinates into axis-correct map-coordinates if( m_precisionCrosshairMode == PRECISION_CROSSHAIR_SNAP ) SnapToPoint( m_mouseX, m_mouseY, mouse3dPos ); else XY_ToPoint( m_mouseX, m_mouseY, mouse3dPos ); x = mouse3dPos[ m_axisHoriz ]; y = mouse3dPos[ m_axisVert ]; /// Use the color specified by the user crossEndColor[0] = g_qeglobals.d_savedinfo.colors[ COLOR_PRECISION_CROSSHAIR ][0]; crossEndColor[1] = g_qeglobals.d_savedinfo.colors[ COLOR_PRECISION_CROSSHAIR ][1]; crossEndColor[2] = g_qeglobals.d_savedinfo.colors[ COLOR_PRECISION_CROSSHAIR ][2]; crossEndColor[3] = 1.0f; crossMidColor = crossEndColor; if( m_precisionCrosshairMode == PRECISION_CROSSHAIR_FREE ) crossMidColor[ 3 ] = 0.0f; // intersection-color is 100% transparent (alpha = 0.0f) /// Set up OpenGL states (for drawing smooth-shaded plain-colored lines) qglEnable( GL_BLEND ); qglDisable( GL_TEXTURE_2D ); qglShadeModel( GL_SMOOTH ); qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); /// Draw a fullscreen-sized crosshair over the cursor qglBegin( GL_LINES ); { /// Draw the horizontal precision line (in two pieces) qglColor4fv( crossEndColor.ToFloatPtr() ); qglVertex2f( m_mcLeft, y ); qglColor4fv( crossMidColor.ToFloatPtr() ); qglVertex2f( x, y ); qglColor4fv( crossMidColor.ToFloatPtr() ); qglVertex2f( x, y ); qglColor4fv( crossEndColor.ToFloatPtr() ); qglVertex2f( m_mcRight, y ); /// Draw the vertical precision line (in two pieces) qglColor4fv( crossEndColor.ToFloatPtr() ); qglVertex2f( x, m_mcTop ); qglColor4fv( crossMidColor.ToFloatPtr() ); qglVertex2f( x, y ); qglColor4fv( crossMidColor.ToFloatPtr() ); qglVertex2f( x, y ); qglColor4fv( crossEndColor.ToFloatPtr() ); qglVertex2f( x, m_mcBottom ); } qglEnd(); // GL_LINES // Radiant was in opaque, flat-shaded mode by default; restore this to prevent possible slowdown qglShadeModel( GL_FLAT ); qglDisable( GL_BLEND ); }
2738  XY_DrawGrid
2739  =======================================================================================================================
2740  */
2742  float x, y, xb, xe, yb, ye;
2743  int w, h;
2744  char text[32];
2745 
2746  int startPos = max ( 64 , g_qeglobals.d_gridsize );
2747 
2748  w = m_nWidth / 2 / m_fScale;
2749  h = m_nHeight / 2 / m_fScale;
2750 
2751  int nDim1 = (m_nViewType == YZ) ? 1 : 0;
2752  int nDim2 = (m_nViewType == XY) ? 1 : 2;
2753 
2754  // int nDim1 = 0; int nDim2 = 1;
2755  xb = m_vOrigin[nDim1] - w;
2756  if (xb < region_mins[nDim1]) {
2757  xb = region_mins[nDim1];
2758  }
2759 
2760  xb = startPos * floor(xb / startPos);
2761 
2762  xe = m_vOrigin[nDim1] + w;
2763  if (xe > region_maxs[nDim1]) {
2764  xe = region_maxs[nDim1];
2765  }
2766 
2767  xe = startPos * ceil(xe / startPos);
2768 
2769  yb = m_vOrigin[nDim2] - h;
2770  if (yb < region_mins[nDim2]) {
2771  yb = region_mins[nDim2];
2772  }
2773 
2774  yb = startPos * floor(yb / startPos);
2775 
2776  ye = m_vOrigin[nDim2] + h;
2777  if (ye > region_maxs[nDim2]) {
2778  ye = region_maxs[nDim2];
2779  }
2780 
2781  ye = startPos * ceil(ye / startPos);
2782 
2783  // draw major blocks
2784  qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR].ToFloatPtr());
2785 
2786  int stepSize = 64 * 0.1 / m_fScale;
2787  if (stepSize < 64) {
2788  stepSize = max ( 64 , g_qeglobals.d_gridsize );
2789  }
2790  else {
2791  int i;
2792  for (i = 1; i < stepSize; i <<= 1) {
2793  }
2794 
2795  stepSize = i;
2796  }
2797 
2798  if (g_qeglobals.d_showgrid) {
2799  qglBegin(GL_LINES);
2800 
2801  for (x = xb; x <= xe; x += stepSize) {
2802  qglVertex2f(x, yb);
2803  qglVertex2f(x, ye);
2804  }
2805 
2806  for (y = yb; y <= ye; y += stepSize) {
2807  qglVertex2f(xb, y);
2808  qglVertex2f(xe, y);
2809  }
2810 
2811  qglEnd();
2812  }
2813 
2814  // draw minor blocks
2815  if ( m_fScale > .1 &&
2816  g_qeglobals.d_showgrid &&
2817  g_qeglobals.d_gridsize * m_fScale >= 4 &&
2818  !g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR].Compare( g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK] ) ) {
2819 
2820  qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR].ToFloatPtr());
2821 
2822  qglBegin(GL_LINES);
2823  for (x = xb; x < xe; x += g_qeglobals.d_gridsize) {
2824  if (!((int)x & (startPos - 1))) {
2825  continue;
2826  }
2827 
2828  qglVertex2f(x, yb);
2829  qglVertex2f(x, ye);
2830  }
2831 
2832  for (y = yb; y < ye; y += g_qeglobals.d_gridsize) {
2833  if (!((int)y & (startPos - 1))) {
2834  continue;
2835  }
2836 
2837  qglVertex2f(xb, y);
2838  qglVertex2f(xe, y);
2839  }
2840 
2841  qglEnd();
2842  }
2843 
2844 
2845  // draw ZClip boundaries (if applicable)...
2846  //
2847  if (m_nViewType == XZ || m_nViewType == YZ)
2848  {
2849  if (g_pParentWnd->GetZWnd()->m_pZClip) // should always be the case at this point I think, but this is safer
2850  {
2852  {
2854  qglLineWidth(2);
2855  qglBegin (GL_LINES);
2856 
2859 
2862 
2863  qglEnd ();
2864  qglLineWidth(1);
2865  }
2866  }
2867  }
2868 
2869 
2870 
2871 
2872  // draw coordinate text if needed
2873  if (g_qeglobals.d_savedinfo.show_coordinates) {
2874  // glColor4f(0, 0, 0, 0);
2875  qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT].ToFloatPtr());
2876 
2877  float lastRaster = xb;
2878 
2879  for (x = xb; x < xe; x += stepSize) {
2880  qglRasterPos2f(x, m_vOrigin[nDim2] + h - 10 / m_fScale);
2881  sprintf(text, "%i", (int)x);
2882  qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
2883  }
2884 
2885  for (y = yb; y < ye; y += stepSize) {
2886  qglRasterPos2f(m_vOrigin[nDim1] - w + 1, y);
2887  sprintf(text, "%i", (int)y);
2888  qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
2889  }
2890 
2891  if (Active()) {
2892  qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME].ToFloatPtr());
2893  }
2894 
2895  qglRasterPos2f(m_vOrigin[nDim1] - w + 35 / m_fScale, m_vOrigin[nDim2] + h - 20 / m_fScale);
2896 
2897  char cView[20];
2898  if (m_nViewType == XY) {
2899  strcpy(cView, "XY Top");
2900  }
2901  else if (m_nViewType == XZ) {
2902  strcpy(cView, "XZ Front");
2903  }
2904  else {
2905  strcpy(cView, "YZ Side");
2906  }
2907 
2908  qglCallLists(strlen(cView), GL_UNSIGNED_BYTE, cView);
2909  }
2910 
2911  /*
2912  * if (true) { qglColor3f(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR]);
2913  * qglBegin (GL_LINES); qglVertex2f (x, yb); qglVertex2f (x, ye); qglEnd(); }
2914  */
2915 }
2916 
2917 /*
2918  =======================================================================================================================
2919  XY_DrawBlockGrid
2920  =======================================================================================================================
2921  */
2923  float x, y, xb, xe, yb, ye;
2924  int w, h;
2925  char text[32];
2926 
2927  w = m_nWidth / 2 / m_fScale;
2928  h = m_nHeight / 2 / m_fScale;
2929 
2930  int nDim1 = (m_nViewType == YZ) ? 1 : 0;
2931  int nDim2 = (m_nViewType == XY) ? 1 : 2;
2932 
2933  xb = m_vOrigin[nDim1] - w;
2934  if (xb < region_mins[nDim1]) {
2935  xb = region_mins[nDim1];
2936  }
2937 
2938  xb = 1024 * floor(xb / 1024);
2939 
2940  xe = m_vOrigin[nDim1] + w;
2941  if (xe > region_maxs[nDim1]) {
2942  xe = region_maxs[nDim1];
2943  }
2944 
2945  xe = 1024 * ceil(xe / 1024);
2946 
2947  yb = m_vOrigin[nDim2] - h;
2948  if (yb < region_mins[nDim2]) {
2949  yb = region_mins[nDim2];
2950  }
2951 
2952  yb = 1024 * floor(yb / 1024);
2953 
2954  ye = m_vOrigin[nDim2] + h;
2955  if (ye > region_maxs[nDim2]) {
2956  ye = region_maxs[nDim2];
2957  }
2958 
2959  ye = 1024 * ceil(ye / 1024);
2960 
2961  // draw major blocks
2962  qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK].ToFloatPtr());
2963  qglLineWidth(0.5);
2964 
2965  qglBegin(GL_LINES);
2966 
2967  for (x = xb; x <= xe; x += 1024) {
2968  qglVertex2f(x, yb);
2969  qglVertex2f(x, ye);
2970  }
2971 
2972  for (y = yb; y <= ye; y += 1024) {
2973  qglVertex2f(xb, y);
2974  qglVertex2f(xe, y);
2975  }
2976 
2977  qglEnd();
2978  qglLineWidth(0.25);
2979 
2980  // draw coordinate text if needed
2981  for (x = xb; x < xe; x += 1024) {
2982  for (y = yb; y < ye; y += 1024) {
2983  qglRasterPos2f(x + 512, y + 512);
2984  sprintf(text, "%i,%i", (int)floor(x / 1024), (int)floor(y / 1024));
2985  qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
2986  }
2987  }
2988 
2989  qglColor4f(0, 0, 0, 0);
2990 }
2991 
2992 void GLColoredBoxWithLabel(float x, float y, float size, idVec4 color, const char *text, idVec4 textColor, float xofs, float yofs, float lineSize) {
2993  globalImages->BindNull();
2994  qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
2995  qglDisable(GL_CULL_FACE);
2996  qglDisable(GL_BLEND);
2997  qglColor4f(color[0], color[1], color[2], color[3]);
2998  qglBegin(GL_QUADS);
2999  qglVertex3f(x - size, y - size, 0);
3000  qglVertex3f(x + size, y - size, 0);
3001  qglVertex3f(x + size, y + size, 0);
3002  qglVertex3f(x - size, y + size, 0);
3003  qglEnd();
3004 
3005  qglColor4f(textColor[0], textColor[1], textColor[2], textColor[3]);
3006  qglLineWidth(lineSize);
3007  qglRasterPos2f(x + xofs, y + yofs);
3008  qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
3009 }
3010 
3011 /*
3012  =======================================================================================================================
3013  =======================================================================================================================
3014  */
3016  float x, y;
3017 
3018  if (m_nViewType == XY) {
3019  x = g_vRotateOrigin[0];
3020  y = g_vRotateOrigin[1];
3021  }
3022  else if (m_nViewType == YZ) {
3023  x = g_vRotateOrigin[1];
3024  y = g_vRotateOrigin[2];
3025  }
3026  else {
3027  x = g_vRotateOrigin[0];
3028  y = g_vRotateOrigin[2];
3029  }
3030 
3031  qglEnable(GL_BLEND);
3033  qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
3034  qglDisable(GL_CULL_FACE);
3035  qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3036  qglColor4f( 0.8f, 0.1f, 0.9f, 0.25f );
3037 
3038  qglBegin(GL_QUADS);
3039  qglVertex3f(x - 4, y - 4, 0);
3040  qglVertex3f(x + 4, y - 4, 0);
3041  qglVertex3f(x + 4, y + 4, 0);
3042  qglVertex3f(x - 4, y + 4, 0);
3043  qglEnd();
3044  qglDisable(GL_BLEND);
3045 
3046  qglColor4f( 1.0f, 0.2f, 1.0f, 1.0f );
3047  qglBegin(GL_POINTS);
3048  qglVertex3f(x, y, 0);
3049  qglEnd();
3050 
3051 
3052  int w = m_nWidth / 2 / m_fScale;
3053  int h = m_nHeight / 2 / m_fScale;
3054  int nDim1 = (m_nViewType == YZ) ? 1 : 0;
3055  int nDim2 = (m_nViewType == XY) ? 1 : 2;
3056  x = m_vOrigin[nDim1] - w + 35 / m_fScale;
3057  y = m_vOrigin[nDim2] + h - 40 / m_fScale;
3058  const char *p = "Rotate Z Axis";
3059  if (g_qeglobals.rotateAxis == 1) {
3060  p = "Rotate Y Axis";
3061  } else if (g_qeglobals.rotateAxis == 0) {
3062  p = "Rotate X Axis";
3063  }
3064  idStr str = p;
3065  if (g_qeglobals.flatRotation) {
3066  str += g_qeglobals.flatRotation == 2 ? " Flat [center] " : " Flat [ rot origin ] ";
3067  }
3068  qglRasterPos2f(x, y);
3069  qglCallLists(str.Length(), GL_UNSIGNED_BYTE, str.c_str());
3070 }
3071 
3072 /*
3073  =======================================================================================================================
3074  =======================================================================================================================
3075  */
3077  float x, y, a;
3078 
3079  if (m_nViewType == XY) {
3080  x = g_pParentWnd->GetCamera()->Camera().origin[0];
3081  y = g_pParentWnd->GetCamera()->Camera().origin[1];
3083  }
3084  else if (m_nViewType == YZ) {
3085  x = g_pParentWnd->GetCamera()->Camera().origin[1];
3086  y = g_pParentWnd->GetCamera()->Camera().origin[2];
3088  }
3089  else {
3090  x = g_pParentWnd->GetCamera()->Camera().origin[0];
3091  y = g_pParentWnd->GetCamera()->Camera().origin[2];
3093  }
3094 
3095  float scale = 1.0/m_fScale; //jhefty - keep the camera icon proportionally the same size
3096 
3097  qglColor3f(0.0, 0.0, 1.0);
3098  qglBegin(GL_LINE_STRIP);
3099  qglVertex3f(x - 16*scale, y, 0);
3100  qglVertex3f(x, y + 8*scale, 0);
3101  qglVertex3f(x + 16*scale, y, 0);
3102  qglVertex3f(x, y - 8*scale, 0);
3103  qglVertex3f(x - 16*scale, y, 0);
3104  qglVertex3f(x + 16*scale, y, 0);
3105  qglEnd();
3106 
3107  qglBegin(GL_LINE_STRIP);
3108  qglVertex3f(x + (48 * cos( a + idMath::PI * 0.25f )*scale), y + (48 * sin( a + idMath::PI * 0.25f )*scale), 0);
3109  qglVertex3f(x, y, 0);
3110  qglVertex3f(x + (48 * cos( a - idMath::PI * 0.25f )*scale), y + (48 * sin( a - idMath::PI * 0.25f )*scale), 0);
3111  qglEnd();
3112 
3113 #if 0
3114 
3115  char text[128];
3116  qglRasterPos2f(x + 64, y + 64);
3117  sprintf(text, "%f", g_pParentWnd->GetCamera()->Camera().angles[YAW]);
3118  qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
3119 #endif
3120 }
3121 
3122 /*
3123  =======================================================================================================================
3124  =======================================================================================================================
3125  */
3126 void CXYWnd::DrawZIcon(void) {
3127  if (m_nViewType == XY) {
3128  float x = z.origin[0];
3129  float y = z.origin[1];
3130  qglEnable(GL_BLEND);
3132  qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
3133  qglDisable(GL_CULL_FACE);
3134  qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3135  qglColor4f(0.0, 0.0, 1.0, 0.25);
3136  qglBegin(GL_QUADS);
3137  qglVertex3f(x - 8, y - 8, 0);
3138  qglVertex3f(x + 8, y - 8, 0);
3139  qglVertex3f(x + 8, y + 8, 0);
3140  qglVertex3f(x - 8, y + 8, 0);
3141  qglEnd();
3142  qglDisable(GL_BLEND);
3143 
3144  qglColor4f(0.0, 0.0, 1.0, 1);
3145 
3146  qglBegin(GL_LINE_LOOP);
3147  qglVertex3f(x - 8, y - 8, 0);
3148  qglVertex3f(x + 8, y - 8, 0);
3149  qglVertex3f(x + 8, y + 8, 0);
3150  qglVertex3f(x - 8, y + 8, 0);
3151  qglEnd();
3152 
3153  qglBegin(GL_LINE_STRIP);
3154  qglVertex3f(x - 4, y + 4, 0);
3155  qglVertex3f(x + 4, y + 4, 0);
3156  qglVertex3f(x - 4, y - 4, 0);
3157  qglVertex3f(x + 4, y - 4, 0);
3158  qglEnd();
3159  }
3160 }
3161 
3162 /*
3163  =======================================================================================================================
3164  FilterBrush
3165  =======================================================================================================================
3166  */
3167 bool FilterBrush(brush_t *pb) {
3168 
3169  if (!pb->owner) {
3170  return false; // during construction
3171  }
3172 
3173  if (pb->hiddenBrush) {
3174  return true;
3175  }
3176 
3177  if ( pb->forceVisibile ) {
3178  return false;
3179  }
3180 
3181  if (g_pParentWnd->GetZWnd()->m_pZClip) // ZClip class up and running? (and hence Z window built)
3182  {
3184  {
3185  // ZClipping active...
3186  //
3187  if (pb->mins[2] > g_pParentWnd->GetZWnd()->m_pZClip->GetTop() // brush bottom edge is above clip top
3188  ||
3189  pb->maxs[2] < g_pParentWnd->GetZWnd()->m_pZClip->GetBottom()// brush top edge is below clip bottom
3190  )
3191  {
3192  return TRUE;
3193  }
3194  }
3195  }
3196 
3197  if (g_qeglobals.d_savedinfo.exclude & (EXCLUDE_CAULK | EXCLUDE_VISPORTALS)) {
3198  //
3199  // filter out the brush only if all faces are caulk if not don't hide the whole
3200  // brush, proceed on a per-face basis (Cam_Draw) ++timo TODO: set this as a
3201  // preference .. show caulk: hide any brush with caulk // don't draw caulk faces
3202  //
3203  face_t *f;
3204  f = pb->brush_faces;
3205  while (f) {
3206  if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK) {
3207  if (!strstr(f->texdef.name, "caulk")) {
3208  break;
3209  }
3210  } else {
3211  if (strstr(f->texdef.name, "visportal")) {
3212  return true;
3213  }
3214  }
3215 
3216  f = f->next;
3217  }
3218 
3219  if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK) {
3220  if (!f) {
3221  return true;
3222  }
3223  }
3224 
3225  // ++timo FIXME: .. same deal here?
3226  if (strstr(pb->brush_faces->texdef.name, "donotenter")) {
3227  return true;
3228  }
3229  }
3230 
3231  if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_HINT) {
3232  if (strstr(pb->brush_faces->texdef.name, "hint")) {
3233  return true;
3234  }
3235  }
3236 
3237  if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP) {
3238  if (strstr(pb->brush_faces->texdef.name, "clip")) {
3239  return true;
3240  }
3241  }
3242 
3243  if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_TRIGGERS) {
3244  if (strstr(pb->brush_faces->texdef.name, "trig")) {
3245  return true;
3246  }
3247  }
3248 
3249  if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_NODRAW) {
3250  if (strstr(pb->brush_faces->texdef.name, "nodraw")) {
3251  return true;
3252  }
3253  }
3254 
3255 
3256  if (strstr(pb->brush_faces->texdef.name, "skip")) {
3257  return true;
3258  }
3259 
3260  if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_DYNAMICS) {
3261  if (pb->modelHandle > 0) {
3262  idRenderModel *model = pb->modelHandle;
3263  if ( dynamic_cast<idRenderModelLiquid*>(model) ) {
3264  return true;
3265  }
3266  }
3267  }
3268 
3269  if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CURVES) {
3270  if (pb->pPatch) {
3271  return true;
3272  }
3273  }
3274 
3275  if (pb->owner == world_entity) {
3276  if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD) {
3277  return true;
3278  }
3279 
3280  return false;
3281  }
3282  else {
3283  if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT ) {
3284  return ( idStr::Cmpn( pb->owner->eclass->name, "func_static", 10 ) != 0 );
3285  }
3286  }
3287 
3288  if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS && pb->owner->eclass->nShowFlags & ECLASS_LIGHT ) {
3289  return true;
3290  }
3291 
3292  if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_COMBATNODES && pb->owner->eclass->nShowFlags & ECLASS_COMBATNODE ) {
3293  return true;
3294  }
3295 
3296  if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS && pb->owner->eclass->nShowFlags & ECLASS_PATH) {
3297  return true;
3298  }
3299 
3300  if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_MODELS && ( pb->owner->eclass->entityModel != NULL || pb->modelHandle > 0 ) ) {
3301  return true;
3302  }
3303 
3304  return false;
3305 }
3306 
3307 /*
3308  =======================================================================================================================
3309  PATH LINES £ DrawPathLines Draws connections between entities. Needs to consider all entities, not just ones on screen, because the lines can be visible when neither end is. Called for both camera view and xy view. ======================================================================================================================= */ void DrawPathLines(void) { int i, k; idVec3 mid, mid1; entity_t *se, *te; brush_t *sb, *tb; const char *psz; idVec3 dir, s1, s2; float len, f; int arrows; int num_entities; const char *ent_target[MAX_MAP_ENTITIES]; entity_t *ent_entity[MAX_MAP_ENTITIES]; if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS) { return; } num_entities = 0; for (te = entities.next; te != &entities && num_entities != MAX_MAP_ENTITIES; te = te->next) { for (int i = 0; i < 2048; i++) { if (i == 0) { ent_target[num_entities] = ValueForKey(te, "target"); } else { ent_target[num_entities] = ValueForKey(te, va("target%i", i)); } if (ent_target[num_entities][0]) { ent_entity[num_entities] = te; num_entities++; } else if (i > 16) { break; } } } for (se = entities.next; se != &entities; se = se->next) { psz = ValueForKey(se, "name"); if (psz == NULL || psz[0] == '\0') { continue; } sb = se->brushes.onext; if (sb == &se->brushes) { continue; } for (k = 0; k < num_entities; k++) { if (strcmp(ent_target[k], psz)) { continue; } te = ent_entity[k]; tb = te->brushes.onext; if (tb == &te->brushes) { continue; } mid = sb->owner->origin; mid1 = tb->owner->origin; VectorSubtract(mid1, mid, dir); len = dir.Normalize(); s1[0] = -dir[1] * 8 + dir[0] * 8; s2[0] = dir[1] * 8 + dir[0] * 8; s1[1] = dir[0] * 8 + dir[1] * 8; s2[1] = -dir[0] * 8 + dir[1] * 8; qglColor3f(se->eclass->color[0], se->eclass->color[1], se->eclass->color[2]); qglBegin(GL_LINES); qglVertex3fv(mid.ToFloatPtr()); qglVertex3fv(mid1.ToFloatPtr()); arrows = (int)(len / 256) + 1; for (i = 0; i < arrows; i++) { f = len * (i + 0.5) / arrows; mid1 = mid + (f * dir); qglVertex3fv(mid1.ToFloatPtr()); qglVertex3f(mid1[0] + s1[0], mid1[1] + s1[1], mid1[2]); qglVertex3fv(mid1.ToFloatPtr()); qglVertex3f(mid1[0] + s2[0], mid1[1] + s2[1], mid1[2]); } qglEnd(); } } return; } // // ======================================================================================================================= // can be greatly simplified but per usual i am in a hurry which is not an excuse, just a fact // ======================================================================================================================= // void CXYWnd::PaintSizeInfo(int nDim1, int nDim2, idVec3 vMinBounds, idVec3 vMaxBounds) { idVec3 vSize; VectorSubtract(vMaxBounds, vMinBounds, vSize); qglColor3f ( g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] * .65, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] * .65, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] * .65 ); if (m_nViewType == XY) { qglBegin(GL_LINES); qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale, 0.0f); qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale, 0.0f); qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, vMinBounds[nDim2], 0.0f); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2], 0.0f); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2], 0.0f); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2], 0.0f); qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, vMaxBounds[nDim2], 0.0f); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2], 0.0f); qglEnd(); qglRasterPos3f(Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), vMinBounds[nDim2] - 20.0 / m_fScale, 0.0f); g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); qglRasterPos3f(vMaxBounds[nDim1] + 16.0 / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2]), 0.0f); g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); qglRasterPos3f(vMinBounds[nDim1] + 4, vMaxBounds[nDim2] + 8 / m_fScale, 0.0f); g_strDim.Format(g_pOrgStrings[0], vMinBounds[nDim1], vMaxBounds[nDim2]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); } else if (m_nViewType == XZ) { qglBegin(GL_LINES); qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 6.0f / m_fScale); qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 6.0f / m_fScale); qglVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, 0, vMinBounds[nDim2]); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMinBounds[nDim2]); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMinBounds[nDim2]); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMaxBounds[nDim2]); qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, 0, vMaxBounds[nDim2]); qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMaxBounds[nDim2]); qglEnd(); qglRasterPos3f(Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), 0, vMinBounds[nDim2] - 20.0 / m_fScale); g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); qglRasterPos3f(vMaxBounds[nDim1] + 16.0 / m_fScale, 0, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2])); g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); qglRasterPos3f(vMinBounds[nDim1] + 4, 0, vMaxBounds[nDim2] + 8 / m_fScale); g_strDim.Format(g_pOrgStrings[1], vMinBounds[nDim1], vMaxBounds[nDim2]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); } else { qglBegin(GL_LINES); qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale); qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale); qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); qglVertex3f(0, vMaxBounds[nDim1] + 6.0f / m_fScale, vMinBounds[nDim2]); qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2]); qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2]); qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2]); qglVertex3f(0, vMaxBounds[nDim1] + 6.0f / m_fScale, vMaxBounds[nDim2]); qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2]); qglEnd(); qglRasterPos3f(0, Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), vMinBounds[nDim2] - 20.0 / m_fScale); g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); qglRasterPos3f(0, vMaxBounds[nDim1] + 16.0 / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2])); g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); qglRasterPos3f(0, vMinBounds[nDim1] + 4.0, vMaxBounds[nDim2] + 8 / m_fScale); g_strDim.Format(g_pOrgStrings[2], vMinBounds[nDim1], vMaxBounds[nDim2]); qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); } } /* XY_Draw */ long g_lCount = 0; long g_lTotal = 0; extern void DrawBrushEntityName(brush_t *b); /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::XY_Draw() { brush_t *brush; float w, h; entity_t *e; idVec3 mins, maxs; int drawn, culled; int i; if (!active_brushes.next) { return; // not valid yet } // clear m_bDirty = false; GL_State( GLS_DEFAULT ); qglViewport(0, 0, m_nWidth, m_nHeight); qglScissor(0, 0, m_nWidth, m_nHeight); qglClearColor ( g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0], g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1], g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2], 0 ); qglDisable(GL_DEPTH_TEST); qglDisable(GL_CULL_FACE); qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // set up viewpoint qglMatrixMode(GL_PROJECTION); qglLoadIdentity(); w = m_nWidth / 2 / m_fScale; h = m_nHeight / 2 / m_fScale; int nDim1 = (m_nViewType == YZ) ? 1 : 0; int nDim2 = (m_nViewType == XY) ? 1 : 2; mins[0] = m_vOrigin[nDim1] - w; maxs[0] = m_vOrigin[nDim1] + w; mins[1] = m_vOrigin[nDim2] - h; maxs[1] = m_vOrigin[nDim2] + h; idBounds viewBounds( mins, maxs ); viewBounds[0].z = -99999; viewBounds[1].z = 99999; qglOrtho(mins[0], maxs[0], mins[1], maxs[1], MIN_WORLD_COORD, MAX_WORLD_COORD); // draw stuff globalImages->BindNull(); // now draw the grid qglLineWidth(0.25); XY_DrawGrid(); qglLineWidth(0.5); drawn = culled = 0; if (m_nViewType != XY) { qglPushMatrix(); if (m_nViewType == YZ) { qglRotatef(-90, 0, 1, 0); // put Z going up } // else qglRotatef(-90, 1, 0, 0); // put Z going up } e = world_entity; for ( brush = active_brushes.next; brush != &active_brushes; brush = brush->next ) { if ( brush->forceVisibile || ( brush->owner->eclass->nShowFlags & ( ECLASS_LIGHT | ECLASS_PROJECTEDLIGHT ) ) ) { } else if ( brush->mins[nDim1] > maxs[0] || brush->mins[nDim2] > maxs[1] || brush->maxs[nDim1] < mins[0] || brush->maxs[nDim2] < mins[1] ) { culled++; continue; // off screen } if ( FilterBrush(brush) ) { continue; } drawn++; if (brush->owner != e && brush->owner) { qglColor3fv(brush->owner->eclass->color.ToFloatPtr()); } else { qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES].ToFloatPtr()); } Brush_DrawXY( brush, m_nViewType ); } DrawPathLines(); // draw pointfile if (g_qeglobals.d_pointfile_display_list) { qglCallList(g_qeglobals.d_pointfile_display_list); } if (!(m_nViewType == XY)) { qglPopMatrix(); } // draw block grid if (g_qeglobals.show_blocks) { XY_DrawBlockGrid(); } // now draw selected brushes if (m_nViewType != XY) { qglPushMatrix(); if (m_nViewType == YZ) { qglRotatef(-90, 0, 1, 0); // put Z going up } // else qglRotatef(-90, 1, 0, 0); // put Z going up } qglPushMatrix(); qglTranslatef ( g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2] ); if (RotateMode()) { qglColor3f( 0.8f, 0.1f, 0.9f ); } else if (ScaleMode()) { qglColor3f( 0.1f, 0.8f, 0.1f ); } else { qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].ToFloatPtr()); } if (g_PrefsDlg.m_bNoStipple == FALSE) { qglEnable(GL_LINE_STIPPLE); qglLineStipple(3, 0xaaaa); } qglLineWidth(1); idVec3 vMinBounds; idVec3 vMaxBounds; vMinBounds[0] = vMinBounds[1] = vMinBounds[2] = 999999.9f; vMaxBounds[0] = vMaxBounds[1] = vMaxBounds[2] = -999999.9f; int nSaveDrawn = drawn; bool bFixedSize = false; for (brush = selected_brushes.next; brush != &selected_brushes; brush = brush->next) { drawn++; Brush_DrawXY(brush, m_nViewType, true); if (!bFixedSize) { if (brush->owner->eclass->fixedsize) { bFixedSize = true; } if (g_PrefsDlg.m_bSizePaint) { for (i = 0; i < 3; i++) { if (brush->mins[i] < vMinBounds[i]) { vMinBounds[i] = brush->mins[i]; } if (brush->maxs[i] > vMaxBounds[i]) { vMaxBounds[i] = brush->maxs[i]; } } } } } if (g_PrefsDlg.m_bNoStipple == FALSE) { qglDisable(GL_LINE_STIPPLE); } qglLineWidth(0.5); if (!bFixedSize && !RotateMode() && !ScaleMode() && drawn - nSaveDrawn > 0 && g_PrefsDlg.m_bSizePaint) { PaintSizeInfo(nDim1, nDim2, vMinBounds, vMaxBounds); } // edge / vertex flags if (g_qeglobals.d_select_mode == sel_vertex) { qglPointSize(4); qglColor3f(0, 1, 0); qglBegin(GL_POINTS); for (i = 0; i < g_qeglobals.d_numpoints; i++) { qglVertex3fv(g_qeglobals.d_points[i].ToFloatPtr()); } qglEnd(); qglPointSize(1); } else if (g_qeglobals.d_select_mode == sel_edge) { float *v1, *v2; qglPointSize(4); qglColor3f(0, 0, 1); qglBegin(GL_POINTS); for (i = 0; i < g_qeglobals.d_numedges; i++) { v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1].ToFloatPtr(); v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2].ToFloatPtr(); qglVertex3f((v1[0] + v2[0]) * 0.5, (v1[1] + v2[1]) * 0.5, (v1[2] + v2[2]) * 0.5); } qglEnd(); qglPointSize(1); } g_splineList->draw (static_cast<bool>(g_qeglobals.d_select_mode == sel_editpoint || g_qeglobals.d_select_mode == sel_addpoint)); if (g_pParentWnd->GetNurbMode() && g_pParentWnd->GetNurb()->GetNumValues()) { int maxage = g_pParentWnd->GetNurb()->GetNumValues(); int time = 0; qglColor3f(0, 0, 1); qglPointSize(1); qglBegin(GL_POINTS); g_pParentWnd->GetNurb()->SetOrder(3); for (i = 0; i < 100; i++) { idVec2 v = g_pParentWnd->GetNurb()->GetCurrentValue(time); qglVertex3f(v.x, v.y, 0.0f); time += 10; } qglEnd(); qglPointSize(4); qglColor3f(0, 0, 1); qglBegin(GL_POINTS); for (i = 0; i < maxage; i++) { idVec2 v = g_pParentWnd->GetNurb()->GetValue(i); qglVertex3f(v.x, v.y, 0.0f); } qglEnd(); qglPointSize(1); } qglPopMatrix(); qglTranslatef ( -g_qeglobals.d_select_translate[0], -g_qeglobals.d_select_translate[1], -g_qeglobals.d_select_translate[2] ); if (!(m_nViewType == XY)) { qglPopMatrix(); } // area selection hack if (g_qeglobals.d_select_mode == sel_area) { qglEnable(GL_BLEND); qglPolygonMode ( GL_FRONT_AND_BACK , GL_FILL ); qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglColor4f(0.0, 0.0, 1.0, 0.25); qglRectf ( g_qeglobals.d_vAreaTL[nDim1], g_qeglobals.d_vAreaTL[nDim2], g_qeglobals.d_vAreaBR[nDim1], g_qeglobals.d_vAreaBR[nDim2] ); qglDisable(GL_BLEND); qglPolygonMode ( GL_FRONT_AND_BACK , GL_LINE ); qglColor3f(1.0f, 1.0f, 1.0f); qglRectf ( g_qeglobals.d_vAreaTL[nDim1], g_qeglobals.d_vAreaTL[nDim2], g_qeglobals.d_vAreaBR[nDim1], g_qeglobals.d_vAreaBR[nDim2] ); } // now draw camera point DrawCameraIcon(); DrawZIcon(); if (RotateMode()) { DrawRotateIcon(); } /// Draw a "precision crosshair" if enabled if( m_precisionCrosshairMode != PRECISION_CROSSHAIR_NONE ) DrawPrecisionCrosshair(); qglFlush(); // QE_CheckOpenGLForErrors(); } /* ======================================================================================================================= ======================================================================================================================= */ idVec3 &CXYWnd::GetOrigin() { return m_vOrigin; } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::SetOrigin(idVec3 org) { m_vOrigin[0] = org[0]; m_vOrigin[1] = org[1]; m_vOrigin[2] = org[2]; } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); CRect rect; GetClientRect(rect); m_nWidth = rect.Width(); m_nHeight = rect.Height(); InvalidateRect(NULL, false); } brush_t hold_brushes; /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::Clip() { if (ClipMode()) { hold_brushes.next = &hold_brushes; ProduceSplitLists(); // brush_t* pList = (g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits; brush_t *pList; if (g_PrefsDlg.m_bSwitchClip) { pList = ((m_nViewType == XZ) ? g_bSwitch : !g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits; } else { pList = ((m_nViewType == XZ) ? !g_bSwitch : g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits; } if (pList->next != pList) { Brush_CopyList(pList, &hold_brushes); CleanList(&g_brFrontSplits); CleanList(&g_brBackSplits); Select_Delete(); Brush_CopyList(&hold_brushes, &selected_brushes); if (RogueClipMode()) { RetainClipMode(false); } else { RetainClipMode(true); } Sys_UpdateWindows(W_ALL); } } else if (PathMode()) { FinishSmartCreation(); if (g_pPathFunc) { g_pPathFunc(true, g_nPathCount); } g_pPathFunc = NULL; g_nPathCount = 0; g_bPathMode = false; } } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::SplitClip() { ProduceSplitLists(); if ((g_brFrontSplits.next != &g_brFrontSplits) && (g_brBackSplits.next != &g_brBackSplits)) { Select_Delete(); Brush_CopyList(&g_brFrontSplits, &selected_brushes); Brush_CopyList(&g_brBackSplits, &selected_brushes); CleanList(&g_brFrontSplits); CleanList(&g_brBackSplits); if (RogueClipMode()) { RetainClipMode(false); } else { RetainClipMode(true); } } } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::FlipClip() { g_bSwitch = !g_bSwitch; Sys_UpdateWindows(XY | W_CAMERA_IFON); } // // ======================================================================================================================= // makes sure the selected brush or camera is in view // ======================================================================================================================= // void CXYWnd::PositionView() { int nDim1 = (m_nViewType == YZ) ? 1 : 0; int nDim2 = (m_nViewType == XY) ? 1 : 2; brush_t *b = selected_brushes.next; if (b && b->next != b) { m_vOrigin[nDim1] = b->mins[nDim1]; m_vOrigin[nDim2] = b->mins[nDim2]; } else { m_vOrigin[nDim1] = g_pParentWnd->GetCamera()->Camera().origin[nDim1]; m_vOrigin[nDim2] = g_pParentWnd->GetCamera()->Camera().origin[nDim2]; } } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::VectorCopyXY(const idVec3 &in, idVec3 &out) { if (m_nViewType == XY) { out[0] = in[0]; out[1] = in[1]; } else if (m_nViewType == XZ) { out[0] = in[0]; out[2] = in[2]; } else { out[1] = in[1]; out[2] = in[2]; } } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnDestroy() { CWnd::OnDestroy(); // delete this; } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::SetViewType(int n) { m_nViewType = n; char *p = "YZ Side"; if (m_nViewType == XY) { p = "XY Top"; } else if (m_nViewType == XZ) { p = "XZ Front"; } SetWindowText(p); }; /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::Redraw(unsigned int nBits) { m_nUpdateBits = nBits; RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); m_nUpdateBits = W_XY; } /* ======================================================================================================================= ======================================================================================================================= */ bool CXYWnd::RotateMode() { return g_bRotateMode; } /* ======================================================================================================================= ======================================================================================================================= */ bool CXYWnd::ScaleMode() { return g_bScaleMode; } /* ======================================================================================================================= ======================================================================================================================= */ extern bool Select_OnlyModelsSelected(); bool CXYWnd::SetRotateMode(bool bMode) { if (bMode && selected_brushes.next != &selected_brushes) { g_bRotateMode = true; if (Select_OnlyModelsSelected()) { Select_GetTrueMid(g_vRotateOrigin); } else { Select_GetMid(g_vRotateOrigin); } g_vRotation.Zero(); Select_InitializeRotation(); } else { if (bMode) { Sys_Status("Need a brush selected to turn on Mouse Rotation mode\n"); } g_bRotateMode = false; Select_FinalizeRotation(); } RedrawWindow(); return g_bRotateMode; } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::SetScaleMode(bool bMode) { g_bScaleMode = bMode; RedrawWindow(); } // // ======================================================================================================================= // xy - z xz - y yz - x // ======================================================================================================================= // void CXYWnd::OnSelectMouserotate() { // TODO: Add your command handler code here } /* ======================================================================================================================= ======================================================================================================================= */ void CleanCopyEntities() { entity_t *pe = g_enClipboard.next; while (pe != NULL && pe != &g_enClipboard) { entity_t *next = pe->next; pe->epairs.Clear(); Entity_Free(pe); pe = next; } g_enClipboard.next = g_enClipboard.prev = &g_enClipboard; } /* ======================================================================================================================= ======================================================================================================================= */ entity_t *Entity_CopyClone(entity_t *e) { entity_t *n; n = Entity_New(); n->brushes.onext = n->brushes.oprev = &n->brushes; n->eclass = e->eclass; n->rotation = e->rotation; // add the entity to the entity list n->next = g_enClipboard.next; g_enClipboard.next = n; n->next->prev = n; n->prev = &g_enClipboard; n->epairs = e->epairs; return n; } /* ======================================================================================================================= ======================================================================================================================= */ bool OnList(entity_t *pFind, CPtrArray *pList) { int nSize = pList->GetSize(); while (nSize-- > 0) { entity_t *pEntity = reinterpret_cast < entity_t * > (pList->GetAt(nSize)); if (pEntity == pFind) { return true; } } return false; } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::Copy() { #if 1 CWaitCursor WaitCursor; g_Clipboard.SetLength(0); g_PatchClipboard.SetLength(0); Map_SaveSelected(&g_Clipboard, &g_PatchClipboard); bool bClipped = false; UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings"); if (nClipboard > 0) { if (OpenClipboard()) { ::EmptyClipboard(); long lSize = g_Clipboard.GetLength(); HANDLE h = ::GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, lSize + sizeof (long)); if (h != NULL) { unsigned char *cp = reinterpret_cast < unsigned char * > (::GlobalLock(h)); memcpy(cp, &lSize, sizeof (long)); cp += sizeof (long); g_Clipboard.SeekToBegin(); g_Clipboard.Read(cp, lSize); ::GlobalUnlock(h); ::SetClipboardData(nClipboard, h); ::CloseClipboard(); bClipped = true; } } } if (!bClipped) { common->Printf("Unable to register Windows clipboard formats, copy/paste between editors will not be possible"); } /* * CString strOut; ::GetTempPath(1024, strOut.GetBuffer(1024)); * strOut.ReleaseBuffer(); AddSlash(strOut); strOut += "RadiantClipboard.$$$"; * Map_SaveSelected(strOut.GetBuffer(0)); */ #else CPtrArray holdArray; CleanList(&g_brClipboard); CleanCopyEntities(); for (brush_t * pBrush = selected_brushes.next; pBrush != NULL && pBrush != &selected_brushes; pBrush = pBrush->next) { if (pBrush->owner == world_entity) { brush_t *pClone = Brush_Clone(pBrush); pClone->owner = NULL; Brush_AddToList(pClone, &g_brClipboard); } else { if (!OnList(pBrush->owner, &holdArray)) { entity_t *e = pBrush->owner; holdArray.Add(reinterpret_cast < void * > (e)); entity_t *pEClone = Entity_CopyClone(e); for (brush_t * pEB = e->brushes.onext; pEB != &e->brushes; pEB = pEB->onext) { brush_t *pClone = Brush_Clone(pEB); // Brush_AddToList (pClone, &g_brClipboard); Entity_LinkBrush(pEClone, pClone); Brush_Build(pClone); } } } } #endif } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::Undo() { /* * if (g_brUndo.next != &g_brUndo) { g_bScreenUpdates = false; Select_Delete(); * for (brush_t* pBrush = g_brUndo.next ; pBrush != NULL && pBrush != &g_brUndo ; * pBrush=pBrush->next) { brush_t* pClone = Brush_Clone(pBrush); Brush_AddToList * (pClone, &active_brushes); Entity_LinkBrush (pBrush->pUndoOwner, pClone); * Brush_Build(pClone); Select_Brush(pClone); } CleanList(&g_brUndo); * g_bScreenUpdates = true; Sys_UpdateWindows(W_ALL); } else common->Printf("Nothing * to undo.../n"); */ } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::UndoClear() { /* CleanList(&g_brUndo); */ } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::UndoCopy() { /* * CleanList(&g_brUndo); for (brush_t* pBrush = selected_brushes.next ; pBrush != * NULL && pBrush != &selected_brushes ; pBrush=pBrush->next) { brush_t* pClone = * Brush_Clone(pBrush); pClone->pUndoOwner = pBrush->owner; Brush_AddToList * (pClone, &g_brUndo); } */ } /* ======================================================================================================================= ======================================================================================================================= */ bool CXYWnd::UndoAvailable() { return(g_brUndo.next != &g_brUndo); } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::Paste() { #if 1 CWaitCursor WaitCursor; bool bPasted = false; UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings"); if (nClipboard > 0 && OpenClipboard() && ::IsClipboardFormatAvailable(nClipboard)) { HANDLE h = ::GetClipboardData(nClipboard); if (h) { g_Clipboard.SetLength(0); unsigned char *cp = reinterpret_cast < unsigned char * > (::GlobalLock(h)); long lSize = 0; memcpy(&lSize, cp, sizeof (long)); cp += sizeof (long); g_Clipboard.Write(cp, lSize); } ::GlobalUnlock(h); ::CloseClipboard(); } if (g_Clipboard.GetLength() > 0) { g_Clipboard.SeekToBegin(); int nLen = g_Clipboard.GetLength(); char *pBuffer = new char[nLen + 1]; memset(pBuffer, 0, sizeof(pBuffer)); g_Clipboard.Read(pBuffer, nLen); pBuffer[nLen] = '\0'; Map_ImportBuffer(pBuffer, !(GetAsyncKeyState(VK_SHIFT) & 0x8000)); delete[] pBuffer; } #if 0 if (g_PatchClipboard.GetLength() > 0) { g_PatchClipboard.SeekToBegin(); int nLen = g_PatchClipboard.GetLength(); char *pBuffer = new char[nLen + 1]; g_PatchClipboard.Read(pBuffer, nLen); pBuffer[nLen] = '\0'; Patch_ReadBuffer(pBuffer, true); delete[] pBuffer; } #endif #else if (g_brClipboard.next != &g_brClipboard || g_enClipboard.next != &g_enClipboard) { Select_Deselect(); for (brush_t * pBrush = g_brClipboard.next; pBrush != NULL && pBrush != &g_brClipboard; pBrush = pBrush->next) { brush_t *pClone = Brush_Clone(pBrush); // pClone->owner = pBrush->owner; if (pClone->owner == NULL) { Entity_LinkBrush(world_entity, pClone); } Brush_AddToList(pClone, &selected_brushes); Brush_Build(pClone); } for ( entity_t * pEntity = g_enClipboard.next; pEntity != NULL && pEntity != &g_enClipboard; pEntity = pEntity->next ) { entity_t *pEClone = Entity_Clone(pEntity); for (brush_t * pEB = pEntity->brushes.onext; pEB != &pEntity->brushes; pEB = pEB->onext) { brush_t *pClone = Brush_Clone(pEB); Brush_AddToList(pClone, &selected_brushes); Entity_LinkBrush(pEClone, pClone); Brush_Build(pClone); if (pClone->owner && pClone->owner != world_entity) { g_Inspectors->UpdateEntitySel(pClone->owner->eclass); } } } Sys_UpdateWindows(W_ALL); } else { common->Printf("Nothing to paste.../n"); } #endif } /* ======================================================================================================================= ======================================================================================================================= */ idVec3 &CXYWnd::Rotation() { return g_vRotation; } /* ======================================================================================================================= ======================================================================================================================= */ idVec3 &CXYWnd::RotateOrigin() { return g_vRotateOrigin; } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnTimer(UINT nIDEvent) { if (nIDEvent == 100) { int nDim1 = (m_nViewType == YZ) ? 1 : 0; int nDim2 = (m_nViewType == XY) ? 1 : 2; m_vOrigin[nDim1] += m_ptDragAdj.x / m_fScale; m_vOrigin[nDim2] -= m_ptDragAdj.y / m_fScale; Sys_UpdateWindows(W_XY | W_CAMERA); // int nH = (m_ptDrag.y == 0) ? -1 : m_ptDrag.y; m_ptDrag += m_ptDragAdj; m_ptDragTotal += m_ptDragAdj; XY_MouseMoved(m_ptDrag.x, m_nHeight - 1 - m_ptDrag.y, m_nScrollFlags); // // m_vOrigin[nDim1] -= m_ptDrag.x / m_fScale; m_vOrigin[nDim1] -= m_ptDrag.x / // m_fScale; // } } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false); // CWnd::OnKeyUp(nChar, nRepCnt, nFlags); } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR *lpncsp) { CWnd::OnNcCalcSize(bCalcValidRects, lpncsp); } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnKillFocus(CWnd *pNewWnd) { CWnd::OnKillFocus(pNewWnd); SendMessage(WM_NCACTIVATE, FALSE, 0); } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnSetFocus(CWnd *pOldWnd) { CWnd::OnSetFocus(pOldWnd); SendMessage(WM_NCACTIVATE, TRUE, 0); } /* ======================================================================================================================= ======================================================================================================================= */ void CXYWnd::OnClose() { CWnd::OnClose(); } // // ======================================================================================================================= // should be static as should be the rotate scale stuff // ======================================================================================================================= // bool CXYWnd::AreaSelectOK() { return RotateMode() ? false : ScaleMode() ? false : true; } /* ======================================================================================================================= ======================================================================================================================= */ BOOL CXYWnd::OnEraseBkgnd(CDC *pDC) { return TRUE; // return CWnd::OnEraseBkgnd(pDC); } extern void AssignModel(); void CXYWnd::OnDropNewmodel() { CPoint point; GetCursorPos(&point); CreateRightClickEntity(this, m_ptDown.x, m_ptDown.y, "func_static"); g_Inspectors->SetMode(W_ENTITY); g_Inspectors->AssignModel(); } BOOL CXYWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { if (zDelta > 0) { g_pParentWnd->OnViewZoomin(); } else { g_pParentWnd->OnViewZoomout(); } return TRUE; } //--------------------------------------------------------------------------- // CyclePrecisionCrosshairMode // // Called when the user presses the "cycle precision cursor mode" key. // Cycles the precision cursor among the following three modes: // PRECISION_CURSOR_NONE // PRECISION_CURSOR_SNAP // PRECISION_CURSOR_FREE //--------------------------------------------------------------------------- void CXYWnd::CyclePrecisionCrosshairMode( void ) { common->Printf("TODO: Make DrawPrecisionCrosshair work..." ); /// Cycle to next mode, wrap if necessary m_precisionCrosshairMode ++; if( m_precisionCrosshairMode >= PRECISION_CROSSHAIR_MAX ) m_precisionCrosshairMode = PRECISION_CROSSHAIR_NONE; Sys_UpdateWindows( W_XY ); } //--------------------------------------------------------------------------- // DrawPrecisionCrosshair // // Draws a precision crosshair beneath the cursor in the 2d (XY) view, // depending on one of the following values for m_precisionCrosshairMode: // // PRECISION_CROSSHAIR_NONE No crosshair is drawn. Do not force refresh of XY view. // PRECISION_CROSSHAIR_SNAP Crosshair snaps to grid size. Force refresh of XY view. // PRECISION_CROSSHAIR_FREE Crosshair does not snap to grid. Force refresh of XY view. //--------------------------------------------------------------------------- void CXYWnd::DrawPrecisionCrosshair( void ) { // FIXME: m_mouseX, m_mouseY, m_axisHoriz, m_axisVert, etc... are never set return; idVec3 mouse3dPos (0.0f, 0.0f, 0.0f); float x, y; idVec4 crossEndColor (1.0f, 0.0f, 1.0f, 1.0f); // the RGBA color of the precision crosshair at its ends idVec4 crossMidColor; // the RGBA color of the precision crosshair at the crossing point /// Transform the mouse coordinates into axis-correct map-coordinates if( m_precisionCrosshairMode == PRECISION_CROSSHAIR_SNAP ) SnapToPoint( m_mouseX, m_mouseY, mouse3dPos ); else XY_ToPoint( m_mouseX, m_mouseY, mouse3dPos ); x = mouse3dPos[ m_axisHoriz ]; y = mouse3dPos[ m_axisVert ]; /// Use the color specified by the user crossEndColor[0] = g_qeglobals.d_savedinfo.colors[ COLOR_PRECISION_CROSSHAIR ][0]; crossEndColor[1] = g_qeglobals.d_savedinfo.colors[ COLOR_PRECISION_CROSSHAIR ][1]; crossEndColor[2] = g_qeglobals.d_savedinfo.colors[ COLOR_PRECISION_CROSSHAIR ][2]; crossEndColor[3] = 1.0f; crossMidColor = crossEndColor; if( m_precisionCrosshairMode == PRECISION_CROSSHAIR_FREE ) crossMidColor[ 3 ] = 0.0f; // intersection-color is 100% transparent (alpha = 0.0f) /// Set up OpenGL states (for drawing smooth-shaded plain-colored lines) qglEnable( GL_BLEND ); qglDisable( GL_TEXTURE_2D ); qglShadeModel( GL_SMOOTH ); qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); /// Draw a fullscreen-sized crosshair over the cursor qglBegin( GL_LINES ); { /// Draw the horizontal precision line (in two pieces) qglColor4fv( crossEndColor.ToFloatPtr() ); qglVertex2f( m_mcLeft, y ); qglColor4fv( crossMidColor.ToFloatPtr() ); qglVertex2f( x, y ); qglColor4fv( crossMidColor.ToFloatPtr() ); qglVertex2f( x, y ); qglColor4fv( crossEndColor.ToFloatPtr() ); qglVertex2f( m_mcRight, y ); /// Draw the vertical precision line (in two pieces) qglColor4fv( crossEndColor.ToFloatPtr() ); qglVertex2f( x, m_mcTop ); qglColor4fv( crossMidColor.ToFloatPtr() ); qglVertex2f( x, y ); qglColor4fv( crossMidColor.ToFloatPtr() ); qglVertex2f( x, y ); qglColor4fv( crossEndColor.ToFloatPtr() ); qglVertex2f( x, m_mcBottom ); } qglEnd(); // GL_LINES // Radiant was in opaque, flat-shaded mode by default; restore this to prevent possible slowdown qglShadeModel( GL_FLAT ); qglDisable( GL_BLEND ); }
3310  DrawPathLines Draws connections between entities. Needs to consider all entities, not just ones on screen, because
3311  the lines can be visible when neither end is. Called for both camera view and xy view.
3312  =======================================================================================================================
3313  */
3314 void DrawPathLines(void) {
3315  int i, k;
3316  idVec3 mid, mid1;
3317  entity_t *se, *te;
3318  brush_t *sb, *tb;
3319  const char *psz;
3320  idVec3 dir, s1, s2;
3321  float len, f;
3322  int arrows;
3323  int num_entities;
3324  const char *ent_target[MAX_MAP_ENTITIES];
3325  entity_t *ent_entity[MAX_MAP_ENTITIES];
3326 
3327  if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS) {
3328  return;
3329  }
3330 
3331  num_entities = 0;
3332  for (te = entities.next; te != &entities && num_entities != MAX_MAP_ENTITIES; te = te->next) {
3333  for (int i = 0; i < 2048; i++) {
3334  if (i == 0) {
3335  ent_target[num_entities] = ValueForKey(te, "target");
3336  } else {
3337  ent_target[num_entities] = ValueForKey(te, va("target%i", i));
3338  }
3339  if (ent_target[num_entities][0]) {
3340  ent_entity[num_entities] = te;
3341  num_entities++;
3342  } else if (i > 16) {
3343  break;
3344  }
3345  }
3346  }
3347 
3348  for (se = entities.next; se != &entities; se = se->next) {
3349  psz = ValueForKey(se, "name");
3350 
3351  if (psz == NULL || psz[0] == '\0') {
3352  continue;
3353  }
3354 
3355  sb = se->brushes.onext;
3356  if (sb == &se->brushes) {
3357  continue;
3358  }
3359 
3360  for (k = 0; k < num_entities; k++) {
3361  if (strcmp(ent_target[k], psz)) {
3362  continue;
3363  }
3364 
3365  te = ent_entity[k];
3366  tb = te->brushes.onext;
3367  if (tb == &te->brushes) {
3368  continue;
3369  }
3370 
3371  mid = sb->owner->origin;
3372  mid1 = tb->owner->origin;
3373 
3374  VectorSubtract(mid1, mid, dir);
3375  len = dir.Normalize();
3376  s1[0] = -dir[1] * 8 + dir[0] * 8;
3377  s2[0] = dir[1] * 8 + dir[0] * 8;
3378  s1[1] = dir[0] * 8 + dir[1] * 8;
3379  s2[1] = -dir[0] * 8 + dir[1] * 8;
3380 
3381  qglColor3f(se->eclass->color[0], se->eclass->color[1], se->eclass->color[2]);
3382 
3383  qglBegin(GL_LINES);
3384  qglVertex3fv(mid.ToFloatPtr());
3385  qglVertex3fv(mid1.ToFloatPtr());
3386 
3387  arrows = (int)(len / 256) + 1;
3388 
3389  for (i = 0; i < arrows; i++) {
3390  f = len * (i + 0.5) / arrows;
3391 
3392  mid1 = mid + (f * dir);
3393 
3394  qglVertex3fv(mid1.ToFloatPtr());
3395  qglVertex3f(mid1[0] + s1[0], mid1[1] + s1[1], mid1[2]);
3396  qglVertex3fv(mid1.ToFloatPtr());
3397  qglVertex3f(mid1[0] + s2[0], mid1[1] + s2[1], mid1[2]);
3398  }
3399 
3400  qglEnd();
3401  }
3402  }
3403 
3404  return;
3405 }
3406 
3407 //
3408 // =======================================================================================================================
3409 // can be greatly simplified but per usual i am in a hurry which is not an excuse, just a fact
3410 // =======================================================================================================================
3411 //
3412 void CXYWnd::PaintSizeInfo(int nDim1, int nDim2, idVec3 vMinBounds, idVec3 vMaxBounds) {
3413  idVec3 vSize;
3414  VectorSubtract(vMaxBounds, vMinBounds, vSize);
3415 
3416  qglColor3f
3417  (
3418  g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] * .65,
3419  g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] * .65,
3420  g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] * .65
3421  );
3422 
3423  if (m_nViewType == XY) {
3424  qglBegin(GL_LINES);
3425 
3426  qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale, 0.0f);
3427  qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f);
3428 
3429  qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f);
3430  qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f);
3431 
3432  qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale, 0.0f);
3433  qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f);
3434 
3435  qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, vMinBounds[nDim2], 0.0f);
3436  qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2], 0.0f);
3437 
3438  qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2], 0.0f);
3439  qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2], 0.0f);
3440 
3441  qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, vMaxBounds[nDim2], 0.0f);
3442  qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2], 0.0f);
3443 
3444  qglEnd();
3445 
3446  qglRasterPos3f(Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), vMinBounds[nDim2] - 20.0 / m_fScale, 0.0f);
3447  g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]);
3448  qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
3449 
3450  qglRasterPos3f(vMaxBounds[nDim1] + 16.0 / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2]), 0.0f);
3451  g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]);
3452  qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
3453 
3454  qglRasterPos3f(vMinBounds[nDim1] + 4, vMaxBounds[nDim2] + 8 / m_fScale, 0.0f);
3455  g_strDim.Format(g_pOrgStrings[0], vMinBounds[nDim1], vMaxBounds[nDim2]);
3456  qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
3457  }
3458  else if (m_nViewType == XZ) {
3459  qglBegin(GL_LINES);
3460 
3461  qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 6.0f / m_fScale);
3462  qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale);
3463 
3464  qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale);
3465  qglVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale);
3466 
3467  qglVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 6.0f / m_fScale);
3468  qglVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale);
3469 
3470  qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, 0, vMinBounds[nDim2]);
3471  qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMinBounds[nDim2]);
3472 
3473  qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMinBounds[nDim2]);
3474  qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMaxBounds[nDim2]);
3475 
3476  qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, 0, vMaxBounds[nDim2]);
3477  qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMaxBounds[nDim2]);
3478 
3479  qglEnd();
3480 
3481  qglRasterPos3f(Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), 0, vMinBounds[nDim2] - 20.0 / m_fScale);
3482  g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]);
3483  qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
3484 
3485  qglRasterPos3f(vMaxBounds[nDim1] + 16.0 / m_fScale, 0, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2]));
3486  g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]);
3487  qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
3488 
3489  qglRasterPos3f(vMinBounds[nDim1] + 4, 0, vMaxBounds[nDim2] + 8 / m_fScale);
3490  g_strDim.Format(g_pOrgStrings[1], vMinBounds[nDim1], vMaxBounds[nDim2]);
3491  qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
3492  }
3493  else {
3494  qglBegin(GL_LINES);
3495 
3496  qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale);
3497  qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale);
3498 
3499  qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale);
3500  qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale);
3501 
3502  qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale);
3503  qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale);
3504 
3505  qglVertex3f(0, vMaxBounds[nDim1] + 6.0f / m_fScale, vMinBounds[nDim2]);
3506  qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2]);
3507 
3508  qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2]);
3509  qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2]);
3510 
3511  qglVertex3f(0, vMaxBounds[nDim1] + 6.0f / m_fScale, vMaxBounds[nDim2]);
3512  qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2]);
3513 
3514  qglEnd();
3515 
3516  qglRasterPos3f(0, Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), vMinBounds[nDim2] - 20.0 / m_fScale);
3517  g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]);
3518  qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
3519 
3520  qglRasterPos3f(0, vMaxBounds[nDim1] + 16.0 / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2]));
3521  g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]);
3522  qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
3523 
3524  qglRasterPos3f(0, vMinBounds[nDim1] + 4.0, vMaxBounds[nDim2] + 8 / m_fScale);
3525  g_strDim.Format(g_pOrgStrings[2], vMinBounds[nDim1], vMaxBounds[nDim2]);
3526  qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim);
3527  }
3528 }
3529 
3530 /* XY_Draw */
3531 long g_lCount = 0;
3532 long g_lTotal = 0;
3533 extern void DrawBrushEntityName(brush_t *b);
3534 
3535 /*
3536  =======================================================================================================================
3537  =======================================================================================================================
3538  */
3540  brush_t *brush;
3541  float w, h;
3542  entity_t *e;
3543  idVec3 mins, maxs;
3544  int drawn, culled;
3545  int i;
3546 
3547  if (!active_brushes.next) {
3548  return; // not valid yet
3549  }
3550 
3551  // clear
3552  m_bDirty = false;
3553 
3554  GL_State( GLS_DEFAULT );
3555  qglViewport(0, 0, m_nWidth, m_nHeight);
3556  qglScissor(0, 0, m_nWidth, m_nHeight);
3558  (
3559  g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0],
3560  g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1],
3561  g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2],
3562  0
3563  );
3564 
3565  qglDisable(GL_DEPTH_TEST);
3566  qglDisable(GL_CULL_FACE);
3567  qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3568 
3569  // set up viewpoint
3570  qglMatrixMode(GL_PROJECTION);
3571  qglLoadIdentity();
3572 
3573  w = m_nWidth / 2 / m_fScale;
3574  h = m_nHeight / 2 / m_fScale;
3575 
3576  int nDim1 = (m_nViewType == YZ) ? 1 : 0;
3577  int nDim2 = (m_nViewType == XY) ? 1 : 2;
3578  mins[0] = m_vOrigin[nDim1] - w;
3579  maxs[0] = m_vOrigin[nDim1] + w;
3580  mins[1] = m_vOrigin[nDim2] - h;
3581  maxs[1] = m_vOrigin[nDim2] + h;
3582 
3583  idBounds viewBounds( mins, maxs );
3584  viewBounds[0].z = -99999;
3585  viewBounds[1].z = 99999;
3586 
3587  qglOrtho(mins[0], maxs[0], mins[1], maxs[1], MIN_WORLD_COORD, MAX_WORLD_COORD);
3588 
3589  // draw stuff
3591  // now draw the grid
3592  qglLineWidth(0.25);
3593  XY_DrawGrid();
3594  qglLineWidth(0.5);
3595 
3596  drawn = culled = 0;
3597 
3598  if (m_nViewType != XY) {
3599  qglPushMatrix();
3600  if (m_nViewType == YZ) {
3601  qglRotatef(-90, 0, 1, 0); // put Z going up
3602  }
3603 
3604  // else
3605  qglRotatef(-90, 1, 0, 0); // put Z going up
3606  }
3607 
3608  e = world_entity;
3609 
3610  for ( brush = active_brushes.next; brush != &active_brushes; brush = brush->next ) {
3611  if ( brush->forceVisibile || ( brush->owner->eclass->nShowFlags & ( ECLASS_LIGHT | ECLASS_PROJECTEDLIGHT ) ) ) {
3612  } else if ( brush->mins[nDim1] > maxs[0] || brush->mins[nDim2] > maxs[1] || brush->maxs[nDim1] < mins[0] || brush->maxs[nDim2] < mins[1] ) {
3613  culled++;
3614  continue; // off screen
3615  }
3616 
3617  if ( FilterBrush(brush) ) {
3618  continue;
3619  }
3620 
3621  drawn++;
3622 
3623  if (brush->owner != e && brush->owner) {
3624  qglColor3fv(brush->owner->eclass->color.ToFloatPtr());
3625  }
3626  else {
3627  qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES].ToFloatPtr());
3628  }
3629 
3630  Brush_DrawXY( brush, m_nViewType );
3631  }
3632 
3633  DrawPathLines();
3634 
3635  // draw pointfile
3636  if (g_qeglobals.d_pointfile_display_list) {
3637  qglCallList(g_qeglobals.d_pointfile_display_list);
3638  }
3639 
3640  if (!(m_nViewType == XY)) {
3641  qglPopMatrix();
3642  }
3643 
3644  // draw block grid
3645  if (g_qeglobals.show_blocks) {
3646  XY_DrawBlockGrid();
3647  }
3648 
3649  // now draw selected brushes
3650  if (m_nViewType != XY) {
3651  qglPushMatrix();
3652  if (m_nViewType == YZ) {
3653  qglRotatef(-90, 0, 1, 0); // put Z going up
3654  }
3655 
3656  // else
3657  qglRotatef(-90, 1, 0, 0); // put Z going up
3658  }
3659 
3660  qglPushMatrix();
3662  (
3663  g_qeglobals.d_select_translate[0],
3664  g_qeglobals.d_select_translate[1],
3665  g_qeglobals.d_select_translate[2]
3666  );
3667 
3668  if (RotateMode()) {
3669  qglColor3f( 0.8f, 0.1f, 0.9f );
3670  }
3671  else if (ScaleMode()) {
3672  qglColor3f( 0.1f, 0.8f, 0.1f );
3673  }
3674  else {
3675  qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].ToFloatPtr());
3676  }
3677 
3678  if (g_PrefsDlg.m_bNoStipple == FALSE) {
3679  qglEnable(GL_LINE_STIPPLE);
3680  qglLineStipple(3, 0xaaaa);
3681  }
3682 
3683  qglLineWidth(1);
3684 
3685  idVec3 vMinBounds;
3686  idVec3 vMaxBounds;
3687  vMinBounds[0] = vMinBounds[1] = vMinBounds[2] = 999999.9f;
3688  vMaxBounds[0] = vMaxBounds[1] = vMaxBounds[2] = -999999.9f;
3689 
3690  int nSaveDrawn = drawn;
3691  bool bFixedSize = false;
3692  for (brush = selected_brushes.next; brush != &selected_brushes; brush = brush->next) {
3693  drawn++;
3694  Brush_DrawXY(brush, m_nViewType, true);
3695 
3696  if (!bFixedSize) {
3697  if (brush->owner->eclass->fixedsize) {
3698  bFixedSize = true;
3699  }
3700 
3701  if (g_PrefsDlg.m_bSizePaint) {
3702  for (i = 0; i < 3; i++) {
3703  if (brush->mins[i] < vMinBounds[i]) {
3704  vMinBounds[i] = brush->mins[i];
3705  }
3706 
3707  if (brush->maxs[i] > vMaxBounds[i]) {
3708  vMaxBounds[i] = brush->maxs[i];
3709  }
3710  }
3711  }
3712  }
3713  }
3714 
3715  if (g_PrefsDlg.m_bNoStipple == FALSE) {
3716  qglDisable(GL_LINE_STIPPLE);
3717  }
3718 
3719  qglLineWidth(0.5);
3720 
3721  if (!bFixedSize && !RotateMode() && !ScaleMode() && drawn - nSaveDrawn > 0 && g_PrefsDlg.m_bSizePaint) {
3722  PaintSizeInfo(nDim1, nDim2, vMinBounds, vMaxBounds);
3723  }
3724 
3725  // edge / vertex flags
3726  if (g_qeglobals.d_select_mode == sel_vertex) {
3727  qglPointSize(4);
3728  qglColor3f(0, 1, 0);
3729  qglBegin(GL_POINTS);
3730  for (i = 0; i < g_qeglobals.d_numpoints; i++) {
3731  qglVertex3fv(g_qeglobals.d_points[i].ToFloatPtr());
3732  }
3733 
3734  qglEnd();
3735  qglPointSize(1);
3736  }
3737  else if (g_qeglobals.d_select_mode == sel_edge) {
3738  float *v1, *v2;
3739 
3740  qglPointSize(4);
3741  qglColor3f(0, 0, 1);
3742  qglBegin(GL_POINTS);
3743  for (i = 0; i < g_qeglobals.d_numedges; i++) {
3744  v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1].ToFloatPtr();
3745  v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2].ToFloatPtr();
3746  qglVertex3f((v1[0] + v2[0]) * 0.5, (v1[1] + v2[1]) * 0.5, (v1[2] + v2[2]) * 0.5);
3747  }
3748 
3749  qglEnd();
3750  qglPointSize(1);
3751  }
3752 
3753  g_splineList->draw (static_cast<bool>(g_qeglobals.d_select_mode == sel_editpoint || g_qeglobals.d_select_mode == sel_addpoint));
3754 
3756  int maxage = g_pParentWnd->GetNurb()->GetNumValues();
3757  int time = 0;
3758  qglColor3f(0, 0, 1);
3759  qglPointSize(1);
3760  qglBegin(GL_POINTS);
3761  g_pParentWnd->GetNurb()->SetOrder(3);
3762  for (i = 0; i < 100; i++) {
3764  qglVertex3f(v.x, v.y, 0.0f);
3765  time += 10;
3766  }
3767  qglEnd();
3768  qglPointSize(4);
3769  qglColor3f(0, 0, 1);
3770  qglBegin(GL_POINTS);
3771  for (i = 0; i < maxage; i++) {
3773  qglVertex3f(v.x, v.y, 0.0f);
3774  }
3775  qglEnd();
3776  qglPointSize(1);
3777  }
3778 
3779  qglPopMatrix();
3780 
3782  (
3783  -g_qeglobals.d_select_translate[0],
3784  -g_qeglobals.d_select_translate[1],
3785  -g_qeglobals.d_select_translate[2]
3786  );
3787 
3788  if (!(m_nViewType == XY)) {
3789  qglPopMatrix();
3790  }
3791 
3792  // area selection hack
3793  if (g_qeglobals.d_select_mode == sel_area) {
3794  qglEnable(GL_BLEND);
3795  qglPolygonMode ( GL_FRONT_AND_BACK , GL_FILL );
3796  qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3797  qglColor4f(0.0, 0.0, 1.0, 0.25);
3798  qglRectf
3799  (
3800  g_qeglobals.d_vAreaTL[nDim1],
3801  g_qeglobals.d_vAreaTL[nDim2],
3802  g_qeglobals.d_vAreaBR[nDim1],
3803  g_qeglobals.d_vAreaBR[nDim2]
3804  );
3805  qglDisable(GL_BLEND);
3806  qglPolygonMode ( GL_FRONT_AND_BACK , GL_LINE );
3807  qglColor3f(1.0f, 1.0f, 1.0f);
3808  qglRectf
3809  (
3810  g_qeglobals.d_vAreaTL[nDim1],
3811  g_qeglobals.d_vAreaTL[nDim2],
3812  g_qeglobals.d_vAreaBR[nDim1],
3813  g_qeglobals.d_vAreaBR[nDim2]
3814  );
3815 
3816  }
3817 
3818  // now draw camera point
3819  DrawCameraIcon();
3820  DrawZIcon();
3821 
3822  if (RotateMode()) {
3823  DrawRotateIcon();
3824  }
3825 
3829 
3830  qglFlush();
3831 
3832  // QE_CheckOpenGLForErrors();
3833 }
3834 
3835 
3836 /*
3837  =======================================================================================================================
3838  =======================================================================================================================
3839  */
3841  return m_vOrigin;
3842 }
3843 
3844 /*
3845  =======================================================================================================================
3846  =======================================================================================================================
3847  */
3849  m_vOrigin[0] = org[0];
3850  m_vOrigin[1] = org[1];
3851  m_vOrigin[2] = org[2];
3852 }
3853 
3854 /*
3855  =======================================================================================================================
3856  =======================================================================================================================
3857  */
3858 void CXYWnd::OnSize(UINT nType, int cx, int cy) {
3859  CWnd::OnSize(nType, cx, cy);
3860 
3861  CRect rect;
3862  GetClientRect(rect);
3863  m_nWidth = rect.Width();
3864  m_nHeight = rect.Height();
3865  InvalidateRect(NULL, false);
3866 }
3867 
3869 
3870 /*
3871  =======================================================================================================================
3872  =======================================================================================================================
3873  */
3875  if (ClipMode()) {
3876  hold_brushes.next = &hold_brushes;
3878 
3879  // brush_t* pList = (g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits;
3880  brush_t *pList;
3881  if (g_PrefsDlg.m_bSwitchClip) {
3882  pList = ((m_nViewType == XZ) ? g_bSwitch : !g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits;
3883  }
3884  else {
3885  pList = ((m_nViewType == XZ) ? !g_bSwitch : g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits;
3886  }
3887 
3888  if (pList->next != pList) {
3889  Brush_CopyList(pList, &hold_brushes);
3892  Select_Delete();
3893  Brush_CopyList(&hold_brushes, &selected_brushes);
3894  if (RogueClipMode()) {
3895  RetainClipMode(false);
3896  }
3897  else {
3898  RetainClipMode(true);
3899  }
3900 
3901  Sys_UpdateWindows(W_ALL);
3902  }
3903  }
3904  else if (PathMode()) {
3906  if (g_pPathFunc) {
3907  g_pPathFunc(true, g_nPathCount);
3908  }
3909 
3910  g_pPathFunc = NULL;
3911  g_nPathCount = 0;
3912  g_bPathMode = false;
3913  }
3914 }
3915 
3916 /*
3917  =======================================================================================================================
3918  =======================================================================================================================
3919  */
3922  if ((g_brFrontSplits.next != &g_brFrontSplits) && (g_brBackSplits.next != &g_brBackSplits)) {
3923  Select_Delete();
3928  if (RogueClipMode()) {
3929  RetainClipMode(false);
3930  }
3931  else {
3932  RetainClipMode(true);
3933  }
3934  }
3935 }
3936 
3937 /*
3938  =======================================================================================================================
3939  =======================================================================================================================
3940  */
3942  g_bSwitch = !g_bSwitch;
3943  Sys_UpdateWindows(XY | W_CAMERA_IFON);
3944 }
3945 
3946 //
3947 // =======================================================================================================================
3948 // makes sure the selected brush or camera is in view
3949 // =======================================================================================================================
3950 //
3952  int nDim1 = (m_nViewType == YZ) ? 1 : 0;
3953  int nDim2 = (m_nViewType == XY) ? 1 : 2;
3954  brush_t *b = selected_brushes.next;
3955  if (b && b->next != b) {
3956  m_vOrigin[nDim1] = b->mins[nDim1];
3957  m_vOrigin[nDim2] = b->mins[nDim2];
3958  }
3959  else {
3960  m_vOrigin[nDim1] = g_pParentWnd->GetCamera()->Camera().origin[nDim1];
3961  m_vOrigin[nDim2] = g_pParentWnd->GetCamera()->Camera().origin[nDim2];
3962  }
3963 }
3964 
3965 /*
3966  =======================================================================================================================
3967  =======================================================================================================================
3968  */
3969 void CXYWnd::VectorCopyXY(const idVec3 &in, idVec3 &out) {
3970  if (m_nViewType == XY) {
3971  out[0] = in[0];
3972  out[1] = in[1];
3973  }
3974  else if (m_nViewType == XZ) {
3975  out[0] = in[0];
3976  out[2] = in[2];
3977  }
3978  else {
3979  out[1] = in[1];
3980  out[2] = in[2];
3981  }
3982 }
3983 
3984 /*
3985  =======================================================================================================================
3986  =======================================================================================================================
3987  */
3989  CWnd::OnDestroy();
3990 
3991  // delete this;
3992 }
3993 
3994 /*
3995  =======================================================================================================================
3996  =======================================================================================================================
3997  */
3999  m_nViewType = n;
4000  char *p = "YZ Side";
4001  if (m_nViewType == XY) {
4002  p = "XY Top";
4003  } else if (m_nViewType == XZ) {
4004  p = "XZ Front";
4005  }
4006  SetWindowText(p);
4007 };
4008 
4009 /*
4010  =======================================================================================================================
4011  =======================================================================================================================
4012  */
4013 void CXYWnd::Redraw(unsigned int nBits) {
4014  m_nUpdateBits = nBits;
4015  RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
4016  m_nUpdateBits = W_XY;
4017 }
4018 
4019 /*
4020  =======================================================================================================================
4021  =======================================================================================================================
4022  */
4024  return g_bRotateMode;
4025 }
4026 
4027 /*
4028  =======================================================================================================================
4029  =======================================================================================================================
4030  */
4032  return g_bScaleMode;
4033 }
4034 
4035 /*
4036  =======================================================================================================================
4037  =======================================================================================================================
4038  */
4039 extern bool Select_OnlyModelsSelected();
4040 bool CXYWnd::SetRotateMode(bool bMode) {
4041  if (bMode && selected_brushes.next != &selected_brushes) {
4042  g_bRotateMode = true;
4043  if (Select_OnlyModelsSelected()) {
4044  Select_GetTrueMid(g_vRotateOrigin);
4045  } else {
4046  Select_GetMid(g_vRotateOrigin);
4047  }
4048  g_vRotation.Zero();
4049  Select_InitializeRotation();
4050  }
4051  else {
4052  if (bMode) {
4053  Sys_Status("Need a brush selected to turn on Mouse Rotation mode\n");
4054  }
4055 
4056  g_bRotateMode = false;
4057  Select_FinalizeRotation();
4058  }
4059 
4060  RedrawWindow();
4061  return g_bRotateMode;
4062 }
4063 
4064 /*
4065  =======================================================================================================================
4066  =======================================================================================================================
4067  */
4068 void CXYWnd::SetScaleMode(bool bMode) {
4069  g_bScaleMode = bMode;
4070  RedrawWindow();
4071 }
4072 
4073 //
4074 // =======================================================================================================================
4075 // xy - z xz - y yz - x
4076 // =======================================================================================================================
4077 //
4079  // TODO: Add your command handler code here
4080 }
4081 
4082 /*
4083  =======================================================================================================================
4084  =======================================================================================================================
4085  */
4087  entity_t *pe = g_enClipboard.next;
4088  while (pe != NULL && pe != &g_enClipboard) {
4089  entity_t *next = pe->next;
4090  pe->epairs.Clear();
4091 
4092  Entity_Free(pe);
4093  pe = next;
4094  }
4095 
4096  g_enClipboard.next = g_enClipboard.prev = &g_enClipboard;
4097 }
4098 
4099 /*
4100  =======================================================================================================================
4101  =======================================================================================================================
4102  */
4104  entity_t *n;
4105 
4106  n = Entity_New();
4107  n->brushes.onext = n->brushes.oprev = &n->brushes;
4108  n->eclass = e->eclass;
4109  n->rotation = e->rotation;
4110 
4111  // add the entity to the entity list
4112  n->next = g_enClipboard.next;
4113  g_enClipboard.next = n;
4114  n->next->prev = n;
4115  n->prev = &g_enClipboard;
4116 
4117  n->epairs = e->epairs;
4118 
4119  return n;
4120 }
4121 
4122 /*
4123  =======================================================================================================================
4124  =======================================================================================================================
4125  */
4126 bool OnList(entity_t *pFind, CPtrArray *pList) {
4127  int nSize = pList->GetSize();
4128  while (nSize-- > 0) {
4129  entity_t *pEntity = reinterpret_cast < entity_t * > (pList->GetAt(nSize));
4130  if (pEntity == pFind) {
4131  return true;
4132  }
4133  }
4134 
4135  return false;
4136 }
4137 
4138 /*
4139  =======================================================================================================================
4140  =======================================================================================================================
4141  */
4143 {
4144 #if 1
4145  CWaitCursor WaitCursor;
4146  g_Clipboard.SetLength(0);
4147  g_PatchClipboard.SetLength(0);
4148 
4150 
4151  bool bClipped = false;
4152  UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings");
4153  if (nClipboard > 0) {
4154  if (OpenClipboard()) {
4155  ::EmptyClipboard();
4156 
4157  long lSize = g_Clipboard.GetLength();
4158  HANDLE h = ::GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, lSize + sizeof (long));
4159  if (h != NULL) {
4160  unsigned char *cp = reinterpret_cast < unsigned char * > (::GlobalLock(h));
4161  memcpy(cp, &lSize, sizeof (long));
4162  cp += sizeof (long);
4163  g_Clipboard.SeekToBegin();
4164  g_Clipboard.Read(cp, lSize);
4165  ::GlobalUnlock(h);
4166  ::SetClipboardData(nClipboard, h);
4167  ::CloseClipboard();
4168  bClipped = true;
4169  }
4170  }
4171  }
4172 
4173  if (!bClipped) {
4174  common->Printf("Unable to register Windows clipboard formats, copy/paste between editors will not be possible");
4175  }
4176 
4177  /*
4178  * CString strOut; ::GetTempPath(1024, strOut.GetBuffer(1024));
4179  * strOut.ReleaseBuffer(); AddSlash(strOut); strOut += "RadiantClipboard.$$$";
4180  * Map_SaveSelected(strOut.GetBuffer(0));
4181  */
4182 #else
4183  CPtrArray holdArray;
4186  for (brush_t * pBrush = selected_brushes.next; pBrush != NULL && pBrush != &selected_brushes; pBrush = pBrush->next) {
4187  if (pBrush->owner == world_entity) {
4188  brush_t *pClone = Brush_Clone(pBrush);
4189  pClone->owner = NULL;
4190  Brush_AddToList(pClone, &g_brClipboard);
4191  }
4192  else {
4193  if (!OnList(pBrush->owner, &holdArray)) {
4194  entity_t *e = pBrush->owner;
4195  holdArray.Add(reinterpret_cast < void * > (e));
4196 
4197  entity_t *pEClone = Entity_CopyClone(e);
4198  for (brush_t * pEB = e->brushes.onext; pEB != &e->brushes; pEB = pEB->onext) {
4199  brush_t *pClone = Brush_Clone(pEB);
4200 
4201  // Brush_AddToList (pClone, &g_brClipboard);
4202  Entity_LinkBrush(pEClone, pClone);
4203  Brush_Build(pClone);
4204  }
4205  }
4206  }
4207  }
4208 #endif
4209 }
4210 
4211 /*
4212  =======================================================================================================================
4213  =======================================================================================================================
4214  */
4216  /*
4217  * if (g_brUndo.next != &g_brUndo) { g_bScreenUpdates = false; Select_Delete();
4218  * for (brush_t* pBrush = g_brUndo.next ; pBrush != NULL && pBrush != &g_brUndo ;
4219  * pBrush=pBrush->next) { brush_t* pClone = Brush_Clone(pBrush); Brush_AddToList
4220  * (pClone, &active_brushes); Entity_LinkBrush (pBrush->pUndoOwner, pClone);
4221  * Brush_Build(pClone); Select_Brush(pClone); } CleanList(&g_brUndo);
4222  * g_bScreenUpdates = true; Sys_UpdateWindows(W_ALL); } else common->Printf("Nothing
4223  * to undo.../n");
4224  */
4225 }
4226 
4227 /*
4228  =======================================================================================================================
4229  =======================================================================================================================
4230  */
4232  /* CleanList(&g_brUndo); */
4233 }
4234 
4235 /*
4236  =======================================================================================================================
4237  =======================================================================================================================
4238  */
4240  /*
4241  * CleanList(&g_brUndo); for (brush_t* pBrush = selected_brushes.next ; pBrush !=
4242  * NULL && pBrush != &selected_brushes ; pBrush=pBrush->next) { brush_t* pClone =
4243  * Brush_Clone(pBrush); pClone->pUndoOwner = pBrush->owner; Brush_AddToList
4244  * (pClone, &g_brUndo); }
4245  */
4246 }
4247 
4248 /*
4249  =======================================================================================================================
4250  =======================================================================================================================
4251  */
4253  return(g_brUndo.next != &g_brUndo);
4254 }
4255 
4256 /*
4257  =======================================================================================================================
4258  =======================================================================================================================
4259  */
4261 {
4262 #if 1
4263 
4264  CWaitCursor WaitCursor;
4265  bool bPasted = false;
4266  UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings");
4267  if (nClipboard > 0 && OpenClipboard() && ::IsClipboardFormatAvailable(nClipboard)) {
4268  HANDLE h = ::GetClipboardData(nClipboard);
4269  if (h) {
4270  g_Clipboard.SetLength(0);
4271 
4272  unsigned char *cp = reinterpret_cast < unsigned char * > (::GlobalLock(h));
4273  long lSize = 0;
4274  memcpy(&lSize, cp, sizeof (long));
4275  cp += sizeof (long);
4276  g_Clipboard.Write(cp, lSize);
4277  }
4278 
4279  ::GlobalUnlock(h);
4280  ::CloseClipboard();
4281  }
4282 
4283  if (g_Clipboard.GetLength() > 0) {
4284  g_Clipboard.SeekToBegin();
4285 
4286  int nLen = g_Clipboard.GetLength();
4287  char *pBuffer = new char[nLen + 1];
4288  memset(pBuffer, 0, sizeof(pBuffer));
4289  g_Clipboard.Read(pBuffer, nLen);
4290  pBuffer[nLen] = '\0';
4291  Map_ImportBuffer(pBuffer, !(GetAsyncKeyState(VK_SHIFT) & 0x8000));
4292  delete[] pBuffer;
4293  }
4294 
4295  #if 0
4296  if (g_PatchClipboard.GetLength() > 0) {
4297  g_PatchClipboard.SeekToBegin();
4298 
4299  int nLen = g_PatchClipboard.GetLength();
4300  char *pBuffer = new char[nLen + 1];
4301  g_PatchClipboard.Read(pBuffer, nLen);
4302  pBuffer[nLen] = '\0';
4303  Patch_ReadBuffer(pBuffer, true);
4304  delete[] pBuffer;
4305  }
4306  #endif
4307 #else
4308  if (g_brClipboard.next != &g_brClipboard || g_enClipboard.next != &g_enClipboard) {
4309  Select_Deselect();
4310 
4311  for (brush_t * pBrush = g_brClipboard.next; pBrush != NULL && pBrush != &g_brClipboard; pBrush = pBrush->next) {
4312  brush_t *pClone = Brush_Clone(pBrush);
4313 
4314  // pClone->owner = pBrush->owner;
4315  if (pClone->owner == NULL) {
4316  Entity_LinkBrush(world_entity, pClone);
4317  }
4318 
4320  Brush_Build(pClone);
4321  }
4322 
4323  for
4324  (
4325  entity_t * pEntity = g_enClipboard.next;
4326  pEntity != NULL && pEntity != &g_enClipboard;
4327  pEntity = pEntity->next
4328  ) {
4329  entity_t *pEClone = Entity_Clone(pEntity);
4330  for (brush_t * pEB = pEntity->brushes.onext; pEB != &pEntity->brushes; pEB = pEB->onext) {
4331  brush_t *pClone = Brush_Clone(pEB);
4333  Entity_LinkBrush(pEClone, pClone);
4334  Brush_Build(pClone);
4335  if (pClone->owner && pClone->owner != world_entity) {
4336  g_Inspectors->UpdateEntitySel(pClone->owner->eclass);
4337  }
4338  }
4339  }
4340 
4341  Sys_UpdateWindows(W_ALL);
4342  }
4343  else {
4344  common->Printf("Nothing to paste.../n");
4345  }
4346 #endif
4347 }
4348 
4349 /*
4350  =======================================================================================================================
4351  =======================================================================================================================
4352  */
4354  return g_vRotation;
4355 }
4356 
4357 /*
4358  =======================================================================================================================
4359  =======================================================================================================================
4360  */
4362  return g_vRotateOrigin;
4363 }
4364 
4365 /*
4366  =======================================================================================================================
4367  =======================================================================================================================
4368  */
4369 void CXYWnd::OnTimer(UINT nIDEvent) {
4370  if (nIDEvent == 100) {
4371  int nDim1 = (m_nViewType == YZ) ? 1 : 0;
4372  int nDim2 = (m_nViewType == XY) ? 1 : 2;
4373  m_vOrigin[nDim1] += m_ptDragAdj.x / m_fScale;
4374  m_vOrigin[nDim2] -= m_ptDragAdj.y / m_fScale;
4375  Sys_UpdateWindows(W_XY | W_CAMERA);
4376 
4377  // int nH = (m_ptDrag.y == 0) ? -1 : m_ptDrag.y;
4378  m_ptDrag += m_ptDragAdj;
4381 
4382  //
4383  // m_vOrigin[nDim1] -= m_ptDrag.x / m_fScale; m_vOrigin[nDim1] -= m_ptDrag.x /
4384  // m_fScale;
4385  //
4386  }
4387 }
4388 
4389 /*
4390  =======================================================================================================================
4391  =======================================================================================================================
4392  */
4393 void CXYWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) {
4394  g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false);
4395 
4396  // CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
4397 }
4398 
4399 /*
4400  =======================================================================================================================
4401  =======================================================================================================================
4402  */
4403 void CXYWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR *lpncsp) {
4404  CWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
4405 }
4406 
4407 /*
4408  =======================================================================================================================
4409  =======================================================================================================================
4410  */
4411 void CXYWnd::OnKillFocus(CWnd *pNewWnd) {
4412  CWnd::OnKillFocus(pNewWnd);
4413  SendMessage(WM_NCACTIVATE, FALSE, 0);
4414 }
4415 
4416 /*
4417  =======================================================================================================================
4418  =======================================================================================================================
4419  */
4420 void CXYWnd::OnSetFocus(CWnd *pOldWnd) {
4421  CWnd::OnSetFocus(pOldWnd);
4422  SendMessage(WM_NCACTIVATE, TRUE, 0);
4423 }
4424 
4425 /*
4426  =======================================================================================================================
4427  =======================================================================================================================
4428  */
4430  CWnd::OnClose();
4431 }
4432 
4433 //
4434 // =======================================================================================================================
4435 // should be static as should be the rotate scale stuff
4436 // =======================================================================================================================
4437 //
4439  return RotateMode() ? false : ScaleMode() ? false : true;
4440 }
4441 
4442 /*
4443  =======================================================================================================================
4444  =======================================================================================================================
4445  */
4447  return TRUE;
4448 
4449  // return CWnd::OnEraseBkgnd(pDC);
4450 }
4451 
4452 extern void AssignModel();
4454 {
4455  CPoint point;
4456  GetCursorPos(&point);
4457  CreateRightClickEntity(this, m_ptDown.x, m_ptDown.y, "func_static");
4458  g_Inspectors->SetMode(W_ENTITY);
4460 }
4461 
4462 BOOL CXYWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
4463 {
4464  if (zDelta > 0) {
4466  } else {
4468  }
4469  return TRUE;
4470 }
4471 
4472 
4473 
4474 
4475  //---------------------------------------------------------------------------
4476  // CyclePrecisionCrosshairMode
4477  //
4478  // Called when the user presses the "cycle precision cursor mode" key.
4479  // Cycles the precision cursor among the following three modes:
4480  // PRECISION_CURSOR_NONE
4481  // PRECISION_CURSOR_SNAP
4482  // PRECISION_CURSOR_FREE
4483  //---------------------------------------------------------------------------
4485  {
4486  common->Printf("TODO: Make DrawPrecisionCrosshair work..." );
4487 
4492  Sys_UpdateWindows( W_XY );
4493  }
4494 
4495  //---------------------------------------------------------------------------
4496 // DrawPrecisionCrosshair
4497 //
4498 // Draws a precision crosshair beneath the cursor in the 2d (XY) view,
4499 // depending on one of the following values for m_precisionCrosshairMode:
4500 //
4501 // PRECISION_CROSSHAIR_NONE No crosshair is drawn. Do not force refresh of XY view.
4502 // PRECISION_CROSSHAIR_SNAP Crosshair snaps to grid size. Force refresh of XY view.
4503 // PRECISION_CROSSHAIR_FREE Crosshair does not snap to grid. Force refresh of XY view.
4504 //---------------------------------------------------------------------------
4506 {
4507  // FIXME: m_mouseX, m_mouseY, m_axisHoriz, m_axisVert, etc... are never set
4508  return;
4509 
4510  idVec3 mouse3dPos (0.0f, 0.0f, 0.0f);
4511  float x, y;
4512  idVec4 crossEndColor (1.0f, 0.0f, 1.0f, 1.0f); // the RGBA color of the precision crosshair at its ends
4513  idVec4 crossMidColor; // the RGBA color of the precision crosshair at the crossing point
4514 
4517  SnapToPoint( m_mouseX, m_mouseY, mouse3dPos );
4518  else
4519  XY_ToPoint( m_mouseX, m_mouseY, mouse3dPos );
4520  x = mouse3dPos[ m_axisHoriz ];
4521  y = mouse3dPos[ m_axisVert ];
4522 
4524 
4525  crossEndColor[0] = g_qeglobals.d_savedinfo.colors[ COLOR_PRECISION_CROSSHAIR ][0];
4526  crossEndColor[1] = g_qeglobals.d_savedinfo.colors[ COLOR_PRECISION_CROSSHAIR ][1];
4527  crossEndColor[2] = g_qeglobals.d_savedinfo.colors[ COLOR_PRECISION_CROSSHAIR ][2];
4528  crossEndColor[3] = 1.0f;
4529 
4530  crossMidColor = crossEndColor;
4531 
4533  crossMidColor[ 3 ] = 0.0f; // intersection-color is 100% transparent (alpha = 0.0f)
4534 
4536  qglEnable( GL_BLEND );
4537  qglDisable( GL_TEXTURE_2D );
4538  qglShadeModel( GL_SMOOTH );
4539  qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
4540 
4542  qglBegin( GL_LINES );
4543  {
4545  qglColor4fv( crossEndColor.ToFloatPtr() );
4546  qglVertex2f( m_mcLeft, y );
4547  qglColor4fv( crossMidColor.ToFloatPtr() );
4548  qglVertex2f( x, y );
4549  qglColor4fv( crossMidColor.ToFloatPtr() );
4550  qglVertex2f( x, y );
4551  qglColor4fv( crossEndColor.ToFloatPtr() );
4552  qglVertex2f( m_mcRight, y );
4553 
4555  qglColor4fv( crossEndColor.ToFloatPtr() );
4556  qglVertex2f( x, m_mcTop );
4557  qglColor4fv( crossMidColor.ToFloatPtr() );
4558  qglVertex2f( x, y );
4559  qglColor4fv( crossMidColor.ToFloatPtr() );
4560  qglVertex2f( x, y );
4561  qglColor4fv( crossEndColor.ToFloatPtr() );
4562  qglVertex2f( x, m_mcBottom );
4563  }
4564  qglEnd(); // GL_LINES
4565 
4566  // Radiant was in opaque, flat-shaded mode by default; restore this to prevent possible slowdown
4567  qglShadeModel( GL_FLAT );
4568  qglDisable( GL_BLEND );
4569 }
CMainFrame * g_pParentWnd
Definition: MainFrm.cpp:73
bool FilterBrush(brush_t *pb)
Definition: XYWnd.cpp:3167
#define IDR_MENU_DROP
CClipPoint * g_pMovingPoint
Definition: XYWnd.cpp:82
void HideInfoDialog()
Definition: DialogInfo.cpp:62
bool g_bPathMode
Definition: XYWnd.cpp:72
byte color[4]
Definition: MegaTexture.cpp:54
bool GetNurbMode()
Definition: MainFrm.h:111
#define strcmp
Definition: Str.h:41
virtual ~CXYWnd()
Definition: XYWnd.cpp:529
#define qglRasterPos3f
Definition: qgl_linked.h:251
void Undo()
Definition: XYWnd.cpp:4215
bool g_bCrossHairs
Definition: XYWnd.cpp:51
#define stricmp
Definition: Str.h:64
void UpdateEntitySel(eclass_t *ent)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct)
Definition: XYWnd.cpp:749
void SetStatusText(int nPane, const char *pText)
Definition: MainFrm.cpp:3922
void WINAPI Sys_UpdateWindows(int nBits)
Definition: MainFrm.cpp:3974
#define min(a, b)
void CyclePrecisionCrosshairMode()
Definition: XYWnd.cpp:4484
type GetValue(const int index) const
Definition: Curve.h:58
float Normalize(void)
Definition: Vector.h:646
entity_t * world_entity
Definition: EditorMap.cpp:49
#define qglScissor
Definition: qgl_linked.h:280
void CleanList(brush_t *pList)
Definition: XYWnd.cpp:988
bool m_bDirty
Definition: XYWnd.h:186
idVec3 m_ptClip
Definition: XYWnd.h:60
void cross(float a[], float b[], float c[])
Definition: Model_lwo.cpp:3889
#define ID_DROP_NEWMODEL
void UpdatePointPtr()
Definition: XYWnd.h:59
CPoint m_ptScreen
Definition: XYWnd.h:63
int m_nPressy
Definition: XYWnd.h:193
afx_msg BOOL OnEraseBkgnd(CDC *pDC)
Definition: XYWnd.cpp:4446
void DropPathPoint(UINT nFlags, CPoint point)
Definition: XYWnd.cpp:843
void ProduceSplits(brush_t **pFront, brush_t **pBack)
Definition: XYWnd.cpp:944
afx_msg void OnSize(UINT nType, int cx, int cy)
Definition: XYWnd.cpp:3858
CClipPoint g_Clip3
Definition: XYWnd.cpp:60
#define qglDisable
Definition: qgl_linked.h:92
void ShowInfoDialog(const char *pText)
Definition: DialogInfo.cpp:46
void Paste()
Definition: XYWnd.cpp:4260
afx_msg void OnMButtonDown(UINT nFlags, CPoint point)
Definition: XYWnd.cpp:923
float m_mcBottom
Definition: XYWnd.h:206
int g_nPointCount
Definition: XYWnd.cpp:83
CPtrArray dragPoints
Definition: XYWnd.cpp:128
brush_t selected_brushes
Definition: EditorMap.cpp:40
long g_lTotal
Definition: XYWnd.cpp:3532
void SetActiveXY(CXYWnd *p)
Definition: MainFrm.h:126
float y
Definition: Vector.h:55
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
Definition: XYWnd.cpp:4393
void _SmartPointDone(bool b, int n)
Definition: XYWnd.cpp:1812
void Entity_Free(entity_t *e)
CONST PIXELFORMATDESCRIPTOR UINT
Definition: win_qgl.cpp:47
afx_msg void OnViewZoomin()
Definition: MainFrm.cpp:2413
brush_t active_brushes
Definition: EditorMap.cpp:39
const GLdouble * v
Definition: glext.h:2936
afx_msg void OnSetFocus(CWnd *pOldWnd)
Definition: XYWnd.cpp:4420
HGLRC hGLRC
Definition: win_local.h:122
int m_mouseX
Definition: XYWnd.h:174
BOOL m_bNoStipple
Definition: PrefsDlg.h:95
#define qglClearColor
Definition: qgl_linked.h:41
bool OnList(entity_t *pFind, CPtrArray *pList)
Definition: XYWnd.cpp:4126
const char * g_pDimStrings[]
Definition: XYWnd.cpp:46
const float * ToFloatPtr(void) const
Definition: Vector.h:719
#define VectorSubtract(a, b, c)
Definition: Vector.h:1995
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:4804
idMat3 Transpose(void) const
Definition: Matrix.h:677
#define qglRotatef
Definition: qgl_linked.h:277
int Length(void) const
Definition: Str.h:702
int g_nSmartY
Definition: XYWnd.cpp:1805
afx_msg BOOL OnCmdMsg(UINT nID, int nCode, void *pExtra, AFX_CMDHANDLERINFO *pHandlerInfo)
Definition: XYWnd.cpp:1972
void PaintSizeInfo(int nDim1, int nDim2, idVec3 vMinBounds, idVec3 vMaxBounds)
Definition: XYWnd.cpp:3412
bool SetDragPointCursor(idVec3 p, int nView)
Definition: XYWnd.cpp:464
CZWnd * GetZWnd()
Definition: MainFrm.h:124
static const float PI
Definition: Math.h:205
idVec3 dragOrigin
Definition: XYWnd.cpp:2319
GLenum GLint GLint y
Definition: glext.h:2849
#define ID_ENTITY_END
GLenum GLsizei n
Definition: glext.h:3705
float z
Definition: Vector.h:320
void HandleDrop()
Definition: XYWnd.cpp:2126
void Map_ImportBuffer(char *buf, bool renameEntities)
Definition: EditorMap.cpp:1145
case const int
Definition: Callbacks.cpp:52
typedef HANDLE(WINAPI *PFNWGLCREATEBUFFERREGIONARBPROC)(HDC hDC
idVec3 g_vRotateOrigin
Definition: XYWnd.cpp:69
#define VectorCopy(a, b)
Definition: Vector.h:1999
int m_mouseY
Definition: XYWnd.h:175
IMPLEMENT_DYNCREATE(CXYWnd, CWnd)
void GLColoredBoxWithLabel(float x, float y, float size, idVec4 color, const char *text, idVec4 textColor, float xofs, float yofs, float lineSize)
Definition: XYWnd.cpp:2992
#define MAX_WORLD_COORD
Definition: Lib.h:98
#define WINAPI
Definition: qgl.h:64
idVec3 dragDir
Definition: XYWnd.cpp:2320
#define qglBegin
Definition: qgl_linked.h:33
bool MergeMenu(CMenu *pMenuDestination, const CMenu *pMenuAdd, bool bTopLevel)
Definition: XYWnd.cpp:1980
void Sys_Status(const char *psz, int part)
Definition: Radiant.cpp:465
CXYWnd * ActiveXY()
Definition: MainFrm.cpp:4034
camera_t & Camera()
Definition: CamWnd.h:90
CString g_strDim
Definition: XYWnd.cpp:48
const char * ValueForKey(entity_t *ent, const char *key)
const int GLS_DEFAULT
Definition: tr_local.h:1047
#define qglGetError
Definition: qgl_linked.h:131
Definition: Vector.h:316
case const float
Definition: Callbacks.cpp:62
const char * g_pOrgStrings[]
Definition: XYWnd.cpp:47
afx_msg void OnMouseMove(UINT nFlags, CPoint point)
Definition: XYWnd.cpp:1198
void XY_Init()
Definition: XYWnd.cpp:2222
#define qglVertex3fv
Definition: qgl_linked.h:350
static float Sqrt(float x)
Definition: Math.h:302
void VectorToAngles(idVec3 vec, idVec3 angles)
Definition: XYWnd.cpp:253
void XY_MouseDown(int x, int y, int buttons)
Definition: XYWnd.cpp:2324
void Brush_Free(brush_t *b, bool bRemoveNode)
afx_msg void OnMButtonUp(UINT nFlags, CPoint point)
Definition: XYWnd.cpp:1129
idVec3 dragY
Definition: XYWnd.cpp:2322
CClipPoint * g_pMovingClip
Definition: XYWnd.cpp:61
#define VectorAdd(a, b, c)
Definition: Vector.h:1996
static const float M_DEG2RAD
Definition: Math.h:214
idAngles angles
Definition: CamWnd.h:49
GLuint GLuint GLsizei GLenum type
Definition: glext.h:2845
void AssignModel()
bool m_bRButtonDown
Definition: XYWnd.h:189
afx_msg void OnSelectMouserotate()
Definition: XYWnd.cpp:4078
brush_t * CreateEntityBrush(int x, int y, CXYWnd *pWnd)
Definition: XYWnd.cpp:1710
float m_mcRight
Definition: XYWnd.h:204
void NewBrushDrag(int x, int y)
Definition: XYWnd.cpp:2523
void XY_DrawBlockGrid()
Definition: XYWnd.cpp:2922
int pressx
brush_t * Brush_Clone(brush_t *b)
void CreateRightClickEntity(CXYWnd *pWnd, int x, int y, char *pName)
Definition: XYWnd.cpp:1756
CClipPoint * g_pMovingPath
Definition: XYWnd.cpp:74
#define qglViewport
Definition: qgl_linked.h:364
GLenum GLsizei len
Definition: glext.h:3472
GLdouble right
Definition: qgl.h:273
idVec3 Cross(const idVec3 &a) const
Definition: Vector.h:619
CXYWnd * GetXYWnd()
Definition: MainFrm.h:120
void SetViewType(int n)
Definition: XYWnd.cpp:3998
void SetActiveDrag(CDragPoint *p)
Definition: XYWnd.cpp:482
void DropClipPoint(UINT nFlags, CPoint point)
Definition: XYWnd.cpp:774
float x
Definition: Vector.h:318
#define qglTranslatef
Definition: qgl_linked.h:338
#define qglCallList
Definition: qgl_linked.h:37
void ClearActiveDrag()
Definition: XYWnd.cpp:490
LONG WINAPI XYWndProc(HWND, UINT, WPARAM, LPARAM)
Definition: XYWnd.cpp:644
GLenum GLint x
Definition: glext.h:2849
bool Set()
Definition: XYWnd.h:57
int pressy
int i
Definition: process.py:33
#define ID_SELECT_MOUSEROTATE
#define BOOL
Definition: mprintf.c:71
int Cmpn(const char *text, int n) const
Definition: Str.h:657
bool SetRotateMode(bool bMode)
Definition: XYWnd.cpp:4040
CPoint m_ptDrag
Definition: XYWnd.h:217
GLuint GLuint num
Definition: glext.h:5390
void UpdateSelectablePoint(brush_t *b, idVec3 v, int type)
Definition: XYWnd.cpp:238
brush_t brushes
Definition: EditorEntity.h:35
void XY_ToGridPoint(int x, int y, idVec3 &point)
Definition: XYWnd.cpp:2284
const int XY_LEFT
Definition: XYWnd.cpp:86
void Brush_Build(brush_t *b, bool bSnap, bool bMarkMap, bool bConvert, bool updateLights)
#define qglEnable
Definition: qgl_linked.h:101
idCurve_NURBS< idVec2 > * GetNurb()
Definition: MainFrm.h:114
CMemFile g_PatchClipboard(4096)
int Icmp(const char *text) const
Definition: Str.h:667
bool g_bSwitch
Definition: XYWnd.cpp:57
idMat3 rotation
Definition: EditorEntity.h:44
int m_axisVert
Definition: XYWnd.h:198
#define MIN_WORLD_COORD
Definition: Lib.h:99
afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR *lpncsp)
Definition: XYWnd.cpp:4403
virtual void SetOrder(const int i)
Definition: Curve.h:1804
bool g_bPointMode
Definition: XYWnd.cpp:80
void SetKeyValue(entity_t *ent, const char *key, const char *value, bool trackAngles)
entity_t * Entity_New()
#define qglPushMatrix
Definition: qgl_linked.h:239
int g_nPathLimit
Definition: XYWnd.cpp:76
void UpdatePatchInspector()
void( PFNPathCallback)(bool, int)
Definition: XYWnd.h:49
#define qglPolygonStipple
Definition: qgl_linked.h:231
void SetScale(float f)
Definition: XYWnd.h:155
idVec3 m_vOrigin
Definition: XYWnd.h:187
idVec3 region_maxs(MAX_WORLD_COORD, MAX_WORLD_COORD, MAX_WORLD_COORD)
entity_t g_enClipboard
Definition: XYWnd.cpp:67
int m_nViewType
Definition: XYWnd.h:213
unsigned int m_nTimerID
Definition: XYWnd.h:215
void Error(const char *pFormat,...)
Definition: cmdlib.cpp:45
GLfloat GLfloat GLfloat v2
Definition: glext.h:3608
CXYWnd()
Definition: XYWnd.cpp:501
GLuint dst
Definition: glext.h:5285
#define ZCLIP_COLOUR
Definition: ZClip.h:35
brush_t g_brBackSplits
Definition: XYWnd.cpp:63
GLuint GLuint GLsizei count
Definition: glext.h:2845
int m_nMouseButtons
Definition: PrefsDlg.h:101
CCamWnd * GetCamera()
Definition: MainFrm.h:123
void PositionView()
Definition: XYWnd.cpp:3951
afx_msg void OnKillFocus(CWnd *pNewWnd)
Definition: XYWnd.cpp:4411
Definition: Vector.h:52
bool RogueClipMode()
Definition: XYWnd.cpp:1436
GLdouble GLdouble GLint GLint order
Definition: qgl.h:339
int GetNumPoints(void) const
Definition: Winding.h:238
afx_msg void OnClose()
Definition: XYWnd.cpp:4429
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
Definition: Vector.h:808
float Length(void) const
Definition: Vector.h:631
idMat3 Brush_RotationMatrix(brush_t *b)
int m_nButtonstate
Definition: XYWnd.h:191
void Brush_SplitBrushByFace(brush_t *in, face_t *f, brush_t **front, brush_t **back)
void Brush_AddToList(brush_t *b, brush_t *list)
BOOL m_bChaseMouse
Definition: PrefsDlg.h:92
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
CPoint m_ptDown
Definition: XYWnd.h:230
idVec3 & Rotation()
Definition: XYWnd.cpp:4353
bool UpdateActiveDragPoint(const idVec3 &move)
Definition: XYWnd.cpp:375
afx_msg void OnLButtonUp(UINT nFlags, CPoint point)
Definition: XYWnd.cpp:1113
int m_nWidth
Definition: XYWnd.h:181
void XY_DrawGrid()
Definition: XYWnd.cpp:2741
BOOL m_bSizePaint
Definition: PrefsDlg.h:86
bool PathMode()
Definition: XYWnd.cpp:1444
GLuint GLuint end
Definition: glext.h:2845
CClipPoint g_PointPoints[512]
Definition: XYWnd.cpp:81
static float Fabs(float f)
Definition: Math.h:779
#define qglPolygonMode
Definition: qgl_linked.h:229
idVec3 g_vRotation
Definition: XYWnd.cpp:70
idCommon * common
Definition: Common.cpp:206
void Copy()
Definition: XYWnd.cpp:4142
void CleanCopyEntities()
Definition: XYWnd.cpp:4086
idVec3 & RotateOrigin()
Definition: XYWnd.cpp:4361
struct entity_s * prev
Definition: EditorEntity.h:34
#define NULL
Definition: Lib.h:88
CString g_strSmartEntity
Definition: XYWnd.cpp:1803
void AddSelectablePoint(brush_t *b, idVec3 v, int type, bool priority)
Definition: XYWnd.cpp:230
brush_t g_brFrontSplits
Definition: XYWnd.cpp:62
bool m_bPress_selection
Definition: XYWnd.h:195
void Clear(void)
Definition: Dict.cpp:201
void Brush_CopyList(brush_t *pFrom, brush_t *pTo)
Definition: XYWnd.cpp:1072
float y
Definition: Vector.h:319
HDC s_hdcXY
Definition: XYWnd.cpp:601
afx_msg void OnLButtonDown(UINT nFlags, CPoint point)
Definition: XYWnd.cpp:887
#define qglOrtho
Definition: qgl_linked.h:218
void OriginalButtonUp(UINT nFlags, CPoint point)
Definition: XYWnd.cpp:1183
void WXY_Print(void)
Definition: XYWnd.cpp:687
void SetScaleMode(bool bMode)
Definition: XYWnd.cpp:4068
virtual void Clear(void)
Definition: Curve.h:2338
CDragPoint * PointRay(const idVec3 &org, const idVec3 &dir, float *dist)
Definition: XYWnd.cpp:157
brush_t hold_brushes
Definition: XYWnd.cpp:3868
#define qglEnd
Definition: qgl_linked.h:103
idImageManager * globalImages
Definition: Image_init.cpp:74
void DrawRotateIcon()
Definition: XYWnd.cpp:3015
#define qglColor3f
Definition: qgl_linked.h:50
CClipPoint g_Clip2
Definition: XYWnd.cpp:59
struct entity_s * next
Definition: EditorEntity.h:34
CPoint m_ptDragAdj
Definition: XYWnd.h:218
int g_nSmartX
Definition: XYWnd.cpp:1804
int m_nPressx
Definition: XYWnd.h:192
brush_t g_brUndo
Definition: XYWnd.cpp:66
float ptSum(idVec3 pt)
Definition: XYWnd.cpp:766
#define qglRectf
Definition: qgl_linked.h:269
tuple dp
Definition: prepare.py:21
#define FAR
Definition: jmorecfg.h:205
void UndoCopy()
Definition: XYWnd.cpp:4239
bool Select_OnlyModelsSelected()
float x
Definition: Vector.h:54
int m_nUpdateBits
Definition: XYWnd.h:180
void HandleKey(UINT nChar, UINT nRepCnt, UINT nFlags, bool bDown=true)
Definition: MainFrm.h:70
#define qglShadeModel
Definition: qgl_linked.h:282
void Redraw(unsigned int nBits)
Definition: XYWnd.cpp:4013
void OnEntityCreate(unsigned int nID)
Definition: XYWnd.cpp:1928
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:2405
int m_nScrollFlags
Definition: XYWnd.h:216
long g_lCount
Definition: XYWnd.cpp:3531
void DrawBrushEntityName(brush_t *b)
int GetViewType()
Definition: XYWnd.h:154
bool XY_MouseMoved(int x, int y, int buttons)
Definition: XYWnd.cpp:2590
void Brush_RemoveFromList(brush_t *b)
idVec3 origin
Definition: CamWnd.h:48
bool AreaSelectOK()
Definition: XYWnd.cpp:4438
entity_t * Entity_Clone(entity_t *e)
const int XY_UP
Definition: XYWnd.cpp:88
typedef HDC(WINAPI *PFNWGLGETCURRENTREADDCARBPROC)(void)
#define ID_ENTITY_START
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
void DeleteKey(entity_t *ent, const char *key)
idVec3 dragX
Definition: XYWnd.cpp:2321
virtual void Printf(const char *fmt,...) id_attribute((format(printf
entity_t * Entity_CopyClone(entity_t *e)
Definition: XYWnd.cpp:4103
float Betwixt(float f1, float f2)
Definition: XYWnd.cpp:931
CInspectorDialog * g_Inspectors
int g_nScaleHow
Definition: XYWnd.cpp:53
void AcquirePath(int nCount, PFNPathCallback *pFunc)
Definition: XYWnd.cpp:98
void RetainClipMode(bool bMode)
Definition: XYWnd.cpp:1383
void DrawZIcon()
Definition: XYWnd.cpp:3126
BOOL m_bRightClick
Definition: PrefsDlg.h:66
const float * ToFloatPtr(void) const
Definition: Vector.h:1051
void UndoClear()
Definition: XYWnd.cpp:4231
idVec3 Brush_TransformedPoint(brush_t *b, const idVec3 &in)
afx_msg void OnPaint()
Definition: XYWnd.cpp:1471
PFNPathCallback * g_pPathFunc
Definition: XYWnd.cpp:91
#define qglPointSize
Definition: qgl_linked.h:228
GLfloat GLfloat v1
Definition: glext.h:3607
void ProjectVector(const idVec3 &src, idVec3 &dst) const
Definition: Matrix.h:628
void SetMode(int mode, bool updateTabs=true)
#define YAW
Definition: Angles.h:42
GLubyte GLubyte b
Definition: glext.h:4662
afx_msg void OnDropNewmodel()
Definition: XYWnd.cpp:4453
afx_msg void OnViewZoomout()
Definition: MainFrm.cpp:2442
bool UndoAvailable()
Definition: XYWnd.cpp:4252
int g_nPointLimit
Definition: XYWnd.cpp:84
bool g_bRogueClipMode
Definition: XYWnd.cpp:56
void VectorCopyXY(const idVec3 &in, idVec3 &out)
Definition: XYWnd.cpp:3969
afx_msg void OnDestroy()
Definition: XYWnd.cpp:3988
const int XY_DOWN
Definition: XYWnd.cpp:89
#define qglFlush
Definition: qgl_linked.h:119
void XY_Draw()
Definition: XYWnd.cpp:3539
#define qglPopMatrix
Definition: qgl_linked.h:234
GLfloat GLfloat GLfloat GLfloat v3
Definition: glext.h:3609
long LONG
bool g_bClipMode
Definition: XYWnd.cpp:55
int Append(const type &obj)
Definition: List.h:646
GLdouble GLdouble GLdouble r
Definition: glext.h:2951
void DrawPrecisionCrosshair()
Definition: XYWnd.cpp:4505
BOOL m_bSwitchClip
Definition: PrefsDlg.h:113
bool GetVectorForKey(entity_t *ent, const char *key, idVec3 &vec)
void Entity_LinkBrush(entity_t *e, brush_t *b)
void CreateEntityFromName(char *pName, brush_t *pBrush, bool forceFixed, idVec3 min, idVec3 max, idVec3 org)
Definition: XYWnd.cpp:1639
Definition: Matrix.h:333
CClipPoint g_Clip1
Definition: XYWnd.cpp:58
HGLRC
Definition: win_qgl.cpp:52
virtual int AddValue(const float time, const type &value)
Definition: Curve.h:2368
CClipPoint g_PathPoints[256]
Definition: XYWnd.cpp:73
bool IsEnabled(void)
Definition: ZClip.cpp:119
bool GetBool(void) const
Definition: CVarSystem.h:142
float m_mcLeft
Definition: XYWnd.h:203
tuple f
Definition: idal.py:89
void Select_Ungroup()
bool m_bActive
Definition: XYWnd.h:159
GLuint in
Definition: glext.h:5388
bool DragDelta(int x, int y, idVec3 &move)
Definition: XYWnd.cpp:2491
const idMat3 & ToMat3(void) const
Definition: Rotation.cpp:60
bool g_bSmartGo
Definition: XYWnd.cpp:78
int m_nHeight
Definition: XYWnd.h:182
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
Definition: XYWnd.cpp:1630
#define qglLineWidth
Definition: qgl_linked.h:184
bool RotateMode()
Definition: XYWnd.cpp:4023
idVec3 tdp
Definition: XYWnd.cpp:1192
#define RAD2DEG(a)
Definition: Math.h:57
GLsizeiptr size
Definition: glext.h:3112
CPrefsDlg & g_PrefsDlg
Definition: MainFrm.cpp:75
#define qglClear
Definition: qgl_linked.h:39
Definition: XYWnd.h:70
entity_t entities
Definition: EditorMap.cpp:47
void SnapToPoint(int x, int y, idVec3 &point)
Definition: XYWnd.cpp:2234
int GetBottom(void)
Definition: ZClip.cpp:80
#define qglColor4f
Definition: qgl_linked.h:66
void ClearSelectablePoints(brush_t *b)
Definition: XYWnd.cpp:205
Definition: Str.h:116
int GetTop(void)
Definition: ZClip.cpp:75
#define qglVertex2f
Definition: qgl_linked.h:341
void DrawCameraIcon()
Definition: XYWnd.cpp:3076
void AddPointPoint(UINT nFlags, idVec3 *pVec)
Definition: XYWnd.cpp:873
brush_t * Brush_Create(idVec3 mins, idVec3 maxs, texdef_t *texdef)
float m_fScale
Definition: XYWnd.h:183
idDict epairs
Definition: EditorEntity.h:42
CPoint m_ptCursor
Definition: XYWnd.h:188
CPtrArray g_ptrMenus
Definition: XYWnd.cpp:105
afx_msg void OnRButtonDown(UINT nFlags, CPoint point)
Definition: XYWnd.cpp:1086
#define qglBlendFunc
Definition: qgl_linked.h:36
idCVar radiant_entityMode("radiant_entityMode","0", CVAR_TOOL|CVAR_ARCHIVE,"")
void SplitClip()
Definition: XYWnd.cpp:3920
const char * c_str(void) const
Definition: Str.h:487
#define FALSE
Definition: mprintf.c:70
idVec3 region_mins(MIN_WORLD_COORD, MIN_WORLD_COORD, MIN_WORLD_COORD)
#define qglColor4fv
Definition: qgl_linked.h:67
#define qglLineStipple
Definition: qgl_linked.h:183
bool g_bScreenUpdates
Definition: MainFrm.cpp:77
void Reset()
Definition: XYWnd.h:56
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
Definition: XYWnd.cpp:4462
void SetOrigin(idVec3 org)
Definition: XYWnd.cpp:3848
bool PointMode()
Definition: XYWnd.cpp:1452
idCameraDef * g_splineList
Definition: splines.cpp:35
void DrawPathLines(void)
Definition: XYWnd.cpp:3314
const int XY_RIGHT
Definition: XYWnd.cpp:87
#define qglCallLists
Definition: qgl_linked.h:38
void Brush_DrawXY(brush_t *b, int nViewType, bool bSelected, bool ignoreViewType)
#define qglVertex3f
Definition: qgl_linked.h:349
void GL_State(int stateBits)
Definition: tr_backend.cpp:239
entity_t * Entity_Create(eclass_t *c, bool forceFixed)
float fDiff(float f1, float f2)
Definition: XYWnd.cpp:117
void XY_MouseUp(int x, int y, int buttons)
Definition: XYWnd.cpp:2475
CString g_strStatus
Definition: XYWnd.cpp:49
void XY_ToPoint(int x, int y, idVec3 &point)
Definition: XYWnd.cpp:2249
#define TRUE
Definition: mprintf.c:69
void draw(bool editMode)
Definition: splines.cpp:862
void FinishSmartCreation()
Definition: XYWnd.cpp:1870
#define qglColor3fv
Definition: qgl_linked.h:51
#define qglLoadIdentity
Definition: qgl_linked.h:186
void CreateSmartEntity(CXYWnd *pWnd, int x, int y, const char *pName)
Definition: XYWnd.cpp:1820
void KillPathMode()
Definition: XYWnd.cpp:1911
bool g_bRotateMode
Definition: XYWnd.cpp:54
CMenu m_mnuDrop
Definition: XYWnd.h:212
char * va(const char *fmt,...)
Definition: Str.cpp:1568
int GetNumValues(void) const
Definition: Curve.h:56
bool g_bScaleMode
Definition: XYWnd.cpp:52
Win32Vars_t win32
Definition: win_main.cpp:65
static float ACos(float a)
Definition: Math.h:544
idVec3 m_vPressdelta
Definition: XYWnd.h:194
float m_mcTop
Definition: XYWnd.h:205
brush_t * CreateSmartBrush(idVec3 v)
Definition: XYWnd.cpp:1781
#define max(x, y)
Definition: os.h:70
GLfloat GLfloat p
Definition: glext.h:4674
int m_axisHoriz
Definition: XYWnd.h:197
void SetKeyVec3(entity_t *ent, const char *key, idVec3 v)
void FlipClip()
Definition: XYWnd.cpp:3941
float Scale()
Definition: XYWnd.h:156
afx_msg void OnTimer(UINT nIDEvent)
Definition: XYWnd.cpp:4369
void Map_SaveSelected(char *fileName)
Definition: EditorMap.cpp:1352
int m_precisionCrosshairMode
Definition: XYWnd.h:173
void ProduceSplitLists()
Definition: XYWnd.cpp:1001
bool ScaleMode()
Definition: XYWnd.cpp:4031
GLdouble GLdouble z
Definition: glext.h:3067
bool Active()
Definition: XYWnd.h:126
void Zero(void)
Definition: Vector.h:415
void SetPointMode(bool b)
Definition: XYWnd.cpp:1460
void Clip()
Definition: XYWnd.cpp:3874
void SetPointPtr(idVec3 *p)
Definition: XYWnd.h:60
#define qglMatrixMode
Definition: qgl_linked.h:203
CMemFile g_Clipboard(4096)
int sprintf(idStr &string, const char *fmt,...)
Definition: Str.cpp:1528
idVec3 & GetOrigin()
Definition: XYWnd.cpp:3840
CZClip * m_pZClip
Definition: ZWnd.h:66
CPoint m_ptDragTotal
Definition: XYWnd.h:219
GLuint start
Definition: glext.h:2845
eclass_t * eclass
Definition: EditorEntity.h:41
#define PITCH
Definition: Angles.h:41
#define qglRasterPos2f
Definition: qgl_linked.h:243
void OriginalButtonDown(UINT nFlags, CPoint point)
Definition: XYWnd.cpp:1165
void SetClipMode(bool bMode)
Definition: XYWnd.cpp:1398
bool g_bSmartWaiting
Definition: XYWnd.cpp:1806
bool ClipMode()
Definition: XYWnd.cpp:1428
brush_t g_brClipboard
Definition: XYWnd.cpp:65
eclass_t * Eclass_ForName(const char *name, bool has_brushes)
afx_msg void OnRButtonUp(UINT nFlags, CPoint point)
Definition: XYWnd.cpp:1137
HGLRC s_hglrcXY
Definition: XYWnd.cpp:602
void VectorSnapGrid(idVec3 &v)
Definition: XYWnd.cpp:291
BOOL m_bNoClamp
Definition: PrefsDlg.h:89
int g_nPathCount
Definition: XYWnd.cpp:75