Changeset - r9405:7db23071075c
[Not reviewed]
master
0 1 0
rubidium - 16 years ago 2008-05-28 20:13:28
rubidium@openttd.org
(svn r13316) -Codechange: move some functions around to make them grouped more logically.
1 file changed with 171 insertions and 174 deletions:
0 comments (0 inline, 0 general)
src/news_gui.cpp
Show inline comments
 
@@ -172,18 +172,26 @@ static const struct NewsSubtypeData _new
 
	{ NT_GENERAL,         NM_NORMAL,   NF_TILE,                NULL                    }, ///< NS_GENERAL
 
};
 

	
 
/** Initialize the news-items data structures */
 
void InitNewsItemStructs()
 
{
 
	free(_news_items);
 
	_max_news_items = max(ScaleByMapSize(30), 30U);
 
	_news_items = CallocT<NewsItem>(_max_news_items);
 
	_current_news = INVALID_NEWS;
 
	_oldest_news = 0;
 
	_latest_news = INVALID_NEWS;
 
	_forced_news = INVALID_NEWS;
 
	_total_news = 0;
 
}
 
/**
 
 * Per-NewsType data
 
 */
 
NewsTypeData _news_type_data[NT_END] = {
 
	/* name,              age, sound,           display */
 
	{ "arrival_player",    60, SND_1D_APPLAUSE, ND_FULL },  ///< NT_ARRIVAL_PLAYER
 
	{ "arrival_other",     60, SND_1D_APPLAUSE, ND_FULL },  ///< NT_ARRIVAL_OTHER
 
	{ "accident",          90, SND_BEGIN,       ND_FULL },  ///< NT_ACCIDENT
 
	{ "company_info",      60, SND_BEGIN,       ND_FULL },  ///< NT_COMPANY_INFO
 
	{ "openclose",         90, SND_BEGIN,       ND_FULL },  ///< NT_OPENCLOSE
 
	{ "economy",           30, SND_BEGIN,       ND_FULL },  ///< NT_ECONOMY
 
	{ "production_player", 30, SND_BEGIN,       ND_FULL },  ///< NT_INDUSTRY_PLAYER
 
	{ "production_other",  30, SND_BEGIN,       ND_FULL },  ///< NT_INDUSTRY_OTHER
 
	{ "production_nobody", 30, SND_BEGIN,       ND_FULL },  ///< NT_INDUSTRY_NOBODY
 
	{ "advice",           150, SND_BEGIN,       ND_FULL },  ///< NT_ADVICE
 
	{ "new_vehicles",      30, SND_1E_OOOOH,    ND_FULL },  ///< NT_NEW_VEHICLES
 
	{ "acceptance",        90, SND_BEGIN,       ND_FULL },  ///< NT_ACCEPTANCE
 
	{ "subsidies",        180, SND_BEGIN,       ND_FULL },  ///< NT_SUBSIDIES
 
	{ "general",           60, SND_BEGIN,       ND_FULL },  ///< NT_GENERAL
 
};
 

	
 
struct NewsWindow : Window {
 
	uint16 chat_height;
 
@@ -334,105 +342,6 @@ struct NewsWindow : Window {
 
	}
 
};
 

	
 
/**
 
 * Return the correct index in the pseudo-fifo
 
 * queue and deals with overflows when increasing the index
 
 */
 
static inline NewsID IncreaseIndex(NewsID i)
 
{
 
	assert(i != INVALID_NEWS);
 
	return (i + 1) % _max_news_items;
 
}
 

	
 
/**
 
 * Return the correct index in the pseudo-fifo
 
 * queue and deals with overflows when decreasing the index
 
 */
 
static inline NewsID DecreaseIndex(NewsID i)
 
{
 
	assert(i != INVALID_NEWS);
 
	return (i + _max_news_items - 1) % _max_news_items;
 
}
 

	
 
/**
 
 * Add a new newsitem to be shown.
 
 * @param string String to display
 
 * @param subtype news category, any of the NewsSubtype enums (NS_)
 
 * @param data_a news-specific value based on news type
 
 * @param data_b news-specific value based on news type
 
 *
 
 * @see NewsSubype
 
 */
 
void AddNewsItem(StringID string, NewsSubtype subtype, uint data_a, uint data_b)
 
