📄 mainfrm.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
//
// MainFrm.cpp : implementation of the CMainFrame class
//
// Purpose: Implementation of 2D Collision System
//
// Created:
// JL 11/1/98
//
// Notes: THIS CONTAINS SOME USEFUL COMPUTATIONAL GEOMETRY ROUTINES AT THE
// END OF THIS FILE.
//
///////////////////////////////////////////////////////////////////////////////
//
// Copyright 1998 Jeff Lander, All Rights Reserved.
// For educational purposes only.
// Please do not republish in electronic or print form without permission
// Thanks - jeffl@darwin3d.com
//
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <math.h>
#include <mmsystem.h>
#include <Direct.h>
#include "Fate.h"
#include "MainFrm.h"
//IGNORE THE DOUBLE TO FLOAT CONVERSION WARNING
#pragma warning ( disable : 4244 )
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_COMMAND(ID_OPTIONS_GRID_DOWN, OnOptionsGridDown)
ON_COMMAND(ID_OPTIONS_GRIDUP, OnOptionsGridup)
ON_WM_KEYDOWN()
ON_COMMAND(ID_OPTIONS_ZOOMIN, OnOptionsZoomin)
ON_COMMAND(ID_OPTIONS_ZOOMOUT, OnOptionsZoomout)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDBLCLK()
ON_WM_RBUTTONUP()
ON_WM_PAINT()
ON_COMMAND(ID_FILE_NEW, OnFileNew)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
ON_COMMAND(ID_FILE_SAVE, OnFileSave)
//}}AFX_MSG_MAP
// Global help commands
END_MESSAGE_MAP()
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_INFO, // status line INFO
ID_INDICATOR_SNAP, // status line SNAP
ID_INDICATOR_GRID, // status line GRIDSIZE
ID_INDICATOR_SC2, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
m_offX = 0;
m_offY = 0;
m_scale = 0.4;
m_gridsize = 64;
m_snap = TRUE;
m_point = NULL;
// SET UP THE WORLD VARIABLES
m_cursector = NULL;
m_curedge = NULL;
m_firstedge = NULL; // FIRST EDGE IN A SECTOR
m_edgecnt = 0;
m_sectorcnt = 0;
m_nearest_edge = -1;
m_nearest_pnt.x = 0;
m_nearest_pnt.y = 0;
m_old_pnt.x = -2;
m_old_pnt.y = -2;
m_cam_pos.x = 0;
m_cam_pos.y = 0;
m_cam_pos.z = 0;
m_cam_yaw = 0;
m_cam_pitch = 0;
m_cam_sector = -1;
InitTrig();
}
CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
char str[80];
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
GetWindowRect(&m_window_rect);
sprintf(str,"Zoom = %2.1f",m_scale);
SetStatusText(4,str);
sprintf(str,"Grid = %3d",m_gridsize);
SetStatusText(3,str);
SetStatusText(2,"Snap On");
sprintf(str,"Sectors = %3d Edges = %3d",m_sectorcnt,m_edgecnt);
SetStatusText(1,str);
return 0;
}
void CMainFrame::SetStatusText(short id,char *string )
{
m_wndStatusBar.SetPaneText(id,string);
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CFrameWnd::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Scale the Grid Size Up
void CMainFrame::OnOptionsGridup()
{
char str[80];
if (m_gridsize <= 1024) m_gridsize *= 2;
sprintf(str,"Grid = %4d",m_gridsize);
SetStatusText(3,str);
Invalidate (TRUE);
}
/////////////////////////////////////////////////////////////////////////////
// Scale the Grid Size Down
void CMainFrame::OnOptionsGridDown()
{
char str[80];
if (m_gridsize > 2)
{
m_gridsize /= 2;
sprintf(str,"Grid = %4d",m_gridsize);
}
else
{
m_gridsize = 1;
sprintf(str,"Grid OFF");
}
SetStatusText(3,str);
Invalidate (TRUE);
}
void CMainFrame::OnOptionsZoomin()
{
char str[80];
if (m_scale <= 10.0) m_scale += .1;
sprintf(str,"Zoom = %2.1f",m_scale);
SetStatusText(4,str);
Invalidate (TRUE);
}
void CMainFrame::OnOptionsZoomout()
{
char str[80];
if (m_scale > 0.2)
{
m_scale -= 0.1;
}
sprintf(str,"Zoom = %2.1f",m_scale);
SetStatusText(4,str);
Invalidate (TRUE);
}
void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
tPoint3D temp;
tPoint2D temp2D;
int cx, cy;
CRect rect;
cx = (GetSystemMetrics(SM_CXFULLSCREEN) - (640 + 8)) / 2;
cy = (GetSystemMetrics(SM_CYFULLSCREEN) - (480 + 94)) / 2;
switch (nChar)
{
case VK_INSERT:
InsertPoint();
Invalidate(TRUE);
break;
case VK_DELETE:
DeleteSector();
Invalidate(TRUE);
break;
case VK_RETURN:
CloseSector();
Invalidate(TRUE);
break;
case VK_ADD:
OnOptionsGridup();
break;
case VK_SUBTRACT:
OnOptionsGridDown();
break;
case 'A':
OnOptionsZoomin();
break;
case 'M':
break;
case 'Z':
OnOptionsZoomout();
break;
case 'S':
m_snap = TRUE - m_snap;
if (m_snap)
SetStatusText(2,"Snap On");
else
SetStatusText(2,"Snap Off");
break;
case VK_UP:
temp.x = m_cam_pos.x + (m_sin[m_cam_yaw]>>13);
temp.z = m_cam_pos.z + (m_cos[m_cam_yaw]>>13);
if (m_cam_sector == -1)
{
m_cam_pos.x = temp.x;
m_cam_pos.z = temp.z;
temp2D.x = temp.x;
temp2D.y = temp.z;
m_cam_sector = InsideSector(&temp2D);
}
else
{
if (CheckCollision(m_cam_sector,&temp))
{
m_cam_pos.x = temp.x;
m_cam_pos.z = temp.z;
}
}
Invalidate(TRUE);
break;
case VK_DOWN:
temp.x = m_cam_pos.x - (m_sin[m_cam_yaw]>>13);
temp.z = m_cam_pos.z - (m_cos[m_cam_yaw]>>13);
if (m_cam_sector == -1)
{
m_cam_pos.x = temp.x;
m_cam_pos.z = temp.z;
temp2D.x = temp.x;
temp2D.y = temp.z;
m_cam_sector = InsideSector(&temp2D);
}
else
{
if (CheckCollision(m_cam_sector,&temp))
{
m_cam_pos.x = temp.x;
m_cam_pos.z = temp.z;
}
}
Invalidate(TRUE);
break;
case VK_LEFT:
m_cam_yaw += (4096 - 128);
m_cam_yaw %= 4096;
Invalidate(TRUE);
break;
case VK_RIGHT:
m_cam_yaw += 128;
m_cam_yaw %= 4096;
Invalidate(TRUE);
break;
}
CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}
//////////////////////////////////////////////////////////////////
// Procedure: OnRButtonUp
// Purpose: Right Mouse Button Handler
//////////////////////////////////////////////////////////////////
void CMainFrame::OnRButtonUp(UINT nFlags, CPoint point)
{
tPoint2D temp;
// MOVE THE CAMERA POSITION TO WHERE THE USER CLICKS
m_cam_pos.x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale);
m_cam_pos.z = -(long)((point.y + m_offY - (m_sizeY / 2)) / m_scale);
temp.x = m_cam_pos.x;
temp.y = m_cam_pos.z;
m_cam_sector = InsideSector(&temp);
Invalidate(TRUE);
CFrameWnd::OnRButtonUp(nFlags, point);
}
#define VERTEX_SNAP_PROXIMITY 100
void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point)
{
short loop,t_sector,t_edge;
tPoint2D temp;
long dist;
char message[80];
temp.x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale);
temp.y = (long)-((point.y + m_offY - (m_sizeY / 2)) / m_scale);
if ((nFlags & MK_CONTROL) > 0)
{
t_sector = -1;
for (loop = 0; loop < m_edgecnt; loop++)
{
dist = (temp.x - m_edgelist[loop].pos.x) * // SQUARED DISTANCE
(temp.x - m_edgelist[loop].pos.x) +
(temp.y - m_edgelist[loop].pos.y) *
(temp.y - m_edgelist[loop].pos.y);
if (dist < VERTEX_SNAP_PROXIMITY)
{
temp.x = m_edgelist[loop].pos.x;
temp.y = m_edgelist[loop].pos.y;
t_sector = m_edgelist[loop].sector;
t_edge = loop;
}
}
if (t_sector == -1) // IF I DIDN'T CLICK ON AN EXISTING POINT, SNAP IT
{
SnapPoint(&temp);
// CHECK ALL POINTS AGAIN ONCE I HAVE SNAPPED
for (loop = 0; loop < m_edgecnt; loop++)
{
dist = (temp.x - m_edgelist[loop].pos.x) * // SQUARED DISTANCE
(temp.x - m_edgelist[loop].pos.x) +
(temp.y - m_edgelist[loop].pos.y) *
(temp.y - m_edgelist[loop].pos.y);
if (dist < VERTEX_SNAP_PROXIMITY)
{
temp.x = m_edgelist[loop].pos.x;
temp.y = m_edgelist[loop].pos.y;
t_sector = m_edgelist[loop].sector;
t_edge = loop;
}
}
}
if (m_cursector == NULL) // haven't created a sector
{
m_cursector = &m_sectorlist[m_sectorcnt];
m_cursector->edge = m_edgecnt;
m_cursector->edgecnt = 1;
m_cursector->flags = 0;
m_curedge = &m_edgelist[m_edgecnt];
m_curedge->pos.x = temp.x;
m_curedge->pos.y = temp.y;
m_curedge->sector = m_sectorcnt;
m_curedge->backsector = -1;
m_curedge->backedge = -1;
m_curedge->nextedge = -1;
m_curedge->prevedge = -1;
m_firstedge = m_curedge;
m_sectorcnt++;
m_edgecnt++;
Invalidate(TRUE);
}
else
{
if (&m_sectorlist[t_sector] == m_cursector)
{
if (t_edge == m_cursector->edge) // CLOSED THE SECTOR
{
m_curedge->nextedge = m_cursector->edge;
m_firstedge->prevedge = m_edgecnt - 1; // LINK BACK THE START TO THE END
m_cursector->flags = SECTOR_FLAGS_CLOSED;
m_cursector->ceil_tex = 0;
m_cursector->floor_tex = 0;
m_cursector->floor_height = 0;
m_cursector->ceil_height = 2048;
m_cursector = NULL;
CheckDoubleSided();
}
}
else
{
m_curedge->nextedge = m_edgecnt;
m_cursector->edgecnt++;
m_curedge = &m_edgelist[m_edgecnt];
m_curedge->pos.x = temp.x;
m_curedge->pos.y = temp.y;
m_curedge->sector = m_sectorcnt - 1;
m_curedge->backsector = -1;
m_curedge->backedge = -1;
m_curedge->nextedge = -1;
m_curedge->prevedge = m_edgecnt - 1;
m_edgecnt++;
}
Invalidate(TRUE);
}
m_point = NULL;
sprintf(message,"Sectors = %d Edges = %d",m_sectorcnt,m_edgecnt);
SetStatusText(1,message);
}
else if ((nFlags & MK_SHIFT) > 0)
{
m_clickpoint = point;
}
else // MOVE A SET POINT
{
m_point = NULL;
for (loop = 0; loop < m_edgecnt; loop++)
{
dist = (temp.x - m_edgelist[loop].pos.x) *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -