diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/options.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'hammer/options.cpp')
| -rw-r--r-- | hammer/options.cpp | 1081 |
1 files changed, 1081 insertions, 0 deletions
diff --git a/hammer/options.cpp b/hammer/options.cpp new file mode 100644 index 0000000..d81c2ac --- /dev/null +++ b/hammer/options.cpp @@ -0,0 +1,1081 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Manages the set of application configuration options. +// +//=============================================================================// + +#include "stdafx.h" +#include "Options.h" +#include "hammer.h" +#include "MainFrm.h" +#include "mapdoc.h" +#include "KeyValues.h" +#include "ConfigManager.h" +#include "GlobalFunctions.h" +#include "CustomMessages.h" +#include "OptionProperties.h" +#include <process.h> + +// memdbgon must be the last include file in a .cpp file!!! +#include <tier0/memdbgon.h> + + +const char GAMECFG_SIG[] = "Game Configurations File\r\n\x1a"; +const float GAMECFG_VERSION = 1.4f; + +static const char *pszGeneral = "General"; +static const char *pszView2D = "2D Views"; +static const char *pszView3D = "3D Views"; +static const char *g_szColors = "Custom2DColors"; + +const int iThisVersion = 2; + +// So File | Open will be in the right directory. +char *g_pMapDir = NULL; + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +COptionsConfigs::COptionsConfigs(void) +{ + nConfigs = 0; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Output : +//----------------------------------------------------------------------------- +COptionsConfigs::~COptionsConfigs(void) +{ + for (int i = 0; i < nConfigs; i++) + { + CGameConfig *pConfig = Configs[i]; + if (!pConfig) + continue; + + delete pConfig; + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Output : +//----------------------------------------------------------------------------- +CGameConfig *COptionsConfigs::AddConfig(void) +{ + CGameConfig *pConfig = new CGameConfig; + Configs.SetAtGrow(nConfigs++, pConfig); + + return pConfig; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : dwID - +// piIndex - +// Output : +//----------------------------------------------------------------------------- +CGameConfig *COptionsConfigs::FindConfig(DWORD dwID, int *piIndex) +{ + for(int i = 0; i < nConfigs; i++) + { + if(Configs[i]->dwID == dwID) + { + if(piIndex) + piIndex[0] = i; + return Configs[i]; + } + } + + return NULL; +} + + +//----------------------------------------------------------------------------- +// Purpose: Looks for a game configuration with a given mod directory. +//----------------------------------------------------------------------------- +CGameConfig *COptionsConfigs::FindConfigForGame(const char *szGame) +{ + for (int i = 0; i < nConfigs; i++) + { + char *pszGameDir = Configs[i]->m_szModDir; + if ( Q_stricmp( pszGameDir, szGame ) == 0 ) + return Configs[i]; + } + + return NULL; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns the number of game configurations successfully imported. +//----------------------------------------------------------------------------- +int COptionsConfigs::ImportOldGameConfigs(const char *pszFileName) +{ + int nConfigsRead = 0; + + char szRootDir[MAX_PATH]; + char szFullPath[MAX_PATH]; + APP()->GetDirectory(DIR_PROGRAM, szRootDir); + Q_MakeAbsolutePath( szFullPath, MAX_PATH, pszFileName, szRootDir ); + std::fstream file( szFullPath, std::ios::in | std::ios::binary ); + if (file.is_open()) + { + // Read sig. + char szSig[sizeof(GAMECFG_SIG)]; + file.read(szSig, sizeof szSig); + if (!memcmp(szSig, GAMECFG_SIG, sizeof szSig)) + { + // Read version. + float fThisVersion; + file.read((char *)&fThisVersion, sizeof(fThisVersion)); + if ((fThisVersion >= 1.0) && (fThisVersion <= GAMECFG_VERSION)) + { + // Read number of configs. + int nTotalConfigs; + file.read((char *)&nTotalConfigs, sizeof(nTotalConfigs)); + + // Load each config. + for (int i = 0; i < nTotalConfigs; i++) + { + CGameConfig *pConfig = AddConfig(); + pConfig->Import(file, fThisVersion); + nConfigsRead++; + + if (!g_pMapDir) + { + g_pMapDir = (char *)pConfig->szMapDir; + } + } + } + } + + file.close(); + } + + return(nConfigsRead); +} + +// Our call to "new" will be hosed without this header +#include "tier0/memdbgoff.h" + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool COptionsConfigs::ResetGameConfigs( bool bOverwrite ) +{ + CGameConfigManager mgr; + int nNumLoaded = 0; + + mgr.SetBaseDirectory( m_strConfigDir ); + + if ( bOverwrite ) + { + // Reset the configurations on the disk + mgr.ResetConfigs(); + + // Load the newly changed game configs + nNumLoaded = LoadGameConfigs(); + } + else + { + // Simply get the keyvalue block from the manager and parse that + KeyValues *pDefaultConfigs = new KeyValues( "Defaults" ); + + if ( mgr.GetDefaultGameBlock( pDefaultConfigs ) == false ) + return false; + + // Load from the blocks + nNumLoaded = LoadGameConfigsBlock( pDefaultConfigs ); + + // Clean up + pDefaultConfigs->deleteThis(); + } + + return ( nNumLoaded > 0 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pBlock - +// Output : int +//----------------------------------------------------------------------------- +int COptionsConfigs::LoadGameConfigsBlock( KeyValues *pBlock ) +{ + if ( pBlock == NULL ) + return 0; + + int nConfigsRead = 0; + + for ( KeyValues *pKey = pBlock->GetFirstTrueSubKey(); pKey; pKey = pKey->GetNextTrueSubKey() ) + { + CGameConfig *pConfig = AddConfig(); + if ( pConfig != NULL ) + { + if ( pConfig->Load( pKey ) ) + { + nConfigsRead++; + } + } + } + + return nConfigsRead; +} + +//----------------------------------------------------------------------------- +// Purpose: Loads all the game configs from disk. +// Output : Returns the number of game configurations successfully loaded. +//----------------------------------------------------------------------------- +int COptionsConfigs::LoadGameConfigs() +{ + // + // Read game configs - this is from an external file so we can distribute it + // with the editor as a set of defaults. + // + // Older versions of the editor used a binary file. Try that first. + // + int nConfigsRead = ImportOldGameConfigs("GameCfg.wc"); + if (nConfigsRead > 0) + { + // This will cause a double conversion, from .wc to .ini to .txt, but oh well... + char szRootDir[MAX_PATH]; + char szFullPath[MAX_PATH]; + APP()->GetDirectory(DIR_PROGRAM, szRootDir); + Q_MakeAbsolutePath( szFullPath, MAX_PATH, "GameCfg.wc", szRootDir ); + remove( szFullPath ); + char szSaveName[MAX_PATH]; + strcpy(szSaveName, m_strConfigDir); + Q_AppendSlash(szSaveName, sizeof(szSaveName)); + Q_strcat(szSaveName, "GameCfg.ini", sizeof(szSaveName)); + SaveGameConfigs(); + return(nConfigsRead); + } + + CGameConfigManager mgr; + + if ( !mgr.LoadConfigs( m_strConfigDir ) ) + return 0; + + KeyValues *pGame = mgr.GetGameBlock(); + if (!pGame) + return 0; + + // Install the message handler for error messages. + GDSetMessageFunc(Msg); + + // Load from the blocks + nConfigsRead = LoadGameConfigsBlock( pGame ); + + return nConfigsRead; +} + + +//----------------------------------------------------------------------------- +// Purpose: Saves all the cgame configurations to disk. +// Input : *pszFileName - +//----------------------------------------------------------------------------- +void COptionsConfigs::SaveGameConfigs() +{ + // Only do this if we've got configs to save! + if ( GetGameConfigCount() == 0 ) + return; + + CGameConfigManager mgr; + + if ( mgr.LoadConfigs( m_strConfigDir ) == false ) + return; + + // Get the global configuration data + KeyValues *pGame = mgr.GetGameBlock(); + + // For each Hammer known configuation, update the values in the global configs + for ( int i = 0; i < nConfigs; i++ ) + { + KeyValues *pConfig = pGame->FindKey(Configs.GetAt(i)->szName); + + // Add the configuration if it wasn't found + if ( pConfig == NULL ) + { + pConfig = pGame->CreateNewKey(); + if ( pConfig == NULL ) + { + // FIXME: fatal error + return; + } + } + + // Update the changes + Configs.GetAt(i)->Save(pConfig); + } + + // For each global configuration, remove any configs Hammer has deleted + bool bFoundConfig; + KeyValues *pConfig = pGame->GetFirstTrueSubKey(); + while ( pConfig != NULL ) + { + // Search through all the configs Hammer knows of for a matching name + bFoundConfig = false; + for ( int i = 0; i < nConfigs; i++ ) + { + if ( !Q_stricmp( pConfig->GetName(), Configs.GetAt(i)->szName ) ) + { + bFoundConfig = true; + break; + } + } + + // Move along to the next config + if ( bFoundConfig ) + { + pConfig = pConfig->GetNextTrueSubKey(); + continue; + } + + // Delete the configuration block if we didn't find it + KeyValues *pNextConfig = pConfig->GetNextTrueSubKey(); + pGame->RemoveSubKey( pConfig ); + pConfig->deleteThis(); + pConfig = pNextConfig; + } + + // Save the resulting changes + mgr.SaveConfigs( m_strConfigDir ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +COptions::COptions(void) +{ +} + + +//----------------------------------------------------------------------------- +// Purpose: Looks for the Valve Hammer Editor registry settings and returns whether +// they were found. +//----------------------------------------------------------------------------- +static bool HammerSettingsFound(void) +{ + bool bFound = false; + HKEY hkeySoftware; + if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_READ | KEY_WRITE, &hkeySoftware) == ERROR_SUCCESS) + { + HKEY hkeyValve; + if (RegOpenKeyEx(hkeySoftware, "Valve", 0, KEY_READ | KEY_WRITE, &hkeyValve) == ERROR_SUCCESS) + { + HKEY hkeyHammer; + if (RegOpenKeyEx(hkeyValve, "Hammer", 0, KEY_READ | KEY_WRITE, &hkeyHammer) == ERROR_SUCCESS) + { + HKEY hkeyConfigured; + if (RegOpenKeyEx(hkeyHammer, "Configured", 0, KEY_READ | KEY_WRITE, &hkeyConfigured) == ERROR_SUCCESS) + { + bFound = true; + RegCloseKey(hkeyConfigured); + } + RegCloseKey(hkeyHammer); + } + RegCloseKey(hkeyValve); + } + RegCloseKey(hkeySoftware); + } + + return bFound; +} + + +//----------------------------------------------------------------------------- +// Purpose: Looks for the Valve Hammer Editor registry settings and returns whether +// they were found. +//----------------------------------------------------------------------------- +static bool ValveHammerEditorSettingsFound(void) +{ + bool bFound = false; + HKEY hkeySoftware; + if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_READ | KEY_WRITE, &hkeySoftware) == ERROR_SUCCESS) + { + HKEY hkeyValve; + if (RegOpenKeyEx(hkeySoftware, "Valve", 0, KEY_READ | KEY_WRITE, &hkeyValve) == ERROR_SUCCESS) + { + HKEY hkeyHammer; + if (RegOpenKeyEx(hkeyValve, "Valve Hammer Editor", 0, KEY_READ | KEY_WRITE, &hkeyHammer) == ERROR_SUCCESS) + { + HKEY hkeyConfigured; + if (RegOpenKeyEx(hkeyHammer, "Configured", 0, KEY_READ | KEY_WRITE, &hkeyConfigured) == ERROR_SUCCESS) + { + bFound = true; + RegCloseKey(hkeyConfigured); + } + RegCloseKey(hkeyHammer); + } + RegCloseKey(hkeyValve); + } + RegCloseKey(hkeySoftware); + } + + return bFound; +} + + +//----------------------------------------------------------------------------- +// Purpose: Looks for the Worldcraft registry settings and returns whether they +// were found. +//----------------------------------------------------------------------------- +static bool WorldcraftSettingsFound(void) +{ + bool bFound = false; + HKEY hkeySoftware; + if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_READ | KEY_WRITE, &hkeySoftware) == ERROR_SUCCESS) + { + HKEY hkeyValve; + if (RegOpenKeyEx(hkeySoftware, "Valve", 0, KEY_READ | KEY_WRITE, &hkeyValve) == ERROR_SUCCESS) + { + HKEY hkeyWorldcraft; + if (RegOpenKeyEx(hkeyValve, "Worldcraft", 0, KEY_READ | KEY_WRITE, &hkeyWorldcraft) == ERROR_SUCCESS) + { + bFound = true; + RegCloseKey(hkeyWorldcraft); + } + RegCloseKey(hkeyValve); + } + RegCloseKey(hkeySoftware); + } + + return bFound; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool COptions::Init(void) +{ + // + // If the we have no registry settings and the "Valve Hammer Editor" registry tree exists, + // import settings from there. If that isn't found, try "Worldcraft". + // + bool bWCSettingsFound = false; + bool bVHESettingsFound = false; + + if (!HammerSettingsFound()) + { + bVHESettingsFound = ValveHammerEditorSettingsFound(); + if (!bVHESettingsFound) + { + bWCSettingsFound = WorldcraftSettingsFound(); + } + } + + if (bVHESettingsFound) + { + APP()->BeginImportVHESettings(); + } + else if (bWCSettingsFound) + { + APP()->BeginImportWCSettings(); + } + + SetDefaults(); + + if (!Read()) + { + return false; + } + + if (bVHESettingsFound || bWCSettingsFound) + { + APP()->EndImportSettings(); + } + + // + // Notify appropriate windows of new settings. + // dvs: is all this necessary? + // + CMainFrame *pMainWnd = GetMainWnd(); + if (pMainWnd != NULL) + { + pMainWnd->SetBrightness(textures.fBrightness); + + pMainWnd->UpdateAllDocViews( MAPVIEW_OPTIONS_CHANGED ); + + // FIXME: can't do this before the filesystem is initialized + //pMainWnd->GlobalNotify(WM_GAME_CHANGED); + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: Enables or disables texture locking. +// Input : b - TRUE to enable texture locking, FALSE to disable. +// Output : Returns the previous value of the texture locking flag. +//----------------------------------------------------------------------------- +BOOL COptions::SetLockingTextures(BOOL b) +{ + BOOL bOld = general.bLockingTextures; + general.bLockingTextures = b; + return(bOld); +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns TRUE if texture locking is enabled, FALSE if not. +//----------------------------------------------------------------------------- +BOOL COptions::IsLockingTextures(void) +{ + return(general.bLockingTextures); +} + +BOOL COptions::SetScaleLockingTextures(BOOL b) +{ + BOOL bOld = general.bScaleLockingTextures; + general.bScaleLockingTextures = b; + return(bOld); +} + +BOOL COptions::IsScaleLockingTextures(void) +{ + return general.bScaleLockingTextures; +} + +//----------------------------------------------------------------------------- +// Purpose: Returns whether new faces should be world aligned or face aligned. +//----------------------------------------------------------------------------- +TextureAlignment_t COptions::GetTextureAlignment(void) +{ + return(general.eTextureAlignment); +} + + +//----------------------------------------------------------------------------- +// Purpose: Sets whether new faces should be world aligned or face aligned. +// Input : eTextureAlignment - TEXTURE_ALIGN_WORLD or TEXTURE_ALIGN_FACE. +// Output : Returns the old setting for texture alignment. +//----------------------------------------------------------------------------- +TextureAlignment_t COptions::SetTextureAlignment(TextureAlignment_t eTextureAlignment) +{ + TextureAlignment_t eOld = general.eTextureAlignment; + general.eTextureAlignment = eTextureAlignment; + return(eOld); +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns whether helpers should be hidden or shown. +//----------------------------------------------------------------------------- +bool COptions::GetShowHelpers(void) +{ + return (general.bShowHelpers == TRUE); +} + +bool COptions::IsVGUIModelBrowserEnabled() +{ + return (general.bUseVGUIModelBrowser == TRUE); +} + + +//----------------------------------------------------------------------------- +// Purpose: Sets whether helpers should be hidden or shown. +//----------------------------------------------------------------------------- +void COptions::SetShowHelpers(bool bShow) +{ + general.bShowHelpers = bShow ? TRUE : FALSE; +} + + +//----------------------------------------------------------------------------- +// Purpose: Loads the application configuration settings. +// Output : Returns TRUE on success, FALSE on failure. +//----------------------------------------------------------------------------- +bool COptions::Read(void) +{ + if (!APP()->GetProfileInt("Configured", "Configured", 0)) + { + return false; + } + + DWORD dwTime = APP()->GetProfileInt("Configured", "Installed", time(NULL)); + CTimeSpan ts(time(NULL) - dwTime); + uDaysSinceInstalled = ts.GetDays(); + + int i, iSize; + CString str; + + // read texture info - it's stored in the general section from + // an old version, but this doesn't matter much. + iSize = APP()->GetProfileInt(pszGeneral, "TextureFileCount", 0); + if(iSize) + { + // make sure default is removed + textures.nTextureFiles = 0; + textures.TextureFiles.RemoveAll(); + // read texture file names + for(i = 0; i < iSize; i++) + { + str.Format("TextureFile%d", i); + str = APP()->GetProfileString(pszGeneral, str); + if(GetFileAttributes(str) == 0xffffffff) + { + // can't find + continue; + } + textures.TextureFiles.Add(str); + textures.nTextureFiles++; + } + } + else + { + // SetDefaults() added 'textures.wad' to the list + } + textures.fBrightness = float(APP()->GetProfileInt(pszGeneral, "Brightness", 10)) / 10.0; + + // load general info + general.nMaxCameras = APP()->GetProfileInt(pszGeneral, "Max Cameras", 100); + general.iUndoLevels = APP()->GetProfileInt(pszGeneral, "Undo Levels", 50); + general.bLockingTextures = APP()->GetProfileInt(pszGeneral, "Locking Textures", TRUE); + general.bScaleLockingTextures = APP()->GetProfileInt(pszGeneral, "Scale Locking Textures", FALSE); + general.eTextureAlignment = (TextureAlignment_t)APP()->GetProfileInt(pszGeneral, "Texture Alignment", TEXTURE_ALIGN_WORLD); + general.bLoadwinpos = APP()->GetProfileInt(pszGeneral, "Load Default Positions", TRUE); + general.bIndependentwin = APP()->GetProfileInt(pszGeneral, "Independent Windows", FALSE); + general.bGroupWhileIgnore = APP()->GetProfileInt(pszGeneral, "GroupWhileIgnore", FALSE); + general.bStretchArches = APP()->GetProfileInt(pszGeneral, "StretchArches", TRUE); + general.bShowHelpers = APP()->GetProfileInt(pszGeneral, "Show Helpers", TRUE); + general.bCheckVisibleMapErrors = APP()->GetProfileInt(pszGeneral, "Visible Map Errors", FALSE); + general.iTimeBetweenSaves = APP()->GetProfileInt(pszGeneral, "Time Between Saves", 15); + general.iMaxAutosaveSpace = APP()->GetProfileInt(pszGeneral, "Max Autosave Space", 100); + general.iMaxAutosavesPerMap = APP()->GetProfileInt(pszGeneral, "Max Saves Per Map", 5); + general.bEnableAutosave = APP()->GetProfileInt(pszGeneral, "Autosaves Enabled", 1); + general.bClosedCorrectly = APP()->GetProfileInt(pszGeneral, "Closed Correctly", TRUE); + general.bUseVGUIModelBrowser = APP()->GetProfileInt(pszGeneral, "VGUI Model Browser", TRUE); + general.bShowHiddenTargetsAsBroken = APP()->GetProfileInt(pszGeneral, "Show Hidden Targets As Broken", TRUE); + general.bRadiusCulling = APP()->GetProfileInt(pszGeneral, "Use Radius Culling", FALSE); + + char szDefaultAutosavePath[MAX_PATH]; + V_strcpy_safe( szDefaultAutosavePath, APP()->GetProfileString( pszGeneral, "Directory", "C:" ) ); + V_strcpy_safe( szDefaultAutosavePath, "\\HammerAutosave\\" ); + strcpy( general.szAutosaveDir, APP()->GetProfileString("General", "Autosave Dir", szDefaultAutosavePath)); + if ( Q_strlen( general.szAutosaveDir ) == 0 ) + { + strcpy( general.szAutosaveDir, szDefaultAutosavePath ); + } + APP()->SetDirectory( DIR_AUTOSAVE, general.szAutosaveDir ); + + // read view2d + view2d.bCrosshairs = APP()->GetProfileInt(pszView2D, "Crosshairs", FALSE); + view2d.bGroupCarve = APP()->GetProfileInt(pszView2D, "GroupCarve", TRUE); + view2d.bScrollbars = APP()->GetProfileInt(pszView2D, "Scrollbars", TRUE); + view2d.bRotateConstrain = APP()->GetProfileInt(pszView2D, "RotateConstrain", FALSE); + view2d.bDrawVertices = APP()->GetProfileInt(pszView2D, "Draw Vertices", TRUE); + view2d.bDrawModels = APP()->GetProfileInt(pszView2D, "Draw Models", TRUE); + view2d.bWhiteOnBlack = APP()->GetProfileInt(pszView2D, "WhiteOnBlack", TRUE); + view2d.bGridHigh1024 = APP()->GetProfileInt(pszView2D, "GridHigh1024", TRUE); + view2d.bGridHigh10 = APP()->GetProfileInt(pszView2D, "GridHigh10", TRUE); + view2d.bHideSmallGrid = APP()->GetProfileInt(pszView2D, "HideSmallGrid", TRUE); + view2d.bNudge = APP()->GetProfileInt(pszView2D, "Nudge", FALSE); + view2d.bOrientPrimitives = APP()->GetProfileInt(pszView2D, "OrientPrimitives", FALSE); + view2d.bAutoSelect = APP()->GetProfileInt(pszView2D, "AutoSelect", FALSE); + view2d.bSelectbyhandles = APP()->GetProfileInt(pszView2D, "SelectByHandles", FALSE); + view2d.iGridIntensity = APP()->GetProfileInt(pszView2D, "GridIntensity", 30); + view2d.iDefaultGrid = APP()->GetProfileInt(pszView2D, "Default Grid", 64); + view2d.iGridHighSpec = APP()->GetProfileInt(pszView2D, "GridHighSpec", 8); + view2d.bKeepclonegroup = APP()->GetProfileInt(pszView2D, "Keepclonegroup", TRUE); + view2d.bGridHigh64 = APP()->GetProfileInt(pszView2D, "Gridhigh64", TRUE); + view2d.bGridDots = APP()->GetProfileInt(pszView2D, "GridDots", FALSE); + view2d.bCenteroncamera = APP()->GetProfileInt(pszView2D, "Centeroncamera", FALSE); + view2d.bUsegroupcolors = APP()->GetProfileInt(pszView2D, "Usegroupcolors", TRUE); + + // read view3d + view3d.bHardware = APP()->GetProfileInt(pszView3D, "Hardware", FALSE); + view3d.bReverseY = APP()->GetProfileInt(pszView3D, "Reverse Y", TRUE); + view3d.iBackPlane = APP()->GetProfileInt(pszView3D, "BackPlane", 5000); + view3d.bUseMouseLook = APP()->GetProfileInt(pszView3D, "UseMouseLook", TRUE); + view3d.nModelDistance = APP()->GetProfileInt(pszView3D, "ModelDistance", 400); + view3d.nDetailDistance = APP()->GetProfileInt(pszView3D, "DetailDistance", 1200); + view3d.bAnimateModels = APP()->GetProfileInt(pszView3D, "AnimateModels", FALSE); + view3d.nForwardSpeedMax = APP()->GetProfileInt(pszView3D, "ForwardSpeedMax", 1000); + view3d.nTimeToMaxSpeed = APP()->GetProfileInt(pszView3D, "TimeToMaxSpeed", 500); + view3d.bFilterTextures = APP()->GetProfileInt(pszView3D, "FilterTextures", TRUE); + view3d.bReverseSelection = APP()->GetProfileInt(pszView3D, "ReverseSelection", FALSE); + view3d.fFOV = 90; + view3d.fLightConeLength = 10; + + ReadColorSettings(); + + // + // If we can't load any game configurations, pop up the options screen. + // + if (configs.LoadGameConfigs() == 0) + { + if (!RunConfigurationDialog()) + return false; + } + + // + // By default use the first config. + // + if (configs.nConfigs > 0) + { + g_pGameConfig = configs.Configs.GetAt(0); + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool COptions::RunConfigurationDialog() +{ + CString strText; + strText.LoadString(IDS_NO_CONFIGS_AVAILABLE); + if (MessageBox(NULL, strText, "First Time Setup", MB_ICONQUESTION | MB_YESNO) == IDYES) + { + APP()->OpenURL(ID_HELP_FIRST_TIME_SETUP, GetMainWnd()->GetSafeHwnd()); + } + + COptionProperties dlg("Configure Hammer"); + + do + { + if (dlg.DoModal() != IDOK) + { + return false; + } + + if (configs.nConfigs == 0) + { + MessageBox(NULL, "You must create at least one game configuration before using Hammer.", "First Time Setup", MB_ICONEXCLAMATION | MB_OK); + } + + } while (configs.nConfigs == 0); + + Options.Write( TRUE, TRUE ); + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void COptions::ReadColorSettings(void) +{ + colors.bUseCustom = (APP()->GetProfileInt(g_szColors, "UseCustom", 0) != 0); + if (colors.bUseCustom) + { + colors.clrAxis = APP()->GetProfileColor(g_szColors, "Grid0", 0 , 100, 100); + colors.bScaleAxisColor = (APP()->GetProfileInt(g_szColors, "ScaleGrid0", 0) != 0); + colors.clrGrid = APP()->GetProfileColor(g_szColors, "Grid", 50 , 50, 50); + colors.bScaleGridColor = (APP()->GetProfileInt(g_szColors, "ScaleGrid", 1) != 0); + colors.clrGrid10 = APP()->GetProfileColor(g_szColors, "Grid10", 40 , 40, 40); + colors.bScaleGrid10Color = (APP()->GetProfileInt(g_szColors, "ScaleGrid10", 1) != 0); + colors.clrGrid1024 = APP()->GetProfileColor(g_szColors, "Grid1024", 40 , 40, 40); + colors.bScaleGrid1024Color = (APP()->GetProfileInt(g_szColors, "ScaleGrid1024", 1) != 0); + colors.clrGridDot = APP()->GetProfileColor(g_szColors, "GridDot", 128, 128, 128); + colors.bScaleGridDotColor = (APP()->GetProfileInt(g_szColors, "ScaleGridDot", 1) != 0); + + colors.clrBrush = APP()->GetProfileColor(g_szColors, "LineColor", 0, 0, 0); + colors.clrEntity = APP()->GetProfileColor(g_szColors, "Entity", 220, 30, 220); + colors.clrVertex = APP()->GetProfileColor(g_szColors, "Vertex", 0, 0, 0); + colors.clrBackground = APP()->GetProfileColor(g_szColors, "Background", 0, 0, 0); + colors.clrToolHandle = APP()->GetProfileColor(g_szColors, "HandleColor", 0, 0, 0); + colors.clrToolBlock = APP()->GetProfileColor(g_szColors, "BoxColor", 0, 0, 0); + colors.clrToolSelection = APP()->GetProfileColor(g_szColors, "ToolSelect", 0, 0, 0); + colors.clrToolMorph = APP()->GetProfileColor(g_szColors, "Morph", 255, 0, 0); + colors.clrToolPath = APP()->GetProfileColor(g_szColors, "Path", 255, 0, 0); + colors.clrSelection = APP()->GetProfileColor(g_szColors, "Selection", 220, 0, 0); + colors.clrToolDrag = APP()->GetProfileColor(g_szColors, "ToolDrag", 255, 255, 0); + } + else + { + if (Options.view2d.bWhiteOnBlack) + { + // BLACK BACKGROUND + colors.clrBackground = RGB(0, 0, 0); + colors.clrGrid = RGB(255, 255, 255); + colors.clrGridDot = RGB(255, 255, 255); + colors.clrGrid1024 = RGB(100, 50, 5); + colors.clrGrid10 = RGB(255, 255, 255); + colors.clrAxis = RGB(0, 100, 100); + colors.clrBrush = RGB(255, 255, 255); + colors.clrVertex = RGB(255, 255, 255); + + colors.clrToolHandle = RGB(255, 255, 255); + colors.clrToolBlock = RGB(255, 255, 255); + colors.clrToolDrag = RGB(255, 255, 0); + } + else + { + // WHITE BACKGROUND + colors.clrBackground = RGB(255, 255, 255); + colors.clrGrid = RGB(50, 50, 50); + colors.clrGridDot = RGB(40, 40, 40); + colors.clrGrid1024 = RGB(200, 100, 10); + colors.clrGrid10 = RGB(40, 40, 40); + colors.clrAxis = RGB(0, 100, 100); + colors.clrBrush = RGB(0, 0, 0); + colors.clrVertex = RGB(0, 0, 0); + + colors.clrToolHandle = RGB(0, 0, 0); + colors.clrToolBlock = RGB(0, 0, 0); + colors.clrToolDrag = RGB(0, 0, 255); + } + + colors.bScaleAxisColor = false; + colors.bScaleGridColor = true; + colors.bScaleGrid10Color = true; + colors.bScaleGrid1024Color = false; + colors.bScaleGridDotColor = true; + + colors.clrToolSelection = RGB(255, 255, 0); + colors.clrSelection = RGB(255, 0, 0); + colors.clrToolMorph = RGB(255, 0, 0); + colors.clrToolPath = RGB(255, 0, 0); + colors.clrEntity = RGB(220, 30, 220); + colors.clrModelCollisionWireframe = RGB( 255, 255, 0 ); + colors.clrModelCollisionWireframeDisabled = RGB( 220, 30, 220 ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : fOverwrite - +//----------------------------------------------------------------------------- +void COptions::Write( BOOL fOverwrite, BOOL fSaveConfigs ) +{ + APP()->WriteProfileInt("Configured", "Configured", iThisVersion); + + int i, iSize; + CString str; + + // write texture info - remember, it's stored in general + iSize = textures.nTextureFiles; + APP()->WriteProfileInt(pszGeneral, "TextureFileCount", iSize); + for(i = 0; i < iSize; i++) + { + str.Format("TextureFile%d", i); + APP()->WriteProfileString(pszGeneral, str, textures.TextureFiles[i]); + } + APP()->WriteProfileInt(pszGeneral, "Brightness", int(textures.fBrightness * 10)); + + // write general + APP()->WriteProfileInt(pszGeneral, "Max Cameras", general.nMaxCameras); + APP()->WriteProfileInt(pszGeneral, "Undo Levels", general.iUndoLevels); + APP()->WriteProfileInt(pszGeneral, "Locking Textures", general.bLockingTextures); + APP()->WriteProfileInt(pszGeneral, "Scale Locking Textures", general.bScaleLockingTextures); + APP()->WriteProfileInt(pszGeneral, "Texture Alignment", general.eTextureAlignment); + APP()->WriteProfileInt(pszGeneral, "Independent Windows", general.bIndependentwin); + APP()->WriteProfileInt(pszGeneral, "Load Default Positions", general.bLoadwinpos); + APP()->WriteProfileInt(pszGeneral, "GroupWhileIgnore", general.bGroupWhileIgnore); + APP()->WriteProfileInt(pszGeneral, "StretchArches", general.bStretchArches); + APP()->WriteProfileInt(pszGeneral, "Show Helpers", general.bShowHelpers); + APP()->WriteProfileInt(pszGeneral, "Visible Map Errors", general.bCheckVisibleMapErrors); + APP()->WriteProfileInt(pszGeneral, "Time Between Saves", general.iTimeBetweenSaves); + APP()->WriteProfileInt(pszGeneral, "Max Autosave Space", general.iMaxAutosaveSpace); + APP()->WriteProfileInt(pszGeneral, "Max Saves Per Map", general.iMaxAutosavesPerMap); + APP()->WriteProfileInt(pszGeneral, "Autosaves Enabled", general.bEnableAutosave); + APP()->WriteProfileInt(pszGeneral, "Closed Correctly", general.bClosedCorrectly); + APP()->WriteProfileString(pszGeneral, "Autosave Dir", general.szAutosaveDir); + APP()->SetDirectory( DIR_AUTOSAVE, general.szAutosaveDir ); + APP()->WriteProfileInt(pszGeneral, "VGUI Model Browser", general.bUseVGUIModelBrowser ); + APP()->WriteProfileInt(pszGeneral, "Show Hidden Targets As Broken", general.bShowHiddenTargetsAsBroken); + APP()->WriteProfileInt(pszGeneral, "Use Radius Culling", general.bRadiusCulling); + + + + // write view2d + APP()->WriteProfileInt(pszView2D, "Crosshairs", view2d.bCrosshairs); + APP()->WriteProfileInt(pszView2D, "GroupCarve", view2d.bGroupCarve); + APP()->WriteProfileInt(pszView2D, "Scrollbars", view2d.bScrollbars); + APP()->WriteProfileInt(pszView2D, "RotateConstrain", view2d.bRotateConstrain); + APP()->WriteProfileInt(pszView2D, "Draw Vertices", view2d.bDrawVertices); + APP()->WriteProfileInt(pszView2D, "Draw Models", view2d.bDrawModels); + APP()->WriteProfileInt(pszView2D, "Default Grid", view2d.iDefaultGrid); + APP()->WriteProfileInt(pszView2D, "WhiteOnBlack", view2d.bWhiteOnBlack); + APP()->WriteProfileInt(pszView2D, "GridHigh1024", view2d.bGridHigh1024); + APP()->WriteProfileInt(pszView2D, "GridHigh10", view2d.bGridHigh10); + APP()->WriteProfileInt(pszView2D, "GridIntensity", view2d.iGridIntensity); + APP()->WriteProfileInt(pszView2D, "HideSmallGrid", view2d.bHideSmallGrid); + APP()->WriteProfileInt(pszView2D, "Nudge", view2d.bNudge); + APP()->WriteProfileInt(pszView2D, "OrientPrimitives", view2d.bOrientPrimitives); + APP()->WriteProfileInt(pszView2D, "AutoSelect", view2d.bAutoSelect); + APP()->WriteProfileInt(pszView2D, "SelectByHandles", view2d.bSelectbyhandles); + APP()->WriteProfileInt(pszView2D, "GridHighSpec", view2d.iGridHighSpec); + APP()->WriteProfileInt(pszView2D, "KeepCloneGroup", view2d.bKeepclonegroup); + APP()->WriteProfileInt(pszView2D, "Gridhigh64", view2d.bGridHigh64); + APP()->WriteProfileInt(pszView2D, "GridDots", view2d.bGridDots); + APP()->WriteProfileInt(pszView2D, "Centeroncamera", view2d.bCenteroncamera); + APP()->WriteProfileInt(pszView2D, "Usegroupcolors", view2d.bUsegroupcolors); + + // write view3d + APP()->WriteProfileInt(pszView3D, "Hardware", view3d.bHardware); + APP()->WriteProfileInt(pszView3D, "Reverse Y", view3d.bReverseY); + APP()->WriteProfileInt(pszView3D, "BackPlane", view3d.iBackPlane); + APP()->WriteProfileInt(pszView3D, "UseMouseLook", view3d.bUseMouseLook); + APP()->WriteProfileInt(pszView3D, "ModelDistance", view3d.nModelDistance); + APP()->WriteProfileInt(pszView3D, "DetailDistance", view3d.nDetailDistance); + APP()->WriteProfileInt(pszView3D, "AnimateModels", view3d.bAnimateModels); + APP()->WriteProfileInt(pszView3D, "ForwardSpeedMax", view3d.nForwardSpeedMax); + APP()->WriteProfileInt(pszView3D, "TimeToMaxSpeed", view3d.nTimeToMaxSpeed); + APP()->WriteProfileInt(pszView3D, "FilterTextures", view3d.bFilterTextures); + APP()->WriteProfileInt(pszView3D, "ReverseSelection", view3d.bReverseSelection); + + // + // We don't write custom color settings because there is no GUI for them yet. + // + + // Write out the game configurations + if ( fSaveConfigs ) + { + configs.SaveGameConfigs(); + } +} + + +void COptions::SetClosedCorrectly(BOOL bClosed) +{ + APP()->WriteProfileInt( pszGeneral, "Closed Correctly", bClosed ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void COptions::SetDefaults(void) +{ + BOOL bWrite = FALSE; + + if (APP()->GetProfileInt("Configured", "Configured", 0) != iThisVersion) + { + bWrite = TRUE; + } + + if (APP()->GetProfileInt("Configured", "Installed", 42151) == 42151) + { + APP()->WriteProfileInt("Configured", "Installed", time(NULL)); + } + + uDaysSinceInstalled = 0; + + // textures + textures.nTextureFiles = 1; + textures.TextureFiles.Add("textures.wad"); + textures.fBrightness = 1.0; + + // general + general.bIndependentwin = FALSE; + general.bLoadwinpos = TRUE; + general.iUndoLevels = 50; + general.nMaxCameras = 100; + general.bGroupWhileIgnore = FALSE; + general.bStretchArches = TRUE; + general.bLockingTextures = TRUE; + general.bScaleLockingTextures = FALSE; + general.bShowHelpers = TRUE; + general.iTimeBetweenSaves = 15; + general.iMaxAutosaveSpace = 100; + general.iMaxAutosavesPerMap = 5; + general.bEnableAutosave = TRUE; + general.bClosedCorrectly = TRUE; + general.bUseVGUIModelBrowser = TRUE; + general.bShowCollisionModels = FALSE; + general.bShowDetailObjects = TRUE; + general.bShowNoDrawBrushes = TRUE; + + // view2d + view2d.bCrosshairs = FALSE; + view2d.bGroupCarve = TRUE; + view2d.bScrollbars = TRUE; + view2d.bRotateConstrain = FALSE; + view2d.bDrawVertices = TRUE; + view2d.bDrawModels = TRUE; + view2d.iDefaultGrid = 64; + view2d.bWhiteOnBlack = TRUE; + view2d.bGridHigh1024 = TRUE; + view2d.bGridHigh10 = TRUE; + view2d.iGridIntensity = 30; + view2d.bHideSmallGrid = TRUE; + view2d.bNudge = FALSE; + view2d.bOrientPrimitives = FALSE; + view2d.bAutoSelect = FALSE; + view2d.bSelectbyhandles = FALSE; + view2d.iGridHighSpec = 8; + view2d.bKeepclonegroup = TRUE; + view2d.bGridHigh64 = FALSE; + view2d.bGridDots = FALSE; + view2d.bCenteroncamera = FALSE; + view2d.bUsegroupcolors = TRUE; + + // view3d + view3d.bUseMouseLook = TRUE; + view3d.bHardware = FALSE; + view3d.bReverseY = FALSE; + view3d.iBackPlane = 5000; + view3d.nModelDistance = 400; + view3d.nDetailDistance = 1200; + view3d.bAnimateModels = FALSE; + view3d.nForwardSpeedMax = 1000; + view3d.nTimeToMaxSpeed = 500; + view3d.bFilterTextures = TRUE; + view3d.bReverseSelection = FALSE; + view3d.bPreviewModelFade = false; + + if ( bWrite ) + { + Write( FALSE, FALSE ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: This is called by the user interface itself when changes are made. +// tells the COptions object to notify the parts of the interface. +// Input : dwOptionsChanged - Flags indicating which options changed. +//----------------------------------------------------------------------------- +void COptions::PerformChanges(DWORD dwOptionsChanged) +{ + CMainFrame *pMainWnd = GetMainWnd(); + + if (dwOptionsChanged & secTextures) + { + if (pMainWnd != NULL) + { + pMainWnd->SetBrightness(textures.fBrightness); + } + } + + if (dwOptionsChanged & secView2D) + { + ReadColorSettings(); + + if (pMainWnd != NULL) + { + pMainWnd->UpdateAllDocViews( MAPVIEW_UPDATE_ONLY_2D | MAPVIEW_OPTIONS_CHANGED | MAPVIEW_RENDER_NOW ); + } + } + + if (dwOptionsChanged & secView3D) + { + if (pMainWnd != NULL) + { + pMainWnd->UpdateAllDocViews(MAPVIEW_UPDATE_ONLY_3D | MAPVIEW_OPTIONS_CHANGED | MAPVIEW_RENDER_NOW ); + } + } + + if (dwOptionsChanged & secConfigs) + { + if (pMainWnd != NULL) + { + pMainWnd->GlobalNotify(WM_GAME_CHANGED); + } + } +} + |