void CProjectileDrawer::DrawProjectile(CProjectile* pro, bool drawReflection, bool drawRefraction) { const CUnit* owner = pro->owner(); const float time = !GML::SimEnabled() ? globalRendering->timeOffset : ((float)spring_tomsecs(globalRendering->lastFrameStart) - (float)pro->lastProjUpdate) * globalRendering->weightedSpeedFactor; pro->drawPos = pro->pos + (pro->speed * time); if ( (gu->spectatingFullView || loshandler->InLos(pro, gu->myAllyTeam) || (owner && teamHandler->Ally(owner->allyteam, gu->myAllyTeam))) && camera->InView(pro->pos, pro->drawRadius) ) { if (drawReflection) { if (pro->pos.y < -pro->drawRadius) { return; } float dif = pro->pos.y - camera->pos.y; float3 zeroPos = camera->pos * (pro->pos.y / dif) + pro->pos * (-camera->pos.y / dif); if (ground->GetApproximateHeight(zeroPos.x, zeroPos.z, false) > 3 + 0.5f * pro->drawRadius) { return; } } if (drawRefraction && pro->pos.y > pro->drawRadius) { return; } DrawProjectileModel(pro, false); pro->tempdist = pro->pos.dot(camera->forward); zSortedProjectiles.insert(pro); } }
void CTimeProfiler::Update() { //FIXME non-locking threadsafe boost::unique_lock<boost::mutex> ulk(m, boost::defer_lock); while (!ulk.try_lock()) {} ++currentPosition; currentPosition &= TimeRecord::frames_size-1; std::map<std::string,TimeRecord>::iterator pi; for (pi = profile.begin(); pi != profile.end(); ++pi) { pi->second.frames[currentPosition] = spring_notime; } const spring_time curTime = spring_gettime(); const float timeDiff = spring_diffmsecs(curTime, lastBigUpdate); if (timeDiff > 500.0f) // twice every second { for (std::map<std::string,TimeRecord>::iterator pi = profile.begin(); pi != profile.end(); ++pi) { pi->second.percent = spring_tomsecs(pi->second.current) / timeDiff; pi->second.current = spring_notime; if(pi->second.percent > pi->second.peak) { pi->second.peak = pi->second.percent; pi->second.newpeak = true; } else pi->second.newpeak = false; } lastBigUpdate = curTime; } }
void CTimeProfiler::AddTime(const std::string& name, const spring_time time, const bool showGraph) { std::map<std::string, TimeRecord>::iterator pi; if ( (pi = profile.find(name)) != profile.end() ) { // profile already exists //FIXME use atomic ints pi->second.total += time; pi->second.current += time; pi->second.frames[currentPosition] += time; } else { boost::unique_lock<boost::mutex> ulk(m, boost::defer_lock); while (!ulk.try_lock()) {} // create a new profile auto& p = profile[name]; p.total = time; p.current = time; p.percent = 0; memset(p.frames, 0, TimeRecord::frames_size * sizeof(unsigned)); static UnsyncedRNG rand; rand.Seed(spring_tomsecs(spring_gettime())); p.color.x = rand.RandFloat(); p.color.y = rand.RandFloat(); p.color.z = rand.RandFloat(); p.showGraph = showGraph; } }
void HangDetector() { while (keepRunning) { // increase multiplier during game load to prevent false positives e.g. during pathing const int hangTimeMultiplier = CrashHandler::gameLoading? 3 : 1; const spring_time hangtimeout = spring_msecs(spring_tomsecs(hangTimeout) * hangTimeMultiplier); spring_time curwdt = spring_gettime(); #if defined(USE_GML) && GML_ENABLE_SIM if (gmlMultiThreadSim) { spring_time cursimwdt = simwdt; if (spring_istime(cursimwdt) && curwdt > cursimwdt && (curwdt - cursimwdt) > hangtimeout) { HangHandler(true); simwdt = curwdt; } } #endif spring_time curdrawwdt = drawwdt; if (spring_istime(curdrawwdt) && curwdt > curdrawwdt && (curwdt - curdrawwdt) > hangtimeout) { HangHandler(false); drawwdt = curwdt; } spring_sleep(spring_secs(1)); } }
void CCameraHandler::UpdateCam() { //??? a lot CameraControllers depend on the calling every frame the 1st part of the if-clause //if (cameraTimeEnd < 0.0f) { // return; //} const float wantedCamFOV = currCamCtrl->GetFOV(); const float3 wantedCamPos = currCamCtrl->GetPos(); const float3 wantedCamDir = currCamCtrl->GetDir(); const float curTime = spring_tomsecs(spring_gettime()) / 1000.0f; if (curTime >= cameraTimeEnd) { camera->pos = wantedCamPos; camera->forward = wantedCamDir; camera->SetFov(wantedCamFOV); //cameraTimeEnd = -1.0f; } else { const float timeRatio = (cameraTimeEnd - curTime) / (cameraTimeEnd - cameraTimeStart); const float tweenFact = 1.0f - (float)math::pow(timeRatio, cameraTimeExponent); camera->pos = mix(startCam.pos, wantedCamPos, tweenFact); camera->forward = mix(startCam.dir, wantedCamDir, tweenFact); camera->SetFov( mix(startCam.fov, wantedCamFOV, tweenFact)); camera->forward.Normalize(); } }
void CCameraHandler::CameraTransition(float time) { time = std::max(time, 0.0f) * cameraTimeFactor; cameraTimeStart = spring_tomsecs(spring_gettime()) / 1000.0f; cameraTimeEnd = cameraTimeStart + time; startCam.pos = camera->pos; startCam.dir = camera->forward; startCam.fov = camera->GetFov(); }
void spring_time::Serialize(creg::ISerializer& s) { if (s.IsWriting()) { int y = spring_tomsecs(*this - spring_gettime()); s.SerializeInt(&y, 4); } else { int y; s.SerializeInt(&y, 4); *this = *this + spring_msecs(y); } }
void CProjectileDrawer::DrawProjectile(CProjectile* pro, bool drawReflection, bool drawRefraction) { const CUnit* owner = pro->owner(); const float time = !GML::SimEnabled() ? globalRendering->timeOffset : ((float)spring_tomsecs(globalRendering->lastFrameStart) - (float)pro->lastProjUpdate) * globalRendering->weightedSpeedFactor; pro->drawPos = pro->pos + (pro->speed * time); if ( (gu->spectatingFullView || loshandler->InLos(pro, gu->myAllyTeam) || (owner && teamHandler->Ally(owner->allyteam, gu->myAllyTeam))) && camera->InView(pro->pos, pro->drawRadius) ) { const bool stunned = owner ? owner->stunned : false; if (stunned && dynamic_cast<CShieldPartProjectile*>(pro)) { // if the unit that fired this projectile is stunned and the projectile // forms part of a shield (ie., the unit has a CPlasmaRepulser weapon but // cannot fire it), prevent the projectile (shield segment) from being drawn // // also prevents shields being drawn at unit's pre-pickup position // (since CPlasmaRepulser::Update() is responsible for updating // CShieldPartProjectile::centerPos) if the unit is in a non-fireplatform // transport return; } if (drawReflection) { if (pro->pos.y < -pro->drawRadius) { return; } float dif = pro->pos.y - camera->pos.y; float3 zeroPos = camera->pos * (pro->pos.y / dif) + pro->pos * (-camera->pos.y / dif); if (ground->GetApproximateHeight(zeroPos.x, zeroPos.z, false) > 3 + 0.5f * pro->drawRadius) { return; } } if (drawRefraction && pro->pos.y > pro->drawRadius) { return; } DrawProjectileModel(pro, false); pro->tempdist = pro->pos.dot(camera->forward); zSortedProjectiles.insert(pro); } }
int LuaParser::TimeCheck(lua_State* L) { if (!lua_isstring(L, 1) || !lua_isfunction(L, 2)) { luaL_error(L, "Invalid arguments to TimeCheck('string', func, ...)"); } const string name = lua_tostring(L, 1); lua_remove(L, 1); const spring_time startTime = spring_gettime(); const int error = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); if (error != 0) { const string errmsg = lua_tostring(L, -1); lua_pop(L, 1); luaL_error(L, errmsg.c_str()); } const spring_time endTime = spring_gettime(); const float elapsed = 1.0e-3f * (float)(spring_tomsecs(endTime - startTime)); logOutput.Print("%s %f", name.c_str(), elapsed); return lua_gettop(L); }
void CTimeProfiler::Update() { //FIXME non-locking threadsafe boost::unique_lock<boost::mutex> ulk(m, boost::defer_lock); while (!ulk.try_lock()) {} ++currentPosition; currentPosition &= TimeRecord::frames_size-1; for (auto& pi: profile) { pi.second.frames[currentPosition] = spring_notime; } const spring_time curTime = spring_gettime(); const float timeDiff = spring_diffmsecs(curTime, lastBigUpdate); if (timeDiff > 500.0f) // twice every second { for (auto& pi: profile) { auto& p = pi.second; p.percent = spring_tomsecs(p.current) / timeDiff; p.current = spring_notime; p.newLagPeak = false; p.newPeak = false; if(p.percent > p.peak) { p.peak = p.percent; p.newPeak = true; } } lastBigUpdate = curTime; } if (curTime.toSecsi() % 6 == 0) { for (auto& pi: profile) { auto& p = pi.second; p.maxLag *= 0.5f; } } }
bool CLoadScreen::Draw() { //! Limit the Frames Per Second to not lock a singlethreaded CPU from loading the game if (mtLoading) { spring_time now = spring_gettime(); unsigned diff_ms = spring_tomsecs(now - last_draw); static const unsigned wantedFPS = 50; static const unsigned min_frame_time = 1000 / wantedFPS; if (diff_ms < min_frame_time) { spring_time nap = spring_msecs(min_frame_time - diff_ms); spring_sleep(nap); } last_draw = now; } //! cause of `curLoadMessage` boost::recursive_mutex::scoped_lock lck(mutex); if (LuaIntro != nullptr) { LuaIntro->Update(); LuaIntro->DrawGenesis(); ClearScreen(); LuaIntro->DrawLoadScreen(); } else { ClearScreen(); float xDiv = 0.0f; float yDiv = 0.0f; const float ratioComp = globalRendering->aspectRatio / aspectRatio; if (math::fabs(ratioComp - 1.0f) < 0.01f) { //! ~= 1 //! show Load-Screen full screen //! nothing to do } else if (ratioComp > 1.0f) { //! show Load-Screen on part of the screens X-Axis only xDiv = (1.0f - (1.0f / ratioComp)) * 0.5f; } else { //! show Load-Screen on part of the screens Y-Axis only yDiv = (1.0f - ratioComp) * 0.5f; } //! Draw loading screen & print load msg. if (startupTexture) { glBindTexture(GL_TEXTURE_2D,startupTexture); glBegin(GL_QUADS); glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f + xDiv, 0.0f + yDiv); glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f + xDiv, 1.0f - yDiv); glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f - xDiv, 1.0f - yDiv); glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f - xDiv, 0.0f + yDiv); glEnd(); } if (showMessages) { font->Begin(); font->SetTextColor(0.5f,0.5f,0.5f,0.9f); font->glPrint(0.1f,0.9f, globalRendering->viewSizeY / 35.0f, FONT_NORM, oldLoadMessages); font->SetTextColor(0.9f,0.9f,0.9f,0.9f); float posy = font->GetTextNumLines(oldLoadMessages) * font->GetLineHeight() * globalRendering->viewSizeY / 35.0f; font->glPrint(0.1f,0.9f - posy * globalRendering->pixelY, globalRendering->viewSizeY / 35.0f, FONT_NORM, curLoadMessage); font->End(); } } // Always render Spring's license notice font->Begin(); font->SetOutlineColor(0.0f,0.0f,0.0f,0.65f); font->SetTextColor(1.0f,1.0f,1.0f,1.0f); font->glFormat(0.5f,0.06f, globalRendering->viewSizeY / 35.0f, FONT_OUTLINE | FONT_CENTER | FONT_NORM, "Spring %s", SpringVersion::GetFull().c_str()); font->glFormat(0.5f,0.02f, globalRendering->viewSizeY / 50.0f, FONT_OUTLINE | FONT_CENTER | FONT_NORM, "This program is distributed under the GNU General Public License, see license.html for more info"); font->End(); if (!mtLoading) SDL_GL_SwapWindow(globalRendering->window); return true; }