{
 
	if (_game_mode == GM_MENU) return;
 

	
 
	/* check the rare case that the oldest (to be overwritten) news item is open */
 
	if (_total_news == _max_news_items && (_oldest_news == _current_news || _oldest_news == _forced_news)) {
 
		MoveToNextItem();
 
	}
 

	
 
	if (_total_news < _max_news_items) _total_news++;
 

	
 
	/* Increase _latest_news. If we have no news yet, use _oldest news as an
 
	 * index. We cannot use 0 as _oldest_news can jump around due to
 
	 * DeleteVehicleNews */
 
	NewsID l_news = _latest_news;
 
	_latest_news = (_latest_news == INVALID_NEWS) ? _oldest_news : IncreaseIndex(_latest_news);
 

	
 
	/* If the fifo-buffer is full, overwrite the oldest entry */
 
	if (l_news != INVALID_NEWS && _latest_news == _oldest_news) {
 
		assert(_total_news == _max_news_items);
 
		_oldest_news = IncreaseIndex(_oldest_news);
 
	}
 

	
 
	/*DEBUG(misc, 0, "+cur %3d, old %2d, lat %3d, for %3d, tot %2d",
 
	  _current_news, _oldest_news, _latest_news, _forced_news, _total_news);*/
 

	
 
	/* Add news to _latest_news */
 
	NewsItem *ni = &_news_items[_latest_news];
 
	memset(ni, 0, sizeof(*ni));
 

	
 
	ni->string_id = string;
 
	ni->subtype = subtype;
 
	ni->flags = _news_subtype_data[subtype].flags;
 

	
 
	/* show this news message in color? */
 
	if (_cur_year >= _settings.gui.colored_news_year) ni->flags |= NF_INCOLOR;
 

	
 
	ni->data_a = data_a;
 
	ni->data_b = data_b;
 
	ni->date = _date;
 
	CopyOutDParam(ni->params, 0, lengthof(ni->params));
 

	
 
	Window *w = FindWindowById(WC_MESSAGE_HISTORY, 0);
 
	if (w == NULL) return;
 
	w->SetDirty();
 
	w->vscroll.count = _total_news;
 
}
 

	
 

	
 
/**
 
 * Per-NewsType data
 
 */
 
NewsTypeData _news_type_data[NT_END] = {
 
	/* name,              age, sound,           display */
 
	{ "arrival_player",    60, SND_1D_APPLAUSE, ND_FULL },  ///< NT_ARRIVAL_PLAYER
 
	{ "arrival_other",     60, SND_1D_APPLAUSE, ND_FULL },  ///< NT_ARRIVAL_OTHER
 
	{ "accident",          90, SND_BEGIN,       ND_FULL },  ///< NT_ACCIDENT
 
	{ "company_info",      60, SND_BEGIN,       ND_FULL },  ///< NT_COMPANY_INFO
 
	{ "openclose",         90, SND_BEGIN,       ND_FULL },  ///< NT_OPENCLOSE
 
	{ "economy",           30, SND_BEGIN,       ND_FULL },  ///< NT_ECONOMY
 
	{ "production_player", 30, SND_BEGIN,       ND_FULL },  ///< NT_INDUSTRY_PLAYER
 
	{ "production_other",  30, SND_BEGIN,       ND_FULL },  ///< NT_INDUSTRY_OTHER
 
	{ "production_nobody", 30, SND_BEGIN,       ND_FULL },  ///< NT_INDUSTRY_NOBODY
 
	{ "advice",           150, SND_BEGIN,       ND_FULL },  ///< NT_ADVICE
 
	{ "new_vehicles",      30, SND_1E_OOOOH,    ND_FULL },  ///< NT_NEW_VEHICLES
 
	{ "acceptance",        90, SND_BEGIN,       ND_FULL },  ///< NT_ACCEPTANCE
 
	{ "subsidies",        180, SND_BEGIN,       ND_FULL },  ///< NT_SUBSIDIES
 
	{ "general",           60, SND_BEGIN,       ND_FULL },  ///< NT_GENERAL
 
};
 

	
 

	
 
static const Widget _news_type13_widgets[] = {
 
{      WWT_PANEL,   RESIZE_NONE,    15,     0,   429,     0,   169, 0x0, STR_NULL},
 
@@ -530,6 +439,157 @@ static void ShowTicker(const NewsItem *n
 
	InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SHOW_TICKER);
 
}
 

	
 
/** Initialize the news-items data structures */
 
void InitNewsItemStructs()
 
{
 
	free(_news_items);
 
	_max_news_items = max(ScaleByMapSize(30), 30U);
 
	_news_items = CallocT<NewsItem>(_max_news_items);
 
	_current_news = INVALID_NEWS;
 
	_oldest_news = 0;
 
	_latest_news = INVALID_NEWS;
 
	_forced_news = INVALID_NEWS;
 
	_total_news = 0;
 
}
 

	
 
/**
 
 * Return the correct index in the pseudo-fifo
 
 * queue and deals with overflows when increasing the index
 
 */
 
