]> Dogcows Code - chaz/yoink/blob - src/engine.cc
new classes; yajl library
[chaz/yoink] / src / engine.cc
1
2 /*******************************************************************************
3
4 Copyright (c) 2009, Charles McGarvey
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 *******************************************************************************/
28
29 #include <iostream>
30 #include <cstdlib> // exit
31 #include <string>
32 #include <stdexcept>
33
34 #include <SDL/SDL.h>
35 #include "fastevents.h"
36
37 #include "random.hh"
38 #include "timer.hh"
39 #include "video.hh"
40 #include "settings.hh"
41 #include "dispatcher.hh"
42
43 #include "engine.hh"
44
45
46 namespace dc {
47
48
49 class engine_impl
50 {
51 public:
52 engine_impl(const std::string& name, int argc, char* argv[],
53 const std::string& configFile, engine* outer) : config(argc, argv),
54 interface(outer)
55 {
56 if (SDL_Init(SDL_INIT_EVERYTHING | SDL_INIT_EVENTTHREAD) != 0)
57 {
58 throw std::runtime_error(SDL_GetError());
59 }
60 if (FE_Init() != 0)
61 {
62 throw std::runtime_error(FE_GetError());
63 }
64
65 rng::seed();
66
67 config.loadFromFile(configFile);
68
69 screen = video_ptr(new video(name));
70 screen->makeActive();
71
72 timestep = 0.01;
73 config.get("engine.timestep", timestep);
74
75 long maxfps = 40;
76 config.get("engine.maxfps", maxfps);
77 drawrate = 1.0 / scalar(maxfps);
78
79 printfps = false;
80 config.get("engine.printfps", printfps);
81 }
82
83 ~engine_impl()
84 {
85 // The video object must be destroyed before we can shutdown SDL.
86 screen.reset();
87
88 FE_Quit();
89 SDL_Quit();
90 }
91
92
93 int run()
94 {
95 scalar ticksNow = ticks();
96
97 scalar nextStep = ticksNow;
98 scalar nextDraw = ticksNow;
99 scalar nextFPSUpdate = ticksNow + 1.0;
100
101 scalar totalTime = 0.0;
102 scalar accumulator = 0.0;
103
104 fps = 0.0;
105 int frameAccum = 0.0;
106
107 running = true;
108 do
109 {
110 dispatchEvents();
111
112 scalar newTicks = ticks();
113 accumulator += newTicks - ticksNow;
114 ticksNow = newTicks;
115
116 if (ticksNow >= nextStep)
117 {
118 interface->update(totalTime, timestep);
119
120 totalTime += timestep;
121 accumulator -= timestep;
122
123 nextStep += timestep;
124 if (ticksNow >= nextStep) nextStep = ticksNow + timestep;
125 }
126
127 if (ticksNow >= nextDraw)
128 {
129 frameAccum++;
130
131 if (ticksNow >= nextFPSUpdate)
132 {
133 fps = frameAccum;// + (ticksNow - nextFPSUpdate) / 1.0;
134 frameAccum = 0;
135
136 nextFPSUpdate += 1.0;
137 if (ticksNow >= nextFPSUpdate) nextFPSUpdate = ticksNow + 1.0;
138
139 if (printfps)
140 {
141 std::cout << "FPS: " << fps << std::endl;
142 }
143 }
144
145 interface->draw(accumulator / timestep);
146 screen->swap();
147
148 nextDraw += drawrate;
149 if (ticksNow >= nextDraw) nextDraw = ticksNow + drawrate;
150 }
151
152 sleep(std::min(nextStep, nextDraw), true);
153 }
154 while (running);
155 }
156
157
158 void dispatchEvents()
159 {
160 SDL_Event event;
161
162 while (FE_PollEvent(&event) == 1)
163 {
164 switch (event.type)
165 {
166 case SDL_KEYDOWN:
167 if (event.key.keysym.sym == SDLK_ESCAPE &&
168 (SDL_GetModState() & KMOD_CTRL) )
169 {
170 exit(0);
171 }
172 break;
173
174 case SDL_VIDEORESIZE:
175 screen->resize(event.resize.w, event.resize.h);
176 break;
177 }
178
179 interface->dispatchEvent(event);
180 }
181 }
182
183
184 settings config;
185 dispatcher relay;
186 video_ptr screen;
187
188 bool running;
189
190 scalar timestep;
191 scalar drawrate;
192
193 long fps;
194 bool printfps;
195
196 engine* interface;
197 };
198
199 engine::engine(const std::string& name, int argc, char* argv[],
200 const std::string& configFile)
201 : impl(new engine_impl(name, argc, argv, configFile, this)) {}
202
203 engine::~engine() {}
204
205
206 int engine::run()
207 {
208 impl->run();
209 }
210
211 void engine::stop()
212 {
213 impl->running = false;
214 }
215
216
217 void engine::setTimestep(scalar ts)
218 {
219 impl->timestep = ts;
220 }
221
222 scalar engine::getTimestep()
223 {
224 return impl->timestep;
225 }
226
227 void engine::setMaxFPS(long maxfps)
228 {
229 impl->drawrate = 1.0 / scalar(maxfps);
230 }
231
232 long engine::getMaxFPS()
233 {
234 return long(1.0 / impl->drawrate);
235 }
236
237
238 video& engine::getVideo()
239 {
240 return *impl->screen;
241 }
242
243 long engine::getFPS()
244 {
245 return impl->fps;
246 }
247
248
249 void engine::update(scalar t, scalar dt) {}
250 void engine::draw(scalar alpha) {}
251 void engine::dispatchEvent(const SDL_Event& event) {}
252
253
254 } // namespace dc
255
This page took 0.040267 seconds and 4 git commands to generate.