]>
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"
55 Impl(int argc
, char* argv
[], const std::string
& name
,
56 const std::string
& iconFile
, const std::string
& configFile
,
62 #if defined(_WIN32) || defined (_WIN64) || defined(__WIN32__)
63 if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_TIMER
) != 0)
65 if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_EVENTTHREAD
) != 0)
68 logError("sdl is complaining: %s", SDL_GetError());
69 throw Exception(Exception::SDL_ERROR
);
73 logError("fast events error: %s", FE_GetError());
74 throw Exception(Exception::SDL_ERROR
);
76 alutInit(&argc
, argv
);
78 Settings
& settings
= Settings::getInstance();
79 settings
.loadFromFile(configFile
);
80 settings
.parseArgs(argc
, argv
);
83 if (settings
.get("rngseed", randomSeed
)) setSeed(randomSeed
);
86 Scalar timestep
= 80.0;
87 settings
.get("timestep", timestep
);
88 mTimestep
= 1.0 / timestep
;
91 settings
.get("maxfps", maxFps
);
92 mDrawRate
= 1.0 / maxFps
;
94 settings
.get("printfps", mPrintFps
);
96 mVideo
= Video::alloc(name
, iconFile
);
102 // the video object must be destroyed before we can shutdown SDL
112 * The main loop. This just calls dispatchEvents(), update(), and draw()
113 * over and over again. The timing of the update and draw are decoupled.
114 * The actual frame rate is also calculated here. This function will return
115 * the exit code used to stop the loop.
120 Scalar ticksNow
= Timer::getTicks();
122 Scalar nextStep
= ticksNow
;
123 Scalar nextDraw
= ticksNow
;
124 Scalar nextFpsUpdate
= ticksNow
+ 1.0;
126 Scalar totalTime
= 0.0;
127 Scalar deltaTime
= 0.0;
128 Scalar accumulator
= mTimestep
;
135 Scalar newTicks
= Timer::getTicks();
136 deltaTime
= newTicks
- ticksNow
;
139 if (deltaTime
>= 0.25) deltaTime
= 0.25;
140 accumulator
+= deltaTime
;
142 Timer::fireIfExpired(ticksNow
);
144 while (accumulator
>= mTimestep
)
147 update(totalTime
, mTimestep
);
149 totalTime
+= mTimestep
;
150 accumulator
-= mTimestep
;
152 nextStep
+= mTimestep
;
154 if (ticksNow
>= nextStep
)
156 nextStep
= ticksNow
+ mTimestep
;
159 if (ticksNow
>= nextDraw
)
163 if (ticksNow
>= nextFpsUpdate
) // determine the actual fps
168 nextFpsUpdate
+= 1.0;
169 if (ticksNow
>= nextFpsUpdate
)
171 nextFpsUpdate
= ticksNow
+ 1.0;
176 logInfo("%d fps", mFps
);
180 draw(accumulator
/ mTimestep
);
183 nextDraw
+= mDrawRate
;
184 if (ticksNow
>= nextDraw
)
186 // we missed some scheduled draws, so reset the schedule
187 nextDraw
= ticksNow
+ mDrawRate
;
191 // be a good citizen and give back what you don't need
192 Timer::sleep(std::min(std::min(nextStep
, nextDraw
),
193 Timer::getNextFire()), true);
195 while (!mStack
.empty());
198 void dispatchEvents()
202 while (FE_PollEvent(&event
) == 1)
207 if (event
.key
.keysym
.sym
== SDLK_ESCAPE
&&
208 (SDL_GetModState() & KMOD_CTRL
) )
215 case SDL_VIDEORESIZE
:
216 mVideo
->resize(event
.resize
.w
, event
.resize
.h
);
225 void update(Scalar t
, Scalar dt
)
227 for (mStackIt
= mStack
.begin(); mStackIt
!= mStack
.end(); ++mStackIt
)
229 (*mStackIt
)->update(t
, dt
);
233 void draw(Scalar alpha
)
235 // FIXME - this will crash if the layer being drawn pops itself
236 std::list
<LayerP
>::reverse_iterator it
;
237 for (it
= mStack
.rbegin(); it
!= mStack
.rend(); ++it
)
243 void handleEvent(const Event
& event
)
245 for (mStackIt
= mStack
.begin(); mStackIt
!= mStack
.end(); ++mStackIt
)
247 if ((*mStackIt
)->handleEvent(event
)) break;
252 void push(LayerP layer
)
254 ASSERT(layer
&& "cannot push null layer");
255 mStack
.push_front(layer
);
256 logInfo(" push: %d", mStack
.size());
257 layer
->pushed(mInterface
);
263 if (mStack
.begin() == mStackIt
) fixIt
= true;
265 LayerP popped
= mStack
.front();
267 logInfo(" pop: %d", mStack
.size());
268 popped
->popped(mInterface
);
270 if (fixIt
) mStackIt
= --mStack
.begin();
275 LayerP
pop(Layer
* layer
)
279 std::list
<LayerP
> popped
;
281 std::list
<LayerP
>::iterator it
;
282 for (it
= mStack
.begin(); it
!= mStack
.end(); ++it
)
284 popped
.push_back(*it
);
286 if (it
== mStackIt
) fixIt
= true;
288 if ((*it
).get() == layer
)
291 mStack
.erase(mStack
.begin(), it
);
293 for (it
= popped
.begin(); it
!= popped
.end(); ++it
)
295 (*it
)->popped(mInterface
);
298 if (fixIt
) mStackIt
= --mStack
.begin();
300 return popped
.back();
310 mStackIt
= mStack
.begin();
311 logInfo("clear: %d", mStack
.size());
319 std::list
<LayerP
> mStack
;
320 std::list
<LayerP
>::iterator mStackIt
;
330 static Engine
* instance
= 0;
332 Engine::Engine(int argc
, char* argv
[], const std::string
& name
,
333 const std::string
& iconFile
, const std::string
& configFile
) :
334 mImpl(new Engine::Impl(argc
, argv
, name
, iconFile
, configFile
, *this))
340 Engine
& Engine::getInstance()
342 ASSERT(instance
&& "dereferencing null pointer");
344 // TODO this has not been completely thought out
345 //static Engine engine;
355 void Engine::setTimestep(Scalar ts
)
357 mImpl
->mTimestep
= ts
;
360 Scalar
Engine::getTimestep() const
362 return mImpl
->mTimestep
;
365 void Engine::setMaxFrameRate(long maxFps
)
367 mImpl
->mDrawRate
= 1.0 / Scalar(maxFps
);
370 long Engine::getMaxFrameRate() const
372 return long(1.0 / mImpl
->mDrawRate
);
376 Video
& Engine::getVideo() const
378 return *mImpl
->mVideo
;
381 long Engine::getFrameRate() const
387 void Engine::push(LayerP layer
)
399 LayerP
Engine::pop(Layer
* layer
)
402 return mImpl
->pop(layer
);
414 /** vim: set ts=4 sw=4 tw=80: *************************************************/
This page took 0.049923 seconds and 4 git commands to generate.