diff --git a/src/controller_base.cpp b/src/controller_base.cpp index b9f93807f364..f455f65d53ba 100644 --- a/src/controller_base.cpp +++ b/src/controller_base.cpp @@ -31,7 +31,8 @@ static lg::log_domain log_display("display"); controller_base::controller_base( const config& game_config, CVideo& /*video*/) - : game_config_(game_config) + : draw_layering(false) + , game_config_(game_config) , key_() , scrolling_(false) , scroll_up_(false) diff --git a/src/editor/controller/editor_controller.cpp b/src/editor/controller/editor_controller.cpp index 060ae6e2c5f8..874ad6f79328 100644 --- a/src/editor/controller/editor_controller.cpp +++ b/src/editor/controller/editor_controller.cpp @@ -85,6 +85,8 @@ editor_controller::editor_controller(const config &game_config, CVideo& video) get_current_map_context().set_starting_position_labels(gui()); cursor::set(cursor::NORMAL); + join(); + gui().create_buttons(); gui().redraw_everything(); events::raise_draw_event(); diff --git a/src/events.cpp b/src/events.cpp index 7c91cecbff99..fce172764c08 100644 --- a/src/events.cpp +++ b/src/events.cpp @@ -402,6 +402,54 @@ static bool remove_on_resize(const SDL_Event& a) return false; } +/** + * The interval between draw events. + * + * When the window is shown this value is set, the callback function always + * uses this value instead of the parameter send, that way the window can stop + * drawing when it wants. + */ +static int draw_interval = 0; + +SDL_TimerID draw_timer_id; + +/** + * SDL_AddTimer() callback for the draw event. + * + * When this callback is called it pushes a new draw event in the event queue. + * + * @returns The new timer interval, 0 to stop. + */ +static Uint32 draw_timer(Uint32, void*) +{ + // DBG_GUI_E << "Pushing draw event in queue.\n"; + + SDL_Event event; + SDL_UserEvent data; + + data.type = DRAW_EVENT; + data.code = 0; + data.data1 = NULL; + data.data2 = NULL; + + event.type = DRAW_EVENT; + event.user = data; + + SDL_PushEvent(&event); + return draw_interval; +} + +void initialise() +{ + draw_interval = 20; + draw_timer_id = SDL_AddTimer(draw_interval, draw_timer, NULL); +} + +void finalize() +{ + SDL_RemoveTimer(draw_timer_id); +} + // TODO: I'm uncertain if this is always safe to call at static init; maybe set in main() instead? static const boost::thread::id main_thread = boost::this_thread::get_id(); @@ -610,6 +658,12 @@ void pump() } } + const bool is_draw_event = event.type == DRAW_EVENT || event.type == DRAW_ALL_EVENT; + + if(is_draw_event) { + CVideo::get_singleton().clear_screen(); + } + for(auto global_handler : event_contexts.front().handlers) { global_handler->handle_event(event); } @@ -619,6 +673,10 @@ void pump() handler->handle_event(event); } } + + if(is_draw_event) { + CVideo::get_singleton().render_screen(); + } } // Inform the pump monitors that an events::pump() has occurred diff --git a/src/events.hpp b/src/events.hpp index 7c6815176c7f..79518befa285 100644 --- a/src/events.hpp +++ b/src/events.hpp @@ -151,6 +151,9 @@ class pump_monitor { virtual void process(pump_info& info) = 0; }; +void initialise(); +void finalize(); + void raise_process_event(); void raise_resize_event(); void raise_draw_event(); diff --git a/src/gui/core/event/handler.cpp b/src/gui/core/event/handler.cpp index bcc0da171120..ffc8020b6859 100644 --- a/src/gui/core/event/handler.cpp +++ b/src/gui/core/event/handler.cpp @@ -532,13 +532,6 @@ void sdl_event_handler::draw(const bool /*force*/) return; } - CVideo& video = dynamic_cast(*dispatchers_.back()).video(); - - /** - * Clear the renderer before beginning the draw cycle. - */ - video.clear_screen(); - /** * @todo Need to evaluate which windows really to redraw. * @@ -548,9 +541,6 @@ void sdl_event_handler::draw(const bool /*force*/) { dispatcher->fire(DRAW, dynamic_cast(*dispatcher)); } - - // Finally, render the screen. - video.render_screen(); } void sdl_event_handler::video_resize(const point& new_size) diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp index 4bf0f06b3513..bd9f7c829b8d 100644 --- a/src/gui/widgets/window.cpp +++ b/src/gui/widgets/window.cpp @@ -110,46 +110,11 @@ namespace const unsigned SHOW = debug_layout_graph::SHOW; const unsigned LAYOUT = debug_layout_graph::LAYOUT; #else -// values are irrelavant when DEBUG_WINDOW_LAYOUT_GRAPHS is not defined. +// values are irrelevant when DEBUG_WINDOW_LAYOUT_GRAPHS is not defined. const unsigned SHOW = 0; const unsigned LAYOUT = 0; #endif -/** - * The interval between draw events. - * - * When the window is shown this value is set, the callback function always - * uses this value instead of the parameter send, that way the window can stop - * drawing when it wants. - */ -static int draw_interval = 0; - -/** - * SDL_AddTimer() callback for the draw event. - * - * When this callback is called it pushes a new draw event in the event queue. - * - * @returns The new timer interval, 0 to stop. - */ -static Uint32 draw_timer(Uint32, void*) -{ - // DBG_GUI_E << "Pushing draw event in queue.\n"; - - SDL_Event event; - SDL_UserEvent data; - - data.type = DRAW_EVENT; - data.code = 0; - data.data1 = nullptr; - data.data2 = nullptr; - - event.type = DRAW_EVENT; - event.user = data; - - SDL_PushEvent(&event); - return draw_interval; -} - /** * SDL_AddTimer() callback for delay_event. * @@ -461,23 +426,21 @@ void window::update_screen_size() { // Only if we're the toplevel window we need to update the size, otherwise // it's done in the resize event. - if(draw_interval == 0) { - const SDL_Rect rect = screen_area(); - settings::screen_width = rect.w; - settings::screen_height = rect.h; - - settings::gamemap_width = settings::screen_width; - settings::gamemap_height = settings::screen_height; - - display* display = display::get_singleton(); - if(display) { - const SDL_Rect rect_gm = display->map_outside_area(); - - if(rect_gm.w && rect_gm.h) { - settings::gamemap_width = rect_gm.w; - settings::gamemap_height = rect_gm.h; - settings::gamemap_x_offset = rect_gm.x; - } + const SDL_Rect rect = screen_area(); + settings::screen_width = rect.w; + settings::screen_height = rect.h; + + settings::gamemap_width = settings::screen_width; + settings::gamemap_height = settings::screen_height; + + display* display = display::get_singleton(); + if(display) { + const SDL_Rect rect_gm = display->map_outside_area(); + + if(rect_gm.w && rect_gm.h) { + settings::gamemap_width = rect_gm.w; + settings::gamemap_height = rect_gm.h; + settings::gamemap_x_offset = rect_gm.x; } } } @@ -559,44 +522,12 @@ int window::show(const bool /*restore*/, const unsigned auto_close_timeout) show_mode_ = modal; - /** - * Helper class to set and restore the drawing interval. - * - * We need to make sure we restore the value when the function ends, be it - * normally or due to an exception. - */ - class draw_interval_setter - { - public: - draw_interval_setter() : interval_(draw_interval) - { - if(interval_ == 0) { - draw_interval = 20; - SDL_AddTimer(draw_interval, draw_timer, nullptr); - - // There might be some time between creation and showing so - // reupdate the sizes. - update_screen_size(); - } - } - - ~draw_interval_setter() - { - draw_interval = interval_; - } - - private: - int interval_; - }; - log_scope2(log_gui_draw, LOG_SCOPE_HEADER); generate_dot_file("show", SHOW); assert(status_ == NEW); - draw_interval_setter draw_interval_setter; - /* * Before show has been called, some functions might have done some testing * on the window and called layout, which can give glitches. So diff --git a/src/wesnoth.cpp b/src/wesnoth.cpp index fa92fa5d7256..180e6b51f6cf 100644 --- a/src/wesnoth.cpp +++ b/src/wesnoth.cpp @@ -616,12 +616,17 @@ static int do_gameloop(const std::vector& args) return 1; } + events::initialise(); + events::pump(); + res = image::update_from_preferences(); if(res == false) { std::cerr << "could not initialize image preferences\n"; return 1; } + events::pump(); + if(preferences::joystick_support_enabled()) { res = game->init_joystick(); if(res == false) { @@ -633,6 +638,8 @@ static int do_gameloop(const std::vector& args) const cursor::manager cursor_manager; cursor::set(cursor::WAIT); + events::pump(); + #if (defined(_X11) && !defined(__APPLE__)) || defined(_WIN32) SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); #endif