]> Dogcows Code - chaz/yoink/blobdiff - src/engine.cc
new classes; yajl library
[chaz/yoink] / src / engine.cc
diff --git a/src/engine.cc b/src/engine.cc
new file mode 100644 (file)
index 0000000..3e40361
--- /dev/null
@@ -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 <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_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
+
This page took 0.026609 seconds and 4 git commands to generate.