From 969fbb189d16d87d26ceab29795644588fb90a32 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 21 May 2011 11:07:03 +0300 Subject: [PATCH] All textures are are now searched first from the directory specified by the texture_path setting. --- src/clientobject.cpp | 9 +-- src/game.cpp | 38 ++++++------ src/main.cpp | 6 +- src/mapblockobject.cpp | 6 +- src/mapblockobject.h | 4 +- src/mineral.cpp | 2 - src/mineral.h | 3 +- src/player.cpp | 4 +- src/texture.h | 134 ----------------------------------------- src/tile.cpp | 62 +++++++++++++++---- src/tile.h | 18 +++++- src/utility.h | 12 ++-- 12 files changed, 108 insertions(+), 190 deletions(-) delete mode 100644 src/texture.h diff --git a/src/clientobject.cpp b/src/clientobject.cpp index 9e4bf75..402535f 100644 --- a/src/clientobject.cpp +++ b/src/clientobject.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "constants.h" #include "utility.h" #include "environment.h" +#include "tile.h" /* ClientActiveObject @@ -114,7 +115,7 @@ void TestCAO::addToScene(scene::ISceneManager *smgr) buf->getMaterial().setFlag(video::EMF_LIGHTING, false); buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); buf->getMaterial().setTexture - (0, driver->getTexture(porting::getDataPath("rat.png").c_str())); + (0, driver->getTexture(getTexturePath("rat.png").c_str())); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; @@ -237,7 +238,7 @@ void ItemCAO::addToScene(scene::ISceneManager *smgr) //buf->getMaterial().setTexture(0, NULL); // Initialize with the stick texture buf->getMaterial().setTexture - (0, driver->getTexture(porting::getDataPath("stick.png").c_str())); + (0, driver->getTexture(getTexturePath("stick.png").c_str())); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; @@ -443,7 +444,7 @@ void RatCAO::addToScene(scene::ISceneManager *smgr) buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); //buf->getMaterial().setTexture(0, NULL); buf->getMaterial().setTexture - (0, driver->getTexture(porting::getDataPath("rat.png").c_str())); + (0, driver->getTexture(getTexturePath("rat.png").c_str())); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; @@ -604,7 +605,7 @@ void Oerkki1CAO::addToScene(scene::ISceneManager *smgr) buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); //buf->getMaterial().setTexture(0, NULL); buf->getMaterial().setTexture - (0, driver->getTexture(porting::getDataPath("oerkki1.png").c_str())); + (0, driver->getTexture(getTexturePath("oerkki1.png").c_str())); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; diff --git a/src/game.cpp b/src/game.cpp index 69e673f..b1a804a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -345,7 +345,7 @@ void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font, */ { video::ITexture *heart_texture = - driver->getTexture(porting::getDataPath("heart.png").c_str()); + driver->getTexture(getTexturePath("heart.png").c_str()); v2s32 p = pos + v2s32(0, -20); for(s32 i=0; i= 0.5) { skybox = smgr->addSkyBoxSceneNode( - driver->getTexture(porting::getDataPath("skybox2.png").c_str()), - driver->getTexture(porting::getDataPath("skybox3.png").c_str()), - driver->getTexture(porting::getDataPath("skybox1.png").c_str()), - driver->getTexture(porting::getDataPath("skybox1.png").c_str()), - driver->getTexture(porting::getDataPath("skybox1.png").c_str()), - driver->getTexture(porting::getDataPath("skybox1.png").c_str())); + driver->getTexture(getTexturePath("skybox2.png").c_str()), + driver->getTexture(getTexturePath("skybox3.png").c_str()), + driver->getTexture(getTexturePath("skybox1.png").c_str()), + driver->getTexture(getTexturePath("skybox1.png").c_str()), + driver->getTexture(getTexturePath("skybox1.png").c_str()), + driver->getTexture(getTexturePath("skybox1.png").c_str())); } else if(brightness >= 0.2) { skybox = smgr->addSkyBoxSceneNode( - driver->getTexture(porting::getDataPath("skybox2_dawn.png").c_str()), - driver->getTexture(porting::getDataPath("skybox3_dawn.png").c_str()), - driver->getTexture(porting::getDataPath("skybox1_dawn.png").c_str()), - driver->getTexture(porting::getDataPath("skybox1_dawn.png").c_str()), - driver->getTexture(porting::getDataPath("skybox1_dawn.png").c_str()), - driver->getTexture(porting::getDataPath("skybox1_dawn.png").c_str())); + driver->getTexture(getTexturePath("skybox2_dawn.png").c_str()), + driver->getTexture(getTexturePath("skybox3_dawn.png").c_str()), + driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()), + driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()), + driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()), + driver->getTexture(getTexturePath("skybox1_dawn.png").c_str())); } else { skybox = smgr->addSkyBoxSceneNode( - driver->getTexture(porting::getDataPath("skybox2_night.png").c_str()), - driver->getTexture(porting::getDataPath("skybox3_night.png").c_str()), - driver->getTexture(porting::getDataPath("skybox1_night.png").c_str()), - driver->getTexture(porting::getDataPath("skybox1_night.png").c_str()), - driver->getTexture(porting::getDataPath("skybox1_night.png").c_str()), - driver->getTexture(porting::getDataPath("skybox1_night.png").c_str())); + driver->getTexture(getTexturePath("skybox2_night.png").c_str()), + driver->getTexture(getTexturePath("skybox3_night.png").c_str()), + driver->getTexture(getTexturePath("skybox1_night.png").c_str()), + driver->getTexture(getTexturePath("skybox1_night.png").c_str()), + driver->getTexture(getTexturePath("skybox1_night.png").c_str()), + driver->getTexture(getTexturePath("skybox1_night.png").c_str())); } } diff --git a/src/main.cpp b/src/main.cpp index 184643b..7b33bdb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -913,7 +913,7 @@ void drawMenuBackground(video::IVideoDriver* driver) core::dimension2d screensize = driver->getScreenSize(); video::ITexture *bgtexture = - driver->getTexture(porting::getDataPath("mud.png").c_str()); + driver->getTexture(getTexturePath("mud.png").c_str()); if(bgtexture) { s32 texturesize = 128; @@ -933,7 +933,7 @@ void drawMenuBackground(video::IVideoDriver* driver) } video::ITexture *logotexture = - driver->getTexture(porting::getDataPath("menulogo.png").c_str()); + driver->getTexture(getTexturePath("menulogo.png").c_str()); if(logotexture) { v2s32 logosize(logotexture->getOriginalSize().Width, @@ -1288,7 +1288,7 @@ int main(int argc, char *argv[]) guienv = device->getGUIEnvironment(); gui::IGUISkin* skin = guienv->getSkin(); - gui::IGUIFont* font = guienv->getFont(porting::getDataPath("fontlucida.png").c_str()); + gui::IGUIFont* font = guienv->getFont(getTexturePath("fontlucida.png").c_str()); if(font) skin->setFont(font); else diff --git a/src/mapblockobject.cpp b/src/mapblockobject.cpp index d05eee8..009163a 100644 --- a/src/mapblockobject.cpp +++ b/src/mapblockobject.cpp @@ -283,7 +283,7 @@ void RatObject::addToScene(scene::ISceneManager *smgr) buf->getMaterial().setFlag(video::EMF_LIGHTING, false); buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); buf->getMaterial().setTexture - (0, driver->getTexture(porting::getDataPath("rat.png").c_str())); + (0, driver->getTexture(getTexturePath("rat.png").c_str())); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; @@ -413,7 +413,7 @@ void PlayerObject::addToScene(scene::ISceneManager *smgr) // Set material buf->getMaterial().setFlag(video::EMF_LIGHTING, false); //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); - buf->getMaterial().setTexture(0, driver->getTexture(porting::getDataPath("player.png").c_str())); + buf->getMaterial().setTexture(0, driver->getTexture(getTexturePath("player.png").c_str())); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; @@ -437,7 +437,7 @@ void PlayerObject::addToScene(scene::ISceneManager *smgr) // Set material buf->getMaterial().setFlag(video::EMF_LIGHTING, false); //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); - buf->getMaterial().setTexture(0, driver->getTexture(porting::getDataPath("player_back.png").c_str())); + buf->getMaterial().setTexture(0, driver->getTexture(getTexturePath("player_back.png").c_str())); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; diff --git a/src/mapblockobject.h b/src/mapblockobject.h index db8006f..8044947 100644 --- a/src/mapblockobject.h +++ b/src/mapblockobject.h @@ -432,7 +432,7 @@ public: buf->getMaterial().setFlag(video::EMF_LIGHTING, false); //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); buf->getMaterial().setTexture - (0, driver->getTexture(porting::getDataPath("sign.png").c_str())); + (0, driver->getTexture(getTexturePath("sign.png").c_str())); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; @@ -456,7 +456,7 @@ public: buf->getMaterial().setFlag(video::EMF_LIGHTING, false); //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); buf->getMaterial().setTexture - (0, driver->getTexture(porting::getDataPath("sign_back.png").c_str())); + (0, driver->getTexture(getTexturePath("sign_back.png").c_str())); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; diff --git a/src/mineral.cpp b/src/mineral.cpp index e61c25c..038251f 100644 --- a/src/mineral.cpp +++ b/src/mineral.cpp @@ -27,7 +27,6 @@ const char *mineral_filenames[MINERAL_COUNT] = "mineral_iron.png" }; -//textureid_t mineral_textures[MINERAL_COUNT] = {0}; std::string mineral_textures[MINERAL_COUNT]; void init_mineral() @@ -40,7 +39,6 @@ void init_mineral() } } -//textureid_t mineral_block_texture(u8 mineral) std::string mineral_block_texture(u8 mineral) { if(mineral >= MINERAL_COUNT) diff --git a/src/mineral.h b/src/mineral.h index fcc1bd1..970ff1f 100644 --- a/src/mineral.h +++ b/src/mineral.h @@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define MINERAL_HEADER #include "inventory.h" -#include "texture.h" +#include "tile.h" /* Minerals @@ -39,7 +39,6 @@ void init_mineral(); #define MINERAL_COUNT 3 -//textureid_t mineral_block_texture(u8 mineral); std::string mineral_block_texture(u8 mineral); inline CraftItem * getDiggedMineralItem(u8 mineral) diff --git a/src/player.cpp b/src/player.cpp index 5392447..12f18de 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -261,7 +261,7 @@ RemotePlayer::RemotePlayer( // Set material buf->getMaterial().setFlag(video::EMF_LIGHTING, false); //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); - buf->getMaterial().setTexture(0, driver->getTexture(porting::getDataPath("player.png").c_str())); + buf->getMaterial().setTexture(0, driver->getTexture(getTexturePath("player.png").c_str())); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; @@ -285,7 +285,7 @@ RemotePlayer::RemotePlayer( // Set material buf->getMaterial().setFlag(video::EMF_LIGHTING, false); //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); - buf->getMaterial().setTexture(0, driver->getTexture(porting::getDataPath("player_back.png").c_str())); + buf->getMaterial().setTexture(0, driver->getTexture(getTexturePath("player_back.png").c_str())); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; diff --git a/src/texture.h b/src/texture.h deleted file mode 100644 index d831078..0000000 --- a/src/texture.h +++ /dev/null @@ -1,134 +0,0 @@ -/* -Minetest-c55 -Copyright (C) 2010 celeron55, Perttu Ahola - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef TEXTURE_HEADER -#define TEXTURE_HEADER - -// This file now contains all that was here -#include "tile.h" - -// TODO: Remove this -typedef u16 textureid_t; - -#if 0 - -#include "common_irrlicht.h" -//#include "utility.h" -#include "debug.h" - -/* - All textures are given a "texture id". - 0 = nothing (a NULL pointer texture) -*/ -typedef u16 textureid_t; - -/* - Every texture in the game can be specified by this. - - It exists instead of specification strings because arbitary - texture combinations for map nodes are handled using this, - and strings are too slow for that purpose. - - Plain texture pointers are not used because they don't contain - content information by themselves. A texture can be completely - reconstructed by just looking at this, while this also is a - fast unique key to containers. -*/ - -#define TEXTURE_SPEC_TEXTURE_COUNT 4 - -struct TextureSpec -{ - TextureSpec() - { - clear(); - } - - TextureSpec(textureid_t id0) - { - clear(); - tids[0] = id0; - } - - TextureSpec(textureid_t id0, textureid_t id1) - { - clear(); - tids[0] = id0; - tids[1] = id1; - } - - void clear() - { - for(u32 i=0; i= other.tids[i]) - return false; - } - return true; - } - - // Ids of textures. They are blit on each other. - textureid_t tids[TEXTURE_SPEC_TEXTURE_COUNT]; -}; - -#endif - -#endif diff --git a/src/tile.cpp b/src/tile.cpp index 5b89c69..dabc1dc 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -1,6 +1,6 @@ /* Minetest-c55 -Copyright (C) 2010 celeron55, Perttu Ahola +Copyright (C) 2010-2011 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,6 +21,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "debug.h" #include "main.h" // for g_settings #include "filesys.h" +#include "utility.h" + +/* + A cache from texture name to texture path +*/ +MutexedMap g_texturename_to_path_cache; /* Replaces the filename extension. @@ -30,7 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., -> image = "a/image.jpg" Returns true on success. */ -inline bool replace_ext(std::string &path, const char *ext) +static bool replace_ext(std::string &path, const char *ext) { if(ext == NULL) return false; @@ -61,7 +67,7 @@ inline bool replace_ext(std::string &path, const char *ext) If failed, return "". */ -inline std::string getImagePath(std::string path) +static std::string getImagePath(std::string path) { // A NULL-ended list of possible image extensions const char *extensions[] = { @@ -86,25 +92,55 @@ inline std::string getImagePath(std::string path) /* Gets the path to a texture by first checking if the texture exists in texture_path and if not, using the data path. + + Checks all supported extensions by replacing the original extension. + + If not found, returns "". + + Utilizes a thread-safe cache. */ -inline std::string getTexturePath(std::string filename) +std::string getTexturePath(const std::string &filename) { + std::string fullpath = ""; + /* + Check from cache + */ + bool incache = g_texturename_to_path_cache.get(filename, &fullpath); + if(incache) + return fullpath; + + /* + Check from texture_path + */ std::string texture_path = g_settings.get("texture_path"); if(texture_path != "") { - std::string fullpath = texture_path + '/' + filename; - // Check all filename extensions - fullpath = getImagePath(fullpath); - // If found, return it - if(fullpath != "") - return fullpath; + std::string testpath = texture_path + '/' + filename; + // Check all filename extensions. Returns "" if not found. + fullpath = getImagePath(testpath); } - std::string fullpath = porting::getDataPath(filename.c_str()); - // Check all filename extensions - fullpath = getImagePath(fullpath); + + /* + Check from default data directory + */ + if(fullpath == "") + { + std::string testpath = porting::getDataPath(filename.c_str()); + // Check all filename extensions. Returns "" if not found. + fullpath = getImagePath(testpath); + } + + // Add to cache (also an empty result is cached) + g_texturename_to_path_cache.set(filename, fullpath); + + // Finally return it return fullpath; } +/* + TextureSource +*/ + TextureSource::TextureSource(IrrlichtDevice *device): m_device(device), m_main_atlas_image(NULL), diff --git a/src/tile.h b/src/tile.h index f062859..216d765 100644 --- a/src/tile.h +++ b/src/tile.h @@ -1,6 +1,6 @@ /* Minetest-c55 -Copyright (C) 2010 celeron55, Perttu Ahola +Copyright (C) 2010-2011 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,6 +25,22 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "utility.h" #include +/* + tile.{h,cpp}: Texture handling stuff. +*/ + +/* + Gets the path to a texture by first checking if the texture exists + in texture_path and if not, using the data path. + + Checks all supported extensions by replacing the original extension. + + If not found, returns "". + + Utilizes a thread-safe cache. +*/ +std::string getTexturePath(const std::string &filename); + /* Specifies a texture in an atlas. diff --git a/src/utility.h b/src/utility.h index 84838c0..cc8891a 100644 --- a/src/utility.h +++ b/src/utility.h @@ -1766,12 +1766,12 @@ private: core::list m_list; }; -#if 0 +#if 1 template -class MutexedCache +class MutexedMap { public: - MutexedCache() + MutexedMap() { m_mutex.Init(); assert(m_mutex.IsInitialized()); @@ -1793,8 +1793,10 @@ public: if(n == NULL) return false; - - *result = n->getValue(); + + if(result != NULL) + *result = n->getValue(); + return true; }