Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
486 lines
12 KiB
C++
486 lines
12 KiB
C++
// mapqueryDlg.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "mapquery.h"
|
|
#include "mapqueryDlg.h"
|
|
#include <stdio.h>
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define MAPLEFT 135
|
|
#define MAPTOP 10
|
|
#define MAPWIDTH 512
|
|
#define MAPHEIGHT 512
|
|
|
|
const unsigned short LEGPASS_FLAG = 0x0001; // true if legged units cannot use
|
|
const unsigned short HOVERPASS_FLAG = 0x0002; // true if hover units cannot use
|
|
const unsigned short TRACKPASS_FLAG = 0x0004; // true if track units cannot use
|
|
const unsigned short WHEELPASS_FLAG = 0x0008; // true if wheel units cannot use
|
|
const unsigned short WATERPASS_FLAG = 0x0010; // true if water units cannot use
|
|
const unsigned short JUMPPASS_FLAG = 0x0020; // true if cannot jump through
|
|
const unsigned short MOVEPASSNOW_FLAG = 0x0040; // if a vehicle has this cell blocked now
|
|
const unsigned short BRIDGE_FLAG = 0x0080; // true if this cell is a bridge cell
|
|
const unsigned short WATER1_FLAG = 0x0100; // with water 2 for four levels of water
|
|
const unsigned short WATER2_FLAG = 0x0200; // no, shallow, medium, deep
|
|
const unsigned short STEEP1_FLAG = 0x0400; // with steep 2 for steepness of slope for descending, going up uses blocked flags
|
|
const unsigned short STEEP2_FLAG = 0x0800; // mech down, track down, wheel down, hover down
|
|
const unsigned short SLOPEDIR1_FLAG = 0x1000; // quanta of slope direction
|
|
const unsigned short SLOPEDIR2_FLAG = 0x2000;
|
|
const unsigned short SLOPEDIR3_FLAG = 0x4000;
|
|
|
|
const int HOVERDOWN_SLOPE = 0;
|
|
const int WHEELDOWN_SLOPE = 1;
|
|
const int TRACKDOWN_SLOPE = 2;
|
|
const int LEGDOWN_SLOPE = 3;
|
|
const int STEEP_MASK = 0x0c00;
|
|
const int STEEP_SHIFT = 10;
|
|
|
|
const int NO_WATER = 0;
|
|
const int SHALLOW_WATER = 1;
|
|
const int MEDIUM_WATER = 2;
|
|
const int DEEP_WATER = 3;
|
|
const int WATER_MASK = 0x0300;
|
|
const int WATER_SHIFT = 8;
|
|
|
|
const int SLOPEDIR_MASK = 0x7000;
|
|
const int SLOPEDIR_SHIFT = 12;
|
|
|
|
const float LEGUP_SLOPE_THRESHOLD = 0.707f; //cos (45 deg)
|
|
const float LEGDOWN_SLOPE_THRESHOLD = 0.5f; //cos (60 deg)
|
|
|
|
const float TRACKUP_SLOPE_THRESHOLD = 0.819f; //cos (35 deg)
|
|
const float TRACKDOWN_SLOPE_THRESHOLD = 0.707f; //cos (45 deg)
|
|
|
|
const float WHEELUP_SLOPE_THRESHOLD = 0.906f; //cos (25 deg)
|
|
const float WHEELDOWN_SLOPE_THRESHOLD = 0.819f; //cos (35 deg)
|
|
|
|
const float HOVERUP_SLOPE_THRESHOLD = 0.965f; //cos (15 deg)
|
|
const float HOVERDOWN_SLOPE_THRESHOLD = 0.906f; //cos (25 deg)
|
|
|
|
const unsigned short BLOCKED_FLAGS = 0x003f; // for all blocked flags
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CAboutDlg dialog used for App About
|
|
|
|
class CAboutDlg : public CDialog
|
|
{
|
|
public:
|
|
CAboutDlg();
|
|
|
|
// Dialog Data
|
|
//{{AFX_DATA(CAboutDlg)
|
|
enum { IDD = IDD_ABOUTBOX };
|
|
//}}AFX_DATA
|
|
|
|
// ClassWizard generated virtual function overrides
|
|
//{{AFX_VIRTUAL(CAboutDlg)
|
|
protected:
|
|
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
|
//}}AFX_VIRTUAL
|
|
|
|
// Implementation
|
|
protected:
|
|
//{{AFX_MSG(CAboutDlg)
|
|
//}}AFX_MSG
|
|
DECLARE_MESSAGE_MAP()
|
|
};
|
|
|
|
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
|
|
{
|
|
//{{AFX_DATA_INIT(CAboutDlg)
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
|
|
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CAboutDlg)
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CAboutDlg)
|
|
// No message handlers
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMapqueryDlg dialog
|
|
|
|
CMapqueryDlg::CMapqueryDlg(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CMapqueryDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CMapqueryDlg)
|
|
m_YValue = 0;
|
|
m_XValue = 0;
|
|
m_Value = _T("");
|
|
//}}AFX_DATA_INIT
|
|
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
|
|
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
|
m_Width = 1;
|
|
m_Height = 1;
|
|
}
|
|
|
|
void CMapqueryDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CMapqueryDlg)
|
|
DDX_Control(pDX, IDC_WHEEL, m_Wheel);
|
|
DDX_Control(pDX, IDC_TRACK, m_Track);
|
|
DDX_Control(pDX, IDC_LEG, m_Leg);
|
|
DDX_Control(pDX, IDC_HOVER, m_Hover);
|
|
DDX_Control(pDX, IDC_BLOCK, m_Block);
|
|
DDX_Text(pDX, IDC_EDITYVALUE, m_YValue);
|
|
DDV_MinMaxInt(pDX, m_YValue, 0, m_Height);
|
|
DDX_Text(pDX, IDC_EDITXVALUE, m_XValue);
|
|
DDV_MinMaxInt(pDX, m_XValue, 0, m_Width);
|
|
DDX_Text(pDX, IDC_MAPVALUE, m_Value);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CMapqueryDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CMapqueryDlg)
|
|
ON_WM_SYSCOMMAND()
|
|
ON_WM_PAINT()
|
|
ON_WM_QUERYDRAGICON()
|
|
ON_BN_CLICKED(IDC_QUERY, OnQuery)
|
|
ON_BN_CLICKED(IDC_FILEOPEN, OnFileopen)
|
|
ON_WM_MOUSEMOVE()
|
|
ON_BN_CLICKED(IDC_BLOCK, OnBlock)
|
|
ON_BN_CLICKED(IDC_HOVER, OnHover)
|
|
ON_BN_CLICKED(IDC_LEG, OnLeg)
|
|
ON_BN_CLICKED(IDC_TRACK, OnTrack)
|
|
ON_BN_CLICKED(IDC_WHEEL, OnWheel)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMapqueryDlg message handlers
|
|
|
|
BOOL CMapqueryDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
// Add "About..." menu item to system menu.
|
|
|
|
// IDM_ABOUTBOX must be in the system command range.
|
|
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
|
|
ASSERT(IDM_ABOUTBOX < 0xF000);
|
|
|
|
CMenu* pSysMenu = GetSystemMenu(FALSE);
|
|
if (pSysMenu != NULL)
|
|
{
|
|
CString strAboutMenu;
|
|
strAboutMenu.LoadString(IDS_ABOUTBOX);
|
|
if (!strAboutMenu.IsEmpty())
|
|
{
|
|
pSysMenu->AppendMenu(MF_SEPARATOR);
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
|
|
}
|
|
}
|
|
|
|
// Set the icon for this dialog. The framework does this automatically
|
|
// when the application's main window is not a dialog
|
|
SetIcon(m_hIcon, TRUE); // Set big icon
|
|
SetIcon(m_hIcon, FALSE); // Set small icon
|
|
|
|
// TODO: Add extra initialization here
|
|
|
|
m_MapSurf.Create (10,10,24);
|
|
m_MapSurf.SetColor (RGB (0,0,0));
|
|
m_Data = NULL;
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
}
|
|
|
|
void CMapqueryDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
|
{
|
|
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
|
|
{
|
|
CAboutDlg dlgAbout;
|
|
dlgAbout.DoModal();
|
|
}
|
|
else
|
|
{
|
|
CDialog::OnSysCommand(nID, lParam);
|
|
}
|
|
}
|
|
|
|
// If you add a minimize button to your dialog, you will need the code below
|
|
// to draw the icon. For MFC applications using the document/view model,
|
|
// this is automatically done for you by the framework.
|
|
|
|
void CMapqueryDlg::OnPaint()
|
|
{
|
|
if (IsIconic())
|
|
{
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
|
|
|
|
// Center icon in client rectangle
|
|
int cxIcon = GetSystemMetrics(SM_CXICON);
|
|
int cyIcon = GetSystemMetrics(SM_CYICON);
|
|
CRect rect;
|
|
GetClientRect(&rect);
|
|
int x = (rect.Width() - cxIcon + 1) / 2;
|
|
int y = (rect.Height() - cyIcon + 1) / 2;
|
|
|
|
// Draw the icon
|
|
dc.DrawIcon(x, y, m_hIcon);
|
|
}
|
|
else
|
|
{
|
|
CPaintDC dc(this);
|
|
HDC surfdc;
|
|
|
|
surfdc = m_MapSurf.GetDC ();
|
|
CDC surface;
|
|
|
|
surface.Attach (surfdc);
|
|
|
|
dc.StretchBlt (MAPLEFT,MAPTOP,MAPWIDTH,MAPHEIGHT,&surface,0,0,m_MapSurf.GetWidth (),m_MapSurf.GetHeight (),SRCCOPY);
|
|
|
|
surface.Detach ();
|
|
m_MapSurf.ReleaseDC (surfdc);
|
|
|
|
CDialog::OnPaint();
|
|
}
|
|
}
|
|
|
|
// The system calls this to obtain the cursor to display while the user drags
|
|
// the minimized window.
|
|
HCURSOR CMapqueryDlg::OnQueryDragIcon()
|
|
{
|
|
return (HCURSOR) m_hIcon;
|
|
}
|
|
|
|
void CMapqueryDlg::OnQuery()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
UpdateData (TRUE);
|
|
|
|
int value;
|
|
value = m_Data[m_YValue][m_XValue];
|
|
m_Value.Format ("%x",value);
|
|
UpdateData (FALSE);
|
|
}
|
|
|
|
void CMapqueryDlg::OnFileopen()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
CFileDialog dlg(TRUE);
|
|
|
|
dlg.m_ofn.lpstrInitialDir = "content\\missions";
|
|
|
|
if (dlg.DoModal ()== IDOK)
|
|
{
|
|
CString filename;
|
|
FILE *file;
|
|
int datasize,size,chunksize;
|
|
|
|
m_Wheel.SetCheck (1);
|
|
m_Track.SetCheck (1);
|
|
m_Leg.SetCheck (1);
|
|
m_Hover.SetCheck (1);
|
|
m_Block.SetCheck (1);
|
|
|
|
filename = dlg.GetPathName ();
|
|
file = fopen ((LPCTSTR) filename,"rb");
|
|
|
|
m_Data = NULL;
|
|
m_AllocWidth = 0;
|
|
m_AllocHeight = 0;
|
|
fread (&m_Width,sizeof (m_Width),1,file);
|
|
m_Width *= -1;
|
|
fread (&m_Height,sizeof (m_Height),1,file);
|
|
m_Height *= -1;
|
|
fread (&datasize,sizeof (datasize),1,file);
|
|
|
|
m_Width /= 10;
|
|
m_Height /= 10;
|
|
m_Data = new unsigned short *[m_Height];
|
|
m_AllocHeight = m_Height;
|
|
m_AllocWidth = m_Width;
|
|
for (int i=0;i<m_Height;i++)
|
|
{
|
|
m_Data[i] = new unsigned short[m_Width];
|
|
}
|
|
|
|
|
|
size = m_Height;
|
|
chunksize = m_Width;
|
|
chunksize <<= 1;
|
|
for (i=0;i<size;i++)
|
|
{
|
|
fread (m_Data[size - i - 1],chunksize,1,file);
|
|
datasize -= chunksize;
|
|
}
|
|
|
|
int x,y;
|
|
for (y=0;y<m_Height;y++)
|
|
{
|
|
for (x=0;x<(m_Width>>1);x++)
|
|
{
|
|
unsigned short temp;
|
|
temp = m_Data[y][x];
|
|
m_Data[y][x] = m_Data[y][m_Width-x];
|
|
m_Data[y][m_Width-x] = temp;
|
|
}
|
|
}
|
|
|
|
fclose (file);
|
|
BuildSurface ();
|
|
}
|
|
|
|
}
|
|
|
|
void CMapqueryDlg::BuildSurface(void)
|
|
{
|
|
int x,y;
|
|
|
|
if (m_Data)
|
|
{
|
|
m_MapSurf.Create (m_Width,m_Height,24);
|
|
for (y=0;y<m_Height;y++)
|
|
{
|
|
for (x=0;x<m_Width;x++)
|
|
{
|
|
m_MapSurf.SetColor (x,y,RGB (255,255,255));
|
|
if (m_Data[y][x] & WATER_MASK)
|
|
{
|
|
switch ((m_Data[y][x] & WATER_MASK) >> WATER_SHIFT)
|
|
{
|
|
case SHALLOW_WATER:
|
|
m_MapSurf.SetColor (x,y,RGB (0,0,255));
|
|
break;
|
|
case MEDIUM_WATER:
|
|
m_MapSurf.SetColor (x,y,RGB (0,0,128));
|
|
break;
|
|
case DEEP_WATER:
|
|
m_MapSurf.SetColor (x,y,RGB (0,0,64));
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
else if ((m_Leg.GetCheck ()) && (m_Data[y][x] & (LEGPASS_FLAG)))
|
|
{
|
|
m_MapSurf.SetColor (x,y,RGB (255,0,0));
|
|
}
|
|
else if ((m_Track.GetCheck ()) && (m_Data[y][x] & (TRACKPASS_FLAG)))
|
|
{
|
|
m_MapSurf.SetColor (x,y,RGB (196,0,0));
|
|
}
|
|
else if ((m_Wheel.GetCheck ()) && (m_Data[y][x] & (WHEELPASS_FLAG)))
|
|
{
|
|
m_MapSurf.SetColor (x,y,RGB (128,0,0));
|
|
}
|
|
else if ((m_Hover.GetCheck ()) && (m_Data[y][x] & (HOVERPASS_FLAG)))
|
|
{
|
|
m_MapSurf.SetColor (x,y,RGB (64,0,0));
|
|
}
|
|
else if (m_Data[y][x] & BRIDGE_FLAG)
|
|
{
|
|
m_MapSurf.SetColor (x,y,RGB (0,255,0));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
InvalidateRect (NULL,FALSE);
|
|
}
|
|
|
|
BOOL CMapqueryDlg::DestroyWindow()
|
|
{
|
|
int i,size;
|
|
|
|
if (m_Data)
|
|
{
|
|
size = m_Height;
|
|
for (i=0;i<size;i++)
|
|
{
|
|
delete[] m_Data[i];
|
|
}
|
|
delete[] m_Data;
|
|
m_Data = NULL;
|
|
}
|
|
|
|
return CDialog::DestroyWindow();
|
|
}
|
|
|
|
void CMapqueryDlg::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
|
|
int mapx,mapy;
|
|
|
|
if (!m_Data)
|
|
{
|
|
CDialog::OnMouseMove(nFlags, point);
|
|
return;
|
|
}
|
|
mapx = point.x - MAPLEFT;
|
|
mapy = point.y - MAPTOP;
|
|
if ((mapx < 0) || (mapy < 0))
|
|
CDialog::OnMouseMove(nFlags, point);
|
|
else if ((mapx>=MAPWIDTH) || (mapy >= MAPHEIGHT))
|
|
CDialog::OnMouseMove(nFlags, point);
|
|
else
|
|
{
|
|
float dx,dy;
|
|
|
|
dx = ((float) MAPWIDTH) / ((float) m_MapSurf.GetWidth ());
|
|
dy = ((float) MAPHEIGHT) / ((float) m_MapSurf.GetHeight ());
|
|
mapx /= dx;
|
|
mapy /= dy;
|
|
int value;
|
|
value = m_Data[m_YValue][m_XValue];
|
|
m_Value.Format ("%x",value);
|
|
m_XValue = mapx;
|
|
m_YValue = mapy;
|
|
UpdateData (FALSE);
|
|
}
|
|
}
|
|
|
|
void CMapqueryDlg::OnBlock()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
BuildSurface ();
|
|
InvalidateRect (NULL,FALSE);
|
|
}
|
|
|
|
void CMapqueryDlg::OnHover()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
BuildSurface ();
|
|
InvalidateRect (NULL,FALSE);
|
|
|
|
}
|
|
|
|
void CMapqueryDlg::OnLeg()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
BuildSurface ();
|
|
InvalidateRect (NULL,FALSE);
|
|
|
|
}
|
|
|
|
void CMapqueryDlg::OnTrack()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
BuildSurface ();
|
|
InvalidateRect (NULL,FALSE);
|
|
|
|
}
|
|
|
|
void CMapqueryDlg::OnWheel()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
BuildSurface ();
|
|
InvalidateRect (NULL,FALSE);
|
|
|
|
}
|