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.
529 lines
13 KiB
C++
529 lines
13 KiB
C++
// MainFrm.cpp : implementation of the CMainFrame class
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "MW4GameEd.h"
|
|
|
|
#include "MainFrm.h"
|
|
#include <Adept\Player.hpp>
|
|
|
|
|
|
#include <ElementRenderer\LineCloudElement.hpp>
|
|
#include <ElementRenderer\GridElement.hpp>
|
|
#include <Adept\RendererManager.hpp>
|
|
#include <Adept\Map.hpp>
|
|
#include <Adept\Mission.hpp>
|
|
|
|
#include "EditEntityDlg.h"
|
|
#include "GridProps.h"
|
|
#include "GenericListDlg.h"
|
|
#include "DisplayWindow.h"
|
|
#include "OverviewWindow.h"
|
|
#include "GlobalDefs.h"
|
|
#include "selection.h"
|
|
|
|
#include "Splash.h"
|
|
|
|
#define PLACEOBJECT_TOOL 7
|
|
|
|
extern CMW4GameEdApp theApp;
|
|
|
|
ElementRenderer::LineCloudElement*
|
|
GridLineCloud = NULL;
|
|
Stuff::Point3D*
|
|
GridPointData = NULL;
|
|
Stuff::RGBAColor*
|
|
GridColorData = NULL;
|
|
|
|
Scalar GridSpacing=10.0f;
|
|
Scalar GridSize=750.0f;
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMainFrame
|
|
|
|
IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)
|
|
|
|
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
|
|
ON_WM_INITMENU()
|
|
//{{AFX_MSG_MAP(CMainFrame)
|
|
ON_WM_CREATE()
|
|
ON_COMMAND(ID_GRIDTOGGLE, OnGridToggle)
|
|
ON_WM_CLOSE()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_TIMER()
|
|
ON_COMMAND(ID_EDIT_SUBSYSTEMS, OnEditSubsystems)
|
|
ON_WM_KEYDOWN()
|
|
ON_COMMAND(ID_VIEW_OVERVIEWWINDOW_HEIGHTFIELD, OnViewOverviewwindowHeightfield)
|
|
ON_COMMAND(ID_VIEW_OVERVIEWWINDOW_SLOPEMAP, OnViewOverviewwindowSlopemap)
|
|
ON_COMMAND(ID_VIEW_OVERVIEWWINDOW_TEXTURE, OnViewOverviewwindowTexture)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_OVERVIEWWINDOW_HEIGHTFIELD, OnUpdateViewOverviewwindowHeightfield)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_OVERVIEWWINDOW_SLOPEMAP, OnUpdateViewOverviewwindowSlopemap)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_OVERVIEWWINDOW_TEXTURE, OnUpdateViewOverviewwindowTexture)
|
|
ON_COMMAND(ID_TOOLS_SHOWGRID, OnToolsShowgrid)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_SHOWGRID, OnUpdateToolsShowgrid)
|
|
ON_COMMAND(ID_VIEW_GRIDPROPERTIES, OnViewGridproperties)
|
|
ON_COMMAND(ID_TOOLS_RESETMISSIONBOUNDS, OnToolsResetmissionbounds)
|
|
ON_COMMAND(ID_EDIT_ROTATESELECTION90CW, OnEditRotateselection90cw)
|
|
ON_COMMAND(ID_EDIT_ROTATESELECTION90CCW, OnEditRotateselection90ccw)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
static UINT indicators[] =
|
|
{
|
|
ID_SEPARATOR, // status line indicator
|
|
ID_INDICATOR_CAPS,
|
|
ID_INDICATOR_NUM,
|
|
ID_INDICATOR_SCRL,
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMainFrame construction/destruction
|
|
|
|
CMainFrame::CMainFrame()
|
|
{
|
|
}
|
|
|
|
CMainFrame::~CMainFrame()
|
|
{
|
|
}
|
|
|
|
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
|
|
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
|
|
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
|
|
{
|
|
TRACE0("Failed to create toolbar\n");
|
|
return -1; // fail to create
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
// TODO: Delete these three lines if you don't want the toolbar to
|
|
// be dockable
|
|
/*
|
|
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
|
|
EnableDocking(CBRS_ALIGN_ANY);
|
|
DockControlBar(&m_wndToolBar);
|
|
*/
|
|
theApp.toolBar = &(m_wndToolBar.GetToolBarCtrl());
|
|
|
|
// CG: The following line was added by the Splash Screen component.
|
|
CSplashWnd::ShowSplashScreen(this);
|
|
return 0;
|
|
}
|
|
|
|
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
|
|
{
|
|
if( !CMDIFrameWnd::PreCreateWindow(cs) )
|
|
return FALSE;
|
|
// TODO: Modify the Window class or styles here by modifying
|
|
// the CREATESTRUCT cs
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch(message)
|
|
{
|
|
case WM_MOVE:
|
|
{
|
|
return theApp.displayWindow->WindowProc(message, wParam, lParam);
|
|
}
|
|
}
|
|
return CMDIFrameWnd::WindowProc(message, wParam, lParam);
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMainFrame diagnostics
|
|
|
|
#ifdef _DEBUG
|
|
void CMainFrame::AssertValid() const
|
|
{
|
|
CMDIFrameWnd::AssertValid();
|
|
}
|
|
|
|
void CMainFrame::Dump(CDumpContext& dc) const
|
|
{
|
|
CMDIFrameWnd::Dump(dc);
|
|
}
|
|
|
|
#endif //_DEBUG
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMainFrame message handlers
|
|
|
|
|
|
BOOL CMainFrame::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
|
{
|
|
return CMDIFrameWnd::OnNotify(wParam, lParam, pResult);
|
|
}
|
|
|
|
|
|
|
|
void CMainFrame::OnGridToggle()
|
|
{
|
|
theApp.gridOn = !theApp.gridOn;
|
|
|
|
if (theApp.gridOn)
|
|
{
|
|
CMenu* m = theApp.m_pMainWnd->GetMenu();
|
|
m->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED);
|
|
theApp.toolBar->CheckButton(ID_GRIDTOGGLE);
|
|
CreateGridData();
|
|
}
|
|
else
|
|
{
|
|
CMenu* m = theApp.m_pMainWnd->GetMenu();
|
|
m->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(0,MF_BYPOSITION | MF_UNCHECKED);
|
|
theApp.toolBar->CheckButton(ID_GRIDTOGGLE,FALSE);
|
|
HideGrid();
|
|
}
|
|
HideGrid();
|
|
|
|
}
|
|
|
|
void CMainFrame::OnClose()
|
|
{
|
|
theApp.OnFileClose();
|
|
theApp.SaveWindowStates();
|
|
|
|
if (!theApp.m_MechLabActive)
|
|
CMDIFrameWnd::OnClose();
|
|
}
|
|
|
|
void CMainFrame::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
CMDIFrameWnd::OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
void CMainFrame::OnTimer(UINT nIDEvent)
|
|
{
|
|
CMDIFrameWnd::OnTimer(nIDEvent);
|
|
}
|
|
|
|
void CMainFrame::OnInitMenu(CMenu* pMenu)
|
|
{
|
|
CMDIFrameWnd::OnInitMenu(pMenu);
|
|
|
|
// CG: This block added by 'Tip of the Day' component.
|
|
{
|
|
// TODO: This code adds the "Tip of the Day" menu item
|
|
// on the fly. It may be removed after adding the menu
|
|
// item to all applicable menu items using the resource
|
|
// editor.
|
|
|
|
// Add Tip of the Day menu item on the fly!
|
|
static CMenu* pSubMenu = NULL;
|
|
|
|
CString strHelp; strHelp.LoadString(CG_IDS_TIPOFTHEDAYHELP);
|
|
CString strMenu;
|
|
int nMenuCount = pMenu->GetMenuItemCount();
|
|
BOOL bFound = FALSE;
|
|
for (int i=0; i < nMenuCount; i++)
|
|
{
|
|
pMenu->GetMenuString(i, strMenu, MF_BYPOSITION);
|
|
if (strMenu == strHelp)
|
|
{
|
|
pSubMenu = pMenu->GetSubMenu(i);
|
|
bFound = TRUE;
|
|
ASSERT(pSubMenu != NULL);
|
|
}
|
|
}
|
|
|
|
CString strTipMenu;
|
|
strTipMenu.LoadString(CG_IDS_TIPOFTHEDAYMENU);
|
|
if (!bFound)
|
|
{
|
|
// Help menu is not available. Please add it!
|
|
if (pSubMenu == NULL)
|
|
{
|
|
// The same pop-up menu is shared between mainfrm and frame
|
|
// with the doc.
|
|
static CMenu popUpMenu;
|
|
pSubMenu = &popUpMenu;
|
|
pSubMenu->CreatePopupMenu();
|
|
pSubMenu->InsertMenu(0, MF_STRING|MF_BYPOSITION,
|
|
CG_IDS_TIPOFTHEDAY, strTipMenu);
|
|
}
|
|
pMenu->AppendMenu(MF_STRING|MF_BYPOSITION|MF_ENABLED|MF_POPUP,
|
|
(UINT)pSubMenu->m_hMenu, strHelp);
|
|
DrawMenuBar();
|
|
}
|
|
else
|
|
{
|
|
// Check to see if the Tip of the Day menu has already been added.
|
|
pSubMenu->GetMenuString(0, strMenu, MF_BYPOSITION);
|
|
|
|
if (strMenu != strTipMenu)
|
|
{
|
|
// Tip of the Day submenu has not been added to the
|
|
// first position, so add it.
|
|
pSubMenu->InsertMenu(0, MF_BYPOSITION); // Separator
|
|
pSubMenu->InsertMenu(0, MF_STRING|MF_BYPOSITION,
|
|
CG_IDS_TIPOFTHEDAY, strTipMenu);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMainFrame::DestroyGridData()
|
|
{
|
|
if (GridLineCloud)
|
|
{
|
|
|
|
Mission::Instance->GetElement()->DetachChild(GridLineCloud);
|
|
delete GridLineCloud;
|
|
delete GridPointData;
|
|
delete GridColorData;
|
|
GridLineCloud = NULL;
|
|
}
|
|
}
|
|
|
|
void CMainFrame::ShowGrid()
|
|
{
|
|
if (!theApp.gridOn)
|
|
{
|
|
Mission::Instance->GetElement()->AttachChild(GridLineCloud);
|
|
}
|
|
}
|
|
|
|
void CMainFrame::HideGrid()
|
|
{
|
|
Mission::Instance->GetElement()->DetachChild(GridLineCloud);
|
|
}
|
|
|
|
unsigned int numPoints;
|
|
|
|
void CMainFrame::CreateGridData()
|
|
{
|
|
if (GridLineCloud)
|
|
ShowGrid();
|
|
|
|
|
|
int numLines = (int)(GridSize/GridSpacing)*2;
|
|
Verify(numLines<512);
|
|
numPoints = numLines * 2;
|
|
|
|
GridPointData = new Stuff::Point3D [numPoints];
|
|
GridColorData = new Stuff::RGBAColor [numPoints];
|
|
|
|
for (int i = 0; i < numPoints; i++)
|
|
GridColorData[i] = Stuff::RGBAColor(1.0f, 0.0f, 1.0f, 0.0f);
|
|
|
|
gos_PushCurrentHeap(ElementRenderer::g_Heap);
|
|
GridLineCloud = new ElementRenderer::LineCloudElement(numPoints);
|
|
GridLineCloud->SetDataPointers(&numPoints, GridPointData, GridColorData);
|
|
|
|
GridLineCloud->m_localOBB.localToParent = LinearMatrix4D::Identity;
|
|
GridLineCloud->m_localOBB.sphereRadius = GridSize;
|
|
Mission::Instance->GetElement()->AttachChild(GridLineCloud);
|
|
|
|
ElementRenderer::StateChange *state = new ElementRenderer::StateChange();
|
|
Check_Object(state);
|
|
state->DisableZBufferCompare();
|
|
state->DisableZBufferWrite();
|
|
state->SetRenderPriority(ElementRenderer::StateChange::HUDPriority0);
|
|
GridLineCloud->AdoptStateChange(state);
|
|
GridLineCloud->SetVolumeCullMode();
|
|
// GridLineCloud->SetName("Grid Cloud");
|
|
GridLineCloud->Sync();
|
|
|
|
Scalar curloc=0.0f;
|
|
for (i = 0; i < numPoints; i+=4)
|
|
{
|
|
GridPointData[i].x = curloc;
|
|
GridPointData[i].y = 0.0f;
|
|
GridPointData[i].z = 0.0f;
|
|
|
|
GridPointData[i+1].x = curloc;
|
|
GridPointData[i+1].y = 0.0f;
|
|
GridPointData[i+1].z = GridSize;
|
|
|
|
GridPointData[i+2].x = 0.0f;
|
|
GridPointData[i+2].y = 0.0f;
|
|
GridPointData[i+2].z = curloc;
|
|
|
|
GridPointData[i+3].x = GridSize;
|
|
GridPointData[i+3].y = 0.0f;
|
|
GridPointData[i+3].z = curloc;
|
|
curloc+=GridSpacing;
|
|
}
|
|
gos_PopCurrentHeap();
|
|
SetGridLocation();
|
|
}
|
|
void CMainFrame::OnEditSubsystems()
|
|
{
|
|
CGenericListDlg listDlg;
|
|
|
|
listDlg.m_Title = "Select Subsystem"; // localize
|
|
listDlg.m_Path = "Content\\WeaponSubsystems";
|
|
listDlg.m_Extension = "data";
|
|
listDlg.m_Strict = false;
|
|
|
|
if (listDlg.DoModal() == IDOK)
|
|
{
|
|
EditEntityDlg editDlg(NULL,NULL,EDIT_SUBSYSTEM,(void *)((LPCTSTR)listDlg.m_Path));
|
|
editDlg.DoModal();
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
|
|
CMDIFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
void CMainFrame::OnViewOverviewwindowHeightfield()
|
|
{
|
|
if(theApp.overviewWindow->CurrentVMode!=COverviewWindow::VM_HFIELD)
|
|
{
|
|
theApp.overviewWindow->CurrentVMode=COverviewWindow::VM_HFIELD;
|
|
theApp.overviewWindow->BuildBackBuffer();
|
|
theApp.overviewWindow->DrawWindow();
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnViewOverviewwindowSlopemap()
|
|
{
|
|
if(theApp.overviewWindow->CurrentVMode!=COverviewWindow::VM_SLOPEMAP)
|
|
{
|
|
theApp.overviewWindow->CurrentVMode=COverviewWindow::VM_SLOPEMAP;
|
|
theApp.overviewWindow->BuildBackBuffer();
|
|
theApp.overviewWindow->DrawWindow();
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnViewOverviewwindowTexture()
|
|
{
|
|
if(theApp.overviewWindow->CurrentVMode!=COverviewWindow::VM_TEXTURE)
|
|
{
|
|
theApp.overviewWindow->CurrentVMode=COverviewWindow::VM_TEXTURE;
|
|
theApp.overviewWindow->BuildBackBuffer();
|
|
theApp.overviewWindow->DrawWindow();
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnUpdateViewOverviewwindowHeightfield(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(theApp.overviewWindow->CurrentVMode==COverviewWindow::VM_HFIELD?1:0);
|
|
|
|
}
|
|
|
|
void CMainFrame::OnUpdateViewOverviewwindowSlopemap(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(theApp.overviewWindow->CurrentVMode==COverviewWindow::VM_SLOPEMAP?1:0);
|
|
}
|
|
|
|
void CMainFrame::OnUpdateViewOverviewwindowTexture(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(theApp.overviewWindow->CurrentVMode==COverviewWindow::VM_TEXTURE?1:0);
|
|
}
|
|
|
|
|
|
void CMainFrame::OnToolsShowgrid()
|
|
{
|
|
if(GridLineCloud)
|
|
DestroyGridData();
|
|
else
|
|
CreateGridData();
|
|
}
|
|
|
|
void CMainFrame::OnUpdateToolsShowgrid(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(GridLineCloud?1:0);
|
|
}
|
|
|
|
void CMainFrame::SetGridLocation()
|
|
{
|
|
if (!GridLineCloud) return;
|
|
|
|
Stuff::Point3D pos;
|
|
pos = Player::Instance->GetLocalToParent();
|
|
pos.x=GridSpacing*(Scalar)floor(pos.x/GridSpacing)-GridSize/2.0f;
|
|
pos.z=GridSpacing*(Scalar)floor(pos.z/GridSpacing)-GridSize/2.0f;
|
|
pos.y=0.0f;
|
|
|
|
LinearMatrix4D new_local_to_parent(pos);
|
|
|
|
GridLineCloud->SetLocalToParent(new_local_to_parent);
|
|
GridLineCloud->Sync();
|
|
}
|
|
|
|
void CMainFrame::OnViewGridproperties()
|
|
{
|
|
CGridProps dlg;
|
|
|
|
dlg.m_GSize=GridSpacing;
|
|
|
|
if(dlg.DoModal()==IDOK )
|
|
{
|
|
GridSpacing=dlg.m_GSize;
|
|
if(GridLineCloud)
|
|
{
|
|
DestroyGridData();
|
|
CreateGridData();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnToolsResetmissionbounds()
|
|
{
|
|
Scalar minz,maxz,minx,maxx,xsize,zsize;
|
|
|
|
Map::Instance->GetMapExtents(&minz,&maxz,&minx,&maxx);
|
|
xsize=maxx-minx;
|
|
zsize=maxz-minz;
|
|
|
|
theApp.missionBoundary.SetLength(4);
|
|
|
|
theApp.missionBoundary[0].x=minx+xsize/10.0f;
|
|
theApp.missionBoundary[0].y=minz+zsize/10.0f;
|
|
|
|
theApp.missionBoundary[1].x=minx+xsize/10.0f;
|
|
theApp.missionBoundary[1].y=maxz-zsize/10.0f;
|
|
|
|
theApp.missionBoundary[2].x=maxx-xsize/10.0f;
|
|
theApp.missionBoundary[2].y=maxz-zsize/10.0f;
|
|
|
|
theApp.missionBoundary[3].x=maxx-xsize/10.0f;
|
|
theApp.missionBoundary[3].y=minz+zsize/10.0f;
|
|
|
|
|
|
|
|
theApp.warningBoundary.SetLength(4);
|
|
|
|
theApp.warningBoundary[0].x=minx+xsize/15.0f;
|
|
theApp.warningBoundary[0].y=minz+zsize/15.0f;
|
|
|
|
theApp.warningBoundary[1].x=minx+xsize/15.0f;
|
|
theApp.warningBoundary[1].y=maxz-zsize/15.0f;
|
|
|
|
theApp.warningBoundary[2].x=maxx-xsize/15.0f;
|
|
theApp.warningBoundary[2].y=maxz-zsize/15.0f;
|
|
|
|
theApp.warningBoundary[3].x=maxx-xsize/15.0f;
|
|
theApp.warningBoundary[3].y=minz+zsize/15.0f;
|
|
|
|
theApp.DeleteBoundaryNodes();
|
|
theApp.LoadBoundary();
|
|
}
|
|
|
|
void CMainFrame::OnEditRotateselection90cw()
|
|
{
|
|
theApp.RotateSel90CW();
|
|
}
|
|
|
|
void CMainFrame::OnEditRotateselection90ccw()
|
|
{
|
|
theApp.RotateSel90CCW();
|
|
}
|