- // Delay a bit\r
- sleep_ms(100);\r
- }\r
- }\r
- catch(con::PeerNotFoundException &e)\r
- {\r
- std::cout<<DTIME<<"Timed out."<<std::endl;\r
- //return 0;\r
- error_message = L"Connection timed out.";\r
- gui_loadingtext->remove();\r
- continue;\r
- }\r
-\r
- /*\r
- Create skybox\r
- */\r
- /*scene::ISceneNode* skybox;\r
- skybox = smgr->addSkyBoxSceneNode(\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
- */\r
-\r
- scene::ICameraSceneNode* camera = smgr->addCameraSceneNode(\r
- 0, // Camera parent\r
- v3f(BS*100, BS*2, BS*100), // Look from\r
- v3f(BS*100+1, BS*2, BS*100), // Look to\r
- -1 // Camera ID\r
- );\r
-\r
- if(camera == NULL)\r
- return 1;\r
-\r
- //video::SColor skycolor = video::SColor(255,90,140,200);\r
- //video::SColor skycolor = video::SColor(255,166,202,244);\r
- video::SColor skycolor = video::SColor(255,120,185,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
- /*\r
- Lighting test code. Doesn't quite work this way.\r
- The CPU-computed lighting is good.\r
- */\r
-\r
- /*\r
- smgr->addLightSceneNode(NULL,\r
- v3f(0, BS*1000000, 0),\r
- video::SColorf(0.3,0.3,0.3),\r
- BS*10000000);\r
-\r
- smgr->setAmbientLight(video::SColorf(0.0, 0.0, 0.0));\r
-\r
- scene::ILightSceneNode *light = smgr->addLightSceneNode(camera,\r
- v3f(0, 0, 0), video::SColorf(0.5,0.5,0.5), BS*4);\r
- */\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
- /*GUIQuickInventory *quick_inventory = new GUIQuickInventory\r
- (guienv, NULL, v2s32(0, 0), quickinv_itemcount, &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
- //s32 guitext_chat_pad_bottom = 70;\r
-\r
- v2u32 screensize(0,0);\r
- v2u32 last_screensize(0,0);\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() && kill == false)\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
- last_screensize = screensize;\r
- screensize = driver->getScreenSize();\r
- v2s32 displaycenter(screensize.X/2,screensize.Y/2);\r
- //bool screensize_changed = screensize != last_screensize;\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
- // When screen size changes, update positions and sizes of stuff\r
- /*if(screensize_changed)\r
- {\r
- v2s32 pos(displaycenter.X-((quickinv_itemcount-1)*quickinv_spacing+quickinv_size)/2, screensize.Y-quickinv_spacing);\r
- quick_inventory->updatePosition(pos);\r
- }*/\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
- // Necessary for device->getTimer()->getTime()\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
- // Necessary for device->getTimer()->getTime()\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
- Misc. stuff\r
- */\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.updateCamera(v3f(0,0,0), v3f(0,0,1));\r
- }\r
- else{\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, BS);\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, BS);\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
- else if(n.d == CONTENT_SIGN_WALL)\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
- v3f vertices[4] =\r
- {\r
- v3f(BS*0.42,-BS*0.35,-BS*0.4),\r
- v3f(BS*0.49, BS*0.35, BS*0.4),\r
- };\r
-\r
- for(s32 i=0; i<2; i++)\r
- {\r
- if(dir == v3s16(1,0,0))\r
- vertices[i].rotateXZBy(0);\r
- if(dir == v3s16(-1,0,0))\r
- vertices[i].rotateXZBy(180);\r
- if(dir == v3s16(0,0,1))\r
- vertices[i].rotateXZBy(90);\r
- if(dir == v3s16(0,0,-1))\r
- vertices[i].rotateXZBy(-90);\r
- if(dir == v3s16(0,-1,0))\r
- vertices[i].rotateXYBy(-90);\r
- if(dir == v3s16(0,1,0))\r
- vertices[i].rotateXYBy(90);\r
-\r
- vertices[i] += npf;\r
- }\r
-\r
- core::aabbox3d<f32> box;\r
-\r
- box = core::aabbox3d<f32>(vertices[0]);\r
- box.addInternalPoint(vertices[1]);\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