summaryrefslogtreecommitdiff
path: root/hammer/optconfigs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hammer/optconfigs.cpp')
-rw-r--r--hammer/optconfigs.cpp839
1 files changed, 839 insertions, 0 deletions
diff --git a/hammer/optconfigs.cpp b/hammer/optconfigs.cpp
new file mode 100644
index 0000000..fc7abd8
--- /dev/null
+++ b/hammer/optconfigs.cpp
@@ -0,0 +1,839 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "stdafx.h"
+#include <shlobj.h>
+#include "GameConfig.h"
+#include "EditGameConfigs.h"
+#include "hammer.h"
+#include "OPTConfigs.h"
+#include "ConfigManager.h"
+#include "process.h"
+#include "Options.h"
+#include "TextureBrowser.h"
+
+#include "tier2/vconfig.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include <tier0/memdbgon.h>
+
+
+IMPLEMENT_DYNCREATE(COPTConfigs, CPropertyPage)
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns the string value of a registry key
+// Input : *pName - name of the subKey to read
+// *pReturn - string buffer to receive read string
+// size - size of specified buffer
+//-----------------------------------------------------------------------------
+bool GetPersistentEnvironmentVariable( const char *pName, char *pReturn, int size )
+{
+ // Open the key
+ HKEY hregkey;
+ // Changed to HKEY_CURRENT_USER from HKEY_LOCAL_MACHINE
+ if ( RegOpenKeyEx( HKEY_CURRENT_USER, VPROJECT_REG_KEY, 0, KEY_QUERY_VALUE, &hregkey ) != ERROR_SUCCESS )
+ return false;
+
+ // Get the value
+ DWORD dwSize = size;
+ if ( RegQueryValueEx( hregkey, pName, NULL, NULL,(LPBYTE) pReturn, &dwSize ) != ERROR_SUCCESS )
+ return false;
+
+ // Close the key
+ RegCloseKey( hregkey );
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Set the registry entry to a string value, under the given subKey
+// Input : *pName - name of the subKey to set
+// *pValue - string value
+//-----------------------------------------------------------------------------
+void SetPersistentEnvironmentVariable( const char *pName, const char *pValue )
+{
+ HKEY hregkey;
+ DWORD dwReturnValue = 0;
+
+ // Changed from HKEY_LOCAL_MACHINE to HKEY_CURRENT_USER
+ if ( RegOpenKeyEx( HKEY_CURRENT_USER, VPROJECT_REG_KEY, 0, KEY_ALL_ACCESS, &hregkey ) != ERROR_SUCCESS )
+ return;
+
+ // Set the value to the string passed in
+ RegSetValueEx( hregkey, pName, 0, REG_SZ, (const unsigned char *)pValue, (int) strlen(pValue) );
+
+ // Propagate changes so that environment variables takes immediate effect!
+ SendMessageTimeout( HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) "Environment", SMTO_ABORTIFHUNG, 5000, &dwReturnValue );
+
+ // Close the key
+ RegCloseKey( hregkey );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Converts a Steam path prefix to %STEAM% and back.
+//-----------------------------------------------------------------------------
+void EditorUtil_ConvertPath(CString &str, bool bExpand)
+{
+ CString strSteamDir;
+ g_pGameConfig->GetSteamDir(strSteamDir);
+
+ CString strSteamUserDir;
+ g_pGameConfig->GetSteamUserDir(strSteamUserDir);
+
+ if (!strSteamDir.GetLength() && !strSteamUserDir.GetLength())
+ {
+ // Can't do the token replacement.
+ return;
+ }
+
+ const char *szSteamDirToken = "$SteamDir";
+ const char *szSteamUserDirToken = "$SteamUserDir";
+
+ char szPathOut[MAX_PATH];
+
+ if (bExpand)
+ {
+ // Replace the tokens with the full strings
+ if (Q_StrSubst(str, szSteamUserDirToken, strSteamUserDir, szPathOut, sizeof(szPathOut)))
+ {
+ str = szPathOut;
+ }
+
+ if (Q_StrSubst(str, szSteamDirToken, strSteamDir, szPathOut, sizeof(szPathOut)))
+ {
+ str = szPathOut;
+ }
+ }
+ else
+ {
+ // Replace the full strings with the tokens
+ // Go from longest paths to shortest paths to insure the most brief expression.
+ if (Q_StrSubst(str, strSteamUserDir, szSteamUserDirToken, szPathOut, sizeof(szPathOut)))
+ {
+ str = szPathOut;
+ }
+
+ if (Q_StrSubst(str, strSteamDir, szSteamDirToken, szPathOut, sizeof(szPathOut)))
+ {
+ str = szPathOut;
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Exchanges path data between a CString and an edit control, converting
+// the Steam path to %STEAM% and back.
+//-----------------------------------------------------------------------------
+void EditorUtil_TransferPath(CDialog *pDlg, int nIDC, char *szDest, bool bExpand)
+{
+ CWnd *pwnd = pDlg->GetDlgItem(nIDC);
+ if (!pwnd)
+ return;
+
+ CString str;
+
+ if (bExpand)
+ {
+ pwnd->GetWindowText(str);
+ EditorUtil_ConvertPath(str, true);
+ strcpy(szDest, str);
+ }
+ else
+ {
+ str = szDest;
+ EditorUtil_ConvertPath(str, false);
+ pwnd->SetWindowText(str);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor.
+//-----------------------------------------------------------------------------
+COPTConfigs::COPTConfigs(void) : CPropertyPage(COPTConfigs::IDD)
+{
+ //{{AFX_DATA_INIT(COPTConfigs)
+ //}}AFX_DATA_INIT
+
+ m_pLastSelConfig = NULL;
+ m_pInitialSelectedConfig = NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor.
+//-----------------------------------------------------------------------------
+COPTConfigs::~COPTConfigs(void)
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pDX -
+//-----------------------------------------------------------------------------
+void COPTConfigs::DoDataExchange(CDataExchange* pDX)
+{
+ CPropertyPage::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(COPTConfigs)
+ DDX_Control(pDX, IDC_MAPDIR, m_cMapDir);
+ DDX_Control(pDX, IDC_GAMEEXEDIR, m_cGameExeDir);
+ DDX_Control(pDX, IDC_MODDIR, m_cModDir);
+ DDX_Control(pDX, IDC_MAPFORMAT, m_cMapFormat);
+ DDX_Control(pDX, IDC_CORDON_TEXTURE, m_cCordonTexture);
+ DDX_Control(pDX, IDC_TEXTUREFORMAT, m_cTextureFormat);
+ DDX_Control(pDX, IDC_DEFAULTPOINT, m_cDefaultPoint);
+ DDX_Control(pDX, IDC_DEFAULTENTITY, m_cDefaultSolid);
+ DDX_Control(pDX, IDC_DATAFILES, m_cGDFiles);
+ DDX_Control(pDX, IDC_CONFIGURATIONS, m_cConfigs);
+ DDX_Control(pDX, IDC_DEFAULT_TEXTURE_SCALE, m_cDefaultTextureScale);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(COPTConfigs, CPropertyPage)
+ //{{AFX_MSG_MAP(COPTConfigs)
+ ON_BN_CLICKED(IDC_EDITCONFIGS, OnEditconfigs)
+ ON_BN_CLICKED(IDC_GDFILE_ADD, OnGdfileAdd)
+ ON_BN_CLICKED(IDC_GDFILE_EDIT, OnGdfileEdit)
+ ON_BN_CLICKED(IDC_GDFILE_REMOVE, OnGdfileRemove)
+ ON_CBN_SELCHANGE(IDC_CONFIGURATIONS, OnSelchangeConfigurations)
+ ON_BN_CLICKED(IDC_BROWSEMAPDIR, OnBrowsemapdir)
+ ON_BN_CLICKED(IDC_BROWSEGAMEEXEDIR, OnBrowseGameExeDir)
+ ON_BN_CLICKED(IDC_BROWSEMODDIR, OnBrowseModDir)
+ ON_BN_CLICKED(IDC_BROWSE_CORDON_TEXTURE, OnBrowseCordonTexture)
+ ON_MESSAGE( WM_SETTINGCHANGE, OnSettingChange )
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+void COPTConfigs::OnEditconfigs(void)
+{
+ SaveInfo(m_pLastSelConfig);
+
+ CEditGameConfigs dlg;
+ dlg.DoModal();
+ UpdateConfigList();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void COPTConfigs::OnGdfileAdd(void)
+{
+ if (m_pLastSelConfig == NULL)
+ return;
+
+ char szAppDir[MAX_PATH];
+ APP()->GetDirectory(DIR_PROGRAM, szAppDir);
+
+ // browse for .FGD files
+ CFileDialog dlg(TRUE, ".fgd", NULL, OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST, "Game Data Files (*.fgd)|*.fgd||");
+ dlg.m_ofn.lpstrInitialDir = szAppDir;
+ if (dlg.DoModal() != IDOK)
+ return;
+
+ CString str = dlg.GetPathName();
+ EditorUtil_ConvertPath(str, false);
+ m_cGDFiles.AddString(str);
+
+ SaveInfo(m_pLastSelConfig);
+ m_pLastSelConfig->LoadGDFiles();
+ UpdateEntityLists();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void COPTConfigs::OnGdfileEdit(void)
+{
+ if(m_pLastSelConfig == NULL)
+ return;
+
+ // edit the selected FGD file
+ int iCurSel = m_cGDFiles.GetCurSel();
+ if(iCurSel == LB_ERR)
+ return;
+
+ CString str;
+ m_cGDFiles.GetText(iCurSel, str);
+ EditorUtil_ConvertPath(str, true);
+
+ // call editor (notepad!)
+ char szBuf[MAX_PATH];
+ GetWindowsDirectory(szBuf, MAX_PATH);
+ strcat(szBuf, "\\notepad.exe");
+ _spawnl(_P_WAIT, szBuf, szBuf, str, NULL);
+
+ m_pLastSelConfig->LoadGDFiles();
+ UpdateEntityLists();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void COPTConfigs::OnGdfileRemove(void)
+{
+ if(m_pLastSelConfig == NULL)
+ return;
+
+ int iCurSel = m_cGDFiles.GetCurSel();
+ if(iCurSel == LB_ERR)
+ return;
+
+ m_cGDFiles.DeleteString(iCurSel);
+
+ SaveInfo(m_pLastSelConfig);
+ m_pLastSelConfig->LoadGDFiles();
+ UpdateEntityLists();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pConfig -
+//-----------------------------------------------------------------------------
+void COPTConfigs::SaveInfo(CGameConfig *pConfig)
+{
+ if (pConfig == NULL)
+ {
+ return;
+ }
+
+ // game data files
+ pConfig->nGDFiles = 0;
+ pConfig->GDFiles.RemoveAll();
+ int iSize = m_cGDFiles.GetCount();
+ for(int i = 0; i < iSize; i++)
+ {
+ CString str;
+ m_cGDFiles.GetText(i, str);
+
+ EditorUtil_ConvertPath(str, true);
+
+ pConfig->GDFiles.Add(str);
+ ++pConfig->nGDFiles;
+ }
+
+ //
+ // Map file type.
+ //
+ int nIndex = m_cMapFormat.GetCurSel();
+ if (nIndex != CB_ERR)
+ {
+ pConfig->mapformat = (MAPFORMAT)m_cMapFormat.GetItemData(nIndex);
+ }
+ else
+ {
+ pConfig->mapformat = mfHalfLife2;
+ }
+
+ //
+ // WAD file type.
+ //
+ nIndex = m_cTextureFormat.GetCurSel();
+ if (nIndex != CB_ERR)
+ {
+ pConfig->SetTextureFormat((TEXTUREFORMAT)m_cTextureFormat.GetItemData(nIndex));
+ }
+ else
+ {
+ pConfig->SetTextureFormat(tfVMT);
+ }
+
+ m_cDefaultSolid.GetWindowText(pConfig->szDefaultSolid, sizeof pConfig->szDefaultSolid);
+ m_cDefaultPoint.GetWindowText(pConfig->szDefaultPoint, sizeof pConfig->szDefaultPoint);
+
+ EditorUtil_TransferPath(this, IDC_GAMEEXEDIR, pConfig->m_szGameExeDir, true);
+ EditorUtil_TransferPath(this, IDC_MODDIR, pConfig->m_szModDir, true);
+ EditorUtil_TransferPath(this, IDC_MAPDIR, pConfig->szMapDir, true);
+
+ char szCordonTexture[MAX_PATH];
+ m_cCordonTexture.GetWindowText(szCordonTexture, sizeof(szCordonTexture));
+ pConfig->SetCordonTexture(szCordonTexture);
+
+ //
+ // Default texture scale.
+ //
+ char szText[100];
+ m_cDefaultTextureScale.GetWindowText(szText, sizeof(szText));
+ float fScale = (float)atof(szText);
+ if (fScale == 0)
+ {
+ fScale = 1;
+ }
+ pConfig->SetDefaultTextureScale(fScale);
+
+ //
+ // Default lightmap scale.
+ //
+ int nLightmapScale = GetDlgItemInt(IDC_DEFAULT_LIGHTMAP_SCALE, NULL, FALSE);
+ pConfig->SetDefaultLightmapScale(nLightmapScale);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void COPTConfigs::OnSelchangeConfigurations(void)
+{
+ // save info from controls into last selected config
+ SaveInfo(m_pLastSelConfig);
+
+ m_pLastSelConfig = NULL;
+
+ // load info from newly selected config into controls
+ int iCurSel = m_cConfigs.GetCurSel();
+ CGameConfig *pConfig = Options.configs.FindConfig(m_cConfigs.GetItemData(iCurSel));
+
+ BOOL bKillFields = FALSE;
+ if (pConfig == NULL)
+ {
+ bKillFields = TRUE;
+ }
+
+ m_cGDFiles.EnableWindow(!bKillFields);
+ m_cDefaultPoint.EnableWindow(!bKillFields);
+ m_cDefaultSolid.EnableWindow(!bKillFields);
+ m_cTextureFormat.EnableWindow(!bKillFields);
+ m_cMapFormat.EnableWindow(!bKillFields);
+ m_cGameExeDir.EnableWindow(!bKillFields);
+ m_cModDir.EnableWindow(!bKillFields);
+ m_cMapDir.EnableWindow(!bKillFields);
+ m_cCordonTexture.EnableWindow(!bKillFields);
+
+ if (pConfig == NULL)
+ {
+ return;
+ }
+
+ m_pLastSelConfig = pConfig;
+
+ // load game data files
+ m_cGDFiles.ResetContent();
+ for (int i = 0; i < pConfig->nGDFiles; i++)
+ {
+ CString str(pConfig->GDFiles[i]);
+ EditorUtil_ConvertPath(str, false);
+ m_cGDFiles.AddString(str);
+ }
+
+ //
+ // Select the correct map format.
+ //
+ m_cMapFormat.SetCurSel(0);
+ int nItems = m_cMapFormat.GetCount();
+ for (int i = 0; i < nItems; i++)
+ {
+ if (pConfig->mapformat == (MAPFORMAT)m_cMapFormat.GetItemData(i))
+ {
+ m_cMapFormat.SetCurSel(i);
+ break;
+ }
+ }
+
+ //
+ // Select the correct texture format.
+ //
+ m_cTextureFormat.SetCurSel(0);
+ nItems = m_cTextureFormat.GetCount();
+ for (int i = 0; i < nItems; i++)
+ {
+ if (pConfig->GetTextureFormat() == (TEXTUREFORMAT)m_cTextureFormat.GetItemData(i))
+ {
+ m_cTextureFormat.SetCurSel(i);
+ break;
+ }
+ }
+
+ EditorUtil_TransferPath(this, IDC_GAMEEXEDIR, pConfig->m_szGameExeDir, false);
+ EditorUtil_TransferPath(this, IDC_MODDIR, pConfig->m_szModDir, false);
+ EditorUtil_TransferPath(this, IDC_MAPDIR, pConfig->szMapDir, false);
+
+ m_cCordonTexture.SetWindowText(pConfig->GetCordonTexture());
+
+ char szText[100];
+ sprintf(szText, "%g", pConfig->GetDefaultTextureScale());
+ m_cDefaultTextureScale.SetWindowText(szText);
+
+ SetDlgItemInt(IDC_DEFAULT_LIGHTMAP_SCALE, pConfig->GetDefaultLightmapScale(), FALSE);
+
+ // load entity type comboboxes and set strings
+ UpdateEntityLists();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void COPTConfigs::UpdateEntityLists(void)
+{
+ if(m_pLastSelConfig == NULL)
+ return;
+
+ m_cDefaultPoint.ResetContent();
+ m_cDefaultSolid.ResetContent();
+
+ CGameConfig *pConfig = m_pLastSelConfig;
+
+ int nCount = pConfig->GD.GetClassCount();
+ for (int i = 0; i < nCount; i++)
+ {
+ GDclass *pClass = pConfig->GD.GetClass(i);
+ if (pClass->IsBaseClass())
+ {
+ continue;
+ }
+ else if (pClass->IsSolidClass())
+ {
+ m_cDefaultSolid.AddString(pClass->GetName());
+ }
+ else
+ {
+ m_cDefaultPoint.AddString(pClass->GetName());
+ }
+ }
+
+ if (pConfig->szDefaultSolid[0] != '\0')
+ {
+ m_cDefaultSolid.SetWindowText(pConfig->szDefaultSolid);
+ }
+ else
+ {
+ m_cDefaultSolid.SetCurSel(0);
+ }
+
+
+ if (pConfig->szDefaultPoint[0] != '\0')
+ {
+ m_cDefaultPoint.SetWindowText(pConfig->szDefaultPoint);
+ }
+ else
+ {
+ m_cDefaultPoint.SetCurSel(0);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Fills the combo box with the list of configs. Tries to select the
+// config that was selected before coming in or, failing that, the
+// currently active config.
+//-----------------------------------------------------------------------------
+void UpdateConfigList(CComboBox &combo)
+{
+ int iCurSel = combo.GetCurSel();
+ DWORD dwSelID = 0xffffffff;
+ if (iCurSel != CB_ERR)
+ {
+ dwSelID = combo.GetItemData(iCurSel);
+ }
+
+ combo.ResetContent();
+
+ // add configs to the combo box
+ for (int i = 0; i < Options.configs.nConfigs; i++)
+ {
+ CGameConfig *pConfig = Options.configs.Configs[i];
+
+ int iIndex = combo.AddString(pConfig->szName);
+ combo.SetItemData(iIndex, pConfig->dwID);
+ }
+
+ if (dwSelID == 0xffffffff)
+ {
+ dwSelID = g_pGameConfig->dwID;
+ }
+
+ // Find the item with the given ID.
+ int nSelIndex = -1;
+ for (int i = 0; i < Options.configs.nConfigs; i++)
+ {
+ DWORD dwData = combo.GetItemData(i);
+ if (dwData == dwSelID)
+ {
+ nSelIndex = i;
+ }
+ }
+
+ combo.SetCurSel(nSelIndex == -1 ? 0 : nSelIndex);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void SelectActiveConfig(CComboBox &combo)
+{
+ char szGameDir[MAX_PATH];
+ if (GetPersistentEnvironmentVariable(GAMEDIR_TOKEN, szGameDir, sizeof(szGameDir)))
+ {
+ CGameConfig *pConfig = Options.configs.FindConfigForGame(szGameDir);
+ if (pConfig)
+ {
+ // Find the item with the given ID.
+ int nSelIndex = -1;
+ int nCount = combo.GetCount();
+ for (int i = 0; i < nCount; i++)
+ {
+ DWORD dwData = combo.GetItemData(i);
+ if (pConfig->dwID == dwData)
+ {
+ nSelIndex = i;
+ break;
+ }
+ }
+
+ if (nSelIndex != -1)
+ {
+ combo.SetCurSel(nSelIndex);
+ }
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void COPTConfigs::UpdateConfigList()
+{
+ m_pLastSelConfig = NULL;
+
+ ::UpdateConfigList(m_cConfigs);
+ ::SelectActiveConfig(m_cConfigs);
+
+ OnSelchangeConfigurations();
+ SetModified();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Populates the combo boxes with the map formats and WAD formats, and
+// the list of game configurations.
+//-----------------------------------------------------------------------------
+BOOL COPTConfigs::OnInitDialog(void)
+{
+ CPropertyPage::OnInitDialog();
+
+ int nIndex;
+
+ //
+ // Add map formats.
+ //
+ nIndex = m_cMapFormat.AddString("Half-Life 2");
+ m_cMapFormat.SetItemData(nIndex, mfHalfLife2);
+
+ nIndex = m_cMapFormat.AddString("Half-Life / TFC");
+ m_cMapFormat.SetItemData(nIndex, mfHalfLife);
+
+ //
+ // Add texture formats.
+ //
+ nIndex = m_cTextureFormat.AddString("Materials (Half-Life 2)");
+ m_cTextureFormat.SetItemData(nIndex, tfVMT);
+
+ nIndex = m_cTextureFormat.AddString("WAD3 (Half-Life / TFC)");
+ m_cTextureFormat.SetItemData(nIndex, tfWAD3);
+
+ UpdateConfigList();
+
+ int nCurSel = m_cConfigs.GetCurSel();
+ m_pInitialSelectedConfig = Options.configs.FindConfig(m_cConfigs.GetItemData(nCurSel));
+
+ m_strInitialGameDir.Empty();
+ if (m_pInitialSelectedConfig)
+ {
+ m_strInitialGameDir = m_pInitialSelectedConfig->m_szModDir;
+ }
+
+ return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns true if the given config is different from the one set when
+// OnInitDialog was called.
+//-----------------------------------------------------------------------------
+bool COPTConfigs::ConfigChanged(CGameConfig *pConfig)
+{
+ if (m_pInitialSelectedConfig != pConfig)
+ return true;
+
+ if (pConfig && m_pInitialSelectedConfig)
+ {
+ if (m_pInitialSelectedConfig->dwID != pConfig->dwID)
+ return true;
+
+ if (m_strInitialGameDir.CompareNoCase(pConfig->m_szModDir))
+ return true;
+ }
+
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns TRUE on success, FALSE on failure.
+//-----------------------------------------------------------------------------
+BOOL COPTConfigs::OnApply(void)
+{
+ SaveInfo(m_pLastSelConfig);
+
+ int nCurSel = m_cConfigs.GetCurSel();
+ CGameConfig *pConfig = Options.configs.FindConfig(m_cConfigs.GetItemData(nCurSel));
+
+ if ( pConfig != NULL && ConfigChanged( pConfig ) )
+ {
+ SetPersistentEnvironmentVariable("vproject", pConfig->m_szModDir);
+ AfxMessageBox("Your changes to the active configuration will not take effect until the next time you run Hammer.");
+ }
+
+ Options.PerformChanges(COptions::secConfigs);
+
+ return CPropertyPage::OnApply();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pszTitle -
+// *pszDirectory -
+// Output : Returns TRUE on success, FALSE on failure.
+//-----------------------------------------------------------------------------
+BOOL COPTConfigs::BrowseForFolder(char *pszTitle, char *pszDirectory)
+{
+ char szTmp[MAX_PATH];
+
+ BROWSEINFO bi;
+ memset(&bi, 0, sizeof bi);
+ bi.hwndOwner = m_hWnd;
+ bi.pszDisplayName = szTmp;
+ bi.lpszTitle = pszTitle;
+ bi.ulFlags = BIF_RETURNONLYFSDIRS;
+
+ LPITEMIDLIST idl = SHBrowseForFolder(&bi);
+
+ if(idl == NULL)
+ return FALSE;
+
+ SHGetPathFromIDList(idl, pszDirectory);
+ CoTaskMemFree(idl);
+
+ return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void COPTConfigs::OnBrowseCordonTexture(void)
+{
+ CTextureBrowser *pBrowser = new CTextureBrowser(this);
+ if (pBrowser != NULL)
+ {
+ //
+ // Use the currently selected texture format for browsing.
+ //
+ TEXTUREFORMAT eTextureFormat = tfVMT;
+ int nIndex = m_cTextureFormat.GetCurSel();
+ if (nIndex != LB_ERR)
+ {
+ eTextureFormat = (TEXTUREFORMAT)m_cTextureFormat.GetItemData(nIndex);
+ }
+ pBrowser->SetTextureFormat(eTextureFormat);
+
+ //
+ // Select the current cordon texture in the texture browser.
+ //
+ CString strTex;
+ m_cCordonTexture.GetWindowText(strTex);
+ pBrowser->SetInitialTexture(strTex);
+
+ if (pBrowser->DoModal() == IDOK)
+ {
+ m_cCordonTexture.SetWindowText(pBrowser->m_cTextureWindow.szCurTexture);
+ }
+
+ delete pBrowser;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void COPTConfigs::OnBrowseGameExeDir(void)
+{
+ char szTmp[MAX_PATH];
+ if (!BrowseForFolder("Select Game Executable Directory", szTmp))
+ {
+ return;
+ }
+
+ CString str(szTmp);
+ EditorUtil_ConvertPath(str, false);
+ m_cGameExeDir.SetWindowText(str);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void COPTConfigs::OnBrowseModDir(void)
+{
+ char szTmp[MAX_PATH];
+ if (!BrowseForFolder("Select Mod Directory", szTmp))
+ {
+ return;
+ }
+
+ CString str(szTmp);
+ EditorUtil_ConvertPath(str, false);
+ m_cModDir.SetWindowText(str);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void COPTConfigs::OnBrowsemapdir(void)
+{
+ char szTmp[MAX_PATH];
+ if (!BrowseForFolder("Select Map Directory", szTmp))
+ {
+ return;
+ }
+
+ CString str(szTmp);
+ EditorUtil_ConvertPath(str, false);
+ m_cMapDir.SetWindowText(str);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the notification from the VCONFIG that the active config has changed.
+//-----------------------------------------------------------------------------
+LRESULT COPTConfigs::OnSettingChange(WPARAM wParam, LPARAM lParam)
+{
+ const char *changedSection = (const char *)lParam;
+ if ( Q_stricmp( changedSection, "Environment" ) == 0 )
+ {
+ UpdateConfigList();
+ //SelectActiveConfig();
+ }
+
+ return 0;
+}
+
+