summaryrefslogtreecommitdiff
path: root/hammer/gameconfig.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/gameconfig.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'hammer/gameconfig.cpp')
-rw-r--r--hammer/gameconfig.cpp622
1 files changed, 622 insertions, 0 deletions
diff --git a/hammer/gameconfig.cpp b/hammer/gameconfig.cpp
new file mode 100644
index 0000000..85b9859
--- /dev/null
+++ b/hammer/gameconfig.cpp
@@ -0,0 +1,622 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#include "stdafx.h"
+#include <direct.h>
+#include <io.h>
+#include <WorldSize.h>
+#include "Gameconfig.h"
+#include "GlobalFunctions.h"
+#include "fgdlib/HelperInfo.h"
+#include "hammer.h"
+#include "KeyValues.h"
+#include "MapDoc.h"
+#include "MapDoc.h"
+#include "MapEntity.h"
+#include "MapInstance.h"
+#include "MapWorld.h"
+#include "filesystem_tools.h"
+#include "TextureSystem.h"
+#include "tier1/strtools.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#pragma warning(disable:4244)
+
+
+const int MAX_ERRORS = 5;
+
+
+GameData *pGD;
+CGameConfig g_DefaultGameConfig;
+CGameConfig *g_pGameConfig = &g_DefaultGameConfig;
+
+
+float g_MAX_MAP_COORD = 4096;
+float g_MIN_MAP_COORD = -4096;
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CGameConfig *CGameConfig::GetActiveGame(void)
+{
+ return g_pGameConfig;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pGame -
+//-----------------------------------------------------------------------------
+void CGameConfig::SetActiveGame(CGameConfig *pGame)
+{
+ if (pGame != NULL)
+ {
+ g_pGameConfig = pGame;
+ pGD = &pGame->GD;
+
+ if (pGame->mapformat == mfHalfLife)
+ {
+ g_MAX_MAP_COORD = 4096;
+ g_MIN_MAP_COORD = -4096;
+ }
+ else
+ {
+ g_MAX_MAP_COORD = pGD->GetMaxMapCoord();
+ g_MIN_MAP_COORD = pGD->GetMinMapCoord();
+ }
+ }
+ else
+ {
+ g_pGameConfig = &g_DefaultGameConfig;
+ pGD = NULL;
+
+ g_MAX_MAP_COORD = 4096;
+ g_MIN_MAP_COORD = -4096;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor. Maintains a static counter uniquely identifying each
+// game configuration.
+//-----------------------------------------------------------------------------
+CGameConfig::CGameConfig(void)
+{
+ nGDFiles = 0;
+ textureformat = tfNone;
+ m_fDefaultTextureScale = DEFAULT_TEXTURE_SCALE;
+ m_nDefaultLightmapScale = DEFAULT_LIGHTMAP_SCALE;
+ m_MaterialExcludeCount = 0;
+
+ memset(szName, 0, sizeof(szName));
+ memset(szExecutable, 0, sizeof(szExecutable));
+ memset(szDefaultPoint, 0, sizeof(szDefaultPoint));
+ memset(szDefaultSolid, 0, sizeof(szDefaultSolid));
+ memset(szBSP, 0, sizeof(szBSP));
+ memset(szLIGHT, 0, sizeof(szLIGHT));
+ memset(szVIS, 0, sizeof(szVIS));
+ memset(szMapDir, 0, sizeof(szMapDir));
+ memset(m_szGameExeDir, 0, sizeof(m_szGameExeDir));
+ memset(szBSPDir, 0, sizeof(szBSPDir));
+ memset(m_szModDir, 0, sizeof(m_szModDir));
+ strcpy(m_szCordonTexture, "BLACK");
+
+ m_szSteamDir[0] = '\0';
+ m_szSteamAppID[0] = '\0';
+
+ static DWORD __dwID = 0;
+ dwID = __dwID++;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Imports an old binary GameCfg.wc file.
+// Input : file -
+// fVersion -
+// Output : Returns TRUE on success, FALSE on failure.
+//-----------------------------------------------------------------------------
+BOOL CGameConfig::Import(std::fstream& file, float fVersion)
+{
+ file.read(szName, sizeof szName);
+ file.read((char*)&nGDFiles, sizeof nGDFiles);
+ file.read((char*)&textureformat, sizeof textureformat);
+
+ if (fVersion >= 1.1f)
+ {
+ file.read((char*)&mapformat, sizeof mapformat);
+ }
+ else
+ {
+ mapformat = mfQuake;
+ }
+
+ //
+ // If reading an old (pre 1.4) format file, skip past the obselete palette
+ // file path.
+ //
+ if (fVersion < 1.4f)
+ {
+ char szPalette[128];
+ file.read(szPalette, sizeof szPalette);
+ }
+
+ file.read(szExecutable, sizeof szExecutable);
+ file.read(szDefaultSolid, sizeof szDefaultSolid);
+ file.read(szDefaultPoint, sizeof szDefaultPoint);
+
+ if (fVersion >= 1.2f)
+ {
+ file.read(szBSP, sizeof szBSP);
+ file.read(szLIGHT, sizeof szLIGHT);
+ file.read(szVIS, sizeof szVIS);
+ file.read(m_szGameExeDir, sizeof m_szGameExeDir);
+ file.read(szMapDir, sizeof szMapDir);
+ }
+
+ if (fVersion >= 1.3f)
+ {
+ file.read(szBSPDir, sizeof(szBSPDir));
+ }
+
+ if (fVersion >= 1.4f)
+ {
+ // CSG setting is gone now.
+ char szTempCSG[128];
+ file.read(szTempCSG, sizeof(szTempCSG));
+
+ file.read(m_szModDir, sizeof(m_szModDir));
+
+ // gamedir is gone now.
+ char tempGameDir[128];
+ file.read(tempGameDir, sizeof(tempGameDir));
+ }
+
+ // read game data files
+ char szBuf[128];
+ for(int i = 0; i < nGDFiles; i++)
+ {
+ file.read(szBuf, sizeof szBuf);
+ GDFiles.Add(CString(szBuf));
+ }
+
+ LoadGDFiles();
+
+ return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Loads this game configuration from a keyvalue block.
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CGameConfig::Load(KeyValues *pkv)
+{
+ char szKey[MAX_PATH];
+
+ // We should at least be able to get the game name and the game dir.
+ Q_strncpy(szName, pkv->GetName(), sizeof(szName));
+ Q_strncpy(m_szModDir, pkv->GetString("GameDir"), sizeof(m_szModDir));
+
+ // Try to get the Hammer settings.
+ KeyValues *pkvHammer = pkv->FindKey("Hammer");
+ if (!pkvHammer)
+ return true;
+
+ //
+ // Load the game data filenames from the "GameData0..GameDataN" keys.
+ //
+ nGDFiles = 0;
+ bool bAdded = true;
+ do
+ {
+ sprintf(szKey, "GameData%d", nGDFiles);
+ const char *pszGameData = pkvHammer->GetString(szKey);
+ if (pszGameData[0] != '\0')
+ {
+ GDFiles.Add(pszGameData);
+ nGDFiles++;
+ }
+ else
+ {
+ bAdded = false;
+ }
+
+ } while (bAdded);
+
+ textureformat = (TEXTUREFORMAT)pkvHammer->GetInt("TextureFormat", tfVMT);
+ mapformat = (MAPFORMAT)pkvHammer->GetInt("MapFormat", mfHalfLife2);
+
+ m_fDefaultTextureScale = pkvHammer->GetFloat("DefaultTextureScale", DEFAULT_TEXTURE_SCALE);
+ if (m_fDefaultTextureScale == 0)
+ {
+ m_fDefaultTextureScale = DEFAULT_TEXTURE_SCALE;
+ }
+
+ m_nDefaultLightmapScale = pkvHammer->GetInt("DefaultLightmapScale", DEFAULT_LIGHTMAP_SCALE);
+
+ Q_strncpy(szExecutable, pkvHammer->GetString("GameExe"), sizeof(szExecutable));
+ Q_strncpy(szDefaultSolid, pkvHammer->GetString("DefaultSolidEntity"), sizeof(szDefaultSolid));
+ Q_strncpy(szDefaultPoint, pkvHammer->GetString("DefaultPointEntity"), sizeof(szDefaultPoint));
+
+ Q_strncpy(szBSP, pkvHammer->GetString("BSP"), sizeof(szBSP));
+ Q_strncpy(szVIS, pkvHammer->GetString("Vis"), sizeof(szVIS));
+ Q_strncpy(szLIGHT, pkvHammer->GetString("Light"), sizeof(szLIGHT));
+ Q_strncpy(m_szGameExeDir, pkvHammer->GetString("GameExeDir"), sizeof(m_szGameExeDir));
+ Q_strncpy(szMapDir, pkvHammer->GetString("MapDir"), sizeof(szMapDir));
+ Q_strncpy(szBSPDir, pkvHammer->GetString("BSPDir"), sizeof(szBSPDir));
+
+ SetCordonTexture( pkvHammer->GetString("CordonTexture", "BLACK") );
+
+ char szExcludeDir[MAX_PATH];
+ m_MaterialExcludeCount = pkvHammer->GetInt( "MaterialExcludeCount" );
+ for ( int i = 0; i < m_MaterialExcludeCount; i++ )
+ {
+ sprintf( szExcludeDir, "-MaterialExcludeDir%d", i );
+ int index = m_MaterialExclusions.AddToTail();
+ Q_strncpy( m_MaterialExclusions[index].szDirectory, pkvHammer->GetString( szExcludeDir ), sizeof( m_MaterialExclusions[index].szDirectory ) );
+ Q_StripTrailingSlash( m_MaterialExclusions[index].szDirectory );
+ m_MaterialExclusions[index].bUserGenerated = true;
+ }
+
+ LoadGDFiles();
+
+ return(true);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Saves this config's data into a keyvalues object.
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CGameConfig::Save(KeyValues *pkv)
+{
+ pkv->SetName(szName);
+ pkv->SetString("GameDir", m_szModDir);
+
+
+ // Try to get the Hammer settings.
+ KeyValues *pkvHammer = pkv->FindKey("Hammer");
+ if (pkvHammer)
+ {
+ pkv->RemoveSubKey(pkvHammer);
+ pkvHammer->deleteThis();
+ }
+
+ pkvHammer = pkv->CreateNewKey();
+ if (!pkvHammer)
+ return false;
+
+ pkvHammer->SetName("Hammer");
+
+ //
+ // Load the game data filenames from the "GameData0..GameDataN" keys.
+ //
+ for (int i = 0; i < nGDFiles; i++)
+ {
+ char szKey[MAX_PATH];
+ sprintf(szKey, "GameData%d", i);
+ pkvHammer->SetString(szKey, GDFiles.GetAt(i));
+ }
+
+ pkvHammer->SetInt("TextureFormat", textureformat);
+ pkvHammer->SetInt("MapFormat", mapformat);
+ pkvHammer->SetFloat("DefaultTextureScale", m_fDefaultTextureScale);
+ pkvHammer->SetInt("DefaultLightmapScale", m_nDefaultLightmapScale);
+
+ pkvHammer->SetString("GameExe", szExecutable);
+ pkvHammer->SetString("DefaultSolidEntity", szDefaultSolid);
+ pkvHammer->SetString("DefaultPointEntity", szDefaultPoint);
+
+ pkvHammer->SetString("BSP", szBSP);
+ pkvHammer->SetString("Vis", szVIS);
+ pkvHammer->SetString("Light", szLIGHT);
+ pkvHammer->SetString("GameExeDir", m_szGameExeDir);
+ pkvHammer->SetString("MapDir", szMapDir);
+ pkvHammer->SetString("BSPDir", szBSPDir);
+
+ pkvHammer->SetString("CordonTexture", m_szCordonTexture);
+
+ char szExcludeDir[MAX_PATH];
+ pkvHammer->SetInt("MaterialExcludeCount", m_MaterialExcludeCount);
+ for (int i = 0; i < m_MaterialExcludeCount; i++)
+ {
+ sprintf(szExcludeDir, "-MaterialExcludeDir%d", i );
+ pkvHammer->SetString(szExcludeDir, m_MaterialExclusions[i].szDirectory);
+ }
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : file -
+//-----------------------------------------------------------------------------
+void CGameConfig::Save(std::fstream &file)
+{
+ file.write(szName, sizeof szName);
+ file.write((char*)&nGDFiles, sizeof nGDFiles);
+ file.write((char*)&textureformat, sizeof textureformat);
+ file.write((char*)&mapformat, sizeof mapformat);
+ file.write(szExecutable, sizeof szExecutable);
+ file.write(szDefaultSolid, sizeof szDefaultSolid);
+ file.write(szDefaultPoint, sizeof szDefaultPoint);
+
+ // 1.2
+ file.write(szBSP, sizeof szBSP);
+ file.write(szLIGHT, sizeof szLIGHT);
+ file.write(szVIS, sizeof szVIS);
+ file.write(m_szGameExeDir, sizeof(m_szGameExeDir));
+ file.write(szMapDir, sizeof szMapDir);
+
+ // 1.3
+ file.write(szBSPDir, sizeof szBSPDir);
+
+ // 1.4
+ char tempCSG[128] = "";
+ file.write(tempCSG, sizeof(tempCSG));
+
+ file.write(m_szModDir, sizeof(m_szModDir));
+
+ char tempGameDir[128] = "";
+ file.write(tempGameDir, sizeof(tempGameDir));
+
+ // write game data files
+ char szBuf[128];
+ for(int i = 0; i < nGDFiles; i++)
+ {
+ strcpy(szBuf, GDFiles[i]);
+ file.write(szBuf, sizeof szBuf);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pConfig -
+//-----------------------------------------------------------------------------
+void CGameConfig::CopyFrom(CGameConfig *pConfig)
+{
+ nGDFiles = pConfig->nGDFiles;
+
+ GDFiles.RemoveAll();
+ GDFiles.Append(pConfig->GDFiles);
+
+ strcpy(szName, pConfig->szName);
+ strcpy(szExecutable, pConfig->szExecutable);
+ strcpy(szDefaultPoint, pConfig->szDefaultPoint);
+ strcpy(szDefaultSolid, pConfig->szDefaultSolid);
+ strcpy(szBSP, pConfig->szBSP);
+ strcpy(szLIGHT, pConfig->szLIGHT);
+ strcpy(szVIS, pConfig->szVIS);
+ strcpy(szMapDir, pConfig->szMapDir);
+ strcpy(m_szGameExeDir, pConfig->m_szGameExeDir);
+ strcpy(szBSPDir, pConfig->szBSPDir);
+ strcpy(m_szModDir, pConfig->m_szModDir);
+
+ pConfig->m_MaterialExcludeCount = m_MaterialExcludeCount;
+ for( int i = 0; i < m_MaterialExcludeCount; i++ )
+ {
+ strcpy( m_MaterialExclusions[i].szDirectory, pConfig->m_MaterialExclusions[i].szDirectory );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pEntity -
+// pGD -
+// Output : Returns TRUE to keep enumerating.
+//-----------------------------------------------------------------------------
+static BOOL UpdateClassPointer(CMapEntity *pEntity, GameData *pGDIn)
+{
+ GDclass *pClass = pGDIn->ClassForName(pEntity->GetClassName());
+ pEntity->SetClass(pClass);
+ return(TRUE);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CGameConfig::LoadGDFiles(void)
+{
+ GD.ClearData();
+
+ // Save the old working directory
+ char szOldDir[MAX_PATH];
+ _getcwd( szOldDir, sizeof(szOldDir) );
+
+ // Set our working directory properly
+ char szAppDir[MAX_PATH];
+ APP()->GetDirectory( DIR_PROGRAM, szAppDir );
+ _chdir( szAppDir );
+
+ for (int i = 0; i < nGDFiles; i++)
+ {
+ GD.Load(GDFiles[i]);
+ }
+
+ // Reset our old working directory
+ _chdir( szOldDir );
+
+ // All the class pointers have changed - now we have to
+ // reset all the class pointers in each map doc that
+ // uses this game.
+ for ( int i=0; i<CMapDoc::GetDocumentCount(); i++ )
+ {
+ CMapDoc *pDoc = CMapDoc::GetDocument(i);
+
+ if (pDoc->GetGame() == this)
+ {
+ CMapWorld *pWorld = pDoc->GetMapWorld();
+ pWorld->SetClass(GD.ClassForName(pWorld->GetClassName()));
+ pWorld->EnumChildren((ENUMMAPCHILDRENPROC)UpdateClassPointer, (DWORD)&GD, MAPCLASS_TYPE(CMapEntity));
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Searches for the given filename, starting in szStartDir and looking
+// up the directory tree.
+// Input: szFile - the name of the file to search for.
+// szStartDir - the folder to start searching from, towards the root.
+// szFoundPath - receives the full path of the FOLDER where szFile was found.
+// Output : Returns true if the file was found, false if not. If the file was
+// found the full path (not including the filename) is returned in szFoundPath.
+//-----------------------------------------------------------------------------
+bool FindFileInTree(const char *szFile, const char *szStartDir, char *szFoundPath)
+{
+ if ((szFile == NULL) || (szStartDir == NULL) || (szFoundPath == NULL))
+ {
+ return false;
+ }
+
+ char szRoot[MAX_PATH];
+ strcpy(szRoot, szStartDir);
+ Q_AppendSlash(szRoot, sizeof(szRoot));
+
+ char szTemp[MAX_PATH];
+ do
+ {
+ strcpy(szTemp, szRoot);
+ strcat(szTemp, szFile);
+
+ if (!_access(szTemp, 0))
+ {
+ strcpy(szFoundPath, szRoot);
+ Q_StripTrailingSlash(szFoundPath);
+ return true;
+ }
+
+ } while (Q_StripLastDir(szRoot, sizeof(szRoot)));
+
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *szDir -
+// *szSteamDir -
+// *szSteamUserDir -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool FindSteamUserDir(const char *szAppDir, const char *szSteamDir, char *szSteamUserDir)
+{
+ if ((szAppDir == NULL) || (szSteamDir == NULL) || (szSteamUserDir == NULL))
+ {
+ return false;
+ }
+
+ // If the szAppDir was run from within the steam tree, we should be able to find the steam user dir.
+ int nSteamDirLen = strlen(szSteamDir);
+ if (!Q_strnicmp(szAppDir, szSteamDir, nSteamDirLen ) && (szAppDir[nSteamDirLen] == '\\'))
+ {
+ strcpy(szSteamUserDir, szAppDir);
+
+ char *pszSlash = strchr(&szSteamUserDir[nSteamDirLen + 1], '\\');
+ if (pszSlash)
+ {
+ pszSlash++;
+
+ pszSlash = strchr(pszSlash, '\\');
+ if (pszSlash)
+ {
+ *pszSlash = '\0';
+ return true;
+ }
+ }
+ }
+
+ szSteamUserDir[0] = '\0';
+
+ return false;
+}
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgoff.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: Loads the settings from <mod dir>\gameinfo.txt into data members.
+//-----------------------------------------------------------------------------
+void CGameConfig::ParseGameInfo()
+{
+ KeyValues *pkv = new KeyValues("gameinfo.txt");
+ if (!pkv->LoadFromFile(g_pFileSystem, "gameinfo.txt", "GAME"))
+ {
+ pkv->deleteThis();
+ return;
+ }
+
+ KeyValues *pKey = pkv->FindKey("FileSystem");
+ if (pKey)
+ {
+ V_strcpy_safe( m_szSteamAppID, pKey->GetString( "SteamAppId", "" ) );
+ }
+
+ const char *InstancePath = pkv->GetString( "InstancePath", NULL );
+ if ( InstancePath )
+ {
+ CMapInstance::SetInstancePath( InstancePath );
+ }
+
+ pkv->deleteThis();
+
+ char szAppDir[MAX_PATH];
+ APP()->GetDirectory(DIR_PROGRAM, szAppDir);
+ if (!FindFileInTree("steam.exe", szAppDir, m_szSteamDir))
+ {
+ // Couldn't find steam.exe in the hammer tree
+ m_szSteamDir[0] = '\0';
+ }
+
+ if (!FindSteamUserDir(szAppDir, m_szSteamDir, m_szSteamUserDir))
+ {
+ m_szSteamUserDir[0] = '\0';
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Accessor methods to get at the mod + the game (*not* full paths)
+//-----------------------------------------------------------------------------
+const char *CGameConfig::GetMod()
+{
+ // Strip path from modDir
+ char szModPath[MAX_PATH];
+ static char szMod[MAX_PATH];
+ Q_strncpy( szModPath, m_szModDir, MAX_PATH );
+ Q_StripTrailingSlash( szModPath );
+ if ( !szModPath[0] )
+ {
+ Q_strcpy( szModPath, "hl2" );
+ }
+
+ Q_FileBase( szModPath, szMod, MAX_PATH );
+
+ return szMod;
+}
+
+const char *CGameConfig::GetGame()
+{
+ return "hl2";
+
+// // Strip path from modDir
+// char szGamePath[MAX_PATH];
+// static char szGame[MAX_PATH];
+// Q_strncpy( szGamePath, m_szGameDir, MAX_PATH );
+// Q_StripTrailingSlash( szGamePath );
+// Q_FileBase( szGamePath, szGame, MAX_PATH );
+
+// return szGame;
+}
+
+