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 |