From e2c30a568dd6c966270123807f50e7339e316a11 Mon Sep 17 00:00:00 2001 From: Aloshi Date: Wed, 17 Jul 2013 01:47:02 -0500 Subject: [PATCH] Added a Window::normalizeNextUpdate() method. If you know something is about to cause the framerate to tank (e.g. theme loading), you can tell the next update to be, at maximum, the average of the previous five seconds of frames. The framerate drawing code has also been moved to Window. --- src/SystemData.cpp | 1 + src/Window.cpp | 67 ++++++++++++++++++++++++++-------- src/Window.h | 9 +++++ src/components/GuiGameList.cpp | 3 +- src/main.cpp | 22 ----------- 5 files changed, 64 insertions(+), 38 deletions(-) diff --git a/src/SystemData.cpp b/src/SystemData.cpp index e856112f5..e891197ba 100644 --- a/src/SystemData.cpp +++ b/src/SystemData.cpp @@ -94,6 +94,7 @@ void SystemData::launchGame(Window* window, GameData* game) window->init(); VolumeControl::getInstance()->init(); AudioManager::getInstance()->init(); + window->normalizeNextUpdate(); //update number of times the game has been launched and the time game->setTimesPlayed(game->getTimesPlayed() + 1); diff --git a/src/Window.cpp b/src/Window.cpp index 95b21b31c..9c0af7905 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -5,8 +5,9 @@ #include "VolumeControl.h" #include "Log.h" #include "Settings.h" +#include -Window::Window() +Window::Window() : mNormalizeNextUpdate(false), mFrameTimeElapsed(0), mFrameCountElapsed(0), mAverageDeltaTime(10) { mInputManager = new InputManager(this); } @@ -45,20 +46,6 @@ GuiComponent* Window::peekGui() return mGuiStack.at(mGuiStack.size() - 1); } -void Window::render() -{ - //there's nothing to render, which should pretty much never happen - if(mGuiStack.size() == 0) - std::cout << "guistack empty\n"; - - Eigen::Affine3f trans(Eigen::Affine3f::Identity()); - - for(unsigned int i = 0; i < mGuiStack.size(); i++) - { - mGuiStack.at(i)->render(trans); - } -} - bool Window::init(unsigned int width, unsigned int height) { if(!Renderer::init(width, height)) @@ -105,10 +92,60 @@ void Window::input(InputConfig* config, Input input) void Window::update(int deltaTime) { + if(mNormalizeNextUpdate) + { + mNormalizeNextUpdate = false; + if(deltaTime > mAverageDeltaTime) + deltaTime = mAverageDeltaTime; + } + + mFrameTimeElapsed += deltaTime; + mFrameCountElapsed++; + if(mFrameTimeElapsed > 500) + { + mAverageDeltaTime = mFrameTimeElapsed / mFrameCountElapsed; + + if(Settings::getInstance()->getBool("DRAWFRAMERATE")) + { + std::stringstream ss; + ss << std::fixed << std::setprecision(1) << (1000.0f * (float)mFrameCountElapsed / (float)mFrameTimeElapsed) << "fps, "; + ss << std::fixed << std::setprecision(2) << ((float)mFrameTimeElapsed / (float)mFrameCountElapsed) << "ms"; + mFrameDataString = ss.str(); + } + + mFrameTimeElapsed = 0; + mFrameCountElapsed = 0; + } + if(peekGui()) peekGui()->update(deltaTime); } +void Window::render() +{ + //there's nothing to render, which should pretty much never happen + if(mGuiStack.size() == 0) + std::cout << "guistack empty\n"; + + Eigen::Affine3f trans(Eigen::Affine3f::Identity()); + + for(unsigned int i = 0; i < mGuiStack.size(); i++) + { + mGuiStack.at(i)->render(trans); + } + + if(Settings::getInstance()->getBool("DRAWFRAMERATE")) + { + Renderer::setMatrix(Eigen::Affine3f::Identity()); + mDefaultFonts.at(1)->drawText(mFrameDataString, Eigen::Vector2f(50, 50), 0xFF00FFFF); + } +} + +void Window::normalizeNextUpdate() +{ + mNormalizeNextUpdate = true; +} + InputManager* Window::getInputManager() { return mInputManager; diff --git a/src/Window.h b/src/Window.h index 52cefcb21..d4698e13a 100644 --- a/src/Window.h +++ b/src/Window.h @@ -27,12 +27,21 @@ public: InputManager* getInputManager(); ResourceManager* getResourceManager(); + void normalizeNextUpdate(); + private: InputManager* mInputManager; ResourceManager mResourceManager; std::vector mGuiStack; std::vector< std::shared_ptr > mDefaultFonts; + + int mFrameTimeElapsed; + int mFrameCountElapsed; + int mAverageDeltaTime; + std::string mFrameDataString; + + bool mNormalizeNextUpdate; }; #endif diff --git a/src/components/GuiGameList.cpp b/src/components/GuiGameList.cpp index d34778625..a08bc7aab 100644 --- a/src/components/GuiGameList.cpp +++ b/src/components/GuiGameList.cpp @@ -100,6 +100,7 @@ void GuiGameList::setSystemId(int id) updateTheme(); updateList(); updateDetailData(); + mWindow->normalizeNextUpdate(); //image loading can be slow } void GuiGameList::render(const Eigen::Affine3f& parentTrans) @@ -135,7 +136,7 @@ void GuiGameList::render(const Eigen::Affine3f& parentTrans) } mList.render(trans); - mTransitionImage.render(trans); + mTransitionImage.render(parentTrans); } bool GuiGameList::input(InputConfig* config, Input input) diff --git a/src/main.cpp b/src/main.cpp index 717b73b77..8a5347aa6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -217,28 +217,6 @@ int main(int argc, char* argv[]) window.update(deltaTime); Renderer::swapBuffers(); //swap here so we can read the last screen state during updates (see ImageComponent::copyScreen()) window.render(); - - if(Settings::getInstance()->getBool("DRAWFRAMERATE")) - { - static int timeElapsed = 0; - static int nrOfFrames = 0; - static std::string fpsString; - - nrOfFrames++; - timeElapsed += deltaTime; - //wait until half a second has passed to recalculate fps - if (timeElapsed >= 500) { - std::stringstream ss; - ss << std::fixed << std::setprecision(1) << (1000.0f * (float)nrOfFrames / (float)timeElapsed) << "fps, "; - ss << std::fixed << std::setprecision(2) << ((float)timeElapsed / (float)nrOfFrames) << "ms"; - fpsString = ss.str(); - nrOfFrames = 0; - timeElapsed = 0; - } - - Renderer::setMatrix(Eigen::Affine3f::Identity()); - Font::get(*window.getResourceManager(), Font::getDefaultPath(), FONT_SIZE_MEDIUM)->drawText(fpsString, Eigen::Vector2f(50, 50), 0x00FF00FF); - } //sleep if we're past our threshold //sleeping entails setting a flag to start skipping frames