namespace dc {
-class engine_impl
+class engine::engine_impl
{
public:
engine_impl(const std::string& name, int argc, char* argv[],
- const std::string& configFile, engine* outer) : config(argc, argv),
- interface(outer)
+ const std::string& configFile, engine* outer) :
+ config(argc, argv),
+ interface(outer)
{
if (SDL_Init(SDL_INIT_EVERYTHING | SDL_INIT_EVENTTHREAD) != 0)
{
screen = video_ptr(new video(name));
screen->makeActive();
- timestep = 0.01;
- config.get("engine.timestep", timestep);
+ double ts = 0.01;
+ config.get("engine.timestep", ts);
+ timestep = scalar(ts);
long maxfps = 40;
- config.get("engine.maxfps", maxfps);
+ config.getNumber("video.maxfps", maxfps);
drawrate = 1.0 / scalar(maxfps);
printfps = false;
- config.get("engine.printfps", printfps);
+ config.get("video.printfps", printfps);
}
~engine_impl()
}
+ /**
+ * The main loop. This just calls dispatchEvents(), update(), and draw()
+ * over and over again. The timing of the update and draw are decoupled.
+ * The actual frame rate is also calculated here. This function will return
+ * with a value of 0 if the member variable running becomes true.
+ */
+
int run()
{
scalar ticksNow = ticks();
scalar nextFPSUpdate = ticksNow + 1.0;
scalar totalTime = 0.0;
- scalar accumulator = 0.0;
+ scalar deltaTime = 0.0;
+ scalar accumulator = timestep;
- fps = 0.0;
- int frameAccum = 0.0;
+ fps = 0;
+ int frameAccum = 0;
running = true;
do
{
- dispatchEvents();
-
scalar newTicks = ticks();
- accumulator += newTicks - ticksNow;
+ deltaTime = newTicks - ticksNow;
ticksNow = newTicks;
- if (ticksNow >= nextStep)
+ if (deltaTime >= 0.25) deltaTime = 0.25;
+ accumulator += deltaTime;
+
+ while (accumulator >= timestep)
{
+ dispatchEvents();
interface->update(totalTime, timestep);
totalTime += timestep;
accumulator -= timestep;
nextStep += timestep;
- if (ticksNow >= nextStep) nextStep = ticksNow + timestep;
}
if (ticksNow >= nextDraw)
{
frameAccum++;
- if (ticksNow >= nextFPSUpdate)
+ if (ticksNow >= nextFPSUpdate) // determine the actual fps
{
- fps = frameAccum;// + (ticksNow - nextFPSUpdate) / 1.0;
+ fps = frameAccum;
frameAccum = 0;
nextFPSUpdate += 1.0;
- if (ticksNow >= nextFPSUpdate) nextFPSUpdate = ticksNow + 1.0;
+ if (ticksNow >= nextFPSUpdate)
+ {
+ nextFPSUpdate = ticksNow + 1.0;
+ }
if (printfps)
{
screen->swap();
nextDraw += drawrate;
- if (ticksNow >= nextDraw) nextDraw = ticksNow + drawrate;
+ if (ticksNow >= nextDraw)
+ {
+ // we missed some scheduled draws, so reset the schedule
+ nextDraw = ticksNow + drawrate;
+ }
}
+ // be a good citizen and give back what you don't need
sleep(std::min(nextStep, nextDraw), true);
}
while (running);
+
+ return 0;
}
void dispatchEvents()
{
- SDL_Event event;
+ SDL_Event e;
- while (FE_PollEvent(&event) == 1)
+ while (FE_PollEvent(&e) == 1)
{
- switch (event.type)
+ switch (e.type)
{
case SDL_KEYDOWN:
- if (event.key.keysym.sym == SDLK_ESCAPE &&
+ if (e.key.keysym.sym == SDLK_ESCAPE &&
(SDL_GetModState() & KMOD_CTRL) )
{
exit(0);
break;
case SDL_VIDEORESIZE:
- screen->resize(event.resize.w, event.resize.h);
+ screen->resize(e.resize.w, e.resize.h);
break;
}
- interface->dispatchEvent(event);
+ interface->handleEvent(e);
}
}
engine* interface;
};
+
engine::engine(const std::string& name, int argc, char* argv[],
- const std::string& configFile)
- : impl(new engine_impl(name, argc, argv, configFile, this)) {}
+ const std::string& configFile) :
+ impl(new engine::engine_impl(name, argc, argv, configFile, this)) {}
engine::~engine() {}
int engine::run()
{
- impl->run();
+ return impl->run();
}
void engine::stop()
void engine::update(scalar t, scalar dt) {}
void engine::draw(scalar alpha) {}
-void engine::dispatchEvent(const SDL_Event& event) {}
+void engine::handleEvent(const SDL_Event& e) {}
} // namespace dc
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+