xywnd.cpp

来自「quake3工具源码。包括生成bsp文件」· C++ 代码 · 共 2,569 行 · 第 1/5 页

CPP
2,569
字号
// XYWnd.cpp : implementation file
//
// QERadiant
//
// 

#include "stdafx.h"
#include "Radiant.h"
#include "XYWnd.h"
#include "qe3.h"
#include "PrefsDlg.h"
#include "DialogInfo.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define	PAGEFLIPS	2


const char* g_pDimStrings[] = {"x:%.f", "y:%.f", "z:%.f"};
const char* g_pOrgStrings[] = {"(x:%.f  y:%.f)", "(x:%.f  z:%.f)", "(y:%.f  z:%.f)"};
CString g_strDim;
CString g_strStatus;

bool g_bCrossHairs = false;
bool g_bScaleMode;
int g_nScaleHow;
bool g_bRotateMode;
bool g_bClipMode;
bool g_bRogueClipMode;
bool g_bSwitch;
CClipPoint g_Clip1;
CClipPoint g_Clip2;
CClipPoint g_Clip3;
CClipPoint* g_pMovingClip;
brush_t g_brFrontSplits;
brush_t g_brBackSplits;

brush_t g_brClipboard;
brush_t g_brUndo;
entity_t	g_enClipboard;

vec3_t g_vRotateOrigin;
vec3_t g_vRotation;

bool g_bPathMode;
CClipPoint g_PathPoints[256];
CClipPoint* g_pMovingPath;
int g_nPathCount;
int g_nPathLimit;

bool g_bSmartGo;

bool g_bPointMode;
CClipPoint g_PointPoints[512];
CClipPoint* g_pMovingPoint;
int g_nPointCount;
int g_nPointLimit;


const int XY_LEFT = 0x01;
const int XY_RIGHT = 0x02;
const int XY_UP = 0x04;
const int XY_DOWN = 0x08;

PFNPathCallback* g_pPathFunc = NULL;

void AcquirePath(int nCount, PFNPathCallback* pFunc)
{
  g_nPathCount = 0;
  g_nPathLimit = nCount;
  g_pPathFunc = pFunc;
  g_bPathMode = true;
}


CPtrArray g_ptrMenus;

CMemFile g_Clipboard(4096);
CMemFile g_PatchClipboard(4096);

extern int pressx;
extern int pressy;


/////////////////////////////////////////////////////////////////////////////
// CXYWnd

IMPLEMENT_DYNCREATE(CXYWnd, CWnd);

CXYWnd::CXYWnd()
{
  g_brClipboard.next = &g_brClipboard;
  g_brUndo.next = &g_brUndo;
  g_nScaleHow = 0;
  g_bRotateMode = false;
  g_bClipMode = false;
  g_bRogueClipMode = false;
  g_bSwitch = true;
  g_pMovingClip = NULL;
  g_pMovingPath = NULL;
  g_brFrontSplits.next = &g_brFrontSplits;
  g_brBackSplits.next = &g_brBackSplits;
  m_bActive = false;
  //m_bTiming = true;
  m_bTiming = false;
  m_bRButtonDown = false;
  m_nUpdateBits = W_XY;
  g_bPathMode = false;
  g_nPathCount = 0;
  g_nPathLimit = 0;
  m_nTimerID = -1;
  XY_Init();
}

CXYWnd::~CXYWnd()
{
  int nSize = g_ptrMenus.GetSize();
  while (nSize > 0)
  {
    CMenu* pMenu = reinterpret_cast<CMenu*>(g_ptrMenus.GetAt(nSize-1));
    ASSERT(pMenu);
    pMenu->DestroyMenu();
    delete pMenu;
    nSize--;
  }
  g_ptrMenus.RemoveAll();
  m_mnuDrop.DestroyMenu();
}


