- use std::filesystem for directory traversal.

So far implemented for scanning search paths
This commit is contained in:
Christoph Oelckers 2019-10-29 19:53:46 +01:00
parent 35342526a5
commit ac87665972
14 changed files with 122 additions and 188 deletions

View file

@ -1,6 +1,11 @@
cmake_minimum_required( VERSION 2.8.7 ) cmake_minimum_required( VERSION 3.1.0 )
project(Demolition) project(Demolition)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if( COMMAND cmake_policy ) if( COMMAND cmake_policy )
if( POLICY CMP0011 ) if( POLICY CMP0011 )
cmake_policy( SET CMP0011 NEW ) cmake_policy( SET CMP0011 NEW )

View file

@ -1,4 +1,4 @@
cmake_minimum_required( VERSION 2.8.7 ) cmake_minimum_required( VERSION 3.1.0 )
include(precompiled_headers) include(precompiled_headers)
@ -789,6 +789,7 @@ set (PCH_SOURCES
common/gamecvars.cpp common/gamecvars.cpp
common/gamecontrol.cpp common/gamecontrol.cpp
common/inputstate.cpp common/inputstate.cpp
common/searchpaths.cpp
common/2d/v_2ddrawer.cpp common/2d/v_2ddrawer.cpp
common/2d/v_draw.cpp common/2d/v_draw.cpp

View file

@ -1,8 +1,4 @@
cmake_minimum_required( VERSION 2.8.7 ) cmake_minimum_required( VERSION 3.1.0 )
if( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
endif()
if (MSVC) if (MSVC)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /J" ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /J" )

View file

@ -475,6 +475,9 @@ GameInterface *CheckFrontend()
void ChooseGame() void ChooseGame()
{ {
gi = CheckFrontend();
return;
#if 0
auto dir = Args->CheckValue("-game"); auto dir = Args->CheckValue("-game");
if (dir && !chdir(dir)) if (dir && !chdir(dir))
{ {
@ -548,6 +551,7 @@ void ChooseGame()
} }
if (gi == nullptr) exit(1); if (gi == nullptr) exit(1);
} }
#endif
} }

View file

