mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-12-25 23:24:51 +01:00
2994 lines
97 KiB
C++
2994 lines
97 KiB
C++
/* Copyright (c) 2002-2012 Croteam Ltd.
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of version 2 of the GNU General Public License as published by
|
|
the Free Software Foundation
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
|
|
|
// WorldEditor.cpp : Defines the class behaviors for the application.
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "WorldEditor.h"
|
|
#include "DlgTipOfTheDay.h"
|
|
#include <Engine/Templates/Stock_CTextureData.h>
|
|
#include <Engine/Templates/Stock_CModelData.h>
|
|
|
|
#include <sys/stat.h>
|
|
#include <sys/utime.h>
|
|
#include <process.h>
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#undef new
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
UINT _uiMessengerMsg=-1;
|
|
UINT _uiMessengerForcePopup=-1;
|
|
|
|
extern FLOAT _fFlyModeSpeedMultiplier = 1.0f;
|
|
FLOAT _fLastMipBrushingOptionUsed = -10000.0f;
|
|
extern INDEX wed_iMaxFPSActive = 500;
|
|
extern FLOAT wed_fFrontClipDistance = 0.5f;
|
|
extern struct GameGUI_interface *_pGameGUI = NULL;
|
|
extern INDEX wed_bUseGenericTextureReplacement = FALSE;
|
|
|
|
CTFileName fnmPersistentSymbols = CTString("Scripts\\PersistentSymbols.ini");
|
|
|
|
// Macros used for ini i/o operations
|
|
#define INI_PRIMITIVE_READ( strname, default_val) \
|
|
strcpy( strIni, CStringA(theApp.GetProfileString( L"World editor prefs", CString(strPrimitiveType+" "+ strname ), CString( default_val ))))
|
|
#define INI_PRIMITIVE_WRITE( strname) \
|
|
theApp.WriteProfileString( L"World editor prefs", CString(strPrimitiveType+" "+strname), CString(strIni))
|
|
|
|
#define INI_READ( strname, default_val) \
|
|
strcpy( strIni, CStringA(theApp.GetProfileString( L"World editor prefs", CString( strname ), CString(default_val))))
|
|
#define GET_FLAG( var) \
|
|
if( strcmp( strIni, "YES") == 0) var = TRUE; \
|
|
else var = FALSE;
|
|
#define GET_COLOR( var) \
|
|
sscanf( strIni, "0X%08x", &var);
|
|
#define GET_INDEX( var) \
|
|
sscanf( strIni, "%d", &var);
|
|
#define GET_FLOAT( var) \
|
|
sscanf( strIni, "%f", &var);
|
|
#define GET_STRING( var) \
|
|
var = CTString( strIni);
|
|
|
|
#define SET_FLAG( var) \
|
|
if( var) strcpy( strIni, "YES"); \
|
|
else strcpy( strIni, "NO");
|
|
#define SET_COLOR( var) \
|
|
sprintf( strIni, "0x%08x", var); \
|
|
_strupr( strIni);
|
|
#define SET_INDEX( var) \
|
|
sprintf( strIni, "%d", var); \
|
|
_strupr( strIni);
|
|
#define SET_FLOAT( var) \
|
|
sprintf( strIni, "%f", var); \
|
|
_strupr( strIni);
|
|
#define SET_STRING( var) \
|
|
sprintf( strIni, "%s", var);
|
|
|
|
#define INI_WRITE( strname) \
|
|
theApp.WriteProfileString( L"World editor prefs", CString( strname ), CString(strIni))
|
|
|
|
void InitializeGame(void)
|
|
{
|
|
try {
|
|
#ifndef NDEBUG
|
|
#define GAMEDLL _fnmApplicationExe.FileDir()+"GameGUI"+_strModExt+"D.dll"
|
|
#else
|
|
#define GAMEDLL _fnmApplicationExe.FileDir()+"GameGUI"+_strModExt+".dll"
|
|
#endif
|
|
CTFileName fnmExpanded;
|
|
ExpandFilePath(EFP_READ, CTString(GAMEDLL), fnmExpanded);
|
|
|
|
HMODULE hGame = LoadLibraryA(fnmExpanded);
|
|
if (hGame==NULL) {
|
|
ThrowF_t("%s", GetWindowsError(GetLastError()));
|
|
}
|
|
GameGUI_interface* (*GAMEGUI_Create)(void) = (GameGUI_interface* (*)(void))GetProcAddress(hGame, "GAMEGUI_Create");
|
|
if (GAMEGUI_Create==NULL) {
|
|
ThrowF_t("%s", GetWindowsError(GetLastError()));
|
|
}
|
|
_pGameGUI = GAMEGUI_Create();
|
|
|
|
} catch (char *strError) {
|
|
FatalError("%s", strError);
|
|
}
|
|
_pGameGUI->Initialize(CTString("Data\\WorldEditor.gms"));
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWorldEditorApp
|
|
|
|
BEGIN_MESSAGE_MAP(CWorldEditorApp, CWinApp)
|
|
//{{AFX_MSG_MAP(CWorldEditorApp)
|
|
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
|
|
ON_COMMAND(ID_FILE_PREFERENCES, OnFilePreferences)
|
|
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
|
|
ON_COMMAND(ID_IMPORT_3D_OBJECT, OnImport3DObject)
|
|
ON_COMMAND(ID_DECADIC_GRID, OnDecadicGrid)
|
|
ON_UPDATE_COMMAND_UI(ID_DECADIC_GRID, OnUpdateDecadicGrid)
|
|
ON_COMMAND(ID_CONVERT_WORLDS, OnConvertWorlds)
|
|
ON_COMMAND(ID_SET_AS_DEFAULT, OnSetAsDefault)
|
|
ON_COMMAND(ID_HELP_SHOWTIPOFTHEDAY, OnHelpShowTipOfTheDay)
|
|
//}}AFX_MSG_MAP
|
|
// Standard file based document commands
|
|
ON_COMMAND(ID_FILE_NEW, OnFileNew)
|
|
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWorldEditorApp construction
|
|
|
|
void SetRenderingPrefs( CViewPrefs vp)
|
|
{
|
|
// store current shadows on/off state
|
|
CWorldRenderPrefs::ShadowsType sht=_wrpWorldRenderPrefs.GetShadowsType();
|
|
_wrpWorldRenderPrefs = vp.m_wrpWorldRenderPrefs;
|
|
_mrpModelRenderPrefs = vp.m_mrpModelRenderPrefs;
|
|
|
|
_wrpWorldRenderPrefs.SetSelectedEntityModel( theApp.m_pEntityMarkerModelObject);
|
|
_wrpWorldRenderPrefs.SetSelectedPortalModel( theApp.m_pPortalMarkerModelObject);
|
|
_wrpWorldRenderPrefs.SetEmptyBrushModel( theApp.m_pEmptyBrushModelObject);
|
|
|
|
// restore current shadows on/off state
|
|
_wrpWorldRenderPrefs.SetShadowsType( sht);
|
|
}
|
|
|
|
void WED_ApplyChildSettings(INDEX iChildCfg)
|
|
{
|
|
CChildConfiguration &cc = theApp.m_ccChildConfigurations[ iChildCfg];
|
|
// find perspective view
|
|
for( INDEX iView=0; iView<cc.m_iHorizontalSplitters*cc.m_iHorizontalSplitters; iView++)
|
|
{
|
|
if( cc.m_ptProjectionType[ iView] == CSlaveViewer::PT_PERSPECTIVE)
|
|
{
|
|
SetRenderingPrefs( cc.m_vpViewPrefs[ iView]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void WED_ApplyChildSettings0(void) { WED_ApplyChildSettings(0);}
|
|
void WED_ApplyChildSettings1(void) { WED_ApplyChildSettings(1);}
|
|
void WED_ApplyChildSettings2(void) { WED_ApplyChildSettings(2);}
|
|
void WED_ApplyChildSettings3(void) { WED_ApplyChildSettings(3);}
|
|
void WED_ApplyChildSettings4(void) { WED_ApplyChildSettings(4);}
|
|
void WED_ApplyChildSettings5(void) { WED_ApplyChildSettings(5);}
|
|
void WED_ApplyChildSettings6(void) { WED_ApplyChildSettings(6);}
|
|
void WED_ApplyChildSettings7(void) { WED_ApplyChildSettings(7);}
|
|
void WED_ApplyChildSettings8(void) { WED_ApplyChildSettings(8);}
|
|
void WED_ApplyChildSettings9(void) { WED_ApplyChildSettings(9);}
|
|
|
|
void WED_ApplyRenderingSettings0(void) { SetRenderingPrefs(theApp.m_vpViewPrefs[0]);}
|
|
void WED_ApplyRenderingSettings1(void) { SetRenderingPrefs(theApp.m_vpViewPrefs[1]);}
|
|
void WED_ApplyRenderingSettings2(void) { SetRenderingPrefs(theApp.m_vpViewPrefs[2]);}
|
|
void WED_ApplyRenderingSettings3(void) { SetRenderingPrefs(theApp.m_vpViewPrefs[3]);}
|
|
void WED_ApplyRenderingSettings4(void) { SetRenderingPrefs(theApp.m_vpViewPrefs[4]);}
|
|
void WED_ApplyRenderingSettings5(void) { SetRenderingPrefs(theApp.m_vpViewPrefs[5]);}
|
|
void WED_ApplyRenderingSettings6(void) { SetRenderingPrefs(theApp.m_vpViewPrefs[6]);}
|
|
void WED_ApplyRenderingSettings7(void) { SetRenderingPrefs(theApp.m_vpViewPrefs[7]);}
|
|
void WED_ApplyRenderingSettings8(void) { SetRenderingPrefs(theApp.m_vpViewPrefs[8]);}
|
|
void WED_ApplyRenderingSettings9(void) { SetRenderingPrefs(theApp.m_vpViewPrefs[9]);}
|
|
|
|
void FindEmptyBrushes( void);
|
|
void WED_FindEmptyBrushes(void) { FindEmptyBrushes(); }
|
|
|
|
// Create primitive default values
|
|
CValuesForPrimitive::CValuesForPrimitive()
|
|
{
|
|
vfp_csgtCSGOperation = CSG_ILLEGAL;
|
|
vfp_ptPrimitiveType = PT_CONUS;
|
|
vfp_avVerticesOnBaseOfPrimitive.Clear();
|
|
vfp_avVerticesOnBaseOfPrimitive.New(4);
|
|
vfp_avVerticesOnBaseOfPrimitive[0] = DOUBLE3D( -8.0f, 0.0f, -8.0f);
|
|
vfp_avVerticesOnBaseOfPrimitive[1] = DOUBLE3D( 8.0f, 0.0f, -8.0f);
|
|
vfp_avVerticesOnBaseOfPrimitive[2] = DOUBLE3D( 8.0f, 0.0f, 8.0f);
|
|
vfp_avVerticesOnBaseOfPrimitive[3] = DOUBLE3D( -8.0f, 0.0f, 8.0f);
|
|
vfp_bClosed = TRUE;
|
|
vfp_ttTriangularisationType = TT_NONE;
|
|
vfp_bDummy = FALSE;
|
|
vfp_bAutoCreateMipBrushes = FALSE;
|
|
vfp_fXMin = -8.0f;
|
|
vfp_fXMax = 8.0f;
|
|
vfp_fYMin = -8.0f;
|
|
vfp_fYMax = 8.0f;
|
|
vfp_fZMin = -8.0f;
|
|
vfp_fZMax = 8.0f;
|
|
vfp_fShearX = 0.0f;
|
|
vfp_fShearZ = 0.0f;
|
|
vfp_fStretchX = 1.0f;
|
|
vfp_fStretchY = 1.0f;
|
|
vfp_plPrimitive.pl_PositionVector = FLOAT3D( 0.0f, 0.0f, 0.0f);
|
|
vfp_plPrimitive.pl_OrientationAngle = ANGLE3D(0,0,0);
|
|
vfp_colSectorsColor = C_BLUE;
|
|
vfp_colPolygonsColor = C_RED;
|
|
vfp_fRadius = 32.0f;
|
|
vfp_bLinearStaircases = FALSE;
|
|
vfp_bOuter = TRUE;
|
|
vfp_iSlicesIn360 = 12;
|
|
vfp_iNoOfSlices = 6;
|
|
vfp_iMeridians = 6;
|
|
vfp_iParalels = 6;
|
|
vfp_iSlicesPerWidth = 6;
|
|
vfp_iSlicesPerHeight= 6;
|
|
vfp_iTopShape = 0;
|
|
vfp_iBottomShape = 0;
|
|
vfp_fAmplitude = 50.0f;
|
|
vfp_fMipStart = 6.0f;
|
|
vfp_fMipStep = 1.5f;
|
|
}
|
|
|
|
CWorldEditorApp::CWorldEditorApp()
|
|
{
|
|
// register message
|
|
_uiMessengerMsg = RegisterWindowMessageA("Croteam Messenger: Incoming Message");
|
|
_uiMessengerForcePopup = RegisterWindowMessageA("Croteam Messenger: Force Popup Message");
|
|
|
|
m_fnClassForDropMarker = CTFILENAME("Classes\\Marker.ecl");
|
|
m_bChangeDisplayModeInProgress = FALSE;
|
|
m_bDisableDataExchange = FALSE;
|
|
m_pLastActivatedDocument = NULL;
|
|
//#ifdef NDEBUG
|
|
m_bShowStatusInfo = TRUE;
|
|
//#else
|
|
// m_bShowStatusInfo = FALSE;
|
|
//#endif
|
|
m_bDocumentChangeOn = FALSE;
|
|
m_bCSGReportEnabled = TRUE;
|
|
m_bRememberUndo = TRUE;
|
|
m_bMeasureModeOn = FALSE;
|
|
m_bCutModeOn = FALSE;
|
|
m_pfntSystem = NULL;
|
|
m_ptdError = NULL;
|
|
m_ptoError = NULL;
|
|
m_ptdIconsTray = NULL;
|
|
m_ptdActiveTexture = NULL;
|
|
|
|
m_vLastTerrainHit=FLOAT3D(0,0,0);
|
|
m_penLastTerrainHit=NULL;
|
|
m_fCurrentTerrainBrush=4.0f;
|
|
m_fTerrainBrushPressure=1024.0f*3.0f/4.0f; //75%
|
|
m_iTerrainEditMode=TEM_HEIGHTMAP;
|
|
m_iTerrainBrushMode=0;
|
|
m_fTerrainBrushPressureEnum=-1.0f;
|
|
m_fnDistributionNoiseTexture=CTFILENAME("Textures\\Editor\\RandomNoise.tex");
|
|
m_fnContinousNoiseTexture=CTFILENAME("Textures\\Editor\\RandomNoise.tex");
|
|
|
|
m_iFBMOctaves=4;
|
|
m_fFBMHighFrequencyStep=1.0f;
|
|
m_fFBMStepFactor=2.2f;
|
|
m_fFBMMaxAmplitude=64.0f;
|
|
m_fFBMfAmplitudeDecreaser=0.5f;
|
|
m_bFBMAddNegativeValues=TRUE;
|
|
m_bFBMRandomOffset=FALSE;
|
|
|
|
m_uwEditAltitude=0;
|
|
m_fPaintPower=1.0f;
|
|
m_fSmoothPower=1.0f;
|
|
m_iFilter=FLT_SHARPEN;
|
|
m_fFilterPower=1.0f;
|
|
m_fPosterizeStep=2.0f;
|
|
m_fNoiseAltitude=1.0f;
|
|
m_iRNDSubdivideAndDisplaceItterations=2;
|
|
m_iTerrainGenerationMethod=0;
|
|
|
|
m_pbpoClipboardPolygon = new CBrushPolygon;
|
|
m_pbpoPolygonWithDeafultValues = new CBrushPolygon;
|
|
m_bFirstTimeStarted = FALSE;
|
|
|
|
// no copy operations performed yet
|
|
m_ctLastCopyType = CT_NONE;
|
|
m_colSectorAmbientClipboard = C_BLACK;
|
|
m_bDecadicGrid = FALSE;
|
|
|
|
// give personality to each values for primitive class
|
|
m_vfpConus.vfp_ptPrimitiveType = PT_CONUS;
|
|
m_vfpTorus.vfp_ptPrimitiveType = PT_TORUS;
|
|
m_vfpStaircases.vfp_ptPrimitiveType = PT_STAIRCASES;
|
|
m_vfpSphere.vfp_ptPrimitiveType = PT_SPHERE;
|
|
m_vfpTerrain.vfp_ptPrimitiveType = PT_TERRAIN;
|
|
m_bTexture1 = TRUE;
|
|
m_bTexture2 = TRUE;
|
|
m_bTexture3 = TRUE;
|
|
m_fTerrainSwitchStart = 100.0f;
|
|
m_fTerrainSwitchStep = 1.0f;
|
|
|
|
m_iLastClassSortAplied = 0;
|
|
m_bInvertClassSort = FALSE;
|
|
m_iLastAutoColorizeColor = 0;
|
|
|
|
m_plClipboard1 = CPlacement3D( FLOAT3D(0.0f,0.0f,0.0f), ANGLE3D(0,0,0));
|
|
m_plClipboard2 = CPlacement3D( FLOAT3D(0.0f,0.0f,0.0f), ANGLE3D(0,0,0));
|
|
m_tmStartStatusLineInfo=0;
|
|
}
|
|
|
|
// default constructor
|
|
CViewPrefs::CViewPrefs( void)
|
|
{
|
|
// set default values
|
|
SetDefaultValues();
|
|
}
|
|
|
|
/*
|
|
* Set default values for view preferences
|
|
*/
|
|
void CViewPrefs::SetDefaultValues( void)
|
|
{
|
|
// set view's defaults
|
|
m_bAutoRenderingRange = TRUE;
|
|
m_fRenderingRange = 100.0f;
|
|
m_PaperColor = C_WHITE;
|
|
m_SelectionColor = C_RED;
|
|
m_GridColor = 0xAFBDFE;
|
|
m_bMeasurementTape = FALSE;
|
|
// set defaults for world
|
|
m_wrpWorldRenderPrefs.SetHiddenLinesOn( TRUE);
|
|
m_wrpWorldRenderPrefs.SetEditorModelsOn( TRUE);
|
|
m_wrpWorldRenderPrefs.SetFieldBrushesOn( TRUE);
|
|
m_wrpWorldRenderPrefs.SetBackgroundTextureOn( FALSE);
|
|
m_wrpWorldRenderPrefs.SetVerticesFillType( CWorldRenderPrefs::FT_NONE);
|
|
m_wrpWorldRenderPrefs.SetVerticesInkColor( C_RED);
|
|
m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_POLYGONCOLOR);
|
|
m_wrpWorldRenderPrefs.SetEdgesInkColor( C_BLACK);
|
|
m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_NONE);
|
|
m_wrpWorldRenderPrefs.SetPolygonsInkColor( C_GRAY);
|
|
m_wrpWorldRenderPrefs.SetLensFlaresType( CWorldRenderPrefs::LFT_NONE);
|
|
m_wrpWorldRenderPrefs.SetFogOn( FALSE);
|
|
m_wrpWorldRenderPrefs.SetHazeOn( FALSE);
|
|
m_wrpWorldRenderPrefs.SetMirrorsOn( FALSE);
|
|
m_wrpWorldRenderPrefs.SetShowTargetsOn( FALSE);
|
|
m_wrpWorldRenderPrefs.SetShowEntityNamesOn( FALSE);
|
|
|
|
// set defaults for models
|
|
m_mrpModelRenderPrefs.SetRenderType( RT_TEXTURE);
|
|
m_mrpModelRenderPrefs.SetShadingType( RT_SHADING_PHONG);
|
|
m_mrpModelRenderPrefs.SetShadowQuality( 0);
|
|
m_mrpModelRenderPrefs.SetInkColor( C_BLACK);
|
|
m_mrpModelRenderPrefs.BBoxFrameShow( FALSE);
|
|
m_mrpModelRenderPrefs.BBoxAllShow( FALSE);
|
|
m_mrpModelRenderPrefs.SetWire( FALSE);
|
|
sprintf( m_achrBcgPicture, "");
|
|
}
|
|
|
|
void CViewPrefs::ClearInvalidConfigPointers(void)
|
|
{
|
|
m_wrpWorldRenderPrefs.SetSelectedEntityModel(NULL);
|
|
m_wrpWorldRenderPrefs.SetSelectedPortalModel(NULL);
|
|
m_wrpWorldRenderPrefs.SetEmptyBrushModel(NULL);
|
|
}
|
|
|
|
CAppPrefs::~CAppPrefs()
|
|
{
|
|
}
|
|
|
|
CWorldEditorApp::~CWorldEditorApp()
|
|
{
|
|
}
|
|
|
|
CWorldEditorDoc* CWorldEditorApp::GetActiveDocument(void)
|
|
{
|
|
// if document change process is on (document view switching)
|
|
if( m_bDocumentChangeOn)
|
|
{
|
|
return NULL;
|
|
}
|
|
else
|
|
{
|
|
// obtain active view
|
|
CWorldEditorView *pWorldEditorView = GetActiveView();
|
|
// if there is active view
|
|
if( pWorldEditorView != NULL)
|
|
{
|
|
// return document that view represents
|
|
return GetActiveView()->GetDocument();
|
|
}
|
|
// otherwise
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
CWorldEditorView* CWorldEditorApp::GetActiveView(void)
|
|
{
|
|
CWorldEditorView *res;
|
|
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
|
|
res = DYNAMIC_DOWNCAST(CWorldEditorView, pMainFrame->GetActiveFrame()->GetActiveView());
|
|
return res;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// The one and only CWorldEditorApp object
|
|
|
|
CWorldEditorApp theApp;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWorldEditorApp initialization
|
|
|
|
BOOL CWorldEditorApp::InitInstance()
|
|
{
|
|
_CrtSetBreakAlloc(55);
|
|
BOOL bResult;
|
|
CTSTREAM_BEGIN {
|
|
bResult = SubInitInstance();
|
|
} CTSTREAM_END;
|
|
return bResult;
|
|
}
|
|
|
|
static CTString _strCmd;
|
|
static CString _strCmdW;
|
|
static CTString cmd_strOutput;
|
|
static CTString cmd_strMod;
|
|
|
|
// get first next word or quoted string
|
|
static CTString GetNextParam(void)
|
|
{
|
|
// strip leading spaces/tabs
|
|
_strCmd.TrimSpacesLeft();
|
|
// if nothing left
|
|
if (_strCmd=="") {
|
|
// no word to return
|
|
return "";
|
|
}
|
|
|
|
// if the first char is quote
|
|
if (_strCmd[0]=='"') {
|
|
// find first next quote
|
|
const char *pchClosingQuote = strchr(_strCmd+1, '"');
|
|
// if not found
|
|
if (pchClosingQuote==NULL) {
|
|
// error in command line
|
|
cmd_strOutput+=CTString(0, TRANS("Command line error!\n"));
|
|
// finish parsing
|
|
_strCmd = "";
|
|
return "";
|
|
}
|
|
INDEX iQuote = pchClosingQuote-_strCmd;
|
|
|
|
// get the quoted string
|
|
CTString strWord;
|
|
CTString strRest;
|
|
_strCmd.Split(iQuote, strWord, strRest);
|
|
// remove the quotes
|
|
strWord.DeleteChar(0);
|
|
strRest.DeleteChar(0);
|
|
// get the word
|
|
_strCmd = strRest;
|
|
return strWord;
|
|
|
|
// if the first char is not quote
|
|
} else {
|
|
// find first next space
|
|
INDEX iSpace;
|
|
INDEX ctChars = strlen(_strCmd);
|
|
for(iSpace=0; iSpace<ctChars; iSpace++) {
|
|
if (isspace(_strCmd[iSpace])) {
|
|
break;
|
|
}
|
|
}
|
|
// get the word string
|
|
CTString strWord;
|
|
CTString strRest;
|
|
_strCmd.Split(iSpace, strWord, strRest);
|
|
// remove the space
|
|
strRest.DeleteChar(0);
|
|
// get the word
|
|
_strCmd = strRest;
|
|
return strWord;
|
|
}
|
|
}
|
|
|
|
// check for custom parameters
|
|
void CWorldEditorApp::MyParseCommandLine(void)
|
|
{
|
|
_strCmd = CStringA(m_lpCmdLine);
|
|
cmd_strOutput = "";
|
|
cmd_strOutput+=CTString(0, TRANS("Command line: '%s'\n"), _strCmd);
|
|
// if no command line
|
|
if (strlen(_strCmd) == 0) {
|
|
// do nothing
|
|
return;
|
|
}
|
|
|
|
FOREVER {
|
|
CTString strWord = GetNextParam();
|
|
if (strWord=="") {
|
|
cmd_strOutput+="\n";
|
|
_strCmdW = CString(_strCmd);
|
|
m_lpCmdLine = (LPWSTR)(LPCWSTR)_strCmdW;
|
|
return;
|
|
} else if (strWord=="+game") {
|
|
CTString strMod = GetNextParam();
|
|
if (strMod!="SeriousSam") { // (we ignore default mod - always use base dir in that case)
|
|
cmd_strMod = strMod;
|
|
_fnmMod = "Mods\\"+strMod+"\\";
|
|
}
|
|
} else {
|
|
_strCmdW = CString(_strCmd);
|
|
m_lpCmdLine = (LPWSTR)(LPCWSTR)_strCmdW;
|
|
return;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
BOOL CWorldEditorApp::SubInitInstance()
|
|
{
|
|
// required for visual styles
|
|
InitCommonControls();
|
|
|
|
// Standard initialization
|
|
// If you are not using these features and wish to reduce the size
|
|
// of your final executable, you should remove from the following
|
|
// the specific initialization routines you do not need.
|
|
|
|
// Initialize OLE 2.0 libraries
|
|
if (!AfxOleInit())
|
|
{
|
|
AfxMessageBox(L"ERROR: Failed to initialize OLE 2.0 libraries");
|
|
return FALSE;
|
|
}
|
|
AfxEnableControlContainer();
|
|
|
|
// check for custom parameters
|
|
MyParseCommandLine();
|
|
|
|
#ifdef _AFXDLL
|
|
Enable3dControls(); // Call this when using MFC in a shared DLL
|
|
#else
|
|
Enable3dControlsStatic(); // Call this when linking to MFC statically
|
|
#endif
|
|
|
|
// initialize entire engine
|
|
SE_InitEngine("SeriousEditor");
|
|
SE_LoadDefaultFonts();
|
|
|
|
// settings will be saved into registry instead of ini file
|
|
if (_strModExt=="") {
|
|
SetRegistryKey( CString("CroTeam"));
|
|
} else {
|
|
SetRegistryKey( CString("CroTeam\\"+_strModExt));
|
|
}
|
|
|
|
CPrintF("%s", cmd_strOutput);
|
|
|
|
// if the registry is not set yet
|
|
CString strDefaultTexture = GetProfileString( L"World editor prefs", L"Default primitive texture", L"");
|
|
if (strDefaultTexture == L"") {
|
|
// load registry from the ini file
|
|
CTString strCommand;
|
|
strCommand.PrintF("regedit.exe -s \"%s%s\"",
|
|
(const CTString&)_fnmApplicationPath,
|
|
(const CTString&)CTString("Data\\Defaults\\WorldEditor.reg"));
|
|
system(strCommand);
|
|
/* _spawnlp(_P_WAIT, "regedit.exe",
|
|
"-s",
|
|
(const CTString&)(_fnmApplicationPath+CTString("Data\\Defaults\\WorldEditor.reg")),
|
|
NULL);
|
|
*/
|
|
}
|
|
|
|
LoadStdProfileSettings(8); // Load standard INI file options (including MRU)
|
|
|
|
// Register the application's document templates. Document templates
|
|
// serve as the connection between documents, frame windows and views.
|
|
|
|
m_pDocTemplate = new CMultiDocTemplate(
|
|
IDR_WEDTYPE,
|
|
RUNTIME_CLASS(CWorldEditorDoc),
|
|
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
|
|
RUNTIME_CLASS(CWorldEditorView));
|
|
AddDocTemplate(m_pDocTemplate);
|
|
|
|
// create application windows font
|
|
LOGFONT logFont;
|
|
memset(&logFont, 0, sizeof(logFont));
|
|
if( !::GetSystemMetrics(SM_DBCSENABLED)){
|
|
logFont.lfHeight = -11;
|
|
logFont.lfWeight = FW_REGULAR;
|
|
logFont.lfPitchAndFamily = FF_ROMAN;
|
|
logFont.lfOrientation = 10;
|
|
logFont.lfQuality = PROOF_QUALITY;
|
|
logFont.lfItalic = TRUE;
|
|
lstrcpy(logFont.lfFaceName, L"Arial");
|
|
if( !m_Font.CreateFontIndirect(&logFont))
|
|
TRACE0("Could Not create font for combo\n");
|
|
} else {
|
|
m_Font.Attach(::GetStockObject(SYSTEM_FONT));
|
|
}
|
|
|
|
memset(&logFont, 0, sizeof(logFont));
|
|
if( !::GetSystemMetrics(SM_DBCSENABLED)){
|
|
logFont.lfHeight = -11;
|
|
logFont.lfWeight = FW_REGULAR;
|
|
logFont.lfPitchAndFamily = FF_MODERN;
|
|
logFont.lfOrientation = 10;
|
|
logFont.lfQuality = PROOF_QUALITY;
|
|
logFont.lfItalic = FALSE;
|
|
lstrcpy(logFont.lfFaceName, L"Courier New");
|
|
if( !m_FixedFont.CreateFontIndirect(&logFont))
|
|
TRACE0("Could Not create fixed font\n");
|
|
} else {
|
|
m_FixedFont.Attach(::GetStockObject(SYSTEM_FONT));
|
|
}
|
|
|
|
// create main MDI Frame window
|
|
CMainFrame* pMainFrame = new CMainFrame;
|
|
if( !pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE;
|
|
m_pMainWnd = pMainFrame;
|
|
|
|
// set main window for engine
|
|
SE_UpdateWindowHandle( m_pMainWnd->m_hWnd);
|
|
|
|
// Enable drag/drop open
|
|
m_pMainWnd->DragAcceptFiles();
|
|
|
|
// Enable DDE Execute open
|
|
EnableShellOpen();
|
|
RegisterShellFileTypes(TRUE);
|
|
|
|
// Parse command line for standard shell commands, DDE, file open
|
|
CCommandLineInfo cmdInfo;
|
|
ParseCommandLine(cmdInfo);
|
|
|
|
// add console variables
|
|
extern INDEX wed_bSaveTestGameFirstTime;
|
|
_pShell->DeclareSymbol("user INDEX wed_bSaveTestGameFirstTime;", &wed_bSaveTestGameFirstTime);
|
|
_pShell->DeclareSymbol("persistent user INDEX wed_iMaxFPSActive;", &wed_iMaxFPSActive);
|
|
_pShell->DeclareSymbol("persistent user FLOAT wed_fFrontClipDistance;", &wed_fFrontClipDistance);
|
|
_pShell->DeclareSymbol("persistent user INDEX wed_bUseGenericTextureReplacement;", &wed_bUseGenericTextureReplacement);
|
|
|
|
// functions that are used to change rendering preferences while testing game
|
|
_pShell->DeclareSymbol("user void WED_ApplyChildSettings0(void);", &WED_ApplyChildSettings0);
|
|
_pShell->DeclareSymbol("user void WED_ApplyChildSettings1(void);", &WED_ApplyChildSettings1);
|
|
_pShell->DeclareSymbol("user void WED_ApplyChildSettings2(void);", &WED_ApplyChildSettings2);
|
|
_pShell->DeclareSymbol("user void WED_ApplyChildSettings3(void);", &WED_ApplyChildSettings3);
|
|
_pShell->DeclareSymbol("user void WED_ApplyChildSettings4(void);", &WED_ApplyChildSettings4);
|
|
_pShell->DeclareSymbol("user void WED_ApplyChildSettings5(void);", &WED_ApplyChildSettings5);
|
|
_pShell->DeclareSymbol("user void WED_ApplyChildSettings6(void);", &WED_ApplyChildSettings6);
|
|
_pShell->DeclareSymbol("user void WED_ApplyChildSettings7(void);", &WED_ApplyChildSettings7);
|
|
_pShell->DeclareSymbol("user void WED_ApplyChildSettings8(void);", &WED_ApplyChildSettings8);
|
|
_pShell->DeclareSymbol("user void WED_ApplyChildSettings9(void);", &WED_ApplyChildSettings9);
|
|
|
|
_pShell->DeclareSymbol("user void WED_ApplyRenderingSettings0(void);", &WED_ApplyRenderingSettings0);
|
|
_pShell->DeclareSymbol("user void WED_ApplyRenderingSettings1(void);", &WED_ApplyRenderingSettings1);
|
|
_pShell->DeclareSymbol("user void WED_ApplyRenderingSettings2(void);", &WED_ApplyRenderingSettings2);
|
|
_pShell->DeclareSymbol("user void WED_ApplyRenderingSettings3(void);", &WED_ApplyRenderingSettings3);
|
|
_pShell->DeclareSymbol("user void WED_ApplyRenderingSettings4(void);", &WED_ApplyRenderingSettings4);
|
|
_pShell->DeclareSymbol("user void WED_ApplyRenderingSettings5(void);", &WED_ApplyRenderingSettings5);
|
|
_pShell->DeclareSymbol("user void WED_ApplyRenderingSettings6(void);", &WED_ApplyRenderingSettings6);
|
|
_pShell->DeclareSymbol("user void WED_ApplyRenderingSettings7(void);", &WED_ApplyRenderingSettings7);
|
|
_pShell->DeclareSymbol("user void WED_ApplyRenderingSettings8(void);", &WED_ApplyRenderingSettings8);
|
|
_pShell->DeclareSymbol("user void WED_ApplyRenderingSettings9(void);", &WED_ApplyRenderingSettings9);
|
|
|
|
_pShell->DeclareSymbol("user void WED_FindEmptyBrush(void);", &WED_FindEmptyBrushes);
|
|
|
|
// load persistent symbols
|
|
_pShell->Execute(CTString("include \""+fnmPersistentSymbols+"\";"));
|
|
|
|
// prepare full screen mode
|
|
_EngineGUI.GetFullScreenModeFromRegistry( "Display modes", m_dmFullScreen, m_gatFullScreen);
|
|
_EngineGUI.SetFullScreenModeToRegistry( "Display modes", m_dmFullScreen, m_gatFullScreen);
|
|
|
|
m_iApi=GAT_OGL;
|
|
m_iApi=AfxGetApp()->GetProfileInt(L"Display modes", L"SED Gfx API", GAT_OGL);
|
|
|
|
// (re)set default display mode
|
|
_pGfx->ResetDisplayMode((enum GfxAPIType) m_iApi);
|
|
|
|
// initialize game itself (GameShell interface) and load settings
|
|
InitializeGame();
|
|
// load startup script
|
|
_pShell->Execute( "include \"Scripts\\WorldEditor_startup.ini\"");
|
|
|
|
// read all data from ini file
|
|
ReadFromIniFileOnInit();
|
|
ReadDefaultPolygonValues();
|
|
|
|
// load primitives history buffer
|
|
CTString strPrimitives("Data\\PrimitivesHistory.pri");
|
|
if (FileExists(strPrimitives)) {
|
|
CTFileStream strmFile;
|
|
try
|
|
{
|
|
strmFile.Open_t(strPrimitives);
|
|
INDEX ctHistory;
|
|
strmFile >> ctHistory;
|
|
for( INDEX iPrim=0; iPrim<ctHistory; iPrim++)
|
|
{
|
|
CPrimitiveInHistoryBuffer *ppihbMember = new CPrimitiveInHistoryBuffer;
|
|
ppihbMember->pihb_vfpPrimitive.Read_t( strmFile);
|
|
m_lhPrimitiveHistory.AddTail( ppihbMember->pihb_lnNode);
|
|
}
|
|
}
|
|
catch( char *strError)
|
|
{
|
|
WarningMessage( strError);
|
|
}
|
|
}
|
|
|
|
m_bDecadicGrid = !m_Preferences.ap_BinaryGrid;
|
|
|
|
// don't start new document automatically
|
|
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
|
|
|
|
// create temporary directory to contain undo files
|
|
CreateDirectoryA( _fnmApplicationPath + "Temp\\", NULL);
|
|
|
|
// try to
|
|
try
|
|
{
|
|
// load error texture
|
|
DECLARE_CTFILENAME( fnErrorTexture, "Textures\\Editor\\Error.tex");
|
|
m_ptdError = _pTextureStock->Obtain_t( fnErrorTexture);
|
|
// load error texture
|
|
DECLARE_CTFILENAME( fnViewIcons, "Models\\Editor\\ViewIcons.tex");
|
|
m_pViewIconsTD = _pTextureStock->Obtain_t( fnViewIcons);
|
|
// load icon tray texture
|
|
DECLARE_CTFILENAME( fnIconTrayTexture, "Textures\\Editor\\IconsTray.tex");
|
|
m_ptdIconsTray = _pTextureStock->Obtain_t( fnIconTrayTexture);
|
|
}
|
|
catch( char *err_str)
|
|
{
|
|
AfxMessageBox( CString(err_str));
|
|
return FALSE;
|
|
}
|
|
m_ptoError = new CTextureObject;
|
|
m_ptoError->SetData( m_ptdError);
|
|
|
|
// assign system font
|
|
m_pfntSystem = _pfdDisplayFont;
|
|
|
|
try
|
|
{
|
|
// load entity selection marker model
|
|
DECLARE_CTFILENAME( fnEntityMarker, "Models\\Editor\\EntityMarker.mdl");
|
|
m_pEntityMarkerModelData = _pModelStock->Obtain_t( fnEntityMarker);
|
|
m_pEntityMarkerModelObject = new CModelObject;
|
|
m_pEntityMarkerModelObject->SetData(m_pEntityMarkerModelData);
|
|
m_pEntityMarkerModelObject->SetAnim( 0);
|
|
// load entity selection marker model's texture
|
|
DECLARE_CTFILENAME( fnEntityMarkerTex, "Models\\Editor\\EntityMarker.tex");
|
|
m_ptdEntityMarkerTexture = _pTextureStock->Obtain_t( fnEntityMarkerTex);
|
|
m_pEntityMarkerModelObject->mo_toTexture.SetData( m_ptdEntityMarkerTexture);
|
|
|
|
// load portal selection marker model
|
|
DECLARE_CTFILENAME( fnPortalMarker, "Models\\Editor\\PortalMarker.mdl");
|
|
m_pPortalMarkerModelData = _pModelStock->Obtain_t( fnPortalMarker);
|
|
m_pPortalMarkerModelObject = new CModelObject;
|
|
m_pPortalMarkerModelObject->SetData(m_pPortalMarkerModelData);
|
|
m_pPortalMarkerModelObject->SetAnim( 0);
|
|
// load portal selection marker model's texture
|
|
DECLARE_CTFILENAME( fnPortalMarkerTex, "Models\\Editor\\PortalMarker.tex");
|
|
m_ptdPortalMarkerTexture = _pTextureStock->Obtain_t( fnPortalMarkerTex);
|
|
m_pPortalMarkerModelObject->mo_toTexture.SetData( m_ptdPortalMarkerTexture);
|
|
|
|
// load empty brush model
|
|
DECLARE_CTFILENAME( fnEmptyBrush, "Models\\Editor\\EmptyBrush.mdl");
|
|
m_pEmptyBrushModelData = _pModelStock->Obtain_t( fnEmptyBrush);
|
|
m_pEmptyBrushModelObject = new CModelObject;
|
|
m_pEmptyBrushModelObject->SetData(m_pEmptyBrushModelData);
|
|
m_pEmptyBrushModelObject->SetAnim( 0);
|
|
// load empty brush model's texture
|
|
DECLARE_CTFILENAME( fnEmptyBrushTex, "Models\\Editor\\EmptyBrush.tex");
|
|
m_ptdEmptyBrushTexture = _pTextureStock->Obtain_t( fnEmptyBrushTex);
|
|
m_pEmptyBrushModelObject->mo_toTexture.SetData( m_ptdEmptyBrushTexture);
|
|
|
|
// load range sphere
|
|
DECLARE_CTFILENAME( fnRangeSphere, "Models\\Editor\\RangeSphere.mdl");
|
|
m_pRangeSphereModelData = _pModelStock->Obtain_t( fnRangeSphere);
|
|
m_pRangeSphereModelObject = new CModelObject;
|
|
m_pRangeSphereModelObject->SetData(m_pRangeSphereModelData);
|
|
m_pRangeSphereModelObject->SetAnim( 0);
|
|
// load range sphere model's texture
|
|
DECLARE_CTFILENAME( fnRangeSphereTex, "Models\\Editor\\RangeSphere.tex");
|
|
m_ptdRangeSphereTexture = _pTextureStock->Obtain_t( fnRangeSphereTex);
|
|
m_pRangeSphereModelObject->mo_toTexture.SetData( m_ptdRangeSphereTexture);
|
|
|
|
// load angle 3d model
|
|
DECLARE_CTFILENAME( fnAngle3D, "Models\\Editor\\AngleVector.mdl");
|
|
m_pAngle3DModelData = _pModelStock->Obtain_t( fnAngle3D);
|
|
m_pAngle3DModelObject = new CModelObject;
|
|
m_pAngle3DModelObject->SetData(m_pAngle3DModelData);
|
|
m_pAngle3DModelObject->SetAnim( 0);
|
|
// load angle 3d model's texture
|
|
DECLARE_CTFILENAME( fnAngle3DTex, "Models\\Editor\\Vector.tex");
|
|
m_ptdAngle3DTexture = _pTextureStock->Obtain_t( fnAngle3DTex);
|
|
m_pAngle3DModelObject->mo_toTexture.SetData( m_ptdAngle3DTexture);
|
|
|
|
// load bounding box
|
|
DECLARE_CTFILENAME( fnBoundingBox, "Models\\Editor\\BoundingBox.mdl");
|
|
m_pBoundingBoxModelData = _pModelStock->Obtain_t( fnBoundingBox);
|
|
m_pBoundingBoxModelObject = new CModelObject;
|
|
m_pBoundingBoxModelObject->SetData(m_pBoundingBoxModelData);
|
|
m_pBoundingBoxModelObject->SetAnim( 0);
|
|
// load bounding box model's texture
|
|
DECLARE_CTFILENAME( fnBoundingBoxTex, "Models\\Editor\\BoundingBox.tex");
|
|
m_ptdBoundingBoxTexture = _pTextureStock->Obtain_t( fnBoundingBoxTex);
|
|
m_pBoundingBoxModelObject->mo_toTexture.SetData( m_ptdBoundingBoxTexture);
|
|
}
|
|
catch (char *error)
|
|
{
|
|
FatalError("Cannot load one of entity selection model components: %s", error);
|
|
return FALSE;
|
|
}
|
|
|
|
// initialize browsing window's view port
|
|
CBrowseWindow *pBrowseWindow = &pMainFrame->m_Browser.m_BrowseWindow;
|
|
_pGfx->CreateWindowCanvas( pMainFrame->m_Browser.m_BrowseWindow.m_hWnd, &pBrowseWindow->m_pViewPort,
|
|
&pBrowseWindow->m_pDrawPort);
|
|
pMainFrame->m_Browser.OpenSelectedDirectory();
|
|
|
|
// assure that terrain brushes exist
|
|
GenerateNonExistingTerrainEditBrushes();
|
|
|
|
// Dispatch commands specified on the command line
|
|
if (!ProcessShellCommand(cmdInfo))
|
|
return FALSE;
|
|
|
|
// The main window has been initialized, so show and update it.
|
|
pMainFrame->ShowWindow(SW_SHOWMAXIMIZED);
|
|
pMainFrame->UpdateWindow();
|
|
|
|
// show tip of the day
|
|
if (m_bShowTipOfTheDay) {
|
|
OnHelpShowTipOfTheDay();
|
|
}
|
|
|
|
// if we should automatically call preferences dialog (because WED is first time started)
|
|
if( m_bFirstTimeStarted) OnFilePreferences();
|
|
|
|
CTString strCmdLine=CTString(CStringA(m_lpCmdLine));
|
|
if(strCmdLine[0]=='\"' && strCmdLine[strCmdLine.Length()-1]=='\"')
|
|
{
|
|
strCmdLine.DeleteChar(0);
|
|
strCmdLine.DeleteChar(strCmdLine.Length()-1);
|
|
}
|
|
|
|
if (strCmdLine != "" && !strCmdLine.RemovePrefix("/dde"))
|
|
{
|
|
// Open a file passed as the first command line parameter.
|
|
OpenDocumentFile(m_lpCmdLine);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// 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)
|
|
// No message handlers
|
|
//}}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()
|
|
|
|
// App command to run the dialog
|
|
void CWorldEditorApp::OnAppAbout()
|
|
{
|
|
CAboutDlg aboutDlg;
|
|
aboutDlg.DoModal();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWorldEditorApp commands
|
|
|
|
BOOL CWorldEditorApp::SaveAllModified()
|
|
{
|
|
CMainFrame* pMainFrame = (CMainFrame *) m_pMainWnd;
|
|
|
|
if( (pMainFrame != NULL) && (pMainFrame->m_Browser.m_bVirtualTreeChanged) )
|
|
{
|
|
switch(::MessageBoxA( pMainFrame->m_hWnd,
|
|
"Virtual tree changed but not saved. Do You want to save it?", "Warning !",
|
|
MB_YESNOCANCEL | MB_ICONWARNING | MB_DEFBUTTON1 | MB_TASKMODAL | MB_TOPMOST) )
|
|
{
|
|
case IDYES:
|
|
{
|
|
pMainFrame->m_Browser.SaveVirtualTree(pMainFrame->m_fnLastVirtualTree, &pMainFrame->m_Browser.m_VirtualTree);
|
|
break;
|
|
}
|
|
case IDCANCEL:
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return CWinApp::SaveAllModified();
|
|
}
|
|
|
|
void CWorldEditorApp::ReadFromIniFileOnInit(void)
|
|
{
|
|
char strIni[ 256];
|
|
|
|
// read data that can be saved multiple times to ini file
|
|
ReadFromIniFile();
|
|
|
|
// obtain texture for primitive
|
|
CString strTexture = GetProfileString( L"World editor prefs", L"Default primitive texture", L"Textures\\Editor\\Default.tex");
|
|
// if exists in ini file
|
|
if( strTexture != L"")
|
|
{
|
|
theApp.SetNewActiveTexture( _fnmApplicationPath + CTString(CStringA(strTexture)));
|
|
}
|
|
|
|
INI_READ( "Paint power", "1.0");
|
|
GET_FLOAT( m_fPaintPower);
|
|
|
|
INI_READ( "Smooth power", "1.0");
|
|
GET_FLOAT( m_fSmoothPower);
|
|
|
|
INI_READ( "Current filter", "1");
|
|
GET_INDEX( m_iFilter);
|
|
|
|
INI_READ( "Posterize step", "2.0");
|
|
GET_FLOAT( m_fPosterizeStep);
|
|
|
|
INI_READ( "Terrain generation method", "0");
|
|
GET_INDEX( m_iTerrainGenerationMethod);
|
|
|
|
INI_READ( "Subdivade and displace itterations", "2");
|
|
GET_INDEX( m_iRNDSubdivideAndDisplaceItterations);
|
|
|
|
INI_READ( "Noise altitude", "1.0");
|
|
GET_FLOAT( m_fNoiseAltitude);
|
|
|
|
INI_READ( "Distribution noise texture", CTFILENAME("Textures\\Editor\\RandomNoise.tex"));
|
|
GET_STRING( m_fnDistributionNoiseTexture);
|
|
|
|
INI_READ( "Continous noise texture", CTFILENAME("Textures\\Editor\\RandomNoise.tex"));
|
|
GET_STRING( m_fnContinousNoiseTexture);
|
|
|
|
INI_READ( "FBM Octaves", "4");
|
|
GET_INDEX( m_iFBMOctaves);
|
|
|
|
INI_READ( "FBM High frequency step", "1.0");
|
|
GET_FLOAT( m_fFBMHighFrequencyStep);
|
|
|
|
INI_READ( "FBM Step factor", "2.0");
|
|
GET_FLOAT( m_fFBMStepFactor);
|
|
|
|
INI_READ( "FBM Max amplitude", "64.0");
|
|
GET_FLOAT( m_fFBMMaxAmplitude);
|
|
|
|
INI_READ( "FBM Amplitude decreaser", "0.5");
|
|
GET_FLOAT( m_fFBMfAmplitudeDecreaser);
|
|
|
|
INI_READ( "FBM Add negative values", "NO");
|
|
GET_FLAG( m_bFBMAddNegativeValues);
|
|
|
|
INI_READ( "FBM Random offset", "NO");
|
|
GET_FLAG( m_bFBMRandomOffset);
|
|
|
|
m_bShowTipOfTheDay = GetProfileInt(L"World editor", L"Show Tip of the Day", TRUE);
|
|
m_iCurrentTipOfTheDay = GetProfileInt(L"World editor", L"Current Tip of the Day", 0);
|
|
_fFlyModeSpeedMultiplier=m_Preferences.ap_fDefaultFlyModeSpeed;
|
|
}
|
|
|
|
void CWorldEditorApp::ReadFromIniFile()
|
|
{
|
|
// if loading of world and model's rendering preferences file fails
|
|
if( !LoadRenderingPreferences())
|
|
{
|
|
CViewPrefs tempVP;
|
|
// for all view's rendering preferences
|
|
for( INDEX i=0; i< VIEW_PREFERENCES_CT; i++)
|
|
{
|
|
// clear possibly wrong loaded values
|
|
m_vpViewPrefs[ i] = tempVP;
|
|
// set default values
|
|
m_vpViewPrefs[ i].SetDefaultValues();
|
|
}
|
|
|
|
// BUFFER 0: -default view
|
|
// BUFFER 1: -no REM
|
|
m_vpViewPrefs[ 1].m_wrpWorldRenderPrefs.SetEditorModelsOn( FALSE);
|
|
m_vpViewPrefs[ 1].m_wrpWorldRenderPrefs.SetFieldBrushesOn( FALSE);
|
|
m_vpViewPrefs[ 1].m_wrpWorldRenderPrefs.SetLensFlaresType( CWorldRenderPrefs::LFT_REFLECTIONS_AND_GLARE);
|
|
// BUFFER 2: -polygon color, edges ink, no REM
|
|
m_vpViewPrefs[ 2].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_POLYGONCOLOR);
|
|
m_vpViewPrefs[ 2].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_INKCOLOR);
|
|
m_vpViewPrefs[ 2].m_wrpWorldRenderPrefs.SetEditorModelsOn( FALSE);
|
|
m_vpViewPrefs[ 2].m_wrpWorldRenderPrefs.SetFieldBrushesOn( FALSE);
|
|
m_vpViewPrefs[ 2].m_wrpWorldRenderPrefs.SetLensFlaresType( CWorldRenderPrefs::LFT_REFLECTIONS_AND_GLARE);
|
|
// BUFFER 3: -wire frame (lines in color of polygons)
|
|
m_vpViewPrefs[ 3].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_NONE);
|
|
m_vpViewPrefs[ 3].m_wrpWorldRenderPrefs.SetEditorModelsOn( FALSE);
|
|
m_vpViewPrefs[ 3].m_wrpWorldRenderPrefs.SetFieldBrushesOn( FALSE);
|
|
m_vpViewPrefs[ 3].m_mrpModelRenderPrefs.BBoxAllShow( TRUE);
|
|
// BUFFER 4: -polygons show sector color, no REM
|
|
m_vpViewPrefs[ 4].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_INKCOLOR);
|
|
m_vpViewPrefs[ 4].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_SECTORCOLOR);
|
|
m_vpViewPrefs[ 4].m_wrpWorldRenderPrefs.SetEditorModelsOn( FALSE);
|
|
m_vpViewPrefs[ 4].m_wrpWorldRenderPrefs.SetFieldBrushesOn( FALSE);
|
|
// BUFFER 5: -polygons in gray color, no REM
|
|
m_vpViewPrefs[ 5].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_NONE);
|
|
m_vpViewPrefs[ 5].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_INKCOLOR);
|
|
m_vpViewPrefs[ 5].m_wrpWorldRenderPrefs.SetEditorModelsOn( FALSE);
|
|
m_vpViewPrefs[ 5].m_wrpWorldRenderPrefs.SetFieldBrushesOn( FALSE);
|
|
m_vpViewPrefs[ 5].m_wrpWorldRenderPrefs.SetPolygonsInkColor( C_GRAY);
|
|
// BUFFER 6: -polygons color, no REM
|
|
m_vpViewPrefs[ 6].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_POLYGONCOLOR);
|
|
m_vpViewPrefs[ 6].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_NONE);
|
|
m_vpViewPrefs[ 6].m_wrpWorldRenderPrefs.SetEditorModelsOn( FALSE);
|
|
m_vpViewPrefs[ 6].m_wrpWorldRenderPrefs.SetFieldBrushesOn( FALSE);
|
|
// BUFFER 7: -polygons in white color
|
|
m_vpViewPrefs[ 7].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_INKCOLOR);
|
|
m_vpViewPrefs[ 7].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_INKCOLOR);
|
|
m_vpViewPrefs[ 7].m_wrpWorldRenderPrefs.SetPolygonsInkColor( C_WHITE);
|
|
// BUFFER 8: -polygons use texture, edges ink
|
|
m_vpViewPrefs[ 8].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_TEXTURE);
|
|
m_vpViewPrefs[ 8].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_INKCOLOR);
|
|
// BUFFER 9: -game view with background texture
|
|
m_vpViewPrefs[ VIEW_PREFERENCES_CT-1].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_TEXTURE);
|
|
m_vpViewPrefs[ VIEW_PREFERENCES_CT-1].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_NONE);
|
|
m_vpViewPrefs[ VIEW_PREFERENCES_CT-1].m_wrpWorldRenderPrefs.SetEditorModelsOn( FALSE);
|
|
m_vpViewPrefs[ VIEW_PREFERENCES_CT-1].m_wrpWorldRenderPrefs.SetFieldBrushesOn( FALSE);
|
|
m_vpViewPrefs[ VIEW_PREFERENCES_CT-1].m_wrpWorldRenderPrefs.SetLensFlaresType( CWorldRenderPrefs::LFT_REFLECTIONS_AND_GLARE);
|
|
m_vpViewPrefs[ VIEW_PREFERENCES_CT-1].m_wrpWorldRenderPrefs.SetBackgroundTextureOn( TRUE);
|
|
m_vpViewPrefs[ VIEW_PREFERENCES_CT-1].m_wrpWorldRenderPrefs.SetFogOn( TRUE);
|
|
m_vpViewPrefs[ VIEW_PREFERENCES_CT-1].m_wrpWorldRenderPrefs.SetHazeOn( TRUE);
|
|
m_vpViewPrefs[ VIEW_PREFERENCES_CT-1].m_wrpWorldRenderPrefs.SetMirrorsOn( TRUE);
|
|
}
|
|
|
|
// if loading of child configuration file fails
|
|
if( !LoadChildConfigurations())
|
|
{
|
|
// for all child configurations
|
|
for( INDEX i=0; i<CHILD_CONFIGURATIONS_CT; i++)
|
|
{
|
|
// set default values
|
|
m_ccChildConfigurations[ i].SetDefaultValues();
|
|
}
|
|
// CONFIGURATION 0: 3+1 defaults, perspective has no wire frame, but has texture
|
|
m_ccChildConfigurations[ 0].m_vpViewPrefs[ 1] = theApp.m_vpViewPrefs[ 0];
|
|
m_ccChildConfigurations[ 0].m_vpViewPrefs[ 1].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_NONE);
|
|
m_ccChildConfigurations[ 0].m_vpViewPrefs[ 1].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_TEXTURE);
|
|
// CONFIGURATION 1: 3+1, same as 0 but no editor models
|
|
m_ccChildConfigurations[ 1].m_vpViewPrefs[ 0] = theApp.m_vpViewPrefs[ 1];
|
|
m_ccChildConfigurations[ 1].m_vpViewPrefs[ 1] = theApp.m_vpViewPrefs[ 1];
|
|
m_ccChildConfigurations[ 1].m_vpViewPrefs[ 2] = theApp.m_vpViewPrefs[ 1];
|
|
m_ccChildConfigurations[ 1].m_vpViewPrefs[ 3] = theApp.m_vpViewPrefs[ 1];
|
|
m_ccChildConfigurations[ 1].m_vpViewPrefs[ 1].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_NONE);
|
|
m_ccChildConfigurations[ 1].m_vpViewPrefs[ 1].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_TEXTURE);
|
|
// CONFIGURATION 2: 3+1, polygon color, edges ink, no REM
|
|
m_ccChildConfigurations[ 2].m_vpViewPrefs[ 0] = theApp.m_vpViewPrefs[ 1];
|
|
m_ccChildConfigurations[ 2].m_vpViewPrefs[ 1] = theApp.m_vpViewPrefs[ 2];
|
|
m_ccChildConfigurations[ 2].m_vpViewPrefs[ 2] = theApp.m_vpViewPrefs[ 1];
|
|
m_ccChildConfigurations[ 2].m_vpViewPrefs[ 3] = theApp.m_vpViewPrefs[ 1];
|
|
// CONFIGURATION 3: 3+1, texture fill in all views, no wire
|
|
m_ccChildConfigurations[ 3].m_vpViewPrefs[ 0] = theApp.m_vpViewPrefs[ 0];
|
|
m_ccChildConfigurations[ 3].m_vpViewPrefs[ 1] = theApp.m_vpViewPrefs[ 0];
|
|
m_ccChildConfigurations[ 3].m_vpViewPrefs[ 2] = theApp.m_vpViewPrefs[ 0];
|
|
m_ccChildConfigurations[ 3].m_vpViewPrefs[ 3] = theApp.m_vpViewPrefs[ 0];
|
|
m_ccChildConfigurations[ 3].m_vpViewPrefs[ 0].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_NONE);
|
|
m_ccChildConfigurations[ 3].m_vpViewPrefs[ 0].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_TEXTURE);
|
|
m_ccChildConfigurations[ 3].m_vpViewPrefs[ 1].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_NONE);
|
|
m_ccChildConfigurations[ 3].m_vpViewPrefs[ 1].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_TEXTURE);
|
|
m_ccChildConfigurations[ 3].m_vpViewPrefs[ 2].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_NONE);
|
|
m_ccChildConfigurations[ 3].m_vpViewPrefs[ 2].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_TEXTURE);
|
|
m_ccChildConfigurations[ 3].m_vpViewPrefs[ 3].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_NONE);
|
|
m_ccChildConfigurations[ 3].m_vpViewPrefs[ 3].m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_TEXTURE);
|
|
// CONFIGURATION 4: 1, shadows (gray), no REM
|
|
m_ccChildConfigurations[ 4].m_iHorizontalSplitters = 1;
|
|
m_ccChildConfigurations[ 4].m_iVerticalSplitters = 1;
|
|
m_ccChildConfigurations[ 4].m_ptProjectionType[ 0] = CSlaveViewer::PT_PERSPECTIVE;
|
|
m_ccChildConfigurations[ 4].m_vpViewPrefs[ 0] = theApp.m_vpViewPrefs[ 5];
|
|
// CONFIGURATION 5: 1, wire frame
|
|
m_ccChildConfigurations[ 5].m_iHorizontalSplitters = 1;
|
|
m_ccChildConfigurations[ 5].m_iVerticalSplitters = 1;
|
|
m_ccChildConfigurations[ 5].m_ptProjectionType[ 0] = CSlaveViewer::PT_PERSPECTIVE;
|
|
m_ccChildConfigurations[ 5].m_vpViewPrefs[ 0] = theApp.m_vpViewPrefs[ 3];
|
|
// CONFIGURATION 6: 1, clean, game view
|
|
m_ccChildConfigurations[ 6].m_iHorizontalSplitters = 1;
|
|
m_ccChildConfigurations[ 6].m_iVerticalSplitters = 1;
|
|
m_ccChildConfigurations[ 6].m_ptProjectionType[ 0] = CSlaveViewer::PT_PERSPECTIVE;
|
|
m_ccChildConfigurations[ 6].m_vpViewPrefs[ 0] = theApp.m_vpViewPrefs[ VIEW_PREFERENCES_CT-1];
|
|
// CONFIGURATION 7: 1, shadows + black wire frame
|
|
m_ccChildConfigurations[ 7].m_iHorizontalSplitters = 1;
|
|
m_ccChildConfigurations[ 7].m_iVerticalSplitters = 1;
|
|
m_ccChildConfigurations[ 7].m_ptProjectionType[ 0] = CSlaveViewer::PT_PERSPECTIVE;
|
|
m_ccChildConfigurations[ 7].m_vpViewPrefs[ 0] = theApp.m_vpViewPrefs[ 5];
|
|
m_ccChildConfigurations[ 7].m_vpViewPrefs[ 0].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_INKCOLOR);
|
|
// CONFIGURATION 8: 1, clean, edges ink
|
|
m_ccChildConfigurations[ 8].m_iHorizontalSplitters = 1;
|
|
m_ccChildConfigurations[ 8].m_iVerticalSplitters = 1;
|
|
m_ccChildConfigurations[ 8].m_ptProjectionType[ 0] = CSlaveViewer::PT_PERSPECTIVE;
|
|
m_ccChildConfigurations[ 8].m_vpViewPrefs[ 0] = theApp.m_vpViewPrefs[ 8];
|
|
m_ccChildConfigurations[ 8].m_vpViewPrefs[ 0].m_wrpWorldRenderPrefs.SetEditorModelsOn( FALSE);
|
|
m_ccChildConfigurations[ 8].m_vpViewPrefs[ 0].m_wrpWorldRenderPrefs.SetFieldBrushesOn( FALSE);
|
|
// CONFIGURATION 9: 1, polygons use texture, edges ink
|
|
m_ccChildConfigurations[ 9].m_iHorizontalSplitters = 1;
|
|
m_ccChildConfigurations[ 9].m_iVerticalSplitters = 1;
|
|
m_ccChildConfigurations[ 9].m_ptProjectionType[ 0] = CSlaveViewer::PT_PERSPECTIVE;
|
|
m_ccChildConfigurations[ 9].m_vpViewPrefs[ 0] = theApp.m_vpViewPrefs[ 8];
|
|
m_ccChildConfigurations[ 9].m_vpViewPrefs[ 0].m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_NONE);
|
|
}
|
|
|
|
// read values for preferences
|
|
m_Preferences.ReadFromIniFile();
|
|
|
|
// read from INI primitive settings
|
|
m_vfpPreLast.ReadFromIniFile("PreLast");
|
|
m_vfpLast.ReadFromIniFile("Last");
|
|
m_vfpCurrent.ReadFromIniFile("Current");
|
|
m_vfpConus.ReadFromIniFile("Conus");
|
|
m_vfpConus.vfp_ptPrimitiveType = PT_CONUS;
|
|
m_vfpTorus.ReadFromIniFile("Torus");
|
|
m_vfpTorus.vfp_ptPrimitiveType = PT_TORUS;
|
|
m_vfpStaircases.ReadFromIniFile("Staircases");
|
|
m_vfpStaircases.vfp_ptPrimitiveType = PT_STAIRCASES;
|
|
m_vfpSphere.ReadFromIniFile("Sphere");
|
|
m_vfpSphere.vfp_ptPrimitiveType = PT_SPHERE;
|
|
m_vfpTerrain.ReadFromIniFile("Terrain");
|
|
m_vfpTerrain.vfp_ptPrimitiveType = PT_TERRAIN;
|
|
}
|
|
|
|
// World editor ini read function for preferences
|
|
void CAppPrefs::ReadFromIniFile()
|
|
{
|
|
char strIni[ 256];
|
|
|
|
INI_READ( "Copy existing window preferences", "NO");
|
|
GET_FLAG( ap_CopyExistingWindowPrefs);
|
|
INI_READ( "Auto maximize window", "YES");
|
|
GET_FLAG( ap_AutoMaximizeWindow);
|
|
INI_READ( "Set default colors", "YES");
|
|
GET_FLAG( ap_SetDefaultColors);
|
|
INI_READ( "Automatic info", "YES");
|
|
GET_FLAG( ap_AutomaticInfo);
|
|
INI_READ( "Update allways", "NO");
|
|
GET_FLAG( ap_UpdateAllways);
|
|
INI_READ( "Binary grid", "YES");
|
|
GET_FLAG( ap_BinaryGrid);
|
|
INI_READ( "Save undo for delete", "YES");
|
|
GET_FLAG( ap_bSaveUndoForDelete);
|
|
INI_READ( "Auto colorize primitives", "YES");
|
|
GET_FLAG( ap_bAutoColorize);
|
|
INI_READ( "Show all on open", "YES");
|
|
GET_FLAG( ap_bShowAllOnOpen);
|
|
INI_READ( "Hide shadows on open", "NO");
|
|
GET_FLAG( ap_bHideShadowsOnOpen);
|
|
INI_READ( "Auto update displace map", "YES");
|
|
GET_FLAG( ap_bAutoUpdateDisplaceMap);
|
|
|
|
INI_READ( "Undo levels", "10");
|
|
GET_INDEX( ap_iUndoLevels);
|
|
INI_READ( "Startup window setup", "0");
|
|
GET_INDEX( ap_iStartupWindowSetup);
|
|
|
|
INI_READ( "Ink color", "0X00000000");
|
|
GET_COLOR( ap_DefaultInkColor);
|
|
INI_READ( "Paper color", "0XAAAAAAAA");
|
|
GET_COLOR( ap_DefaultPaperColor);
|
|
INI_READ( "Current selection color", "0XFFFFFFFF");
|
|
GET_COLOR( ap_DefaultSelectionColor);
|
|
INI_READ( "Current grid color", "0XFF000000");
|
|
GET_COLOR( ap_DefaultGridColor);
|
|
|
|
INI_READ( "Source safe project", "$/Flesh/");
|
|
GET_STRING( ap_strSourceSafeProject);
|
|
|
|
INI_READ( "Default fly mode speed", "1.0");
|
|
GET_FLOAT( ap_fDefaultFlyModeSpeed);
|
|
|
|
INI_READ( "Terrain selection visible", "0");
|
|
GET_INDEX( ap_iTerrainSelectionVisible);
|
|
INI_READ( "Terrain selection hidden", "1");
|
|
GET_INDEX( ap_iTerrainSelectionHidden);
|
|
|
|
INI_READ( "Memory for terrain undo", "32");
|
|
GET_INDEX( ap_iMemoryForTerrainUndo);
|
|
|
|
INI_READ( "Auto generate distribution", "YES");
|
|
GET_FLAG( ap_bAutoUpdateTerrainDistribution);
|
|
|
|
}
|
|
|
|
// read from INI last values for primitive
|
|
void CValuesForPrimitive::ReadFromIniFile(CTString strPrimitiveType)
|
|
{
|
|
CSetFPUPrecision FPUPrecision(FPT_53BIT);
|
|
char strIni[ 256];
|
|
|
|
INI_PRIMITIVE_READ( "primitive type", "1");
|
|
GET_INDEX( vfp_ptPrimitiveType);
|
|
INI_PRIMITIVE_READ( "x", "0.0");
|
|
GET_FLOAT( vfp_plPrimitive.pl_PositionVector(1));
|
|
INI_PRIMITIVE_READ( "y", "0.0");
|
|
GET_FLOAT( vfp_plPrimitive.pl_PositionVector(2));
|
|
INI_PRIMITIVE_READ( "z", "0.0");
|
|
GET_FLOAT( vfp_plPrimitive.pl_PositionVector(3));
|
|
INI_PRIMITIVE_READ( "heading", "0.0");
|
|
GET_FLOAT( vfp_plPrimitive.pl_OrientationAngle(1));
|
|
INI_PRIMITIVE_READ( "pitch", "0.0");
|
|
GET_FLOAT( vfp_plPrimitive.pl_OrientationAngle(2));
|
|
INI_PRIMITIVE_READ( "banking", "0.0");
|
|
GET_FLOAT( vfp_plPrimitive.pl_OrientationAngle(3));
|
|
|
|
INI_PRIMITIVE_READ( "triangularisation type", "0");
|
|
GET_INDEX( vfp_ttTriangularisationType);
|
|
|
|
INI_PRIMITIVE_READ( "closed", "NO");
|
|
GET_FLAG( vfp_bClosed);
|
|
INI_PRIMITIVE_READ( "gouraud shadows", "NO");
|
|
GET_FLAG( vfp_bDummy);
|
|
INI_PRIMITIVE_READ( "auto create mip brushes", "NO");
|
|
GET_FLAG( vfp_bAutoCreateMipBrushes);
|
|
INI_PRIMITIVE_READ( "sectors color", "0X0000FF00");
|
|
GET_COLOR( vfp_colSectorsColor);
|
|
INI_PRIMITIVE_READ( "polygons color", "0XFF000000");
|
|
GET_COLOR( vfp_colPolygonsColor);
|
|
|
|
INI_PRIMITIVE_READ( "x min", "-8");
|
|
GET_FLOAT( vfp_fXMin);
|
|
INI_PRIMITIVE_READ( "x max", "8");
|
|
GET_FLOAT( vfp_fXMax);
|
|
INI_PRIMITIVE_READ( "y min", "0");
|
|
GET_FLOAT( vfp_fYMin);
|
|
INI_PRIMITIVE_READ( "y max", "8");
|
|
GET_FLOAT( vfp_fYMax);
|
|
INI_PRIMITIVE_READ( "z min", "-8");
|
|
GET_FLOAT( vfp_fZMin);
|
|
INI_PRIMITIVE_READ( "z max", "8");
|
|
GET_FLOAT( vfp_fZMax);
|
|
INI_PRIMITIVE_READ( "shear x", "0.0");
|
|
GET_FLOAT( vfp_fShearX);
|
|
INI_PRIMITIVE_READ( "shear z", "0.0");
|
|
GET_FLOAT( vfp_fShearZ);
|
|
INI_PRIMITIVE_READ( "stretch x", "1.0");
|
|
GET_FLOAT( vfp_fStretchX);
|
|
INI_PRIMITIVE_READ( "stretch y", "1.0");
|
|
GET_FLOAT( vfp_fStretchY);
|
|
|
|
INI_PRIMITIVE_READ( "linear staircases", "NO");
|
|
GET_FLAG( vfp_bLinearStaircases);
|
|
INI_PRIMITIVE_READ( "outer", "YES");
|
|
GET_FLAG( vfp_bOuter);
|
|
|
|
INI_PRIMITIVE_READ( "slices in 360", "12");
|
|
GET_INDEX( vfp_iSlicesIn360);
|
|
INI_PRIMITIVE_READ( "no of slices", "6");
|
|
GET_INDEX( vfp_iNoOfSlices);
|
|
INI_PRIMITIVE_READ( "radius", "32.0");
|
|
GET_FLOAT( vfp_fRadius);
|
|
|
|
INI_PRIMITIVE_READ( "Primitive no of slices", "6");
|
|
GET_INDEX( vfp_iNoOfSlices);
|
|
|
|
INI_PRIMITIVE_READ( "meridians", "6");
|
|
GET_INDEX( vfp_iMeridians);
|
|
INI_PRIMITIVE_READ( "paralels", "6");
|
|
GET_INDEX( vfp_iParalels);
|
|
INI_PRIMITIVE_READ( "slices per width", "6");
|
|
GET_INDEX( vfp_iSlicesPerWidth);
|
|
INI_PRIMITIVE_READ( "slices per height", "6");
|
|
GET_INDEX( vfp_iSlicesPerHeight);
|
|
INI_PRIMITIVE_READ( "top shape", "0");
|
|
GET_INDEX( vfp_iTopShape);
|
|
INI_PRIMITIVE_READ( "bottom shape", "0");
|
|
GET_INDEX( vfp_iBottomShape);
|
|
INI_PRIMITIVE_READ( "csg operation", "0");
|
|
GET_INDEX( vfp_csgtCSGOperation);
|
|
|
|
INI_PRIMITIVE_READ( "amplitude", "50.0");
|
|
GET_FLOAT( vfp_fAmplitude);
|
|
INI_PRIMITIVE_READ( "mip start", "6.0");
|
|
GET_FLOAT( vfp_fMipStart);
|
|
INI_PRIMITIVE_READ( "mip step", "1.5");
|
|
GET_FLOAT( vfp_fMipStep);
|
|
INI_PRIMITIVE_READ( "displacement picture", "");
|
|
GET_STRING( vfp_fnDisplacement);
|
|
|
|
INDEX ctPrimitiveBaseVertices;
|
|
INI_PRIMITIVE_READ( "base vertices", "4");
|
|
GET_INDEX( ctPrimitiveBaseVertices);
|
|
vfp_avVerticesOnBaseOfPrimitive.Clear();
|
|
vfp_avVerticesOnBaseOfPrimitive.New( ctPrimitiveBaseVertices);
|
|
CalculatePrimitiveBase();
|
|
}
|
|
// write to INI last used values for primitive
|
|
void CValuesForPrimitive::WriteToIniFile(CTString strPrimitiveType)
|
|
{
|
|
char strIni[ 256];
|
|
|
|
SET_INDEX( vfp_ptPrimitiveType);
|
|
INI_PRIMITIVE_WRITE( "primitive type");
|
|
|
|
SET_INDEX( vfp_avVerticesOnBaseOfPrimitive.Count());
|
|
INI_PRIMITIVE_WRITE( "base vertices");
|
|
|
|
SET_FLOAT( vfp_plPrimitive.pl_PositionVector(1));
|
|
INI_PRIMITIVE_WRITE( "x");
|
|
SET_FLOAT( vfp_plPrimitive.pl_PositionVector(2));
|
|
INI_PRIMITIVE_WRITE( "y");
|
|
SET_FLOAT( vfp_plPrimitive.pl_PositionVector(3));
|
|
INI_PRIMITIVE_WRITE( "z");
|
|
SET_FLOAT( vfp_plPrimitive.pl_OrientationAngle(1));
|
|
INI_PRIMITIVE_WRITE( "heading");
|
|
SET_FLOAT( vfp_plPrimitive.pl_OrientationAngle(2));
|
|
INI_PRIMITIVE_WRITE( "pitch");
|
|
SET_FLOAT( vfp_plPrimitive.pl_OrientationAngle(3));
|
|
INI_PRIMITIVE_WRITE( "banking");
|
|
|
|
SET_INDEX( vfp_ttTriangularisationType);
|
|
INI_PRIMITIVE_WRITE( "triangularisation type");
|
|
|
|
SET_FLAG( vfp_bClosed);
|
|
INI_PRIMITIVE_WRITE( "closed");
|
|
SET_FLAG( vfp_bDummy);
|
|
INI_PRIMITIVE_WRITE( "gouraud shadows");
|
|
SET_FLAG( vfp_bAutoCreateMipBrushes);
|
|
INI_PRIMITIVE_WRITE( "auto create mip brushes");
|
|
SET_COLOR( vfp_colSectorsColor);
|
|
INI_PRIMITIVE_WRITE( "sectors color");
|
|
SET_COLOR( vfp_colPolygonsColor);
|
|
INI_PRIMITIVE_WRITE( "polygons color");
|
|
|
|
SET_FLOAT( vfp_fXMin);
|
|
INI_PRIMITIVE_WRITE( "x min");
|
|
SET_FLOAT( vfp_fXMax);
|
|
INI_PRIMITIVE_WRITE( "x max");
|
|
SET_FLOAT( vfp_fYMin);
|
|
INI_PRIMITIVE_WRITE( "y min");
|
|
SET_FLOAT( vfp_fYMax);
|
|
INI_PRIMITIVE_WRITE( "y max");
|
|
SET_FLOAT( vfp_fZMin);
|
|
INI_PRIMITIVE_WRITE( "z min");
|
|
SET_FLOAT( vfp_fZMax);
|
|
INI_PRIMITIVE_WRITE( "z max");
|
|
SET_FLOAT( vfp_fShearX);
|
|
INI_PRIMITIVE_WRITE( "shear x");
|
|
SET_FLOAT( vfp_fShearZ);
|
|
INI_PRIMITIVE_WRITE( "shear z");
|
|
SET_FLOAT( vfp_fStretchX);
|
|
INI_PRIMITIVE_WRITE( "stretch x");
|
|
SET_FLOAT( vfp_fStretchY);
|
|
INI_PRIMITIVE_WRITE( "stretch y");
|
|
|
|
SET_FLAG( vfp_bLinearStaircases);
|
|
INI_PRIMITIVE_WRITE( "linear staircases");
|
|
SET_FLAG( vfp_bOuter);
|
|
INI_PRIMITIVE_WRITE( "outer");
|
|
|
|
SET_INDEX( vfp_iSlicesIn360);
|
|
INI_PRIMITIVE_WRITE( "slices in 360");
|
|
SET_INDEX( vfp_iNoOfSlices);
|
|
INI_PRIMITIVE_WRITE( "no of slices");
|
|
SET_FLOAT( vfp_fRadius);
|
|
INI_PRIMITIVE_WRITE( "radius");
|
|
|
|
SET_INDEX( vfp_iNoOfSlices);
|
|
INI_PRIMITIVE_WRITE( "Primitive no of slices");
|
|
|
|
SET_INDEX( vfp_iMeridians);
|
|
INI_PRIMITIVE_WRITE( "meridians");
|
|
SET_INDEX( vfp_iParalels);
|
|
INI_PRIMITIVE_WRITE( "paralels");
|
|
SET_INDEX( vfp_iSlicesPerWidth);
|
|
INI_PRIMITIVE_WRITE( "slices per width");
|
|
SET_INDEX( vfp_iSlicesPerHeight);
|
|
INI_PRIMITIVE_WRITE( "slices per height");
|
|
SET_INDEX( vfp_iTopShape);
|
|
INI_PRIMITIVE_WRITE( "top shape");
|
|
SET_INDEX( vfp_iBottomShape);
|
|
INI_PRIMITIVE_WRITE( "bottom shape");
|
|
SET_INDEX( vfp_csgtCSGOperation);
|
|
INI_PRIMITIVE_WRITE( "csg operation");
|
|
SET_FLOAT( vfp_fAmplitude);
|
|
INI_PRIMITIVE_WRITE( "amplitude");
|
|
SET_FLOAT( vfp_fMipStart);
|
|
INI_PRIMITIVE_WRITE( "mip start");
|
|
SET_FLOAT( vfp_fMipStep);
|
|
INI_PRIMITIVE_WRITE( "mip step");
|
|
SET_STRING( vfp_fnDisplacement);
|
|
INI_PRIMITIVE_WRITE( "displacement picture");
|
|
}
|
|
|
|
void CValuesForPrimitive::CalculatePrimitiveBase(void)
|
|
{
|
|
ASSERT(GetFPUPrecision()==FPT_53BIT);
|
|
|
|
// pick up number of vertices for base polygon
|
|
INDEX vtxCt = vfp_avVerticesOnBaseOfPrimitive.Count();
|
|
// calculate width and lenght
|
|
DOUBLE fWidth = (vfp_fXMax-vfp_fXMin)/2.0f;
|
|
DOUBLE fLenght = (vfp_fZMax-vfp_fZMin)/2.0f;
|
|
// some values must be valid, if they are not, coorect them
|
|
if( fWidth < SNAP_FLOAT_12) fWidth = SNAP_FLOAT_12;
|
|
if( fLenght < SNAP_FLOAT_12) fLenght = SNAP_FLOAT_12;
|
|
|
|
// We calculate vertices as this is box-type primitive
|
|
// Step, ammount of angle ct increasement
|
|
ANGLE angle = AngleDeg(360.0)/vtxCt;
|
|
ANGLE angleCt = -angle/2;
|
|
// Radius of circle surrounding polygon if height of polygon's basic triangle is 1 m
|
|
DOUBLE dA = fWidth/Cos(angle/2);
|
|
DOUBLE dB = dA*fLenght/fWidth;
|
|
|
|
// if base is created inside circle
|
|
if( !vfp_bOuter)
|
|
{
|
|
angleCt = 0.0;
|
|
dA = fWidth;
|
|
dB = fLenght;
|
|
}
|
|
// for all of the base vertices
|
|
for(INDEX iVtx=0; iVtx<vtxCt; iVtx++)
|
|
{
|
|
DOUBLE x = Cos( angleCt) * dA + (vfp_fXMin+vfp_fXMax)/2.0f;
|
|
DOUBLE z = Sin( angleCt) * dB + (vfp_fZMin+vfp_fZMax)/2.0f;
|
|
// snap X coordinate (1 cm)
|
|
//Snap(x, SNAP_DOUBLE_CM);
|
|
// snap Y coordinate (1 cm)
|
|
//Snap(z, SNAP_DOUBLE_CM);
|
|
// calculate vertice on base polygon of the primitive
|
|
vfp_avVerticesOnBaseOfPrimitive[ iVtx] = DOUBLE3D( x, 0.0, z);
|
|
angleCt += angle;
|
|
}
|
|
}
|
|
|
|
void CValuesForPrimitive::Write_t(CTStream &strmFile)
|
|
{
|
|
strmFile.WriteID_t( CChunkID(VALUES_FOR_PRIMITIVE_VERSION3));
|
|
|
|
strmFile << (INDEX) vfp_ptPrimitiveType;
|
|
INDEX ctBaseVtx = vfp_avVerticesOnBaseOfPrimitive.Count();
|
|
strmFile << ctBaseVtx;
|
|
for( INDEX iBaseVtx=0; iBaseVtx<ctBaseVtx; iBaseVtx++)
|
|
{
|
|
strmFile << vfp_avVerticesOnBaseOfPrimitive[iBaseVtx];
|
|
}
|
|
strmFile << vfp_plPrimitive;
|
|
strmFile << (INDEX) vfp_ttTriangularisationType;
|
|
strmFile << vfp_bClosed;
|
|
strmFile << vfp_bDummy;
|
|
|
|
INDEX iPrimitiveType = (INDEX) vfp_ptPrimitiveType;
|
|
strmFile << iPrimitiveType;
|
|
|
|
strmFile << vfp_bAutoCreateMipBrushes;
|
|
strmFile << vfp_colSectorsColor;
|
|
strmFile << vfp_colPolygonsColor;
|
|
strmFile << vfp_fXMin;
|
|
strmFile << vfp_fXMax;
|
|
strmFile << vfp_fYMin;
|
|
strmFile << vfp_fYMax;
|
|
strmFile << vfp_fZMin;
|
|
strmFile << vfp_fZMax;
|
|
strmFile << vfp_fShearX;
|
|
strmFile << vfp_fShearZ;
|
|
strmFile << vfp_fStretchX;
|
|
strmFile << vfp_fStretchY;
|
|
strmFile << vfp_bLinearStaircases;
|
|
strmFile << vfp_bOuter;
|
|
strmFile << vfp_iSlicesIn360;
|
|
strmFile << vfp_iNoOfSlices;
|
|
strmFile << vfp_fRadius;
|
|
strmFile << vfp_iMeridians;
|
|
strmFile << vfp_iParalels;
|
|
strmFile << vfp_iSlicesPerWidth;
|
|
strmFile << vfp_iSlicesPerHeight;
|
|
strmFile << vfp_iTopShape;
|
|
strmFile << vfp_iBottomShape;
|
|
|
|
strmFile << vfp_fAmplitude;
|
|
strmFile << vfp_fnDisplacement;
|
|
strmFile << vfp_fMipStart;
|
|
strmFile << vfp_fMipStep;
|
|
}
|
|
|
|
void CValuesForPrimitive::Read_t(CTStream &strmFile)
|
|
{
|
|
|
|
CChunkID cidVersion = strmFile.GetID_t();
|
|
if( !((cidVersion == CChunkID(VALUES_FOR_PRIMITIVE_VERSION2)) ||
|
|
(cidVersion == CChunkID(VALUES_FOR_PRIMITIVE_VERSION3))) )
|
|
{
|
|
throw( "Only versions 2 and 3 of primitive value files is supported!");
|
|
}
|
|
|
|
INDEX iPrimitiveType;
|
|
strmFile >> iPrimitiveType;
|
|
vfp_ptPrimitiveType = (enum PrimitiveType) iPrimitiveType;
|
|
|
|
INDEX ctBaseVtx;
|
|
strmFile >> ctBaseVtx;
|
|
vfp_avVerticesOnBaseOfPrimitive.Clear();
|
|
vfp_avVerticesOnBaseOfPrimitive.New( ctBaseVtx);
|
|
for( INDEX iBaseVtx=0; iBaseVtx<ctBaseVtx; iBaseVtx++)
|
|
{
|
|
strmFile >> vfp_avVerticesOnBaseOfPrimitive[iBaseVtx];
|
|
}
|
|
strmFile >> vfp_plPrimitive;
|
|
INDEX iTriangularisationType;
|
|
strmFile >> iTriangularisationType;
|
|
vfp_ttTriangularisationType = (enum TriangularisationType) iTriangularisationType;
|
|
strmFile >> vfp_bClosed;
|
|
strmFile >> vfp_bDummy;
|
|
|
|
INDEX iCSGOperation;
|
|
strmFile >> iCSGOperation;
|
|
vfp_csgtCSGOperation = (enum CSGType) iCSGOperation;
|
|
|
|
strmFile >> vfp_bAutoCreateMipBrushes;
|
|
strmFile >> vfp_colSectorsColor;
|
|
strmFile >> vfp_colPolygonsColor;
|
|
strmFile >> vfp_fXMin;
|
|
strmFile >> vfp_fXMax;
|
|
strmFile >> vfp_fYMin;
|
|
strmFile >> vfp_fYMax;
|
|
strmFile >> vfp_fZMin;
|
|
strmFile >> vfp_fZMax;
|
|
strmFile >> vfp_fShearX;
|
|
strmFile >> vfp_fShearZ;
|
|
strmFile >> vfp_fStretchX;
|
|
strmFile >> vfp_fStretchY;
|
|
strmFile >> vfp_bLinearStaircases;
|
|
strmFile >> vfp_bOuter;
|
|
strmFile >> vfp_iSlicesIn360;
|
|
strmFile >> vfp_iNoOfSlices;
|
|
strmFile >> vfp_fRadius;
|
|
strmFile >> vfp_iMeridians;
|
|
strmFile >> vfp_iParalels;
|
|
strmFile >> vfp_iSlicesPerWidth;
|
|
strmFile >> vfp_iSlicesPerHeight;
|
|
strmFile >> vfp_iTopShape;
|
|
strmFile >> vfp_iBottomShape;
|
|
|
|
strmFile >> vfp_fAmplitude;
|
|
strmFile >> vfp_fnDisplacement;
|
|
if( cidVersion == CChunkID(VALUES_FOR_PRIMITIVE_VERSION3))
|
|
{
|
|
strmFile >> vfp_fMipStart;
|
|
strmFile >> vfp_fMipStep;
|
|
}
|
|
}
|
|
|
|
void CWorldEditorApp::WriteToIniFileOnEnd(void)
|
|
{
|
|
char strIni[ 256];
|
|
|
|
// write data that can be saved multiple times to ini file
|
|
WriteToIniFile();
|
|
|
|
if( theApp.m_ptdActiveTexture != NULL)
|
|
{
|
|
CTFileName fnTextureForPrimitive( theApp.m_ptdActiveTexture->GetName());
|
|
fnTextureForPrimitive.SetAbsolutePath();
|
|
strcpy( strIni, fnTextureForPrimitive);
|
|
WriteProfileString( L"World editor prefs", L"Default primitive texture", CString(strIni));
|
|
}
|
|
|
|
SET_FLOAT( m_fPaintPower);
|
|
INI_WRITE( "Paint power");
|
|
|
|
SET_FLOAT( m_fSmoothPower);
|
|
INI_WRITE( "Smooth power");
|
|
|
|
SET_INDEX( m_iFilter);
|
|
INI_WRITE( "Current filter");
|
|
|
|
SET_FLOAT( m_fPosterizeStep);
|
|
INI_WRITE( "Posterize step");
|
|
|
|
SET_INDEX( m_iTerrainGenerationMethod);
|
|
INI_WRITE( "Terrain generation method");
|
|
|
|
SET_INDEX( m_iRNDSubdivideAndDisplaceItterations);
|
|
INI_WRITE( "Subdivade and displace itterations");
|
|
|
|
SET_FLOAT( m_fNoiseAltitude);
|
|
INI_WRITE( "Noise altitude");
|
|
|
|
SET_STRING( m_fnDistributionNoiseTexture);
|
|
INI_WRITE( "Distribution noise texture");
|
|
|
|
SET_STRING( m_fnContinousNoiseTexture);
|
|
INI_WRITE( "Continous noise texture");
|
|
|
|
SET_INDEX( m_iFBMOctaves);
|
|
INI_WRITE( "FBM Octaves");
|
|
|
|
SET_FLOAT( m_fFBMHighFrequencyStep);
|
|
INI_WRITE( "FBM High frequency step");
|
|
|
|
SET_FLOAT( m_fFBMStepFactor);
|
|
INI_WRITE( "FBM Step factor");
|
|
|
|
SET_FLOAT( m_fFBMMaxAmplitude);
|
|
INI_WRITE( "FBM Max amplitude");
|
|
|
|
SET_FLOAT( m_fFBMfAmplitudeDecreaser);
|
|
INI_WRITE( "FBM Amplitude decreaser");
|
|
|
|
SET_FLAG( m_bFBMAddNegativeValues);
|
|
INI_WRITE( "FBM Add negative values");
|
|
|
|
SET_FLAG( m_bFBMRandomOffset);
|
|
INI_WRITE( "FBM Random offset");
|
|
|
|
WriteProfileInt(L"World editor", L"Show Tip of the Day", m_bShowTipOfTheDay);
|
|
WriteProfileInt(L"World editor", L"Current Tip of the Day", m_iCurrentTipOfTheDay);
|
|
WriteProfileInt(L"Display modes", L"SED Gfx API", m_iApi);
|
|
}
|
|
|
|
void CWorldEditorApp::WriteToIniFile()
|
|
{
|
|
// write values for preferences
|
|
m_Preferences.WriteToIniFile();
|
|
|
|
// write to INI file last values used for primitive
|
|
m_vfpPreLast.WriteToIniFile("PreLast");
|
|
m_vfpLast.WriteToIniFile("Last");
|
|
m_vfpCurrent.WriteToIniFile("Current");
|
|
// write to INI last values for each type of primitive
|
|
m_vfpConus.WriteToIniFile("Conus");
|
|
m_vfpTorus.WriteToIniFile("Torus");
|
|
m_vfpStaircases.WriteToIniFile("Staircases");
|
|
m_vfpSphere.WriteToIniFile("Sphere");
|
|
m_vfpTerrain.WriteToIniFile("Terrain");
|
|
|
|
// save world and model rendering preferences
|
|
SaveRenderingPreferences();
|
|
|
|
// save child configurations
|
|
SaveChildConfigurations();
|
|
}
|
|
|
|
// World editor ini write function for preferences
|
|
void CAppPrefs::WriteToIniFile()
|
|
{
|
|
char strIni[ 256];
|
|
|
|
SET_FLAG( ap_CopyExistingWindowPrefs);
|
|
INI_WRITE( "Copy existing window preferences");
|
|
SET_FLAG( ap_AutoMaximizeWindow);
|
|
INI_WRITE( "Auto maximize window");
|
|
SET_FLAG( ap_SetDefaultColors);
|
|
INI_WRITE( "Set default colors");
|
|
SET_FLAG( ap_AutomaticInfo);
|
|
INI_WRITE( "Automatic info");
|
|
SET_FLAG( ap_UpdateAllways);
|
|
INI_WRITE( "Update allways");
|
|
SET_FLAG( ap_BinaryGrid);
|
|
INI_WRITE( "Binary grid");
|
|
SET_FLAG( ap_bSaveUndoForDelete);
|
|
INI_WRITE( "Save undo for delete");
|
|
SET_FLAG( ap_bAutoColorize);
|
|
INI_WRITE( "Auto colorize primitives");
|
|
SET_FLAG( ap_bShowAllOnOpen);
|
|
INI_WRITE( "Show all on open");
|
|
SET_FLAG( ap_bHideShadowsOnOpen);
|
|
INI_WRITE( "Hide shadows on open");
|
|
SET_FLAG( ap_bAutoUpdateDisplaceMap);
|
|
INI_WRITE( "Auto update displace map");
|
|
|
|
SET_INDEX( ap_iUndoLevels);
|
|
INI_WRITE( "Undo levels");
|
|
SET_INDEX( ap_iStartupWindowSetup);
|
|
INI_WRITE( "Startup window setup");
|
|
|
|
SET_COLOR( ap_DefaultInkColor);
|
|
INI_WRITE( "Ink color");
|
|
SET_COLOR( ap_DefaultPaperColor);
|
|
INI_WRITE( "Paper color");
|
|
SET_COLOR( ap_DefaultSelectionColor);
|
|
INI_WRITE( "Current selection color");
|
|
SET_COLOR( ap_DefaultGridColor);
|
|
INI_WRITE( "Current grid color");
|
|
|
|
SET_STRING( ap_strSourceSafeProject);
|
|
INI_WRITE( "Source safe project");
|
|
|
|
SET_FLOAT( ap_fDefaultFlyModeSpeed);
|
|
INI_WRITE( "Default fly mode speed");
|
|
|
|
SET_INDEX( ap_iTerrainSelectionVisible);
|
|
INI_WRITE( "Terrain selection visible");
|
|
SET_INDEX( ap_iTerrainSelectionHidden);
|
|
INI_WRITE( "Terrain selection hidden");
|
|
|
|
SET_INDEX( ap_iMemoryForTerrainUndo);
|
|
INI_WRITE( "Memory for terrain undo");
|
|
|
|
SET_FLAG( ap_bAutoUpdateTerrainDistribution);
|
|
INI_WRITE( "Auto generate distribution");
|
|
}
|
|
|
|
|
|
BOOL CWorldEditorApp::LoadRenderingPreferences()
|
|
{
|
|
CTFileName fnRenderingPrefs = CTString("Data\\WEDRenderingPrefs.bin");
|
|
|
|
// if rendering preferences file does not exist
|
|
if (!FileExists(fnRenderingPrefs)) {
|
|
// just reset to defaults without a note
|
|
return FALSE;
|
|
}
|
|
|
|
// load world and model rendering preferences
|
|
CTFileStream strmFile;
|
|
try
|
|
{
|
|
// open binary file to read rendering preferences
|
|
strmFile.Open_t( fnRenderingPrefs);
|
|
// read file ID
|
|
strmFile.ExpectID_t( CChunkID( "RPRF")); // rendering preferences
|
|
// check version number
|
|
if( !(CChunkID( VIEW_PREFERENCES_VER) == strmFile.GetID_t()) )
|
|
{
|
|
throw( "Invalid version of rendering preferences, switching to defaults.");
|
|
}
|
|
// read view rendering preferences
|
|
strmFile.Read_t( &m_vpViewPrefs, sizeof( m_vpViewPrefs));
|
|
for(INDEX i=0; i<ARRAYCOUNT(m_vpViewPrefs); i++) {
|
|
m_vpViewPrefs[i].ClearInvalidConfigPointers();
|
|
}
|
|
// read ID for end of rendering prefs
|
|
strmFile.ExpectID_t( CChunkID( "RPED")); // rendering preferences end
|
|
}
|
|
catch( char *err_str)
|
|
{
|
|
char achrMessage[ 256];
|
|
sprintf( achrMessage, "%s\nWorld editor's rendering preferences will be switched "
|
|
"to defaults.", err_str);
|
|
AfxMessageBox( CString(achrMessage));
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void CWorldEditorApp::SaveRenderingPreferences(void)
|
|
{
|
|
// save world and model rendering preferences
|
|
CTFileStream strmFile;
|
|
try
|
|
{
|
|
// open binary file to save rendering preferences
|
|
CTFileName fnRenderingPrefs = CTString("Data\\WEDRenderingPrefs.bin");
|
|
strmFile.Create_t( fnRenderingPrefs, CTStream::CM_BINARY);
|
|
// write file ID
|
|
strmFile.WriteID_t( CChunkID( "RPRF")); // child configurations
|
|
// write version number
|
|
strmFile.WriteID_t( CChunkID( VIEW_PREFERENCES_VER));
|
|
// write child configurations array
|
|
strmFile.Write_t( &m_vpViewPrefs, sizeof( m_vpViewPrefs));
|
|
// write ID for end of rendering prefs
|
|
strmFile.WriteID_t( CChunkID( "RPED")); // rendering preferences end
|
|
}
|
|
catch( char *err_str)
|
|
{
|
|
AfxMessageBox( CString(err_str));
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Set default values for view preferences
|
|
*/
|
|
void CChildConfiguration::SetDefaultValues(void)
|
|
{
|
|
m_iHorizontalSplitters = 2;
|
|
m_iVerticalSplitters = 2;
|
|
m_fPercentageLeft = 0.480064f;
|
|
m_fPercentageTop = 0.476654f;
|
|
m_bGridOn = TRUE;
|
|
m_vpViewPrefs[ 0] = theApp.m_vpViewPrefs[ 0];
|
|
m_vpViewPrefs[ 1] = theApp.m_vpViewPrefs[ 0];
|
|
m_vpViewPrefs[ 2] = theApp.m_vpViewPrefs[ 0];
|
|
m_vpViewPrefs[ 3] = theApp.m_vpViewPrefs[ 0];
|
|
m_ptProjectionType[ 0] = CSlaveViewer::PT_ISOMETRIC_TOP;
|
|
m_ptProjectionType[ 1] = CSlaveViewer::PT_PERSPECTIVE;
|
|
m_ptProjectionType[ 2] = CSlaveViewer::PT_ISOMETRIC_FRONT;
|
|
m_ptProjectionType[ 3] = CSlaveViewer::PT_ISOMETRIC_RIGHT;
|
|
}
|
|
void CChildConfiguration::ClearInvalidConfigPointers(void)
|
|
{
|
|
m_vpViewPrefs[0].ClearInvalidConfigPointers();
|
|
m_vpViewPrefs[1].ClearInvalidConfigPointers();
|
|
m_vpViewPrefs[2].ClearInvalidConfigPointers();
|
|
m_vpViewPrefs[3].ClearInvalidConfigPointers();
|
|
}
|
|
|
|
BOOL CWorldEditorApp::LoadChildConfigurations(void)
|
|
{
|
|
CTFileName fnChildConfigurations = CTString("Data\\WEDChildConfigurations.bin");
|
|
|
|
// if child configuration file does not exist
|
|
if (!FileExists(fnChildConfigurations)) {
|
|
// just reset to defaults without a note
|
|
return FALSE;
|
|
}
|
|
|
|
// load child configurations
|
|
CTFileStream strmFile;
|
|
try
|
|
{
|
|
// create binary file to receive child configurations
|
|
strmFile.Open_t( fnChildConfigurations);
|
|
// read file ID
|
|
strmFile.ExpectID_t( CChunkID( "CCFG")); // child configurations
|
|
// check version number
|
|
if( !( CChunkID(CHILD_CONFIGURATION_VER) == strmFile.GetID_t()) )
|
|
{
|
|
throw( "Invalid version of child configurations file, switching to defaults.");
|
|
}
|
|
// clear configurations
|
|
m_ccChildConfigurations->SetDefaultValues();
|
|
// read child configurations array
|
|
strmFile.Read_t( &m_ccChildConfigurations, sizeof( m_ccChildConfigurations));
|
|
// read end of file ID
|
|
strmFile.ExpectID_t( CChunkID( "CCED")); // end of child configurations ID
|
|
}
|
|
catch( char *err_str)
|
|
{
|
|
char achrMessage[ 256];
|
|
sprintf( achrMessage, "%s\nSplit window configurations will be switched to defaults.", err_str);
|
|
AfxMessageBox( CString(achrMessage));
|
|
ClearInvalidConfigPointers();
|
|
return FALSE;
|
|
}
|
|
ClearInvalidConfigPointers();
|
|
return TRUE;
|
|
}
|
|
|
|
void CWorldEditorApp::SaveChildConfigurations(void)
|
|
{
|
|
ClearInvalidConfigPointers();
|
|
// save child configurations
|
|
CTFileStream strmFile;
|
|
try
|
|
{
|
|
CTFileName fnChildConfigurations = CTString("Data\\WEDChildConfigurations.bin");
|
|
// create binary file to receive child configurations
|
|
strmFile.Create_t( fnChildConfigurations, CTStream::CM_BINARY);
|
|
// write file ID
|
|
strmFile.WriteID_t( CChunkID( "CCFG")); // child configurations
|
|
// write version number
|
|
strmFile.WriteID_t( CChunkID( CHILD_CONFIGURATION_VER));
|
|
// write child configurations array
|
|
strmFile.Write_t( &m_ccChildConfigurations, sizeof( m_ccChildConfigurations));
|
|
// write end of file ID
|
|
strmFile.WriteID_t( CChunkID( "CCED")); // end of child configurations ID
|
|
}
|
|
catch( char *err_str)
|
|
{
|
|
AfxMessageBox( CString(err_str));
|
|
}
|
|
}
|
|
|
|
// clear possibly invalid pointers in view configurations
|
|
void CWorldEditorApp::ClearInvalidConfigPointers(void)
|
|
{
|
|
for(INDEX i=0; i<ARRAYCOUNT(m_ccChildConfigurations); i++) {
|
|
m_ccChildConfigurations[i].ClearInvalidConfigPointers();
|
|
}
|
|
}
|
|
|
|
int CWorldEditorApp::ExitInstance()
|
|
{
|
|
// cleanup game library
|
|
_pGameGUI->End();
|
|
|
|
// delete clipboard file
|
|
RemoveFile( CTString("Temp\\ClipboardWorld.wld"));
|
|
|
|
WriteToIniFileOnEnd();
|
|
WriteDefaultPolygonValues();
|
|
|
|
// release entity marker texture
|
|
if( m_ptdEntityMarkerTexture != NULL)
|
|
{
|
|
_pTextureStock->Release( m_ptdEntityMarkerTexture);
|
|
m_ptdEntityMarkerTexture = NULL;
|
|
}
|
|
// and entity marker model data
|
|
if( m_pEntityMarkerModelData != NULL)
|
|
{
|
|
_pModelStock->Release( m_pEntityMarkerModelData);
|
|
delete m_pEntityMarkerModelObject;
|
|
m_pEntityMarkerModelObject = NULL;
|
|
}
|
|
|
|
// release portal marker texture
|
|
if( m_ptdPortalMarkerTexture != NULL)
|
|
{
|
|
_pTextureStock->Release( m_ptdPortalMarkerTexture);
|
|
m_ptdPortalMarkerTexture = NULL;
|
|
}
|
|
// and portal marker model data
|
|
if( m_pPortalMarkerModelData != NULL)
|
|
{
|
|
_pModelStock->Release( m_pPortalMarkerModelData);
|
|
delete m_pPortalMarkerModelObject;
|
|
m_pPortalMarkerModelObject = NULL;
|
|
}
|
|
|
|
// release empty brush texture
|
|
if( m_ptdEmptyBrushTexture != NULL)
|
|
{
|
|
_pTextureStock->Release( m_ptdEmptyBrushTexture);
|
|
m_ptdEmptyBrushTexture = NULL;
|
|
}
|
|
// and empty brush model data
|
|
if( m_pEmptyBrushModelData != NULL)
|
|
{
|
|
_pModelStock->Release( m_pEmptyBrushModelData);
|
|
delete m_pEmptyBrushModelObject;
|
|
m_pEmptyBrushModelObject = NULL;
|
|
}
|
|
|
|
// release range sphere texture
|
|
if( m_ptdRangeSphereTexture != NULL)
|
|
{
|
|
_pTextureStock->Release( m_ptdRangeSphereTexture);
|
|
m_ptdRangeSphereTexture = NULL;
|
|
}
|
|
// and range sphere model data
|
|
if( m_pRangeSphereModelData != NULL)
|
|
{
|
|
_pModelStock->Release( m_pRangeSphereModelData);
|
|
delete m_pRangeSphereModelObject;
|
|
m_pRangeSphereModelObject = NULL;
|
|
}
|
|
|
|
// release angle3d texture
|
|
if( m_ptdAngle3DTexture != NULL)
|
|
{
|
|
_pTextureStock->Release( m_ptdAngle3DTexture);
|
|
m_ptdAngle3DTexture = NULL;
|
|
}
|
|
// and angle3d model data
|
|
if( m_pAngle3DModelData != NULL)
|
|
{
|
|
_pModelStock->Release( m_pAngle3DModelData);
|
|
delete m_pAngle3DModelObject;
|
|
m_pAngle3DModelObject = NULL;
|
|
}
|
|
|
|
// release bounding box texture
|
|
if( m_ptdBoundingBoxTexture != NULL)
|
|
{
|
|
_pTextureStock->Release( m_ptdBoundingBoxTexture);
|
|
m_ptdBoundingBoxTexture = NULL;
|
|
}
|
|
// and range bounding box model data
|
|
if( m_pBoundingBoxModelData != NULL)
|
|
{
|
|
_pModelStock->Release( m_pBoundingBoxModelData);
|
|
delete m_pBoundingBoxModelObject;
|
|
m_pBoundingBoxModelObject = NULL;
|
|
}
|
|
|
|
// release error texture object
|
|
if( m_ptoError != NULL)
|
|
{
|
|
delete m_ptoError;
|
|
}
|
|
// release error texture
|
|
if( m_ptdError != NULL)
|
|
{
|
|
_pTextureStock->Release( m_ptdError);
|
|
}
|
|
// release icons tray texture
|
|
if( m_ptdIconsTray != NULL)
|
|
{
|
|
_pTextureStock->Release( m_ptdIconsTray);
|
|
}
|
|
|
|
// release orientation icons
|
|
if( m_pViewIconsTD != NULL)
|
|
{
|
|
_pTextureStock->Release( m_pViewIconsTD);
|
|
}
|
|
|
|
// release default primitive texture
|
|
if( m_ptdActiveTexture != NULL)
|
|
{
|
|
_pTextureStock->Release( m_ptdActiveTexture);
|
|
}
|
|
|
|
/*
|
|
FORDELETELIST( CDisplayMode, dm_Node, m_AvailableModes, litDM)
|
|
{
|
|
delete &litDM.Current();
|
|
} */
|
|
|
|
FORDELETELIST( CPrimitiveInHistoryBuffer, pihb_lnNode, theApp.m_lhPrimitiveHistory, itPrim)
|
|
{
|
|
delete &itPrim.Current();
|
|
}
|
|
|
|
delete m_pbpoClipboardPolygon;
|
|
|
|
// end entire engine
|
|
SE_EndEngine();
|
|
|
|
int iResult = CWinApp::ExitInstance();
|
|
return iResult;
|
|
}
|
|
|
|
|
|
void CWorldEditorApp::OnFilePreferences()
|
|
{
|
|
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
|
|
CDlgPreferences dlg;
|
|
|
|
dlg.m_dmFullScreen = m_dmFullScreen;
|
|
dlg.m_gatFullScreen = m_gatFullScreen;
|
|
if( dlg.DoModal() == IDOK)
|
|
{ // remember new full screen mode
|
|
m_dmFullScreen = dlg.m_dmFullScreen;
|
|
m_gatFullScreen = dlg.m_gatFullScreen;
|
|
}
|
|
}
|
|
|
|
BOOL CWorldEditorApp::OnIdle(LONG lCount)
|
|
{
|
|
// if game is on
|
|
if( _pInput->IsInputEnabled())
|
|
{
|
|
ASSERT(FALSE); //!!!!!
|
|
return FALSE;
|
|
}
|
|
// if game is on, everithing else is off (don't execute this)
|
|
else if( !(lCount&0xF))
|
|
{
|
|
POSITION pos = m_pDocTemplate->GetFirstDocPosition();
|
|
while (pos!=NULL) {
|
|
CWorldEditorDoc *pdocCurrent = (CWorldEditorDoc *)m_pDocTemplate->GetNextDoc(pos);
|
|
pdocCurrent->OnIdle();
|
|
}
|
|
|
|
// remember the world pointer of current document
|
|
CWorldEditorView *pvCurrent = GetActiveView();
|
|
if (pvCurrent!=NULL) {
|
|
CWorldEditorDoc *pdocCurrent = pvCurrent->GetDocument();
|
|
if (pdocCurrent!=NULL) {
|
|
_pShell->SetINDEX("pwoCurrentWorld", (INDEX)&pdocCurrent->m_woWorld);
|
|
}
|
|
}
|
|
|
|
((CMainFrame *)m_pMainWnd)->OnIdle( lCount);
|
|
}
|
|
BOOL bLMB = (GetKeyState( VK_LBUTTON)&0x8000) != 0;
|
|
BOOL bRMB = (GetKeyState( VK_RBUTTON)&0x8000) != 0;
|
|
|
|
BOOL bResult=CWinApp::OnIdle(lCount);
|
|
return bResult||bLMB||bRMB;
|
|
}
|
|
|
|
// force all documents to repaint thir views
|
|
void CWorldEditorApp::RefreshAllDocuments( void)
|
|
{
|
|
POSITION pos = m_pDocTemplate->GetFirstDocPosition();
|
|
|
|
while (pos!=NULL)
|
|
{
|
|
CWorldEditorDoc *pdocCurrent = (CWorldEditorDoc *)m_pDocTemplate->GetNextDoc(pos);
|
|
pdocCurrent->UpdateAllViews( NULL);
|
|
}
|
|
}
|
|
|
|
// sets new active texture for primitive's default material
|
|
void CWorldEditorApp::SetNewActiveTexture( CTFileName fnFullTexName)
|
|
{
|
|
CMainFrame *pMainFrame = (CMainFrame *)m_pMainWnd;
|
|
// to hold new texture
|
|
CTextureData *pdtNewTexture = NULL;
|
|
// to hold short texture name
|
|
CTFileName fnTexName = fnFullTexName;
|
|
// try to
|
|
try
|
|
{
|
|
// obtain the new texture
|
|
fnTexName.RemoveApplicationPath_t();
|
|
pdtNewTexture = _pTextureStock->Obtain_t( fnTexName);
|
|
}
|
|
// if failed
|
|
catch( char *err_str)
|
|
{
|
|
pdtNewTexture = _pTextureStock->Obtain_t( CTFILENAME("Textures\\Editor\\Default.tex") );
|
|
(void)err_str;
|
|
// report error
|
|
//AfxMessageBox( CString(err_str));
|
|
//return;
|
|
}
|
|
ASSERT(pdtNewTexture != NULL);
|
|
// if there is old texture
|
|
if (m_ptdActiveTexture!=NULL) {
|
|
// release it
|
|
_pTextureStock->Release(m_ptdActiveTexture);
|
|
}
|
|
// remember the new texture
|
|
m_ptdActiveTexture = pdtNewTexture;
|
|
// if info frame exists, update it
|
|
if( pMainFrame->m_pInfoFrame != NULL)
|
|
{
|
|
CInfoSheet *pSheet = pMainFrame->m_pInfoFrame->m_pInfoSheet;
|
|
// redraw info frame
|
|
pMainFrame->m_pInfoFrame->Invalidate(FALSE);
|
|
// info's page is pg global
|
|
if( (pSheet->GetActivePage() == &pSheet->m_PgGlobal) )
|
|
{
|
|
// update texture description
|
|
pMainFrame->m_pInfoFrame->m_pInfoSheet->m_PgGlobal.UpdateData( FALSE);
|
|
}
|
|
|
|
// get active view
|
|
CWorldEditorView *pWorldEditorView = theApp.GetActiveView();
|
|
// get active document
|
|
CWorldEditorDoc* pDoc = theApp.GetActiveDocument();
|
|
// if view and second layer exist (CSG is on), and primitive mode is on
|
|
if( (pWorldEditorView != NULL) &&
|
|
(pDoc->m_pwoSecondLayer != NULL) &&
|
|
(pDoc->m_bPrimitiveMode) )
|
|
{
|
|
// apply texture change for CSG primitive
|
|
pSheet->m_PgPrimitive.ApplySCGChange();
|
|
}
|
|
}
|
|
}
|
|
|
|
// opens directory wich contains given item
|
|
void CWorldEditorApp::FindItemInBrowser( CTFileName fnItemFileName)
|
|
{
|
|
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
|
|
pMainFrame->m_Browser.SelectItemDirectory( fnItemFileName);
|
|
}
|
|
|
|
void CWorldEditorApp::TexturizeSelection(void)
|
|
{
|
|
// get active document
|
|
CWorldEditorDoc* pDoc = theApp.GetActiveDocument();
|
|
|
|
// if it exists
|
|
if( pDoc != NULL)
|
|
{
|
|
// try to apply new texture to current selection
|
|
try
|
|
{
|
|
// if polygon mode
|
|
if( (pDoc->m_iMode == POLYGON_MODE) && (m_ptdActiveTexture != NULL) )
|
|
{
|
|
// get name from serial object
|
|
CTFileName fnTextureName = m_ptdActiveTexture->GetName();
|
|
pDoc->PasteTextureOverSelection_t( fnTextureName);
|
|
}
|
|
}
|
|
// if failed
|
|
catch( char *err_str)
|
|
{
|
|
// report error
|
|
AfxMessageBox( CString(err_str));
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CWorldEditorApp::OnFileOpen()
|
|
{
|
|
// call file requester for opening documents
|
|
CDynamicArray<CTFileName> afnOpenedWorlds;
|
|
_EngineGUI.FileRequester( "Choose worlds to open", FILTER_WLD FILTER_ALL FILTER_END,
|
|
"Open world directory", "Worlds\\", "", &afnOpenedWorlds);
|
|
FOREACHINDYNAMICARRAY( afnOpenedWorlds, CTFileName, itWorld)
|
|
{
|
|
// try to load document
|
|
m_pDocTemplate->OpenDocumentFile( CString(_fnmApplicationPath+itWorld.Current()));
|
|
}
|
|
}
|
|
|
|
void CWorldEditorApp::OnConvertWorlds()
|
|
{
|
|
_pShell->Execute( CTString("con_bNoWarnings=1;"));
|
|
|
|
// call file requester for list containing worlds to convert
|
|
CTFileName fnFileList = _EngineGUI.FileRequester( "Choose list file for conversion",
|
|
FILTER_LST FILTER_TXT FILTER_ALL FILTER_END, "List files directory", "");
|
|
if( fnFileList == "") return;
|
|
|
|
INDEX ctLines = 0;
|
|
char achrLine[256];
|
|
CTFileStream fsFileList;
|
|
|
|
// count lines in list file
|
|
try {
|
|
fsFileList.Open_t( fnFileList);
|
|
while( !fsFileList.AtEOF()) {
|
|
fsFileList.GetLine_t( achrLine, 256);
|
|
// increase counter only for lines that are not blank
|
|
if( achrLine != "") ctLines++;
|
|
}
|
|
fsFileList.Close();
|
|
}
|
|
// if the list file can't be opened
|
|
catch(char *strError) {
|
|
_pShell->Execute( CTString("con_bNoWarnings=0;"));
|
|
WarningMessage( "Error reading list file: %s", strError);
|
|
return;
|
|
}
|
|
|
|
// process list file
|
|
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
|
|
CDlgProgress dlgProgressDialog( pMainFrame, TRUE);
|
|
dlgProgressDialog.Create( IDD_PROGRESS_DIALOG); // create progress dialog
|
|
dlgProgressDialog.SetWindowText( L"Convert files");
|
|
dlgProgressDialog.ShowWindow( SW_SHOW); // show progress window
|
|
dlgProgressDialog.CenterWindow(); // center window
|
|
dlgProgressDialog.m_ctrlProgres.SetRange( 0, (short)ctLines); // set progress range
|
|
|
|
// prepare error file
|
|
CTFileStream fsErrorFile;
|
|
CTFileName fnErrorFile = fnFileList.NoExt() + ".err";
|
|
// reopen list file
|
|
fsFileList.Open_t( fnFileList);
|
|
|
|
INDEX iCurrent = 0;
|
|
BOOL bConvertError = FALSE;
|
|
CTString strReport;
|
|
CTFileName fnmFile, fnmExt, fnmFileFull;
|
|
// loop thru lines
|
|
while( !fsFileList.AtEOF())
|
|
{
|
|
try {
|
|
if( dlgProgressDialog.m_bCancelPressed) break;
|
|
|
|
// read one line from list file
|
|
fsFileList.GetLine_t( achrLine, 256);
|
|
// ignore blank lines
|
|
if( achrLine == "") continue;
|
|
|
|
// set message and progress position
|
|
char achrProgressMessage[256];
|
|
sprintf( achrProgressMessage, "Converting files ... (%d / %d)", iCurrent+1, ctLines);
|
|
dlgProgressDialog.SetProgressMessageAndPosition( achrProgressMessage, iCurrent+1);
|
|
|
|
// convert needed type of object
|
|
fnmFile = CTString( achrLine);
|
|
fnmFileFull = _fnmApplicationPath+fnmFile;
|
|
fnmExt = fnmFile.FileExt();
|
|
struct _stat FileStat;
|
|
struct _utimbuf FileTime;
|
|
|
|
// convert world?
|
|
if( fnmExt == ".wld")
|
|
{
|
|
// load the world
|
|
CWorld woWorld;
|
|
woWorld.Load_t(fnmFile);
|
|
// reinitialize all entities
|
|
woWorld.ReinitializeEntities();
|
|
// flush stale caches
|
|
_pShell->Execute("FreeUnusedStock();");
|
|
// show all sectors and entities
|
|
woWorld.ShowAllSectors();
|
|
woWorld.ShowAllEntities();
|
|
// recalculate shadows on all brush polygons in the world
|
|
woWorld.DiscardAllShadows();
|
|
woWorld.CalculateDirectionalShadows();
|
|
woWorld.CalculateNonDirectionalShadows();
|
|
// get original file date
|
|
if( _stat( fnmFileFull, &FileStat)) throw "Error getting file date.";
|
|
// save world in new format
|
|
woWorld.Save_t(fnmFile);
|
|
_pShell->Execute( CTString( "bReinitializeShadowLayers=0;"));
|
|
woWorld.Clear();
|
|
// revert to original file date
|
|
FileTime.actime = FileStat.st_atime;
|
|
FileTime.modtime = FileStat.st_mtime;
|
|
if( _utime( fnmFileFull, &FileTime)) throw "Error setting file date.";
|
|
}
|
|
// convert texture?
|
|
else if( fnmExt == ".tex" || fnmExt == ".tbn")
|
|
{
|
|
// convert textures (but keep the file date)
|
|
CTextureData tdTex;
|
|
tdTex.Load_t( fnmFile);
|
|
// if old texture has been loaded
|
|
if( tdTex.td_ulFlags & TEX_WASOLD) {
|
|
// cannost convert mangled textures
|
|
if( tdTex.td_ptegEffect==NULL && tdTex.IsModified()) throw( TRANS("Cannot write texture that has modified frames."));
|
|
// get original file date
|
|
if( _stat( fnmFileFull, &FileStat)) throw "Error getting file date.";
|
|
// save texture in new format
|
|
tdTex.Save_t( fnmFile);
|
|
// revert to original file date
|
|
FileTime.actime = FileStat.st_atime;
|
|
FileTime.modtime = FileStat.st_mtime;
|
|
if( _utime( fnmFileFull, &FileTime)) throw "Error setting file date.";
|
|
}
|
|
}
|
|
// convert WHAT?
|
|
else if( fnmFile=="")
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
ThrowF_t( "Unsupported file format: %s", (CTString&)fnmExt);
|
|
}
|
|
}
|
|
|
|
// if file can't be opened
|
|
catch( char *strError) {
|
|
try {
|
|
// on first error
|
|
if( !bConvertError) {
|
|
// (re)create error file
|
|
fsErrorFile.Create_t( fnErrorFile);
|
|
bConvertError = TRUE;
|
|
}
|
|
// report error to file
|
|
strReport.PrintF( "File: %s\nHad error: %s\n", (CTString)fnmFile, strError);
|
|
|
|
fsErrorFile.PutString_t( strReport);
|
|
fsErrorFile.PutLine_t( "-----------------------------------------------");
|
|
}
|
|
// here should be no errors,
|
|
catch( char *strError) {
|
|
// otherwise ...
|
|
(void) strError;
|
|
WarningMessage( "Fatal error occured while working with error file!");
|
|
break;
|
|
}
|
|
}
|
|
|
|
// advance to next line
|
|
iCurrent++;
|
|
}
|
|
|
|
fsFileList.Close();
|
|
dlgProgressDialog.DestroyWindow(); // destroy progress dialog
|
|
_pShell->Execute( CTString("con_bNoWarnings=0;"));
|
|
|
|
// report error situation (if any)
|
|
if( bConvertError) {
|
|
fsErrorFile.PutLine_t( "DONE.");
|
|
fsErrorFile.Close();
|
|
WarningMessage( "There were some errors in conversion. They are listed in file:\n %s", fnErrorFile);
|
|
}
|
|
}
|
|
|
|
CEntity *CWorldEditorApp::CreateWorldBaseEntity(CWorld &woWorld, BOOL bZoning,
|
|
CPlacement3D plWorld/*=CPlacement3D(FLOAT3D(0,0,0),ANGLE3D(0,0,0))*/)
|
|
{
|
|
CEntity *penwb;
|
|
// try to
|
|
try
|
|
{
|
|
// create world base entity
|
|
penwb = woWorld.CreateEntity_t(plWorld, CTFILENAME("Classes\\WorldBase.ecl"));
|
|
}
|
|
// catch and
|
|
catch( char *err_str)
|
|
{
|
|
// report errors
|
|
AfxMessageBox( CString(err_str));
|
|
return NULL;
|
|
}
|
|
// prepare the entity
|
|
penwb->Initialize();
|
|
|
|
if( bZoning)
|
|
{
|
|
EFirstWorldBase eFirstWorldBase;
|
|
penwb->SendEvent( eFirstWorldBase);
|
|
CEntity::HandleSentEvents();
|
|
}
|
|
return penwb;
|
|
}
|
|
|
|
BOOL CWorldEditorApp::Add3DObject(CWorldEditorDoc *pDoc, CEntity *penwb, CTFileName fnFile, BOOL bAdd)
|
|
{
|
|
CObject3D o3d;
|
|
// temporary world
|
|
CWorld woWorld;
|
|
CEntity *penwb2=CreateWorldBaseEntity(woWorld, FALSE);
|
|
if( penwb2==NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// try to
|
|
try
|
|
{
|
|
// load 3D object
|
|
FLOATmatrix3D mStretch;
|
|
mStretch.Diagonal(1.0f);
|
|
if (fnFile.FileExt()==".obj") { // Maya Obj has different orientation
|
|
mStretch.Diagonal(FLOAT3D(-1.0f, 1.0f, -1.0f));
|
|
}
|
|
o3d.LoadAny3DFormat_t( fnFile, mStretch);
|
|
|
|
FOREACHINDYNAMICARRAY(o3d.ob_aoscSectors, CObjectSector, itosc)
|
|
{
|
|
// for each material in object3D
|
|
FOREACHINDYNAMICARRAY(itosc->osc_aomtMaterials, CObjectMaterial, itom)
|
|
{
|
|
if( !FileExists(itom->omt_Name))
|
|
{
|
|
itom->omt_Name = "Textures\\Editor\\Default.tex";
|
|
}
|
|
}
|
|
}
|
|
// create world base's brush from object 3D
|
|
CBrush3D *pbr = penwb2->GetBrush();
|
|
pbr->FromObject3D_t( o3d);
|
|
pbr->CalculateBoundingBoxes();
|
|
|
|
CPlacement3D plDummy;
|
|
plDummy.pl_PositionVector = FLOAT3D(0.0f,0.0f,0.0f);
|
|
plDummy.pl_OrientationAngle = ANGLE3D(0,0,0);
|
|
// if should apply CSG add
|
|
if(bAdd)
|
|
{
|
|
penwb->en_pwoWorld->CSGAdd(*penwb, woWorld, *penwb2, plDummy);
|
|
}
|
|
// if should perform join layers
|
|
else
|
|
{
|
|
// copy entities
|
|
penwb->en_pwoWorld->CopyEntities( woWorld, woWorld.wo_cenEntities, pDoc->m_selEntitySelection, plDummy);
|
|
}
|
|
}
|
|
// catch and
|
|
catch( char *err_str)
|
|
{
|
|
// report errors
|
|
AfxMessageBox( CString(err_str));
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
* Import 3d object(s), create new document
|
|
*/
|
|
void CWorldEditorApp::OnImport3DObject()
|
|
{
|
|
// try to load document
|
|
CWorldEditorDoc *pDoc = (CWorldEditorDoc *) m_pDocTemplate->CreateNewDocument();
|
|
|
|
// create the World entity
|
|
CEntity *pwb=CreateWorldBaseEntity(pDoc->m_woWorld, TRUE);
|
|
if( pwb==NULL)
|
|
{
|
|
delete pDoc;
|
|
return;
|
|
}
|
|
|
|
// create 3d objects
|
|
INDEX ctImported=Insert3DObjects(pDoc);
|
|
if( ctImported==0)
|
|
{
|
|
delete pDoc;
|
|
return;
|
|
}
|
|
|
|
// finish creating document
|
|
if (pDoc == NULL)
|
|
{
|
|
TRACE0("CDocTemplate::CreateNewDocument returned NULL.\n");
|
|
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
|
|
return;
|
|
}
|
|
ASSERT_VALID(pDoc);
|
|
|
|
BOOL bAutoDelete = pDoc->m_bAutoDelete;
|
|
pDoc->m_bAutoDelete = FALSE; // don't destroy if something goes wrong
|
|
CFrameWnd* pFrame = m_pDocTemplate->CreateNewFrame(pDoc, NULL);
|
|
pDoc->m_bAutoDelete = bAutoDelete;
|
|
if (pFrame == NULL)
|
|
{
|
|
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
|
|
delete pDoc; // explicit delete on error
|
|
return;
|
|
}
|
|
ASSERT_VALID(pFrame);
|
|
|
|
pDoc->SetModifiedFlag();
|
|
// set document name and don't add it into MRU
|
|
//pDoc->SetPathName( _fnmApplicationPath+"Worlds\\"+"Untitled.wld", FALSE);
|
|
//pDoc->SetTitle( fn3D.FileName() + ".wld");
|
|
m_pDocTemplate->InitialUpdateFrame(pFrame, pDoc, TRUE);
|
|
pDoc->SetModifiedFlag( TRUE);
|
|
}
|
|
|
|
INDEX CWorldEditorApp::Insert3DObjects(CWorldEditorDoc *pDoc)
|
|
{
|
|
INDEX ctInserted=0;
|
|
CDynamicArray<CTFileName> afnFiles;
|
|
CTFileName fn3D = _EngineGUI.FileRequester( "Import 3D object series",
|
|
FILTER_3DOBJ FILTER_LWO FILTER_OBJ FILTER_3DS FILTER_ALL FILTER_END,
|
|
"Import 3D object directory", "", "", &afnFiles);
|
|
|
|
if( afnFiles.Count() == 0) return 0;
|
|
|
|
// get first file (when strings are sorted)
|
|
CTString strMin="a";
|
|
((char *)(const char *) strMin)[0]=char(255);
|
|
CTFileName *pfn=NULL;
|
|
{FOREACHINDYNAMICARRAY(afnFiles, CTFileName, itfn)
|
|
{
|
|
CTString str=itfn->FileName();
|
|
if( strcmp(str, strMin)<0)
|
|
{
|
|
strMin=str;
|
|
pfn=&*itfn;
|
|
}
|
|
}}
|
|
ASSERT(pfn!=NULL);
|
|
if(pfn==NULL) return ctInserted;
|
|
|
|
// create main World entity
|
|
CEntity *pwb=CreateWorldBaseEntity(pDoc->m_woWorld, TRUE);
|
|
if( pwb==NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
// add first 3D file as zoning base
|
|
if( !Add3DObject(pDoc, pwb, *pfn, TRUE))
|
|
{
|
|
return 0;
|
|
}
|
|
ctInserted++;
|
|
|
|
// remove added file from dynamic container
|
|
afnFiles.Delete(pfn);
|
|
// add other files
|
|
{FOREACHINDYNAMICARRAY(afnFiles, CTFileName, itfn)
|
|
{
|
|
CTString &str=*itfn;
|
|
CTString strName=itfn->FileName();
|
|
if( ((char *)(const char *)strName)[strlen(strName)-1] == 'E')
|
|
{
|
|
// join layers
|
|
Add3DObject(pDoc, pwb, *itfn, FALSE);
|
|
}
|
|
else
|
|
{
|
|
// CSG add
|
|
Add3DObject(pDoc, pwb, *itfn, TRUE);
|
|
}
|
|
ctInserted++;
|
|
}}
|
|
return ctInserted;
|
|
}
|
|
|
|
CWorldEditorDoc* CWorldEditorApp::GetLastActivatedDocument(void)
|
|
{
|
|
return m_pLastActivatedDocument;
|
|
}
|
|
|
|
void CWorldEditorApp::ActivateDocument(CWorldEditorDoc *pDocToActivate)
|
|
{
|
|
// remember document to be activated as last activated
|
|
m_pLastActivatedDocument = pDocToActivate;
|
|
}
|
|
|
|
CWorldEditorDoc *CWorldEditorApp::GetDocument()
|
|
{
|
|
// obtain current view ptr
|
|
CWorldEditorView *pWorldEditorView = GetActiveView();
|
|
// if view does not exist, return
|
|
if( pWorldEditorView == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
// obtain document ptr
|
|
CWorldEditorDoc *pDoc = pWorldEditorView->GetDocument();
|
|
// return it
|
|
return pDoc;
|
|
}
|
|
|
|
void CWorldEditorApp::OnFileNew()
|
|
{
|
|
CWinApp::OnFileNew();
|
|
// obtain new document ptr
|
|
CWorldEditorDoc *pDoc = GetDocument();
|
|
|
|
CTFileName fnDefaultBcg = CTString(CStringA(theApp.GetProfileString(
|
|
L"World editor prefs", L"Default background picture",
|
|
CString("Textures\\Editor\\Default.tex"))));
|
|
|
|
try
|
|
{
|
|
//!!!! pDoc->m_woWorld.SetBackgroundTexture_t( fnDefaultBcg);
|
|
}
|
|
catch( char *strError)
|
|
{
|
|
(void) strError;
|
|
}
|
|
|
|
try
|
|
{
|
|
//!!!! pDoc->m_woWorld.SetBackgroundTexture_t( CTString("Textures\\Editor\\Default.tex"));
|
|
}
|
|
catch( char *strError)
|
|
{
|
|
AfxMessageBox( CString(strError));
|
|
}
|
|
|
|
char chrColor[ 16];
|
|
COLOR colBackground;
|
|
// obtain background color form INI file
|
|
strcpy( chrColor, CStringA(theApp.GetProfileString( L"World editor prefs",
|
|
L"Default background color", L"0XFF000000")));
|
|
sscanf( chrColor, "0X%08x", &colBackground);
|
|
// set background color to color button
|
|
pDoc->m_woWorld.SetBackgroundColor( colBackground);
|
|
pDoc->m_woWorld.SetDescription( "No mission description");
|
|
pDoc->SetModifiedFlag( TRUE);
|
|
|
|
CString strOpenPath;
|
|
strOpenPath = CStringA(theApp.GetProfileString(L"World editor", L"Open directory", L""));
|
|
// set default document's name and don't set it into MRU
|
|
pDoc->SetPathName( strOpenPath + "Untitled.wld", FALSE);
|
|
pDoc->SetTitle( L"Untitled.wld");
|
|
}
|
|
|
|
int CWorldEditorApp::Run()
|
|
{
|
|
int iResult;
|
|
CTSTREAM_BEGIN {
|
|
iResult=CWinApp::Run();
|
|
} CTSTREAM_END;
|
|
return iResult;
|
|
}
|
|
|
|
BOOL CWorldEditorApp::PreTranslateMessage(MSG* pMsg)
|
|
{
|
|
return CWinApp::PreTranslateMessage(pMsg);
|
|
}
|
|
|
|
CTString CWorldEditorApp::GetNameForVirtualTreeNode( CVirtualTreeNode *pvtnNode)
|
|
{
|
|
ASSERT( pvtnNode != NULL);
|
|
// start from selected directory
|
|
CVirtualTreeNode *pvtnCurrentDir = pvtnNode;
|
|
// reset curently opened virtual directory name
|
|
CTString strResult = "";
|
|
// compile full path name
|
|
while( pvtnCurrentDir->vnt_pvtnParent != NULL)
|
|
{
|
|
strResult = pvtnCurrentDir->vtn_strName+"\\"+ strResult;
|
|
pvtnCurrentDir = pvtnCurrentDir->vnt_pvtnParent;
|
|
}
|
|
// if given is root directory
|
|
if( strResult == "")
|
|
{
|
|
strResult = "<ROOT>";
|
|
}
|
|
return strResult;
|
|
}
|
|
|
|
void CWorldEditorApp::OnDecadicGrid()
|
|
{
|
|
m_bDecadicGrid = !m_bDecadicGrid;
|
|
// refresh all documents
|
|
RefreshAllDocuments();
|
|
}
|
|
|
|
void CWorldEditorApp::OnUpdateDecadicGrid(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck( m_bDecadicGrid);
|
|
}
|
|
|
|
void CCustomToolTip::ManualOn( PIX pixManualX, PIX pixManualY, TTCFunction_type *pCallBack, void *pThis)
|
|
{
|
|
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
|
|
cct_pCallback = pCallBack;
|
|
cct_pThis = pThis;
|
|
|
|
if( pMainFrame->m_pwndToolTip != NULL)
|
|
{
|
|
ManualOff();
|
|
}
|
|
|
|
pMainFrame->ManualToolTipOn( pixManualX, pixManualY);
|
|
}
|
|
|
|
void CCustomToolTip::ManualOff( void)
|
|
{
|
|
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
|
|
pMainFrame->m_pwndToolTip->ManualOff();
|
|
pMainFrame->m_pwndToolTip = NULL;
|
|
}
|
|
|
|
void CCustomToolTip::ManualUpdate(void)
|
|
{
|
|
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
|
|
pMainFrame->ManualToolTipUpdate();
|
|
}
|
|
|
|
void CCustomToolTip::MouseMoveNotify( HWND hwndCaller, ULONG ulTime, TTCFunction_type *pCallBack, void *pThis)
|
|
{
|
|
cct_hwndCaller = hwndCaller;
|
|
cct_pCallback = pCallBack;
|
|
cct_pThis = pThis;
|
|
|
|
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
|
|
pMainFrame->KillTimer( 0);
|
|
pMainFrame->SetTimer( 0, ulTime, NULL);
|
|
}
|
|
|
|
void CWorldEditorApp::OnSetAsDefault()
|
|
{
|
|
CWorldEditorDoc *pDoc = GetDocument();
|
|
ASSERT( pDoc->m_selPolygonSelection.Count() == 1);
|
|
|
|
pDoc->m_selPolygonSelection.Lock();
|
|
m_pbpoPolygonWithDeafultValues->CopyPropertiesWithoutTexture( pDoc->m_selPolygonSelection[0]);
|
|
pDoc->m_selPolygonSelection.Unlock();
|
|
}
|
|
|
|
void CWorldEditorApp::ReadDefaultPolygonValues()
|
|
{
|
|
char strIni[ 256];
|
|
INI_READ( "Default polygon flags", "0");
|
|
GET_INDEX( m_pbpoPolygonWithDeafultValues->bpo_ulFlags);
|
|
INI_READ( "Default polygon shadow color", "0XFFFFFFFF");
|
|
GET_COLOR( m_pbpoPolygonWithDeafultValues->bpo_colShadow);
|
|
INI_READ( "Default polygon surface", "0");
|
|
GET_INDEX( m_pbpoPolygonWithDeafultValues->bpo_bppProperties.bpp_ubSurfaceType);
|
|
INI_READ( "Default polygon illumination", "0");
|
|
GET_INDEX( m_pbpoPolygonWithDeafultValues->bpo_bppProperties.bpp_ubIlluminationType);
|
|
INI_READ( "Default polygon blend", "1");
|
|
GET_INDEX( m_pbpoPolygonWithDeafultValues->bpo_bppProperties.bpp_ubShadowBlend);
|
|
INI_READ( "Default polygon mirror", "0");
|
|
GET_INDEX( m_pbpoPolygonWithDeafultValues->bpo_bppProperties.bpp_ubMirrorType);
|
|
INI_READ( "Default polygon cluster size", "2");
|
|
GET_INDEX( m_pbpoPolygonWithDeafultValues->bpo_bppProperties.bpp_sbShadowClusterSize);
|
|
}
|
|
|
|
void CWorldEditorApp::WriteDefaultPolygonValues()
|
|
{
|
|
char strIni[ 256];
|
|
SET_INDEX( m_pbpoPolygonWithDeafultValues->bpo_ulFlags);
|
|
INI_WRITE( "Default polygon flags");
|
|
SET_COLOR( m_pbpoPolygonWithDeafultValues->bpo_colShadow);
|
|
INI_WRITE( "Default polygon shadow color");
|
|
SET_INDEX( m_pbpoPolygonWithDeafultValues->bpo_bppProperties.bpp_ubSurfaceType);
|
|
INI_WRITE( "Default polygon surface");
|
|
SET_INDEX( m_pbpoPolygonWithDeafultValues->bpo_bppProperties.bpp_ubIlluminationType);
|
|
INI_WRITE( "Default polygon illumination");
|
|
SET_INDEX( m_pbpoPolygonWithDeafultValues->bpo_bppProperties.bpp_ubShadowBlend);
|
|
INI_WRITE( "Default polygon blend");
|
|
SET_INDEX( m_pbpoPolygonWithDeafultValues->bpo_bppProperties.bpp_ubMirrorType);
|
|
INI_WRITE( "Default polygon mirror");
|
|
SET_INDEX( m_pbpoPolygonWithDeafultValues->bpo_bppProperties.bpp_sbShadowClusterSize);
|
|
INI_WRITE( "Default polygon cluster size");
|
|
}
|
|
|
|
void CWorldEditorApp::OnHelpShowTipOfTheDay()
|
|
{
|
|
CDlgTipOfTheDay dlgTips;
|
|
dlgTips.DoModal();
|
|
m_bShowTipOfTheDay = dlgTips.m_bShowTipsAtStartup;
|
|
}
|
|
|
|
void FindEmptyBrushes( void)
|
|
{
|
|
// remember the world pointer of current document
|
|
CWorldEditorView *pvCurrent = theApp.GetActiveView();
|
|
if (pvCurrent!=NULL)
|
|
{
|
|
CWorldEditorDoc *pDoc = pvCurrent->GetDocument();
|
|
if (pDoc!=NULL)
|
|
{
|
|
// for each entity in the world
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten) {
|
|
FLOAT3D vPos = iten->GetPlacement().pl_PositionVector;
|
|
// if it is brush entity
|
|
if (iten->en_RenderType == CEntity::RT_BRUSH) {
|
|
INDEX iMip = 0;
|
|
// for each mip in its brush
|
|
FOREACHINLIST(CBrushMip, bm_lnInBrush, iten->en_pbrBrush->br_lhBrushMips, itbm)
|
|
{
|
|
if( itbm->bm_abscSectors.Count() == 0)
|
|
{
|
|
CPrintF("Found brush named %s, without sectors in mip %d at coordinates: (%g, %g, %g)\n",
|
|
iten->GetName(), iMip, vPos(1), vPos(2), vPos(3));
|
|
}
|
|
iMip++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CWorldEditorApp::WinHelp(DWORD dwData, UINT nCmd)
|
|
{
|
|
// TODO: Add your specialized code here and/or call the base class
|
|
|
|
if (nCmd == HELP_CONTEXT) {
|
|
DisplayHelp(CTFILENAME("Help\\SeriousEditorContext.hlk"), HH_HELP_CONTEXT, dwData);
|
|
} else {
|
|
CWinApp::WinHelp(dwData, nCmd);
|
|
}
|
|
}
|
|
|
|
void CWorldEditorApp::DisplayHelp(const CTFileName &fnHlk, UINT uCommand, DWORD dwData)
|
|
{
|
|
CTString strHelpPath;
|
|
BOOL bHlkFound = TRUE;
|
|
try
|
|
{
|
|
strHelpPath.Load_t(fnHlk.NoExt()+".hlk");
|
|
}
|
|
catch(char *strError)
|
|
{
|
|
(void) strError;
|
|
if (fnHlk.FileExt()==".ecl") {
|
|
WarningMessage("No help available for class: %s", fnHlk.FileName());
|
|
}
|
|
bHlkFound = FALSE;
|
|
}
|
|
|
|
// extract prefix
|
|
CTString strHelpFormatID = strHelpPath;
|
|
strHelpFormatID.OnlyFirstLine();
|
|
strHelpPath.RemovePrefix(strHelpFormatID);
|
|
strHelpPath.DeleteChar(0);
|
|
strHelpPath.OnlyFirstLine();
|
|
|
|
if( bHlkFound)
|
|
{
|
|
if( strHelpFormatID=="HTM" || strHelpFormatID=="HTML" || strHelpFormatID=="TXT")
|
|
{
|
|
// obtain iexplore path
|
|
CTString strKey = "HKEY_CLASSES_ROOT\\.htm\\";
|
|
CTString strString;
|
|
REG_GetString(strKey, strString);
|
|
strKey = "HKEY_CLASSES_ROOT\\"+strString+"\\shell\\open\\command\\";
|
|
REG_GetString(strKey, strString);
|
|
|
|
// now extract file path between two "
|
|
char aExePath[PATH_MAX];
|
|
sscanf( strString, "\"%1024[^\"]\"", aExePath);
|
|
|
|
CTString strCommand = "\""+CTString(aExePath)+"\"";
|
|
CTString strInputParam = "\""+_fnmApplicationPath+strHelpPath+"\"";
|
|
const char *argv[4];
|
|
argv[0] = strCommand;
|
|
argv[1] = strInputParam;
|
|
argv[2] = NULL;
|
|
_spawnvp(_P_NOWAIT, aExePath, argv);
|
|
return;
|
|
}
|
|
else if( strHelpFormatID=="CHM")
|
|
{
|
|
HtmlHelp(dwData);
|
|
//HtmlHelp(NULL,
|
|
// _fnmApplicationPath+strHelpPath, uCommand, dwData);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
WarningMessage("Expected TXT, HTM, HTML, or CHM help format indentifier.");
|
|
}
|
|
}
|
|
HtmlHelp(dwData);
|
|
//HtmlHelp(NULL,
|
|
// _fnmApplicationPath+"Help\\ToolsHelp.chm::/SeriousEditor/Overview.htm", uCommand, dwData);
|
|
}
|
|
|
|
CEntity *GetTerrainEntity(void)
|
|
{
|
|
CTerrain *ptTerrain=GetTerrain();
|
|
if(ptTerrain!=NULL)
|
|
{
|
|
return ptTerrain->tr_penEntity;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
CTerrain *GetTerrain(void)
|
|
{
|
|
CWorldEditorDoc* pDoc = theApp.GetActiveDocument();
|
|
if(pDoc==NULL) return NULL;
|
|
return pDoc->m_ptrSelectedTerrain;
|
|
}
|
|
|
|
CTerrainLayer *GetLayer(INDEX iLayer)
|
|
{
|
|
CTerrain *ptTerrain=GetTerrain();
|
|
if(ptTerrain==NULL) return NULL;
|
|
if(!(ptTerrain->tr_atlLayers.Count()>0) || iLayer>=ptTerrain->tr_atlLayers.Count()) return NULL;
|
|
return &ptTerrain->tr_atlLayers[iLayer];
|
|
}
|
|
|
|
CTerrainLayer *GetLayer(void)
|
|
{
|
|
CTerrain *ptTerrain=GetTerrain();
|
|
if(ptTerrain==NULL) return NULL;
|
|
if(!(ptTerrain->tr_atlLayers.Count()>0)) return NULL;
|
|
if(ptTerrain->tr_iSelectedLayer>=ptTerrain->tr_atlLayers.Count())
|
|
{
|
|
ptTerrain->tr_iSelectedLayer=0;
|
|
}
|
|
return &ptTerrain->tr_atlLayers[ptTerrain->tr_iSelectedLayer];
|
|
}
|
|
|
|
INDEX GetLayerIndex(void)
|
|
{
|
|
CTerrain *ptTerrain=GetTerrain();
|
|
if(ptTerrain==NULL) return 0;
|
|
if(ptTerrain->tr_atlLayers.Count()<=0 ||
|
|
ptTerrain->tr_iSelectedLayer>=ptTerrain->tr_atlLayers.Count())
|
|
{
|
|
ptTerrain->tr_iSelectedLayer=0;
|
|
}
|
|
return ptTerrain->tr_iSelectedLayer;
|
|
}
|
|
|
|
void SelectLayer(INDEX iLayer)
|
|
{
|
|
CTerrain *ptrTerrain=GetTerrain();
|
|
if(ptrTerrain==NULL) return;
|
|
|
|
if(ptrTerrain->tr_atlLayers.Count()<=iLayer || iLayer<0)
|
|
{
|
|
ptrTerrain->tr_iSelectedLayer=0;
|
|
}
|
|
else
|
|
{
|
|
ptrTerrain->tr_iSelectedLayer=iLayer;
|
|
}
|
|
}
|