Add clouds to all loading screens and better progress handling

This commit is contained in:
Zeg9 2013-05-09 18:23:48 +02:00 committed by PilzAdam
parent d859ad7ed7
commit 81c863ac4d
3 changed files with 163 additions and 81 deletions

@ -396,12 +396,11 @@ PointedThing getPointedThing(Client *client, v3f player_position,
Draws a screen with a single text on it. Draws a screen with a single text on it.
Text will be removed when the screen is drawn the next time. 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. Additionally, a progressbar can be drawn when percent is set between 0 and 100.
With drawsmgr, you can for example draw clouds
*/ */
/*gui::IGUIStaticText **/ /*gui::IGUIStaticText **/
void draw_load_screen(const std::wstring &text, void draw_load_screen(const std::wstring &text,
IrrlichtDevice* device, gui::IGUIFont* font, 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(); video::IVideoDriver* driver = device->getVideoDriver();
v2u32 screensize = driver->getScreenSize(); v2u32 screensize = driver->getScreenSize();
@ -415,11 +414,13 @@ void draw_load_screen(const std::wstring &text,
loadingtext, textrect, false, false); loadingtext, textrect, false, false);
guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT); 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)); driver->beginScene(true, true, video::SColor(255,140,186,250));
scene::ISceneManager* smgr = device->getSceneManager(); g_menucloudsmgr->drawAll();
smgr->drawAll();
} }
else else
driver->beginScene(true, true, video::SColor(255,0,0,0)); 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::vector2d<s32> barsize(256,32);
core::rect<s32> barrect(center-barsize/2, center+barsize/2); 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,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.UpperLeftCorner+1,
barrect.LowerRightCorner-1), NULL); // black inside the bar barrect.LowerRightCorner-1), NULL); // black inside the bar
driver->draw2DRectangle(video::SColor(255,128,128,128), core::rect<s32> ( driver->draw2DRectangle(video::SColor(255,128,128,128), core::rect<s32> (
@ -907,7 +908,11 @@ void the_game(
Draw "Loading" screen 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 // Create texture source
IWritableTextureSource *tsrc = createTextureSource(device); IWritableTextureSource *tsrc = createTextureSource(device);
@ -964,7 +969,9 @@ void the_game(
*/ */
if(address == ""){ 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; infostream<<"Creating server"<<std::endl;
server = new Server(map_dir, configpath, gamespec, server = new Server(map_dir, configpath, gamespec,
simple_singleplayer_mode); simple_singleplayer_mode);
@ -977,7 +984,11 @@ void the_game(
Create client 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; infostream<<"Creating client"<<std::endl;
MapDrawControl draw_control; MapDrawControl draw_control;
@ -988,7 +999,11 @@ void the_game(
// Client acts as our GameDef // Client acts as our GameDef
IGameDef *gamedef = &client; 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); Address connect_address(0,0,0,0, port);
try{ try{
if(address == "") if(address == "")
@ -1020,15 +1035,26 @@ void the_game(
bool could_connect = false; bool could_connect = false;
bool connect_aborted = false; bool connect_aborted = false;
try{ try{
float frametime = 0.033;
float time_counter = 0.0; float time_counter = 0.0;
input->clear(); 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()) 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 // Update client and server
client.step(frametime); client.step(dtime);
if(server != NULL) if(server != NULL)
server->step(frametime); server->step(dtime);
// End condition // End condition
if(client.connectedAndInitialized()){ if(client.connectedAndInitialized()){
@ -1049,15 +1075,37 @@ void the_game(
} }
// Display status // Display status
std::wostringstream ss; {
ss<<L"Connecting to server... (press Escape to cancel)\n"; wchar_t* text = wgettext("Connecting to server...");
std::wstring animation = L"/-\\|"; draw_load_screen(text, device, font, dtime, 100);
ss<<animation[(int)(time_counter/0.2)%4]; delete[] text;
draw_load_screen(ss.str(), device, font); }
// Delay a bit // On some computers framerate doesn't seem to be
sleep_ms(1000*frametime); // automatically limited
time_counter += frametime; 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) catch(con::PeerNotFoundException &e)
@ -1081,32 +1129,26 @@ void the_game(
bool got_content = false; bool got_content = false;
bool content_aborted = false; bool content_aborted = false;
{ {
float frametime = 0.033;
float time_counter = 0.0; float time_counter = 0.0;
input->clear(); input->clear();
float fps_max = g_settings->getFloat("fps_max");
scene::ISceneManager* smgr = device->getSceneManager(); bool cloud_menu_background = g_settings->getBool("menu_clouds");
Clouds *clouds = 0; u32 lasttime = device->getTimer()->getTime();
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);
}
while(device->run()) 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 // Update client and server
client.step(frametime); client.step(dtime);
if(server != NULL) if(server != NULL)
server->step(frametime); server->step(dtime);
// End condition // End condition
if(client.texturesReceived() && if(client.texturesReceived() &&
@ -1128,30 +1170,52 @@ void the_game(
} }
// Display status // Display status
std::wostringstream ss; std::ostringstream ss;
int progress=0;
if (!client.itemdefReceived()) if (!client.itemdefReceived())
ss << L"Item definitions..."; {
ss << "Item definitions...";
progress = 0;
}
else if (!client.nodedefReceived()) else if (!client.nodedefReceived())
ss << L"Node definitions..."; {
ss << "Node definitions...";
progress = 25;
}
else else
ss << L"Media (" << (int)(client.mediaReceiveProgress()*100+0.5) << L"%)...";
if (clouds != 0)
{ {
clouds->step(frametime*3); ss << "Media...";
clouds->render(); 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); // 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;
// Delay a bit // FPS limiter
sleep_ms(1000*frametime); u32 frametime_min = 1000./fps_max;
time_counter += frametime;
if(busytime_u32 < frametime_min) {
u32 sleeptime = frametime_min - busytime_u32;
device->sleep(sleeptime);
} }
if (clouds != 0) } else {
{ sleep_ms(25);
smgr->addToDeletionQueue(clouds); }
clouds->drop(); time_counter += dtime;
} }
} }
@ -3278,7 +3342,9 @@ void the_game(
*/ */
{ {
/*gui::IGUIStaticText *gui_shuttingdowntext = */ /*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)); /*driver->beginScene(true, true, video::SColor(255,0,0,0));
guienv->drawAll(); guienv->drawAll();
driver->endScene(); driver->endScene();

@ -88,6 +88,10 @@ Settings *g_settings = &main_settings;
Profiler main_profiler; Profiler main_profiler;
Profiler *g_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 Debug streams
*/ */
@ -1569,6 +1573,19 @@ int main(int argc, char *argv[])
skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255,96,134,49)); skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255,96,134,49));
#endif #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 GUI stuff
*/ */
@ -1744,18 +1761,6 @@ int main(int argc, char *argv[])
&g_menumgr, &menudata, g_gamecallback); &g_menumgr, &menudata, g_gamecallback);
menu->allowFocusRemoval(true); 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"") if(error_message != L"")
{ {
verbosestream<<"error_message = " verbosestream<<"error_message = "
@ -1796,7 +1801,7 @@ int main(int argc, char *argv[])
} }
// Time calc for the clouds // Time calc for the clouds
f32 dtime; // in seconds f32 dtime=0; // in seconds
if (cloud_menu_background) { if (cloud_menu_background) {
u32 time = device->getTimer()->getTime(); u32 time = device->getTimer()->getTime();
if(time > lasttime) if(time > lasttime)
@ -1811,9 +1816,9 @@ int main(int argc, char *argv[])
if (cloud_menu_background) { if (cloud_menu_background) {
// *3 otherwise the clouds would move very slowly // *3 otherwise the clouds would move very slowly
clouds->step(dtime*3); g_menuclouds->step(dtime*3);
clouds->render(); g_menuclouds->render();
smgr->drawAll(); g_menucloudsmgr->drawAll();
drawMenuOverlay(driver, menutextures); drawMenuOverlay(driver, menutextures);
drawMenuHeader(driver, menutextures); drawMenuHeader(driver, menutextures);
drawMenuFooter(driver, menutextures); drawMenuFooter(driver, menutextures);
@ -1856,8 +1861,6 @@ int main(int argc, char *argv[])
infostream<<"Dropping main menu"<<std::endl; infostream<<"Dropping main menu"<<std::endl;
menu->drop(); menu->drop();
clouds->drop();
smgr->clear();
} }
playername = wide_to_narrow(menudata.name); playername = wide_to_narrow(menudata.name);
@ -2018,6 +2021,7 @@ int main(int argc, char *argv[])
gamespec, gamespec,
simple_singleplayer_mode simple_singleplayer_mode
); );
smgr->clear();
} //try } //try
catch(con::PeerNotFoundException &e) catch(con::PeerNotFoundException &e)
@ -2048,6 +2052,10 @@ int main(int argc, char *argv[])
} }
} // Menu-game loop } // Menu-game loop
g_menuclouds->drop();
g_menucloudsmgr->drop();
delete input; delete input;
/* /*

@ -28,6 +28,14 @@ extern Settings *g_settings;
class Profiler; class Profiler;
extern Profiler *g_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 // Debug streams
#include <fstream> #include <fstream>