void HideMouse() { UpdateMouse(0); }
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; }