void Update() { const float TRANS_SPEED = 6.0f; // units / sec GetSystemUtils()->GetCurrentTimeStamp(CURR_TIME); float timeDiff = GetSystemUtils()->TimeStampDiff(PREV_TIME, CURR_TIME, STU_SEC); GetSystemUtils()->CopyTimeStamp(PREV_TIME, CURR_TIME); CUBE_ORBIT += timeDiff * (Math::PI / 4.0f); Math::Vector incTrans; if (KEYMAP[K_Forward]) incTrans.z = +TRANS_SPEED * timeDiff; if (KEYMAP[K_Back]) incTrans.z = -TRANS_SPEED * timeDiff; if (KEYMAP[K_Right]) incTrans.x = +TRANS_SPEED * timeDiff; if (KEYMAP[K_Left]) incTrans.x = -TRANS_SPEED * timeDiff; if (KEYMAP[K_Up]) incTrans.y = +TRANS_SPEED * timeDiff; if (KEYMAP[K_Down]) incTrans.y = -TRANS_SPEED * timeDiff; Math::Point rotTrans = Math::RotatePoint(-ROTATION.y, Math::Point(incTrans.x, incTrans.z)); incTrans.x = rotTrans.x; incTrans.z = rotTrans.y; TRANSLATION += incTrans; }
void Update() { const float ROT_SPEED = 80.0f * Math::DEG_TO_RAD; // rad / sec const float TRANS_SPEED = 3.0f; // units / sec GetSystemUtils()->GetCurrentTimeStamp(CURR_TIME); float timeDiff = GetSystemUtils()->TimeStampDiff(PREV_TIME, CURR_TIME, STU_SEC); GetSystemUtils()->CopyTimeStamp(PREV_TIME, CURR_TIME); if (KEYMAP[K_RotYLeft]) ROTATION.y -= ROT_SPEED * timeDiff; if (KEYMAP[K_RotYRight]) ROTATION.y += ROT_SPEED * timeDiff; if (KEYMAP[K_RotXDown]) ROTATION.x -= ROT_SPEED * timeDiff; if (KEYMAP[K_RotXUp]) ROTATION.x += ROT_SPEED * timeDiff; if (KEYMAP[K_Forward]) TRANSLATION.z -= TRANS_SPEED * timeDiff; if (KEYMAP[K_Back]) TRANSLATION.z += TRANS_SPEED * timeDiff; if (KEYMAP[K_Left]) TRANSLATION.x += TRANS_SPEED * timeDiff; if (KEYMAP[K_Right]) TRANSLATION.x -= TRANS_SPEED * timeDiff; if (KEYMAP[K_Up]) TRANSLATION.y += TRANS_SPEED * timeDiff; if (KEYMAP[K_Down]) TRANSLATION.y -= TRANS_SPEED * timeDiff; }
CSoundInterface* CApplication::GetSound() { return m_sound; for (int i = 0; i < PCNT_MAX; ++i) { GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][0]); GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][1]); } }
void CApplication::ResumeSimulation() { m_simulationSuspended = false; GetSystemUtils()->GetCurrentTimeStamp(m_baseTimeStamp); GetSystemUtils()->CopyTimeStamp(m_curTimeStamp, m_baseTimeStamp); m_realAbsTimeBase = m_realAbsTime; m_absTimeBase = m_exactAbsTime; GetLogger()->Info("Resume simulation\n"); }
bool CApplication::ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig) { static bool restore = false; m_lastDeviceConfig = m_deviceConfig; m_deviceConfig = newConfig; SDL_FreeSurface(m_private->surface); if (! CreateVideoSurface()) { // Fatal error, so post the quit event m_eventQueue->AddEvent(Event(EVENT_QUIT)); return false; } if (m_private->surface == nullptr) { if (! restore) { std::string error = std::string("SDL error while setting video mode:\n") + std::string(SDL_GetError()) + std::string("\n") + std::string("Previous mode will be restored"); GetLogger()->Error(error.c_str()); GetSystemUtils()->SystemDialog( SDT_ERROR, "COLOBT - Error", error); restore = true; ChangeVideoConfig(m_lastDeviceConfig); return false; } else { restore = false; std::string error = std::string("SDL error while restoring previous video mode:\n") + std::string(SDL_GetError()); GetLogger()->Error(error.c_str()); GetSystemUtils()->SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", error); // Fatal error, so post the quit event m_eventQueue->AddEvent(Event(EVENT_QUIT)); return false; } } ( static_cast<Gfx::CGLDevice*>(m_device) )->ConfigChanged(m_deviceConfig); m_engine->ResetAfterDeviceChanged(); return true; }
void CApplication::UpdatePerformanceCountersData() { long long sum = GetSystemUtils()->TimeStampExactDiff(m_performanceCounters[PCNT_ALL][0], m_performanceCounters[PCNT_ALL][1]); for (int i = 0; i < PCNT_MAX; ++i) { long long diff = GetSystemUtils()->TimeStampExactDiff(m_performanceCounters[i][0], m_performanceCounters[i][1]); m_performanceCountersData[static_cast<PerformanceCounter>(i)] = static_cast<float>(diff) / static_cast<float>(sum); } }
void CApplication::SetSimulationSpeed(float speed) { m_simulationSpeed = speed; GetSystemUtils()->GetCurrentTimeStamp(m_baseTimeStamp); m_realAbsTimeBase = m_realAbsTime; m_absTimeBase = m_exactAbsTime; GetLogger()->Info("Simulation speed = %.2f\n", speed); }
Event CApplication::CreateUpdateEvent() { if (m_simulationSuspended) return Event(EVENT_NULL); GetSystemUtils()->CopyTimeStamp(m_lastTimeStamp, m_curTimeStamp); GetSystemUtils()->GetCurrentTimeStamp(m_curTimeStamp); long long absDiff = GetSystemUtils()->TimeStampExactDiff(m_baseTimeStamp, m_curTimeStamp); long long newRealAbsTime = m_realAbsTimeBase + absDiff; long long newRealRelTime = GetSystemUtils()->TimeStampExactDiff(m_lastTimeStamp, m_curTimeStamp); if (newRealAbsTime < m_realAbsTime || newRealRelTime < 0) { GetLogger()->Error("Fatal error: got negative system counter difference!\n"); GetLogger()->Error("This should never happen. Please report this error.\n"); m_eventQueue->AddEvent(Event(EVENT_QUIT)); return Event(EVENT_NULL); } else { m_realAbsTime = newRealAbsTime; // m_baseTimeStamp is updated on simulation speed change, so this is OK m_exactAbsTime = m_absTimeBase + m_simulationSpeed * absDiff; m_absTime = (m_absTimeBase + m_simulationSpeed * absDiff) / 1e9f; m_realRelTime = newRealRelTime; m_exactRelTime = m_simulationSpeed * m_realRelTime; m_relTime = (m_simulationSpeed * m_realRelTime) / 1e9f; } Event frameEvent(EVENT_FRAME); frameEvent.systemEvent = true; frameEvent.trackedKeysState = m_trackedKeys; frameEvent.kmodState = m_kmodState; frameEvent.mousePos = m_mousePos; frameEvent.mouseButtonsState = m_mouseButtonsState; frameEvent.rTime = m_relTime; return frameEvent; }
bool CProfile::InitCurrentDirectory() { try { bp::ini_parser::read_ini(GetSystemUtils()->profileFileLocation(), m_propertyTree); } catch (std::exception & e) { GetLogger()->Info("Error on parsing profile: %s\n", e.what()); return false; } return true; }
CProfile::~CProfile() { if (m_profileNeedSave) { try { bp::ini_parser::write_ini(GetSystemUtils()->profileFileLocation(), m_propertyTree); } catch (std::exception & e) { GetLogger()->Info("Error on storing profile: %s\n", e.what()); } } }
CApplication::~CApplication() { delete m_private; m_private = nullptr; delete m_eventQueue; m_eventQueue = nullptr; delete m_profile; m_profile = nullptr; delete m_iMan; m_iMan = nullptr; GetSystemUtils()->DestroyTimeStamp(m_baseTimeStamp); GetSystemUtils()->DestroyTimeStamp(m_curTimeStamp); GetSystemUtils()->DestroyTimeStamp(m_lastTimeStamp); for (int i = 0; i < PCNT_MAX; ++i) { GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][0]); GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][1]); } }
int SDL_MAIN_FUNC(int argc, char *argv[]) { CLogger logger; CSystemUtils* systemUtils = CSystemUtils::Create(); // platform-specific utils systemUtils->Init(); PREV_TIME = GetSystemUtils()->CreateTimeStamp(); CURR_TIME = GetSystemUtils()->CreateTimeStamp(); GetSystemUtils()->GetCurrentTimeStamp(PREV_TIME); GetSystemUtils()->GetCurrentTimeStamp(CURR_TIME); if (argc != 3) { std::cerr << "Usage: " << argv[0] << " {old|new_txt|new_bin} model_file" << std::endl; return 1; } Gfx::CModelFile *modelFile = new Gfx::CModelFile(); if (std::string(argv[1]) == "old") { if (! modelFile->ReadModel(argv[2])) { std::cerr << "Error reading model file" << std::endl; return 1; } } else if (std::string(argv[1]) == "new_txt") { if (! modelFile->ReadTextModel(argv[2])) { std::cerr << "Error reading model file" << std::endl; return 1; } } else if (std::string(argv[1]) == "new_bin") { if (! modelFile->ReadBinaryModel(argv[2])) { std::cerr << "Error reading model file" << std::endl; return 1; } } else { std::cerr << "Usage: " << argv[0] << "{old|new_txt|new_bin} model_file" << std::endl; return 1; } // Without any error checking, for simplicity SDL_Init(SDL_INIT_VIDEO); IMG_Init(IMG_INIT_PNG); const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); Uint32 videoFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE; if (videoInfo->hw_available) videoFlags |= SDL_HWSURFACE; else videoFlags |= SDL_SWSURFACE; if (videoInfo->blit_hw) videoFlags |= SDL_HWACCEL; SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_Surface *surface = SDL_SetVideoMode(800, 600, 32, videoFlags); SDL_WM_SetCaption("Model Test", "Model Test"); Gfx::CGLDevice *device = new Gfx::CGLDevice(Gfx::GLDeviceConfig()); device->Create(); Init(device, modelFile); bool done = false; while (! done) { Render(device, modelFile); Update(); SDL_GL_SwapBuffers(); SDL_Event event; SDL_PollEvent(&event); if (event.type == SDL_QUIT) done = true; else if (event.type == SDL_KEYDOWN) KeyboardDown(event.key.keysym.sym); else if (event.type == SDL_KEYUP) KeyboardUp(event.key.keysym.sym); usleep(FRAME_DELAY); } delete modelFile; device->Destroy(); delete device; SDL_FreeSurface(surface); IMG_Quit(); SDL_Quit(); GetSystemUtils()->DestroyTimeStamp(PREV_TIME); GetSystemUtils()->DestroyTimeStamp(CURR_TIME); return 0; }
int SDL_MAIN_FUNC(int argc, char *argv[]) { CLogger logger; CSystemUtils* systemUtils = CSystemUtils::Create(); // platform-specific utils systemUtils->Init(); PREV_TIME = GetSystemUtils()->CreateTimeStamp(); CURR_TIME = GetSystemUtils()->CreateTimeStamp(); GetSystemUtils()->GetCurrentTimeStamp(PREV_TIME); GetSystemUtils()->GetCurrentTimeStamp(CURR_TIME); // Without any error checking, for simplicity SDL_Init(SDL_INIT_VIDEO); IMG_Init(IMG_INIT_PNG); const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); Uint32 videoFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE; if (videoInfo->hw_available) videoFlags |= SDL_HWSURFACE; else videoFlags |= SDL_SWSURFACE; if (videoInfo->blit_hw) videoFlags |= SDL_HWACCEL; SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_Surface *surface = SDL_SetVideoMode(800, 600, 32, videoFlags); SDL_WM_SetCaption("Light Test", "Light Test"); //SDL_WM_GrabInput(SDL_GRAB_ON); SDL_ShowCursor(SDL_DISABLE); Gfx::CGLDevice *device = new Gfx::CGLDevice(Gfx::GLDeviceConfig()); device->Create(); Init(device); bool done = false; while (! done) { Render(device); Update(); SDL_GL_SwapBuffers(); SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { break; done = true; } else if (event.type == SDL_KEYDOWN) { if (event.key.keysym.sym == SDLK_q) { done = true; break; } else KeyboardDown(event.key.keysym.sym); } else if (event.type == SDL_KEYUP) KeyboardUp(event.key.keysym.sym); else if (event.type == SDL_MOUSEMOTION) MouseMove(event.motion.x, event.motion.y); } usleep(FRAME_DELAY); } //SDL_WM_GrabInput(SDL_GRAB_OFF); SDL_ShowCursor(SDL_ENABLE); device->Destroy(); delete device; SDL_FreeSurface(surface); IMG_Quit(); SDL_Quit(); GetSystemUtils()->DestroyTimeStamp(PREV_TIME); GetSystemUtils()->DestroyTimeStamp(CURR_TIME); return 0; }
CApplication::CApplication() { m_private = new ApplicationPrivate(); m_iMan = new CInstanceManager(); m_eventQueue = new CEventQueue(); m_profile = new CProfile(); m_engine = nullptr; m_device = nullptr; m_modelManager = nullptr; m_robotMain = nullptr; m_sound = nullptr; m_exitCode = 0; m_active = false; m_debugMode = false; m_windowTitle = "COLOBOT"; m_simulationSuspended = false; m_simulationSpeed = 1.0f; m_realAbsTimeBase = 0LL; m_realAbsTime = 0LL; m_realRelTime = 0LL; m_absTimeBase = 0LL; m_exactAbsTime = 0LL; m_exactRelTime = 0LL; m_absTime = 0.0f; m_relTime = 0.0f; m_baseTimeStamp = GetSystemUtils()->CreateTimeStamp(); m_curTimeStamp = GetSystemUtils()->CreateTimeStamp(); m_lastTimeStamp = GetSystemUtils()->CreateTimeStamp(); for (int i = 0; i < PCNT_MAX; ++i) { m_performanceCounters[i][0] = GetSystemUtils()->CreateTimeStamp(); m_performanceCounters[i][1] = GetSystemUtils()->CreateTimeStamp(); } m_joystickEnabled = false; m_mouseMode = MOUSE_SYSTEM; m_kmodState = 0; m_mouseButtonsState = 0; m_trackedKeys = 0; m_dataPath = COLOBOT_DEFAULT_DATADIR; m_langPath = COLOBOT_I18N_DIR; m_language = LANGUAGE_ENV; m_lowCPU = true; for (int i = 0; i < DIR_MAX; ++i) m_dataDirs[i] = nullptr; m_dataDirs[DIR_AI] = "ai"; m_dataDirs[DIR_FONT] = "fonts"; m_dataDirs[DIR_HELP] = "help"; m_dataDirs[DIR_ICON] = "icons"; m_dataDirs[DIR_LEVEL] = "levels"; m_dataDirs[DIR_MODEL] = "models"; m_dataDirs[DIR_MUSIC] = "music"; m_dataDirs[DIR_SOUND] = "sounds"; m_dataDirs[DIR_TEXTURE] = "textures"; }
int CApplication::Run() { m_active = true; GetSystemUtils()->GetCurrentTimeStamp(m_baseTimeStamp); GetSystemUtils()->GetCurrentTimeStamp(m_lastTimeStamp); GetSystemUtils()->GetCurrentTimeStamp(m_curTimeStamp); MoveMouse(Math::Point(0.5f, 0.5f)); // center mouse on start while (true) { ResetPerformanceCounters(); if (m_active) { StartPerformanceCounter(PCNT_ALL); StartPerformanceCounter(PCNT_EVENT_PROCESSING); } // To be sure no old event remains m_private->currentEvent.type = SDL_NOEVENT; // Call SDL_PumpEvents() only once here // (SDL_PeepEvents() doesn't call it) if (m_active) SDL_PumpEvents(); m_private->lastMouseMotionEvent.type = SDL_NOEVENT; bool haveEvent = true; while (haveEvent) { haveEvent = false; int count = 0; // Use SDL_PeepEvents() if the app is active, so we can use idle time to // render the scene. Else, use SDL_WaitEvent() to avoid eating CPU time. if (m_active) count = SDL_PeepEvents(&m_private->currentEvent, 1, SDL_GETEVENT, SDL_ALLEVENTS); else count = SDL_WaitEvent(&m_private->currentEvent); // If received an event if (count > 0) { haveEvent = true; // Skip mouse motion events, for now if (m_private->currentEvent.type == SDL_MOUSEMOTION) { m_private->lastMouseMotionEvent = m_private->currentEvent; continue; } Event event = ProcessSystemEvent(); if (event.type == EVENT_QUIT) goto end; // exit the loop if (event.type != EVENT_NULL) { bool passOn = ProcessEvent(event); if (m_engine != nullptr && passOn) passOn = m_engine->ProcessEvent(event); if (passOn) m_eventQueue->AddEvent(event); } Event virtualEvent = CreateVirtualEvent(event); if (virtualEvent.type != EVENT_NULL) { bool passOn = ProcessEvent(virtualEvent); if (m_engine != nullptr && passOn) passOn = m_engine->ProcessEvent(virtualEvent); if (passOn) m_eventQueue->AddEvent(virtualEvent); } } } // Now, process the last received mouse motion if (m_private->lastMouseMotionEvent.type != SDL_NOEVENT) { m_private->currentEvent = m_private->lastMouseMotionEvent; Event event = ProcessSystemEvent(); if (event.type == EVENT_QUIT) goto end; // exit the loop if (event.type != EVENT_NULL) { bool passOn = ProcessEvent(event); if (m_engine != nullptr && passOn) passOn = m_engine->ProcessEvent(event); if (passOn) m_eventQueue->AddEvent(event); } } // Enter game update & frame rendering only if active if (m_active) { Event event; while (m_eventQueue->GetEvent(event)) { if (event.type == EVENT_QUIT) goto end; // exit both loops bool passOn = true; // Skip system events (they have been processed earlier) if (! event.systemEvent) { passOn = ProcessEvent(event); if (passOn && m_engine != nullptr) passOn = m_engine->ProcessEvent(event); } if (passOn && m_robotMain != nullptr) m_robotMain->EventProcess(event); } StopPerformanceCounter(PCNT_EVENT_PROCESSING); StartPerformanceCounter(PCNT_UPDATE_ALL); // Prepare and process step simulation event event = CreateUpdateEvent(); if (event.type != EVENT_NULL && m_robotMain != nullptr) { StartPerformanceCounter(PCNT_UPDATE_ENGINE); m_engine->FrameUpdate(); StopPerformanceCounter(PCNT_UPDATE_ENGINE); m_sound->FrameMove(m_relTime); StartPerformanceCounter(PCNT_UPDATE_GAME); m_robotMain->EventProcess(event); StopPerformanceCounter(PCNT_UPDATE_GAME); } StopPerformanceCounter(PCNT_UPDATE_ALL); /* Update mouse position explicitly right before rendering * because mouse events are usually way behind */ UpdateMouse(); StartPerformanceCounter(PCNT_RENDER_ALL); Render(); StopPerformanceCounter(PCNT_RENDER_ALL); StopPerformanceCounter(PCNT_ALL); UpdatePerformanceCountersData(); if (m_lowCPU) { usleep(20000); // should still give plenty of fps } } } end: Destroy(); return m_exitCode; }
void CApplication::StopPerformanceCounter(PerformanceCounter counter) { GetSystemUtils()->GetCurrentTimeStamp(m_performanceCounters[counter][1]); }