BEGIN_MESSAGE_MAP(CXYWnd, CWnd)
	//{{AFX_MSG_MAP(CXYWnd)
	ON_WM_CREATE()
	ON_WM_LBUTTONDOWN()
	ON_WM_MBUTTONDOWN()
	ON_WM_RBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MBUTTONUP()
	ON_WM_RBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_PAINT()
	ON_WM_KEYDOWN()
	ON_WM_SIZE()
	ON_WM_DESTROY()
	ON_COMMAND(ID_SELECT_MOUSEROTATE, OnSelectMouserotate)
	ON_WM_TIMER()
	ON_WM_KEYUP()
	ON_WM_NCCALCSIZE()
	ON_WM_KILLFOCUS()
	ON_WM_SETFOCUS()
	ON_WM_CLOSE()
	ON_COMMAND(ID_SELECTION_MAKE_DETAIL, CMainFrame::OnSelectionMakeDetail)
	ON_COMMAND(ID_SELECTION_MAKE_STRUCTURAL, CMainFrame::OnSelectionMakeStructural)
	ON_COMMAND(ID_SELECTION_SELECTCOMPLETETALL, CMainFrame::OnSelectionSelectcompletetall)
	ON_COMMAND(ID_SELECTION_SELECTINSIDE, CMainFrame::OnSelectionSelectinside)
	ON_COMMAND(ID_SELECTION_SELECTPARTIALTALL, CMainFrame::OnSelectionSelectpartialtall)
	ON_COMMAND(ID_SELECTION_SELECTTOUCHING, CMainFrame::OnSelectionSelecttouching)
	ON_COMMAND(ID_SELECTION_UNGROUPENTITY, CMainFrame::OnSelectionUngroupentity)
	//}}AFX_MSG_MAP
  ON_COMMAND_RANGE(ID_ENTITY_START, ID_ENTITY_END, OnEntityCreate)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CXYWnd message handlers
LONG WINAPI XYWndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CXYWnd::PreCreateWindow(CREATESTRUCT& cs) 
{
  WNDCLASS wc;
  HINSTANCE hInstance = AfxGetInstanceHandle();
  if (::GetClassInfo(hInstance, XY_WINDOW_CLASS, &wc) == FALSE)
  {
    // Register a new class
  	memset (&wc, 0, sizeof(wc));
    wc.style         = CS_NOCLOSE | CS_OWNDC;
    wc.lpszClassName = XY_WINDOW_CLASS;
    wc.hCursor       = NULL; //LoadCursor (NULL,IDC_ARROW);
    wc.lpfnWndProc   = ::DefWindowProc;
    if (AfxRegisterClass(&wc) == FALSE)
      Error ("CCamWnd RegisterClass: failed");
  }

  cs.lpszClass = XY_WINDOW_CLASS;
  cs.lpszName = "VIEW";
  if (cs.style != QE3_CHILDSTYLE)
    cs.style = QE3_SPLITTER_STYLE;

	return CWnd::PreCreateWindow(cs);
}

HDC   s_hdcXY;
HGLRC s_hglrcXY;

static unsigned s_stipple[32] =
{
	0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
	0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
	0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
	0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
	0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
	0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
	0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
	0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555,
};

/*
============
WXY_WndProc
============
*/
LONG WINAPI XYWndProc (
    HWND    hWnd,
    UINT    uMsg,
    WPARAM  wParam,
    LPARAM  lParam)
{
    switch (uMsg)
    {
	case WM_DESTROY:
		QEW_StopGL( hWnd, s_hglrcXY, s_hdcXY );
		return 0;

	case WM_NCCALCSIZE:// don't let windows copy pixels
		DefWindowProc (hWnd, uMsg, wParam, lParam);
		return WVR_REDRAW;

	case WM_KILLFOCUS:
	case WM_SETFOCUS:
		SendMessage( hWnd, WM_NCACTIVATE, uMsg == WM_SETFOCUS, 0 );
		return 0;

   	case WM_CLOSE:
        DestroyWindow (hWnd);
		return 0;
    }

	return DefWindowProc (hWnd, uMsg, wParam, lParam);
}


static void WXY_InitPixelFormat( PIXELFORMATDESCRIPTOR *pPFD )
{
	memset( pPFD, 0, sizeof( *pPFD ) );

	pPFD->nSize    = sizeof( PIXELFORMATDESCRIPTOR );
	pPFD->nVersion = 1;
	pPFD->dwFlags  = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
	pPFD->iPixelType = PFD_TYPE_RGBA;
	pPFD->cColorBits = 24;
	pPFD->cDepthBits = 32;
	pPFD->iLayerType = PFD_MAIN_PLANE;

}

