- //video::SColor skycolor = video::SColor(255,90,140,200);\r
- video::SColor skycolor = video::SColor(255,166,202,244);\r
-\r
- camera->setFOV(FOV_ANGLE);\r
-\r
- // Just so big a value that everything rendered is visible\r
- camera->setFarValue(100000*BS);\r
-\r
- f32 camera_yaw = 0; // "right/left"\r
- f32 camera_pitch = 0; // "up/down"\r
-\r
- /*\r
- Move into game\r
- */\r
- \r
- gui_loadingtext->remove();\r
-\r
- /*\r
- Add some gui stuff\r
- */\r
-\r
- GUIQuickInventory *quick_inventory = new GUIQuickInventory\r
- (guienv, NULL, v2s32(10, 70), 5, &local_inventory);\r
- \r
- // Test the text input system\r
- /*(new GUITextInputMenu(guienv, guiroot, -1, &g_menumgr,\r
- NULL))->drop();*/\r
- /*GUIMessageMenu *menu =\r
- new GUIMessageMenu(guienv, guiroot, -1, \r
- &g_menumgr,\r
- L"Asd");\r
- menu->drop();*/\r
- \r
- // Launch pause menu\r
- (new GUIPauseMenu(guienv, guiroot, -1, &g_gamecallback,\r
- &g_menumgr))->drop();\r
- \r
- // Enable texts\r
- guitext2->setVisible(true);\r
- guitext_info->setVisible(true);\r
- guitext_chat->setVisible(true);\r
- \r
- /*\r
- Some statistics are collected in these\r
- */\r
- u32 drawtime = 0;\r
- u32 beginscenetime = 0;\r
- u32 scenetime = 0;\r
- u32 endscenetime = 0;\r
- \r
- // A test\r
- //throw con::PeerNotFoundException("lol");\r
-\r
- core::list<float> frametime_log;\r
-\r
- /*\r
- Main loop\r
- */\r
-\r
- bool first_loop_after_window_activation = true;\r
-\r
- // Time is in milliseconds\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
- {\r
- if(g_disconnect_requested)\r
- {\r
- g_disconnect_requested = false;\r
- break;\r
- }\r
-\r
- /*\r
- Run global IrrlichtWrapper's main thread processing stuff\r
- */\r
- g_irrlicht->Run();\r
-\r
- /*\r
- Process TextureSource's queue\r
- */\r
- texturesource->processQueue();\r
-\r
- /*\r
- Random calculations\r
- */\r
- v2u32 screensize = driver->getScreenSize();\r
- core::vector2d<s32> displaycenter(screensize.X/2,screensize.Y/2);\r
- \r
- // Hilight boxes collected during the loop and displayed\r
- core::list< core::aabbox3d<f32> > hilightboxes;\r
- \r
- // Info text\r
- std::wstring infotext;\r
-\r
- //TimeTaker //timer1("//timer1");\r
- \r
- // Time of frame without fps limit\r
- float busytime;\r
- u32 busytime_u32;\r
- {\r
- // not using getRealTime is necessary for wine\r
- u32 time = device->getTimer()->getTime();\r
- if(time > lasttime)\r
- busytime_u32 = time - lasttime;\r
- else\r
- busytime_u32 = 0;\r
- busytime = busytime_u32 / 1000.0;\r
- }\r
-\r
- //std::cout<<"busytime_u32="<<busytime_u32<<std::endl;\r
- \r
- // Absolutelu necessary for wine!\r
- device->run();\r
-\r
- /*\r
- Viewing range\r
- */\r
- \r
- updateViewingRange(busytime, &client);\r
- \r
- /*\r
- FPS limiter\r
- */\r
-\r
- {\r
- float fps_max = g_settings.getFloat("fps_max");\r
- u32 frametime_min = 1000./fps_max;\r
- \r
- if(busytime_u32 < frametime_min)\r
- {\r
- u32 sleeptime = frametime_min - busytime_u32;\r
- device->sleep(sleeptime);\r
- }\r
- }\r
-\r
- // Absolutelu necessary for wine!\r
- device->run();\r
-\r
- /*\r
- Time difference calculation\r
- */\r
- f32 dtime; // in seconds\r
- \r
- u32 time = device->getTimer()->getTime();\r
- if(time > lasttime)\r
- dtime = (time - lasttime) / 1000.0;\r
- else\r
- dtime = 0;\r
- lasttime = time;\r
-\r
- /*\r
- Log frametime for visualization\r
- */\r
- frametime_log.push_back(dtime);\r
- if(frametime_log.size() > 100)\r
- {\r
- core::list<float>::Iterator i = frametime_log.begin();\r
- frametime_log.erase(i);\r
- }\r
-\r
- /*\r
- Visualize frametime in terminal\r
- */\r
- /*for(u32 i=0; i<dtime*400; i++)\r
- std::cout<<"X";\r
- std::cout<<std::endl;*/\r
-\r
- /*\r
- Time average and jitter calculation\r
- */\r
-\r
- static f32 dtime_avg1 = 0.0;\r
- dtime_avg1 = dtime_avg1 * 0.98 + dtime * 0.02;\r
- f32 dtime_jitter1 = dtime - dtime_avg1;\r
-\r
- static f32 dtime_jitter1_max_sample = 0.0;\r
- static f32 dtime_jitter1_max_fraction = 0.0;\r
- {\r
- static f32 jitter1_max = 0.0;\r
- static f32 counter = 0.0;\r
- if(dtime_jitter1 > jitter1_max)\r
- jitter1_max = dtime_jitter1;\r
- counter += dtime;\r
- if(counter > 0.0)\r
- {\r
- counter -= 3.0;\r
- dtime_jitter1_max_sample = jitter1_max;\r
- dtime_jitter1_max_fraction\r
- = dtime_jitter1_max_sample / (dtime_avg1+0.001);\r
- jitter1_max = 0.0;\r
- }\r
- }\r
- \r
- /*\r
- Busytime average and jitter calculation\r
- */\r
-\r
- static f32 busytime_avg1 = 0.0;\r
- busytime_avg1 = busytime_avg1 * 0.98 + busytime * 0.02;\r
- f32 busytime_jitter1 = busytime - busytime_avg1;\r
- \r
- static f32 busytime_jitter1_max_sample = 0.0;\r
- static f32 busytime_jitter1_min_sample = 0.0;\r
- {\r
- static f32 jitter1_max = 0.0;\r
- static f32 jitter1_min = 0.0;\r
- static f32 counter = 0.0;\r
- if(busytime_jitter1 > jitter1_max)\r
- jitter1_max = busytime_jitter1;\r
- if(busytime_jitter1 < jitter1_min)\r
- jitter1_min = busytime_jitter1;\r
- counter += dtime;\r
- if(counter > 0.0){\r
- counter -= 3.0;\r
- busytime_jitter1_max_sample = jitter1_max;\r
- busytime_jitter1_min_sample = jitter1_min;\r
- jitter1_max = 0.0;\r
- jitter1_min = 0.0;\r
- }\r
- }\r
- \r
- /*\r
- Debug info for client\r
- */\r
- {\r
- static float counter = 0.0;\r
- counter -= dtime;\r
- if(counter < 0)\r
- {\r
- counter = 30.0;\r
- client.printDebugInfo(std::cout);\r
- }\r
- }\r
-\r
- /*\r
- Input handler step()\r
- */\r
- g_input->step(dtime);\r
-\r
- /*\r
- Player speed control\r
- */\r
- \r
- {\r
- /*bool a_up,\r
- bool a_down,\r
- bool a_left,\r
- bool a_right,\r
- bool a_jump,\r
- bool a_superspeed,\r
- bool a_sneak,\r
- float a_pitch,\r
- float a_yaw*/\r
- PlayerControl control(\r
- g_input->isKeyDown(irr::KEY_KEY_W),\r
- g_input->isKeyDown(irr::KEY_KEY_S),\r
- g_input->isKeyDown(irr::KEY_KEY_A),\r
- g_input->isKeyDown(irr::KEY_KEY_D),\r
- g_input->isKeyDown(irr::KEY_SPACE),\r
- g_input->isKeyDown(irr::KEY_KEY_E),\r
- g_input->isKeyDown(irr::KEY_LSHIFT)\r
- || g_input->isKeyDown(irr::KEY_RSHIFT),\r
- camera_pitch,\r
- camera_yaw\r
- );\r
- client.setPlayerControl(control);\r
- }\r
-\r
- /*\r
- Process environment\r
- */\r
- \r
- {\r
- //TimeTaker timer("client.step(dtime)");\r
- client.step(dtime);\r
- //client.step(dtime_avg1);\r
- }\r
-\r
- if(server != NULL)\r
- {\r
- //TimeTaker timer("server->step(dtime)");\r
- server->step(dtime);\r
- }\r
-\r
- v3f player_position = client.getPlayerPosition();\r
- \r
- //TimeTaker //timer2("//timer2");\r
-\r
- /*\r
- Mouse and camera control\r
- */\r
- \r
- if((device->isWindowActive() && noMenuActive()) || random_input)\r
- {\r
- if(!random_input)\r
- device->getCursorControl()->setVisible(false);\r
-\r
- if(first_loop_after_window_activation){\r
- //std::cout<<"window active, first loop"<<std::endl;\r
- first_loop_after_window_activation = false;\r
- }\r
- else{\r
- s32 dx = g_input->getMousePos().X - displaycenter.X;\r
- s32 dy = g_input->getMousePos().Y - displaycenter.Y;\r
- //std::cout<<"window active, pos difference "<<dx<<","<<dy<<std::endl;\r
- camera_yaw -= dx*0.2;\r
- camera_pitch += dy*0.2;\r
- if(camera_pitch < -89.5) camera_pitch = -89.5;\r
- if(camera_pitch > 89.5) camera_pitch = 89.5;\r
- }\r
- g_input->setMousePos(displaycenter.X, displaycenter.Y);\r
- }\r
- else{\r
- device->getCursorControl()->setVisible(true);\r
-\r
- //std::cout<<"window inactive"<<std::endl;\r
- first_loop_after_window_activation = true;\r
- }\r
-\r
- camera_yaw = wrapDegrees(camera_yaw);\r
- camera_pitch = wrapDegrees(camera_pitch);\r
- \r
- v3f camera_direction = v3f(0,0,1);\r
- camera_direction.rotateYZBy(camera_pitch);\r
- camera_direction.rotateXZBy(camera_yaw);\r
- \r
- // This is at the height of the eyes of the current figure\r
- //v3f camera_position = player_position + v3f(0, BS+BS/2, 0);\r
- // This is more like in minecraft\r
- v3f camera_position = player_position + v3f(0, BS+BS*0.625, 0);\r
-\r
- camera->setPosition(camera_position);\r
- // *100.0 helps in large map coordinates\r
- camera->setTarget(camera_position + camera_direction * 100.0);\r
-\r
- if(FIELD_OF_VIEW_TEST){\r
- //client.m_env.getMap().updateCamera(v3f(0,0,0), v3f(0,0,1));\r
- client.updateCamera(v3f(0,0,0), v3f(0,0,1));\r
- }\r
- else{\r
- //client.m_env.getMap().updateCamera(camera_position, camera_direction);\r
- //TimeTaker timer("client.updateCamera");\r
- client.updateCamera(camera_position, camera_direction);\r
- }\r
- \r
- //timer2.stop();\r
- //TimeTaker //timer3("//timer3");\r
-\r
- /*\r
- Calculate what block is the crosshair pointing to\r
- */\r
- \r
- //u32 t1 = device->getTimer()->getRealTime();\r
- \r
- //f32 d = 4; // max. distance\r
- f32 d = 4; // max. distance\r
- core::line3d<f32> shootline(camera_position,\r
- camera_position + camera_direction * BS * (d+1));\r
-\r
- MapBlockObject *selected_object = client.getSelectedObject\r
- (d*BS, camera_position, shootline);\r
-\r
- /*\r
- If it's pointing to a MapBlockObject\r
- */\r
-\r
- if(selected_object != NULL)\r
- {\r
- //dstream<<"Client returned selected_object != NULL"<<std::endl;\r
-\r
- core::aabbox3d<f32> box_on_map\r
- = selected_object->getSelectionBoxOnMap();\r
-\r
- hilightboxes.push_back(box_on_map);\r
-\r
- infotext = narrow_to_wide(selected_object->infoText());\r
-\r
- if(g_input->getLeftClicked())\r
- {\r
- std::cout<<DTIME<<"Left-clicked object"<<std::endl;\r
- client.clickObject(0, selected_object->getBlock()->getPos(),\r
- selected_object->getId(), g_selected_item);\r
- }\r
- else if(g_input->getRightClicked())\r
- {\r
- std::cout<<DTIME<<"Right-clicked object"<<std::endl;\r
- /*\r
- Check if we want to modify the object ourselves\r
- */\r
- if(selected_object->getTypeId() == MAPBLOCKOBJECT_TYPE_SIGN)\r
- {\r
- dstream<<"Sign object right-clicked"<<std::endl;\r
- \r
- if(random_input == false)\r
- {\r
- // Get a new text for it\r
-\r
- TextDest *dest = new TextDestSign(\r
- selected_object->getBlock()->getPos(),\r
- selected_object->getId(),\r
- &client);\r
-\r
- SignObject *sign_object = (SignObject*)selected_object;\r
-\r
- std::wstring wtext =\r
- narrow_to_wide(sign_object->getText());\r
-\r
- (new GUITextInputMenu(guienv, guiroot, -1,\r
- &g_menumgr, dest,\r
- wtext))->drop();\r
- }\r
- }\r
- /*\r
- Otherwise pass the event to the server as-is\r
- */\r
- else\r
- {\r
- client.clickObject(1, selected_object->getBlock()->getPos(),\r
- selected_object->getId(), g_selected_item);\r
- }\r
- }\r
- }\r
- else // selected_object == NULL\r
- {\r
-\r
- /*\r
- Find out which node we are pointing at\r
- */\r
- \r
- bool nodefound = false;\r
- v3s16 nodepos;\r
- v3s16 neighbourpos;\r
- core::aabbox3d<f32> nodehilightbox;\r
- f32 mindistance = BS * 1001;\r
- \r
- v3s16 pos_i = floatToInt(player_position);\r
-\r
- /*std::cout<<"pos_i=("<<pos_i.X<<","<<pos_i.Y<<","<<pos_i.Z<<")"\r
- <<std::endl;*/\r
-\r
- s16 a = d;\r
- s16 ystart = pos_i.Y + 0 - (camera_direction.Y<0 ? a : 1);\r
- s16 zstart = pos_i.Z - (camera_direction.Z<0 ? a : 1);\r
- s16 xstart = pos_i.X - (camera_direction.X<0 ? a : 1);\r
- s16 yend = pos_i.Y + 1 + (camera_direction.Y>0 ? a : 1);\r
- s16 zend = pos_i.Z + (camera_direction.Z>0 ? a : 1);\r
- s16 xend = pos_i.X + (camera_direction.X>0 ? a : 1);\r
- \r
- for(s16 y = ystart; y <= yend; y++)\r
- for(s16 z = zstart; z <= zend; z++)\r
- for(s16 x = xstart; x <= xend; x++)\r
- {\r
- MapNode n;\r
- try\r
- {\r
- n = client.getNode(v3s16(x,y,z));\r
- if(content_pointable(n.d) == false)\r
- continue;\r
- }\r
- catch(InvalidPositionException &e)\r
- {\r
- continue;\r
- }\r
-\r
- v3s16 np(x,y,z);\r
- v3f npf = intToFloat(np);\r
- \r
- f32 d = 0.01;\r
- \r
- v3s16 dirs[6] = {\r
- v3s16(0,0,1), // back\r
- v3s16(0,1,0), // top\r
- v3s16(1,0,0), // right\r
- v3s16(0,0,-1), // front\r
- v3s16(0,-1,0), // bottom\r
- v3s16(-1,0,0), // left\r
- };\r
- \r
- /*\r
- Meta-objects\r
- */\r
- if(n.d == CONTENT_TORCH)\r
- {\r
- v3s16 dir = unpackDir(n.dir);\r
- v3f dir_f = v3f(dir.X, dir.Y, dir.Z);\r
- dir_f *= BS/2 - BS/6 - BS/20;\r
- v3f cpf = npf + dir_f;\r
- f32 distance = (cpf - camera_position).getLength();\r
-\r
- core::aabbox3d<f32> box;\r
- \r
- // bottom\r
- if(dir == v3s16(0,-1,0))\r
- {\r
- box = core::aabbox3d<f32>(\r
- npf - v3f(BS/6, BS/2, BS/6),\r
- npf + v3f(BS/6, -BS/2+BS/3*2, BS/6)\r
- );\r
- }\r
- // top\r
- else if(dir == v3s16(0,1,0))\r
- {\r
- box = core::aabbox3d<f32>(\r
- npf - v3f(BS/6, -BS/2+BS/3*2, BS/6),\r
- npf + v3f(BS/6, BS/2, BS/6)\r
- );\r
- }\r
- // side\r
- else\r
- {\r
- box = core::aabbox3d<f32>(\r
- cpf - v3f(BS/6, BS/3, BS/6),\r
- cpf + v3f(BS/6, BS/3, BS/6)\r
- );\r
- }\r
-\r
- if(distance < mindistance)\r
- {\r
- if(box.intersectsWithLine(shootline))\r
- {\r
- nodefound = true;\r
- nodepos = np;\r
- neighbourpos = np;\r
- mindistance = distance;\r
- nodehilightbox = box;\r
- }\r
- }\r
- }\r
- /*\r
- Regular blocks\r
- */\r
- else\r
- {\r
- for(u16 i=0; i<6; i++)\r
- {\r
- v3f dir_f = v3f(dirs[i].X,\r
- dirs[i].Y, dirs[i].Z);\r
- v3f centerpoint = npf + dir_f * BS/2;\r
- f32 distance =\r
- (centerpoint - camera_position).getLength();\r
- \r
- if(distance < mindistance)\r
- {\r
- core::CMatrix4<f32> m;\r
- m.buildRotateFromTo(v3f(0,0,1), dir_f);\r
-\r
- // This is the back face\r
- v3f corners[2] = {\r
- v3f(BS/2, BS/2, BS/2),\r
- v3f(-BS/2, -BS/2, BS/2+d)\r
- };\r
- \r
- for(u16 j=0; j<2; j++)\r
- {\r
- m.rotateVect(corners[j]);\r
- corners[j] += npf;\r
- }\r
-\r
- core::aabbox3d<f32> facebox(corners[0]);\r
- facebox.addInternalPoint(corners[1]);\r
-\r
- if(facebox.intersectsWithLine(shootline))\r
- {\r
- nodefound = true;\r
- nodepos = np;\r
- neighbourpos = np + dirs[i];\r
- mindistance = distance;\r
-\r
- //nodehilightbox = facebox;\r
-\r
- const float d = 0.502;\r
- core::aabbox3d<f32> nodebox\r
- (-BS*d, -BS*d, -BS*d, BS*d, BS*d, BS*d);\r
- v3f nodepos_f = intToFloat(nodepos);\r
- nodebox.MinEdge += nodepos_f;\r
- nodebox.MaxEdge += nodepos_f;\r
- nodehilightbox = nodebox;\r
- }\r
- } // if distance < mindistance\r
- } // for dirs\r
- } // regular block\r
- } // for coords\r
-\r
- static float nodig_delay_counter = 0.0;\r
-\r
- if(nodefound)\r
- {\r
- static v3s16 nodepos_old(-32768,-32768,-32768);\r
-\r
- static float dig_time = 0.0;\r
- static u16 dig_index = 0;\r
- \r
- // Visualize selection\r
-\r
- hilightboxes.push_back(nodehilightbox);\r
-\r
- // Handle digging\r
- \r
- if(g_input->getLeftReleased())\r
- {\r
- client.clearTempMod(nodepos);\r
- dig_time = 0.0;\r
- }\r
- \r
- if(nodig_delay_counter > 0.0)\r
- {\r
- nodig_delay_counter -= dtime;\r
- }\r
- else\r
- {\r
- if(nodepos != nodepos_old)\r
- {\r
- std::cout<<DTIME<<"Pointing at ("<<nodepos.X<<","\r
- <<nodepos.Y<<","<<nodepos.Z<<")"<<std::endl;\r
-\r
- if(nodepos_old != v3s16(-32768,-32768,-32768))\r
- {\r
- client.clearTempMod(nodepos_old);\r
- dig_time = 0.0;\r
- }\r
- }\r
-\r
- if(g_input->getLeftClicked() ||\r
- (g_input->getLeftState() && nodepos != nodepos_old))\r
- {\r
- dstream<<DTIME<<"Started digging"<<std::endl;\r
- client.groundAction(0, nodepos, neighbourpos, g_selected_item);\r
- }\r
- if(g_input->getLeftClicked())\r
- {\r
- client.setTempMod(nodepos, NodeMod(NODEMOD_CRACK, 0));\r
- }\r
- if(g_input->getLeftState())\r
- {\r
- MapNode n = client.getNode(nodepos);\r
- \r
- // Get tool name. Default is "" = bare hands\r
- std::string toolname = "";\r
- InventoryList *mlist = local_inventory.getList("main");\r
- if(mlist != NULL)\r
- {\r
- InventoryItem *item = mlist->getItem(g_selected_item);\r
- if(item && (std::string)item->getName() == "ToolItem")\r
- {\r
- ToolItem *titem = (ToolItem*)item;\r
- toolname = titem->getToolName();\r
- }\r
- }\r
-\r
- // Get digging properties for material and tool\r
- u8 material = n.d;\r
- DiggingProperties prop =\r
- getDiggingProperties(material, toolname);\r
- \r
- float dig_time_complete = 0.0;\r
-\r
- if(prop.diggable == false)\r
- {\r
- /*dstream<<"Material "<<(int)material\r
- <<" not diggable with \""\r
- <<toolname<<"\""<<std::endl;*/\r
- // I guess nobody will wait for this long\r
- dig_time_complete = 10000000.0;\r
- }\r
- else\r
- {\r
- dig_time_complete = prop.time;\r
- }\r
- \r
- if(dig_time_complete >= 0.001)\r
- {\r
- dig_index = (u16)((float)CRACK_ANIMATION_LENGTH\r
- * dig_time/dig_time_complete);\r
- }\r
- // This is for torches\r
- else\r
- {\r
- dig_index = CRACK_ANIMATION_LENGTH;\r
- }\r
-\r
- if(dig_index < CRACK_ANIMATION_LENGTH)\r
- {\r
- //TimeTaker timer("client.setTempMod");\r
- //dstream<<"dig_index="<<dig_index<<std::endl;\r
- client.setTempMod(nodepos, NodeMod(NODEMOD_CRACK, dig_index));\r
- }\r
- else\r
- {\r
- dstream<<DTIME<<"Digging completed"<<std::endl;\r
- client.groundAction(3, nodepos, neighbourpos, g_selected_item);\r
- client.clearTempMod(nodepos);\r
- client.removeNode(nodepos);\r
-\r
- dig_time = 0;\r
-\r
- nodig_delay_counter = dig_time_complete\r
- / (float)CRACK_ANIMATION_LENGTH;\r
-\r
- // We don't want a corresponding delay to\r
- // very time consuming nodes\r
- if(nodig_delay_counter > 0.5)\r
- {\r
- nodig_delay_counter = 0.5;\r
- }\r
- // We want a slight delay to very little\r
- // time consuming nodes\r
- float mindelay = 0.15;\r
- if(nodig_delay_counter < mindelay)\r
- {\r
- nodig_delay_counter = mindelay;\r
- }\r
- }\r
-\r
- dig_time += dtime;\r
- }\r
- }\r
- \r
- if(g_input->getRightClicked())\r
- {\r
- std::cout<<DTIME<<"Ground right-clicked"<<std::endl;\r
- client.groundAction(1, nodepos, neighbourpos, g_selected_item);\r
- }\r
- \r
- nodepos_old = nodepos;\r
- }\r
- else{\r
- }\r
-\r
- } // selected_object == NULL\r
- \r
- g_input->resetLeftClicked();\r
- g_input->resetRightClicked();\r
- \r
- if(g_input->getLeftReleased())\r
- {\r
- std::cout<<DTIME<<"Left button released (stopped digging)"\r
- <<std::endl;\r
- client.groundAction(2, v3s16(0,0,0), v3s16(0,0,0), 0);\r
- }\r
- if(g_input->getRightReleased())\r
- {\r
- //std::cout<<DTIME<<"Right released"<<std::endl;\r
- // Nothing here\r
- }\r
- \r
- g_input->resetLeftReleased();\r
- g_input->resetRightReleased();\r
- \r
- /*\r
- Calculate stuff for drawing\r
- */\r
-\r
- camera->setAspectRatio((f32)screensize.X / (f32)screensize.Y);\r
- \r
- u32 daynight_ratio = client.getDayNightRatio();\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
-\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
- \r
- if(g_settings.getBool("enable_fog") == true)\r
- {\r
- //f32 range = draw_control.wanted_range * BS + MAP_BLOCKSIZE/2*BS;\r
- f32 range = draw_control.wanted_range * BS + MAP_BLOCKSIZE/3*BS;\r
- if(draw_control.range_all)\r
- range = 100000*BS;\r
-\r
- driver->setFog(\r
- bgcolor,\r
- video::EFT_FOG_LINEAR,\r
- range*0.6,\r
- range*1.1,\r
- 0.01,\r
- false, // pixel fog\r
- false // range fog\r
- );\r
- }\r
-\r
-\r
- /*\r
- Update gui stuff (0ms)\r
- */\r
-\r
- //TimeTaker guiupdatetimer("Gui updating");\r
- \r
- {\r
- static float drawtime_avg = 0;\r
- drawtime_avg = drawtime_avg * 0.95 + (float)drawtime*0.05;\r
- static float beginscenetime_avg = 0;\r
- beginscenetime_avg = beginscenetime_avg * 0.95 + (float)beginscenetime*0.05;\r
- static float scenetime_avg = 0;\r
- scenetime_avg = scenetime_avg * 0.95 + (float)scenetime*0.05;\r
- static float endscenetime_avg = 0;\r
- endscenetime_avg = endscenetime_avg * 0.95 + (float)endscenetime*0.05;\r
- \r
- char temptext[300];\r
- snprintf(temptext, 300, "Minetest-c55 ("\r
- "F: item=%i"\r
- ", R: range_all=%i"\r
- ")"\r
- " drawtime=%.0f, beginscenetime=%.0f"\r
- ", scenetime=%.0f, endscenetime=%.0f",\r
- g_selected_item,\r
- draw_control.range_all,\r
- drawtime_avg,\r
- beginscenetime_avg,\r
- scenetime_avg,\r
- endscenetime_avg\r
- );\r
- \r
- guitext->setText(narrow_to_wide(temptext).c_str());\r
- }\r
- \r
- {\r
- char temptext[300];\r
- snprintf(temptext, 300,\r
- "(% .1f, % .1f, % .1f)"\r
- " (% .3f < btime_jitter < % .3f"\r
- ", dtime_jitter = % .1f %%"\r
- ", 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
- draw_control.wanted_range\r
- );\r
-\r
- guitext2->setText(narrow_to_wide(temptext).c_str());\r
- }\r
- \r
- {\r
- guitext_info->setText(infotext.c_str());\r
- }\r
- \r
- /*\r
- Get chat messages from client\r
- */\r
- {\r
- // Get new messages\r
- std::wstring message;\r
- while(client.getChatMessage(message))\r
- {\r
- chat_lines.push_back(ChatLine(message));\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
- // 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
- /*\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
- }\r
- whole += (*i).text + L'\n';\r
- }\r
- for(u16 i=0; i<to_be_removed_count; i++)\r
- {\r
- core::list<ChatLine>::Iterator\r
- it = chat_lines.begin();\r
- chat_lines.erase(it);\r
- }\r
- guitext_chat->setText(whole.c_str());\r
- // Update gui element size and position\r
- core::rect<s32> rect(\r
- 10,\r
- screensize.Y - 10 - text_height*chat_lines.size(),\r
- screensize.X - 10,\r
- screensize.Y - 10\r
- );\r
- guitext_chat->setRelativePosition(rect);\r
-\r
- if(chat_lines.size() == 0)\r
- guitext_chat->setVisible(false);\r
- else\r
- guitext_chat->setVisible(true);\r
- }\r
-\r
- /*\r
- Inventory\r
- */\r
- \r
- static u16 old_selected_item = 65535;\r
- if(client.getLocalInventoryUpdated()\r
- || g_selected_item != old_selected_item)\r
- {\r
- old_selected_item = g_selected_item;\r
- //std::cout<<"Updating local inventory"<<std::endl;\r
- client.getLocalInventory(local_inventory);\r
- quick_inventory->setSelection(g_selected_item);\r
- quick_inventory->update();\r
- }\r
- \r
- /*\r
- Send actions returned by the inventory menu\r
- */\r
- while(inventory_action_queue.size() != 0)\r
- {\r
- InventoryAction *a = inventory_action_queue.pop_front();\r
-\r
- client.sendInventoryAction(a);\r
- // Eat it\r
- delete a;\r
- }\r
-\r
- /*\r
- Drawing begins\r
- */\r
-\r
- TimeTaker drawtimer("Drawing");\r
-\r
- \r
- {\r
- TimeTaker timer("beginScene");\r
- driver->beginScene(true, true, bgcolor);\r
- //driver->beginScene(false, true, bgcolor);\r
- beginscenetime = timer.stop(true);\r
- }\r
-\r
- //timer3.stop();\r
- \r
- //std::cout<<DTIME<<"smgr->drawAll()"<<std::endl;\r
- \r
- {\r
- TimeTaker timer("smgr");\r
- smgr->drawAll();\r
- scenetime = timer.stop(true);\r
- }\r
- \r
- {\r
- //TimeTaker timer9("auxiliary drawings");\r
- // 0ms\r
- \r
- //timer9.stop();\r
- //TimeTaker //timer10("//timer10");\r
- \r
- video::SMaterial m;\r
- //m.Thickness = 10;\r
- m.Thickness = 3;\r
- m.Lighting = false;\r
- driver->setMaterial(m);\r
-\r
- driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);\r
-\r
- for(core::list< core::aabbox3d<f32> >::Iterator i=hilightboxes.begin();\r
- i != hilightboxes.end(); i++)\r
- {\r
- /*std::cout<<"hilightbox min="\r
- <<"("<<i->MinEdge.X<<","<<i->MinEdge.Y<<","<<i->MinEdge.Z<<")"\r
- <<" max="\r
- <<"("<<i->MaxEdge.X<<","<<i->MaxEdge.Y<<","<<i->MaxEdge.Z<<")"\r
- <<std::endl;*/\r
- driver->draw3DBox(*i, video::SColor(255,0,0,0));\r
- }\r
-\r
- /*\r
- Draw crosshair\r
- */\r
- driver->draw2DLine(displaycenter - core::vector2d<s32>(10,0),\r
- displaycenter + core::vector2d<s32>(10,0),\r
- video::SColor(255,255,255,255));\r
- driver->draw2DLine(displaycenter - core::vector2d<s32>(0,10),\r
- displaycenter + core::vector2d<s32>(0,10),\r
- video::SColor(255,255,255,255));\r
-\r
- /*\r
- Frametime log\r
- */\r
- if(g_settings.getBool("frametime_graph") == true)\r
- {\r
- s32 x = 10;\r
- for(core::list<float>::Iterator\r
- i = frametime_log.begin();\r
- i != frametime_log.end();\r
- i++)\r
- {\r
- driver->draw2DLine(v2s32(x,50),\r
- v2s32(x,50+(*i)*1000),\r
- video::SColor(255,255,255,255));\r
- x++;\r
- }\r
- }\r
-\r
- } // timer\r
-\r
- //timer10.stop();\r
- //TimeTaker //timer11("//timer11");\r
-\r
- /*\r
- Draw gui\r
- */\r
- // 0-1ms\r
- guienv->drawAll();\r
- \r
- // End drawing\r
- {\r
- TimeTaker timer("endScene");\r
- driver->endScene();\r
- endscenetime = timer.stop(true);\r
- }\r
-\r
- drawtime = drawtimer.stop(true);\r
-\r
- /*\r
- Drawing ends\r
- */\r
- \r
- static s16 lastFPS = 0;\r
- //u16 fps = driver->getFPS();\r
- u16 fps = (1.0/dtime_avg1);\r
-\r
- if (lastFPS != fps)\r
- {\r
- core::stringw str = L"Minetest [";\r
- str += driver->getName();\r
- str += "] FPS:";\r
- str += fps;\r
-\r
- device->setWindowCaption(str.c_str());\r
- lastFPS = fps;\r
- }\r
- \r
- /*}\r
- else\r
- device->yield();*/\r
- }\r
-\r
- delete quick_inventory;\r
-\r
- /*\r
- Disable texture fetches and other stuff that is queued\r
- to be processed by the main loop.\r
-\r
- This has to be done before client goes out of scope.\r
- */\r
- g_irrlicht->Shutdown(true);\r
-\r
- } // client and server are deleted at this point\r
-\r
- } //try\r
- catch(con::PeerNotFoundException &e)\r
- {\r
- dstream<<DTIME<<"Connection timed out."<<std::endl;\r
- error_message = L"Connection timed out.";\r
- }\r
-\r
- } // Menu-game loop\r
- \r
- delete g_input;\r
-\r
- /*\r
- In the end, delete the Irrlicht device.\r
- */\r
- device->drop();\r
- \r
- /*\r
- Update configuration file\r
- */\r
- /*if(configpath != "")\r
- {\r
- g_settings.updateConfigFile(configpath.c_str());\r
- }*/\r
-\r