diff --git Makefile Makefile index bc4e60017..7a7c003f5 100644 --- Makefile +++ Makefile @@ -91,7 +91,7 @@ ifdef OPTIMISE endif endif else - CFLAGS += -O + CFLAGS += -O0 endif ifdef DEBUG diff --git gui/simwin.cc gui/simwin.cc index ae71625a5..3f156b043 100644 --- gui/simwin.cc +++ gui/simwin.cc @@ -1530,7 +1530,7 @@ void win_poll_event(event_t* const ev) if( ev->ev_class==EVENT_SYSTEM && ev->ev_code==SYSTEM_RESIZE ) { // main window resized simgraph_resize( ev->size_x, ev->size_y ); - ticker::redraw_ticker(); + ticker::redraw(); wl->set_dirty(); wl->get_viewport()->metrics_updated(); ev->ev_class = EVENT_NONE; @@ -1551,7 +1551,7 @@ void win_poll_event(event_t* const ev) } wl->set_dirty(); ev->ev_class = EVENT_NONE; - ticker::redraw_ticker(); + ticker::redraw(); } if( ev->ev_class==EVENT_SYSTEM && ev->ev_code==SYSTEM_THEME_CHANGED ) { // called when font is changed @@ -1560,7 +1560,7 @@ void win_poll_event(event_t* const ev) i.gui->infowin_event(ev); } ev->ev_class = EVENT_NONE; - ticker::redraw_ticker(); + ticker::redraw(); } } @@ -1612,20 +1612,18 @@ void win_display_flush(double konto) display_set_clip_wh( 0, menu_height, disp_width, disp_height-menu_height+1 ); show_ticker = false; - if( !ticker::empty() ) { - ticker::draw(); - if (ticker::empty()) { - // set dirty background for removing ticker - if(wl) { - wl->set_background_dirty(); - } - } - else { - show_ticker = true; - // need to adapt tooltip_y coordinates - tooltip_ypos = min(tooltip_ypos, disp_height-15-10-16); + ticker::draw(); + if (ticker::empty()) { + // set dirty background for removing ticker + if(wl) { + wl->set_background_dirty(); } } + else { + show_ticker = true; + // need to adapt tooltip_y coordinates + tooltip_ypos = min(tooltip_ypos, disp_height-15-10-16); + } if( skinverwaltung_t::compass_iso && env_t::compass_screen_position ) { display_img_aligned( skinverwaltung_t::compass_iso->get_image_id( wl->get_settings().get_rotation() ), scr_rect(4,menu_height+4,disp_width-2*4,disp_height-menu_height-15-2*4-(TICKER_HEIGHT)*show_ticker), env_t::compass_screen_position, false ); diff --git simmesg.cc simmesg.cc index b110eca65..1b24f9fe8 100644 --- simmesg.cc +++ simmesg.cc @@ -82,7 +82,7 @@ void message_t::clear() while (!list.empty()) { delete list.remove_first(); } - ticker::clear_ticker(); + ticker::clear_messages(); } diff --git simticker.cc simticker.cc index d375d6511..41aa1152a 100644 --- simticker.cc +++ simticker.cc @@ -16,8 +16,8 @@ #include "gui/gui_frame.h" -// how much scrolling per call? -#define X_DIST 2 +#define X_DIST (2) // how much scrolling per update call? +#define X_SPACING (18) // spacing between messages, in pixels uint16 win_get_statusbar_height(); // simwin.h @@ -33,35 +33,33 @@ struct node { static slist_tpl list; -static koord default_pos = koord::invalid; -static bool redraw_all; // true, if also trigger background need redraw -static int next_pos; +static koord default_pos = koord::invalid; // world position of newest message +static bool redraw_all = false; //< true, if also trigger background need redraw +static int next_pos; //< Next x offset of new message. Always greater or equal to display_width +static int dx_since_last_draw = 0; //< Increased during update(); positive values move messages to the left bool ticker::empty() { - return list.empty(); + return list.empty(); } -void ticker::clear_ticker() +void ticker::clear_messages() { - if (!list.empty()) { - const int height = display_get_height(); - const int width = display_get_width(); - mark_rect_dirty_wc(0, height-TICKER_YPOS_BOTTOM, width, height); - } list.clear(); + set_redraw_all(true); } -void ticker::set_redraw_all(const bool b) + +void ticker::set_redraw_all(bool redraw) { - redraw_all=b; + redraw_all = redraw; } + void ticker::add_msg(const char* txt, koord pos, FLAGGED_PIXVAL color) { - // don't store more than 4 messages, it's useless. const int count = list.get_count(); if(count==0) { @@ -70,38 +68,40 @@ void ticker::add_msg(const char* txt, koord pos, FLAGGED_PIXVAL color) default_pos = koord::invalid; } - if(count < 4) { - // Don't repeat messages - if (count == 0 || !strstart(list.back().msg, txt)) { - node n; - int i=0; - - // remove breaks - for( int j=0; i<250 && txt[j]!=0; j++ ) { - if( txt[j]=='\n' ) { - if( i==0 || n.msg[i-1]==' ' ) { - continue; - } - n.msg[i++] = ' '; + // don't store more than 4 messages, it's useless. + if(count >= 4) { + return; + } + // Don't repeat messages + else if (count == 0 || !strstart(list.back().msg, txt)) { + node n; + int i=0; + + // remove breaks + for( int j=0; i<250 && txt[j]!=0; j++ ) { + if( txt[j]=='\n' ) { + if( i==0 || n.msg[i-1]==' ' ) { + continue; } - else { - if( txt[j]==' ' && (i==0 || n.msg[i-1]==' ') ) { - // avoid double or leading spaces - continue; - } - n.msg[i++] = txt[j]; + n.msg[i++] = ' '; + } + else { + if( txt[j]==' ' && (i==0 || n.msg[i-1]==' ') ) { + // avoid double or leading spaces + continue; } + n.msg[i++] = txt[j]; } - n.msg[i++] = 0; + } + n.msg[i++] = 0; - n.pos = pos; - n.color = color; - n.xpos = next_pos; - n.w = proportional_string_width(n.msg); + n.pos = pos; + n.color = color; + n.xpos = next_pos; + n.w = proportional_string_width(n.msg); - next_pos += n.w + 18; - list.append(n); - } + next_pos += n.w + X_SPACING; + list.append(n); } } @@ -112,71 +112,89 @@ koord ticker::get_welt_pos() } -void ticker::draw() +void ticker::update() { - TICKER_YPOS_BOTTOM = TICKER_HEIGHT + win_get_statusbar_height(); + const int dx = X_DIST; + const int display_width = display_get_width(); - if (!list.empty()) { + FOR(slist_tpl, & n, list) { + n.xpos -= dx; - const int start_y=display_get_height()-TICKER_YPOS_BOTTOM; - const int width = display_get_width(); - - // redraw whole ticker - if(redraw_all) { - redraw_ticker(); - } - // redraw ticker partially - else { - display_scroll_band( start_y+1, X_DIST, TICKER_HEIGHT-1 ); - display_fillbox_wh_rgb(width-X_DIST-6, start_y+1, X_DIST+6, TICKER_HEIGHT-1, SYSCOL_TICKER_BACKGROUND, true); - // ok, ready for the text - PUSH_CLIP( 0, start_y + 1, width - 1, TICKER_HEIGHT-1 ); - FOR(slist_tpl, & n, list) { - n.xpos -= X_DIST; - if (n.xpos < width) { - display_proportional_clip_rgb(n.xpos, start_y + 2, n.msg, ALIGN_LEFT, n.color, true); - default_pos = n.pos; - } - } - POP_CLIP(); + if (n.xpos < display_width) { + default_pos = n.pos; } + } - // remove old news - while (!list.empty() && list.front().xpos + list.front().w < 0) { - list.remove_first(); - } - if (list.empty()) { - // old: mark_rect_dirty_wc(0, start_y, width, start_y + TICKER_HEIGHT); - // now everything at the bottom to clear also tooltips and compass - mark_rect_dirty_wc(0, start_y-128, width, start_y + 128 +TICKER_HEIGHT); - } - if(next_pos>width) { - next_pos -= X_DIST; - } + dx_since_last_draw += dx; + next_pos = std::max(next_pos - dx, display_width); - redraw_all = false; + // remove old news + while (!list.empty() && list.front().xpos + list.front().w < 0) { + list.remove_first(); } -} + if (list.empty()) { + set_redraw_all(true); + } +} -// complete redraw (after resizing) -void ticker::redraw_ticker() +void ticker::draw() { + if (redraw_all) { + redraw(); + return; + } + else if (list.empty()) { + // ticker not visible + return; + } + TICKER_YPOS_BOTTOM = TICKER_HEIGHT + win_get_statusbar_height(); - if (!list.empty()) { + const int start_y=display_get_height()-TICKER_YPOS_BOTTOM; + const int width = display_get_width(); + + // do partial redraw + display_scroll_band( start_y+1, dx_since_last_draw, TICKER_HEIGHT-1 ); + display_fillbox_wh_rgb(width-dx_since_last_draw-6, start_y+1, dx_since_last_draw+6, TICKER_HEIGHT-1, SYSCOL_TICKER_BACKGROUND, true); + + // ok, ready for the text + PUSH_CLIP( 0, start_y + 1, width - 1, TICKER_HEIGHT-1 ); + FOR(slist_tpl, & n, list) { + if (n.xpos < width) { + display_proportional_clip_rgb(n.xpos, start_y + 2, n.msg, ALIGN_LEFT, n.color, true); + } + } + POP_CLIP(); + + dx_since_last_draw = 0; +} + + +void ticker::redraw() +{ + set_redraw_all(false); + dx_since_last_draw = 0; + + if (list.empty()) { const int start_y=display_get_height()-TICKER_YPOS_BOTTOM; - const int width = display_get_width(); - - // just draw the ticker in its colour ... (to be sure ... ) - display_fillbox_wh_rgb(0, start_y+1, width, TICKER_HEIGHT-1, SYSCOL_TICKER_BACKGROUND, true); - FOR(slist_tpl, & n, list) { - n.xpos -= X_DIST; - if (n.xpos < width) { - display_proportional_clip_rgb(n.xpos, start_y + 2, n.msg, ALIGN_LEFT, n.color, true); - default_pos = n.pos; - } + + // mark everything at the bottom as dirty to clear also tooltips and compass + mark_rect_dirty_wc(0, start_y-128, display_get_width(), start_y + 128 +TICKER_HEIGHT); + return; + } + + TICKER_YPOS_BOTTOM = TICKER_HEIGHT + win_get_statusbar_height(); + + const int start_y=display_get_height()-TICKER_YPOS_BOTTOM; + const int width = display_get_width(); + + // just draw the ticker in its colour ... (to be sure ... ) + display_fillbox_wh_rgb(0, start_y+1, width, TICKER_HEIGHT-1, SYSCOL_TICKER_BACKGROUND, true); + FOR(slist_tpl, & n, list) { + if (n.xpos < width) { + display_proportional_clip_rgb(n.xpos, start_y + 2, n.msg, ALIGN_LEFT, n.color, true); } } } diff --git simticker.h simticker.h index 1eb0bb136..fcaed253d 100644 --- simticker.h +++ simticker.h @@ -20,8 +20,7 @@ extern uint16 TICKER_YPOS_BOTTOM; class koord; /** - * A very simple news ticker. - * The news are displayed by karte_vollansicht_t + * A very simple scrolling news ticker. */ namespace ticker { @@ -35,26 +34,35 @@ namespace ticker void add_msg(const char*, koord pos, FLAGGED_PIXVAL color = color_idx_to_rgb(COL_BLACK)); /** - * Ticker infowin pops up + * Remove all messages and mark for redraw + */ + void clear_messages(); + + /** + * @returns the 2D world position of the most recent visible message */ koord get_welt_pos(); /** - * Ticker redraw + * Update message positions and remove old messages */ - void draw(); + void update(); /** - * Set true if ticker has to be redrawn + * Redraw the ticker partially or fully (if set_redraw_all() was called) */ - void set_redraw_all(const bool); + void draw(); /** - * Ticker text redraw after resize + * Set true if ticker has to be redrawn fully + * @sa redraw */ - void redraw_ticker(); + void set_redraw_all(bool redraw); - void clear_ticker(); + /** + * Force a ticker redraw (e.g. after a window resize) + */ + void redraw(); }; #endif diff --git simworld.cc simworld.cc index d00ead2d3..6fe4f5057 100644 --- simworld.cc +++ simworld.cc @@ -3524,6 +3524,8 @@ void karte_t::sync_step(uint32 delta_t, bool do_sync_step, bool display ) clear_random_mode( INTERACTIVE_RANDOM ); sync.sync_step( delta_t ); + + ticker::update(); } if(display) {