Add clouds to all loading screens and better progress handling
authorZeg9 <dazeg9@gmail.com>
Thu, 9 May 2013 16:23:48 +0000 (18:23 +0200)
committerPilzAdam <pilzadam@minetest.net>
Fri, 10 May 2013 13:04:21 +0000 (15:04 +0200)
src/game.cpp
src/main.cpp
src/main.h

index 61e4963c04292420e10c825730b51652081ca06f..81f35d4c0f61202c724c6702dcb9ffe7c871efa2 100644 (file)
@@ -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<s32> barsize(256,32);
                core::rect<s32> 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<s32> (
+               driver->draw2DRectangle(video::SColor(255,64,64,64), core::rect<s32> (
                                barrect.UpperLeftCorner+1,
                                barrect.LowerRightCorner-1), NULL); // black inside the bar
                driver->draw2DRectangle(video::SColor(255,128,128,128), core::rect<s32> (
@@ -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"<<std::endl;
                server = new Server(map_dir, configpath, gamespec,
                                simple_singleplayer_mode);
@@ -977,7 +984,11 @@ void the_game(
                Create client
        */
 
-       draw_load_screen(L"Creating client...", device, font);
+       {
+               wchar_t* text = wgettext("Creating client...");
+               draw_load_screen(text, device, font,0,50);
+               delete[] text;
+       }
        infostream<<"Creating client"<<std::endl;
        
        MapDrawControl draw_control;
@@ -987,8 +998,12 @@ void the_game(
        
        // Client acts as our GameDef
        IGameDef *gamedef = &client;
-                       
-       draw_load_screen(L"Resolving address...", device, font);
+       
+       {
+               wchar_t* text = wgettext("Resolving address...");
+               draw_load_screen(text, device, font,0,75);
+               delete[] text;
+       }
        Address connect_address(0,0,0,0, port);
        try{
                if(address == "")
@@ -1020,15 +1035,26 @@ void the_game(
        bool could_connect = false;
        bool connect_aborted = false;
        try{
-               float frametime = 0.033;
                float time_counter = 0.0;
                input->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<<L"Connecting to server... (press Escape to cancel)\n";
-                       std::wstring animation = L"/-\\|";
-                       ss<<animation[(int)(time_counter/0.2)%4];
-                       draw_load_screen(ss.str(), device, font);
+                       {
+                               wchar_t* text = wgettext("Connecting to server...");
+                               draw_load_screen(text, device, font, dtime, 100);
+                               delete[] text;
+                       }
                        
-                       // Delay a bit
-                       sleep_ms(1000*frametime);
-                       time_counter += frametime;
+                       // 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;
                }
        }
        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...";
+                       {
+                               ss << "Item definitions...";
+                               progress = 0;
+                       }
                        else if (!client.nodedefReceived())
-                               ss << L"Node definitions...";
+                       {
+                               ss << "Node definitions...";
+                               progress = 25;
+                       }
                        else
-                               ss << L"Media (" << (int)(client.mediaReceiveProgress()*100+0.5) << L"%)...";
-                       
-                       if (clouds != 0)
                        {
-                               clouds->step(frametime*3); 
-                               clouds->render();
+                               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();
index b87a3e6d0e7cfa19d585e85db81d3019304a9a21..94382ec6085eaaa8575e7161cc9862e3f9b9b5ec 100644 (file)
@@ -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"<<std::endl;
 
                                        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;
 
        /*
index daa8c70d28be2a61f7216646e85020ced5717a03..df67a634848bfecd28d534749cf82018bc39c404 100644 (file)
@@ -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 <fstream>