X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fengine.cc;fp=src%2Fengine.cc;h=3e40361a3213f73c220d2ced348931c9dfd4e8cb;hp=0000000000000000000000000000000000000000;hb=79b5f738f2e38acb60cda7e09f54802933a17105;hpb=a891a2dcbbb63d9e771da6efff00a33da614e737 diff --git a/src/engine.cc b/src/engine.cc new file mode 100644 index 0000000..3e40361 --- /dev/null +++ b/src/engine.cc @@ -0,0 +1,255 @@ + +/******************************************************************************* + + 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 +#include // exit +#include +#include + +#include +#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_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(); + + timestep = 0.01; + config.get("engine.timestep", timestep); + + long maxfps = 40; + config.get("engine.maxfps", maxfps); + drawrate = 1.0 / scalar(maxfps); + + printfps = false; + config.get("engine.printfps", printfps); + } + + ~engine_impl() + { + // The video object must be destroyed before we can shutdown SDL. + screen.reset(); + + FE_Quit(); + SDL_Quit(); + } + + + int run() + { + scalar ticksNow = ticks(); + + scalar nextStep = ticksNow; + scalar nextDraw = ticksNow; + scalar nextFPSUpdate = ticksNow + 1.0; + + scalar totalTime = 0.0; + scalar accumulator = 0.0; + + fps = 0.0; + int frameAccum = 0.0; + + running = true; + do + { + dispatchEvents(); + + scalar newTicks = ticks(); + accumulator += newTicks - ticksNow; + ticksNow = newTicks; + + if (ticksNow >= nextStep) + { + interface->update(totalTime, timestep); + + totalTime += timestep; + accumulator -= timestep; + + nextStep += timestep; + if (ticksNow >= nextStep) nextStep = ticksNow + timestep; + } + + if (ticksNow >= nextDraw) + { + frameAccum++; + + if (ticksNow >= nextFPSUpdate) + { + fps = frameAccum;// + (ticksNow - nextFPSUpdate) / 1.0; + 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) nextDraw = ticksNow + drawrate; + } + + sleep(std::min(nextStep, nextDraw), true); + } + while (running); + } + + + void dispatchEvents() + { + SDL_Event event; + + while (FE_PollEvent(&event) == 1) + { + switch (event.type) + { + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_ESCAPE && + (SDL_GetModState() & KMOD_CTRL) ) + { + exit(0); + } + break; + + case SDL_VIDEORESIZE: + screen->resize(event.resize.w, event.resize.h); + break; + } + + interface->dispatchEvent(event); + } + } + + + 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_impl(name, argc, argv, configFile, this)) {} + +engine::~engine() {} + + +int engine::run() +{ + 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::dispatchEvent(const SDL_Event& event) {} + + +} // namespace dc +