Impl() :
mError(Error::NONE),
mTimestep(0.01),
- mPrintFps(false)
+ mFramerate(0.02),
+ mShowFps(false)
{
- // first, initialize the libraries
-
#if defined(_WIN32) || defined(__WIN32__)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
#else
{
const char* error = SDL_GetError();
mError.init(Error::SDL_INIT, error);
- //throw Exception(Error::SDL_INIT, error);
+ return; // fatal
}
else
{
- char vdName[128];
- SDL_VideoDriverName(vdName, sizeof(vdName));
+ char name[128];
+ SDL_VideoDriverName(name, sizeof(name));
logInfo << "initialized SDL; using video driver `"
- << vdName << "'" << std::endl;
+ << name << "'" << std::endl;
}
if (FE_Init() != 0)
{
const char* error = FE_GetError();
mError.init(Error::FASTEVENTS_INIT, error);
- //throw Exception(Error::FASTEVENTS_INIT, error);
+ return; // fatal
}
mAlDevice = alcOpenDevice(0);
if (!mAlDevice || !mAlContext)
{
const char* error = alcGetString(mAlDevice,alcGetError(mAlDevice));
- logError << "error while creating audio context: "
- << error << std::endl;
+ mError.init(Error::OPENAL_INIT, error);
}
else
{
<< alcGetString(mAlDevice, ALC_DEFAULT_DEVICE_SPECIFIER)
<< "'" << std::endl;
}
+ }
- // now load the settings the engine needs
-
- Settings& settings = Settings::getInstance();
-
+ bool initWithSettings(const Settings& settings)
+ {
unsigned randomSeed;
if (settings.get("rngseed", randomSeed)) srand(randomSeed);
else srand(time(0));
settings.get("timestep", timestep);
mTimestep = 1.0 / timestep;
- Scalar maxFps = 40.0;
- settings.get("maxfps", maxFps);
- mMaxFps = 1.0 / maxFps;
+ Scalar framerate = 40.0;
+ settings.get("framerate", framerate);
+ mFramerate = 1.0 / framerate;
capFps();
- settings.get("printfps", mPrintFps);
+ mShowFps = false;
+ settings.get("showfps", mShowFps);
+
+ return true;
}
~Impl()
void run()
{
- Scalar ticksNow = Timer::getTicks();
-
- Scalar nextStep = ticksNow;
- Scalar nextDraw = ticksNow;
- Scalar nextFpsUpdate = ticksNow + 1.0;
-
Scalar totalTime = 0.0;
- Scalar deltaTime = 0.0;
- Scalar accumulator = mTimestep;
+ Scalar ticks = Timer::getTicks();
+
+ Scalar nextUpdate = ticks;
+ Scalar nextDraw = ticks;
+ Scalar nextSecond = ticks + SCALAR(1.0);
mFps = 0;
- int frameAccum = 0;
+ int frames = 0;
+
+ const int MAX_FRAMESKIP = 15;
+ const Scalar inverseTimestep = SCALAR(1.0) / mTimestep;
do
{
- Scalar newTicks = Timer::getTicks();
- deltaTime = newTicks - ticksNow;
- ticksNow = newTicks;
-
- // don't slow the animation until 4Hz, which is unplayable anyway
- if (deltaTime >= 0.25) deltaTime = 0.25;
- accumulator += deltaTime;
-
- Timer::fireIfExpired(ticksNow);
+ Timer::fireIfExpired();
dispatchEvents();
- while (accumulator >= mTimestep)
+ int i = 0;
+ while (nextUpdate < Timer::getTicks() && i < MAX_FRAMESKIP)
{
- update(totalTime, mTimestep);
-
totalTime += mTimestep;
- accumulator -= mTimestep;
+ update(totalTime, mTimestep);
- nextStep += mTimestep;
- }
- if (ticksNow >= nextStep)
- {
- nextStep = ticksNow + mTimestep;
+ nextUpdate += mTimestep;
+ ++i;
}
- if (ticksNow >= nextDraw)
+ if (nextDraw < (ticks = Timer::getTicks()))
{
- frameAccum++;
+ ++frames;
+ draw((ticks + mTimestep - nextUpdate) * inverseTimestep);
+ mVideo->swap();
- if (ticksNow >= nextFpsUpdate) // determine the actual fps
- {
- mFps = frameAccum;
- frameAccum = 0;
+ nextDraw += mFramerate;
- nextFpsUpdate += 1.0;
- if (ticksNow >= nextFpsUpdate)
- {
- nextFpsUpdate = ticksNow + 1.0;
- }
-
- if (mPrintFps)
- {
- logInfo << mFps << " fps" << std::endl;
- }
- }
+ if (mShowFps && nextSecond < ticks)
+ {
+ mFps = frames;
+ frames = 0;
- draw(accumulator / mTimestep);
- mVideo->swap();
+ logInfo << mFps << " fps" << std::endl;
- nextDraw += mMaxFps;
- if (ticksNow >= nextDraw)
- {
- // we missed some scheduled draws, so reset the schedule
- nextDraw = ticksNow + mMaxFps;
+ nextSecond += SCALAR(1.0);
}
}
// be a good citizen and give back what you don't need
- Timer::sleep(std::min(std::min(nextStep, nextDraw),
- Timer::getNextFire()), Timer::ACTUAL);
+ Timer::sleep(0.0);
}
while (!mStack.empty());
void capFps()
{
- if (mMaxFps < mTimestep)
- {
- logWarning << "capping maximum fps to timestep ("
- << mTimestep << ")" << std::endl;
- mMaxFps = mTimestep;
- }
+ //if (mFramerate < mTimestep)
+ //{
+ //logWarning << "capping maximum fps to timestep ("
+ //<< mTimestep << ")" << std::endl;
+ //mFramerate = mTimestep;
+ //}
}
std::list<LayerP>::iterator mStackIt;
Scalar mTimestep;
- Scalar mMaxFps;
+ Scalar mFramerate;
int mFps;
- bool mPrintFps;
+ bool mShowFps;
};
mImpl(new Engine::Impl) {}
-const Error& Engine::getError() const
+bool Engine::initWithSettings(const Settings& settings)
{
// pass through
- return mImpl->mError;
+ return mImpl->initWithSettings(settings);
}
-
-void Engine::setVideo(VideoP video)
+const Error& Engine::getError() const
{
// pass through
- mImpl->mVideo = video;
-}
-
-VideoP Engine::getVideo() const
-{
- return mImpl->mVideo;
-}
-
-
-void Engine::setTimestep(int ts)
-{
- mImpl->mTimestep = 1.0 / Scalar(ts);
- mImpl->capFps();
+ return mImpl->mError;
}
-int Engine::getTimestep() const
+void Engine::clearError()
{
- return int(1.0 / mImpl->mTimestep);
+ // pass through
+ mImpl->mError.init(Error::NONE);
}
-void Engine::setMaxFps(int maxFps)
+void Engine::setVideo(VideoP video)
{
- mImpl->mMaxFps = 1.0 / Scalar(maxFps);
- mImpl->capFps();
+ // pass through
+ mImpl->mVideo = video;
}
-int Engine::getMaxFps() const
+VideoP Engine::getVideo() const
{
- return int(1.0 / mImpl->mMaxFps);
+ return mImpl->mVideo;
}