/* filesystem/filesystem.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include #ifdef _WIN32 #include #include #endif #include "filesystem/filesystem.h" #include "filesystem/diskfile.h" #include "filesystem/file.h" #include "sys/sys.h" namespace filesystem { SearchPath filesystem_searchpath; std::string filesystem_basename; std::string filesystem_modname; std::string filesystem_homedir; std::string filesystem_writedir; std::string filesystem_datadir; std::string const & writedir() { return filesystem_writedir; } std::string const & homedir() { return filesystem_homedir; } SearchPath & searchpath() { return filesystem_searchpath; } void init(const std::string &binaryname, const std::string & basename, const std::string & 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 // UNIX home directory is $HOME/.osirion filesystem_homedir.assign(getenv("HOME")); filesystem_homedir.append("/.osirion"); // create homedir if necessary if (!sys::directory_exists(filesystem_homedir)) sys::mkdir(filesystem_homedir); filesystem_homedir += '/'; #else // windows home directory is My Documents\My Games\Osirion char mydocuments[512]; memset(mydocuments, 0, sizeof(mydocuments)); SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocuments); filesystem_homedir.assign(mydocuments); if (filesystem_homedir.size()) { filesystem_homedir.append("\\My Games"); if (!sys::directory_exists(filesystem_homedir)) sys::mkdir(filesystem_homedir); filesystem_homedir.append("\\Osirion"); if (!sys::directory_exists(filesystem_homedir)) sys::mkdir(filesystem_homedir); filesystem_homedir.append("\\"); } else { con_warn << "using fallback home directory" << std::endl; filesystem_homedir.assign("home"); if (!sys::directory_exists(filesystem_homedir)) sys::mkdir(filesystem_homedir); filesystem_homedir += '/'; } #endif // try the data/ subdirectory of the directory where the binary is located std::string current_datadir(binaryname); size_t i = current_datadir.size(); while (--i && (current_datadir[i] != '/')) { current_datadir.erase(i, 1); } current_datadir.append("data/"); // use the data/ subdirectory of the current working directory as a fallback if (!sys::directory_exists(current_datadir)) { current_datadir.assign("data/"); } // the data dir set by the configure script std::string package_datadir(PACKAGE_DATADIR); std::string dir; // 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); } else { // append basename to writedir filesystem_writedir.append(filesystem_basename); } // create writedir if necessary if (!sys::directory_exists(filesystem_writedir)) sys::mkdir(filesystem_writedir); filesystem_writedir += '/'; // modname search path if (filesystem_modname.size()) { // HOME/modname dir.assign(filesystem_homedir + filesystem_modname); if (sys::directory_exists(dir)) { dir += '/'; filesystem_searchpath.push_back(dir); } // CURRENT/data/modname dir.assign(current_datadir + filesystem_modname); if (sys::directory_exists(dir)) { dir += '/'; filesystem_searchpath.push_back(dir); } // PACKAGE_DATADIR/modname std::string dir(package_datadir + '/' + filesystem_modname); if (sys::directory_exists(dir)) { dir += '/'; filesystem_searchpath.push_back(dir); } } // basename search path // HOME/basename dir.assign(filesystem_homedir + filesystem_basename); if (sys::directory_exists(dir)) { dir += '/'; filesystem_searchpath.push_back(dir); } // PACKAGE_DATADIR/basename dir.assign(package_datadir + '/' + filesystem_basename); if (sys::directory_exists(dir)) { dir += '/'; filesystem_searchpath.push_back(dir); filesystem_datadir.assign(dir); } else { // CURRENT/data/basename dir.assign(current_datadir + filesystem_basename); if (sys::directory_exists(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) { #ifdef _WIN32 for (size_t i = 0; i < (*path).size(); i++) if ((*path)[i] == '/')(*path)[i] = '\\'; #endif con_print << " directory " << (*path) << std::endl; } // create writedir con_print << " home " << 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) { // for now, File is always a DiskFile DiskFile *f = new DiskFile(); if (!f->open(filename)) { delete f; f = 0; return 0; } return f; } void close(File *file) { if (!file) return; file->close(); delete file; } }