diff --git a/src/client.cpp b/src/client.cpp index 7d2fab179..8a9d62d29 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1553,7 +1553,39 @@ float Client::mediaReceiveProgress() return 1.0; // downloader only exists when not yet done } -void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font) +typedef struct TextureUpdateArgs { + IrrlichtDevice *device; + gui::IGUIEnvironment *guienv; + u32 last_time_ms; + u16 last_percent; + const wchar_t* text_base; +} TextureUpdateArgs; + +void texture_update_progress(void *args, u32 progress, u32 max_progress) +{ + TextureUpdateArgs* targs = (TextureUpdateArgs*) args; + u16 cur_percent = ceil(progress / (double) max_progress * 100.); + + // update the loading menu -- if neccessary + bool do_draw = false; + u32 time_ms = targs->last_time_ms; + if (cur_percent != targs->last_percent) { + targs->last_percent = cur_percent; + time_ms = getTimeMs(); + // only draw when the user will notice something: + do_draw = (time_ms - targs->last_time_ms > 100); + } + + if (do_draw) { + targs->last_time_ms = time_ms; + std::basic_stringstream strm; + strm << targs->text_base << " " << targs->last_percent << "%..."; + draw_load_screen(strm.str(), targs->device, targs->guienv, 0, + 72 + (u16) ((18. / 100.) * (double) targs->last_percent)); + } +} + +void Client::afterContentReceived(IrrlichtDevice *device) { infostream<<"Client::afterContentReceived() started"<rebuildShaders(); delete[] text; // Update node aliases infostream<<"- Updating node aliases"<updateAliases(m_itemdef); m_nodedef->setNodeRegistrationStatus(true); m_nodedef->runNodeResolverCallbacks(); @@ -1586,7 +1618,14 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font) // Update node textures and assign shaders to each tile infostream<<"- Updating node textures"<updateTextures(this); + TextureUpdateArgs tu_args; + tu_args.device = device; + tu_args.guienv = guienv; + tu_args.last_time_ms = getTimeMs(); + tu_args.last_percent = 0; + tu_args.text_base = wgettext("Initializing nodes"); + m_nodedef->updateTextures(this, texture_update_progress, &tu_args); + delete[] tu_args.text_base; // Preload item textures and meshes if configured to if(g_settings->getBool("preload_item_visuals")) diff --git a/src/client.h b/src/client.h index 9baa034de..a455213e9 100644 --- a/src/client.h +++ b/src/client.h @@ -492,7 +492,7 @@ public: float mediaReceiveProgress(); - void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font); + void afterContentReceived(IrrlichtDevice *device); float getRTT(void); float getCurRate(void); diff --git a/src/game.cpp b/src/game.cpp index 7b6d2a3c1..937f6cb23 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1998,7 +1998,7 @@ bool Game::createClient(const std::string &playername, } // Update cached textures, meshes and materials - client->afterContentReceived(device, g_fontengine->getFont()); + client->afterContentReceived(device); /* Camera */ diff --git a/src/nodedef.cpp b/src/nodedef.cpp index a0dcf6b71..4aee1b1c6 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -398,7 +398,9 @@ public: virtual content_t set(const std::string &name, const ContentFeatures &def); virtual content_t allocateDummy(const std::string &name); virtual void updateAliases(IItemDefManager *idef); - virtual void updateTextures(IGameDef *gamedef); + virtual void updateTextures(IGameDef *gamedef, + /*argument: */void (*progress_callback)(void *progress_args, u32 progress, u32 max_progress), + /*argument: */void *progress_callback_args); void serialize(std::ostream &os, u16 protocol_version); void deSerialize(std::istream &is); @@ -715,7 +717,9 @@ void CNodeDefManager::updateAliases(IItemDefManager *idef) } -void CNodeDefManager::updateTextures(IGameDef *gamedef) +void CNodeDefManager::updateTextures(IGameDef *gamedef, + void (*progress_callback)(void *progress_args, u32 progress, u32 max_progress), + void *progress_callback_args) { #ifndef SERVER infostream << "CNodeDefManager::updateTextures(): Updating " @@ -738,7 +742,9 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef) bool use_normal_texture = enable_shaders && (enable_bumpmapping || enable_parallax_occlusion); - for (u32 i = 0; i < m_content_features.size(); i++) { + u32 size = m_content_features.size(); + + for (u32 i = 0; i < size; i++) { ContentFeatures *f = &m_content_features[i]; // Figure out the actual tiles to use @@ -911,6 +917,8 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef) recalculateBoundingBox(f->mesh_ptr[0]); meshmanip->recalculateNormals(f->mesh_ptr[0], true, false); } + + progress_callback(progress_callback_args, i, size); } #endif } diff --git a/src/nodedef.h b/src/nodedef.h index a1c2e1b53..bd13a7bb2 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -378,7 +378,9 @@ public: /* Update tile textures to latest return values of TextueSource. */ - virtual void updateTextures(IGameDef *gamedef)=0; + virtual void updateTextures(IGameDef *gamedef, + /*argument: */void (*progress_callback)(void *progress_args, u32 progress, u32 max_progress), + /*argument: */void *progress_callback_args)=0; virtual void serialize(std::ostream &os, u16 protocol_version)=0; virtual void deSerialize(std::istream &is)=0;