Files
FC1/Editor/StartupDialog.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

517 lines
15 KiB
C++

// StartupDialog.cpp : implementation file
//
#include "stdafx.h"
#include "StartupDialog.h"
#include "GameExporter.h"
#include "StringDlg.h"
#include "CryEdit.h"
#include "CryEditDoc.h"
#include "SelectFileDlg.h"
#include <afxpriv.h>
#include <direct.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CStartupDialog dialog
CStartupDialog::CStartupDialog(CWnd* pParent /*=NULL*/)
: CDialog(CStartupDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CStartupDialog)
m_optSelection = 0;
m_strMapFileName = _T("");
m_strDirName = _T("Untitled");
//}}AFX_DATA_INIT
}
void CStartupDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CStartupDialog)
DDX_Control(pDX, IDC_BASE, m_cUseAsBase);
DDX_Control(pDX, IDC_RECENT_MAPS, m_lstRecentMaps);
DDX_Radio(pDX, IDC_CREATE_NEW, m_optSelection);
DDX_Text(pDX, IDC_MAP_FILENAME, m_strMapFileName);
DDX_Text(pDX, IDC_DIR_NAME, m_strDirName);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CStartupDialog, CDialog)
//{{AFX_MSG_MAP(CStartupDialog)
ON_BN_CLICKED(IDC_BROWSE_FOR_MAP, OnBrowseForMap)
ON_BN_CLICKED(IDC_CHANGE_LEV_DIR, OnChangeLevDir)
ON_LBN_SELCHANGE(IDC_RECENT_MAPS, OnSelectedRecentDoc)
ON_LBN_DBLCLK(IDC_RECENT_MAPS, OnDblClickRecentDoc)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CStartupDialog message handlers
void CStartupDialog::OnOK()
{
//////////////////////////////////////////////////////////////////////
// Perform the action selected by the user
//////////////////////////////////////////////////////////////////////
UpdateData(TRUE);
CString strSelection;
char szLevelRoot[_MAX_PATH];
char szFileName[_MAX_PATH];
int nResult;
SNoiseParams sParam;
CFile cFile;
CString strFilePath, strTempCopyStr;
CBitmap bmpLoad;
bool bReturn;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
DWORD *pImageData;
FILE *hFile;
BeginWaitCursor();
switch (m_optSelection)
{
case 0:
//////////////////////////////////////////////////////////////////////
// Create a new map
//////////////////////////////////////////////////////////////////////
CLogFile::WriteLine("User choose to create new map");
// Ask first
if (GetIEditor()->IsModified())
{
// Ask the user about saving / aborting
nResult = MessageBox("Save changes to document ?",
"CryEngine Sandbox", MB_ICONQUESTION | MB_YESNOCANCEL | MB_APPLMODAL);
// Evaluate the user's choice
switch (nResult)
{
case IDCANCEL:
// Abort saving
return;
break;
case IDYES:
// Save first
GetIEditor()->GetDocument()->DoSave(szFileName, TRUE);
break;
case IDNO:
// Don't save, go on
break;
default:
ASSERT(FALSE);
break;
}
}
// Construct the directory name
sprintf(szLevelRoot, "%sLevels\\%s", GetIEditor()->GetMasterCDFolder(),
m_strDirName.GetBuffer(1));
// Does the directory already exist ?
if (PathFileExists(szLevelRoot))
{
AfxMessageBox("Directory / level aready exists, choose another name !");
return;
}
// Create the directory
CLogFile::WriteLine("Creating level directory");
CFileUtil::CreateDirectory( szLevelRoot );
// Should we create the new map based on the current ?
if (m_cUseAsBase.GetCheck() == 0)
{
CLogFile::WriteLine("User doesn not want to use current document as base, throw it away");
// No, throw away the current map by creating a new empty document
if (!GetIEditor()->GetDocument()->OnNewDocument())
return;
// We now erased the previous settings, ask the user if we should load /
// generate some default ones to provide him a better starting point
nResult = MessageBox("Do you want to create a default level as starting point ? This is highly" \
" recommended if you are using the editor for the first time or if you want to quickly create a new map.",
"Create default level ?", MB_YESNO | MB_ICONQUESTION | MB_APPLMODAL);
if (nResult == IDYES)
{
CLogFile::WriteLine("Creating default level");
// Load or generate a heightmap
strFilePath = GetIEditor()->GetDocument()->GetMasterCDFolder() + "EditorTemplate\\Default.hm";
if (PathFileExists(strFilePath.GetBuffer(0)))
{
CLogFile::WriteLine("Hightmap template file found");
// Heightmap file exists, we can load it
GetIEditor()->GetDocument()->m_cHeightmap.Read(strFilePath);
}
else
{
CLogFile::WriteLine("No heightmap template found, generating one");
// We don't have a heightmap template, Generate the heightmap
sParam.bBlueSky = false;
sParam.bValid = true;
sParam.fFade = 0.46f;
sParam.fFrequency = 7.0f;
sParam.fFrequencyStep = 2.0f;
sParam.iCover = 0;
sParam.iHeight = GetIEditor()->GetDocument()->m_cHeightmap.GetWidth();
sParam.iWidth = GetIEditor()->GetDocument()->m_cHeightmap.GetHeight();
sParam.iPasses = 8;
sParam.iRandom = 1;
sParam.iSharpness = 0;
sParam.iSmoothness = 0;
GetIEditor()->GetDocument()->m_cHeightmap.GenerateTerrain(sParam);
GetIEditor()->GetDocument()->m_cHeightmap.MakeIsle();
}
/*
// Load static object settings
strFilePath = GetIEditor()->GetDocument()->GetMasterCDFolder() + "EditorTemplate\\Default.sto";
if (PathFileExists(strFilePath.GetBuffer(0)))
{
CLogFile::WriteLine("Static object template found");
// File exists, we can safely load it
CXmlArchive ar;
ar.Load( strFilePath );
GetIEditor()->GetDocument()->ClearStaticObjects();
GetIEditor()->GetDocument()->SerializeStaticObjSettings(ar);
}
*/
// Load layer settings
strFilePath = GetIEditor()->GetDocument()->GetMasterCDFolder() + "EditorTemplate\\Default.lay";
if (PathFileExists(strFilePath.GetBuffer(0)))
{
CLogFile::WriteLine("Layer template found");
// File exists, we can safely load it
CXmlArchive ar;
ar.Load( strFilePath );
GetIEditor()->GetDocument()->SerializeLayerSettings(ar);
}
// Load detail texture
strFilePath = GetIEditor()->GetDocument()->GetMasterCDFolder() + "EditorTemplate\\Default.bmp";
if (PathFileExists(strFilePath.GetBuffer(0)))
{
CLogFile::WriteLine("Detail texture template found");
// File exists, we can safely load it
// Open the bitmap and extract the size
hFile = fopen(strFilePath.GetBuffer(0), "r");
ASSERT(hFile);
// Read in the info header
fread(&bfh, sizeof(BITMAPFILEHEADER), 1, hFile);
fread(&bih, sizeof(BITMAPINFOHEADER), 1, hFile);
ASSERT(bih.biWidth && bih.biHeight);
fclose(hFile);
// Load the bitmap
bReturn = bmpLoad.Attach(::LoadImage(AfxGetInstanceHandle(),strFilePath.GetBuffer(0), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE |
LR_LOADFROMFILE));
ASSERT(bReturn);
// Allocate memory for the image data
pImageData = new DWORD[bih.biWidth * bih.biHeight];
ASSERT(pImageData);
// Get the image data from the bitmap
bmpLoad.GetBitmapBits(bih.biWidth * bih.biHeight * sizeof(DWORD), pImageData);
// Free the image data memory
delete [] pImageData;
pImageData = 0;
}
// Copy the skybox
// Create the subfolders
strFilePath = CString(szLevelRoot) + "\\Skybox";
_mkdir(strFilePath.GetBuffer(0));
// Copy the JPG files
strFilePath = GetIEditor()->GetDocument()->GetMasterCDFolder() + "EditorTemplate\\Skybox\\12.jpg";
if (PathFileExists(strFilePath.GetBuffer(0)))
{
CLogFile::WriteLine("Skybox template found");
VERIFY(CopyFile(strFilePath.GetBuffer(0), (CString(szLevelRoot) +
"\\Skybox\\12.jpg").GetBuffer(0), FALSE));
}
strFilePath = GetIEditor()->GetDocument()->GetMasterCDFolder() + "EditorTemplate\\Skybox\\34.jpg";
if (PathFileExists(strFilePath.GetBuffer(0)))
{
VERIFY(CopyFile(strFilePath.GetBuffer(0), (CString(szLevelRoot) +
"\\Skybox\\34.jpg").GetBuffer(0), FALSE));
}
strFilePath = GetIEditor()->GetDocument()->GetMasterCDFolder() + "EditorTemplate\\Skybox\\5.jpg";
if (PathFileExists(strFilePath.GetBuffer(0)))
{
VERIFY(CopyFile(strFilePath.GetBuffer(0), (CString(szLevelRoot) +
"\\Skybox\\5.jpg").GetBuffer(0), FALSE));
}
}
}
// Save the document to this folder
PathAddBackslash(szLevelRoot);
sprintf(szFileName, "%s%s.cry", szLevelRoot, m_strDirName.GetBuffer(1));
if (!GetIEditor()->GetDocument()->DoSave(szFileName, TRUE))
return;
// Only ask about a full export if the user choose to create a default level
if (nResult == IDYES)
{
// Ask the user if he wants to do a full export ?
nResult = MessageBox("Do you want to make a full export before starting to edit the level ? This" \
" means creating a complete copy / export of the data for the engine. If you are going" \
" to change all default settings before previewing the level anyway, choosing 'No' will" \
" speed up the loading process.", "Do export first ?", MB_YESNO | MB_ICONQUESTION | MB_APPLMODAL);
}
// Did the user create a default level and wants a full export ?
if (nResult == IDYES)
{
CLogFile::WriteLine("User choose to perform a full export");
// Export the default values. Make a full export which involves generating the
// surface texture
//GetIEditor()->GetDocument()->ExportToGame(true);
CGameExporter gameExporter( GetIEditor()->GetSystem() );
gameExporter.Export(true,true);
}
else
{
// Export the default values. This is relatively fast because no surface
// texture will be generated
//GetIEditor()->GetDocument()->ExportToGame(false);
CGameExporter gameExporter( GetIEditor()->GetSystem() );
gameExporter.Export(false,true);
}
/*
// Let the engine load the new empty map
CEngineSingleton::GetGameInterface()->GetInterface()->LoadLevel(szFileName);
*/
break;
case 1:
//////////////////////////////////////////////////////////////////////
// Open an recent map
//////////////////////////////////////////////////////////////////////
if (m_lstRecentMaps.GetCurSel() == LB_ERR)
{
// No selection
AfxMessageBox("Please select a map before pressing OK");
return;
}
CLogFile::WriteLine("User choose to open an map");
// Open the map
m_lstRecentMaps.GetText(m_lstRecentMaps.GetCurSel(), strSelection);
if (!AfxGetApp()->OpenDocumentFile(strSelection))
return;
break;
case 2:
//////////////////////////////////////////////////////////////////////
// Open a map
//////////////////////////////////////////////////////////////////////
if (!PathFileExists(m_strMapFileName.GetBuffer(0)))
{
// File does not exist
AfxMessageBox("Please specify / select a valid filename before pressing OK");
return;
}
CLogFile::WriteLine("User choose to open an map");
// Open the map
if(!AfxGetApp()->OpenDocumentFile(m_strMapFileName))
return;
break;
default:
ASSERT(FALSE);
break;
}
EndWaitCursor();
CDialog::OnOK();
}
BOOL CStartupDialog::OnInitDialog()
{
//////////////////////////////////////////////////////////////////////
// Fill the list box with the names of the recent maps
//////////////////////////////////////////////////////////////////////
UINT i;
CRecentFileList *pList = ((CCryEditApp *) (AfxGetApp()))->GetRecentFileList();
CDialog::OnInitDialog();
CLogFile::WriteLine("Loading startup dialog...");
ASSERT(pList);
if (!pList)
return TRUE;
// Loop trough the array and add each string
for (i=0; i<(unsigned int) pList->GetSize() - 1; i++)
{
// Does the file exist ?
if (PathFileExists((* pList)[i].GetBuffer(0)))
// Add it to the list
m_lstRecentMaps.InsertString(0, (* pList)[i]);
}
// You can only use the current map as base if there is one
m_cUseAsBase.EnableWindow(!GetIEditor()->GetDocument()->GetPathName().IsEmpty());
m_cUseAsBase.SetCheck(0);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CStartupDialog::OnBrowseForMap()
{
//////////////////////////////////////////////////////////////////////
// Browse for a map
//////////////////////////////////////////////////////////////////////
CSelectFileDlg cDialog;
CString strFileName;
if (cDialog.SelectFileName(&strFileName, NULL, CString("*.cry"), CString("Levels")))
{
// Save the filename in the text box
m_strMapFileName = strFileName;
// Activate the correct option
m_optSelection = 2;
// Update the controls
UpdateData(FALSE);
}
}
void CStartupDialog::OnChangeLevDir()
{
//////////////////////////////////////////////////////////////////////
// Let the user create a directory in the level subfolder where all
// the data is stored and exported
//////////////////////////////////////////////////////////////////////
char szLevelRoot[_MAX_PATH];
char szCompBuf[2];
CStringDlg cDialog;
bool bPathIsValid = true;
UINT i;
// Query for a name
cDialog.m_strString = m_strDirName;
cDialog.DoModal();
// Verify new name
if (cDialog.m_strString.IsEmpty())
bPathIsValid = false;
// User entered string, check for invalid chars
for (i=0; i<(unsigned int) cDialog.m_strString.GetLength(); i++)
{
// Paste the char into the compare buffer
szCompBuf[0] = cDialog.m_strString.GetBuffer(0)[i];
szCompBuf[1] = '\0';
// Is the char invalid ?
if (strpbrk(szCompBuf, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_ ") == NULL)
{
bPathIsValid = false;
break;
}
}
// Valid ?
if (!bPathIsValid)
{
AfxMessageBox("Level name is invalid, please use only a-z, A-Z and 0-9 !");
return;
}
// Construct the directory name
sprintf(szLevelRoot, "%sLevels\\%s", GetIEditor()->GetDocument()->GetMasterCDFolder().GetBuffer(1),
cDialog.m_strString.GetBuffer(0));
// Does the directory already exist ?
if (PathFileExists(szLevelRoot))
{
AfxMessageBox("Directory / level aready exists, choose another name !");
return;
}
// Write it into the control
m_strDirName = cDialog.m_strString;
// Chose option 1, "Create new Level"
m_optSelection = 0;
UpdateData(FALSE);
}
void CStartupDialog::OnSelectedRecentDoc()
{
//////////////////////////////////////////////////////////////////////
// User selected an item in the recent document list. Make the
// second choice the default one
//////////////////////////////////////////////////////////////////////
m_optSelection = 1;
UpdateData(FALSE);
}
void CStartupDialog::OnDblClickRecentDoc()
{
//////////////////////////////////////////////////////////////////////
// User selected an item in the recent document list. Open this map
//////////////////////////////////////////////////////////////////////
// Make the second choice the default one for the case that the
// loading fails and the user gets dropped back to the dialog
m_optSelection = 1;
UpdateData(FALSE);
// Open this map
OnOK();
}