src/news_gui.cpp
changeset 10301 bae9252dd4c6
parent 10273 248661824a1e
child 10410 126c3c59ea05
equal deleted inserted replaced
10298:0a4a98c78137 10301:bae9252dd4c6
    14 #include "date_func.h"
    14 #include "date_func.h"
    15 #include "vehicle_base.h"
    15 #include "vehicle_base.h"
    16 #include "sound_func.h"
    16 #include "sound_func.h"
    17 #include "string_func.h"
    17 #include "string_func.h"
    18 #include "widgets/dropdown_func.h"
    18 #include "widgets/dropdown_func.h"
       
    19 #include "map_func.h"
    19 
    20 
    20 #include "table/sprites.h"
    21 #include "table/sprites.h"
    21 #include "table/strings.h"
    22 #include "table/strings.h"
    22 
    23 
    23 /** @file news_gui.cpp
    24 /** @file news_gui.cpp
    43  * This is where we have wrapped around the array and have
    44  * This is where we have wrapped around the array and have
    44  * (MAX_NEWS - O) + L news items
    45  * (MAX_NEWS - O) + L news items
    45  * \endverbatim
    46  * \endverbatim
    46  */
    47  */
    47 
    48 
    48 /** Number of news items in the FIFO queue */
       
    49 #define MAX_NEWS 30
       
    50 #define NB_WIDG_PER_SETTING 4
    49 #define NB_WIDG_PER_SETTING 4
    51 
    50 
    52 typedef byte NewsID;
    51 typedef byte NewsID;
    53 #define INVALID_NEWS 255
    52 #define INVALID_NEWS 255
    54 
    53 
    55 NewsItem _statusbar_news_item;
    54 NewsItem _statusbar_news_item;
    56 bool _news_ticker_sound;
    55 bool _news_ticker_sound;
    57 static NewsItem _news_items[MAX_NEWS];      ///< The news FIFO queue
    56 static NewsItem *_news_items = NULL;        ///< The news FIFO queue
       
    57 static uint _max_news_items = 0;            ///< size of news FIFO queue
    58 static NewsID _current_news = INVALID_NEWS; ///< points to news item that should be shown next
    58 static NewsID _current_news = INVALID_NEWS; ///< points to news item that should be shown next
    59 static NewsID _oldest_news = 0;             ///< points to first item in fifo queue
    59 static NewsID _oldest_news = 0;             ///< points to first item in fifo queue
    60 static NewsID _latest_news = INVALID_NEWS;  ///< points to last item in fifo queue
    60 static NewsID _latest_news = INVALID_NEWS;  ///< points to last item in fifo queue
    61 
    61 
    62 struct news_d : vp_d {
    62 struct news_d : vp_d {
    73  * Users can force an item by accessing the history or "last message".
    73  * Users can force an item by accessing the history or "last message".
    74  * If the message being shown was forced by the user, its index is stored in
    74  * If the message being shown was forced by the user, its index is stored in
    75  * _forced_news. Otherwise, \a _forced_news variable is INVALID_NEWS. */
    75  * _forced_news. Otherwise, \a _forced_news variable is INVALID_NEWS. */
    76 static NewsID _forced_news = INVALID_NEWS;
    76 static NewsID _forced_news = INVALID_NEWS;
    77 
    77 
    78 static byte _total_news = 0; ///< Number of news items in FIFO queue @see _news_items
    78 static uint _total_news = 0; ///< Number of news items in FIFO queue @see _news_items
    79 
    79 
    80 void DrawNewsNewVehicleAvail(Window *w, const NewsItem *ni);
    80 void DrawNewsNewVehicleAvail(Window *w, const NewsItem *ni);
    81 void DrawNewsBankrupcy(Window *w, const NewsItem *ni);
    81 void DrawNewsBankrupcy(Window *w, const NewsItem *ni);
    82 static void MoveToNextItem();
    82 static void MoveToNextItem();
    83 
    83 
    96 };
    96 };
    97 
    97 
    98 /** Initialize the news-items data structures */
    98 /** Initialize the news-items data structures */
    99 void InitNewsItemStructs()
    99 void InitNewsItemStructs()
   100 {
   100 {
   101 	memset(_news_items, 0, sizeof(_news_items));
   101 	free(_news_items);
       
   102 	_max_news_items = max(ScaleByMapSize(30), 30U);
       
   103 	_news_items = CallocT<NewsItem>(_max_news_items);
   102 	_current_news = INVALID_NEWS;
   104 	_current_news = INVALID_NEWS;
   103 	_oldest_news = 0;
   105 	_oldest_news = 0;
   104 	_latest_news = INVALID_NEWS;
   106 	_latest_news = INVALID_NEWS;
   105 	_forced_news = INVALID_NEWS;
   107 	_forced_news = INVALID_NEWS;
   106 	_total_news = 0;
   108 	_total_news = 0;
   243  * queue and deals with overflows when increasing the index
   245  * queue and deals with overflows when increasing the index
   244  */
   246  */
   245 static inline NewsID IncreaseIndex(NewsID i)
   247 static inline NewsID IncreaseIndex(NewsID i)
   246 {
   248 {
   247 	assert(i != INVALID_NEWS);
   249 	assert(i != INVALID_NEWS);
   248 	return (i + 1) % MAX_NEWS;
   250 	return (i + 1) % _max_news_items;
   249 }
   251 }
   250 
   252 
   251 /**
   253 /**
   252  * Return the correct index in the pseudo-fifo
   254  * Return the correct index in the pseudo-fifo
   253  * queue and deals with overflows when decreasing the index
   255  * queue and deals with overflows when decreasing the index
   254  */
   256  */
   255 static inline NewsID DecreaseIndex(NewsID i)
   257 static inline NewsID DecreaseIndex(NewsID i)
   256 {
   258 {
   257 	assert(i != INVALID_NEWS);
   259 	assert(i != INVALID_NEWS);
   258 	return (i + MAX_NEWS - 1) % MAX_NEWS;
   260 	return (i + _max_news_items - 1) % _max_news_items;
   259 }
   261 }
   260 
   262 
   261 /**
   263 /**
   262  * Add a new newsitem to be shown.
   264  * Add a new newsitem to be shown.
   263  * @param string String to display, can have special values based on parameter \a display_mode
   265  * @param string String to display, can have special values based on parameter \a display_mode
   285 void AddNewsItem(StringID string, NewsMode display_mode, NewsFlag flags, NewsType type, NewsCallback callback, uint data_a, uint data_b)
   287 void AddNewsItem(StringID string, NewsMode display_mode, NewsFlag flags, NewsType type, NewsCallback callback, uint data_a, uint data_b)
   286 {
   288 {
   287 	if (_game_mode == GM_MENU) return;
   289 	if (_game_mode == GM_MENU) return;
   288 
   290 
   289 	/* check the rare case that the oldest (to be overwritten) news item is open */
   291 	/* check the rare case that the oldest (to be overwritten) news item is open */
   290 	if (_total_news == MAX_NEWS && (_oldest_news == _current_news || _oldest_news == _forced_news)) {
   292 	if (_total_news == _max_news_items && (_oldest_news == _current_news || _oldest_news == _forced_news)) {
   291 		MoveToNextItem();
   293 		MoveToNextItem();
   292 	}
   294 	}
   293 
   295 
   294 	if (_total_news < MAX_NEWS) _total_news++;
   296 	if (_total_news < _max_news_items) _total_news++;
   295 
   297 
   296 	/* Increase _latest_news. If we have no news yet, use _oldest news as an
   298 	/* Increase _latest_news. If we have no news yet, use _oldest news as an
   297 	 * index. We cannot use 0 as _oldest_news can jump around due to
   299 	 * index. We cannot use 0 as _oldest_news can jump around due to
   298 	 * DeleteVehicleNews */
   300 	 * DeleteVehicleNews */
   299 	NewsID l_news = _latest_news;
   301 	NewsID l_news = _latest_news;
   300 	_latest_news = (_latest_news == INVALID_NEWS) ? _oldest_news : IncreaseIndex(_latest_news);
   302 	_latest_news = (_latest_news == INVALID_NEWS) ? _oldest_news : IncreaseIndex(_latest_news);
   301 
   303 
   302 	/* If the fifo-buffer is full, overwrite the oldest entry */
   304 	/* If the fifo-buffer is full, overwrite the oldest entry */
   303 	if (l_news != INVALID_NEWS && _latest_news == _oldest_news) {
   305 	if (l_news != INVALID_NEWS && _latest_news == _oldest_news) {
   304 		assert(_total_news == MAX_NEWS);
   306 		assert(_total_news == _max_news_items);
   305 		_oldest_news = IncreaseIndex(_oldest_news);
   307 		_oldest_news = IncreaseIndex(_oldest_news);
   306 	}
   308 	}
   307 
   309 
   308 	/*DEBUG(misc, 0, "+cur %3d, old %2d, lat %3d, for %3d, tot %2d",
   310 	/*DEBUG(misc, 0, "+cur %3d, old %2d, lat %3d, for %3d, tot %2d",
   309 	  _current_news, _oldest_news, _latest_news, _forced_news, _total_news);*/
   311 	  _current_news, _oldest_news, _latest_news, _forced_news, _total_news);*/
   465  */
   467  */
   466 static bool ReadyForNextItem()
   468 static bool ReadyForNextItem()
   467 {
   469 {
   468 	NewsID item = (_forced_news == INVALID_NEWS) ? _current_news : _forced_news;
   470 	NewsID item = (_forced_news == INVALID_NEWS) ? _current_news : _forced_news;
   469 
   471 
   470 	if (item >= MAX_NEWS) return true;
   472 	if (item >= _max_news_items) return true;
   471 	NewsItem *ni = &_news_items[item];
   473 	NewsItem *ni = &_news_items[item];
   472 
   474 
   473 	/* Ticker message
   475 	/* Ticker message
   474 	 * Check if the status bar message is still being displayed? */
   476 	 * Check if the status bar message is still being displayed? */
   475 	const Window *w = FindWindowById(WC_STATUS_BAR, 0);
   477 	const Window *w = FindWindowById(WC_STATUS_BAR, 0);
   573 static NewsID getNews(NewsID i)
   575 static NewsID getNews(NewsID i)
   574 {
   576 {
   575 	if (i >= _total_news) return INVALID_NEWS;
   577 	if (i >= _total_news) return INVALID_NEWS;
   576 
   578 
   577 	if (_latest_news < i) {
   579 	if (_latest_news < i) {
   578 		i = _latest_news + MAX_NEWS - i;
   580 		i = _latest_news + _max_news_items - i;
   579 	} else {
   581 	} else {
   580 		i = _latest_news - i;
   582 		i = _latest_news - i;
   581 	}
   583 	}
   582 
   584 
   583 	i %= MAX_NEWS;
   585 	i %= _max_news_items;
   584 	return i;
   586 	return i;
   585 }
   587 }
   586 
   588 
   587 /**
   589 /**
   588  * Draw an unformatted news message truncated to a maximum length. If
   590  * Draw an unformatted news message truncated to a maximum length. If