From 90b2c7fb10b244b781b84965a0d36f1f323ee94d Mon Sep 17 00:00:00 2001 From: Charles McGarvey Date: Wed, 3 Mar 2010 14:44:13 -0700 Subject: [PATCH 1/1] bugfix: resource file searching was broken --- README | 2 - src/Animation.cc | 14 ++++-- src/Animation.hh | 2 +- src/GameLayer.cc | 10 ++-- src/Main.cc | 3 +- src/Main.hh | 8 +-- src/Moof/Error.hh | 6 +-- src/Moof/Image.cc | 29 +++++------ src/Moof/Image.hh | 4 +- src/Moof/ModalDialog.hh | 20 +++++--- src/Moof/Resource.cc | 106 +++++++++++++++++++++++++++++----------- src/Moof/Resource.hh | 18 +++++-- src/Moof/Sound.cc | 24 +++------ src/Moof/Sound.hh | 2 +- src/Moof/Texture.cc | 22 +++------ src/Moof/Texture.hh | 2 +- src/Scene.cc | 10 ++-- src/Scene.hh | 2 +- src/TitleLayer.cc | 2 +- 19 files changed, 171 insertions(+), 115 deletions(-) diff --git a/README b/README index e86d940..7994e69 100644 --- a/README +++ b/README @@ -123,5 +123,3 @@ I haven't tried building with cygwin or mingw32 on an actual Windows machine, and I certainly haven't tried to do it with Visual Studio. You're on your own if you go that route. - - diff --git a/src/Animation.cc b/src/Animation.cc index 2a3d03a..6df8556 100644 --- a/src/Animation.cc +++ b/src/Animation.cc @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -151,13 +152,18 @@ public: void init(const std::string& name) { Mf::Script script; - std::string filePath = Animation::getPath(name); + std::string path(name); + + if (!Animation::getPath(path)) + { + Mf::Error(Mf::Error::RESOURCE_NOT_FOUND).raise(); + } script.importBaseLibrary(); importLogFunctions(script); importAnimationBindings(script); - if (script.doFile(filePath) != Mf::Script::SUCCESS) + if (script.doFile(path) != Mf::Script::SUCCESS) { std::string str; script[-1].get(str); @@ -322,8 +328,8 @@ unsigned Animation::getFrame() const * the "animations" subdirectory of any of the search directories. */ -std::string Animation::getPath(const std::string& name) +bool Animation::getPath(std::string& name) { - return Mf::Resource::getPath("animations/" + name + ".lua"); + return Mf::Resource::getPath(name, "animations/", "lua"); } diff --git a/src/Animation.hh b/src/Animation.hh index ac00679..d8651dd 100644 --- a/src/Animation.hh +++ b/src/Animation.hh @@ -56,7 +56,7 @@ public: void update(Mf::Scalar t, Mf::Scalar dt); unsigned getFrame() const; - static std::string getPath(const std::string& name); + static bool getPath(std::string& name); }; diff --git a/src/GameLayer.cc b/src/GameLayer.cc index 0be8eb7..8f2f4ec 100644 --- a/src/GameLayer.cc +++ b/src/GameLayer.cc @@ -28,13 +28,13 @@ void GameLayer::loadSceneLoader() mState.script.importStandardLibraries(); importLogFunctions(mState.script); - std::string loaderPath = Scene::getPath("loader"); - if (loaderPath == "") + std::string path("loader"); + if (!Scene::getPath(path)) { throw Mf::Error(Mf::Error::RESOURCE_NOT_FOUND, "loader"); } - Mf::Script::Result status = mState.script.doFile(loaderPath); + Mf::Script::Result status = mState.script.doFile(path); if (status != Mf::Script::SUCCESS) { std::string str; @@ -284,6 +284,8 @@ void GameLayer::setProjection() void GameLayer::setProjection(Mf::Scalar width, Mf::Scalar height) { - mState.camera.setProjection(cml::rad(45.0), width / height, 1.0, 200.0); + mState.camera.setProjection(cml::rad(45.0), + width / height, + SCALAR(1.0), SCALAR(200.0)); } diff --git a/src/Main.cc b/src/Main.cc index 7b31ae4..fc84ceb 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -128,7 +128,8 @@ std::string Main::getConfigPath() // 3. $HOME/.yoinkrc // 4. YOINKRC (environment) - std::string path = Mf::Resource::getPath("yoinkrc"); + std::string path("yoinkrc"); + Mf::Resource::getPath(path); #if !defined(_WIN32) path += ":/etc/yoinkrc"; diff --git a/src/Main.hh b/src/Main.hh index a5ce293..b6a6684 100644 --- a/src/Main.hh +++ b/src/Main.hh @@ -27,11 +27,13 @@ #include -namespace Mf { -class Settings; -class View; +namespace Mf +{ + class Settings; + class View; } + class Main; typedef boost::shared_ptr
MainP; diff --git a/src/Moof/Error.hh b/src/Moof/Error.hh index 78c894f..494dd60 100644 --- a/src/Moof/Error.hh +++ b/src/Moof/Error.hh @@ -30,8 +30,8 @@ public: NONE = 0, // - ALC_INIT, // description FASTEVENTS_INIT, // description - OPENAL_INIT, // description FILE_NOT_FOUND, // path of missing file + OPENAL_INIT, // description RESOURCE_NOT_FOUND, // name of missing resource SCRIPT_ERROR, // description SDL_INIT, // description @@ -46,10 +46,10 @@ public: } virtual ~Error() throw() {} - void init(unsigned code, const std::string& what = "") + void init(unsigned code = NONE, const std::string& what = "") { - mWhat[sizeof(mWhat)-1] = '\0'; strncpy(mWhat, what.c_str(), sizeof(mWhat)-1); + mWhat[sizeof(mWhat)-1] = '\0'; mCode = code; } diff --git a/src/Moof/Image.cc b/src/Moof/Image.cc index 54e9972..2237c88 100644 --- a/src/Moof/Image.cc +++ b/src/Moof/Image.cc @@ -70,13 +70,13 @@ public: } - bool init(const std::string& name, bool flipped = false) + void init(const std::string& name, bool flipped = false) { - std::string path = Image::getPath(name); + std::string path(name); logInfo << "opening image file " << path << std::endl; - FILE* fp = fopen(path.c_str(), "rb"); - if (!fp) return false; + FILE* fp = Image::openFile(path); + if (!fp) return; png_byte signature[8]; size_t bytesRead; @@ -217,8 +217,6 @@ public: pngInfo ? &pngInfo : 0, pngInfoEnd ? &pngInfoEnd : 0); fclose(fp); - - return mContext; } @@ -300,19 +298,14 @@ void Image::setAsIcon() const } -std::string Image::getPath(const std::string& name) +bool Image::getPath(std::string& name) { - if (boost::find_last(name, ".png")) - { - return Resource::getPath(name); - } - else - { - std::string path("images/"); - path += name; - path += ".png"; - return Resource::getPath(path); - } + return Resource::getPath(name, "images/", "png"); +} + +FILE* Image::openFile(std::string& name) +{ + return Resource::openFile(name, "images/", "png"); } diff --git a/src/Moof/Image.hh b/src/Moof/Image.hh index d923b0c..6c36cdd 100644 --- a/src/Moof/Image.hh +++ b/src/Moof/Image.hh @@ -53,10 +53,12 @@ public: void setAsIcon() const; - static std::string getPath(const std::string& name); + static bool getPath(std::string& name); private: + static FILE* openFile(std::string& name); + class Impl; boost::shared_ptr mImpl; }; diff --git a/src/Moof/ModalDialog.hh b/src/Moof/ModalDialog.hh index d56d8ea..1e96dd4 100644 --- a/src/Moof/ModalDialog.hh +++ b/src/Moof/ModalDialog.hh @@ -132,10 +132,13 @@ struct ModalDialog "%s", text2.c_str()); gtk_window_set_title(GTK_WINDOW(dialog), title.c_str()); - std::string iconPath = Resource::getPath(PACKAGE".png"); - GdkPixbuf* iconPixbuf = gdk_pixbuf_new_from_file(iconPath.c_str(), - NULL); - gtk_window_set_icon(GTK_WINDOW(dialog), iconPixbuf); + std::string iconPath(PACKAGE".png"); + if (Resource::getPath(iconPath)) + { + GdkPixbuf* iconPixbuf = gdk_pixbuf_new_from_file(iconPath.c_str(), + NULL); + gtk_window_set_icon(GTK_WINDOW(dialog), iconPixbuf); + } gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); @@ -169,9 +172,12 @@ struct ModalDialog dialog.setInformativeText(text2.c_str()); dialog.setStandardButtons(QMessageBox::Close); - std::string iconPath = Resource::getPath(PACKAGE".png"); - QIcon icon(iconPath.c_str()); - dialog.setWindowIcon(icon); + std::string iconPath(PACKAGE".png"); + if (Resource::getPath(iconPath)) + { + QIcon icon(iconPath.c_str()); + dialog.setWindowIcon(icon); + } dialog.exec(); diff --git a/src/Moof/Resource.cc b/src/Moof/Resource.cc index b04acd7..d1dc5fa 100644 --- a/src/Moof/Resource.cc +++ b/src/Moof/Resource.cc @@ -9,8 +9,6 @@ * **************************************************************************/ -#include - #include #include "Log.hh" @@ -24,62 +22,114 @@ namespace Mf { std::vector Resource::gSearchPaths; -void Resource::addSearchPaths(const std::string& path) +void Resource::addSearchPaths(const std::string& paths) { - std::vector paths; - boost::split(paths, path, boost::is_any_of(":")); + std::vector pathList; + boost::split(pathList, paths, boost::is_any_of(":")); - addSearchPaths(paths); + addSearchPaths(pathList); } -void Resource::addSearchPaths(const std::vector& path) +void Resource::addSearchPaths(const std::vector& pathList) { std::vector::const_iterator it; - - for (it = path.begin(); it != path.end(); ++it) + for (it = pathList.begin(); it != pathList.end(); ++it) { - std::string onePath(*it); + std::string path(*it); - ASSERT(!onePath.empty() && "empty search path string"); + ASSERT(!path.empty() && "empty search path string"); // add a slash if there isn't one already - if (*onePath.rbegin() != '/') - { - onePath += '/'; - } + if (*path.rbegin() != '/') path += '/'; #if defined(_WIN32) - boost::replace_all(onePath, "/", "\\"); + boost::replace_all(path, "/", "\\"); #endif - gSearchPaths.push_back(onePath); - logInfo << "added search path " << onePath << std::endl; + gSearchPaths.push_back(path); + logInfo << "added search path " << path << std::endl; } } -std::string Resource::getPath(const std::string& name) +std::string Resource::getPath(const std::string& path, + const std::string& prefix, + const std::string& extension) { - std::vector::iterator it; + std::string realPath(path); + if (getPath(realPath, prefix, extension)) return realPath; + + return std::string(); +} - std::string path(name); +bool Resource::getPath(std::string& path, + const std::string& prefix, + const std::string& extension) +{ + FILE* file = openFile(path, prefix, extension); + if (file) + { + fclose(file); + return true; + } + return false; +} + +FILE* Resource::openFile(std::string& path, + std::string prefix, + const std::string& extension, + const std::string& mode) +{ #if defined(_WIN32) + // Windows always has to be the odd one. boost::replace_all(path, "/", "\\"); + boost::replace_all(prefix, "/", "\\"); #endif + std::vector preList; + boost::split(preList, prefix, boost::is_any_of(":")); + std::vector postList; + boost::split(postList, extension, boost::is_any_of(":")); + + std::vector::iterator it; for (it = gSearchPaths.begin(); it != gSearchPaths.end(); ++it) { - std::string fullPath(*it); - fullPath += path; + std::vector::iterator jt; + for (jt = preList.begin(); jt != preList.end(); ++jt) + { + std::vector::iterator kt; + for (kt = postList.begin(); kt != postList.end(); ++kt) + { + std::string realPath(*it); + realPath += *jt; + realPath += path; + realPath += "."; + realPath += *kt; + + FILE* file = fopen(realPath.c_str(), mode.c_str()); + if (file) + { + path = realPath; + return file; + } + } + } - if (access(fullPath.c_str(), R_OK) == 0) return fullPath; - } + // check path relative to search path + std::string realPath(*it); + realPath += path; - logWarning << "cannot find resource " << name << std::endl; + FILE* file = fopen(realPath.c_str(), mode.c_str()); + if (file) + { + path = realPath; + return file; + } + } - // empty string - return std::string(); + // last ditch effort; maybe it's already a path to a valid resource + return fopen(path.c_str(), mode.c_str()); } diff --git a/src/Moof/Resource.hh b/src/Moof/Resource.hh index 8446d08..db6fe13 100644 --- a/src/Moof/Resource.hh +++ b/src/Moof/Resource.hh @@ -17,6 +17,7 @@ * Interface for textures, sounds, and other types of resources. */ +#include #include #include @@ -40,8 +41,8 @@ public: * @param directory Path to a directory. */ - static void addSearchPaths(const std::string& path); - static void addSearchPaths(const std::vector& path); + static void addSearchPaths(const std::string& paths); + static void addSearchPaths(const std::vector& pathList); /** * Get the path to a resource of a given name. @@ -50,7 +51,18 @@ public: * @return The first path found which resolves to a file. */ - static std::string getPath(const std::string& name); + static std::string getPath(const std::string& path, + const std::string& prefix = "", + const std::string& extension = ""); + + static bool getPath(std::string& path, + const std::string& prefix = "", + const std::string& extension = ""); + + static FILE* openFile(std::string& path, + std::string prefix = "", + const std::string& extension = "", + const std::string& mode = "rb"); private: diff --git a/src/Moof/Sound.cc b/src/Moof/Sound.cc index c78b35c..ffa270e 100644 --- a/src/Moof/Sound.cc +++ b/src/Moof/Sound.cc @@ -75,12 +75,14 @@ public: mOggStream.datasource = 0; } - std::string path = Sound::getPath(name); - int result = ov_fopen((char*)path.c_str(), &mOggStream); + std::string path(name); + if (!Sound::getPath(path)) + { + Error(Error::RESOURCE_NOT_FOUND, path).raise(); + } - if (result < 0) + if (ov_fopen((char*)path.c_str(), &mOggStream) < 0) { - logWarning << "couldn't load sound: " << path << std::endl; Error(Error::UNKNOWN_AUDIO_FORMAT, path).raise(); } @@ -572,19 +574,9 @@ void Sound::setListenerOrientation(const Vector3& forward, } -std::string Sound::getPath(const std::string& name) +bool Sound::getPath(std::string& name) { - if (boost::find_last(name, ".ogg")) - { - return Resource::getPath(name); - } - else - { - std::string path("sounds/"); - path += name; - path += ".ogg"; - return Resource::getPath(path); - } + return Resource::getPath(name, "sounds/", "ogg"); } diff --git a/src/Moof/Sound.hh b/src/Moof/Sound.hh index d3cfa89..bbfef12 100644 --- a/src/Moof/Sound.hh +++ b/src/Moof/Sound.hh @@ -70,7 +70,7 @@ public: static void setListenerOrientation(const Vector3& forward, const Vector3& up); - static std::string getPath(const std::string& name); + static bool getPath(std::string& name); protected: diff --git a/src/Moof/Texture.cc b/src/Moof/Texture.cc index 7d82e2d..3ca067a 100644 --- a/src/Moof/Texture.cc +++ b/src/Moof/Texture.cc @@ -215,7 +215,9 @@ public: void init(const std::string& name) { - std::string path = Texture::getPath(name); + std::string path(name); + + Texture::getPath(path); mImage = Image::alloc(path); if (!mImage->isValid()) @@ -395,8 +397,8 @@ public: GLuint Texture::Impl::gObject = 0; -Texture::Texture(const std::string& name) : - Image(Texture::getPath(name)), +Texture::Texture(const std::string& name) : // TODO hmm.. + Image(name), // pass through mImpl(Texture::Impl::getInstance(name)) {} @@ -490,19 +492,9 @@ bool Texture::getTileCoords(TileIndex index, Scalar coords[8], } -std::string Texture::getPath(const std::string& name) +bool Texture::getPath(std::string& name) { - if (boost::find_last(name, ".png")) - { - return Resource::getPath(name); - } - else - { - std::string path("textures/"); - path += name; - path += ".png"; - return Resource::getPath(path); - } + return Resource::getPath(name, "textures/", "png"); } diff --git a/src/Moof/Texture.hh b/src/Moof/Texture.hh index 27ec414..f352550 100644 --- a/src/Moof/Texture.hh +++ b/src/Moof/Texture.hh @@ -100,7 +100,7 @@ public: Orientation what) const; - static std::string getPath(const std::string& name); + static bool getPath(std::string& name); private: diff --git a/src/Scene.cc b/src/Scene.cc index bfc788a..afbfa44 100644 --- a/src/Scene.cc +++ b/src/Scene.cc @@ -195,15 +195,15 @@ struct Scene::Impl : public Mf::Manager Mf::Script::Result load(Mf::Settings& settings, Mf::Script& script) { - std::string filePath = Scene::getPath(getName()); - if (filePath == "") + std::string path(getName()); + if (!Scene::getPath(path)) { script.push("the scene file could not be found"); return Mf::Script::FILE_ERROR; } importSceneBindings(settings, script); - return script.doFile(filePath); + return script.doFile(path); } @@ -609,8 +609,8 @@ bool Scene::checkForCollision(Character& character) } -std::string Scene::getPath(const std::string& name) +bool Scene::getPath(std::string& name) { - return Mf::Resource::getPath("scenes/" + name + ".lua"); + return Mf::Resource::getPath(name, "scenes/", "lua"); } diff --git a/src/Scene.hh b/src/Scene.hh index 31a4ecd..d92784a 100644 --- a/src/Scene.hh +++ b/src/Scene.hh @@ -58,7 +58,7 @@ public: std::list::Contact>& hits) const; bool checkForCollision(Character& character); - static std::string getPath(const std::string& name); + static bool getPath(std::string& name); }; diff --git a/src/TitleLayer.cc b/src/TitleLayer.cc index b865be0..9e33c36 100644 --- a/src/TitleLayer.cc +++ b/src/TitleLayer.cc @@ -45,7 +45,7 @@ bool TitleLayer::handleEvent(const Mf::Event& event) case SDL_KEYUP: if (event.key.keysym.sym == SDLK_ESCAPE) { - parent().removeChild(this); + parent().stop(); return true; } -- 2.43.0