]>
Dogcows Code - chaz/yoink/blob - src/Moof/Engine.cc
2 /*******************************************************************************
4 Copyright (c) 2009, Charles McGarvey
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
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.
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.
27 *******************************************************************************/
30 #include <cstdlib> // exit
35 #include "fastevents.h"
38 #include "Dispatcher.hh"
43 #include "Settings.hh"
54 Impl(int argc
, char* argv
[], const std::string
& name
,
55 const std::string
& iconFile
, const std::string
& configFile
,
61 #if defined(_WIN32) || defined (_WIN64) || defined(__WIN32__)
62 if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_TIMER
) != 0)
64 if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_EVENTTHREAD
) != 0)
67 logError("sdl is complaining: %s", SDL_GetError());
68 throw Exception(Exception::SDL_ERROR
);
72 logError("fast events error: %s", FE_GetError());
73 throw Exception(Exception::SDL_ERROR
);
75 alutInit(&argc
, argv
);
77 Settings
& settings
= Settings::getInstance();
78 settings
.loadFromFile(configFile
);
79 settings
.parseArgs(argc
, argv
);
82 if (settings
.get("rngseed", randomSeed
)) setSeed(randomSeed
);
85 Scalar timeStep
= 80.0;
86 settings
.get("timestep", timeStep
);
87 timestep
= 1.0 / timeStep
;
90 settings
.get("maxfps", maxFps
);
91 drawRate
= 1.0 / maxFps
;
93 settings
.get("printfps", printFps
);
95 video
= Video::alloc(name
, iconFile
);
101 // the video object must be destroyed before we can shutdown SDL
111 * The main loop. This just calls dispatchEvents(), update(), and draw()
112 * over and over again. The timing of the update and draw are decoupled.
113 * The actual frame rate is also calculated here. This function will return
114 * the exit code used to stop the loop.
119 Scalar ticksNow
= Timer::getTicks();
121 Scalar nextStep
= ticksNow
;
122 Scalar nextDraw
= ticksNow
;
123 Scalar nextFpsUpdate
= ticksNow
+ 1.0;
125 Scalar totalTime
= 0.0;
126 Scalar deltaTime
= 0.0;
127 Scalar accumulator
= timestep
;
134 Scalar newTicks
= Timer::getTicks();
135 deltaTime
= newTicks
- ticksNow
;
138 if (deltaTime
>= 0.25) deltaTime
= 0.25;
139 accumulator
+= deltaTime
;
141 Timer::fireIfExpired(ticksNow
);
143 while (accumulator
>= timestep
)
146 update(totalTime
, timestep
);
148 totalTime
+= timestep
;
149 accumulator
-= timestep
;
151 nextStep
+= timestep
;
153 if (ticksNow
>= nextStep
)
155 nextStep
= ticksNow
+ timestep
;
158 if (ticksNow
>= nextDraw
)
162 if (ticksNow
>= nextFpsUpdate
) // determine the actual fps
167 nextFpsUpdate
+= 1.0;
168 if (ticksNow
>= nextFpsUpdate
)
170 nextFpsUpdate
= ticksNow
+ 1.0;
175 logInfo("%d fps", fps
);
179 draw(accumulator
/ timestep
);
182 nextDraw
+= drawRate
;
183 if (ticksNow
>= nextDraw
)
185 // we missed some scheduled draws, so reset the schedule
186 nextDraw
= ticksNow
+ drawRate
;
190 // be a good citizen and give back what you don't need
191 Timer::sleep(std::min(std::min(nextStep
, nextDraw
),
192 Timer::getNextFire()), true);
194 while (!stack
.empty());
197 void dispatchEvents()
201 while (FE_PollEvent(&event
) == 1)
206 if (event
.key
.keysym
.sym
== SDLK_ESCAPE
&&
207 (SDL_GetModState() & KMOD_CTRL
) )
214 case SDL_VIDEORESIZE
:
215 video
->resize(event
.resize
.w
, event
.resize
.h
);
224 void update(Scalar t
, Scalar dt
)
226 for (stackIt
= stack
.begin(); stackIt
!= stack
.end(); ++stackIt
)
228 (*stackIt
)->update(t
, dt
);
232 void draw(Scalar alpha
)
234 // FIXME - this will crash if the layer being drawn pops itself
235 std::list
<LayerP
>::reverse_iterator it
;
236 for (it
= stack
.rbegin(); it
!= stack
.rend(); ++it
)
242 void handleEvent(const Event
& event
)
244 for (stackIt
= stack
.begin(); stackIt
!= stack
.end(); ++stackIt
)
246 if ((*stackIt
)->handleEvent(event
)) break;
251 void push(LayerP layer
)
253 ASSERT(layer
&& "cannot push null layer");
254 stack
.push_front(layer
);
255 logInfo(" push: %d", stack
.size());
256 layer
->pushed(interface
);
262 if (stack
.begin() == stackIt
) fixIt
= true;
264 LayerP popped
= stack
.front();
266 logInfo(" pop: %d", stack
.size());
267 popped
->popped(interface
);
269 if (fixIt
) stackIt
= --stack
.begin();
274 LayerP
pop(Layer
* layer
)
278 std::list
<LayerP
> popped
;
280 std::list
<LayerP
>::iterator it
;
281 for (it
= stack
.begin(); it
!= stack
.end(); ++it
)
283 popped
.push_back(*it
);
285 if (it
== stackIt
) fixIt
= true;
287 if ((*it
).get() == layer
)
290 stack
.erase(stack
.begin(), it
);
292 for (it
= popped
.begin(); it
!= popped
.end(); ++it
)
294 (*it
)->popped(interface
);
297 if (fixIt
) stackIt
= --stack
.begin();
299 return popped
.back();
309 stackIt
= stack
.begin();
310 logInfo("clear: %d", stack
.size());
318 std::list
<LayerP
> stack
;
319 std::list
<LayerP
>::iterator stackIt
;
329 static Engine
* instance
= 0;
331 Engine::Engine(int argc
, char* argv
[], const std::string
& name
,
332 const std::string
& iconFile
, const std::string
& configFile
) :
333 impl_(new Engine::Impl(argc
, argv
, name
, iconFile
, configFile
, *this))
339 Engine
& Engine::getInstance()
341 ASSERT(instance
&& "dereferencing null pointer");
343 //static Engine engine;
353 void Engine::setTimestep(Scalar ts
)
355 impl_
->timestep
= ts
;
358 Scalar
Engine::getTimestep() const
360 return impl_
->timestep
;
363 void Engine::setMaxFrameRate(long maxFps
)
365 impl_
->drawRate
= 1.0 / Scalar(maxFps
);
368 long Engine::getMaxFrameRate() const
370 return long(1.0 / impl_
->drawRate
);
374 Video
& Engine::getVideo() const
376 return *impl_
->video
;
379 long Engine::getFrameRate() const
385 void Engine::push(LayerP layer
)
397 LayerP
Engine::pop(Layer
* layer
)
400 return impl_
->pop(layer
);
412 /** vim: set ts=4 sw=4 tw=80: *************************************************/
This page took 0.057505 seconds and 4 git commands to generate.