X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Ftile.cpp;h=1f4456653f5a1867e60defac5eb03a7dd3dc79cd;hb=9a22d02903549c09f059b12f0ec06ea12a19abbb;hp=4a6523aca5d255a9174ea6d2e6b4817ffc77d16d;hpb=607f548712ae5a41eceb668085c87d10089849b9;p=dragonfireclient.git diff --git a/src/tile.cpp b/src/tile.cpp index 4a6523aca..1f4456653 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -19,6 +19,91 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "tile.h" #include "debug.h" +#include "main.h" // for g_settings +#include "filesys.h" + +/* + Replaces the filename extension. + eg: + std::string image = "a/image.png" + replace_ext(image, "jpg") + -> image = "a/image.jpg" + Returns true on success. +*/ +inline bool replace_ext(std::string &path, const char *ext) +{ + if(ext == NULL) + return false; + // Find place of last dot, fail if \ or / found. + s32 last_dot_i = -1; + for(s32 i=path.size()-1; i>=0; i--) + { + if(path[i] == '.') + { + last_dot_i = i; + break; + } + + if(path[i] == '\\' || path[i] == '/') + break; + } + // If not found, return an empty string + if(last_dot_i == -1) + return false; + // Else make the new path + path = path.substr(0, last_dot_i+1) + ext; + return true; +} + +/* + Find out the full path of an image by trying different filename + extensions. + + If failed, return "". +*/ +inline std::string getImagePath(std::string path) +{ + // A NULL-ended list of possible image extensions + const char *extensions[] = { + "png", "jpg", "bmp", "tga", + "pcx", "ppm", "psd", "wal", "rgb", + NULL + }; + + const char **ext = extensions; + do{ + bool r = replace_ext(path, *ext); + if(r == false) + return ""; + if(fs::PathExists(path)) + return path; + } + while((++ext) != NULL); + + return ""; +} + +/* + Gets the path to a texture by first checking if the texture exists + in texture_path and if not, using the data path. +*/ +inline std::string getTexturePath(std::string filename) +{ + 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 fullpath = porting::getDataPath(filename.c_str()); + // Check all filename extensions + fullpath = getImagePath(fullpath); + return fullpath; +} TextureSource::TextureSource(IrrlichtDevice *device): m_device(device), @@ -36,7 +121,10 @@ TextureSource::TextureSource(IrrlichtDevice *device): m_name_to_id[""] = 0; // Build main texture atlas - buildMainAtlas(); + if(g_settings.getBool("enable_texture_atlas")) + buildMainAtlas(); + else + dstream<<"INFO: Not building texture atlas."<createImageFromFile( - porting::getDataPath(name.c_str()).c_str()); + getTexturePath(name.c_str()).c_str()); if(img == NULL) continue; @@ -432,6 +520,25 @@ void TextureSource::buildMainAtlas() } core::dimension2d dim = img2->getDimension(); + + // Don't add to atlas if image is large + core::dimension2d max_size_in_atlas(32,32); + if(dim.Width > max_size_in_atlas.Width + || dim.Height > max_size_in_atlas.Height) + { + dstream<<"INFO: TextureSource::buildMainAtlas(): Not adding " + <<"\""< atlas_dim.Height) + { + dstream<<"WARNING: TextureSource::buildMainAtlas(): " + <<"Atlas is full, not adding more textures." + <writeImageToFile(atlas_img, - porting::getDataPath("main_atlas.png").c_str());*/ + getTexturePath("main_atlas.png").c_str());*/ } video::IImage* generate_image_from_scratch(std::string name, @@ -596,7 +703,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, if(part_of_name[0] != '[') { // A normal texture; load it from a file - std::string path = porting::getDataPath(part_of_name.c_str()); + std::string path = getTexturePath(part_of_name.c_str()); dstream<<"INFO: getTextureIdDirect(): Loading path \""< dim_base = baseimg->getDimension(); - // Crack will be drawn at this size - u32 cracksize = 16; - // Size of the crack image - core::dimension2d dim_crack(cracksize,cracksize); - // Position to copy the crack from in the crack image - core::position2d pos_other(0, 16 * progression); - - video::IImage *crackimage = driver->createImageFromFile( - porting::getDataPath("crack.png").c_str()); + + /* + Load crack image. + + It is an image with a number of cracking stages + horizontally tiled. + */ + video::IImage *img_crack = driver->createImageFromFile( + getTexturePath("crack.png").c_str()); - if(crackimage) + if(img_crack) { - /*crackimage->copyToWithAlpha(baseimg, v2s32(0,0), - core::rect(pos_other, dim_base), - video::SColor(255,255,255,255), - NULL);*/ - - for(u32 y0=0; y0 dim_crack + = img_crack->getDimension(); + // Count of crack stages + u32 crack_count = dim_crack.Height / dim_crack.Width; + // Limit progression + if(progression > crack_count-1) + progression = crack_count-1; + // Dimension of a single scaled crack stage + core::dimension2d dim_crack_scaled_single( + dim_base.Width, + dim_base.Height + ); + // Dimension of scaled size + core::dimension2d dim_crack_scaled( + dim_crack_scaled_single.Width, + dim_crack_scaled_single.Height * crack_count + ); + // Create scaled crack image + video::IImage *img_crack_scaled = driver->createImage( + video::ECF_A8R8G8B8, dim_crack_scaled); + if(img_crack_scaled) { - // Position to copy the crack to in the base image - core::position2d pos_base(x0*cracksize, y0*cracksize); - crackimage->copyToWithAlpha(baseimg, pos_base, - core::rect(pos_other, dim_crack), - video::SColor(255,255,255,255), - NULL); + // Scale crack image by copying + img_crack->copyToScaling(img_crack_scaled); + + // Position to copy the crack from + core::position2d pos_crack_scaled( + 0, + dim_crack_scaled_single.Height * progression + ); + + // This tiling does nothing currently but is useful + for(u32 y0=0; y0 pos_base( + x0*dim_crack_scaled_single.Width, + y0*dim_crack_scaled_single.Height + ); + // Rectangle to copy the crack from on the scaled image + core::rect rect_crack_scaled( + pos_crack_scaled, + dim_crack_scaled_single + ); + // Copy it + img_crack_scaled->copyToWithAlpha(baseimg, pos_base, + rect_crack_scaled, + video::SColor(255,255,255,255), + NULL); + } + + img_crack_scaled->drop(); } - - crackimage->drop(); + + img_crack->drop(); } } /* @@ -755,7 +906,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, <<"\" to combined ("<createImageFromFile( - porting::getDataPath(filename.c_str()).c_str()); + getTexturePath(filename.c_str()).c_str()); if(img) { core::dimension2d dim = img->getDimension(); @@ -814,7 +965,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, std::string filename = part_of_name.substr(9); - std::string path = porting::getDataPath(filename.c_str()); + std::string path = getTexturePath(filename.c_str()); dstream<<"INFO: getTextureIdDirect(): Loading path \""<setProjectionMatrix(pm, true); - scene::ILightSceneNode *light = smgr->addLightSceneNode(0, + /*scene::ILightSceneNode *light =*/ smgr->addLightSceneNode(0, v3f(-50, 100, 0), video::SColorf(0.5,0.5,0.5), 1000); + smgr->setAmbientLight(video::SColorf(0.2,0.2,0.2)); + // Render scene driver->beginScene(true, true, video::SColor(0,0,0,0)); smgr->drawAll(); driver->endScene(); - // Drop scene - cube->drop(); + // NOTE: The scene nodes should not be dropped, otherwise + // smgr->drop() segfaults + /*cube->drop(); camera->drop(); - light->drop(); - // Drop scene manager FIXME: Segfaults - //smgr->drop(); + light->drop();*/ + // Drop scene manager + smgr->drop(); // Unset render target driver->setRenderTarget(0, true, true, 0); @@ -998,9 +1152,9 @@ void make_progressbar(float value, video::IImage *image) core::dimension2d size = image->getDimension(); - u32 barheight = 1; - u32 barpad_x = 1; - u32 barpad_y = 1; + u32 barheight = size.Height/16; + u32 barpad_x = size.Width/16; + u32 barpad_y = size.Height/16; u32 barwidth = size.Width - barpad_x*2; v2u32 barpos(barpad_x, size.Height - barheight - barpad_y);