@ -126,7 +126,7 @@ int FDirectory::AddDirectory(const char *dirpath)
dirmatch += '*'; dirmatch += '*';
if ((handle = _wfindfirst(wdirmatch, &fileinfo)) == -1) if ((handle = _wfindfirst(dirmatch.c_str(), &fileinfo)) == -1)
{ {
Printf("Could not scan '%s': %s\n", dirpath, strerror(errno)); Printf("Could not scan '%s': %s\n", dirpath, strerror(errno));
} }
@ -157,7 +157,7 @@ int FDirectory::AddDirectory(const char *dirpath)
} }
else else
{ {
if (strstr(fileinfo.name, ".orig") || strstr(fileinfo.name, ".bak")) if (strstr(fi, ".orig") || strstr(fi, ".bak"))
{ {
// We shouldn't add backup files to the lump directory // We shouldn't add backup files to the lump directory
continue; continue;

View file

@ -554,10 +554,14 @@ CCMD (whereisini)
FGameConfigFile* GameConfig; FGameConfigFile* GameConfig;
static FString GameName; static FString GameName;
void G_LoadConfig(const char* game) void G_LoadConfig()
{ {
OSD_Init(); OSD_Init();
GameConfig = new FGameConfigFile(); GameConfig = new FGameConfigFile();
}
void G_ReadConfig(const char* game)
{
GameConfig->DoGlobalSetup(); GameConfig->DoGlobalSetup();
GameConfig->DoGameSetup(game); GameConfig->DoGameSetup(game);
GameConfig->DoKeySetup(game); GameConfig->DoKeySetup(game);

View file

@ -72,7 +72,8 @@ private:
}; };
extern FGameConfigFile *GameConfig; extern FGameConfigFile *GameConfig;
void G_LoadConfig(const char*); void G_LoadConfig();
void G_ReadConfig(const char*);
void G_SaveConfig(); void G_SaveConfig();
#endif //__GAMECONFIGFILE_H__ #endif //__GAMECONFIGFILE_H__

View file

@ -17,6 +17,7 @@
InputState inputState; InputState inputState;
void SetClipshapes(); void SetClipshapes();
TArray<FString> CollectSearchPaths();
struct GameFuncNameDesc struct GameFuncNameDesc
{ {
@ -295,9 +296,6 @@ void UserConfig::ProcessOptions()
void CONFIG_Init() void CONFIG_Init()
{ {
LumpFilter = currentGame;
if (LumpFilter.Compare("Redneck") == 0) LumpFilter = "Redneck.Redneck";
else if (LumpFilter.Compare("RedneckRides") == 0) LumpFilter = "Redneck.RidesAgain";
SetClipshapes(); SetClipshapes();
// This must be done before initializing any data, so doing it late in the startup process won't work. // This must be done before initializing any data, so doing it late in the startup process won't work.
@ -307,10 +305,22 @@ void CONFIG_Init()
} }
userConfig.ProcessOptions(); userConfig.ProcessOptions();
CONFIG_ReadCombatMacros(); G_LoadConfig();
// Startup dialog must be presented here so that everything can be set up before reading the keybinds. // Startup dialog must be presented here so that everything can be set up before reading the keybinds.
G_LoadConfig(currentGame);
TArray<FString> paths = CollectSearchPaths();
for (auto& path : paths)
{
OutputDebugStringA(path);
OutputDebugStringA("\r\n");
}
LumpFilter = currentGame;
if (LumpFilter.Compare("Redneck") == 0) LumpFilter = "Redneck.Redneck";
else if (LumpFilter.Compare("RedneckRides") == 0) LumpFilter = "Redneck.RidesAgain";
CONFIG_ReadCombatMacros();
G_ReadConfig(currentGame);
if (userConfig.CommandName.IsNotEmpty()) if (userConfig.CommandName.IsNotEmpty())
{ {
@ -318,7 +328,6 @@ void CONFIG_Init()
} }
int index = 0; int index = 0;
for(auto &gf : gamefuncs) for(auto &gf : gamefuncs)
{ {

View file

@ -12,6 +12,10 @@ FString M_GetScreenshotsPath();
FString M_GetSavegamesPath(); FString M_GetSavegamesPath();
FString M_GetDocumentsPath(); FString M_GetDocumentsPath();
#ifdef _WIN32
int ReadRegistryValue(char const* const SubKey, char const* const Value, char* const Output, unsigned long* OutputSize);
#endif
#ifdef __APPLE__ #ifdef __APPLE__
FString M_GetMacAppSupportPath(const bool create = true); FString M_GetMacAppSupportPath(const bool create = true);
void M_GetMacSearchDirectories(FString& user_docs, FString& user_app_support, FString& local_app_support); void M_GetMacSearchDirectories(FString& user_docs, FString& user_app_support, FString& local_app_support);

View file

@ -21,42 +21,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
#include <filesystem>
#include "i_specialpaths.h"
#include "compat.h"
#include "gameconfigfile.h"
#include "cmdlib.h"
#include "utf8.h"
// //
// Search path management // Search path management
// //
namespace fs = std::filesystem;
#if defined _WIN32
//-------------------------------------------------------------------------
//
//
//
//-------------------------------------------------------------------------
static int G_ReadRegistryValue(char const * const SubKey, char const * const Value, char * const Output, DWORD * OutputSize) #ifndef _WIN32
{
// KEY_WOW64_32KEY gets us around Wow6432Node on 64-bit builds
REGSAM const wow64keys[] = { KEY_WOW64_32KEY, KEY_WOW64_64KEY };
for (auto &wow64key : wow64keys)
{
HKEY hkey;
LONG keygood = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NULL, 0, KEY_READ | wow64key, &hkey);
if (keygood != ERROR_SUCCESS)
continue;
LONG retval = SHGetValueA(hkey, SubKey, Value, NULL, Output, OutputSize);
RegCloseKey(hkey);
if (retval == ERROR_SUCCESS)
return 1;
}
return 0;
}
#elif defined (__APPLE__) || defined (__FreeBSD__) || defined(__OpenBSD__) || defined (__linux__)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// //
@ -346,14 +324,14 @@ void G_AddExternalSearchPaths(TArray<FString> &searchpaths)
// Duke Nukem 3D: 20th Anniversary World Tour (Steam) // Duke Nukem 3D: 20th Anniversary World Tour (Steam)
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (G_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 434050)", "InstallLocation", buf, &bufsize)) if (ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 434050)", "InstallLocation", buf, &bufsize))
{ {
searchpaths.Push(buf); searchpaths.Push(buf);
} }
// Duke Nukem 3D: Megaton Edition (Steam) // Duke Nukem 3D: Megaton Edition (Steam)
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (G_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 225140)", "InstallLocation", buf, &bufsize)) if (ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 225140)", "InstallLocation", buf, &bufsize))
{ {
char * const suffix = buf + bufsize - 1; char * const suffix = buf + bufsize - 1;
size_t const remaining = sizeof(buf) - bufsize; size_t const remaining = sizeof(buf) - bufsize;
@ -370,7 +348,7 @@ void G_AddExternalSearchPaths(TArray<FString> &searchpaths)
// Duke Nukem 3D (3D Realms Anthology (Steam) / Kill-A-Ton Collection 2015) // Duke Nukem 3D (3D Realms Anthology (Steam) / Kill-A-Ton Collection 2015)
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (G_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 359850)", "InstallLocation", buf, &bufsize)) if (ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 359850)", "InstallLocation", buf, &bufsize))
{ {
char * const suffix = buf + bufsize - 1; char * const suffix = buf + bufsize - 1;
size_t const remaining = sizeof(buf) - bufsize; size_t const remaining = sizeof(buf) - bufsize;
@ -381,25 +359,25 @@ void G_AddExternalSearchPaths(TArray<FString> &searchpaths)
// Duke Nukem 3D: Atomic Edition (GOG.com) // Duke Nukem 3D: Atomic Edition (GOG.com)
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (G_ReadRegistryValue("SOFTWARE\\GOG.com\\GOGDUKE3D", "PATH", buf, &bufsize)) if (ReadRegistryValue("SOFTWARE\\GOG.com\\GOGDUKE3D", "PATH", buf, &bufsize))
{ {
searchpaths.Push(buf); searchpaths.Push(buf);
} }
// Duke Nukem 3D (3D Realms Anthology) // Duke Nukem 3D (3D Realms Anthology)
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (G_ReadRegistryValue("SOFTWARE\\3DRealms\\Duke Nukem 3D", NULL, buf, &bufsize)) if (ReadRegistryValue("SOFTWARE\\3DRealms\\Duke Nukem 3D", NULL, buf, &bufsize))
{ {
char * const suffix = buf + bufsize - 1; char * const suffix = buf + bufsize - 1;
size_t const remaining = sizeof(buf) - bufsize; size_t const remaining = sizeof(buf) - bufsize;
Bstrncpy(suffix, "/Duke Nukem 3D", remaining); strncpy(suffix, "/Duke Nukem 3D", remaining);
searchpaths.Push(buf); searchpaths.Push(buf);
} }
// 3D Realms Anthology // 3D Realms Anthology
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (G_ReadRegistryValue("SOFTWARE\\3DRealms\\Anthology", NULL, buf, &bufsize)) if (ReadRegistryValue("SOFTWARE\\3DRealms\\Anthology", NULL, buf, &bufsize))
{ {
char * const suffix = buf + bufsize - 1; char * const suffix = buf + bufsize - 1;
size_t const remaining = sizeof(buf) - bufsize; size_t const remaining = sizeof(buf) - bufsize;
@ -410,7 +388,7 @@ void G_AddExternalSearchPaths(TArray<FString> &searchpaths)
// NAM (Steam) // NAM (Steam)
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (G_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 329650)", "InstallLocation", buf, &bufsize)) if (ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 329650)", "InstallLocation", buf, &bufsize))
{ {
char * const suffix = buf + bufsize - 1; char * const suffix = buf + bufsize - 1;
size_t const remaining = sizeof(buf) - bufsize; size_t const remaining = sizeof(buf) - bufsize;
@ -421,7 +399,7 @@ void G_AddExternalSearchPaths(TArray<FString> &searchpaths)
// WWII GI (Steam) // WWII GI (Steam)
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (G_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 376750)", "InstallLocation", buf, &bufsize)) if (ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 376750)", "InstallLocation", buf, &bufsize))
{ {
char * const suffix = buf + bufsize - 1; char * const suffix = buf + bufsize - 1;
size_t const remaining = sizeof(buf) - bufsize; size_t const remaining = sizeof(buf) - bufsize;
@ -432,35 +410,35 @@ void G_AddExternalSearchPaths(TArray<FString> &searchpaths)
// Redneck Rampage (GOG.com) // Redneck Rampage (GOG.com)
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (G_ReadRegistryValue("SOFTWARE\\GOG.com\\GOGREDNECKRAMPAGE", "PATH", buf, &bufsize)) if (ReadRegistryValue("SOFTWARE\\GOG.com\\GOGREDNECKRAMPAGE", "PATH", buf, &bufsize))
{ {
searchpaths.Push(buf); searchpaths.Push(buf);
} }
// Redneck Rampage Rides Again (GOG.com) // Redneck Rampage Rides Again (GOG.com)
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (G_ReadRegistryValue("SOFTWARE\\GOG.com\\GOGCREDNECKRIDESAGAIN", "PATH", buf, &bufsize)) if (ReadRegistryValue("SOFTWARE\\GOG.com\\GOGCREDNECKRIDESAGAIN", "PATH", buf, &bufsize))
{ {
searchpaths.Push(buf); searchpaths.Push(buf);
} }
// Blood: One Unit Whole Blood (Steam) // Blood: One Unit Whole Blood (Steam)
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (G_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 299030)", "InstallLocation", buf, &bufsize)) if (ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 299030)", "InstallLocation", buf, &bufsize))
{ {
searchpaths.Push(buf); searchpaths.Push(buf);
} }
// Blood: One Unit Whole Blood (GOG.com) // Blood: One Unit Whole Blood (GOG.com)
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (G_ReadRegistryValue("SOFTWARE\\GOG.com\\GOGONEUNITONEBLOOD", "PATH", buf, &bufsize)) if (ReadRegistryValue("SOFTWARE\\GOG.com\\GOGONEUNITONEBLOOD", "PATH", buf, &bufsize))
{ {
searchpaths.Push(buf); searchpaths.Push(buf);
} }
// Blood: Fresh Supply (Steam) // Blood: Fresh Supply (Steam)
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (!found && G_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 1010750)", "InstallLocation", buf, &bufsize)) if (ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 1010750)", "InstallLocation", buf, &bufsize))
{ {
searchpaths.Push(buf); searchpaths.Push(buf);
strncat(buf, R"(\addons\Cryptic Passage)", 23); strncat(buf, R"(\addons\Cryptic Passage)", 23);
@ -469,7 +447,7 @@ void G_AddExternalSearchPaths(TArray<FString> &searchpaths)
// Blood: Fresh Supply (GOG.com) // Blood: Fresh Supply (GOG.com)
bufsize = sizeof(buf); bufsize = sizeof(buf);
if (!found && G_ReadRegistryValue(R"(SOFTWARE\Wow6432Node\GOG.com\Games\1374469660)", "path", buf, &bufsize)) if (ReadRegistryValue(R"(SOFTWARE\Wow6432Node\GOG.com\Games\1374469660)", "path", buf, &bufsize))
{ {
searchpaths.Push(buf); searchpaths.Push(buf);
strncat(buf, R"(\addons\Cryptic Passage)", 23); strncat(buf, R"(\addons\Cryptic Passage)", 23);
@ -478,18 +456,7 @@ void G_AddExternalSearchPaths(TArray<FString> &searchpaths)
} }
#endif #endif
//-------------------------------------------------------------------------
//
//
//
//-------------------------------------------------------------------------
void AddExpandedPath(TArray<FString> &searchpaths, const char *basepath)
{
}
#ifdef _WIN32
//========================================================================== //==========================================================================
// //
// Windows version // Windows version
@ -498,110 +465,30 @@ void AddExpandedPath(TArray<FString> &searchpaths, const char *basepath)
void CollectSubdirectories(TArray<FString> &searchpath, const char *dirmatch) void CollectSubdirectories(TArray<FString> &searchpath, const char *dirmatch)
{ {
struct _wfinddata_t fileinfo; try
intptr_t handle;
FString dirpath;
int count = 0;
auto wdirmatch = WideString(dirmatch);
dirpath.Truncate(dirpath.Len()-1); // remove the '*'
if ((handle = _wfindfirst(wdirmatch, &fileinfo)) == -1)
{ {
// silently ignore non-existent paths FString dirpath = MakeUTF8(dirmatch); // convert into clean UTF-8
return; dirpath.Truncate(dirpath.Len() - 1); // remove the '*'
fs::path path = fs::u8path(dirpath.GetChars());
if (fs::exists(path) && fs::is_directory(path))
{
for (const auto& entry : fs::directory_iterator(path))
{
if (fs::is_directory(entry.status()))
{
auto filename = entry.path().filename().u8string();
FString newdir = dirpath + filename.c_str();
searchpath.Push(newdir);
} }
else
{
do
{
if (fileinfo.attrib & _A_HIDDEN)
{
// Skip hidden files and directories. (Prevents SVN bookkeeping
// info from being included.)
continue;
} }
FString fi = FString(fileinfo.name); }
if (fileinfo.attrib & _A_SUBDIR) }
catch (fs::filesystem_error &)
{ {
// Just ignore this path if it caused an error.
if (fi[0] == '.' &&
(fi[1] == '\0' ||
(fi[1] == '.' && fi[2] == '\0')))
{
// Do not record . and .. directories.
continue;
} }
FString newdir = dirpath + fi;
count += AddDirectory(newdir);
}
} while (_wfindnext(handle, &fileinfo) == 0);
_findclose(handle);
}
return count;
} }
#else
//==========================================================================
//
// add_dirs
// 4.4BSD version
//
//==========================================================================
void FDirectory::AddDirectory(const char *dirpath)
{
char *argv [2] = { NULL, NULL };
argv[0] = new char[strlen(dirpath)+1];
strcpy(argv[0], dirpath);
FTS *fts;
FTSENT *ent;
fts = fts_open(argv, FTS_LOGICAL, NULL);
if (fts == NULL)
{
return 0;
}
const size_t namepos = strlen(dirpath);
FString pathfix;
while ((ent = fts_read(fts)) != NULL)
{
if (ent->fts_info != FTS_D)
{
// We're only interested in getting directories.
continue;
}
fts_set(fts, ent, FTS_SKIP);
if (ent->fts_name[0] == '.')
{
// Skip hidden directories. (Prevents SVN bookkeeping
// info from being included.)
}
// Some implementations add an extra separator between
// root of the hierarchy and entity's path.
// It needs to be removed in order to resolve
// lumps' relative paths properly.
const char* path = ent->fts_path;
if ('/' == path[namepos])
{
pathfix = FString(path, namepos);
pathfix.AppendCStrPart(&path[namepos + 1], ent->fts_pathlen - namepos - 1);
path = pathfix.GetChars();
}
searchpaths.Push(path);
}
fts_close(fts);
delete[] argv[0];
}
#endif
//========================================================================== //==========================================================================
// //
// CollectSearchPaths // CollectSearchPaths
@ -612,7 +499,7 @@ void FDirectory::AddDirectory(const char *dirpath)
TArray<FString> CollectSearchPaths() TArray<FString> CollectSearchPaths()
{ {
TArray<FString> searchpths; TArray<FString> searchpaths;
if (GameConfig->SetSection("GameSearch.Directories")) if (GameConfig->SetSection("GameSearch.Directories"))
{ {
@ -627,31 +514,33 @@ TArray<FString> CollectSearchPaths()
if (nice.Len() > 0) if (nice.Len() > 0)
{ {
#ifdef _WIN32 #ifdef _WIN32
if (isalpha(nice[0] && nice[1] == ':' && nice[2] != '/') continue; // ignore drive relative paths because they are meaningless. if (isalpha(nice[0] && nice[1] == ':' && nice[2] != '/')) continue; // ignore drive relative paths because they are meaningless.
#endif #endif
// A path ending with "/*" means to add all subdirectories. // A path ending with "/*" means to add all subdirectories.
if (nice[nice.Len()-2] == '/' && nice[nice.Len()-1] == '*') if (nice[nice.Len()-2] == '/' && nice[nice.Len()-1] == '*')
{ {
AddExpandedPath(searchpaths, nice); CollectSubdirectories(searchpaths, nice);
} }
// Checking Steam via a list entry allows easy removal if not wanted. // Checking Steam via a list entry allows easy removal if not wanted.
else if (nice.CompareNoCase("$STEAM")) else if (nice.CompareNoCase("$STEAM") == 0)
{ {
G_AddExternalSearchPaths(searchpaths); G_AddExternalSearchPaths(searchpaths);
} }
else else
{ {
mSearchPaths.Push(nice); searchpaths.Push(nice);
} }
} }
} }
} }
} }
// Unify and remove trailing slashes // Unify and remove trailing slashes
for (auto &str : mSearchPaths) for (auto &str : searchpaths)
{ {
str.Substitute("\\", "/"); str.Substitute("\\", "/");
str.Substitute("//", "/"); // Double slashes can happen when constructing paths so just get rid of them here.
if (str.Back() == '/') str.Truncate(str.Len() - 1); if (str.Back() == '/') str.Truncate(str.Len() - 1);
} }
return searchpaths;
} }

View file

@ -1,8 +1,4 @@
cmake_minimum_required( VERSION 2.8.7 ) cmake_minimum_required( VERSION 3.1.0 )
if( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
endif()
if (MSVC) if (MSVC)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /J" ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /J" )

View file

@ -36,6 +36,7 @@
#include <windows.h> #include <windows.h>
#include <lmcons.h> #include <lmcons.h>
#include <shlobj.h> #include <shlobj.h>
#include <Shlwapi.h>
#include "i_specialpaths.h" #include "i_specialpaths.h"
#include "printf.h" #include "printf.h"
@ -334,3 +335,35 @@ FString M_GetDocumentsPath()
} }
return path; return path;
} }
//===========================================================================
//
// ReadRegistryValue Windows
//
// Reads a value from the registry
//
//===========================================================================
int ReadRegistryValue(char const* const SubKey, char const* const Value, char* const Output, unsigned long* OutputSize)
{
// KEY_WOW64_32KEY gets us around Wow6432Node on 64-bit builds
REGSAM const wow64keys[] = { KEY_WOW64_32KEY, KEY_WOW64_64KEY };
for (auto& wow64key : wow64keys)
{
HKEY hkey;
LONG keygood = RegOpenKeyExA(HKEY_LOCAL_MACHINE, NULL, 0, KEY_READ | wow64key, &hkey);
if (keygood != ERROR_SUCCESS)
continue;
LONG retval = SHGetValueA(hkey, SubKey, Value, NULL, Output, OutputSize);
RegCloseKey(hkey);
if (retval == ERROR_SUCCESS)
return 1;
}
return 0;
}

View file

@ -1,8 +1,4 @@
cmake_minimum_required( VERSION 2.8.7 ) cmake_minimum_required( VERSION 3.1.0 )
if( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
endif()
if (MSVC) if (MSVC)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /J" ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /J" )

View file

@ -1,8 +1,4 @@
cmake_minimum_required( VERSION 2.8.7 ) cmake_minimum_required( VERSION 3.1.0 )
if( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
endif()
if (MSVC) if (MSVC)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /J" ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /J" )