: screen(screen)
, states()
, last(SDL_GetTicks())
+, remaining(0)
, inStateChage(false) {
assert(initialState && "cannot create application without initial state");
RealPushState(initialState);
if (!CurrentState()) return;
input.ResetInteractiveState();
SDL_Event event;
- while (SDL_PollEvent(&event)) {
+ while (!StateChangePending() && SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
PopAllStates();
void Application::UpdateWorld(Uint32 deltaT) {
if (!CurrentState()) return;
- for (Uint32 i(0); i < deltaT && !StateChangePending(); ++i) {
- CurrentState()->PhysicsTimers().Update(1);
- CurrentState()->UpdateWorld(1);
+ remaining += deltaT;
+ Uint32 step = CurrentState()->Timestep();
+ if (step > 0) {
+ for (; remaining >= step && !StateChangePending(); remaining -= step) {
+ CurrentState()->PhysicsTimers().Update(step);
+ CurrentState()->UpdateWorld(step);
+ }
+ } else {
+ CurrentState()->PhysicsTimers().Update(deltaT);
+ CurrentState()->UpdateWorld(deltaT);
}
}
/// Draw a picture of the world.
virtual void Render(SDL_Surface *) = 0;
+ /// Number of milliseconds per simulation frame.
+ Uint32 Timestep() const { return timestep; }
+
protected:
/// Get a handle to the application this state is running on.
/// Do not call this while the state is off the stack (e.g. in c'tor/d'tor)
Application &Ctrl();
const Application &Ctrl() const;
+ /// Set the number of milliseconds per simulation frame.
+ void Timestep(Uint32 t) { timestep = t; }
+
private:
/// Do some setup that needs an application and/or screen handle and thus
/// can not be done by the constructor.
/// Adapt the state's graphics to given dimensions.
/// NOTE: currently, this is only called for the stack top and not
/// propagated on stack changes.
- /// Will be fixed soom ;).
+ /// Will be fixed sometime ;).
virtual void OnResize(int width, int height) = 0;
public:
/// Timers handle intended for graphics, sync'ed with render time.
/// These timers are only updated for the stack top and thus appear paused
- /// when the state is visible (roughly).
+ /// when the state is invisible (roughly).
Timers<Uint32> &GraphicsTimers() { return graphicsTimers; }
/// Timers handle intended for graphics, sync'ed with world time.
/// These timers are only updated for the stack top and thus appear paused
- /// when the state is visible (roughly).
+ /// when the state is invisible (roughly).
Timers<Uint32> &PhysicsTimers() { return physicsTimers; }
private:
Application *ctrl;
Timers<Uint32> graphicsTimers;
Timers<Uint32> physicsTimers;
+ Uint32 timestep;
};