From 1dede60c5c498beb2960be83dd6716534af7b7a5 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 6 Dec 2007 19:15:07 +0000 Subject: [PATCH] - New: On Windows, the game now checks the registry to see if you have Steam installed. If so, it checks your SteamApps directory for any IWADs you may have purchased through Steam and adds any it finds to the list of available IWADs you can play. This means that if you bought your id games through Steam, you can just extract ZDoom anywhere you like and run it without doing any additional setup. SVN r581 (trunk) --- docs/rh-log.txt | 6 ++++++ src/d_main.cpp | 22 +++++++++++++++++++++- src/win32/i_system.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/win32/i_system.h | 4 ++++ src/zstring.cpp | 9 +++++++++ src/zstring.h | 4 ++++ 6 files changed, 86 insertions(+), 1 deletion(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index d3674bbd2..f79685aa8 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,10 @@ December 6, 2007 +- New: On Windows, the game now checks the registry to see if you have Steam + installed. If so, it checks your SteamApps directory for any IWADs you may + have purchased through Steam and adds any it finds to the list of available + IWADs you can play. This means that if you bought your id games through + Steam, you can just extract ZDoom anywhere you like and run it without doing + any additional setup. - Fixed: The FLAC/makefile.mgw should use md5.o as an OBJ, not md5.c. - Fixed: The Linux makefile probably shouldn't be using the bundled zlib headers, either. diff --git a/src/d_main.cpp b/src/d_main.cpp index ec3369af4..734f4dd89 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1629,6 +1629,26 @@ static EIWADType IdentifyVersion (const char *zdoom_wad) } } } +#ifdef _WIN32 + FString steam_path = I_GetSteamPath(); + if (steam_path.IsNotEmpty()) + { + static const char *const steam_dirs[] = + { + "doom 2/base", + "final doom/base", + "heretic shadow of the serpent riders/base", + "hexen/base", + "hexen deathkings of the dark citadel/base", + "ultimate doom/base" + }; + steam_path += "/SteamApps/common/"; + for (i = 0; i < countof(steam_dirs); ++i) + { + CheckIWAD (steam_path + steam_dirs[i], wads); + } + } +#endif } if (iwadparm != NULL && !wads[0].Path.IsEmpty()) @@ -1636,7 +1656,7 @@ static EIWADType IdentifyVersion (const char *zdoom_wad) iwadparmfound = true; } - for (i = numwads = 0; i < sizeof(IWADNames)/sizeof(char *); i++) + for (i = numwads = 0; i < countof(IWADNames); i++) { if (!wads[i].Path.IsEmpty()) { diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 10850eb81..bdb4fd0c4 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -793,3 +793,45 @@ int I_FindClose (void *handle) { return FindClose ((HANDLE)handle); } + +static bool QueryPathKey(HKEY key, const char *keypath, const char *valname, FString &value) +{ + HKEY steamkey; + DWORD pathtype; + DWORD pathlen; + LONG res; + + if(ERROR_SUCCESS == RegOpenKeyEx(key, keypath, 0, KEY_QUERY_VALUE, &steamkey)) + { + if (ERROR_SUCCESS == RegQueryValueEx(steamkey, valname, 0, &pathtype, NULL, &pathlen) && + pathtype == REG_SZ && pathlen != 0) + { + // Don't include terminating null in count + char *chars = value.LockNewBuffer(pathlen - 1); + res = RegQueryValueEx(steamkey, valname, 0, NULL, (LPBYTE)chars, &pathlen); + value.UnlockBuffer(); + if (res != ERROR_SUCCESS) + { + value = ""; + } + } + RegCloseKey(steamkey); + } + return value.IsNotEmpty(); +} + +FString I_GetSteamPath() +{ + FString path; + + if (QueryPathKey(HKEY_CURRENT_USER, "Software\\Valve\\Steam", "SteamPath", path)) + { + return path; + } + if (QueryPathKey(HKEY_LOCAL_MACHINE, "Software\\Valve\\Steam", "InstallPath", path)) + { + return path; + } + path = ""; + return path; +} diff --git a/src/win32/i_system.h b/src/win32/i_system.h index 1975d4c21..e17125d4c 100644 --- a/src/win32/i_system.h +++ b/src/win32/i_system.h @@ -207,6 +207,10 @@ extern const IWADInfo *DoomStartupInfo; // [RH] Used by the display code to set the normal window procedure void I_SetWndProc(); +// [RH] Checks the registry for Steam's install path, so we can scan its +// directories for IWADs if the user purchased any through Steam. +FString I_GetSteamPath(); + // Damn Microsoft for doing Get/SetWindowLongPtr half-assed. Instead of // giving them proper prototypes under Win32, they are just macros for // Get/SetWindowLong, meaning they take LONGs and not LONG_PTRs. diff --git a/src/zstring.cpp b/src/zstring.cpp index b74480938..db9d9d4dd 100644 --- a/src/zstring.cpp +++ b/src/zstring.cpp @@ -156,6 +156,15 @@ FString::~FString () Data()->Release(); } +char *FString::LockNewBuffer(size_t len) +{ + Data()->Release(); + AllocBuffer(len); + assert(Data()->RefCount == 1); + Data()->RefCount = -1; + return Chars; +} + char *FString::LockBuffer() { if (Data()->RefCount == 1) diff --git a/src/zstring.h b/src/zstring.h index 4d64261c6..ec21cfa53 100644 --- a/src/zstring.h +++ b/src/zstring.h @@ -130,6 +130,9 @@ public: ~FString (); + // Discard string's contents, create a new buffer, and lock it. + char *LockNewBuffer(size_t len); + char *LockBuffer(); // Obtain write access to the character buffer void UnlockBuffer(); // Allow shared access to the character buffer @@ -232,6 +235,7 @@ public: size_t Len() const { return Data()->Len; } bool IsEmpty() const { return Len() == 0; } + bool IsNotEmpty() const { return Len() != 0; } void Truncate (long newlen);