static inline NewsID IncreaseIndex(NewsID i)
 
{
 
	assert(i != INVALID_NEWS);
 
	return (i + 1) % _max_news_items;
 
}
 

	
 
/**
 
 * Return the correct index in the pseudo-fifo
 
 * queue and deals with overflows when decreasing the index
 
 */
 
static inline NewsID DecreaseIndex(NewsID i)
 
{
 
	assert(i != INVALID_NEWS);
 
	return (i + _max_news_items - 1) % _max_news_items;
 
}
 

	
 
/**
 
 * Add a new newsitem to be shown.
 
 * @param string String to display
 
 * @param subtype news category, any of the NewsSubtype enums (NS_)
 
 * @param data_a news-specific value based on news type
 
 * @param data_b news-specific value based on news type
 
 *
 
 * @see NewsSubype
 
 */
 
void AddNewsItem(StringID string, NewsSubtype subtype, uint data_a, uint data_b)
 
{
 
	if (_game_mode == GM_MENU) return;
 

	
 
	/* check the rare case that the oldest (to be overwritten) news item is open */
 
	if (_total_news == _max_news_items && (_oldest_news == _current_news || _oldest_news == _forced_news)) {
 
		MoveToNextItem();
 
	}
 

	
 
	if (_total_news < _max_news_items) _total_news++;
 

	
 
	/* Increase _latest_news. If we have no news yet, use _oldest news as an
 
	 * index. We cannot use 0 as _oldest_news can jump around due to
 
	 * DeleteVehicleNews */
 
	NewsID l_news = _latest_news;
 
	_latest_news = (_latest_news == INVALID_NEWS) ? _oldest_news : IncreaseIndex(_latest_news);
 

	
 
	/* If the fifo-buffer is full, overwrite the oldest entry */
 
	if (l_news != INVALID_NEWS && _latest_news == _oldest_news) {
 
		assert(_total_news == _max_news_items);
 
		_oldest_news = IncreaseIndex(_oldest_news);
 
	}
 

	
 
	/*DEBUG(misc, 0, "+cur %3d, old %2d, lat %3d, for %3d, tot %2d",
 
	  _current_news, _oldest_news, _latest_news, _forced_news, _total_news);*/
 

	
 
	/* Add news to _latest_news */
 
	NewsItem *ni = &_news_items[_latest_news];
 
	memset(ni, 0, sizeof(*ni));
 

	
 
	ni->string_id = string;
 
	ni->subtype = subtype;
 
	ni->flags = _news_subtype_data[subtype].flags;
 

	
 
	/* show this news message in color? */
 
	if (_cur_year >= _settings.gui.colored_news_year) ni->flags |= NF_INCOLOR;
 

	
 
	ni->data_a = data_a;
 
	ni->data_b = data_b;
 
	ni->date = _date;
 
	CopyOutDParam(ni->params, 0, lengthof(ni->params));
 

	
 
	Window *w = FindWindowById(WC_MESSAGE_HISTORY, 0);
 
	if (w == NULL) return;
 
	w->SetDirty();
 
	w->vscroll.count = _total_news;
 
}
 

	
 
void DeleteVehicleNews(VehicleID vid, StringID news)
 
{
 
	for (NewsID n = _oldest_news; _latest_news != INVALID_NEWS; n = IncreaseIndex(n)) {
 
		const NewsItem *ni = &_news_items[n];
 

	
 
		if (ni->flags & NF_VEHICLE &&
 
				ni->data_a == vid &&
 
				(news == INVALID_STRING_ID || ni->string_id == news)) {
 
			/* If we delete a forced news and it is just before the current news
 
			 * then we need to advance to the next news (if any) */
 
			if (_forced_news == n) MoveToNextItem();
 
			if (_forced_news == INVALID_NEWS && _current_news == n) MoveToNextItem();
 
			_total_news--;
 

	
 
			/* If this is the last news item, invalidate _latest_news */
 
			if (_total_news == 0) {
 
				assert(_latest_news == _oldest_news);
 
				_latest_news = INVALID_NEWS;
 
				_current_news = INVALID_NEWS;
 
			}
 

	
 
			/* Since we only imitate a FIFO removing an arbitrary element does need
 
			 * some magic. Remove the item by shifting head towards the tail. eg
 
			 *    oldest    remove  last
 
			 *        |        |     |
 
			 * [------O--------n-----L--]
 
			 * will become (change dramatized to make clear)
 
			 * [---------O-----------L--]
 
			 * We also need an update of the current, forced and visible (open window)
 
			 * news's as this shifting could change the items they were pointing to */
 
			if (_total_news != 0) {
 
				NewsWindow *w = dynamic_cast<NewsWindow*>(FindWindowById(WC_NEWS_WINDOW, 0));
 
				NewsID visible_news = (w != NULL) ? (NewsID)(w->ni - _news_items) : INVALID_NEWS;
 

	
 
				for (NewsID i = n;; i = DecreaseIndex(i)) {
 
					_news_items[i] = _news_items[DecreaseIndex(i)];
 

	
 
					if (i != _latest_news) {
 
						if (i == _current_news) _current_news = IncreaseIndex(_current_news);
 
						if (i == _forced_news) _forced_news = IncreaseIndex(_forced_news);
 
						if (i == visible_news) w->ni = &_news_items[IncreaseIndex(visible_news)];
 
					}
 

	
 
					if (i == _oldest_news) break;
 
				}
 
				_oldest_news = IncreaseIndex(_oldest_news);
 
			}
 

	
 
			/*DEBUG(misc, 0, "-cur %3d, old %2d, lat %3d, for %3d, tot %2d",
 
			  _current_news, _oldest_news, _latest_news, _forced_news, _total_news);*/
 

	
 
			Window *w = FindWindowById(WC_MESSAGE_HISTORY, 0);
 
			if (w != NULL) {
 
				w->SetDirty();
 
				w->vscroll.count = _total_news;
 
			}
 
		}
 

	
 
		if (n == _latest_news) break;
 
	}
 
}
 

	
 
