diff --git a/src/Client/System/GameDirectoryGuesser.cpp b/src/Client/System/GameDirectoryGuesser.cpp new file mode 100644 index 0000000..c0f3dd9 --- /dev/null +++ b/src/Client/System/GameDirectoryGuesser.cpp @@ -0,0 +1,61 @@ +#include +#include + +#ifdef WOS_WINDOWS +# include +# include +#elif defined WOS_LINUX +# include +# include +# include +#endif + +std::vector GameDirectoryGuesser::getDirectoryList() +{ + std::vector directories; + +#ifdef WOS_WINDOWS + + // TODO: Handle non-ASCII paths better. + TCHAR programFilesDirectory[MAX_PATH]; + TCHAR programFilesX86Directory[MAX_PATH]; + SHGetFolderPath(nullptr, CSIDL_PROGRAM_FILES, nullptr, 0, programFilesDirectory); + SHGetFolderPath(nullptr, CSIDL_PROGRAM_FILESX86, nullptr, 0, programFilesX86Directory); + + std::wstring programFilesW(programFilesDirectory); + std::wstring programFilesX86W(programFilesX86Directory); + + std::string programFilesA(programFilesW.begin(), programFilesW.end()); + std::string programFilesX86A(programFilesX86W.begin(), programFilesX86W.end()); + + directories.push_back(programFilesA + "\\Steam\\SteamApps\\common\\Crypt of the NecroDancer"); + directories.push_back(programFilesX86A + "\\Steam\\SteamApps\\common\\Crypt of the NecroDancer"); + +#elif defined WOS_LINUX + + // Get user's home directory, if set through $HOME. + const char * homeDirectoryPtr = std::getenv("HOME"); + + if (homeDirectoryPtr == nullptr) + { + // Get user's home directory, if not set through $HOME. + homeDirectoryPtr = getpwuid(getuid())->pw_dir; + } + + if (homeDirectoryPtr != nullptr) + { + std::string homeDirectory(homeDirectoryPtr); + + // Try all capitalization variants. The exact capitalization depends on when Steam was installed/cleaned. + directories.push_back(homeDirectory + "/.local/share/steam/steamapps/common/Crypt of the NecroDancer"); + directories.push_back(homeDirectory + "/.local/share/Steam/steamapps/common/Crypt of the NecroDancer"); + directories.push_back(homeDirectory + "/.local/share/steam/SteamApps/common/Crypt of the NecroDancer"); + directories.push_back(homeDirectory + "/.local/share/Steam/SteamApps/common/Crypt of the NecroDancer"); + } + +#endif + + // TODO: Detect game path for Mac OS X. + + return directories; +} diff --git a/src/Client/System/GameDirectoryGuesser.hpp b/src/Client/System/GameDirectoryGuesser.hpp new file mode 100644 index 0000000..20b263e --- /dev/null +++ b/src/Client/System/GameDirectoryGuesser.hpp @@ -0,0 +1,14 @@ +#ifndef SRC_CLIENT_SYSTEM_GAMEDIRECTORYGUESSER_HPP_ +#define SRC_CLIENT_SYSTEM_GAMEDIRECTORYGUESSER_HPP_ + +#include +#include + +class GameDirectoryGuesser +{ +public: + + static std::vector getDirectoryList(); +}; + +#endif diff --git a/src/Client/System/NEApplication.cpp b/src/Client/System/NEApplication.cpp index ccd40fe..ddf6b97 100644 --- a/src/Client/System/NEApplication.cpp +++ b/src/Client/System/NEApplication.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -32,6 +33,17 @@ bool NEApplication::chooseGameDirectory() return true; } + // Check common game directories. + for (auto dir : GameDirectoryGuesser::getDirectoryList()) + { + gameDirectory = dir; + + if (checkGameDirectory()) + { + return true; + } + } + bool showMessage = false; FileChooser fc; @@ -39,8 +51,7 @@ bool NEApplication::chooseGameDirectory() MessageBox errorMessage("This is not a valid NecroDancer directory.\n\n" "Please select your NecroDancer installation directory (typically found in " - "your SteamApps folder)\nor click \"Cancel\" to exit.", "NecroEdit", MessageBox::Error, - MessageBox::OkCancel); + "your SteamApps folder)\nor click \"Cancel\" to exit.", "NecroEdit", MessageBox::Error, MessageBox::OkCancel); do { @@ -66,7 +77,8 @@ bool NEApplication::chooseGameDirectory() showMessage = true; - } while (!checkGameDirectory()); + } + while (!checkGameDirectory()); return true; } @@ -174,7 +186,7 @@ int NEApplication::init(const std::vector& args) fontError.show(); return LoadErrorFont; } - + setTextureSmoothingEnabled(false); open(); @@ -187,9 +199,9 @@ void NEApplication::printUsage(const std::string & exeName) std::cout << "Usage: " << exeName << " [Options] [Dungeon File]" << std::endl; std::cout << "Options:" << std::endl; std::cout << "-g / --game-directory [dir]: Specify [dir] as containing the game's executable and resource files" - << std::endl; + << std::endl; std::cout << "-r / --resource-directory [dir]: Specify [dir] as containing the editor's resource files" - << std::endl; + << std::endl; std::cout << "-h / --help: Show this help" << std::endl; std::cout << "--: Treat following arguments as dungeon file to load, rather than as options" << std::endl; }