news_gui.c
changeset 5245 2dae2048ac0a
parent 5244 af95451c3b88
child 5246 fb214a312549
equal deleted inserted replaced
5244:af95451c3b88 5245:2dae2048ac0a
   217 		SetDirtyBlocks(w->left, w->top - diff, w->left + w->width, w->top + w->height);
   217 		SetDirtyBlocks(w->left, w->top - diff, w->left + w->width, w->top + w->height);
   218 	} break;
   218 	} break;
   219 	}
   219 	}
   220 }
   220 }
   221 
   221 
   222 // returns the correct index in the array
   222 /** Return the correct index in the pseudo-fifo
   223 // (to deal with overflows)
   223  * queue and deals with overflows when increasing the index */
   224 static byte increaseIndex(byte i)
   224 static inline byte increaseIndex(byte i)
   225 {
   225 {
   226 	if (i == INVALID_NEWS) return 0;
   226 	if (i == INVALID_NEWS) return 0;
   227 	i++;
   227 	return (i + 1) % MAX_NEWS;
   228 	if (i >= MAX_NEWS) i = i % MAX_NEWS;
   228 }
   229 	return i;
   229 
       
   230 /** Return the correct index in the pseudo-fifo
       
   231  * queue and deals with overflows when decreasing the index */
       
   232 static inline byte decreaseIndex(byte i)
       
   233 {
       
   234 	assert(i != INVALID_NEWS);
       
   235 	return (i + MAX_NEWS - 1) % MAX_NEWS;
   230 }
   236 }
   231 
   237 
   232 /** Add a new newsitem to be shown.
   238 /** Add a new newsitem to be shown.
   233  * @param string String to display, can have special values based on parameter 'flags'
   239  * @param string String to display, can have special values based on parameter 'flags'
   234  * @param flags various control bits that will show various news-types. See macro NEWS_FLAGS()
   240  * @param flags various control bits that will show various news-types. See macro NEWS_FLAGS()
   249  * @see NewsFlags
   255  * @see NewsFlags
   250  * @see NewsType
   256  * @see NewsType
   251  * @see NewsCallback */
   257  * @see NewsCallback */
   252 void AddNewsItem(StringID string, uint32 flags, uint data_a, uint data_b)
   258 void AddNewsItem(StringID string, uint32 flags, uint data_a, uint data_b)
   253 {
   259 {
   254 	NewsItem *ni;
       
   255 	Window *w;
       
   256 	byte l_news;
   260 	byte l_news;
   257 
   261 
   258 	if (_game_mode == GM_MENU) return;
   262 	if (_game_mode == GM_MENU) return;
   259 
   263 
   260 	// check the rare case that the oldest (to be overwritten) news item is open
   264 	// check the rare case that the oldest (to be overwritten) news item is open
   261 	if (_total_news==MAX_NEWS && (_oldest_news == _current_news || _oldest_news == _forced_news))
   265 	if (_total_news == MAX_NEWS && (_oldest_news == _current_news || _oldest_news == _forced_news))
   262 		MoveToNexItem();
   266 		MoveToNexItem();
   263 
   267 
   264 	_forced_news = INVALID_NEWS;
   268 	_forced_news = INVALID_NEWS;
   265 	if (_total_news < MAX_NEWS) _total_news++;
   269 	if (_total_news < MAX_NEWS) _total_news++;
   266 
   270 
   267 	// make sure our pointer isn't overflowing
   271 	// make sure our pointer isn't overflowing
   268 	l_news = _latest_news;
   272 	l_news = _latest_news;
   269 	_latest_news = increaseIndex(_latest_news);
   273 	_latest_news = increaseIndex(_latest_news);
   270 
   274 
   271 	/* If the fifo-buffer is full, overwrite the oldest entry */
   275 	/* If the fifo-buffer is full, overwrite the oldest entry */
   272 	if (l_news != INVALID_NEWS && _latest_news == _oldest_news)
   276 	if (l_news != INVALID_NEWS && _latest_news == _oldest_news) {
   273 		_oldest_news = increaseIndex(_oldest_news); // but make sure we're not overflowing here
   277 		assert(_total_news == MAX_NEWS);
   274 
   278 		_oldest_news = increaseIndex(_oldest_news);
   275 	// add news to _latest_news
   279 	}
   276 	ni = &_news_items[_latest_news];
   280 
   277 	memset(ni, 0, sizeof(*ni));
   281 	{ /* Add news to _latest_news */
   278 
   282 		Window *w;
   279 	ni->string_id = string;
   283 		NewsItem *ni = &_news_items[_latest_news];
   280 	ni->display_mode = (byte)flags;
   284 		memset(ni, 0, sizeof(*ni));
   281 	ni->flags = (byte)(flags >> 8);
   285 
   282 
   286 		ni->string_id = string;
   283 	// show this news message in color?
   287 		ni->display_mode = (byte)flags;
   284 	if (_cur_year >= _patches.colored_news_year)
   288 		ni->flags = (byte)(flags >> 8);
   285 		ni->flags |= NF_INCOLOR;
   289 
   286 
   290 		// show this news message in color?
   287 	ni->type = (byte)(flags >> 16);
   291 		if (_cur_year >= _patches.colored_news_year) ni->flags |= NF_INCOLOR;
   288 	ni->callback = (byte)(flags >> 24);
   292 
   289 	ni->data_a = data_a;
   293 		ni->type = (byte)(flags >> 16);
   290 	ni->data_b = data_b;
   294 		ni->callback = (byte)(flags >> 24);
   291 	ni->date = _date;
   295 		ni->data_a = data_a;
   292 	COPY_OUT_DPARAM(ni->params, 0, lengthof(ni->params));
   296 		ni->data_b = data_b;
   293 
   297 		ni->date = _date;
   294 	w = FindWindowById(WC_MESSAGE_HISTORY, 0);
   298 		COPY_OUT_DPARAM(ni->params, 0, lengthof(ni->params));
   295 	if (w == NULL) return;
   299 
   296 	SetWindowDirty(w);
   300 		w = FindWindowById(WC_MESSAGE_HISTORY, 0);
   297 	w->vscroll.count = _total_news;
   301 		if (w == NULL) return;
       
   302 		SetWindowDirty(w);
       
   303 		w->vscroll.count = _total_news;
       
   304 	}
   298 }
   305 }
   299 
   306 
   300 
   307 
   301 // don't show item if it's older than x days
   308 // don't show item if it's older than x days
   302 static const byte _news_items_age[] = {60, 60, 90, 60, 90, 30, 150, 30, 90, 180};
   309 static const byte _news_items_age[] = {60, 60, 90, 60, 90, 30, 150, 30, 90, 180};
   469 static void MoveToNexItem(void)
   476 static void MoveToNexItem(void)
   470 {
   477 {
   471 	DeleteWindowById(WC_NEWS_WINDOW, 0);
   478 	DeleteWindowById(WC_NEWS_WINDOW, 0);
   472 	_forced_news = INVALID_NEWS;
   479 	_forced_news = INVALID_NEWS;
   473 
   480 
   474 	// if we're not at the last item, than move on
   481 	// if we're not at the last item, then move on
   475 	if (_current_news != _latest_news) {
   482 	if (_current_news != _latest_news) {
   476 		NewsItem *ni;
   483 		NewsItem *ni;
   477 
   484 
   478 		_current_news = increaseIndex(_current_news);
   485 		_current_news = increaseIndex(_current_news);
   479 		ni = &_news_items[_current_news];
   486 		ni = &_news_items[_current_news];
   534 	}
   541 	}
   535 }
   542 }
   536 
   543 
   537 void ShowLastNewsMessage(void)
   544 void ShowLastNewsMessage(void)
   538 {
   545 {
   539 	if (_forced_news == INVALID_NEWS) {
   546 	switch (_forced_news) {
   540 		ShowNewsMessage(_current_news);
   547 		case INVALID_NEWS: // Not forced any news yet, show the current one
   541 	} else if (_forced_news != 0) {
   548 			ShowNewsMessage(_current_news);
   542 		ShowNewsMessage(_forced_news - 1);
   549 			break;
   543 	} else {
   550 		case 0: //
   544 		ShowNewsMessage(_total_news != MAX_NEWS ? _latest_news : MAX_NEWS - 1);
   551 			ShowNewsMessage(_total_news != MAX_NEWS ? _latest_news : MAX_NEWS - 1);
       
   552 			break;
       
   553 		default: // 'Scrolling' through news history show each one in turn
       
   554 			ShowNewsMessage(_forced_news - 1);
       
   555 			break;
   545 	}
   556 	}
   546 }
   557 }
   547 
   558 
   548 
   559 
   549 /* return news by number, with 0 being the most
   560 /* return news by number, with 0 being the most
   874 
   885 
   875 void DeleteVehicleNews(VehicleID vid, StringID news)
   886 void DeleteVehicleNews(VehicleID vid, StringID news)
   876 {
   887 {
   877 	byte n;
   888 	byte n;
   878 
   889 
   879 	for (n = _oldest_news; _latest_news != INVALID_NEWS && n != (_latest_news + 1) % MAX_NEWS; n = (n + 1) % MAX_NEWS) {
   890 	for (n = _oldest_news; _latest_news != INVALID_NEWS && n != increaseIndex(_latest_news); n = increaseIndex(n)) {
   880 		const NewsItem* ni = &_news_items[n];
   891 		const NewsItem *ni = &_news_items[n];
   881 
   892 
   882 		if (ni->flags & NF_VEHICLE &&
   893 		if (ni->flags & NF_VEHICLE &&
   883 				ni->data_a == vid &&
   894 				ni->data_a == vid &&
   884 				(news == INVALID_STRING_ID || ni->string_id == news)) {
   895 				(news == INVALID_STRING_ID || ni->string_id == news)) {
   885 			Window *w;
   896 			Window *w;
   886 			byte i;
   897 			byte i;
   887 
   898 
   888 			if (_forced_news  == n) MoveToNexItem();
   899 			if (_forced_news  == n || _current_news == n) MoveToNexItem();
   889 			if (_current_news == n) MoveToNexItem();
       
   890 
   900 
   891 			// If this is the last news item, invalidate _latest_news
   901 			// If this is the last news item, invalidate _latest_news
   892 			if (_latest_news == _oldest_news) _latest_news = INVALID_NEWS;
   902 			if (_latest_news == _oldest_news) _latest_news = INVALID_NEWS;
   893 
   903 
   894 			if (n != _oldest_news) {
   904 			if (n != _oldest_news) {