diff --git a/src/main.cpp b/src/main.cpp index ac43bc0..a043eb2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -278,23 +278,16 @@ int main(int argc, char* argv[]) regSvc(fs); std::string programpath = PHYSFS_getBaseDir(); - fs.mount(programpath + "/data", "/", - FileSystem::mountOptional); - std::string const baselib = programpath + "/base.jd"; - if (!fs.mount(baselib, "/", FileSystem::mountOptional)) { - FileSystem::Error const err("Could not open \"" + baselib + '\"'); - if (!fs.mount("./base.jd", "/", FileSystem::mountOptional)) { - LOG_W(err.what()); - LOG_W(FileSystem::Error( - "Could not open \"./base.jd\"").what()); - } - } - - if (!fs.mount(game, "/", gameSpecified ? - FileSystem::prependPath : FileSystem::mountOptional) + std::vector baselibpaths; + baselibpaths.push_back(programpath + "/base.jd"); + baselibpaths.push_back(programpath + "/../base.jd"); + baselibpaths.push_back(programpath + "/../share/base.jd"); + baselibpaths.push_back(basepath + "/base.jd"); + fs.mountFirstWorking(baselibpaths, "/", FileSystem::logWarnings|FileSystem::mountOptional); + + if (!fs.mount(game, "/", FileSystem::logWarnings|(gameSpecified ? + FileSystem::prependPath : FileSystem::mountOptional)) ) { - LOG_W(FileSystem::Error( - "Failed mounting game \"" + game + "\"").what()); LOG_W("Mounting working directory instead."); fs.mount("."); } diff --git a/src/svc/FileSystem.cpp b/src/svc/FileSystem.cpp index e7d2b87..e1e5e07 100644 --- a/src/svc/FileSystem.cpp +++ b/src/svc/FileSystem.cpp @@ -8,10 +8,16 @@ #include +static std::string lastPhysFsError() +{ + char const* err = PHYSFS_getLastError(); + return err ? err : "OK"; +} + FileSystem::Error::Error(std::string const& msg, bool getLastError): std::runtime_error(msg + ( - getLastError ? std::string(": ") + PHYSFS_getLastError() : std::string())) { } + getLastError ? std::string(": ") + lastPhysFsError() : std::string())) { } @@ -243,9 +249,37 @@ bool FileSystem::mount( } if (!PHYSFS_mount(path.c_str(), mountPoint.c_str(), flags & appendPath)) { + Error err("", false); + if (flags & logWarnings || !(flags & mountOptional)) { + err = Error("Mounting \"" + path + "\" failed"); + if (flags & logWarnings) + LOG_W(err.what()); + } if (flags & mountOptional) return false; - throw Error ("Mounting \"" + path + "\" failed"); + throw err; } return true; } + + +bool FileSystem::mountFirstWorking( + std::vector const& paths, + std::string const& mountPoint, + int flags) +{ + int const mflags = flags & ~logWarnings | mountOptional; + std::string message = "Failed mounting all of the following:"; + for (auto const& path: paths) { + if (mount(path, mountPoint, mflags)) + return true; + else + message += "\n\t" + path + ": " + lastPhysFsError(); + } + if (flags & logWarnings) + LOG_W(message); + if (flags & mountOptional) + return false; + throw Error(message, false); +} + diff --git a/src/svc/FileSystem.hpp b/src/svc/FileSystem.hpp index 727f214..ad18462 100644 --- a/src/svc/FileSystem.hpp +++ b/src/svc/FileSystem.hpp @@ -6,10 +6,11 @@ #include #include #include +#include #include #include - +#include struct PHYSFS_File; @@ -96,13 +97,19 @@ class FileSystem: public Component { enum MountFlags { prependPath = 0, appendPath = 1, writeDirectory = 2, - mountOptional = 4}; + mountOptional = 4, + logWarnings = 8}; bool mount( std::string const& path, std::string const& mountPoint = std::string(), int flags = prependPath); + bool mountFirstWorking( + std::vector const& paths, + std::string const& mountPoint = std::string(), + int flags = prependPath); + private: FileSystem(); };