From a016a156e76f7394c5632da325ab0b453cfb3b37 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Mon, 26 Mar 2018 14:19:50 +0200 Subject: Independent game timing. --- src/game/game.cpp | 65 ++++++++++++++++++++++++++++++++++---------------- src/game/interface.cpp | 16 +++++++++---- 2 files changed, 57 insertions(+), 24 deletions(-) (limited to 'src/game') diff --git a/src/game/game.cpp b/src/game/game.cpp index f76b478..44ea95d 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -92,6 +92,8 @@ void state_t::start(void) soldier = new unit_soldier_t(this); soldier->place(&world, v2f_t(2.5, 0.5)); select(rectf_t(v2f_t(0.5, 0.5), v2f_t(2.5, 0.5))); + + resume(); } void state_t::stop(void) @@ -179,34 +181,57 @@ void state_t::spawn_soldier(v2f_t x) soldier->destroy(); } -void state_t::tick(double now_, double dt_) +void state_t::pause(void) +{ + paused = true; +} + +void state_t::resume(void) +{ + t0 = nclock(); + frames_since_t0 = 0; + + paused = false; +} + + +#define TIME_DELTA ((ntime_t)1000000000 / 60) + +void state_t::tick(ntime_t time_) { - union { - double d; - uint32_t i; - } u; + size_t target, frames_this_tick = 0; if (paused) return; - if (dt > 0.05) - dt = 0.05; - else - dt = dt_; + target = (time_ - t0) / TIME_DELTA; + + while (frames_since_t0 < target) { + // FIXME: Is this non-deterministic enough? + dice_prng.seed(dice_prng.next() ^ time); - now += dt; + // setting up old variables (refactor them out eventually) + now = time * 1.0e-9; + dt = TIME_DELTA * 1.0e-9; - // FIXME: Is this non-deterministic enough? - u.d = now; - dice_prng.seed(dice_prng.next() ^ u.i); - u.d = dt; - dice_prng.seed(dice_prng.next() ^ u.i); + // on_think can insert/erase elements of awake_entities so iterate + // over a copy of it. + auto copy = awake_entities; + for (entity_t *ent : copy) + ent->on_think(); - // on_think can insert/erase elements of awake_entities so iterate - // over a copy of it. - auto copy = awake_entities; - for (entity_t *ent : copy) - ent->on_think(); + frames++; + frames_since_t0++; + frames_this_tick++; + time += TIME_DELTA; + + if (frames_this_tick == 3) { + t0 = time_; + frames_since_t0 = 0; + frames_behind++; + break; + } + } } die_t::die_t(size_t sides_) diff --git a/src/game/interface.cpp b/src/game/interface.cpp index 7697a22..262c3ae 100644 --- a/src/game/interface.cpp +++ b/src/game/interface.cpp @@ -160,11 +160,13 @@ void state_t::tick(double dt) case sf::Event::KeyPressed: switch (event.key.code) { case sf::Keyboard::Key::Space: - game->paused ^= 1; - if (game->paused) + if (!game->paused) { + game->pause(); print(text::get(text::PAUSED)); - else + } else { + game->resume(); print(text::get(text::UNPAUSED)); + } break; case sf::Keyboard::Key::F: @@ -239,7 +241,7 @@ void state_t::render_to(render::state_t *render) x[1] += em; } - x = v2f_t(0.0f, h - em * 4.5); + x = v2f_t(0.0f, h - em * 5.5); ss << "World S/T:"; ss << game->world.stats.sectors << "/"; ss << game->world.stats.tiles; @@ -271,6 +273,12 @@ void state_t::render_to(render::state_t *render) ss << std::fixed << std::setprecision(1); ss << "FPS: " << fps; render->render_text(x, em, ss.str(), render::ALIGN_LEFT_TOP, sf::Color::White); + + x[1] += em; + ss.str(std::string()); + ss << std::fixed << std::setprecision(3); + ss << "Game t/F/B: " << game->time * 1.0e-9 << "/" << game->frames << "/" << game->frames_behind; + render->render_text(x, em, ss.str(), render::ALIGN_LEFT_TOP, sf::Color::White); } } // namespace interface -- cgit