if something is already in it)\r
- Use it in active block queue in water flowing\r
\r
-SUGG: Signs could be done in the same way as torches. For this, blocks\r
- need an additional metadata field for the texts\r
- - This is also needed for item container chests\r
-\r
SUGG: Precalculate lighting translation table at runtime (at startup)\r
\r
SUGG: A version number to blocks, which increments when the block is\r
gets used\r
- That is >500 vertices\r
\r
-TODO: Better dungeons\r
-TODO: Cliffs, arcs\r
-\r
TODO: Startup and configuration menu\r
\r
TODO: There are some lighting-related todos and fixmes in\r
\r
TODO: Make the video backend selectable\r
\r
+TODO: Copy the text of the last picked sign to inventory in creative\r
+ mode\r
+\r
+TODO: Get rid of GotSplitPacketException\r
+\r
+TODO: Check what goes wrong with caching map to disk (Kray)\r
+ - Nothing?\r
+\r
Block object server side:\r
- A "near blocks" buffer, in which some nearby blocks are stored.\r
- For all blocks in the buffer, objects are stepped(). This\r
- TODO: For incoming blocks, time difference is calculated and\r
objects are stepped according to it.\r
\r
-TODO: Copy the text of the last picked sign to inventory in creative\r
- mode\r
-\r
-TODO: Get rid of GotSplitPacketException\r
-\r
-TODO: Check what goes wrong with caching map to disk (Kray)\r
-\r
-TODO: Remove LazyMeshUpdater. It is not used as supposed.\r
-\r
-TODO: TOSERVER_LEAVE\r
-\r
TODO: Better handling of objects and mobs\r
- Scripting?\r
- There has to be some way to do it with less spaghetti code\r
TODO: Draw big amounts of torches better (that is, throw them in the\r
same meshbuffer (can the meshcollector class be used?))\r
\r
-TODO: Check if the usage of Client::isFetchingBlocks() in\r
- updateViewingRange() actually does something\r
-\r
TODO: Make an option to the server to disable building and digging near\r
the starting position\r
\r
+SUGG: Signs could be done in the same way as torches. For this, blocks\r
+ need an additional metadata field for the texts\r
+ - This is also needed for item container chests\r
+TODO: There has to be some better way to handle static objects than to\r
+ send them all the time. This affects signs and item objects.\r
+\r
+TODO: When server sees that client is removing an inexistent block or\r
+ adding a block to an existent position, resend the MapBlock.\r
+\r
+TODO: When player dies, throw items on map\r
+\r
+TODO: Use porting::path_userdata for configuration file\r
+\r
+TODO: Optimize day/night mesh updating somehow\r
+ - create copies of all textures for all lighting values and only\r
+ change texture for material?\r
+ - Umm... the collecting of the faces is the slow part\r
+ -> what about just changing the color values of the existing\r
+ meshbuffers? It should go quite fast.\r
+\r
+TODO: Map generator version 2\r
+ - Create surface areas based on central points; a given point's\r
+ area type is given by the nearest central point\r
+ - Separate points for heightmap, caves, plants and minerals?\r
+ - Flat land, mountains, forest, jungle\r
+ - Cliffs, arcs\r
+\r
+TODO: Add gui option to remove map\r
+\r
Doing now:\r
======================================================================\r
\r
-TODO: Tool capability table: Which materials, at what speed, how much\r
- wearing\r
-TODO: Transferring of the table from server to client\r
-\r
======================================================================\r
\r
*/\r
*/\r
#define FIELD_OF_VIEW_TEST 0\r
\r
-#ifdef UNITTEST_DISABLE\r
+#ifdef NDEBUG\r
#ifdef _WIN32\r
#pragma message ("Disabling unit tests")\r
#else\r
#include "guiInventoryMenu.h"\r
#include "guiTextInputMenu.h"\r
#include "materials.h"\r
+#include "guiMessageMenu.h"\r
+#include "filesys.h"\r
+#include "config.h"\r
\r
IrrlichtWrapper *g_irrlicht;\r
\r
-// All range-related stuff below is locked behind this\r
-JMutex g_range_mutex;\r
-\r
-// Blocks are viewed in this range from the player\r
-s16 g_viewing_range_nodes = 60;\r
-//s16 g_viewing_range_nodes = 0;\r
-\r
-// This is updated by the client's fetchBlocks routine\r
-//s16 g_actual_viewing_range_nodes = VIEWING_RANGE_NODES_DEFAULT;\r
-\r
-// If true, the preceding value has no meaning and all blocks\r
-// already existing in memory are drawn\r
-bool g_viewing_range_all = false;\r
-\r
-// This is the freetime ratio imposed by the dynamic viewing\r
-// range changing code.\r
-// It is controlled by the main loop to the smallest value that\r
-// inhibits glitches (dtime jitter) in the main loop.\r
-//float g_freetime_ratio = FREETIME_RATIO_MAX;\r
+MapDrawControl draw_control;\r
\r
/*\r
Settings.\r
// Viewing range selection\r
if(event.KeyInput.Key == irr::KEY_KEY_R)\r
{\r
- JMutexAutoLock lock(g_range_mutex);\r
- if(g_viewing_range_all)\r
+ if(draw_control.range_all)\r
{\r
- g_viewing_range_all = false;\r
+ draw_control.range_all = false;\r
dstream<<DTIME<<"Disabled full viewing range"<<std::endl;\r
}\r
else\r
{\r
- g_viewing_range_all = true;\r
+ draw_control.range_all = true;\r
dstream<<DTIME<<"Enabled full viewing range"<<std::endl;\r
}\r
}\r
\r
s32 Rand(s32 min, s32 max)\r
{\r
- return (rand()%(max-min+1))+min;\r
+ return (myrand()%(max-min+1))+min;\r
}\r
private:\r
bool keydown[KEY_KEY_CODES_COUNT];\r
bool rightclicked;\r
};\r
\r
-void updateViewingRange(f32 frametime, Client *client)\r
+void updateViewingRange(f32 frametime_in, Client *client)\r
{\r
- // Range_all messes up frametime_avg\r
- if(g_viewing_range_all == true)\r
+ if(draw_control.range_all == true)\r
return;\r
-\r
- float wanted_fps = g_settings.getFloat("wanted_fps");\r
\r
- // Initialize to the target value\r
- static float frametime_avg = 1.0/wanted_fps;\r
- //frametime_avg = frametime_avg * 0.9 + frametime * 0.1;\r
- frametime_avg = frametime_avg * 0.7 + frametime * 0.3;\r
+ static f32 added_frametime = 0;\r
+ static s16 added_frames = 0;\r
+\r
+ added_frametime += frametime_in;\r
+ added_frames += 1;\r
\r
+ // Actually this counter kind of sucks because frametime is busytime\r
static f32 counter = 0;\r
- if(counter > 0){\r
- counter -= frametime;\r
+ counter -= frametime_in;\r
+ if(counter > 0)\r
return;\r
- }\r
- //counter = 1.0; //seconds\r
- counter = 0.5; //seconds\r
-\r
- //float freetime_ratio = 0.2;\r
- //float freetime_ratio = 0.4;\r
- float freetime_ratio = FREETIME_RATIO;\r
+ //counter = 0.1;\r
+ counter = 0.2;\r
\r
- float frametime_wanted = (1.0/(wanted_fps/(1.0-freetime_ratio)));\r
-\r
- float fraction = sqrt(frametime_avg / frametime_wanted);\r
-\r
- /*float fraction = sqrt(frametime_avg / frametime_wanted) / 2.0\r
- + frametime_avg / frametime_wanted / 2.0;*/\r
+ /*dstream<<__FUNCTION_NAME\r
+ <<": Collected "<<added_frames<<" frames, total of "\r
+ <<added_frametime<<"s."<<std::endl;*/\r
\r
- //float fraction = frametime_avg / frametime_wanted;\r
-\r
- static bool fraction_is_good = false;\r
+ /*dstream<<"draw_control.blocks_drawn="\r
+ <<draw_control.blocks_drawn\r
+ <<", draw_control.blocks_would_have_drawn="\r
+ <<draw_control.blocks_would_have_drawn\r
+ <<std::endl;*/\r
\r
- //float fraction_good_threshold = 0.1;\r
- //float fraction_bad_threshold = 0.25;\r
- float fraction_good_threshold = 0.075;\r
- float fraction_bad_threshold = 0.125;\r
- float fraction_limit;\r
- // Use high limit if fraction is good AND the fraction would\r
- // lower the range. We want to keep the range fairly high.\r
- if(fraction_is_good && fraction > 1.0)\r
- fraction_limit = fraction_bad_threshold;\r
- else\r
- fraction_limit = fraction_good_threshold;\r
-\r
- if(fabs(fraction - 1.0) < fraction_limit)\r
+ float range_min = g_settings.getS16("viewing_range_nodes_min");\r
+ float range_max = g_settings.getS16("viewing_range_nodes_max");\r
+ \r
+ draw_control.wanted_min_range = range_min;\r
+ draw_control.wanted_max_blocks = (1.2*draw_control.blocks_drawn)+1;\r
+ \r
+ float block_draw_ratio = 1.0;\r
+ if(draw_control.blocks_would_have_drawn != 0)\r
{\r
- fraction_is_good = true;\r
- return;\r
+ block_draw_ratio = (float)draw_control.blocks_drawn\r
+ / (float)draw_control.blocks_would_have_drawn;\r
}\r
- else\r
+\r
+ // Calculate the average frametime in the case that all wanted\r
+ // blocks had been drawn\r
+ f32 frametime = added_frametime / added_frames / block_draw_ratio;\r
+ \r
+ added_frametime = 0.0;\r
+ added_frames = 0;\r
+ \r
+ float wanted_fps = g_settings.getFloat("wanted_fps");\r
+ float wanted_frametime = 1.0 / wanted_fps;\r
+ \r
+ f32 wanted_frametime_change = wanted_frametime - frametime;\r
+ //dstream<<"wanted_frametime_change="<<wanted_frametime_change<<std::endl;\r
+ \r
+ // If needed frametime change is very small, just return\r
+ if(fabs(wanted_frametime_change) < wanted_frametime*0.2)\r
{\r
- fraction_is_good = false;\r
+ //dstream<<"ignoring small wanted_frametime_change"<<std::endl;\r
+ return;\r
}\r
\r
- //dstream<<"frametime_avg="<<frametime_avg<<std::endl;\r
- //dstream<<"frametime_wanted="<<frametime_wanted<<std::endl;\r
- /*dstream<<"fetching="<<client->isFetchingBlocks()\r
- <<" faction = "<<fraction<<std::endl;*/\r
+ float range = draw_control.wanted_range;\r
+ float new_range = range;\r
\r
- JMutexAutoLock lock(g_range_mutex);\r
+ static s16 range_old = 0;\r
+ static f32 frametime_old = 0;\r
+ \r
+ float d_range = range - range_old;\r
+ f32 d_frametime = frametime - frametime_old;\r
+ // A sane default of 30ms per 50 nodes of range\r
+ static f32 time_per_range = 30. / 50;\r
+ if(d_range != 0)\r
+ {\r
+ time_per_range = d_frametime / d_range;\r
+ }\r
\r
- s16 viewing_range_nodes_min = g_settings.getS16("viewing_range_nodes_min");\r
- s16 viewing_range_nodes_max = g_settings.getS16("viewing_range_nodes_max");\r
+ // The minimum allowed calculated frametime-range derivative:\r
+ // Practically this sets the maximum speed of changing the range.\r
+ // The lower this value, the higher the maximum changing speed.\r
+ // A low value here results in wobbly range (0.001)\r
+ // A high value here results in slow changing range (0.0025)\r
+ // SUGG: This could be dynamically adjusted so that when\r
+ // the camera is turning, this is lower\r
+ //float min_time_per_range = 0.0015;\r
+ float min_time_per_range = 0.0010;\r
+ //float min_time_per_range = 0.05 / range;\r
+ if(time_per_range < min_time_per_range)\r
+ {\r
+ time_per_range = min_time_per_range;\r
+ //dstream<<"time_per_range="<<time_per_range<<" (min)"<<std::endl;\r
+ }\r
+ else\r
+ {\r
+ //dstream<<"time_per_range="<<time_per_range<<std::endl;\r
+ }\r
\r
- s16 n = (float)g_viewing_range_nodes / fraction;\r
- if(n < viewing_range_nodes_min)\r
- n = viewing_range_nodes_min;\r
- if(n > viewing_range_nodes_max)\r
- n = viewing_range_nodes_max;\r
+ f32 wanted_range_change = wanted_frametime_change / time_per_range;\r
+ // Dampen the change a bit to kill oscillations\r
+ //wanted_range_change *= 0.9;\r
+ //wanted_range_change *= 0.75;\r
+ wanted_range_change *= 0.5;\r
+ //dstream<<"wanted_range_change="<<wanted_range_change<<std::endl;\r
\r
- bool can_change = true;\r
+ // If needed range change is very small, just return\r
+ if(fabs(wanted_range_change) < 0.001)\r
+ {\r
+ //dstream<<"ignoring small wanted_range_change"<<std::endl;\r
+ return;\r
+ }\r
\r
- if(client->isFetchingBlocks() == true && n > g_viewing_range_nodes)\r
- can_change = false;\r
+ new_range += wanted_range_change;\r
+ //dstream<<"new_range="<<new_range/*<<std::endl*/;\r
\r
- if(can_change)\r
- g_viewing_range_nodes = n;\r
+ //float new_range_unclamped = new_range;\r
+ if(new_range < range_min)\r
+ new_range = range_min;\r
+ if(new_range > range_max)\r
+ new_range = range_max;\r
+ \r
+ /*if(new_range != new_range_unclamped)\r
+ dstream<<", clamped to "<<new_range<<std::endl;\r
+ else\r
+ dstream<<std::endl;*/\r
\r
- /*dstream<<"g_viewing_range_nodes = "\r
- <<g_viewing_range_nodes<<std::endl;*/\r
+ draw_control.wanted_range = new_range;\r
+\r
+ range_old = new_range;\r
+ frametime_old = frametime;\r
}\r
\r
class GUIQuickInventory : public IEventReceiver\r
debug_stacks_init();\r
\r
DSTACK(__FUNCTION_NAME);\r
- \r
+\r
+ porting::initializePaths();\r
+ // Create user data directory\r
+ fs::CreateDir(porting::path_userdata);\r
+\r
initializeMaterialProperties();\r
\r
+ BEGIN_DEBUG_EXCEPTION_HANDLER\r
+\r
+ // Print startup message\r
+ dstream<<DTIME<<"minetest-c55"\r
+ " with SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST\r
+ <<", "<<BUILD_INFO\r
+ <<std::endl;\r
+ \r
try\r
{\r
\r
allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG));\r
allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG));\r
allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG));\r
+ allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING));\r
\r
Settings cmd_args;\r
\r
// Initialize default settings\r
set_default_settings();\r
\r
- // Print startup message\r
- dstream<<DTIME<<"minetest-c55"\r
- " with SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST\r
- <<", ENABLE_TESTS="<<ENABLE_TESTS\r
- <<std::endl;\r
- \r
// Set locale. This is for forcing '.' as the decimal point.\r
std::locale::global(std::locale("C"));\r
// This enables printing all characters in bitmap font\r
}\r
else\r
{\r
- const char *filenames[2] =\r
- {\r
- "../minetest.conf",\r
- "../../minetest.conf"\r
- };\r
+ core::array<std::string> filenames;\r
+ filenames.push_back(porting::path_userdata + "/minetest.conf");\r
+#ifdef RUN_IN_PLACE\r
+ filenames.push_back(porting::path_userdata + "/../minetest.conf");\r
+#endif\r
\r
- for(u32 i=0; i<2; i++)\r
+ for(u32 i=0; i<filenames.size(); i++)\r
{\r
- bool r = g_settings.readConfigFile(filenames[i]);\r
+ bool r = g_settings.readConfigFile(filenames[i].c_str());\r
if(r)\r
{\r
configpath = filenames[i];\r
\r
// Initialize random seed\r
srand(time(0));\r
+ mysrand(time(0));\r
\r
/*\r
Run unit tests\r
run_tests();\r
}\r
\r
- /*\r
- Global range mutex\r
- */\r
- g_range_mutex.Init();\r
- assert(g_range_mutex.IsInitialized());\r
-\r
// Read map parameters from settings\r
\r
HMParams hm_params;\r
std::cout<<"-> "<<port<<std::endl;\r
}\r
\r
+ //Map directory\r
+ std::string map_dir = porting::path_userdata+"/map";\r
+ if(cmd_args.exists("map-dir"))\r
+ map_dir = cmd_args.get("map-dir");\r
+ else if(g_settings.exists("map-dir"))\r
+ map_dir = g_settings.get("map-dir");\r
+ \r
if(cmd_args.getFlag("server"))\r
{\r
DSTACK("Dedicated server branch");\r
std::cout<<"========================"<<std::endl;\r
std::cout<<std::endl;\r
\r
- Server server("../map", hm_params, map_params);\r
+ Server server(map_dir, hm_params, map_params);\r
server.start(port);\r
\r
for(;;)\r
/*\r
This changes the minimum allowed number of vertices in a VBO\r
*/\r
- //driver->setMinHardwareBufferVertexCount(1);\r
+ //driver->setMinHardwareBufferVertexCount(50);\r
\r
scene::ISceneManager* smgr = device->getSceneManager();\r
\r
guienv = device->getGUIEnvironment();\r
gui::IGUISkin* skin = guienv->getSkin();\r
- gui::IGUIFont* font = guienv->getFont("../data/fontlucida.png");\r
+ gui::IGUIFont* font = guienv->getFont(porting::getDataPath("fontlucida.png").c_str());\r
if(font)\r
skin->setFont(font);\r
\r
Preload some textures\r
*/\r
\r
+ init_content_inventory_texture_paths();\r
+ init_tile_texture_paths();\r
tile_materials_preload(g_irrlicht);\r
\r
/*\r
*/\r
SharedPtr<Server> server;\r
if(hosting){\r
- server = new Server("../map", hm_params, map_params);\r
+ server = new Server(map_dir, hm_params, map_params);\r
server->start(port);\r
}\r
\r
Create client\r
*/\r
\r
- Client client(device, playername,\r
- g_range_mutex,\r
- g_viewing_range_nodes,\r
- g_viewing_range_all);\r
+ Client client(device, playername, draw_control);\r
\r
g_client = &client;\r
\r
*/\r
/*scene::ISceneNode* skybox;\r
skybox = smgr->addSkyBoxSceneNode(\r
- driver->getTexture("../data/skybox2.png"),\r
- driver->getTexture("../data/skybox3.png"),\r
- driver->getTexture("../data/skybox1.png"),\r
- driver->getTexture("../data/skybox1.png"),\r
- driver->getTexture("../data/skybox1.png"),\r
- driver->getTexture("../data/skybox1.png"));*/\r
+ driver->getTexture(porting::getDataPath("skybox2.png").c_str()),\r
+ driver->getTexture(porting::getDataPath("skybox3.png").c_str()),\r
+ driver->getTexture(porting::getDataPath("skybox1.png").c_str()),\r
+ driver->getTexture(porting::getDataPath("skybox1.png").c_str()),\r
+ driver->getTexture(porting::getDataPath("skybox1.png").c_str()),\r
+ driver->getTexture(porting::getDataPath("skybox1.png").c_str()));*/\r
\r
/*\r
Create the camera node\r
// Test the text input system\r
/*(new GUITextInputMenu(guienv, guiroot, -1, &g_active_menu_count,\r
NULL))->drop();*/\r
+ /*GUIMessageMenu *menu =\r
+ new GUIMessageMenu(guienv, guiroot, -1, \r
+ &g_active_menu_count,\r
+ L"Asd");\r
+ menu->drop();*/\r
\r
// Launch pause menu\r
(new GUIPauseMenu(guienv, guiroot, -1, g_device,\r
L"Chat here\nOther line\nOther line\nOther line\nOther line",\r
core::rect<s32>(70, 60, 795, 150),\r
false, true);\r
+ chat_guitext->setBackgroundColor(video::SColor(96,0,0,0));\r
core::list<ChatLine> chat_lines;\r
\r
/*\r
u32 beginscenetime = 0;\r
u32 scenetime = 0;\r
u32 endscenetime = 0;\r
+ \r
+ // A test\r
+ //throw con::PeerNotFoundException("lol");\r
\r
/*\r
Main loop\r
bool first_loop_after_window_activation = true;\r
\r
// Time is in milliseconds\r
- // NOTE: getRealTime() without run()s causes strange problems in wine\r
- // NOTE: Have to call run() between calls of this to update the timer\r
+ // NOTE: getRealTime() causes strange problems in wine (imprecision?)\r
+ // NOTE: So we have to use getTime() and call run()s between them\r
u32 lasttime = device->getTimer()->getTime();\r
\r
while(device->run())\r
v3f camera_direction = v3f(0,0,1);\r
camera_direction.rotateYZBy(camera_pitch);\r
camera_direction.rotateXZBy(camera_yaw);\r
-\r
+ \r
+ // This is at the height of the eyes of the current figure\r
v3f camera_position =\r
player_position + v3f(0, BS+BS/2, 0);\r
+ // This is more like in minecraft\r
+ /*v3f camera_position =\r
+ player_position + v3f(0, BS+BS*0.65, 0);*/\r
\r
camera->setPosition(camera_position);\r
// *100.0 helps in large map coordinates\r
camera->setAspectRatio((f32)screensize.X / (f32)screensize.Y);\r
\r
u32 daynight_ratio = client.getDayNightRatio();\r
- video::SColor bgcolor = video::SColor(\r
+ /*video::SColor bgcolor = video::SColor(\r
255,\r
skycolor.getRed() * daynight_ratio / 1000,\r
skycolor.getGreen() * daynight_ratio / 1000,\r
- skycolor.getBlue() * daynight_ratio / 1000);\r
+ skycolor.getBlue() * daynight_ratio / 1000);*/\r
+\r
+ u8 l = decode_light((daynight_ratio * LIGHT_SUN) / 1000);\r
+ video::SColor bgcolor = video::SColor(\r
+ 255,\r
+ skycolor.getRed() * l / 255,\r
+ skycolor.getGreen() * l / 255,\r
+ skycolor.getBlue() * l / 255);\r
\r
/*\r
Fog\r
\r
if(g_settings.getBool("enable_fog") == true)\r
{\r
- f32 range = g_viewing_range_nodes * BS;\r
- if(g_viewing_range_all)\r
+ f32 range = draw_control.wanted_range * BS;\r
+ if(draw_control.range_all)\r
range = 100000*BS;\r
\r
driver->setFog(\r
wchar_t temptext[150];\r
\r
static float drawtime_avg = 0;\r
- drawtime_avg = drawtime_avg * 0.98 + (float)drawtime*0.02;\r
+ drawtime_avg = drawtime_avg * 0.95 + (float)drawtime*0.05;\r
static float beginscenetime_avg = 0;\r
- beginscenetime_avg = beginscenetime_avg * 0.98 + (float)beginscenetime*0.02;\r
+ beginscenetime_avg = beginscenetime_avg * 0.95 + (float)beginscenetime*0.05;\r
static float scenetime_avg = 0;\r
- scenetime_avg = scenetime_avg * 0.98 + (float)scenetime*0.02;\r
+ scenetime_avg = scenetime_avg * 0.95 + (float)scenetime*0.05;\r
static float endscenetime_avg = 0;\r
- endscenetime_avg = endscenetime_avg * 0.98 + (float)endscenetime*0.02;\r
+ endscenetime_avg = endscenetime_avg * 0.95 + (float)endscenetime*0.05;\r
\r
swprintf(temptext, 150, L"Minetest-c55 ("\r
L"F: item=%i"\r
L")"\r
L" drawtime=%.0f, beginscenetime=%.0f, scenetime=%.0f, endscenetime=%.0f",\r
g_selected_item,\r
- g_viewing_range_all,\r
+ draw_control.range_all,\r
drawtime_avg,\r
beginscenetime_avg,\r
scenetime_avg,\r
swprintf(temptext, 150,\r
L"(% .1f, % .1f, % .1f)"\r
L" (% .3f < btime_jitter < % .3f"\r
- L", dtime_jitter = % .1f %%)",\r
+ L", dtime_jitter = % .1f %%"\r
+ L", v_range = %.1f)",\r
player_position.X/BS,\r
player_position.Y/BS,\r
player_position.Z/BS,\r
busytime_jitter1_min_sample,\r
busytime_jitter1_max_sample,\r
- dtime_jitter1_max_fraction * 100.0\r
+ dtime_jitter1_max_fraction * 100.0,\r
+ draw_control.wanted_range\r
);\r
\r
guitext2->setText(temptext);\r
while(client.getChatMessage(message))\r
{\r
chat_lines.push_back(ChatLine(message));\r
- if(chat_lines.size() > 7)\r
+ /*if(chat_lines.size() > 6)\r
{\r
core::list<ChatLine>::Iterator\r
i = chat_lines.begin();\r
chat_lines.erase(i);\r
- }\r
+ }*/\r
}\r
// Append them to form the whole static text and throw\r
// it to the gui element\r
std::wstring whole;\r
+ // This will correspond to the line number counted from\r
+ // top to bottom, from size-1 to 0\r
+ s16 line_number = chat_lines.size();\r
+ // Count of messages to be removed from the top\r
u16 to_be_removed_count = 0;\r
for(core::list<ChatLine>::Iterator\r
i = chat_lines.begin();\r
i != chat_lines.end(); i++)\r
{\r
+ // After this, line number is valid for this loop\r
+ line_number--;\r
+ // Increment age\r
(*i).age += dtime;\r
- if((*i).age > 60.0)\r
+ /*\r
+ This results in a maximum age of 60*6 to the\r
+ lowermost line and a maximum of 6 lines\r
+ */\r
+ float allowed_age = (6-line_number) * 60.0;\r
+\r
+ if((*i).age > allowed_age)\r
{\r
to_be_removed_count++;\r
continue;\r
screensize.Y - 10\r
);\r
chat_guitext->setRelativePosition(rect);\r
+\r
+ if(chat_lines.size() == 0)\r
+ chat_guitext->setVisible(false);\r
+ else\r
+ chat_guitext->setVisible(true);\r
}\r
\r
/*\r
catch(con::PeerNotFoundException &e)\r
{\r
dstream<<DTIME<<"Connection timed out."<<std::endl;\r
+ \r
+ /*if(g_device)\r
+ {\r
+ GUIMessageMenu *menu =\r
+ new GUIMessageMenu(guienv, guiroot, -1, \r
+ &g_active_menu_count,\r
+ L"Connection timed out");\r
+\r
+ video::IVideoDriver* driver = g_device->getVideoDriver();\r
+ \r
+ dstream<<"Created menu"<<std::endl;\r
+\r
+ while(g_device->run() && menu->getStatus() == false)\r
+ {\r
+ driver->beginScene(true, true, video::SColor(255,0,0,0));\r
+ guienv->drawAll();\r
+ driver->endScene();\r
+ }\r
+ \r
+ dstream<<"Dropping menu"<<std::endl;\r
+\r
+ menu->drop();\r
+ }*/\r
}\r
-#if CATCH_UNHANDLED_EXCEPTIONS\r
- /*\r
- This is what has to be done in every thread to get suitable debug info\r
- */\r
- catch(std::exception &e)\r
- {\r
- dstream<<std::endl<<DTIME<<"An unhandled exception occurred: "\r
- <<e.what()<<std::endl;\r
- assert(0);\r
- }\r
-#endif\r
\r
+ END_DEBUG_EXCEPTION_HANDLER\r
+ \r
debugstreams_deinit();\r
\r
return 0;\r