+++ /dev/null
-
-/*******************************************************************************
-
- Copyright (c) 2009, Charles McGarvey
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-*******************************************************************************/
-
-#include <iostream>
-#include <cstdlib> // exit
-#include <string>
-#include <stdexcept>
-
-#include <SDL/SDL.h>
-#include "fastevents.h"
-
-#include "random.hh"
-#include "timer.hh"
-#include "video.hh"
-#include "settings.hh"
-#include "dispatcher.hh"
-
-#include "engine.hh"
-
-
-namespace dc {
-
-
-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)
- {
- if (SDL_Init(SDL_INIT_EVERYTHING | SDL_INIT_EVENTTHREAD) != 0)
- {
- throw std::runtime_error(SDL_GetError());
- }
- if (FE_Init() != 0)
- {
- throw std::runtime_error(FE_GetError());
- }
-
- rng::seed();
-
- config.loadFromFile(configFile);
-
- screen = video_ptr(new video(name));
- screen->makeActive();
-
- double ts = 0.01;
- config.get("engine.timestep", ts);
- timestep = scalar(ts);
-
- long maxfps = 40;
- config.getNumber("video.maxfps", maxfps);
- drawrate = 1.0 / scalar(maxfps);
-
- printfps = false;
- config.get("video.printfps", printfps);
- }
-
- ~engine_impl()
- {
- // The video object must be destroyed before we can shutdown SDL.
- screen.reset();
-
- FE_Quit();
- SDL_Quit();
- }
-
-
- /**
- * 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 nextStep = ticksNow;
- scalar nextDraw = ticksNow;
- scalar nextFPSUpdate = ticksNow + 1.0;
-
- scalar totalTime = 0.0;
- scalar deltaTime = 0.0;
- scalar accumulator = timestep;
-
- fps = 0;
- int frameAccum = 0;
-
- running = true;
- do
- {
- scalar newTicks = ticks();
- deltaTime = newTicks - ticksNow;
- ticksNow = newTicks;
-
- 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 >= nextDraw)
- {
- frameAccum++;
-
- if (ticksNow >= nextFPSUpdate) // determine the actual fps
- {
- fps = frameAccum;
- frameAccum = 0;
-
- nextFPSUpdate += 1.0;
- if (ticksNow >= nextFPSUpdate)
- {
- nextFPSUpdate = ticksNow + 1.0;
- }
-
- if (printfps)
- {
- std::cout << "FPS: " << fps << std::endl;
- }
- }
-
- interface->draw(accumulator / timestep);
- screen->swap();
-
- nextDraw += 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 e;
-
- while (FE_PollEvent(&e) == 1)
- {
- switch (e.type)
- {
- case SDL_KEYDOWN:
- if (e.key.keysym.sym == SDLK_ESCAPE &&
- (SDL_GetModState() & KMOD_CTRL) )
- {
- exit(0);
- }
- break;
-
- case SDL_VIDEORESIZE:
- screen->resize(e.resize.w, e.resize.h);
- break;
- }
-
- interface->handleEvent(e);
- }
- }
-
-
- settings config;
- dispatcher relay;
- video_ptr screen;
-
- bool running;
-
- scalar timestep;
- scalar drawrate;
-
- long fps;
- bool printfps;
-
- engine* interface;
-};
-
-
-engine::engine(const std::string& name, int argc, char* argv[],
- const std::string& configFile) :
- impl(new engine::engine_impl(name, argc, argv, configFile, this)) {}
-
-engine::~engine() {}
-
-
-int engine::run()
-{
- return impl->run();
-}
-
-void engine::stop()
-{
- impl->running = false;
-}
-
-
-void engine::setTimestep(scalar ts)
-{
- impl->timestep = ts;
-}
-
-scalar engine::getTimestep()
-{
- return impl->timestep;
-}
-
-void engine::setMaxFPS(long maxfps)
-{
- impl->drawrate = 1.0 / scalar(maxfps);
-}
-
-long engine::getMaxFPS()
-{
- return long(1.0 / impl->drawrate);
-}
-
-
-video& engine::getVideo()
-{
- return *impl->screen;
-}
-
-long engine::getFPS()
-{
- return impl->fps;
-}
-
-
-void engine::update(scalar t, scalar dt) {}
-void engine::draw(scalar alpha) {}
-void engine::handleEvent(const SDL_Event& e) {}
-
-
-} // namespace dc
-
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
-