void WXY_Print( void )
{
	DOCINFO di;

	PRINTDLG pd;

	/*
	** initialize the PRINTDLG struct and execute it
	*/
	memset( &pd, 0, sizeof( pd ) );
	pd.lStructSize = sizeof( pd );
	pd.hwndOwner = g_qeglobals.d_hwndXY;
	pd.Flags = PD_RETURNDC;
	pd.hInstance = 0;
	if ( !PrintDlg( &pd ) || !pd.hDC )
	{
		MessageBox( g_qeglobals.d_hwndMain, "Could not PrintDlg()", "QE4 Print Error", MB_OK | MB_ICONERROR );
		return;
	}

	/*
	** StartDoc
	*/
	memset( &di, 0, sizeof( di ) );
	di.cbSize = sizeof( di );
	di.lpszDocName = "QE4";
	if ( StartDoc( pd.hDC, &di ) <= 0 )
	{
		MessageBox( g_qeglobals.d_hwndMain, "Could not StartDoc()", "QE4 Print Error", MB_OK | MB_ICONERROR );
		return;
	}

	/*
	** StartPage
	*/
	if ( StartPage( pd.hDC ) <= 0 )
	{
		MessageBox( g_qeglobals.d_hwndMain, "Could not StartPage()", "QE4 Print Error", MB_OK | MB_ICONERROR );
		return;
	}

	/*
	** read pixels from the XY window
	*/
	{
		int bmwidth = 320, bmheight = 320;
		int pwidth, pheight;

		RECT r;

		GetWindowRect( g_qeglobals.d_hwndXY, &r );

		bmwidth  = r.right - r.left;
		bmheight = r.bottom - r.top;

		pwidth  = GetDeviceCaps( pd.hDC, PHYSICALWIDTH ) - GetDeviceCaps( pd.hDC, PHYSICALOFFSETX );
		pheight = GetDeviceCaps( pd.hDC, PHYSICALHEIGHT ) - GetDeviceCaps( pd.hDC, PHYSICALOFFSETY );

		StretchBlt( pd.hDC,
			0, 0,
			pwidth, pheight,
			s_hdcXY,
			0, 0,
			bmwidth, bmheight,
			SRCCOPY );
	}

	/*
	** EndPage and EndDoc
	*/
	if ( EndPage( pd.hDC ) <= 0 )
	{
		MessageBox( g_qeglobals.d_hwndMain, "QE4 Print Error", "Could not EndPage()", MB_OK | MB_ICONERROR );
		return;
	}

	if ( EndDoc( pd.hDC ) <= 0 )
	{
		MessageBox( g_qeglobals.d_hwndMain, "QE4 Print Error", "Could not EndDoc()", MB_OK | MB_ICONERROR );
		return;
	}
}

int CXYWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

  s_hdcXY = ::GetDC(GetSafeHwnd());
	QEW_SetupPixelFormat(s_hdcXY, false);
	if ( ( s_hglrcXY = qwglCreateContext( s_hdcXY ) ) == 0 )
	  Error( "wglCreateContext in WXY_WndProc failed" );

	if (!qwglShareLists( g_qeglobals.d_hglrcBase, s_hglrcXY ) )
	  Error( "wglShareLists in WXY_WndProc failed" );

  if (!qwglMakeCurrent( s_hdcXY, s_hglrcXY ))
	  Error ("wglMakeCurrent failed");

	qglPolygonStipple ((unsigned char *)s_stipple);
	qglLineStipple (3, 0xaaaa);
  g_qeglobals.d_hwndXY = GetSafeHwnd();
	return 0;
}

float ptSum(vec3_t pt)
{
  return pt[0] + pt[1] + pt[2];
}

