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);