/**
 
 * Are we ready to show another news item?
 
@@ -976,66 +1036,3 @@ void ShowMessageOptions()
 
	DeleteWindowById(WC_GAME_OPTIONS, 0);
 
	new MessageOptionsWindow(&_message_options_desc);
 
}
 

	
 

	
 
void DeleteVehicleNews(VehicleID vid, StringID news)
 
{
 
	for (NewsID n = _oldest_news; _latest_news != INVALID_NEWS; n = IncreaseIndex(n)) {
 
		const NewsItem *ni = &_news_items[n];
 

	
 
		if (ni->flags & NF_VEHICLE &&
 
				ni->data_a == vid &&
 
				(news == INVALID_STRING_ID || ni->string_id == news)) {
 
			/* If we delete a forced news and it is just before the current news
 
			 * then we need to advance to the next news (if any) */
 
			if (_forced_news == n) MoveToNextItem();
 
			if (_forced_news == INVALID_NEWS && _current_news == n) MoveToNextItem();
 
			_total_news--;
 

	
 
			/* If this is the last news item, invalidate _latest_news */
 
			if (_total_news == 0) {
 
				assert(_latest_news == _oldest_news);
 
				_latest_news = INVALID_NEWS;
 
				_current_news = INVALID_NEWS;
 
			}
 

	
 
			/* Since we only imitate a FIFO removing an arbitrary element does need
 
			 * some magic. Remove the item by shifting head towards the tail. eg
 
			 *    oldest    remove  last
 
			 *        |        |     |
 
			 * [------O--------n-----L--]
 
			 * will become (change dramatized to make clear)
 
			 * [---------O-----------L--]
 
			 * We also need an update of the current, forced and visible (open window)
 
			 * news's as this shifting could change the items they were pointing to */
 
			if (_total_news != 0) {
 
				NewsWindow *w = dynamic_cast<NewsWindow*>(FindWindowById(WC_NEWS_WINDOW, 0));
 
				NewsID visible_news = (w != NULL) ? (NewsID)(w->ni - _news_items) : INVALID_NEWS;
 

	
 
				for (NewsID i = n;; i = DecreaseIndex(i)) {
 
					_news_items[i] = _news_items[DecreaseIndex(i)];
 

	
 
					if (i != _latest_news) {
 
						if (i == _current_news) _current_news = IncreaseIndex(_current_news);
 
						if (i == _forced_news) _forced_news = IncreaseIndex(_forced_news);
 
						if (i == visible_news) w->ni = &_news_items[IncreaseIndex(visible_news)];
 
					}
 

	
 
					if (i == _oldest_news) break;
 
				}
 
				_oldest_news = IncreaseIndex(_oldest_news);
 
			}
 

	
 
			/*DEBUG(misc, 0, "-cur %3d, old %2d, lat %3d, for %3d, tot %2d",
 
			  _current_news, _oldest_news, _latest_news, _forced_news, _total_news);*/
 

	
 
			Window *w = FindWindowById(WC_MESSAGE_HISTORY, 0);
 
			if (w != NULL) {
 
				w->SetDirty();
 
				w->vscroll.count = _total_news;
 
			}
 
		}
 

	
 
		if (n == _latest_news) break;
 
	}
 
}
0 comments (0 inline, 0 general)