widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #06112
[Merge] lp:~widelands-dev/widelands/lock_game_logic into lp:widelands
SirVer has proposed merging lp:~widelands-dev/widelands/lock_game_logic into lp:widelands.
Commit message:
Decouples UI update frequency from game update frequency (which is now 15 times per second).
Requested reviews:
Widelands Developers (widelands-dev)
Related bugs:
Bug #1545098 in widelands: "Desync in bzr7818[trunk] "
https://bugs.launchpad.net/widelands/+bug/1545098
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/lock_game_logic/+merge/285980
This is a hacky-hack. The game logic should not be driven by the UI, but that is such a fundamental design in Widelands that I am not sure if we can ever pull that apart.
For now, this should fix desyncs, I could not reproduce them on my system anymore.
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/lock_game_logic into lp:widelands.
=== modified file 'src/economy/request.cc'
--- src/economy/request.cc 2016-02-07 06:10:47 +0000
+++ src/economy/request.cc 2016-02-13 19:22:05 +0000
@@ -351,7 +351,7 @@
economy_->remove_request(*this);
economy_ = e;
if (economy_ && is_open())
- economy_-> add_request(*this);
+ economy_->add_request(*this);
}
}
=== modified file 'src/ui_basic/panel.cc'
--- src/ui_basic/panel.cc 2016-02-07 16:31:06 +0000
+++ src/ui_basic/panel.cc 2016-02-13 19:22:05 +0000
@@ -148,41 +148,53 @@
// Panel-specific startup code. This might call end_modal()!
start();
- const uint32_t minimum_frame_time =
+ // think() is called at most 15 times per second.
+ const uint32_t kGameLogicDelay = 1000 / 15;
+
+ const uint32_t draw_delay =
1000 / std::max(5, g_options.pull_section("global").get_int("maxfps", 30));
+ static InputCallback input_callback = {
+ Panel::ui_mousepress,
+ Panel::ui_mouserelease,
+ Panel::ui_mousemove,
+ Panel::ui_key,
+ Panel::ui_textinput,
+ Panel::ui_mousewheel
+ };
+
+ uint32_t next_think_time = SDL_GetTicks() + kGameLogicDelay;
+ uint32_t next_draw_time = SDL_GetTicks() + draw_delay;
while (_running) {
- const uint32_t startTime = SDL_GetTicks();
-
- static InputCallback icb = {
- Panel::ui_mousepress,
- Panel::ui_mouserelease,
- Panel::ui_mousemove,
- Panel::ui_key,
- Panel::ui_textinput,
- Panel::ui_mousewheel
- };
-
- app->handle_input(&icb);
- if (app->should_die())
- end_modal<Returncodes>(Returncodes::kBack);
-
- do_think();
-
- RenderTarget& rt = *g_gr->get_render_target();
- forefather->do_draw(rt);
- rt.blit(app->get_mouse_position() - Point(3, 7),
- WLApplication::get()->is_mouse_pressed() ? s_default_cursor_click : s_default_cursor);
- forefather->do_tooltip();
- g_gr->refresh();
-
- if (_flags & pf_child_die)
- check_child_death();
-
- // Wait until 1second/maxfps are over.
- const uint32_t frame_time = SDL_GetTicks() - startTime;
- if (frame_time < minimum_frame_time) {
- SDL_Delay(minimum_frame_time - frame_time);
+ const uint32_t start_time = SDL_GetTicks();
+
+ app->handle_input(&input_callback);
+
+ if (start_time >= next_think_time) {
+ if (app->should_die())
+ end_modal<Returncodes>(Returncodes::kBack);
+
+ do_think();
+
+ if (_flags & pf_child_die)
+ check_child_death();
+ next_think_time = start_time + kGameLogicDelay;
+ }
+
+ if (start_time >= next_draw_time) {
+ RenderTarget& rt = *g_gr->get_render_target();
+ forefather->do_draw(rt);
+ rt.blit(app->get_mouse_position() - Point(3, 7), WLApplication::get()->is_mouse_pressed() ?
+ s_default_cursor_click :
+ s_default_cursor);
+ forefather->do_tooltip();
+ g_gr->refresh();
+ next_draw_time = start_time + draw_delay;
+ }
+
+ int32_t delay = std::min<int32_t>(next_draw_time, next_think_time) - SDL_GetTicks();
+ if (delay > 0) {
+ SDL_Delay(delay);
}
}
end();
=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc 2016-02-01 11:46:58 +0000
+++ src/wui/interactive_base.cc 2016-02-13 19:22:05 +0000
@@ -307,13 +307,6 @@
*/
void InteractiveBase::think()
{
- // Timing
- uint32_t curframe = SDL_GetTicks();
-
- frametime_ = curframe - lastframe_;
- avg_usframetime_ = ((avg_usframetime_ * 15) + (frametime_ * 1000)) / 16;
- lastframe_ = curframe;
-
// If one of the arrow keys is pressed, scroll here
const uint32_t scrollval = 10;
@@ -347,6 +340,13 @@
===============
*/
void InteractiveBase::draw_overlay(RenderTarget& dst) {
+ // Timing
+ uint32_t curframe = SDL_GetTicks();
+
+ frametime_ = curframe - lastframe_;
+ avg_usframetime_ = ((avg_usframetime_ * 15) + (frametime_ * 1000)) / 16;
+ lastframe_ = curframe;
+
const Map & map = egbase().map();
const bool is_game = dynamic_cast<const Game*>(&egbase());
Follow ups