void insert(const std::string &name, video::IImage *img, bool prefer_local, video::IVideoDriver *driver) { assert(img); // Remove old image core::map<std::string, video::IImage*>::Node *n; n = m_images.find(name); if(n){ video::IImage *oldimg = n->getValue(); if(oldimg) oldimg->drop(); } // Try to use local texture instead if asked to if(prefer_local){ std::string path = getTexturePath(name.c_str()); if(path != ""){ video::IImage *img2 = driver->createImageFromFile(path.c_str()); if(img2){ m_images[name] = img2; return; } } } img->grab(); m_images[name] = img; }
/* RatObject */ void RatObject::addToScene(scene::ISceneManager *smgr) { if(m_node != NULL) return; video::IVideoDriver* driver = smgr->getVideoDriver(); scene::SMesh *mesh = new scene::SMesh(); scene::IMeshBuffer *buf = new scene::SMeshBuffer(); video::SColor c(255,255,255,255); video::S3DVertex vertices[4] = { video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1), video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1), video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0), video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0), }; u16 indices[] = {0,1,2,2,3,0}; buf->append(vertices, 4, indices, 6); // Set material buf->getMaterial().setFlag(video::EMF_LIGHTING, false); buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); buf->getMaterial().setTexture (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; // Add to mesh mesh->addMeshBuffer(buf); buf->drop(); m_node = smgr->addMeshSceneNode(mesh, NULL); mesh->drop(); updateNodePos(); }
void insert(const std::string &name, video::IImage *img, bool prefer_local, video::IVideoDriver *driver) { assert(img); // Remove old image std::map<std::string, video::IImage*>::iterator n; n = m_images.find(name); if(n != m_images.end()){ if(n->second) n->second->drop(); } video::IImage* toadd = img; bool need_to_grab = true; // Try to use local texture instead if asked to if(prefer_local){ std::string path = getTexturePath(name.c_str()); if(path != ""){ video::IImage *img2 = driver->createImageFromFile(path.c_str()); if(img2){ toadd = img2; need_to_grab = false; } } } if (need_to_grab) toadd->grab(); m_images[name] = toadd; }
// Primarily fetches from cache, secondarily tries to read from filesystem video::IImage* getOrLoad(const std::string &name, IrrlichtDevice *device) { std::map<std::string, video::IImage*>::iterator n; n = m_images.find(name); if(n != m_images.end()){ n->second->grab(); // Grab for caller return n->second; } video::IVideoDriver* driver = device->getVideoDriver(); std::string path = getTexturePath(name.c_str()); if(path == ""){ infostream<<"SourceImageCache::getOrLoad(): No path found for \"" <<name<<"\""<<std::endl; return NULL; } infostream<<"SourceImageCache::getOrLoad(): Loading path \""<<path <<"\""<<std::endl; video::IImage *img = driver->createImageFromFile(path.c_str()); if(img){ m_images[name] = img; img->grab(); // Grab for caller } return img; }
// Primarily fetches from cache, secondarily tries to read from filesystem video::IImage* getOrLoad(const std::string &name, IrrlichtDevice *device) { core::map<std::string, video::IImage*>::Node *n; n = m_images.find(name); if(n){ n->getValue()->grab(); // Grab for caller return n->getValue(); } video::IVideoDriver* driver = device->getVideoDriver(); std::string path = getTexturePath(name.c_str()); if(path == ""){ infostream<<"SourceImageCache::getOrLoad(): No path found for \"" <<name<<"\""<<std::endl; return NULL; } infostream<<"SourceImageCache::getOrLoad(): Loading path \""<<path <<"\""<<std::endl; video::IImage *img = driver->createImageFromFile(path.c_str()); // Even if could not be loaded, put as NULL //m_images[name] = img; if(img){ m_images[name] = img; img->grab(); // Grab for caller } return img; }
void drawMenuBackground(video::IVideoDriver* driver) { core::dimension2d<u32> screensize = driver->getScreenSize(); video::ITexture *bgtexture = driver->getTexture(getTexturePath("menubg.png").c_str()); if(bgtexture) { s32 scaledsize = 128; // The important difference between destsize and screensize is // that destsize is rounded to whole scaled pixels. // These formulas use component-wise multiplication and division of v2u32. v2u32 texturesize = bgtexture->getSize(); v2u32 sourcesize = texturesize * screensize / scaledsize + v2u32(1,1); v2u32 destsize = scaledsize * sourcesize / texturesize; // Default texture wrapping mode in Irrlicht is ETC_REPEAT. driver->draw2DImage(bgtexture, core::rect<s32>(0, 0, destsize.X, destsize.Y), core::rect<s32>(0, 0, sourcesize.X, sourcesize.Y), NULL, NULL, true); } video::ITexture *logotexture = driver->getTexture(getTexturePath("menulogo.png").c_str()); if(logotexture) { v2s32 logosize(logotexture->getOriginalSize().Width, logotexture->getOriginalSize().Height); logosize *= 4; video::SColor bgcolor(255,50,50,50); core::rect<s32> bgrect(0, screensize.Height-logosize.Y-20, screensize.Width, screensize.Height); driver->draw2DRectangle(bgcolor, bgrect, NULL); core::rect<s32> rect(0,0,logosize.X,logosize.Y); rect += v2s32(screensize.Width/2,screensize.Height-10-logosize.Y); rect -= v2s32(logosize.X/2, 0); driver->draw2DImage(logotexture, rect, core::rect<s32>(core::position2d<s32>(0,0), core::dimension2di(logotexture->getSize())), NULL, NULL, true); } }
void drawMenuBackground(video::IVideoDriver* driver) { core::dimension2d<u32> screensize = driver->getScreenSize(); video::ITexture *bgtexture = driver->getTexture(getTexturePath("menubg.png").c_str()); if(bgtexture) { s32 texturesize = 128; s32 tiled_y = screensize.Height / texturesize + 1; s32 tiled_x = screensize.Width / texturesize + 1; for(s32 y=0; y<tiled_y; y++) for(s32 x=0; x<tiled_x; x++) { core::rect<s32> rect(0,0,texturesize,texturesize); rect += v2s32(x*texturesize, y*texturesize); driver->draw2DImage(bgtexture, rect, core::rect<s32>(core::position2d<s32>(0,0), core::dimension2di(bgtexture->getSize())), NULL, NULL, true); } } video::ITexture *logotexture = driver->getTexture(getTexturePath("menulogo.png").c_str()); if(logotexture) { v2s32 logosize(logotexture->getOriginalSize().Width, logotexture->getOriginalSize().Height); logosize *= 4; video::SColor bgcolor(255,50,50,50); core::rect<s32> bgrect(0, screensize.Height-logosize.Y-20, screensize.Width, screensize.Height); driver->draw2DRectangle(bgcolor, bgrect, NULL); core::rect<s32> rect(0,0,logosize.X,logosize.Y); rect += v2s32(screensize.Width/2,screensize.Height-10-logosize.Y); rect -= v2s32(logosize.X/2, 0); driver->draw2DImage(logotexture, rect, core::rect<s32>(core::position2d<s32>(0,0), core::dimension2di(logotexture->getSize())), NULL, NULL, true); } }
bool isKnownSourceImage(const std::string &name) { bool is_known = false; bool cache_found = m_source_image_existence.get(name, &is_known); if(cache_found) return is_known; // Not found in cache; find out if a local file exists is_known = (getTexturePath(name) != ""); m_source_image_existence.set(name, is_known); return is_known; }
//! constructor Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, LocalPlayer* player): scene::ISceneNode(parent, mgr, id), m_visible(true), m_fallback_bg_color(255,255,255,255), m_first_update(true), m_brightness(0.5), m_cloud_brightness(0.5), m_bgcolor_bright_f(1,1,1,1), m_skycolor_bright_f(1,1,1,1), m_cloudcolor_bright_f(1,1,1,1), m_player(player) { setAutomaticCulling(scene::EAC_OFF); Box.MaxEdge.set(0,0,0); Box.MinEdge.set(0,0,0); // create material video::SMaterial mat; mat.Lighting = false; mat.ZBuffer = video::ECFN_NEVER; mat.ZWriteEnable = false; mat.AntiAliasing=0; mat.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; mat.BackfaceCulling = false; m_materials[0] = mat; m_materials[1] = mat; //m_materials[1].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; m_materials[1].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; m_materials[2] = mat; m_materials[2].setTexture(0, mgr->getVideoDriver()->getTexture( getTexturePath("sunrisebg.png").c_str())); m_materials[2].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; //m_materials[2].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; for(u32 i=0; i<SKY_STAR_COUNT; i++){ m_stars[i] = v3f( myrand_range(-10000,10000), myrand_range(-10000,10000), myrand_range(-10000,10000) ); m_stars[i].normalize(); } m_directional_colored_fog = g_settings->getBool("directional_colored_fog"); }
void GUICharDefMenu::drawMenu() { gui::IGUISkin* skin = Environment->getSkin(); if (!skin) return; video::IVideoDriver* driver = Environment->getVideoDriver(); core::rect<s32> left( AbsoluteRect.UpperLeftCorner.X, AbsoluteRect.UpperLeftCorner.Y, AbsoluteRect.UpperLeftCorner.X+250, AbsoluteRect.LowerRightCorner.Y ); core::rect<s32> right( AbsoluteRect.LowerRightCorner.X-230, AbsoluteRect.UpperLeftCorner.Y, AbsoluteRect.LowerRightCorner.X, AbsoluteRect.LowerRightCorner.Y ); driver->draw2DRectangle(left, GUI_BG_TOP, GUI_BG_TOP, GUI_BG_BTM, GUI_BG_BTM, &AbsoluteClippingRect); driver->draw2DRectangleOutline(left, GUI_BORDER); driver->draw2DRectangle(right, GUI_BG_TOP, GUI_BG_TOP, GUI_BG_BTM, GUI_BG_BTM, &AbsoluteClippingRect); driver->draw2DRectangleOutline(right, GUI_BORDER); video::ITexture *texture = driver->getTexture(getTexturePath("menulogo.png").c_str()); if (texture != 0) { const core::dimension2d<u32>& img_origsize = texture->getOriginalSize(); core::rect<s32> logo( AbsoluteRect.UpperLeftCorner.X+25, AbsoluteRect.UpperLeftCorner.Y, AbsoluteRect.UpperLeftCorner.X+225, AbsoluteRect.UpperLeftCorner.Y+200 ); const video::SColor color(255,255,255,255); const video::SColor colors[] = {color,color,color,color}; driver->draw2DImage(texture, logo, core::rect<s32>(core::position2d<s32>(0,0),img_origsize), NULL, colors, true); } gui::IGUIElement::draw(); if (!m_model) return; m_model_rotation++; m_model->setRotation(v3f(0,m_model_rotation,0)); }
WEmitter::WEmitter(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, v3s16 position, s16 height) : scene::ISceneNode(parent, mgr, id), m_position(position), m_height(height), m_texture_v(0.5) { m_material.setFlag(video::EMF_LIGHTING, false); m_material.setFlag(video::EMF_BACK_FACE_CULLING, false); m_material.setFlag(video::EMF_BILINEAR_FILTER, false); m_material.setFlag(video::EMF_FOG_ENABLE, false); m_material.setFlag(video::EMF_ANTI_ALIASING, false); video::IVideoDriver* driver = SceneManager->getVideoDriver(); // driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); m_material.setTexture(0, driver->getTexture(getTexturePath("rain.png").c_str())); m_material.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; m_box = core::aabbox3d<f32>(m_position.X * BS - BS / 2, m_position.Y * BS - BS / 2, m_position.Z * BS - BS / 2, m_position.X * BS + BS / 2, m_position.Y * BS + BS / 2 + m_height * BS, m_position.Z * BS + BS / 2); f32 rx = BS / 2; f32 ry = BS / 2; f32 rz = BS / 2; f32 h = m_height * BS; m_material.getTextureMatrix(0).setTextureScale(1.0, -m_height); video::SColor c_top(128, 240, 240, 255); m_planes[0] = video::S3DVertex(-rx, h, 0, 0, 0, 0, c_top, 0, 1); m_planes[1] = video::S3DVertex( rx, h, 0, 0, 0, 0, c_top, 1, 1); m_planes[2] = video::S3DVertex( rx, -ry, 0, 0, 0, 0, c_top, 1, 0); m_planes[3] = video::S3DVertex(-rx, -ry, 0, 0, 0, 0, c_top, 0, 0); m_planes[4] = video::S3DVertex(0, h, -rz, 0, 0, 0, c_top, 0, 1); m_planes[5] = video::S3DVertex(0, h, rz, 0, 0, 0, c_top, 1, 1); m_planes[6] = video::S3DVertex(0, -ry, rz, 0, 0, 0, c_top, 1, 0); m_planes[7] = video::S3DVertex(0, -ry, -rz, 0, 0, 0, c_top, 0, 0); for (u16 i = 0; i < 8; i++) m_planes[i].Pos += v3f(m_position.X * BS, m_position.Y * BS, m_position.Z * BS); m_indices = { 0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4 }; }
FarMesh::FarMesh( scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, u64 seed, Client *client ): scene::ISceneNode(parent, mgr, id), m_seed(seed), m_camera_pos(0,0), m_time(0), m_client(client), m_render_range(20*MAP_BLOCKSIZE) { dstream<<__FUNCTION_NAME<<std::endl; video::IVideoDriver* driver = mgr->getVideoDriver(); m_materials[0].setFlag(video::EMF_LIGHTING, false); m_materials[0].setFlag(video::EMF_BACK_FACE_CULLING, true); //m_materials[0].setFlag(video::EMF_BACK_FACE_CULLING, false); m_materials[0].setFlag(video::EMF_BILINEAR_FILTER, false); m_materials[0].setFlag(video::EMF_FOG_ENABLE, false); //m_materials[0].setFlag(video::EMF_ANTI_ALIASING, true); //m_materials[0].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; m_materials[0].setFlag(video::EMF_FOG_ENABLE, true); m_materials[1].setFlag(video::EMF_LIGHTING, false); m_materials[1].setFlag(video::EMF_BACK_FACE_CULLING, false); m_materials[1].setFlag(video::EMF_BILINEAR_FILTER, false); m_materials[1].setFlag(video::EMF_FOG_ENABLE, false); m_materials[1].setTexture (0, driver->getTexture(getTexturePath("treeprop.png").c_str())); m_materials[1].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; m_materials[1].setFlag(video::EMF_FOG_ENABLE, true); m_box = core::aabbox3d<f32>(-BS*1000000,-BS*31000,-BS*1000000, BS*1000000,BS*31000,BS*1000000); trees = g_settings.getBool("farmesh_trees"); }
GameObject::GameObject(QString type, QObject *parent) : Item(parent),type(type) { gItem = new QGraphicsRectItem(); textureFile = type; textureFile.append(".png"); //gItem->setBrush(QBrush(QColor(100,100,100))); gItem->setBrush(QBrush(QPixmap(getTexturePath()))); gItem->setPen(QPen(Qt::NoPen)); QRectF rect = gItem->rect(); QSizeF size = sizeMap.value(type); rect.setSize(size); gItem->setRect(rect); gItem->setFlag(QGraphicsRectItem::ItemIsSelectable,true); gItem->setFlag(QGraphicsRectItem::ItemIsMovable,true); gItem->setFlag(QGraphicsRectItem::ItemIsFocusable,true); gItem->setFlag(QGraphicsRectItem::ItemSendsGeometryChanges,true); }
void GUISettingsMenu::drawMenu() { video::IVideoDriver* driver = Environment->getVideoDriver(); { core::rect<s32> left( AbsoluteRect.UpperLeftCorner.X, AbsoluteRect.UpperLeftCorner.Y, AbsoluteRect.LowerRightCorner.X-550, AbsoluteRect.LowerRightCorner.Y ); core::rect<s32> right( AbsoluteRect.UpperLeftCorner.X+250, AbsoluteRect.UpperLeftCorner.Y, AbsoluteRect.LowerRightCorner.X, AbsoluteRect.LowerRightCorner.Y ); driver->draw2DRectangle(left, GUI_BG_BTM, GUI_BG_BTM, GUI_BG_BTM, GUI_BG_BTM, &AbsoluteClippingRect); driver->draw2DRectangle(right, GUI_BG_TOP, GUI_BG_BTM, GUI_BG_TOP, GUI_BG_BTM, &AbsoluteClippingRect); video::ITexture *texture = driver->getTexture(getTexturePath("menulogo.png").c_str()); if (texture != 0) { const core::dimension2d<u32>& img_origsize = texture->getOriginalSize(); core::rect<s32> logo( AbsoluteRect.UpperLeftCorner.X+25, AbsoluteRect.UpperLeftCorner.Y, AbsoluteRect.UpperLeftCorner.X+225, AbsoluteRect.UpperLeftCorner.Y+200 ); const video::SColor color(255,255,255,255); const video::SColor colors[] = {color,color,color,color}; driver->draw2DImage(texture, logo, core::rect<s32>(core::position2d<s32>(0,0),img_origsize), NULL, colors, true); } } gui::IGUIElement::draw(); }
int main(int argc, char *argv[]) { int retval = 0; /* Initialization */ log_add_output_maxlev(&main_stderr_log_out, LMT_ACTION); log_add_output_all_levs(&main_dstream_no_stderr_log_out); log_register_thread("main"); // Set locale. This is for forcing '.' as the decimal point. std::locale::global(std::locale("C")); // This enables printing all characters in bitmap font setlocale(LC_CTYPE, "en_US"); /* Parse command line */ // List all allowed options core::map<std::string, ValueSpec> allowed_options; allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG, _("Show allowed options"))); allowed_options.insert("config", ValueSpec(VALUETYPE_STRING, _("Load configuration from specified file"))); allowed_options.insert("port", ValueSpec(VALUETYPE_STRING, _("Set network port (UDP)"))); allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG, _("Disable unit tests"))); allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG, _("Enable unit tests"))); allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING, _("Same as --world (deprecated)"))); allowed_options.insert("world", ValueSpec(VALUETYPE_STRING, _("Set world path (implies local game) ('list' lists all)"))); allowed_options.insert("worldname", ValueSpec(VALUETYPE_STRING, _("Set world by name (implies local game)"))); allowed_options.insert("info", ValueSpec(VALUETYPE_FLAG, _("Print more information to console"))); allowed_options.insert("verbose", ValueSpec(VALUETYPE_FLAG, _("Print even more information to console"))); allowed_options.insert("trace", ValueSpec(VALUETYPE_FLAG, _("Print enormous amounts of information to log and console"))); allowed_options.insert("logfile", ValueSpec(VALUETYPE_STRING, _("Set logfile path ('' = no logging)"))); allowed_options.insert("gameid", ValueSpec(VALUETYPE_STRING, _("Set gameid (\"--gameid list\" prints available ones)"))); #ifndef SERVER allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG, _("Run speed tests"))); allowed_options.insert("address", ValueSpec(VALUETYPE_STRING, _("Address to connect to. ('' = local game)"))); allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG, _("Enable random user input, for testing"))); allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG, _("Run dedicated server"))); allowed_options.insert("name", ValueSpec(VALUETYPE_STRING, _("Set player name"))); allowed_options.insert("password", ValueSpec(VALUETYPE_STRING, _("Set password"))); allowed_options.insert("go", ValueSpec(VALUETYPE_FLAG, _("Disable main menu"))); #endif Settings cmd_args; bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options); if(ret == false || cmd_args.getFlag("help") || cmd_args.exists("nonopt1")) { dstream<<_("Allowed options:")<<std::endl; for(core::map<std::string, ValueSpec>::Iterator i = allowed_options.getIterator(); i.atEnd() == false; i++) { std::ostringstream os1(std::ios::binary); os1<<" --"<<i.getNode()->getKey(); if(i.getNode()->getValue().type == VALUETYPE_FLAG) {} else os1<<_(" <value>"); dstream<<padStringRight(os1.str(), 24); if(i.getNode()->getValue().help != NULL) dstream<<i.getNode()->getValue().help; dstream<<std::endl; } return cmd_args.getFlag("help") ? 0 : 1; } /* Low-level initialization */ // If trace is enabled, enable logging of certain things if(cmd_args.getFlag("trace")){ dstream<<_("Enabling trace level debug output")<<std::endl; log_trace_level_enabled = true; dout_con_ptr = &verbosestream; // this is somewhat old crap socket_enable_debug_output = true; // socket doesn't use log.h } // In certain cases, output info level on stderr if(cmd_args.getFlag("info") || cmd_args.getFlag("verbose") || cmd_args.getFlag("trace") || cmd_args.getFlag("speedtests")) log_add_output(&main_stderr_log_out, LMT_INFO); // In certain cases, output verbose level on stderr if(cmd_args.getFlag("verbose") || cmd_args.getFlag("trace")) log_add_output(&main_stderr_log_out, LMT_VERBOSE); porting::signal_handler_init(); bool &kill = *porting::signal_handler_killstatus(); porting::initializePaths(); // Create user data directory fs::CreateDir(porting::path_user); init_gettext((porting::path_share+DIR_DELIM+".."+DIR_DELIM+"locale").c_str()); // Initialize debug streams #define DEBUGFILE "debug.txt" #if RUN_IN_PLACE std::string logfile = DEBUGFILE; #else std::string logfile = porting::path_user+DIR_DELIM+DEBUGFILE; #endif if(cmd_args.exists("logfile")) logfile = cmd_args.get("logfile"); if(logfile != "") debugstreams_init(false, logfile.c_str()); else debugstreams_init(false, NULL); infostream<<"logfile = "<<logfile<<std::endl; infostream<<"path_share = "<<porting::path_share<<std::endl; infostream<<"path_user = "******"gameid") && cmd_args.get("gameid") == "list") { std::set<std::string> gameids = getAvailableGameIds(); for(std::set<std::string>::const_iterator i = gameids.begin(); i != gameids.end(); i++) dstream<<(*i)<<std::endl; return 0; } // List worlds if requested if(cmd_args.exists("world") && cmd_args.get("world") == "list"){ dstream<<_("Available worlds:")<<std::endl; std::vector<WorldSpec> worldspecs = getAvailableWorlds(); print_worldspecs(worldspecs, dstream); return 0; } // Print startup message infostream<<PROJECT_NAME<< " "<<_("with")<<" SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST <<", "<<BUILD_INFO <<std::endl; /* Basic initialization */ // Initialize default settings set_default_settings(g_settings); // Initialize sockets sockets_init(); atexit(sockets_cleanup); /* Read config file */ // Path of configuration file in use std::string configpath = ""; if(cmd_args.exists("config")) { bool r = g_settings->readConfigFile(cmd_args.get("config").c_str()); if(r == false) { errorstream<<"Could not read configuration from \"" <<cmd_args.get("config")<<"\""<<std::endl; return 1; } configpath = cmd_args.get("config"); } else { core::array<std::string> filenames; filenames.push_back(porting::path_user + DIR_DELIM + "minetest.conf"); // Legacy configuration file location filenames.push_back(porting::path_user + DIR_DELIM + ".." + DIR_DELIM + "minetest.conf"); #if RUN_IN_PLACE // Try also from a lower level (to aid having the same configuration // for many RUN_IN_PLACE installs) filenames.push_back(porting::path_user + DIR_DELIM + ".." + DIR_DELIM + ".." + DIR_DELIM + "minetest.conf"); #endif for(u32 i=0; i<filenames.size(); i++) { bool r = g_settings->readConfigFile(filenames[i].c_str()); if(r) { configpath = filenames[i]; break; } } // If no path found, use the first one (menu creates the file) if(configpath == "") configpath = filenames[0]; } // Initialize random seed srand(time(0)); mysrand(time(0)); /* Run unit tests */ if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false) || cmd_args.getFlag("enable-unittests") == true) { run_tests(); } /* Game parameters */ // Port u16 port = 30000; if(cmd_args.exists("port")) port = cmd_args.getU16("port"); else if(g_settings->exists("port")) port = g_settings->getU16("port"); if(port == 0) port = 30000; // World directory std::string commanded_world = ""; if(cmd_args.exists("world")) commanded_world = cmd_args.get("world"); else if(cmd_args.exists("map-dir")) commanded_world = cmd_args.get("map-dir"); else if(cmd_args.exists("nonopt0")) // First nameless argument commanded_world = cmd_args.get("nonopt0"); else if(g_settings->exists("map-dir")) commanded_world = g_settings->get("map-dir"); // World name std::string commanded_worldname = ""; if(cmd_args.exists("worldname")) commanded_worldname = cmd_args.get("worldname"); // Strip world.mt from commanded_world { std::string worldmt = "world.mt"; if(commanded_world.size() > worldmt.size() && commanded_world.substr(commanded_world.size()-worldmt.size()) == worldmt){ dstream<<_("Supplied world.mt file - stripping it off.")<<std::endl; commanded_world = commanded_world.substr( 0, commanded_world.size()-worldmt.size()); } } // If a world name was specified, convert it to a path if(commanded_worldname != ""){ // Get information about available worlds std::vector<WorldSpec> worldspecs = getAvailableWorlds(); bool found = false; for(u32 i=0; i<worldspecs.size(); i++){ std::string name = worldspecs[i].name; if(name == commanded_worldname){ if(commanded_world != ""){ dstream<<_("--worldname takes precedence over previously " "selected world.")<<std::endl; } commanded_world = worldspecs[i].path; found = true; break; } } if(!found){ dstream<<_("World")<<" '"<<commanded_worldname<<_("' not " "available. Available worlds:")<<std::endl; print_worldspecs(worldspecs, dstream); return 1; } } // Gamespec SubgameSpec commanded_gamespec; if(cmd_args.exists("gameid")){ std::string gameid = cmd_args.get("gameid"); commanded_gamespec = findSubgame(gameid); if(!commanded_gamespec.isValid()){ errorstream<<"Game \""<<gameid<<"\" not found"<<std::endl; return 1; } } /* Run dedicated server if asked to or no other option */ #ifdef SERVER bool run_dedicated_server = true; #else bool run_dedicated_server = cmd_args.getFlag("server"); #endif if(run_dedicated_server) { DSTACK("Dedicated server branch"); // Create time getter if built with Irrlicht #ifndef SERVER g_timegetter = new SimpleTimeGetter(); #endif // World directory std::string world_path; verbosestream<<_("Determining world path")<<std::endl; bool is_legacy_world = false; // If a world was commanded, use it if(commanded_world != ""){ world_path = commanded_world; infostream<<"Using commanded world path ["<<world_path<<"]" <<std::endl; } // No world was specified; try to select it automatically else { // Get information about available worlds std::vector<WorldSpec> worldspecs = getAvailableWorlds(); // If a world name was specified, select it if(commanded_worldname != ""){ world_path = ""; for(u32 i=0; i<worldspecs.size(); i++){ std::string name = worldspecs[i].name; if(name == commanded_worldname){ world_path = worldspecs[i].path; break; } } if(world_path == ""){ dstream<<_("World")<<" '"<<commanded_worldname<<"' "<<_("not " "available. Available worlds:")<<std::endl; print_worldspecs(worldspecs, dstream); return 1; } } // If there is only a single world, use it if(worldspecs.size() == 1){ world_path = worldspecs[0].path; dstream<<_("Automatically selecting world at")<<" [" <<world_path<<"]"<<std::endl; // If there are multiple worlds, list them } else if(worldspecs.size() > 1){ dstream<<_("Multiple worlds are available.")<<std::endl; dstream<<_("Please select one using --worldname <name>" " or --world <path>")<<std::endl; print_worldspecs(worldspecs, dstream); return 1; // If there are no worlds, automatically create a new one } else { // This is the ultimate default world path world_path = porting::path_user + DIR_DELIM + "worlds" + DIR_DELIM + "world"; infostream<<"Creating default world at [" <<world_path<<"]"<<std::endl; } } if(world_path == ""){ errorstream<<"No world path specified or found."<<std::endl; return 1; } verbosestream<<_("Using world path")<<" ["<<world_path<<"]"<<std::endl; // We need a gamespec. SubgameSpec gamespec; verbosestream<<_("Determining gameid/gamespec")<<std::endl; // If world doesn't exist if(!getWorldExists(world_path)) { // Try to take gamespec from command line if(commanded_gamespec.isValid()){ gamespec = commanded_gamespec; infostream<<"Using commanded gameid ["<<gamespec.id<<"]"<<std::endl; } // Otherwise we will be using "minetest" else{ gamespec = findSubgame(g_settings->get("default_game")); infostream<<"Using default gameid ["<<gamespec.id<<"]"<<std::endl; } } // World exists else { std::string world_gameid = getWorldGameId(world_path, is_legacy_world); // If commanded to use a gameid, do so if(commanded_gamespec.isValid()){ gamespec = commanded_gamespec; if(commanded_gamespec.id != world_gameid){ errorstream<<"WARNING: Using commanded gameid [" <<gamespec.id<<"]"<<" instead of world gameid [" <<world_gameid<<"]"<<std::endl; } } else{ // If world contains an embedded game, use it; // Otherwise find world from local system. gamespec = findWorldSubgame(world_path); infostream<<"Using world gameid ["<<gamespec.id<<"]"<<std::endl; } } if(!gamespec.isValid()){ errorstream<<"Subgame ["<<gamespec.id<<"] could not be found." <<std::endl; return 1; } verbosestream<<_("Using gameid")<<" ["<<gamespec.id<<"]"<<std::endl; // Create server Server server(world_path, configpath, gamespec, false); server.start(port); // Run server dedicated_server_loop(server, kill); return 0; } #ifndef SERVER // Exclude from dedicated server build /* More parameters */ std::string address = g_settings->get("address"); if(commanded_world != "") address = ""; else if(cmd_args.exists("address")) address = cmd_args.get("address"); std::string playername = g_settings->get("name"); if(cmd_args.exists("name")) playername = cmd_args.get("name"); bool skip_main_menu = cmd_args.getFlag("go"); /* Device initialization */ // Resolution selection bool fullscreen = g_settings->getBool("fullscreen"); u16 screenW = g_settings->getU16("screenW"); u16 screenH = g_settings->getU16("screenH"); // bpp, fsaa, vsync bool vsync = g_settings->getBool("vsync"); u16 bits = g_settings->getU16("fullscreen_bpp"); u16 fsaa = g_settings->getU16("fsaa"); // Determine driver video::E_DRIVER_TYPE driverType; std::string driverstring = g_settings->get("video_driver"); if(driverstring == "null") driverType = video::EDT_NULL; else if(driverstring == "software") driverType = video::EDT_SOFTWARE; else if(driverstring == "burningsvideo") driverType = video::EDT_BURNINGSVIDEO; else if(driverstring == "direct3d8") driverType = video::EDT_DIRECT3D8; else if(driverstring == "direct3d9") driverType = video::EDT_DIRECT3D9; else if(driverstring == "opengl") driverType = video::EDT_OPENGL; else { errorstream<<"WARNING: Invalid video_driver specified; defaulting " "to opengl"<<std::endl; driverType = video::EDT_OPENGL; } /* Create device and exit if creation failed */ MyEventReceiver receiver; IrrlichtDevice *device; SIrrlichtCreationParameters params = SIrrlichtCreationParameters(); params.DriverType = driverType; params.WindowSize = core::dimension2d<u32>(screenW, screenH); params.Bits = bits; params.AntiAlias = fsaa; params.Fullscreen = fullscreen; params.Stencilbuffer = false; params.Vsync = vsync; params.EventReceiver = &receiver; device = createDeviceEx(params); if (device == 0) return 1; // could not create selected driver. /* Continue initialization */ video::IVideoDriver* driver = device->getVideoDriver(); /* This changes the minimum allowed number of vertices in a VBO. Default is 500. */ //driver->setMinHardwareBufferVertexCount(50); // Create time getter g_timegetter = new IrrlichtTimeGetter(device); // Create game callback for menus g_gamecallback = new MainGameCallback(device); /* Speed tests (done after irrlicht is loaded to get timer) */ if(cmd_args.getFlag("speedtests")) { dstream<<"Running speed tests"<<std::endl; SpeedTests(); return 0; } device->setResizable(true); bool random_input = g_settings->getBool("random_input") || cmd_args.getFlag("random-input"); InputHandler *input = NULL; if(random_input) input = new RandomInputHandler(); else input = new RealInputHandler(device, &receiver); scene::ISceneManager* smgr = device->getSceneManager(); guienv = device->getGUIEnvironment(); gui::IGUISkin* skin = guienv->getSkin(); gui::IGUIFont* font = guienv->getFont(getTexturePath("fontlucida.png").c_str()); if(font) skin->setFont(font); else errorstream<<"WARNING: Font file was not found." " Using default font."<<std::endl; // If font was not found, this will get us one font = skin->getFont(); assert(font); u32 text_height = font->getDimension(L"Hello, world!").Height; infostream<<"text_height="<<text_height<<std::endl; //skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,0,0,0)); skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,255,255,255)); //skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(0,0,0,0)); //skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(0,0,0,0)); skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255,0,0,0)); skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255,0,0,0)); skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255,70,100,50)); skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255,255,255,255)); #if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2 // Irrlicht 1.8 input colours skin->setColor(gui::EGDC_EDITABLE, video::SColor(255,128,128,128)); skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255,96,134,49)); #endif /* GUI stuff */ ChatBackend chat_backend; /* If an error occurs, this is set to something and the menu-game loop is restarted. It is then displayed before the menu. */ std::wstring error_message = L""; // The password entered during the menu screen, std::string password; bool first_loop = true; /* Menu-game loop */ while(device->run() && kill == false) { // Set the window caption device->setWindowCaption((std::wstring(L"Minetest [")+wgettext("Main Menu")+L"]").c_str()); // This is used for catching disconnects try { /* Clear everything from the GUIEnvironment */ guienv->clear(); /* We need some kind of a root node to be able to add custom gui elements directly on the screen. Otherwise they won't be automatically drawn. */ guiroot = guienv->addStaticText(L"", core::rect<s32>(0, 0, 10000, 10000)); SubgameSpec gamespec; WorldSpec worldspec; bool simple_singleplayer_mode = false; // These are set up based on the menu and other things std::string current_playername = "inv£lid"; std::string current_password = ""; std::string current_address = "does-not-exist"; int current_port = 0; /* Out-of-game menu loop. Loop quits when menu returns proper parameters. */ while(kill == false) { // If skip_main_menu, only go through here once if(skip_main_menu && !first_loop){ kill = true; break; } first_loop = false; // Cursor can be non-visible when coming from the game device->getCursorControl()->setVisible(true); // Some stuff are left to scene manager when coming from the game // (map at least?) smgr->clear(); // Initialize menu data MainMenuData menudata; if(g_settings->exists("selected_mainmenu_tab")) menudata.selected_tab = g_settings->getS32("selected_mainmenu_tab"); menudata.address = narrow_to_wide(address); menudata.name = narrow_to_wide(playername); menudata.port = narrow_to_wide(itos(port)); if(cmd_args.exists("password")) menudata.password = narrow_to_wide(cmd_args.get("password")); menudata.fancy_trees = g_settings->getBool("new_style_leaves"); menudata.smooth_lighting = g_settings->getBool("smooth_lighting"); menudata.clouds_3d = g_settings->getBool("enable_3d_clouds"); menudata.opaque_water = g_settings->getBool("opaque_water"); menudata.mip_map = g_settings->getBool("mip_map"); menudata.anisotropic_filter = g_settings->getBool("anisotropic_filter"); menudata.bilinear_filter = g_settings->getBool("bilinear_filter"); menudata.trilinear_filter = g_settings->getBool("trilinear_filter"); menudata.enable_shaders = g_settings->getS32("enable_shaders"); menudata.preload_item_visuals = g_settings->getBool("preload_item_visuals"); driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, menudata.mip_map); menudata.creative_mode = g_settings->getBool("creative_mode"); menudata.enable_damage = g_settings->getBool("enable_damage"); // Default to selecting nothing menudata.selected_world = -1; // Get world listing for the menu std::vector<WorldSpec> worldspecs = getAvailableWorlds(); // If there is only one world, select it if(worldspecs.size() == 1){ menudata.selected_world = 0; } // Otherwise try to select according to selected_world_path else if(g_settings->exists("selected_world_path")){ std::string trypath = g_settings->get("selected_world_path"); for(u32 i=0; i<worldspecs.size(); i++){ if(worldspecs[i].path == trypath){ menudata.selected_world = i; break; } } } // If a world was commanded, append and select it if(commanded_world != ""){ std::string gameid = getWorldGameId(commanded_world, true); std::string name = _("[--world parameter]"); if(gameid == ""){ gameid = g_settings->get("default_game"); name += " [new]"; } WorldSpec spec(commanded_world, name, gameid); worldspecs.push_back(spec); menudata.selected_world = worldspecs.size()-1; } // Copy worldspecs to menu menudata.worlds = worldspecs; if(skip_main_menu == false) { video::IVideoDriver* driver = device->getVideoDriver(); infostream<<"Waiting for other menus"<<std::endl; while(device->run() && kill == false) { if(noMenuActive()) break; driver->beginScene(true, true, video::SColor(255,128,128,128)); drawMenuBackground(driver); guienv->drawAll(); driver->endScene(); // On some computers framerate doesn't seem to be // automatically limited sleep_ms(25); } infostream<<"Waited for other menus"<<std::endl; GUIMainMenu *menu = new GUIMainMenu(guienv, guiroot, -1, &g_menumgr, &menudata, g_gamecallback); menu->allowFocusRemoval(true); if(error_message != L"") { verbosestream<<"error_message = " <<wide_to_narrow(error_message)<<std::endl; GUIMessageMenu *menu2 = new GUIMessageMenu(guienv, guiroot, -1, &g_menumgr, error_message.c_str()); menu2->drop(); error_message = L""; } infostream<<"Created main menu"<<std::endl; while(device->run() && kill == false) { if(menu->getStatus() == true) break; //driver->beginScene(true, true, video::SColor(255,0,0,0)); driver->beginScene(true, true, video::SColor(255,128,128,128)); drawMenuBackground(driver); guienv->drawAll(); driver->endScene(); // On some computers framerate doesn't seem to be // automatically limited sleep_ms(25); } infostream<<"Dropping main menu"<<std::endl; menu->drop(); } playername = wide_to_narrow(menudata.name); password = translatePassword(playername, menudata.password); //infostream<<"Main: password hash: '"<<password<<"'"<<std::endl; address = wide_to_narrow(menudata.address); int newport = stoi(wide_to_narrow(menudata.port)); if(newport != 0) port = newport; simple_singleplayer_mode = menudata.simple_singleplayer_mode; // Save settings g_settings->setS32("selected_mainmenu_tab", menudata.selected_tab); g_settings->set("new_style_leaves", itos(menudata.fancy_trees)); g_settings->set("smooth_lighting", itos(menudata.smooth_lighting)); g_settings->set("enable_3d_clouds", itos(menudata.clouds_3d)); g_settings->set("opaque_water", itos(menudata.opaque_water)); g_settings->set("mip_map", itos(menudata.mip_map)); g_settings->set("anisotropic_filter", itos(menudata.anisotropic_filter)); g_settings->set("bilinear_filter", itos(menudata.bilinear_filter)); g_settings->set("trilinear_filter", itos(menudata.trilinear_filter)); g_settings->setS32("enable_shaders", menudata.enable_shaders); g_settings->set("preload_item_visuals", itos(menudata.preload_item_visuals)); g_settings->set("creative_mode", itos(menudata.creative_mode)); g_settings->set("enable_damage", itos(menudata.enable_damage)); g_settings->set("name", playername); g_settings->set("address", address); g_settings->set("port", itos(port)); if(menudata.selected_world != -1) g_settings->set("selected_world_path", worldspecs[menudata.selected_world].path); // Break out of menu-game loop to shut down cleanly if(device->run() == false || kill == true) break; current_playername = playername; current_password = password; current_address = address; current_port = port; // If using simple singleplayer mode, override if(simple_singleplayer_mode){ current_playername = "singleplayer"; current_password = ""; current_address = ""; current_port = 30011; } // Set world path to selected one if(menudata.selected_world != -1){ worldspec = worldspecs[menudata.selected_world]; infostream<<"Selected world: "<<worldspec.name <<" ["<<worldspec.path<<"]"<<std::endl; } // Only refresh if so requested if(menudata.only_refresh){ infostream<<"Refreshing menu"<<std::endl; continue; } // Create new world if requested if(menudata.create_world_name != L"") { std::string path = porting::path_user + DIR_DELIM "worlds" + DIR_DELIM + wide_to_narrow(menudata.create_world_name); // Create world if it doesn't exist if(!initializeWorld(path, menudata.create_world_gameid)){ error_message = wgettext("Failed to initialize world"); errorstream<<wide_to_narrow(error_message)<<std::endl; continue; } g_settings->set("selected_world_path", path); continue; } // If local game if(current_address == "") { if(menudata.selected_world == -1){ error_message = wgettext("No world selected and no address " "provided. Nothing to do."); errorstream<<wide_to_narrow(error_message)<<std::endl; continue; } // Load gamespec for required game gamespec = findWorldSubgame(worldspec.path); if(!gamespec.isValid() && !commanded_gamespec.isValid()){ error_message = wgettext("Could not find or load game \"") + narrow_to_wide(worldspec.gameid) + L"\""; errorstream<<wide_to_narrow(error_message)<<std::endl; continue; } if(commanded_gamespec.isValid() && commanded_gamespec.id != worldspec.gameid){ errorstream<<"WARNING: Overriding gamespec from \"" <<worldspec.gameid<<"\" to \"" <<commanded_gamespec.id<<"\""<<std::endl; gamespec = commanded_gamespec; } if(!gamespec.isValid()){ error_message = wgettext("Invalid gamespec."); error_message += L" (world_gameid=" +narrow_to_wide(worldspec.gameid)+L")"; errorstream<<wide_to_narrow(error_message)<<std::endl; continue; } } // Continue to game break; } // Break out of menu-game loop to shut down cleanly if(device->run() == false || kill == true) break; /* Run game */ the_game( kill, random_input, input, device, font, worldspec.path, current_playername, current_password, current_address, current_port, error_message, configpath, chat_backend, gamespec, simple_singleplayer_mode ); } //try catch(con::PeerNotFoundException &e) { error_message = wgettext("Connection error (timed out?)"); errorstream<<wide_to_narrow(error_message)<<std::endl; } catch(ServerError &e) { error_message = narrow_to_wide(e.what()); errorstream<<wide_to_narrow(error_message)<<std::endl; } catch(ModError &e) { errorstream<<e.what()<<std::endl; error_message = narrow_to_wide(e.what()) + wgettext("\nCheck debug.txt for details."); } #ifdef NDEBUG catch(std::exception &e) { std::string narrow_message = "Some exception: \""; narrow_message += e.what(); narrow_message += "\""; errorstream<<narrow_message<<std::endl; error_message = narrow_to_wide(narrow_message); } #endif // If no main menu, show error and exit if(skip_main_menu) { if(error_message != L""){ verbosestream<<"error_message = " <<wide_to_narrow(error_message)<<std::endl; retval = 1; } break; } } // Menu-game loop delete input; /* In the end, delete the Irrlicht device. */ device->drop(); #endif // !SERVER // Update configuration file if(configpath != "") g_settings->updateConfigFile(configpath.c_str()); // Print modified quicktune values { bool header_printed = false; std::vector<std::string> names = getQuicktuneNames(); for(u32 i=0; i<names.size(); i++){ QuicktuneValue val = getQuicktuneValue(names[i]); if(!val.modified) continue; if(!header_printed){ dstream<<"Modified quicktune values:"<<std::endl; header_printed = true; } dstream<<names[i]<<" = "<<val.getString()<<std::endl; } } END_DEBUG_EXCEPTION_HANDLER(errorstream) debugstreams_deinit(); return retval; }
void GUIMainMenu::drawMenu() { gui::IGUISkin* skin = Environment->getSkin(); if (!skin) return; video::IVideoDriver* driver = Environment->getVideoDriver(); /*video::SColor bgcolor(140,0,0,0); driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);*/ video::SColor bgcolor(140,0,0,0); if(getTab() == TAB_SINGLEPLAYER) { { core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y); rect += AbsoluteRect.UpperLeftCorner + m_topleft_client; driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect); } } else if(getTab() == TAB_MULTIPLAYER) { { core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y); rect += AbsoluteRect.UpperLeftCorner + m_topleft_client; driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect); } } else if(getTab() == TAB_ADVANCED) { { core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y); rect += AbsoluteRect.UpperLeftCorner + m_topleft_client; driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect); } { core::rect<s32> rect(0, 0, m_size_server.X, m_size_server.Y); rect += AbsoluteRect.UpperLeftCorner + m_topleft_server; driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect); } } else if(getTab() == TAB_SETTINGS) { { core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y); rect += AbsoluteRect.UpperLeftCorner + m_topleft_client; driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect); } } else if(getTab() == TAB_CREDITS) { { core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y); rect += AbsoluteRect.UpperLeftCorner + m_topleft_client; driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect); } video::ITexture *logotexture = driver->getTexture(getTexturePath("menulogo.png").c_str()); if(logotexture) { v2s32 logosize(logotexture->getOriginalSize().Width, logotexture->getOriginalSize().Height); logosize *= 2; core::rect<s32> rect(0,0,logosize.X,logosize.Y); rect += AbsoluteRect.UpperLeftCorner + m_topleft_client; rect += v2s32(130, 50); driver->draw2DImage(logotexture, rect, core::rect<s32>(core::position2d<s32>(0,0), core::dimension2di(logotexture->getSize())), NULL, NULL, true); } } gui::IGUIElement::draw(); }
int main(int argc, char *argv[]) { /* Initialization */ log_add_output_maxlev(&main_stderr_log_out, LMT_ACTION); log_add_output_all_levs(&main_dstream_no_stderr_log_out); log_register_thread("main"); // Set locale. This is for forcing '.' as the decimal point. std::locale::global(std::locale("C")); // This enables printing all characters in bitmap font setlocale(LC_CTYPE, "en_US"); /* Parse command line */ // List all allowed options core::map<std::string, ValueSpec> allowed_options; allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG)); allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG, "Run server directly")); allowed_options.insert("config", ValueSpec(VALUETYPE_STRING, "Load configuration from specified file")); allowed_options.insert("port", ValueSpec(VALUETYPE_STRING)); allowed_options.insert("address", ValueSpec(VALUETYPE_STRING)); allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG)); allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG)); allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG)); allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING)); #ifdef _WIN32 allowed_options.insert("dstream-on-stderr", ValueSpec(VALUETYPE_FLAG)); #endif allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG)); allowed_options.insert("info-on-stderr", ValueSpec(VALUETYPE_FLAG)); Settings cmd_args; bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options); if(ret == false || cmd_args.getFlag("help")) { dstream<<"Allowed options:"<<std::endl; for(core::map<std::string, ValueSpec>::Iterator i = allowed_options.getIterator(); i.atEnd() == false; i++) { dstream<<" --"<<i.getNode()->getKey(); if(i.getNode()->getValue().type == VALUETYPE_FLAG) { } else { dstream<<" <value>"; } dstream<<std::endl; if(i.getNode()->getValue().help != NULL) { dstream<<" "<<i.getNode()->getValue().help <<std::endl; } } return cmd_args.getFlag("help") ? 0 : 1; } /* Low-level initialization */ bool disable_stderr = false; #ifdef _WIN32 if(cmd_args.getFlag("dstream-on-stderr") == false) disable_stderr = true; #endif if(cmd_args.getFlag("info-on-stderr")) log_add_output(&main_stderr_log_out, LMT_INFO); porting::signal_handler_init(); bool &kill = *porting::signal_handler_killstatus(); // Initialize porting::path_data and porting::path_userdata porting::initializePaths(); // Create user data directory fs::CreateDir(porting::path_userdata); init_gettext((porting::path_data+DIR_DELIM+".."+DIR_DELIM+"locale").c_str()); // Initialize debug streams #ifdef RUN_IN_PLACE std::string debugfile = DEBUGFILE; #else std::string debugfile = porting::path_userdata+DIR_DELIM+DEBUGFILE; #endif debugstreams_init(disable_stderr, debugfile.c_str()); // Initialize debug stacks debug_stacks_init(); DSTACK(__FUNCTION_NAME); // Init material properties table //initializeMaterialProperties(); // Debug handler BEGIN_DEBUG_EXCEPTION_HANDLER // Print startup message actionstream<<PROJECT_NAME<< " with SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST <<", "<<BUILD_INFO <<std::endl; /* Basic initialization */ // Initialize default settings set_default_settings(g_settings); // Initialize sockets sockets_init(); atexit(sockets_cleanup); /* Read config file */ // Path of configuration file in use std::string configpath = ""; if(cmd_args.exists("config")) { bool r = g_settings->readConfigFile(cmd_args.get("config").c_str()); if(r == false) { errorstream<<"Could not read configuration from \"" <<cmd_args.get("config")<<"\""<<std::endl; return 1; } configpath = cmd_args.get("config"); } else { core::array<std::string> filenames; filenames.push_back(porting::path_userdata + DIR_DELIM + "minetest.conf"); #ifdef RUN_IN_PLACE filenames.push_back(porting::path_userdata + DIR_DELIM + ".." + DIR_DELIM + "minetest.conf"); #endif for(u32 i=0; i<filenames.size(); i++) { bool r = g_settings->readConfigFile(filenames[i].c_str()); if(r) { configpath = filenames[i]; break; } } // If no path found, use the first one (menu creates the file) if(configpath == "") configpath = filenames[0]; } // Initialize random seed srand(time(0)); mysrand(time(0)); /* Run unit tests */ if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false) || cmd_args.getFlag("enable-unittests") == true) { run_tests(); } /*for(s16 y=-100; y<100; y++) for(s16 x=-100; x<100; x++) { std::cout<<noise2d_gradient((double)x/10,(double)y/10, 32415)<<std::endl; } return 0;*/ /* Game parameters */ // Port u16 port = 30000; if(cmd_args.exists("port")) port = cmd_args.getU16("port"); else if(g_settings->exists("port")) port = g_settings->getU16("port"); if(port == 0) port = 30000; // Map directory std::string map_dir = porting::path_userdata+DIR_DELIM+"world"; if(cmd_args.exists("map-dir")) map_dir = cmd_args.get("map-dir"); else if(g_settings->exists("map-dir")) map_dir = g_settings->get("map-dir"); // Run dedicated server if asked to if(cmd_args.getFlag("server")) { DSTACK("Dedicated server branch"); // Create time getter g_timegetter = new SimpleTimeGetter(); // Create server Server server(map_dir.c_str(), configpath); server.start(port); // Run server dedicated_server_loop(server, kill); return 0; } /* More parameters */ // Address to connect to std::string address = ""; if(cmd_args.exists("address")) { address = cmd_args.get("address"); } else { address = g_settings->get("address"); } std::string playername = g_settings->get("name"); /* Device initialization */ // Resolution selection bool fullscreen = false; u16 screenW = g_settings->getU16("screenW"); u16 screenH = g_settings->getU16("screenH"); // Determine driver video::E_DRIVER_TYPE driverType; std::string driverstring = g_settings->get("video_driver"); if(driverstring == "null") driverType = video::EDT_NULL; else if(driverstring == "software") driverType = video::EDT_SOFTWARE; else if(driverstring == "burningsvideo") driverType = video::EDT_BURNINGSVIDEO; else if(driverstring == "direct3d8") driverType = video::EDT_DIRECT3D8; else if(driverstring == "direct3d9") driverType = video::EDT_DIRECT3D9; else if(driverstring == "opengl") driverType = video::EDT_OPENGL; else { errorstream<<"WARNING: Invalid video_driver specified; defaulting " "to opengl"<<std::endl; driverType = video::EDT_OPENGL; } /* Create device and exit if creation failed */ MyEventReceiver receiver; IrrlichtDevice *device; device = createDevice(driverType, core::dimension2d<u32>(screenW, screenH), 16, fullscreen, false, false, &receiver); if (device == 0) return 1; // could not create selected driver. /* Continue initialization */ video::IVideoDriver* driver = device->getVideoDriver(); // Disable mipmaps (because some of them look ugly) driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); /* This changes the minimum allowed number of vertices in a VBO. Default is 500. */ //driver->setMinHardwareBufferVertexCount(50); // Set the window caption device->setWindowCaption(L"Minetest [Main Menu]"); // Create time getter g_timegetter = new IrrlichtTimeGetter(device); // Create game callback for menus g_gamecallback = new MainGameCallback(device); /* Speed tests (done after irrlicht is loaded to get timer) */ if(cmd_args.getFlag("speedtests")) { dstream<<"Running speed tests"<<std::endl; SpeedTests(); return 0; } device->setResizable(true); bool random_input = g_settings->getBool("random_input") || cmd_args.getFlag("random-input"); InputHandler *input = NULL; if(random_input) input = new RandomInputHandler(); else input = new RealInputHandler(device, &receiver); scene::ISceneManager* smgr = device->getSceneManager(); guienv = device->getGUIEnvironment(); gui::IGUISkin* skin = guienv->getSkin(); gui::IGUIFont* font = guienv->getFont(getTexturePath("fontlucida.png").c_str()); if(font) skin->setFont(font); else errorstream<<"WARNING: Font file was not found." " Using default font."<<std::endl; // If font was not found, this will get us one font = skin->getFont(); assert(font); u32 text_height = font->getDimension(L"Hello, world!").Height; infostream<<"text_height="<<text_height<<std::endl; //skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,0,0,0)); skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,255,255,255)); //skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(0,0,0,0)); //skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(0,0,0,0)); skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255,0,0,0)); skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255,0,0,0)); /* GUI stuff */ /* If an error occurs, this is set to something and the menu-game loop is restarted. It is then displayed before the menu. */ std::wstring error_message = L""; // The password entered during the menu screen, std::string password; /* Menu-game loop */ while(device->run() && kill == false) { // This is used for catching disconnects try { /* Clear everything from the GUIEnvironment */ guienv->clear(); /* We need some kind of a root node to be able to add custom gui elements directly on the screen. Otherwise they won't be automatically drawn. */ guiroot = guienv->addStaticText(L"", core::rect<s32>(0, 0, 10000, 10000)); /* Out-of-game menu loop. Loop quits when menu returns proper parameters. */ while(kill == false) { // Cursor can be non-visible when coming from the game device->getCursorControl()->setVisible(true); // Some stuff are left to scene manager when coming from the game // (map at least?) smgr->clear(); // Reset or hide the debug gui texts /*guitext->setText(L"Minetest-c55"); guitext2->setVisible(false); guitext_info->setVisible(false); guitext_chat->setVisible(false);*/ // Initialize menu data MainMenuData menudata; menudata.address = narrow_to_wide(address); menudata.name = narrow_to_wide(playername); menudata.port = narrow_to_wide(itos(port)); menudata.fancy_trees = g_settings->getBool("new_style_leaves"); menudata.smooth_lighting = g_settings->getBool("smooth_lighting"); menudata.clouds_3d = g_settings->getBool("enable_3d_clouds"); menudata.opaque_water = g_settings->getBool("opaque_water"); menudata.creative_mode = g_settings->getBool("creative_mode"); menudata.enable_damage = g_settings->getBool("enable_damage"); GUIMainMenu *menu = new GUIMainMenu(guienv, guiroot, -1, &g_menumgr, &menudata, g_gamecallback); menu->allowFocusRemoval(true); if(error_message != L"") { errorstream<<"error_message = " <<wide_to_narrow(error_message)<<std::endl; GUIMessageMenu *menu2 = new GUIMessageMenu(guienv, guiroot, -1, &g_menumgr, error_message.c_str()); menu2->drop(); error_message = L""; } video::IVideoDriver* driver = device->getVideoDriver(); infostream<<"Created main menu"<<std::endl; while(device->run() && kill == false) { if(menu->getStatus() == true) break; //driver->beginScene(true, true, video::SColor(255,0,0,0)); driver->beginScene(true, true, video::SColor(255,128,128,128)); drawMenuBackground(driver); guienv->drawAll(); driver->endScene(); // On some computers framerate doesn't seem to be // automatically limited sleep_ms(25); } // Break out of menu-game loop to shut down cleanly if(device->run() == false || kill == true) break; infostream<<"Dropping main menu"<<std::endl; menu->drop(); // Delete map if requested if(menudata.delete_map) { bool r = fs::RecursiveDeleteContent(map_dir); if(r == false) error_message = L"Delete failed"; continue; } playername = wide_to_narrow(menudata.name); password = translatePassword(playername, menudata.password); //infostream<<"Main: password hash: '"<<password<<"'"<<std::endl; address = wide_to_narrow(menudata.address); int newport = stoi(wide_to_narrow(menudata.port)); if(newport != 0) port = newport; g_settings->set("new_style_leaves", itos(menudata.fancy_trees)); g_settings->set("smooth_lighting", itos(menudata.smooth_lighting)); g_settings->set("enable_3d_clouds", itos(menudata.clouds_3d)); g_settings->set("opaque_water", itos(menudata.opaque_water)); g_settings->set("creative_mode", itos(menudata.creative_mode)); g_settings->set("enable_damage", itos(menudata.enable_damage)); // NOTE: These are now checked server side; no need to do it // here, so let's not do it here. /*// Check for valid parameters, restart menu if invalid. if(playername == "") { error_message = L"Name required."; continue; } // Check that name has only valid chars if(string_allowed(playername, PLAYERNAME_ALLOWED_CHARS)==false) { error_message = L"Characters allowed: " +narrow_to_wide(PLAYERNAME_ALLOWED_CHARS); continue; }*/ // Save settings g_settings->set("name", playername); g_settings->set("address", address); g_settings->set("port", itos(port)); // Update configuration file if(configpath != "") g_settings->updateConfigFile(configpath.c_str()); // Continue to game break; } // Break out of menu-game loop to shut down cleanly if(device->run() == false || kill == true) break; /* Run game */ the_game( kill, random_input, input, device, font, map_dir, playername, password, address, port, error_message, configpath ); } //try catch(con::PeerNotFoundException &e) { errorstream<<"Connection error (timed out?)"<<std::endl; error_message = L"Connection error (timed out?)"; } catch(SocketException &e) { errorstream<<"Socket error (port already in use?)"<<std::endl; error_message = L"Socket error (port already in use?)"; } catch(ModError &e) { errorstream<<e.what()<<std::endl; error_message = narrow_to_wide(e.what()) + L"\nCheck debug.txt for details."; } #ifdef NDEBUG catch(std::exception &e) { std::string narrow_message = "Some exception, what()=\""; narrow_message += e.what(); narrow_message += "\""; errorstream<<narrow_message<<std::endl; error_message = narrow_to_wide(narrow_message); } #endif } // Menu-game loop delete input; /* In the end, delete the Irrlicht device. */ device->drop(); END_DEBUG_EXCEPTION_HANDLER(errorstream) debugstreams_deinit(); return 0; }
//------------------------------------------------------------------------------ // Read the BMP file //------------------------------------------------------------------------------ bool BmpTexture::readFile() { return readFileBMP(getTextureFileName(), getTexturePath()); }
RemotePlayer::RemotePlayer( scene::ISceneNode* parent, IrrlichtDevice *device, s32 id): scene::ISceneNode(parent, (device==NULL)?NULL:device->getSceneManager(), id), m_text(NULL) { m_box = core::aabbox3d<f32>(-BS/2,0,-BS/2,BS/2,BS*2,BS/2); if(parent != NULL && device != NULL) { // ISceneNode stores a member called SceneManager scene::ISceneManager* mgr = SceneManager; video::IVideoDriver* driver = mgr->getVideoDriver(); gui::IGUIEnvironment* gui = device->getGUIEnvironment(); // Add a text node for showing the name wchar_t wname[1] = {0}; m_text = mgr->addTextSceneNode(gui->getBuiltInFont(), wname, video::SColor(255,255,255,255), this); m_text->setPosition(v3f(0, (f32)BS*2.1, 0)); // Attach a simple mesh to the player for showing an image scene::SMesh *mesh = new scene::SMesh(); { // Front scene::IMeshBuffer *buf = new scene::SMeshBuffer(); video::SColor c(255,255,255,255); video::S3DVertex vertices[4] = { video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1), video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1), video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0), video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0), }; u16 indices[] = {0,1,2,2,3,0}; buf->append(vertices, 4, indices, 6); // Set material buf->getMaterial().setFlag(video::EMF_LIGHTING, false); //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); 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; buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; // Add to mesh mesh->addMeshBuffer(buf); buf->drop(); } { // Back scene::IMeshBuffer *buf = new scene::SMeshBuffer(); video::SColor c(255,255,255,255); video::S3DVertex vertices[4] = { video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1), video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1), video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0), video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0), }; u16 indices[] = {0,1,2,2,3,0}; buf->append(vertices, 4, indices, 6); // Set material buf->getMaterial().setFlag(video::EMF_LIGHTING, false); //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); 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; // Add to mesh mesh->addMeshBuffer(buf); buf->drop(); } m_node = mgr->addMeshSceneNode(mesh, this); mesh->drop(); m_node->setPosition(v3f(0,0,0)); } }
//------------------------------------------------------------------------------ // Write the BMP file //------------------------------------------------------------------------------ bool BmpTexture::writeFile() { return writeFileBMP(getTextureFileName(), getTexturePath()); }
GUIChatConsole::GUIChatConsole( gui::IGUIEnvironment* env, gui::IGUIElement* parent, s32 id, ChatBackend* backend, Client* client ): IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, core::rect<s32>(0,0,100,100)), m_chat_backend(backend), m_client(client), m_screensize(v2u32(0,0)), m_animate_time_old(0), m_open(false), m_height(0), m_desired_height(0), m_desired_height_fraction(0.0), m_height_speed(5.0), m_open_inhibited(0), m_cursor_blink(0.0), m_cursor_blink_speed(0.0), m_cursor_height(0.0), m_background(NULL), m_background_color(255, 0, 0, 0), m_font(NULL), m_fontsize(0, 0) { m_animate_time_old = getTimeMs(); // load background settings bool console_color_set = !g_settings->get("console_color").empty(); s32 console_alpha = g_settings->getS32("console_alpha"); // load the background texture depending on settings m_background_color.setAlpha(clamp_u8(console_alpha)); if (console_color_set) { v3f console_color = g_settings->getV3F("console_color"); m_background_color.setRed(clamp_u8(myround(console_color.X))); m_background_color.setGreen(clamp_u8(myround(console_color.Y))); m_background_color.setBlue(clamp_u8(myround(console_color.Z))); } else { m_background = env->getVideoDriver()->getTexture(getTexturePath("background_chat.jpg").c_str()); m_background_color.setRed(255); m_background_color.setGreen(255); m_background_color.setBlue(255); } // load the font // FIXME should a custom texture_path be searched too? #if USE_FREETYPE std::string font_name = g_settings->get("mono_font_path"); u16 font_size = g_settings->getU16("mono_font_size"); m_font = gui::CGUITTFont::createTTFont(env, font_name.c_str(), font_size); #else std::string font_name = "fontdejavusansmono.png"; m_font = env->getFont(getTexturePath(font_name).c_str()); #endif if (m_font == NULL) { dstream << "Unable to load font: " << font_name << std::endl; } else { core::dimension2d<u32> dim = m_font->getDimension(L"M"); m_fontsize = v2u32(dim.Width, dim.Height); dstream << "Font size: " << m_fontsize.X << " " << m_fontsize.Y << std::endl; } m_fontsize.X = MYMAX(m_fontsize.X, 1); m_fontsize.Y = MYMAX(m_fontsize.Y, 1); // set default cursor options setCursor(true, true, 2.0, 0.1); }
bool generate_image(std::string part_of_name, video::IImage *& baseimg, IrrlichtDevice *device) { video::IVideoDriver* driver = device->getVideoDriver(); assert(driver); // Stuff starting with [ are special commands if(part_of_name[0] != '[') { // A normal texture; load it from a file std::string path = getTexturePath(part_of_name.c_str()); /*infostream<<"generate_image(): Loading path \""<<path <<"\""<<std::endl;*/ video::IImage *image = driver->createImageFromFile(path.c_str()); if(image == NULL) { infostream<<"generate_image(): Could not load image \"" <<part_of_name<<"\" from path \""<<path<<"\"" <<" while building texture"<<std::endl; //return false; infostream<<"generate_image(): Creating a dummy" <<" image for \""<<part_of_name<<"\""<<std::endl; // Just create a dummy image //core::dimension2d<u32> dim(2,2); core::dimension2d<u32> dim(1,1); image = driver->createImage(video::ECF_A8R8G8B8, dim); assert(image); /*image->setPixel(0,0, video::SColor(255,255,0,0)); image->setPixel(1,0, video::SColor(255,0,255,0)); image->setPixel(0,1, video::SColor(255,0,0,255)); image->setPixel(1,1, video::SColor(255,255,0,255));*/ image->setPixel(0,0, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); /*image->setPixel(1,0, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); image->setPixel(0,1, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); image->setPixel(1,1, video::SColor(255,myrand()%256, myrand()%256,myrand()%256));*/ } // If base image is NULL, load as base. if(baseimg == NULL) { //infostream<<"Setting "<<part_of_name<<" as base"<<std::endl; /* Copy it this way to get an alpha channel. Otherwise images with alpha cannot be blitted on images that don't have alpha in the original file. */ core::dimension2d<u32> dim = image->getDimension(); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); image->copyTo(baseimg); image->drop(); } // Else blit on base. else { //infostream<<"Blitting "<<part_of_name<<" on base"<<std::endl; // Size of the copied area core::dimension2d<u32> dim = image->getDimension(); //core::dimension2d<u32> dim(16,16); // Position to copy the blitted to in the base image core::position2d<s32> pos_to(0,0); // Position to copy the blitted from in the blitted image core::position2d<s32> pos_from(0,0); // Blit image->copyToWithAlpha(baseimg, pos_to, core::rect<s32>(pos_from, dim), video::SColor(255,255,255,255), NULL); // Drop image image->drop(); } } else { // A special texture modification infostream<<"generate_image(): generating special " <<"modification \""<<part_of_name<<"\"" <<std::endl; /* This is the simplest of all; it just adds stuff to the name so that a separate texture is created. It is used to make textures for stuff that doesn't want to implement getting the texture from a bigger texture atlas. */ if(part_of_name == "[forcesingle") { } /* [crackN Adds a cracking texture */ else if(part_of_name.substr(0,6) == "[crack") { if(baseimg == NULL) { infostream<<"generate_image(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } // Crack image number u16 progression = stoi(part_of_name.substr(6)); // Size of the base image core::dimension2d<u32> dim_base = baseimg->getDimension(); /* 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(img_crack) { // Dimension of original image core::dimension2d<u32> 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<u32> dim_crack_scaled_single( dim_base.Width, dim_base.Height ); // Dimension of scaled size core::dimension2d<u32> 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) { // Scale crack image by copying img_crack->copyToScaling(img_crack_scaled); // Position to copy the crack from core::position2d<s32> pos_crack_scaled( 0, dim_crack_scaled_single.Height * progression ); // This tiling does nothing currently but is useful for(u32 y0=0; y0<dim_base.Height / dim_crack_scaled_single.Height; y0++) for(u32 x0=0; x0<dim_base.Width / dim_crack_scaled_single.Width; x0++) { // Position to copy the crack to in the base image core::position2d<s32> 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<s32> 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(); } img_crack->drop(); } } /* [combine:WxH:X,Y=filename:X,Y=filename2 Creates a bigger texture from an amount of smaller ones */ else if(part_of_name.substr(0,8) == "[combine") { Strfnd sf(part_of_name); sf.next(":"); u32 w0 = stoi(sf.next("x")); u32 h0 = stoi(sf.next(":")); infostream<<"combined w="<<w0<<" h="<<h0<<std::endl; core::dimension2d<u32> dim(w0,h0); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); while(sf.atend() == false) { u32 x = stoi(sf.next(",")); u32 y = stoi(sf.next("=")); std::string filename = sf.next(":"); infostream<<"Adding \""<<filename <<"\" to combined ("<<x<<","<<y<<")" <<std::endl; video::IImage *img = driver->createImageFromFile( getTexturePath(filename.c_str()).c_str()); if(img) { core::dimension2d<u32> dim = img->getDimension(); infostream<<"Size "<<dim.Width <<"x"<<dim.Height<<std::endl; core::position2d<s32> pos_base(x, y); video::IImage *img2 = driver->createImage(video::ECF_A8R8G8B8, dim); img->copyTo(img2); img->drop(); img2->copyToWithAlpha(baseimg, pos_base, core::rect<s32>(v2s32(0,0), dim), video::SColor(255,255,255,255), NULL); img2->drop(); } else { infostream<<"img==NULL"<<std::endl; } } } /* [progressbarN Adds a progress bar, 0.0 <= N <= 1.0 */ else if(part_of_name.substr(0,12) == "[progressbar") { if(baseimg == NULL) { infostream<<"generate_image(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } float value = stof(part_of_name.substr(12)); make_progressbar(value, baseimg); } /* "[noalpha:filename.png" Use an image without it's alpha channel. Used for the leaves texture when in old leaves mode, so that the transparent parts don't look completely black when simple alpha channel is used for rendering. */ else if(part_of_name.substr(0,8) == "[noalpha") { if(baseimg != NULL) { infostream<<"generate_image(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } std::string filename = part_of_name.substr(9); std::string path = getTexturePath(filename.c_str()); infostream<<"generate_image(): Loading path \""<<path <<"\""<<std::endl; video::IImage *image = driver->createImageFromFile(path.c_str()); if(image == NULL) { infostream<<"generate_image(): Loading path \"" <<path<<"\" failed"<<std::endl; } else { core::dimension2d<u32> dim = image->getDimension(); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); // Set alpha to full for(u32 y=0; y<dim.Height; y++) for(u32 x=0; x<dim.Width; x++) { video::SColor c = image->getPixel(x,y); c.setAlpha(255); image->setPixel(x,y,c); } // Blit image->copyTo(baseimg); image->drop(); } } /* "[makealpha:R,G,B:filename.png" Use an image with converting one color to transparent. */ else if(part_of_name.substr(0,11) == "[makealpha:") { if(baseimg != NULL) { infostream<<"generate_image(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } Strfnd sf(part_of_name.substr(11)); u32 r1 = stoi(sf.next(",")); u32 g1 = stoi(sf.next(",")); u32 b1 = stoi(sf.next(":")); std::string filename = sf.next(""); std::string path = getTexturePath(filename.c_str()); infostream<<"generate_image(): Loading path \""<<path <<"\""<<std::endl; video::IImage *image = driver->createImageFromFile(path.c_str()); if(image == NULL) { infostream<<"generate_image(): Loading path \"" <<path<<"\" failed"<<std::endl; } else { core::dimension2d<u32> dim = image->getDimension(); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); for(u32 y=0; y<dim.Height; y++) for(u32 x=0; x<dim.Width; x++) { video::SColor c = image->getPixel(x,y); u32 r = c.getRed(); u32 g = c.getGreen(); u32 b = c.getBlue(); if(!(r == r1 && g == g1 && b == b1)) continue; c.setAlpha(0); image->setPixel(x,y,c); } // Blit image->copyTo(baseimg); image->drop(); } } /* "[makealpha2:R,G,B;R2,G2,B2:filename.png" Use an image with converting two colors to transparent. */ else if(part_of_name.substr(0,12) == "[makealpha2:") { if(baseimg != NULL) { infostream<<"generate_image(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } Strfnd sf(part_of_name.substr(12)); u32 r1 = stoi(sf.next(",")); u32 g1 = stoi(sf.next(",")); u32 b1 = stoi(sf.next(";")); u32 r2 = stoi(sf.next(",")); u32 g2 = stoi(sf.next(",")); u32 b2 = stoi(sf.next(":")); std::string filename = sf.next(""); std::string path = getTexturePath(filename.c_str()); infostream<<"generate_image(): Loading path \""<<path <<"\""<<std::endl; video::IImage *image = driver->createImageFromFile(path.c_str()); if(image == NULL) { infostream<<"generate_image(): Loading path \"" <<path<<"\" failed"<<std::endl; } else { core::dimension2d<u32> dim = image->getDimension(); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); for(u32 y=0; y<dim.Height; y++) for(u32 x=0; x<dim.Width; x++) { video::SColor c = image->getPixel(x,y); u32 r = c.getRed(); u32 g = c.getGreen(); u32 b = c.getBlue(); if(!(r == r1 && g == g1 && b == b1) && !(r == r2 && g == g2 && b == b2)) continue; c.setAlpha(0); image->setPixel(x,y,c); } // Blit image->copyTo(baseimg); image->drop(); } } /* [inventorycube{topimage{leftimage{rightimage In every subimage, replace ^ with &. Create an "inventory cube". NOTE: This should be used only on its own. Example (a grass block (not actually used in game): "[inventorycube{grass.png{mud.png&grass_side.png{mud.png&grass_side.png" */ else if(part_of_name.substr(0,14) == "[inventorycube") { if(baseimg != NULL) { infostream<<"generate_image(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } str_replace_char(part_of_name, '&', '^'); Strfnd sf(part_of_name); sf.next("{"); std::string imagename_top = sf.next("{"); std::string imagename_left = sf.next("{"); std::string imagename_right = sf.next("{"); #if 1 //TODO if(driver->queryFeature(video::EVDF_RENDER_TO_TARGET) == false) { infostream<<"generate_image(): EVDF_RENDER_TO_TARGET" " not supported. Creating fallback image"<<std::endl; baseimg = generate_image_from_scratch( imagename_top, device); return true; } u32 w0 = 64; u32 h0 = 64; //infostream<<"inventorycube w="<<w0<<" h="<<h0<<std::endl; core::dimension2d<u32> dim(w0,h0); // Generate images for the faces of the cube video::IImage *img_top = generate_image_from_scratch( imagename_top, device); video::IImage *img_left = generate_image_from_scratch( imagename_left, device); video::IImage *img_right = generate_image_from_scratch( imagename_right, device); assert(img_top && img_left && img_right); // TODO: Create textures from images video::ITexture *texture_top = driver->addTexture( (imagename_top + "__temp__").c_str(), img_top); assert(texture_top); // Drop images img_top->drop(); img_left->drop(); img_right->drop(); // Create render target texture video::ITexture *rtt = NULL; std::string rtt_name = part_of_name + "_RTT"; rtt = driver->addRenderTargetTexture(dim, rtt_name.c_str(), video::ECF_A8R8G8B8); assert(rtt); // Set render target driver->setRenderTarget(rtt, true, true, video::SColor(0,0,0,0)); // Get a scene manager scene::ISceneManager *smgr_main = device->getSceneManager(); assert(smgr_main); scene::ISceneManager *smgr = smgr_main->createNewSceneManager(); assert(smgr); /* Create scene: - An unit cube is centered at 0,0,0 - Camera looks at cube from Y+, Z- towards Y-, Z+ NOTE: Cube has to be changed to something else because the textures cannot be set individually (or can they?) */ scene::ISceneNode* cube = smgr->addCubeSceneNode(1.0, NULL, -1, v3f(0,0,0), v3f(0, 45, 0)); // Set texture of cube cube->setMaterialTexture(0, texture_top); //cube->setMaterialFlag(video::EMF_LIGHTING, false); cube->setMaterialFlag(video::EMF_ANTI_ALIASING, false); cube->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); scene::ICameraSceneNode* camera = smgr->addCameraSceneNode(0, v3f(0, 1.0, -1.5), v3f(0, 0, 0)); // Set orthogonal projection core::CMatrix4<f32> pm; pm.buildProjectionMatrixOrthoLH(1.65, 1.65, 0, 100); camera->setProjectionMatrix(pm, true); /*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(); // NOTE: The scene nodes should not be dropped, otherwise // smgr->drop() segfaults /*cube->drop(); camera->drop(); light->drop();*/ // Drop scene manager smgr->drop(); // Unset render target driver->setRenderTarget(0, true, true, 0); //TODO: Free textures of images driver->removeTexture(texture_top); // Create image of render target video::IImage *image = driver->createImage(rtt, v2s32(0,0), dim); assert(image); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); if(image) { image->copyTo(baseimg); image->drop(); } #endif } else { infostream<<"generate_image(): Invalid " " modification: \""<<part_of_name<<"\""<<std::endl; } } return true; }