diff --git a/src/modules/filesystem/physfs/Filesystem.cpp b/src/modules/filesystem/physfs/Filesystem.cpp index 4b4af3db0..f00d63165 100644 --- a/src/modules/filesystem/physfs/Filesystem.cpp +++ b/src/modules/filesystem/physfs/Filesystem.cpp @@ -67,6 +67,13 @@ namespace physfs releaseSet = true; } + bool Filesystem::isRelease() const + { + if (!releaseSet) + return false; + return release; + } + bool Filesystem::setIdentity( const char * ident ) { if(!isInited) diff --git a/src/modules/filesystem/physfs/Filesystem.h b/src/modules/filesystem/physfs/Filesystem.h index 327022886..d87881059 100644 --- a/src/modules/filesystem/physfs/Filesystem.h +++ b/src/modules/filesystem/physfs/Filesystem.h @@ -119,6 +119,7 @@ namespace physfs void init(const char * arg0); void setRelease(bool release); + bool isRelease() const; /** * This sets up the save directory. If the diff --git a/src/modules/filesystem/physfs/wrap_Filesystem.cpp b/src/modules/filesystem/physfs/wrap_Filesystem.cpp index 6786b90ed..c5575ffc0 100644 --- a/src/modules/filesystem/physfs/wrap_Filesystem.cpp +++ b/src/modules/filesystem/physfs/wrap_Filesystem.cpp @@ -297,6 +297,59 @@ namespace physfs return 1; } + inline const char * library_extension() + { +#ifdef LOVE_WINDOWS + return ".dll"; +#elif defined(LOVE_MACOSX) || defined(LOVE_MACOS) + return ".dylib"; +#else + return ".so"; +#endif + } + + int extloader(lua_State * L) + { + const char * filename = lua_tostring(L, -1); + std::string tokenized_name(filename); + std::string tokenized_function(filename); + + for (int i = 0; i < tokenized_name.size(); i++) + { + if (tokenized_name[i] == '.') + { + tokenized_name[i] = '/'; + tokenized_function[i] = '_'; + } + } + + tokenized_name += library_extension(); + + void * handle = SDL_LoadObject((std::string(instance->getAppdataDirectory()) + LOVE_PATH_SEPARATOR LOVE_APPDATA_FOLDER LOVE_PATH_SEPARATOR + tokenized_name).c_str()); + if (!handle && instance->isRelease()) + handle = SDL_LoadObject((std::string(instance->getSaveDirectory()) + LOVE_PATH_SEPARATOR + tokenized_name).c_str()); + + if (!handle) + { + lua_pushfstring(L, "\n\tno extension \"%s\" in LOVE paths.\n", filename); + return 1; + } + + void * func = SDL_LoadFunction(handle, ("loveopen_" + tokenized_function).c_str()); + if (!func) + func = SDL_LoadFunction(handle, ("luaopen_" + tokenized_function).c_str()); + + if (!func) + { + SDL_UnloadObject(handle); + lua_pushfstring(L, "\n\textension \"%s\" is incompatible.\n", filename); + return 1; + } + + lua_pushcfunction(L, (lua_CFunction) func); + return 1; + } + // List of functions to wrap. static const luaL_Reg functions[] = { { "init", w_init }, @@ -337,6 +390,7 @@ namespace physfs { instance = new Filesystem(); love::luax_register_searcher(L, loader); + love::luax_register_searcher(L, extloader); } catch(Exception & e) { diff --git a/src/modules/filesystem/physfs/wrap_Filesystem.h b/src/modules/filesystem/physfs/wrap_Filesystem.h index a7307e355..5bd348081 100644 --- a/src/modules/filesystem/physfs/wrap_Filesystem.h +++ b/src/modules/filesystem/physfs/wrap_Filesystem.h @@ -26,6 +26,9 @@ #include "wrap_File.h" #include "wrap_FileData.h" +// SDL +#include + namespace love { namespace filesystem @@ -60,6 +63,7 @@ namespace physfs int w_load(lua_State * L); int w_getLastModified(lua_State * L); int loader(lua_State * L); + int extloader(lua_State * L); extern "C" LOVE_EXPORT int luaopen_love_filesystem(lua_State * L); } // physfs