void CXYWnd::DropClipPoint(UINT nFlags, CPoint point)
{
  CRect rctZ;
  GetClientRect(rctZ);
  if (g_pMovingClip)
  {
    SetCapture();
    SnapToPoint (point.x, rctZ.Height() - 1 - point.y , *g_pMovingClip);
  }
  else
  {
    vec3_t* pPt = NULL;
    if (g_Clip1.Set() == false)
    {
      pPt = g_Clip1;
      g_Clip1.Set(true);
      g_Clip1.m_ptScreen = point;
    }
    else 
    if (g_Clip2.Set() == false)
    {
      pPt = g_Clip2;
      g_Clip2.Set(true);
      g_Clip2.m_ptScreen = point;
    }
    else 
    if (g_Clip3.Set() == false)
    {
      pPt = g_Clip3;
      g_Clip3.Set(true);
      g_Clip3.m_ptScreen = point;
    }
    else 
    {
      RetainClipMode(true);
      pPt = g_Clip1;
      g_Clip1.Set(true);
      g_Clip1.m_ptScreen = point;
    }
    SnapToPoint (point.x, rctZ.Height() - 1 - point.y , *pPt);
  }
  Sys_UpdateWindows(XY | W_CAMERA_IFON);
}


void CXYWnd::DropPathPoint(UINT nFlags, CPoint point)
{
  CRect rctZ;
  GetClientRect(rctZ);
  if (g_pMovingPath)
  {
    SetCapture();
    SnapToPoint (point.x, rctZ.Height() - 1 - point.y , *g_pMovingPath);
  }
  else
  {
    g_PathPoints[g_nPathCount].Set(true);
    g_PathPoints[g_nPathCount].m_ptScreen = point;
    SnapToPoint(point.x, rctZ.Height() - 1 - point.y, g_PathPoints[g_nPathCount]);
    g_nPathCount++;
    if (g_nPathCount == g_nPathLimit)
    {
      if (g_pPathFunc)
        g_pPathFunc(true, g_nPathCount);
      g_nPathCount = 0;
      g_bPathMode = false;
      g_pPathFunc = NULL;
    }
  }
  Sys_UpdateWindows(XY | W_CAMERA_IFON);
}

void CXYWnd::AddPointPoint(UINT nFlags, vec3_t* pVec)
{
  g_PointPoints[g_nPointCount].Set(true);
  //g_PointPoints[g_nPointCount].m_ptScreen = point;
  _VectorCopy(*pVec, g_PointPoints[g_nPointCount]);
  g_PointPoints[g_nPointCount].SetPointPtr(pVec);
  g_nPointCount++;
  Sys_UpdateWindows(XY | W_CAMERA_IFON);
}


void CXYWnd::OnLButtonDown(UINT nFlags, CPoint point) 
{
  g_pParentWnd->SetActiveXY(this);
  UndoCopy();

	// plugin entities
	if (DispatchOnLButtonDown(nFlags, point.x, point.y ))
		return;

  if (ClipMode() && !RogueClipMode())
  {
    DropClipPoint(nFlags, point);
  }
  else if (PathMode())
  {
    DropPathPoint(nFlags, point);
  }
  else OriginalButtonDown(nFlags, point);
}

void CXYWnd::OnMButtonDown(UINT nFlags, CPoint point) 
{
  OriginalButtonDown(nFlags, point);
}


float Betwixt(float f1, float f2)
{
  if (f1 > f2)
    return f2 + ((f1 - f2) / 2);
  else
    return f1 + ((f2 - f1) / 2);
}

void CXYWnd::ProduceSplits(brush_t** pFront, brush_t** pBack)
{
  *pFront = NULL;
  *pBack = NULL;
  if (ClipMode())
  {
    if (g_Clip1.Set() && g_Clip2.Set())
    {
      face_t face;
      VectorCopy(g_Clip1.m_ptClip,face.planepts[0]);
      VectorCopy(g_Clip2.m_ptClip,face.planepts[1]);
      VectorCopy(g_Clip3.m_ptClip,face.planepts[2]);
      if (selected_brushes.next && (selected_brushes.next->next == &selected_brushes))
      {
        if (g_Clip3.Set() == false)
        {
          if (m_nViewType == XY)
          {
            face.planepts[0][2] = selected_brushes.next->mins[2];
            face.planepts[1][2] = selected_brushes.next->mins[2];
            face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]);
            face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);
            face.planepts[2][2] = selected_brushes.next->maxs[2];
          }
          else if (m_nViewType == YZ)
          {
            face.planepts[0][0] = selected_brushes.next->mins[0];
            face.planepts[1][0] = selected_brushes.next->mins[0];
            face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?