From 81c863ac4df1530123ef7952713623dadb049bec Mon Sep 17 00:00:00 2001 From: Zeg9 Date: Thu, 9 May 2013 18:23:48 +0200 Subject: [PATCH] Add clouds to all loading screens and better progress handling --- src/game.cpp | 192 ++++++++++++++++++++++++++++++++++----------------- src/main.cpp | 44 +++++++----- src/main.h | 8 +++ 3 files changed, 163 insertions(+), 81 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 61e4963c0..81f35d4c0 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -396,12 +396,11 @@ PointedThing getPointedThing(Client *client, v3f player_position, Draws a screen with a single text on it. Text will be removed when the screen is drawn the next time. Additionally, a progressbar can be drawn when percent is set between 0 and 100. - With drawsmgr, you can for example draw clouds */ /*gui::IGUIStaticText **/ void draw_load_screen(const std::wstring &text, IrrlichtDevice* device, gui::IGUIFont* font, - int percent=-1, bool drawsmgr=false) + float dtime=0 ,int percent=0, bool clouds=true) { video::IVideoDriver* driver = device->getVideoDriver(); v2u32 screensize = driver->getScreenSize(); @@ -415,11 +414,13 @@ void draw_load_screen(const std::wstring &text, loadingtext, textrect, false, false); guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT); - if (drawsmgr) + bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds"); + if (cloud_menu_background) { + g_menuclouds->step(dtime*3); + g_menuclouds->render(); driver->beginScene(true, true, video::SColor(255,140,186,250)); - scene::ISceneManager* smgr = device->getSceneManager(); - smgr->drawAll(); + g_menucloudsmgr->drawAll(); } else driver->beginScene(true, true, video::SColor(255,0,0,0)); @@ -428,7 +429,7 @@ void draw_load_screen(const std::wstring &text, core::vector2d barsize(256,32); core::rect barrect(center-barsize/2, center+barsize/2); driver->draw2DRectangle(video::SColor(255,255,255,255),barrect, NULL); // border - driver->draw2DRectangle(video::SColor(255,0,0,0), core::rect ( + driver->draw2DRectangle(video::SColor(255,64,64,64), core::rect ( barrect.UpperLeftCorner+1, barrect.LowerRightCorner-1), NULL); // black inside the bar driver->draw2DRectangle(video::SColor(255,128,128,128), core::rect ( @@ -907,7 +908,11 @@ void the_game( Draw "Loading" screen */ - draw_load_screen(L"Loading...", device, font); + { + wchar_t* text = wgettext("Loading..."); + draw_load_screen(text, device, font,0,0); + delete[] text; + } // Create texture source IWritableTextureSource *tsrc = createTextureSource(device); @@ -964,7 +969,9 @@ void the_game( */ if(address == ""){ - draw_load_screen(L"Creating server...", device, font); + wchar_t* text = wgettext("Creating server...."); + draw_load_screen(text, device, font,0,25); + delete[] text; infostream<<"Creating server"<clear(); + float fps_max = g_settings->getFloat("fps_max"); + bool cloud_menu_background = g_settings->getBool("menu_clouds"); + u32 lasttime = device->getTimer()->getTime(); while(device->run()) { + f32 dtime=0; // in seconds + if (cloud_menu_background) { + u32 time = device->getTimer()->getTime(); + if(time > lasttime) + dtime = (time - lasttime) / 1000.0; + else + dtime = 0; + lasttime = time; + } // Update client and server - client.step(frametime); + client.step(dtime); if(server != NULL) - server->step(frametime); + server->step(dtime); // End condition if(client.connectedAndInitialized()){ @@ -1049,15 +1075,37 @@ void the_game( } // Display status - std::wostringstream ss; - ss<getTimer()->getTime(); + if(time > lasttime) + busytime_u32 = time - lasttime; + else + busytime_u32 = 0; + busytime = busytime_u32 / 1000.0; + + // FPS limiter + u32 frametime_min = 1000./fps_max; + + if(busytime_u32 < frametime_min) { + u32 sleeptime = frametime_min - busytime_u32; + device->sleep(sleeptime); + } + } else { + sleep_ms(25); + } + time_counter += dtime; } } catch(con::PeerNotFoundException &e) @@ -1081,32 +1129,26 @@ void the_game( bool got_content = false; bool content_aborted = false; { - float frametime = 0.033; float time_counter = 0.0; input->clear(); - - scene::ISceneManager* smgr = device->getSceneManager(); - Clouds *clouds = 0; - if (g_settings->getBool("menu_clouds")) - { - // add clouds - clouds = new Clouds(smgr->getRootSceneNode(), - smgr, -1, rand(), 100); - clouds->update(v2f(0, 0), video::SColor(255,200,200,255)); - - // A camera to see the clouds - scene::ICameraSceneNode* camera; - camera = smgr->addCameraSceneNode(0, - v3f(0,0,0), v3f(0, 60, 100)); - camera->setFarValue(10000); - } - + float fps_max = g_settings->getFloat("fps_max"); + bool cloud_menu_background = g_settings->getBool("menu_clouds"); + u32 lasttime = device->getTimer()->getTime(); while(device->run()) { + f32 dtime=0; // in seconds + if (cloud_menu_background) { + u32 time = device->getTimer()->getTime(); + if(time > lasttime) + dtime = (time - lasttime) / 1000.0; + else + dtime = 0; + lasttime = time; + } // Update client and server - client.step(frametime); + client.step(dtime); if(server != NULL) - server->step(frametime); + server->step(dtime); // End condition if(client.texturesReceived() && @@ -1128,30 +1170,52 @@ void the_game( } // Display status - std::wostringstream ss; + std::ostringstream ss; + int progress=0; if (!client.itemdefReceived()) - ss << L"Item definitions..."; - else if (!client.nodedefReceived()) - ss << L"Node definitions..."; - else - ss << L"Media (" << (int)(client.mediaReceiveProgress()*100+0.5) << L"%)..."; - - if (clouds != 0) { - clouds->step(frametime*3); - clouds->render(); + ss << "Item definitions..."; + progress = 0; } + else if (!client.nodedefReceived()) + { + ss << "Node definitions..."; + progress = 25; + } + else + { + ss << "Media..."; + progress = 50+client.mediaReceiveProgress()*50+0.5; + } + wchar_t* text = wgettext(ss.str().c_str()); + draw_load_screen(text, device, font, dtime, progress); + delete[] text; - draw_load_screen(ss.str(), device, font, client.mediaReceiveProgress()*100+0.5, clouds!=0); - - // Delay a bit - sleep_ms(1000*frametime); - time_counter += frametime; - } - if (clouds != 0) - { - smgr->addToDeletionQueue(clouds); - clouds->drop(); + // On some computers framerate doesn't seem to be + // automatically limited + if (cloud_menu_background) { + // Time of frame without fps limit + float busytime; + u32 busytime_u32; + // not using getRealTime is necessary for wine + u32 time = device->getTimer()->getTime(); + if(time > lasttime) + busytime_u32 = time - lasttime; + else + busytime_u32 = 0; + busytime = busytime_u32 / 1000.0; + + // FPS limiter + u32 frametime_min = 1000./fps_max; + + if(busytime_u32 < frametime_min) { + u32 sleeptime = frametime_min - busytime_u32; + device->sleep(sleeptime); + } + } else { + sleep_ms(25); + } + time_counter += dtime; } } @@ -3278,7 +3342,9 @@ void the_game( */ { /*gui::IGUIStaticText *gui_shuttingdowntext = */ - draw_load_screen(L"Shutting down stuff...", device, font); + wchar_t* text = wgettext("Shutting down stuff..."); + draw_load_screen(text, device, font, 0, -1, false); + delete[] text; /*driver->beginScene(true, true, video::SColor(255,0,0,0)); guienv->drawAll(); driver->endScene(); diff --git a/src/main.cpp b/src/main.cpp index b87a3e6d0..94382ec60 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,6 +88,10 @@ Settings *g_settings = &main_settings; Profiler main_profiler; Profiler *g_profiler = &main_profiler; +// Menu clouds are created later +Clouds *g_menuclouds = 0; +irr::scene::ISceneManager *g_menucloudsmgr = 0; + /* Debug streams */ @@ -1569,6 +1573,19 @@ int main(int argc, char *argv[]) skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255,96,134,49)); #endif + + // Create the menu clouds + if (!g_menucloudsmgr) + g_menucloudsmgr = smgr->createNewSceneManager(); + if (!g_menuclouds) + g_menuclouds = new Clouds(g_menucloudsmgr->getRootSceneNode(), + g_menucloudsmgr, -1, rand(), 100); + g_menuclouds->update(v2f(0, 0), video::SColor(255,200,200,255)); + scene::ICameraSceneNode* camera; + camera = g_menucloudsmgr->addCameraSceneNode(0, + v3f(0,0,0), v3f(0, 60, 100)); + camera->setFarValue(10000); + /* GUI stuff */ @@ -1744,18 +1761,6 @@ int main(int argc, char *argv[]) &g_menumgr, &menudata, g_gamecallback); menu->allowFocusRemoval(true); - // Always create clouds because they may or may not be - // needed based on the game selected - Clouds *clouds = new Clouds(smgr->getRootSceneNode(), - smgr, -1, rand(), 100); - clouds->update(v2f(0, 0), video::SColor(255,200,200,255)); - - // A camera to see the clouds - scene::ICameraSceneNode* camera; - camera = smgr->addCameraSceneNode(0, - v3f(0,0,0), v3f(0, 60, 100)); - camera->setFarValue(10000); - if(error_message != L"") { verbosestream<<"error_message = " @@ -1796,7 +1801,7 @@ int main(int argc, char *argv[]) } // Time calc for the clouds - f32 dtime; // in seconds + f32 dtime=0; // in seconds if (cloud_menu_background) { u32 time = device->getTimer()->getTime(); if(time > lasttime) @@ -1811,9 +1816,9 @@ int main(int argc, char *argv[]) if (cloud_menu_background) { // *3 otherwise the clouds would move very slowly - clouds->step(dtime*3); - clouds->render(); - smgr->drawAll(); + g_menuclouds->step(dtime*3); + g_menuclouds->render(); + g_menucloudsmgr->drawAll(); drawMenuOverlay(driver, menutextures); drawMenuHeader(driver, menutextures); drawMenuFooter(driver, menutextures); @@ -1856,8 +1861,6 @@ int main(int argc, char *argv[]) infostream<<"Dropping main menu"<drop(); - clouds->drop(); - smgr->clear(); } playername = wide_to_narrow(menudata.name); @@ -2018,6 +2021,7 @@ int main(int argc, char *argv[]) gamespec, simple_singleplayer_mode ); + smgr->clear(); } //try catch(con::PeerNotFoundException &e) @@ -2048,6 +2052,10 @@ int main(int argc, char *argv[]) } } // Menu-game loop + + g_menuclouds->drop(); + g_menucloudsmgr->drop(); + delete input; /* diff --git a/src/main.h b/src/main.h index daa8c70d2..df67a6348 100644 --- a/src/main.h +++ b/src/main.h @@ -28,6 +28,14 @@ extern Settings *g_settings; class Profiler; extern Profiler *g_profiler; +// Menu clouds +class Clouds; +extern Clouds *g_menuclouds; + +// Scene manager used for menu clouds +namespace irr{namespace scene{class ISceneManager;}} +extern irr::scene::ISceneManager *g_menucloudsmgr; + // Debug streams #include