// this test draws lines of different lengths and compares // them with pixel placement // grey pixels denote start and end of the white drawn lines // black pixels only make those grey points better visible // yellow and magenta lines should start and end next toa black pixel, // yellow one right to the last black pixel down, magenta below the last // black pixel to the right // white lines are always double drawn, lines back and forth. static bool drawLine(E_DRIVER_TYPE driverType) { IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32); if (!device) return true; // Treat a failure to create a driver as benign; this saves a lot of #ifdefs IVideoDriver* driver = device->getVideoDriver(); stabilizeScreenBackground(driver); logTestString("Testing driver %ls\n", driver->getName()); device->getSceneManager()->addCameraSceneNode(); driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, SColor(255,100,101,140)); // horizontal lines for (u32 i=0; i<20; ++i) { driver->draw2DLine(core::vector2di(10,10+3*i), core::vector2di(10+2*i,10+3*i)); // mark start point driver->drawPixel(9,10+3*i+1, video::SColor(0xff000000)); driver->drawPixel(10,10+3*i+1, video::SColor(0xff888888)); driver->drawPixel(11,10+3*i+1, video::SColor(0xff000000)); // mark end point driver->drawPixel(9+2*i,10+3*i+1, video::SColor(0xff000000)); driver->drawPixel(10+2*i,10+3*i+1, video::SColor(0xff888888)); driver->drawPixel(11+2*i,10+3*i+1, video::SColor(0xff000000)); driver->draw2DLine(core::vector2di(10+2*i,10+3*i+2), core::vector2di(10,10+3*i+2)); } // vertical lines for (u32 i=0; i<20; ++i) { driver->draw2DLine(core::vector2di(11+3*i,10), core::vector2di(11+3*i,10+2*i)); // mark start point driver->drawPixel(11+3*i+1,9, video::SColor(0xff000000)); driver->drawPixel(11+3*i+1,10, video::SColor(0xff888888)); driver->drawPixel(11+3*i+1,11, video::SColor(0xff000000)); // mark end point driver->drawPixel(11+3*i+1,9+2*i, video::SColor(0xff000000)); driver->drawPixel(11+3*i+1,10+2*i, video::SColor(0xff888888)); driver->drawPixel(11+3*i+1,11+2*i, video::SColor(0xff000000)); driver->draw2DLine(core::vector2di(11+3*i+2,10+2*i), core::vector2di(11+3*i+2, 10)); } // diagonal lines driver->draw2DLine(core::vector2di(14,14),core::vector2di(50,68), video::SColor(0xffffff00)); driver->draw2DLine(core::vector2di(15,14),core::vector2di(69,50), video::SColor(0xffff00ff)); driver->endScene(); bool result = takeScreenshotAndCompareAgainstReference(driver, "-drawLine.png"); device->closeDevice(); device->run(); device->drop(); return result; }
bool Editor::run(IrrlichtDevice* irr_device,Configuration* conf){ // Do Irrlicht Stuff _device = irr_device; IVideoDriver* driver = GetDevice()->getVideoDriver(); ISceneManager* smgr = GetDevice()->getSceneManager(); IGUIEnvironment* guienv = GetDevice()->getGUIEnvironment(); GetDevice()->setEventReceiver(this); if (!conf->getSettingAsBool("fullscreen")) GetDevice()->setResizable(true); // Project and state Project* proj = new Project(); _state = new EditorState(GetDevice(),proj,conf); // Menu State MenuState* ms = new MenuState(GetState()); GetState()->SetMenu(ms); // Add editor modes GetState()->AddMode(new NBEditor(GetState())); // Set up project proj->AddNode(new Node(GetDevice(),GetState())); proj->SelectNode(0); // Load user interface LoadScene(); GetState()->Menu()->init(); GetState()->Mode()->load(); printf("Complete!\n"); int LastX = driver->getScreenSize().Width; if (!GetState()->Settings()->getSettingAsBool("hide_sidebar")) LastX -= 256; int LastY = driver->getScreenSize().Height; int lastFPS = -1; while (GetDevice()->run()){ if (GetState()->NeedsClose()){ GetDevice()->closeDevice(); return true; } driver->beginScene(true, true, irr::video::SColor(255,150,150,150)); int ResX = driver->getScreenSize().Width; if (!GetState()->Settings()->getSettingAsBool("hide_sidebar")) ResX -= 256; int ResY = driver->getScreenSize().Height; if (currentWindow == -1) { // Draw Camera 0 if (camera[0]){ smgr->setActiveCamera(camera[0]); rect<s32> offset = rect<s32>(0,0,ResX/2,ResY/2); driver->setViewPort(offset); smgr->drawAll(); if (GetState()->Mode()) GetState()->Mode()->viewportTick(EVIEW_PERS, driver, offset); } // Draw Camera 1 if (camera[1]){ smgr->setActiveCamera(camera[1]); rect<s32> offset = rect<s32>(ResX/2,0,ResX,ResY/2); driver->setViewPort(offset); smgr->drawAll(); if (GetState()->Mode()) GetState()->Mode()->viewportTick(EVIEW_XZ, driver, offset); } // Draw Camera 2 if (camera[2]){ smgr->setActiveCamera(camera[2]); rect<s32> offset = rect<s32>(0,ResY/2,ResX/2,ResY); driver->setViewPort(offset); smgr->drawAll(); if (GetState()->Mode()) GetState()->Mode()->viewportTick(EVIEW_XY, driver, offset); } // Draw Camera 3 if (camera[3]){ smgr->setActiveCamera(camera[3]); rect<s32> offset = rect<s32>(ResX/2,ResY/2,ResX,ResY); driver->setViewPort(offset); smgr->drawAll(); if (GetState()->Mode()) GetState()->Mode()->viewportTick(EVIEW_ZY, driver, offset); } // Draw GUI driver->setViewPort(rect<s32>(0,0,driver->getScreenSize().Width,driver->getScreenSize().Height)); driver->draw2DLine(vector2d<irr::s32>(0,ResY/2),vector2d<irr::s32>(ResX,ResY/2),SColor(175,255,255,255)); driver->draw2DLine(vector2d<irr::s32>(0,ResY/2-1),vector2d<irr::s32>(ResX,ResY/2-1),SColor(175,255,255,255)); driver->draw2DLine(vector2d<irr::s32>(ResX/2,0),vector2d<irr::s32>(ResX/2,ResY),SColor(175,255,255,255)); driver->draw2DLine(vector2d<irr::s32>(ResX/2+1,0),vector2d<irr::s32>(ResX/2+1,ResY),SColor(175,255,255,255)); }else if (camera[currentWindow]){ smgr->setActiveCamera(camera[currentWindow]); driver->setViewPort(rect<s32>(0,0,ResX,ResY)); smgr->drawAll(); if (GetState()->Mode()) GetState()->Mode()->viewportTick((VIEWPORT)currentWindow, driver, rect<s32>(0,0,ResX,ResY)); driver->setViewPort(rect<s32>(0,0,driver->getScreenSize().Width,driver->getScreenSize().Height)); } if (GetState()->Menu()) GetState()->Menu()->draw(driver); if (GetState()->Mode()) GetState()->Mode()->draw(driver); guienv->drawAll(); driver->endScene(); int fps = driver->getFPS(); if (lastFPS != fps) { irr::core::stringw str = L"Nodebox Editor [FPS: "; str += fps; str += "]"; GetDevice()->setWindowCaption(str.c_str()); lastFPS = fps; } if (LastX != ResX || LastY != ResY){ printf("Adjusting FOV to new screen size...\n"); LastX = ResX; LastY = ResY; camera[0]->setAspectRatio((float)ResX/(float)ResY); // reset matrix matrix4 projMat; irr::f32 orth_w = (float)ResX / (float)ResY; orth_w = 3 * orth_w; projMat.buildProjectionMatrixOrthoLH(orth_w,3,1,100); for (int i=1;i<4;i++){ if (camera[i]){ camera[i]->remove(); camera[i]=NULL; } } // Remake cameras camera[1]=smgr->addCameraSceneNode(target,vector3df(0,2,-0.01),vector3df(0,0,0)); camera[1]->setProjectionMatrix(projMat,true); camera[2]=smgr->addCameraSceneNode(target,vector3df(0,0,-5),vector3df(0,0,0)); camera[2]->setProjectionMatrix(projMat,true); camera[3]=smgr->addCameraSceneNode(target,vector3df(-5,0,0),vector3df(0,0,0)); camera[3]->setProjectionMatrix(projMat,true); } } return true; }
void Editor::viewportTick(Viewport viewport, rect<s32> rect, bool mousehit, bool middlehit) { // Init IVideoDriver *driver = device->getVideoDriver(); ISceneManager *smgr = device->getSceneManager(); IGUIEnvironment *guienv = device->getGUIEnvironment(); ViewportType type = state->getViewportType(viewport); // Draw camera smgr->setActiveCamera(camera[(int)viewport]); driver->setViewPort(rect); if (type == VIEWT_BOTTOM) plane->setVisible(false); smgr->drawAll(); if (type == VIEWT_BOTTOM) plane->setVisible(true); // Callbacks if (state->Mode()) state->Mode()->viewportTick(viewport, driver, rect); if (viewport_drag == viewport) { vector2di delta = state->mouse_position; delta -= viewport_drag_last; viewport_drag_last = state->mouse_position; viewport_offset[(int)viewport].X -= (f32)delta.X * 0.01f; viewport_offset[(int)viewport].Y += (f32)delta.Y * 0.01f; if (viewport_offset[(int)viewport].X > 0.5) viewport_offset[(int)viewport].X = 0.5; if (viewport_offset[(int)viewport].X < -0.5) viewport_offset[(int)viewport].X = -0.5; if (viewport_offset[(int)viewport].Y > 0.5) viewport_offset[(int)viewport].Y = 0.5; if (viewport_offset[(int)viewport].Y < -0.5) viewport_offset[(int)viewport].Y = -0.5; applyCameraOffsets(viewport); } if (middlehit && rect.isPointInside(state->mouse_position) && type != VIEWT_PERS) { viewport_drag = viewport; viewport_drag_last = state->mouse_position; } // Draw text driver->setViewPort(rects32(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height)); { static const wchar_t* labels[7] = {L"Perspective", L"Front", L"Left", L"Top", L"Back", L"Right", L"Bottom"}; // Handle clicking position2d<s32> labelpos(rect.LowerRightCorner.X - 86, rect.UpperLeftCorner.Y + ((rect.UpperLeftCorner.Y < 50)?30:10)); rects32 backgroundrect(rect.LowerRightCorner.X - 96, rect.UpperLeftCorner.Y + ((rect.UpperLeftCorner.Y < 50)?25:5), rect.LowerRightCorner.X - 5, rect.UpperLeftCorner.Y + ((rect.UpperLeftCorner.Y < 50)?185:165)); bool context_is_open = (viewport_contextmenu == viewport); if (mousehit && !state->menu->dialog) { if ((rects32(labelpos.X, labelpos.Y, labelpos.X + 90, labelpos.Y + 25)).isPointInside(state->mouse_position)) { viewport_contextmenu = viewport; } else if (context_is_open) { context_is_open = false; viewport_contextmenu = VIEW_NONE; if (backgroundrect.isPointInside(state->mouse_position)) { int y = 0; for (int i = 0; i < 7; i++) { if (i != (int)type) { int ty = rect.UpperLeftCorner.Y + ((rect.UpperLeftCorner.Y < 50)?56:36) + y * 20; rects32 trect(rect.LowerRightCorner.X - 96, ty, rect.LowerRightCorner.X - 5, ty + 20); y++; if (trect.isPointInside(state->mouse_position)) { viewport_offset[(int)viewport] = vector3df(0, 0, 0); state->settings->set(viewportToSetting(viewport), viewportTypeToSetting((ViewportType)i)); recreateCameras(); break; } } } } } } // Context menu if (context_is_open) { // Context menu background driver->draw2DRectangle(SColor(100, 32, 32, 32), backgroundrect); s32 y2 = rect.UpperLeftCorner.Y + ((rect.UpperLeftCorner.Y < 50)?52:32); driver->draw2DLine(position2d<s32>(rect.LowerRightCorner.X - 96, y2), position2d<s32>(rect.LowerRightCorner.X - 5, y2), SColor(100, 255, 255, 255)); // Draw options guienv->getSkin()->getFont()->draw(labels[(int)type], core::rect<s32>(labelpos.X, labelpos.Y, 200, 50), video::SColor(255, 255, 255, 255)); int y = 0; for (int i = 0; i < 7; i++) { if (i != (int)type) { guienv->getSkin()->getFont()->draw( labels[i], core::rect<s32>(rect.LowerRightCorner.X - 86, rect.UpperLeftCorner.Y + ((rect.UpperLeftCorner.Y < 50)?59:39) + y * 20, 200, 50), video::SColor(255, 255, 255, 255) ); y++; } } } else { // Draw label guienv->getSkin()->getFont()->draw(labels[(int)type], core::rect<s32>(rect.LowerRightCorner.X - wcslen(labels[(int)type]) * 6 - 20, labelpos.Y, 200, 50), video::SColor(255, 255, 255, 255)); } } // Draw coordinate arrows if (type != VIEWT_PERS) { switch(type) { case VIEWT_TOP: drawCoord(guienv->getSkin()->getFont(), driver, rect.UpperLeftCorner.X + 10, rect.LowerRightCorner.Y - 42, L"X", L"Z"); break; case VIEWT_BOTTOM: drawCoord(guienv->getSkin()->getFont(), driver, rect.UpperLeftCorner.X + 10, rect.LowerRightCorner.Y - 42, L"X", L"-Z"); break; case VIEWT_LEFT: drawCoord(guienv->getSkin()->getFont(), driver, rect.UpperLeftCorner.X + 10, rect.LowerRightCorner.Y - 42, L"-Z", L"Y"); break; case VIEWT_RIGHT: drawCoord(guienv->getSkin()->getFont(), driver, rect.UpperLeftCorner.X + 10, rect.LowerRightCorner.Y - 42, L"Z", L"Y"); break; case VIEWT_FRONT: drawCoord(guienv->getSkin()->getFont(), driver, rect.UpperLeftCorner.X + 10, rect.LowerRightCorner.Y - 42, L"X", L"Y"); break; case VIEWT_BACK: drawCoord(guienv->getSkin()->getFont(), driver, rect.UpperLeftCorner.X + 10, rect.LowerRightCorner.Y - 42, L"-X", L"Y"); break; } } }
bool Editor::run(IrrlichtDevice* irr_device, Configuration* conf, bool editor_is_installed) { // Do Irrlicht Stuff device = irr_device; IVideoDriver *driver = device->getVideoDriver(); ISceneManager *smgr = device->getSceneManager(); IGUIEnvironment *guienv = device->getGUIEnvironment(); device->setEventReceiver(this); device->setWindowCaption(L"Node Box Editor"); if (!conf->getBool("fullscreen")) { device->setResizable(true); } // Project and state Project *proj = new Project(); state = new EditorState(device, proj, conf); state->isInstalled = editor_is_installed; // Menu State state->menu = new MenuState(state); // Add editor modes state->AddMode(new NBEditor(state)); state->AddMode(new NodeEditor(state)); state->AddMode(new TextureEditor(state)); // Set up project proj->AddNode(state, true, false); proj->media.debug(); // Load user interface LoadScene(); state->SelectMode(0); int LastX = driver->getScreenSize().Width; if (!state->settings->getBool("hide_sidebar")) { LastX -= 256; } int LastY = driver->getScreenSize().Height; #ifdef _DEBUG int lastFPS = -1; #endif bool dosleep = state->settings->getBool("use_sleep"); u32 last = std::clock(); double dtime = 0; while (device->run()) { if (state->NeedsClose()) { device->closeDevice(); return true; } driver->beginScene(true, true, irr::video::SColor(255, 150, 150, 150)); int ResX = driver->getScreenSize().Width; if (!state->settings->getBool("hide_sidebar")) ResX -= 256; int ResY = driver->getScreenSize().Height; if (currentWindow == -1) { bool newmoused = (state->mousedown && !click_handled); viewportTick(VIEW_TL, rect<s32>(0, 0, ResX/2, ResY/2), newmoused, !middle_click_handled); viewportTick(VIEW_TR, rect<s32>(ResX/2, 0, ResX, ResY/2), newmoused, !middle_click_handled); viewportTick(VIEW_BL, rect<s32>(0, ResY/2, ResX/2, ResY ), newmoused, !middle_click_handled); viewportTick(VIEW_BR, rect<s32>(ResX/2, ResY/2, ResX, ResY ), newmoused, !middle_click_handled); // Draw separating lines driver->setViewPort(rect<s32>(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height)); driver->draw2DLine(vector2d<irr::s32>(0, ResY/2), vector2d<irr::s32>(ResX, ResY/2), SColor(175,255,255,255)); driver->draw2DLine(vector2d<irr::s32>(0, ResY/2-1), vector2d<irr::s32>(ResX, ResY/2-1), SColor(175,255,255,255)); driver->draw2DLine(vector2d<irr::s32>(ResX/2, 0), vector2d<irr::s32>(ResX/2, ResY), SColor(175,255,255,255)); driver->draw2DLine(vector2d<irr::s32>(ResX/2+1, 0), vector2d<irr::s32>(ResX/2+1, ResY), SColor(175,255,255,255)); } else if (camera[currentWindow]) { viewportTick((Viewport)currentWindow, rect<s32>(0, 0, ResX, ResY), (state->mousedown && !click_handled), !middle_click_handled); } if (state->menu) { state->menu->draw(driver); } if (state->Mode()) { state->Mode()->draw(driver); } if (state->project && state->project->GetCurrentNode()) { vector3df pos = vector3df( (f32)state->project->GetCurrentNode()->position.X, (f32)state->project->GetCurrentNode()->position.Y, (f32)state->project->GetCurrentNode()->position.Z ); target->setPosition(pos); } guienv->drawAll(); if (state->menu->dialog) state->menu->dialog->draw(driver); driver->endScene(); #ifdef _DEBUG int fps = driver->getFPS(); if (lastFPS != fps) { irr::core::stringw str = L"Node Box Editor [FPS: "; str += fps; str += "]"; device->setWindowCaption(str.c_str()); lastFPS = fps; } #endif if (LastX != ResX || LastY != ResY) { LastX = ResX; LastY = ResY; recreateCameras(); } // Update if (state->Mode()) { state->Mode()->update(dtime); } // Do sleep unsigned int now = std::clock(); if (dosleep) { u32 sleeptime = int(double(1000) / double(60)) - (now - last); if (sleeptime > 0 && sleeptime < 200) device->sleep(sleeptime); } dtime = double(now - last) / 1000; last = now; click_handled = true; middle_click_handled = true; } return true; }
bool Editor::run(IrrlichtDevice* irr_device,Configuration* conf) { // Do Irrlicht Stuff device = irr_device; IVideoDriver *driver = device->getVideoDriver(); ISceneManager *smgr = device->getSceneManager(); IGUIEnvironment *guienv = device->getGUIEnvironment(); device->setEventReceiver(this); device->setWindowCaption(L"Node Box Editor"); if (!conf->getBool("fullscreen")) { device->setResizable(true); } // Project and state Project *proj = new Project(); state = new EditorState(device, proj, conf); // Menu State state->menu = new MenuState(state); // Add editor modes state->AddMode(new NBEditor(state)); state->AddMode(new NodeEditor(state)); // Set up project proj->AddNode(state, true, false); // Load user interface LoadScene(); state->SelectMode(0); int LastX = driver->getScreenSize().Width; if (!state->settings->getBool("hide_sidebar")) { LastX -= 256; } int LastY = driver->getScreenSize().Height; #ifdef _DEBUG int lastFPS = -1; #endif bool dosleep = state->settings->getBool("use_sleep"); u32 last = std::clock(); double dtime = 0; while (device->run()) { if (state->NeedsClose()) { device->closeDevice(); return true; } driver->beginScene(true, true, irr::video::SColor(255, 150, 150, 150)); int ResX = driver->getScreenSize().Width; if (!state->settings->getBool("hide_sidebar")) ResX -= 256; int ResY = driver->getScreenSize().Height; if (currentWindow == -1) { // Draw Camera 0 if (camera[0]) { smgr->setActiveCamera(camera[0]); rect<s32> offset = rect<s32>(0, 0, ResX/2, ResY/2); driver->setViewPort(offset); smgr->drawAll(); if (state->Mode()) state->Mode()->viewportTick(VIEW_PERS, driver, offset); } // Draw Camera 1 if (camera[1]) { smgr->setActiveCamera(camera[1]); rect<s32> offset = rect<s32>(ResX/2, 0, ResX, ResY/2); driver->setViewPort(offset); smgr->drawAll(); if (state->Mode()) state->Mode()->viewportTick(VIEW_XZ, driver, offset); } // Draw Camera 2 if (camera[2]) { smgr->setActiveCamera(camera[2]); rect<s32> offset = rect<s32>(0, ResY/2, ResX/2, ResY); driver->setViewPort(offset); smgr->drawAll(); if (state->Mode()) state->Mode()->viewportTick(VIEW_XY, driver, offset); } // Draw Camera 3 if (camera[3]) { smgr->setActiveCamera(camera[3]); rect<s32> offset = rect<s32>(ResX/2, ResY/2, ResX, ResY); driver->setViewPort(offset); smgr->drawAll(); if (state->Mode()) state->Mode()->viewportTick(VIEW_ZY, driver, offset); } // Draw GUI driver->setViewPort(rect<s32>(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height)); driver->draw2DLine(vector2d<irr::s32>(0, ResY/2), vector2d<irr::s32>(ResX, ResY/2), SColor(175,255,255,255)); driver->draw2DLine(vector2d<irr::s32>(0, ResY/2-1), vector2d<irr::s32>(ResX, ResY/2-1), SColor(175,255,255,255)); driver->draw2DLine(vector2d<irr::s32>(ResX/2, 0), vector2d<irr::s32>(ResX/2, ResY), SColor(175,255,255,255)); driver->draw2DLine(vector2d<irr::s32>(ResX/2+1, 0), vector2d<irr::s32>(ResX/2+1, ResY), SColor(175,255,255,255)); } else if (camera[currentWindow]) { smgr->setActiveCamera(camera[currentWindow]); driver->setViewPort(rect<s32>(0, 0, ResX, ResY)); smgr->drawAll(); if (state->Mode()) { state->Mode()->viewportTick((Viewport) currentWindow, driver, rect<s32>(0, 0, ResX, ResY)); } driver->setViewPort(rect<s32>(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height)); } if (state->menu) { state->menu->draw(driver); } if (state->Mode()) { state->Mode()->draw(driver); } if (state->project && state->project->GetCurrentNode()) { vector3df pos = vector3df( state->project->GetCurrentNode()->position.X, state->project->GetCurrentNode()->position.Y, state->project->GetCurrentNode()->position.Z ); target->setPosition(pos); camera[0]->setTarget(pos); camera[1]->setTarget(pos); camera[2]->setTarget(pos); camera[3]->setTarget(pos); } guienv->drawAll(); driver->endScene(); #ifdef _DEBUG int fps = driver->getFPS(); if (lastFPS != fps) { irr::core::stringw str = L"Node Box Editor [FPS: "; str += fps; str += "]"; device->setWindowCaption(str.c_str()); lastFPS = fps; } #endif if (LastX != ResX || LastY != ResY) { LastX = ResX; LastY = ResY; camera[0]->setAspectRatio((float)ResX / (float)ResY); // reset matrix matrix4 projMat; irr::f32 orth_w = (float)ResX / (float)ResY; orth_w = 3 * orth_w; projMat.buildProjectionMatrixOrthoLH(orth_w,3,1,100); for (int i = 1; i < 4; i++) { if (camera[i]) { camera[i]->remove(); camera[i] = NULL; } } // Remake cameras camera[1] = smgr->addCameraSceneNode(target, vector3df(0, 2, -0.01), vector3df(0, 0, 0)); camera[1]->setProjectionMatrix(projMat, true); camera[2] = smgr->addCameraSceneNode(target, vector3df(0, 0, -5), vector3df(0, 0, 0)); camera[2]->setProjectionMatrix(projMat, true); camera[3] = smgr->addCameraSceneNode(target, vector3df(-5, 0, 0), vector3df(0, 0, 0)); camera[3]->setProjectionMatrix(projMat, true); } // Update if (state->Mode()) { state->Mode()->update(dtime); } // Do sleep unsigned int now = std::clock(); if (dosleep) { u32 sleeptime = int(double(1000) / double(65)) - (now - last); if (sleeptime > 0 && sleeptime < 200) device->sleep(sleeptime); } dtime = double(now - last) / 1000; last = now; } return true; }