diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/console.cc | 4 | ||||
-rw-r--r-- | src/client/keyboard.cc | 4 | ||||
-rw-r--r-- | src/client/video.cc | 4 | ||||
-rw-r--r-- | src/core/application.cc | 12 | ||||
-rw-r--r-- | src/filesystem/diskfile.cc | 44 | ||||
-rw-r--r-- | src/filesystem/filesystem.cc | 145 | ||||
-rw-r--r-- | src/filesystem/filesystem.h | 26 | ||||
-rw-r--r-- | src/sys/sys.cc | 14 | ||||
-rw-r--r-- | src/sys/sys.h | 3 |
9 files changed, 169 insertions, 87 deletions
diff --git a/src/client/console.cc b/src/client/console.cc index ddcaa32..60e2a7f 100644 --- a/src/client/console.cc +++ b/src/client/console.cc @@ -190,7 +190,7 @@ void Console::save_history() if (history.size() <= 1) return; - std::string filename(filesystem::writedir); + std::string filename(filesystem::writedir()); filename.append("history.txt"); std::ofstream ofs(filename.c_str()); @@ -211,7 +211,7 @@ void Console::save_history() void Console::load_history() { - std::string filename(filesystem::writedir); + std::string filename(filesystem::writedir()); filename.append("history.txt"); std::ifstream ifs(filename.c_str(), std::ifstream::in); diff --git a/src/client/keyboard.cc b/src/client/keyboard.cc index 420d1bb..1ebba12 100644 --- a/src/client/keyboard.cc +++ b/src/client/keyboard.cc @@ -229,7 +229,7 @@ Keyboard::~Keyboard() void Keyboard::save_binds() { - std::string filename(filesystem::writedir); + std::string filename(filesystem::writedir()); filename.append("binds.cfg"); std::ofstream ofs(filename.c_str()); @@ -269,7 +269,7 @@ void Keyboard::save_binds() void Keyboard::load_binds() { - std::string filename(filesystem::writedir); + std::string filename(filesystem::writedir()); filename.append("binds.cfg"); std::ifstream ifs(filename.c_str(), std::ifstream::in); diff --git a/src/client/video.cc b/src/client/video.cc index 56514a9..ceea25d 100644 --- a/src/client/video.cc +++ b/src/client/video.cc @@ -158,7 +158,7 @@ void screenshot() std::string filename; // make sure the screenshots folder exists - filename.assign(filesystem::writedir); + filename.assign(filesystem::writedir()); filename.append("screenshots/"); sys::mkdir(filename); @@ -174,7 +174,7 @@ void screenshot() shortname.insert(0, "screenshots/osirion"); shortname.append(".tga"); - filename.assign(filesystem::writedir); + filename.assign(filesystem::writedir()); filename.append(shortname); FILE *handle = fopen(filename.c_str(), "r"); diff --git a/src/core/application.cc b/src/core/application.cc index 4d1ef86..5cf4d66 100644 --- a/src/core/application.cc +++ b/src/core/application.cc @@ -139,7 +139,7 @@ void Application::init(int count, char **arguments) con_debug << "Debug messages enabled\n"; con_print << "^BInitializing core...\n"; - filesystem::init(); + filesystem::init("base", ""); CommandBuffer::init(); @@ -328,7 +328,7 @@ void Application::frame(float seconds) void Application::save_config() { - std::string filename(filesystem::writedir); + std::string filename(filesystem::writedir()); if (!Cvar::sv_dedicated->value()) filename.append("client.cfg"); else @@ -350,15 +350,17 @@ void Application::save_config() ofs << "# this file is automaticly generated" << std::endl; for (Cvar::Registry::iterator it = Cvar::registry().begin(); it != Cvar::registry().end(); it++) { - if (((*it).second->flags() & Cvar::Archive) == Cvar::Archive) + if (((*it).second->flags() & Cvar::Archive) == Cvar::Archive) { + ofs << "# " << (*it).first << " " << (*it).second->info() << std::endl; ofs << "set " << (*it).first << " " << (*it).second->str() << std::endl; + } } ofs.close(); } void Application::load_config() { - std::string filename(filesystem::writedir); + std::string filename(filesystem::writedir()); if (!Cvar::sv_dedicated->value()) filename.append("client.cfg"); else @@ -387,7 +389,7 @@ void Application::load_autoexec() if (Cvar::sv_dedicated->value()) return; - std::string filename(filesystem::writedir); + std::string filename(filesystem::writedir()); filename.append("autoexec.cfg"); std::ifstream ifs(filename.c_str(), std::ifstream::in); diff --git a/src/filesystem/diskfile.cc b/src/filesystem/diskfile.cc index a01a327..56e2727 100644 --- a/src/filesystem/diskfile.cc +++ b/src/filesystem/diskfile.cc @@ -4,6 +4,7 @@ the terms of the GNU General Public License version 2 */ +#include "filesystem/filesystem.h" #include "filesystem/diskfile.h" namespace filesystem { @@ -27,46 +28,19 @@ bool DiskFile::open(const char *filename) } file_name.assign(filename); - std::string fn; - - // if moddir is set, try the mods subdir first - if (moddir.size()) { - // try homedir + moddir - file_path = homedir; - file_path.append(moddir); - fn = file_path; - fn.append(filename); - diskfile_handle = fopen(fn.c_str(), "rb"); - if (diskfile_handle) - return true; + file_path.clear(); - // try datadir + moddir - file_path = datadir; - file_path.append(moddir); - fn = file_path; + for (SearchPath::iterator path = searchpath().begin(); path != searchpath().end(); path++) { + std::string fn((*path)); fn.append(filename); + diskfile_handle = fopen(fn.c_str(), "rb"); - if (diskfile_handle) + if (diskfile_handle) { + file_path.assign((*path)); return true; - } - // try homedir + basedir - file_path = homedir; - file_path.append(basedir); - fn = file_path; - fn.append(filename); - diskfile_handle = fopen(fn.c_str(), "rb"); - if (diskfile_handle) - return true; + } + } - // try datadir + basedir - file_path = datadir; - file_path.append(basedir); - fn = file_path; - fn.append(filename); - diskfile_handle = fopen(fn.c_str(), "rb"); - if (diskfile_handle) - return true; - //con_error << "Could not open " << filename << std::endl; return false; } diff --git a/src/filesystem/filesystem.cc b/src/filesystem/filesystem.cc index dd694ee..1cb13e9 100644 --- a/src/filesystem/filesystem.cc +++ b/src/filesystem/filesystem.cc @@ -5,6 +5,7 @@ */ // project headers +#include <list> #include "filesystem/filesystem.h" #include "filesystem/diskfile.h" @@ -14,49 +15,139 @@ namespace filesystem { -std::string datadir = ""; -std::string homedir = ""; -std::string basedir = ""; -std::string moddir = ""; -std::string writedir = ""; +SearchPath filesystem_searchpath; +std::string filesystem_basename; +std::string filesystem_modname; -void init() +std::string filesystem_homedir; +std::string filesystem_writedir; +std::string filesystem_datadir; + +std::string const & writedir() { - con_print << "^BInitializing filesystem..." << std::endl; + return filesystem_writedir; +} - // initialize game data locations - // FIXME datadir should by set by ./configure and read from config.h - datadir = "./data/"; +std::string const & homedir() +{ + return filesystem_homedir; +} - // FIXME a local or remote game module must be able to set these - basedir = "base/"; - moddir = ""; +SearchPath & searchpath() +{ + return filesystem_searchpath; +} +void init(std::string const & basename, std::string const & modname) +{ + con_print << "^BInitializing filesystem..." << std::endl; + + // clear everything + filesystem_searchpath.clear(); + filesystem_basename.assign(basename); + if (!filesystem_basename.size()) + filesystem_basename.assign("base"); + + filesystem_modname.assign(modname); #ifndef _WIN32 - homedir = getenv("HOME"); - homedir = homedir + "/.osirion/"; + filesystem_homedir.assign(getenv("HOME")); + filesystem_homedir.append("/.osirion/"); #else // FIXME win32 - homedir = "./home/"; + filesystem_homedir.assign("./home/"); #endif - - sys::mkdir(homedir); - sys::mkdir(homedir+basedir); - - writedir = homedir; - if (moddir.size()) { - writedir.append(moddir); - } else - writedir.append(basedir); - sys::mkdir(writedir); + std::string current_datadir("data/"); + std::string package_datadir(PACKAGE_DATADIR); + std::string dir; - con_print << " files are created in " << writedir << std::endl; + // set writedir depending on modname and add home paths to the searchpath + filesystem_writedir.assign(filesystem_homedir); + if (filesystem_modname.size()) { + // append modname to writedir + filesystem_writedir.append(filesystem_modname); + filesystem_writedir += '/'; + } else { + // append basename to writedir + filesystem_writedir.append(filesystem_basename); + filesystem_writedir += '/'; + } + + sys::mkdir(filesystem_homedir); + sys::mkdir(filesystem_writedir); + + + // modname search path + if (filesystem_modname.size()) { + // HOME/modname + dir.assign(filesystem_homedir + filesystem_modname); + if (sys::isdirectory(dir)) { + dir += '/'; + filesystem_searchpath.push_back(dir); + } + + // CURRENT/data/modname + dir.assign(current_datadir + filesystem_modname); + if (sys::isdirectory(dir)) { + dir += '/'; + filesystem_searchpath.push_back(dir); + } + + // PACKAGE_DATADIR/modname + std::string dir(package_datadir + '/' + filesystem_modname); + if (sys::isdirectory(dir)) { + dir += '/'; + filesystem_searchpath.push_back(dir); + } + } + + // basename search path + // HOME/basename + dir.assign(filesystem_homedir + filesystem_basename); + if (sys::isdirectory(dir)) { + dir += '/'; + filesystem_searchpath.push_back(dir); + } + + // PACKAGE_DATADIR/basename + dir.assign(package_datadir + '/' + filesystem_basename); + if (sys::isdirectory(dir)) { + dir += '/'; + filesystem_searchpath.push_back(dir); + filesystem_datadir.assign(dir); + } else { + // CURRENT/data/basename + dir.assign(current_datadir + filesystem_basename); + if (sys::isdirectory(dir)) { + dir += '/'; + filesystem_searchpath.push_back(dir); + filesystem_datadir.assign(dir); + } else { + con_warn << "data/" << basename << " not found!" << std::endl; + } + } + + // print search path + for (SearchPath::iterator path = filesystem_searchpath.begin(); path != filesystem_searchpath.end(); ++path) { + con_print << " " << (*path) << std::endl; + } + con_print << " " << filesystem_searchpath.size() << " directories added to searchpath" << std::endl; + + // create writedir + con_print << " files are created in " << filesystem_writedir << std::endl; } void shutdown() { con_print << "^BShutting down filesystem..." << std::endl; + + filesystem_searchpath.clear(); + filesystem_basename.clear(); + + filesystem_modname.clear(); + filesystem_homedir.clear(); + + filesystem_writedir.clear(); } File *open(const char *filename) diff --git a/src/filesystem/filesystem.h b/src/filesystem/filesystem.h index 83e93c0..f8740d1 100644 --- a/src/filesystem/filesystem.h +++ b/src/filesystem/filesystem.h @@ -11,37 +11,35 @@ #include "filesystem/diskfile.h" #include <string> +#include <list> /// The filesystem namespace contains classes and functions for common file operations. /** filesystem is a core subsystem */ namespace filesystem { -/// location of the main data files, includes trailing / -extern std::string datadir; +typedef std::list<std::string> SearchPath; -/// location of the personal data files, includes trailing / -extern std::string homedir; - -/// writeable location -extern std::string writedir; - -/// subdirectory with the base data files, includes trailing / -extern std::string basedir; - -/// subdirectory for the current mod, includes trailing / -extern std::string moddir; +SearchPath & searchpath(); /// initialize the filesystem subsystem -void init(); +void init(std::string const & basename, std::string const & modname); /// shutdown the filesystem subsystem void shutdown(); +/// current home directory e.g. ~/.osirion/ +std::string const & homedir(); + +/// current write directory e.g. ~/.osirion/base/ +std::string const & writedir(); + /// open a file and return a pointer to a File instance File *open(const char *filename); + /// open a file and return a pointer to a File instance File *open(const std::string &filename); + /// close and delete a file instance void close(File *file); diff --git a/src/sys/sys.cc b/src/sys/sys.cc index da9b08d..9526166 100644 --- a/src/sys/sys.cc +++ b/src/sys/sys.cc @@ -27,6 +27,20 @@ namespace sys { +bool isdirectory(std::string const &path) +{ + struct stat path_stat; + memset(&path_stat, 0, sizeof(path_stat)); + if (stat(path.c_str(), &path_stat) != 0) + return false; + + if (path_stat.st_mode & S_IFDIR) { + return true; + } + + return false; +} + void mkdir(std::string const &path) { #ifdef _WIN32 diff --git a/src/sys/sys.h b/src/sys/sys.h index e455b82..66040f0 100644 --- a/src/sys/sys.h +++ b/src/sys/sys.h @@ -21,6 +21,9 @@ namespace sys { typedef void (* signalfunc)(int signum); +/// check if a path exists and if it is a directory +bool isdirectory(std::string const &path); + /// create a directory void mkdir(std::string const &path); |