src/news_gui.cpp
changeset 9236 0c4f622cbcec
parent 9234 bfc9d27d3d0d
child 9245 cd9305c986e4
equal deleted inserted replaced
9235:1517b0d83518 9236:0c4f622cbcec
    58 static uint _max_news_items = 0;            ///< size of news FIFO queue
    58 static uint _max_news_items = 0;            ///< size of news FIFO queue
    59 static NewsID _current_news = INVALID_NEWS; ///< points to news item that should be shown next
    59 static NewsID _current_news = INVALID_NEWS; ///< points to news item that should be shown next
    60 static NewsID _oldest_news = 0;             ///< points to first item in fifo queue
    60 static NewsID _oldest_news = 0;             ///< points to first item in fifo queue
    61 static NewsID _latest_news = INVALID_NEWS;  ///< points to last item in fifo queue
    61 static NewsID _latest_news = INVALID_NEWS;  ///< points to last item in fifo queue
    62 
    62 
    63 struct news_d {
       
    64 	uint16 chat_height;
       
    65 	NewsItem *ni;
       
    66 };
       
    67 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(news_d));
       
    68 
       
    69 /** Forced news item.
    63 /** Forced news item.
    70  * Users can force an item by accessing the history or "last message".
    64  * Users can force an item by accessing the history or "last message".
    71  * If the message being shown was forced by the user, its index is stored in
    65  * If the message being shown was forced by the user, its index is stored in
    72  * _forced_news. Otherwise, \a _forced_news variable is INVALID_NEWS. */
    66  * _forced_news. Otherwise, \a _forced_news variable is INVALID_NEWS. */
    73 static NewsID _forced_news = INVALID_NEWS;
    67 static NewsID _forced_news = INVALID_NEWS;
    74 
    68 
    75 static uint _total_news = 0; ///< Number of news items in FIFO queue @see _news_items
    69 static uint _total_news = 0; ///< Number of news items in FIFO queue @see _news_items
    76 
    70 static void MoveToNextItem();
       
    71 
       
    72 
       
    73 typedef void DrawNewsCallbackProc(struct Window *w, const NewsItem *ni);
    77 void DrawNewsNewVehicleAvail(Window *w, const NewsItem *ni);
    74 void DrawNewsNewVehicleAvail(Window *w, const NewsItem *ni);
    78 void DrawNewsBankrupcy(Window *w, const NewsItem *ni);
    75 void DrawNewsBankrupcy(Window *w, const NewsItem *ni);
    79 static void MoveToNextItem();
       
    80 
    76 
    81 static DrawNewsCallbackProc * const _draw_news_callback[] = {
    77 static DrawNewsCallbackProc * const _draw_news_callback[] = {
    82 	DrawNewsNewVehicleAvail,  ///< DNC_VEHICLEAVAIL
    78 	DrawNewsNewVehicleAvail,  ///< DNC_VEHICLEAVAIL
    83 	DrawNewsBankrupcy,        ///< DNC_BANKRUPCY
    79 	DrawNewsBankrupcy,        ///< DNC_BANKRUPCY
    84 };
    80 };
   129 	_latest_news = INVALID_NEWS;
   125 	_latest_news = INVALID_NEWS;
   130 	_forced_news = INVALID_NEWS;
   126 	_forced_news = INVALID_NEWS;
   131 	_total_news = 0;
   127 	_total_news = 0;
   132 }
   128 }
   133 
   129 
   134 void DrawNewsBorder(const Window *w)
   130 struct NewsWindow : Window {
   135 {
   131 	uint16 chat_height;
   136 	int left = 0;
   132 	NewsItem *ni;
   137 	int right = w->width - 1;
   133 
   138 	int top = 0;
   134 	NewsWindow(const WindowDesc *desc, NewsItem *ni) : Window(desc), ni(ni)
   139 	int bottom = w->height - 1;
   135 	{
   140 
   136 		const Window *w = FindWindowById(WC_SEND_NETWORK_MSG, 0);
   141 	GfxFillRect(left, top, right, bottom, 0xF);
   137 		this->chat_height = (w != NULL) ? w->height : 0;
   142 
   138 
   143 	GfxFillRect(left, top, left, bottom, 0xD7);
   139 		this->ni = &_news_items[_forced_news == INVALID_NEWS ? _current_news : _forced_news];
   144 	GfxFillRect(right, top, right, bottom, 0xD7);
   140 		this->flags4 |= WF_DISABLE_VP_SCROLL;
   145 	GfxFillRect(left, top, right, top, 0xD7);
   141 
   146 	GfxFillRect(left, bottom, right, bottom, 0xD7);
   142 		this->FindWindowPlacementAndResize(desc);
   147 
   143 	}
   148 	DrawString(left + 2, top + 1, STR_00C6, TC_FROMSTRING);
   144 
   149 }
   145 	void DrawNewsBorder()
   150 
   146 	{
   151 static void NewsWindowProc(Window *w, WindowEvent *e)
   147 		int left = 0;
   152 {
   148 		int right = this->width - 1;
   153 	switch (e->event) {
   149 		int top = 0;
   154 		case WE_CREATE: { // If chatbar is open at creation time, we need to go above it
   150 		int bottom = this->height - 1;
   155 			const Window *w1 = FindWindowById(WC_SEND_NETWORK_MSG, 0);
   151 
   156 			WP(w, news_d).chat_height = (w1 != NULL) ? w1->height : 0;
   152 		GfxFillRect(left, top, right, bottom, 0xF);
   157 			break;
   153 
       
   154 		GfxFillRect(left, top, left, bottom, 0xD7);
       
   155 		GfxFillRect(right, top, right, bottom, 0xD7);
       
   156 		GfxFillRect(left, top, right, top, 0xD7);
       
   157 		GfxFillRect(left, bottom, right, bottom, 0xD7);
       
   158 
       
   159 		DrawString(left + 2, top + 1, STR_00C6, TC_FROMSTRING);
       
   160 	}
       
   161 
       
   162 	virtual void OnPaint()
       
   163 	{
       
   164 		const NewsMode display_mode = _news_subtype_data[this->ni->subtype].display_mode;
       
   165 
       
   166 		switch (display_mode) {
       
   167 			case NM_NORMAL:
       
   168 			case NM_THIN: {
       
   169 				this->DrawNewsBorder();
       
   170 
       
   171 				DrawString(2, 1, STR_00C6, TC_FROMSTRING);
       
   172 
       
   173 				SetDParam(0, this->ni->date);
       
   174 				DrawStringRightAligned(428, 1, STR_01FF, TC_FROMSTRING);
       
   175 
       
   176 				if (!(this->ni->flags & NF_VIEWPORT)) {
       
   177 					CopyInDParam(0, this->ni->params, lengthof(this->ni->params));
       
   178 					DrawStringMultiCenter(215, display_mode == NM_NORMAL ? 76 : 56,
       
   179 						this->ni->string_id, this->width - 4);
       
   180 				} else {
       
   181 					/* Back up transparency options to draw news view */
       
   182 					TransparencyOptionBits to_backup = _transparency_opt;
       
   183 					_transparency_opt = 0;
       
   184 					DrawWindowViewport(this);
       
   185 					_transparency_opt = to_backup;
       
   186 
       
   187 					/* Shade the viewport into gray, or color*/
       
   188 					ViewPort *vp = this->viewport;
       
   189 					GfxFillRect(vp->left - this->left, vp->top - this->top,
       
   190 						vp->left - this->left + vp->width - 1, vp->top - this->top + vp->height - 1,
       
   191 						(this->ni->flags & NF_INCOLOR ? PALETTE_TO_TRANSPARENT : PALETTE_TO_STRUCT_GREY) | (1 << USE_COLORTABLE)
       
   192 					);
       
   193 
       
   194 					CopyInDParam(0, this->ni->params, lengthof(this->ni->params));
       
   195 					DrawStringMultiCenter(this->width / 2, 20, this->ni->string_id, this->width - 4);
       
   196 				}
       
   197 				break;
       
   198 			}
       
   199 
       
   200 			case NM_CALLBACK:
       
   201 				this->DrawNewsBorder();
       
   202 				_draw_news_callback[_news_subtype_data[this->ni->subtype].callback](this, ni);
       
   203 				break;
       
   204 
       
   205 			default:
       
   206 				DrawWindowWidgets(this);
       
   207 				if (!(this->ni->flags & NF_VIEWPORT)) {
       
   208 					CopyInDParam(0, this->ni->params, lengthof(this->ni->params));
       
   209 					DrawStringMultiCenter(140, 38, this->ni->string_id, 276);
       
   210 				} else {
       
   211 					DrawWindowViewport(this);
       
   212 					CopyInDParam(0, this->ni->params, lengthof(this->ni->params));
       
   213 					DrawStringMultiCenter(this->width / 2, this->height - 16, this->ni->string_id, this->width - 4);
       
   214 				}
       
   215 				break;
   158 		}
   216 		}
   159 
   217 	}
   160 		case WE_PAINT: {
   218 
   161 			const NewsItem *ni = WP(w, news_d).ni;
   219 	virtual void OnClick(Point pt, int widget)
   162 			const NewsMode display_mode = _news_subtype_data[ni->subtype].display_mode;
   220 	{
   163 
   221 		switch (widget) {
   164 			switch (display_mode) {
   222 			case 1:
   165 				case NM_NORMAL:
   223 				this->ni->duration = 0;
   166 				case NM_THIN: {
   224 				delete this;
   167 					DrawNewsBorder(w);
   225 				_forced_news = INVALID_NEWS;
   168 
   226 				break;
   169 					DrawString(2, 1, STR_00C6, TC_FROMSTRING);
   227 
   170 
   228 			case 0:
   171 					SetDParam(0, ni->date);
   229 				if (this->ni->flags & NF_VEHICLE) {
   172 					DrawStringRightAligned(428, 1, STR_01FF, TC_FROMSTRING);
   230 					Vehicle *v = GetVehicle(this->ni->data_a);
   173 
   231 					ScrollMainWindowTo(v->x_pos, v->y_pos);
   174 					if (!(ni->flags & NF_VIEWPORT)) {
   232 				} else if (this->ni->flags & NF_TILE) {
   175 						CopyInDParam(0, ni->params, lengthof(ni->params));
   233 					if (_ctrl_pressed) {
   176 						DrawStringMultiCenter(215, display_mode == NM_NORMAL ? 76 : 56,
   234 						ShowExtraViewPortWindow(this->ni->data_a);
   177 							ni->string_id, w->width - 4);
   235 						if (this->ni->flags & NF_TILE2) {
       
   236 							ShowExtraViewPortWindow(this->ni->data_b);
       
   237 						}
   178 					} else {
   238 					} else {
   179 						/* Back up transparency options to draw news view */
   239 						if (!ScrollMainWindowToTile(this->ni->data_a) && this->ni->flags & NF_TILE2) {
   180 						TransparencyOptionBits to_backup = _transparency_opt;
   240 							ScrollMainWindowToTile(this->ni->data_b);
   181 						_transparency_opt = 0;
       
   182 						DrawWindowViewport(w);
       
   183 						_transparency_opt = to_backup;
       
   184 
       
   185 						/* Shade the viewport into gray, or color*/
       
   186 						ViewPort *vp = w->viewport;
       
   187 						GfxFillRect(vp->left - w->left, vp->top - w->top,
       
   188 							vp->left - w->left + vp->width - 1, vp->top - w->top + vp->height - 1,
       
   189 							(ni->flags & NF_INCOLOR ? PALETTE_TO_TRANSPARENT : PALETTE_TO_STRUCT_GREY) | (1 << USE_COLORTABLE)
       
   190 						);
       
   191 
       
   192 						CopyInDParam(0, ni->params, lengthof(ni->params));
       
   193 						DrawStringMultiCenter(w->width / 2, 20, ni->string_id, w->width - 4);
       
   194 					}
       
   195 					break;
       
   196 				}
       
   197 
       
   198 				case NM_CALLBACK:
       
   199 					_draw_news_callback[_news_subtype_data[ni->subtype].callback](w, ni);
       
   200 					break;
       
   201 
       
   202 				default:
       
   203 					DrawWindowWidgets(w);
       
   204 					if (!(ni->flags & NF_VIEWPORT)) {
       
   205 						CopyInDParam(0, ni->params, lengthof(ni->params));
       
   206 						DrawStringMultiCenter(140, 38, ni->string_id, 276);
       
   207 					} else {
       
   208 						DrawWindowViewport(w);
       
   209 						CopyInDParam(0, ni->params, lengthof(ni->params));
       
   210 						DrawStringMultiCenter(w->width / 2, w->height - 16, ni->string_id, w->width - 4);
       
   211 					}
       
   212 					break;
       
   213 			}
       
   214 			break;
       
   215 		}
       
   216 
       
   217 		case WE_CLICK:
       
   218 			switch (e->we.click.widget) {
       
   219 				case 1: {
       
   220 					NewsItem *ni = WP(w, news_d).ni;
       
   221 					delete w;
       
   222 					ni->duration = 0;
       
   223 					_forced_news = INVALID_NEWS;
       
   224 					break;
       
   225 				}
       
   226 
       
   227 				case 0: {
       
   228 					NewsItem *ni = WP(w, news_d).ni;
       
   229 					if (ni->flags & NF_VEHICLE) {
       
   230 						Vehicle *v = GetVehicle(ni->data_a);
       
   231 						ScrollMainWindowTo(v->x_pos, v->y_pos);
       
   232 					} else if (ni->flags & NF_TILE) {
       
   233 						if (_ctrl_pressed) {
       
   234 							ShowExtraViewPortWindow(ni->data_a);
       
   235 							if (ni->flags & NF_TILE2) {
       
   236 								ShowExtraViewPortWindow(ni->data_b);
       
   237 							}
       
   238 						} else {
       
   239 							if (!ScrollMainWindowToTile(ni->data_a) && ni->flags & NF_TILE2) {
       
   240 								ScrollMainWindowToTile(ni->data_b);
       
   241 							}
       
   242 						}
   241 						}
   243 					}
   242 					}
   244 					break;
       
   245 				}
   243 				}
   246 			}
   244 				break;
   247 			break;
       
   248 
       
   249 		case WE_KEYPRESS:
       
   250 			if (e->we.keypress.keycode == WKC_SPACE) {
       
   251 				/* Don't continue. */
       
   252 				e->we.keypress.cont = false;
       
   253 				delete w;
       
   254 			}
       
   255 			break;
       
   256 
       
   257 		case WE_INVALIDATE_DATA: // The chatbar has notified us that is was either created or closed
       
   258 			WP(w, news_d).chat_height = e->we.invalidate.data;
       
   259 			break;
       
   260 
       
   261 		case WE_TICK: { // Scroll up newsmessages from the bottom in steps of 4 pixels
       
   262 			int y = max(w->top - 4, _screen.height - w->height - 12 - WP(w, news_d).chat_height);
       
   263 			if (y == w->top) return;
       
   264 
       
   265 			if (w->viewport != NULL) {
       
   266 				w->viewport->top += y - w->top;
       
   267 			}
       
   268 
       
   269 			int diff = Delta(w->top, y);
       
   270 			w->top = y;
       
   271 
       
   272 			SetDirtyBlocks(w->left, w->top - diff, w->left + w->width, w->top + w->height);
       
   273 			break;
       
   274 		}
   245 		}
   275 	}
   246 	}
   276 }
   247 
       
   248 	virtual bool OnKeyPress(uint16 key, uint16 keycode)
       
   249 	{
       
   250 		if (keycode == WKC_SPACE) {
       
   251 			/* Don't continue. */
       
   252 			delete this;
       
   253 			return false;
       
   254 		}
       
   255 		return true;
       
   256 	}
       
   257 
       
   258 	virtual void OnInvalidateData(int data)
       
   259 	{
       
   260 		/* The chatbar has notified us that is was either created or closed */
       
   261 		this->chat_height = data;
       
   262 	}
       
   263 
       
   264 	virtual void OnTick()
       
   265 	{
       
   266 		/* Scroll up newsmessages from the bottom in steps of 4 pixels */
       
   267 		int y = max(this->top - 4, _screen.height - this->height - 12 - this->chat_height);
       
   268 		if (y == this->top) return;
       
   269 
       
   270 		if (this->viewport != NULL) this->viewport->top += y - this->top;
       
   271 
       
   272 		int diff = Delta(this->top, y);
       
   273 		this->top = y;
       
   274 
       
   275 		SetDirtyBlocks(this->left, this->top - diff, this->left + this->width, this->top + this->height);
       
   276 	}
       
   277 };
   277 
   278 
   278 /**
   279 /**
   279  * Return the correct index in the pseudo-fifo
   280  * Return the correct index in the pseudo-fifo
   280  * queue and deals with overflows when increasing the index
   281  * queue and deals with overflows when increasing the index
   281  */
   282  */
   399 static WindowDesc _news_type13_desc = {
   400 static WindowDesc _news_type13_desc = {
   400 	WDP_CENTER, 476, 430, 170, 430, 170,
   401 	WDP_CENTER, 476, 430, 170, 430, 170,
   401 	WC_NEWS_WINDOW, WC_NONE,
   402 	WC_NEWS_WINDOW, WC_NONE,
   402 	WDF_DEF_WIDGET,
   403 	WDF_DEF_WIDGET,
   403 	_news_type13_widgets,
   404 	_news_type13_widgets,
   404 	NewsWindowProc
   405 	NULL
   405 };
   406 };
   406 
   407 
   407 static const Widget _news_type2_widgets[] = {
   408 static const Widget _news_type2_widgets[] = {
   408 {      WWT_PANEL,   RESIZE_NONE,    15,     0,   429,     0,   129, 0x0, STR_NULL},
   409 {      WWT_PANEL,   RESIZE_NONE,    15,     0,   429,     0,   129, 0x0, STR_NULL},
   409 {      WWT_PANEL,   RESIZE_NONE,    15,     0,    10,     0,    11, 0x0, STR_NULL},
   410 {      WWT_PANEL,   RESIZE_NONE,    15,     0,    10,     0,    11, 0x0, STR_NULL},
   413 static WindowDesc _news_type2_desc = {
   414 static WindowDesc _news_type2_desc = {
   414 	WDP_CENTER, 476, 430, 130, 430, 130,
   415 	WDP_CENTER, 476, 430, 130, 430, 130,
   415 	WC_NEWS_WINDOW, WC_NONE,
   416 	WC_NEWS_WINDOW, WC_NONE,
   416 	WDF_DEF_WIDGET,
   417 	WDF_DEF_WIDGET,
   417 	_news_type2_widgets,
   418 	_news_type2_widgets,
   418 	NewsWindowProc
   419 	NULL
   419 };
   420 };
   420 
   421 
   421 static const Widget _news_type0_widgets[] = {
   422 static const Widget _news_type0_widgets[] = {
   422 {      WWT_PANEL,   RESIZE_NONE,     5,     0,   279,    14,    86, 0x0,              STR_NULL},
   423 {      WWT_PANEL,   RESIZE_NONE,     5,     0,   279,    14,    86, 0x0,              STR_NULL},
   423 {   WWT_CLOSEBOX,   RESIZE_NONE,     5,     0,    10,     0,    13, STR_00C5,         STR_018B_CLOSE_WINDOW},
   424 {   WWT_CLOSEBOX,   RESIZE_NONE,     5,     0,    10,     0,    13, STR_00C5,         STR_018B_CLOSE_WINDOW},
   429 static WindowDesc _news_type0_desc = {
   430 static WindowDesc _news_type0_desc = {
   430 	WDP_CENTER, 476, 280, 87, 280, 87,
   431 	WDP_CENTER, 476, 280, 87, 280, 87,
   431 	WC_NEWS_WINDOW, WC_NONE,
   432 	WC_NEWS_WINDOW, WC_NONE,
   432 	WDF_DEF_WIDGET,
   433 	WDF_DEF_WIDGET,
   433 	_news_type0_widgets,
   434 	_news_type0_widgets,
   434 	NewsWindowProc
   435 	NULL
   435 };
   436 };
   436 
   437 
   437 
   438 
   438 /** Open up an own newspaper window for the news item */
   439 /** Open up an own newspaper window for the news item */
   439 static void ShowNewspaper(NewsItem *ni)
   440 static void ShowNewspaper(NewsItem *ni)
   448 	Window *w;
   449 	Window *w;
   449 	switch (_news_subtype_data[ni->subtype].display_mode) {
   450 	switch (_news_subtype_data[ni->subtype].display_mode) {
   450 		case NM_NORMAL:
   451 		case NM_NORMAL:
   451 		case NM_CALLBACK:
   452 		case NM_CALLBACK:
   452 			_news_type13_desc.top = top;
   453 			_news_type13_desc.top = top;
   453 			w = new Window(&_news_type13_desc);
   454 			w = new NewsWindow(&_news_type13_desc, ni);
   454 			if (ni->flags & NF_VIEWPORT) {
   455 			if (ni->flags & NF_VIEWPORT) {
   455 				InitializeWindowViewport(w, 2, 58, 426, 110,
   456 				InitializeWindowViewport(w, 2, 58, 426, 110,
   456 					ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), ZOOM_LVL_NEWS);
   457 					ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), ZOOM_LVL_NEWS);
   457 			}
   458 			}
   458 			break;
   459 			break;
   459 
   460 
   460 		case NM_THIN:
   461 		case NM_THIN:
   461 			_news_type2_desc.top = top;
   462 			_news_type2_desc.top = top;
   462 			w = new Window(&_news_type2_desc);
   463 			w = new NewsWindow(&_news_type2_desc, ni);
   463 			if (ni->flags & NF_VIEWPORT) {
   464 			if (ni->flags & NF_VIEWPORT) {
   464 				InitializeWindowViewport(w, 2, 58, 426, 70,
   465 				InitializeWindowViewport(w, 2, 58, 426, 70,
   465 					ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), ZOOM_LVL_NEWS);
   466 					ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), ZOOM_LVL_NEWS);
   466 			}
   467 			}
   467 			break;
   468 			break;
   468 
   469 
   469 		default:
   470 		default:
   470 			_news_type0_desc.top = top;
   471 			_news_type0_desc.top = top;
   471 			w = new Window(&_news_type0_desc);
   472 			w = new NewsWindow(&_news_type0_desc, ni);
   472 			if (ni->flags & NF_VIEWPORT) {
   473 			if (ni->flags & NF_VIEWPORT) {
   473 				InitializeWindowViewport(w, 3, 17, 274, 47,
   474 				InitializeWindowViewport(w, 3, 17, 274, 47,
   474 					ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), ZOOM_LVL_NEWS);
   475 					ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), ZOOM_LVL_NEWS);
   475 			}
   476 			}
   476 			break;
   477 			break;
   477 	}
   478 	}
   478 
   479 
   479 	/*DEBUG(misc, 0, " cur %3d, old %2d, lat %3d, for %3d, tot %2d",
   480 	/*DEBUG(misc, 0, " cur %3d, old %2d, lat %3d, for %3d, tot %2d",
   480 	  _current_news, _oldest_news, _latest_news, _forced_news, _total_news);*/
   481 	  _current_news, _oldest_news, _latest_news, _forced_news, _total_news);*/
   481 
       
   482 	WP(w, news_d).ni = &_news_items[_forced_news == INVALID_NEWS ? _current_news : _forced_news];
       
   483 	w->flags4 |= WF_DISABLE_VP_SCROLL;
       
   484 }
   482 }
   485 
   483 
   486 /** Show news item in the ticker */
   484 /** Show news item in the ticker */
   487 static void ShowTicker(const NewsItem *ni)
   485 static void ShowTicker(const NewsItem *ni)
   488 {
   486 {
   981 			 * will become (change dramatized to make clear)
   979 			 * will become (change dramatized to make clear)
   982 			 * [---------O-----------L--]
   980 			 * [---------O-----------L--]
   983 			 * We also need an update of the current, forced and visible (open window)
   981 			 * We also need an update of the current, forced and visible (open window)
   984 			 * news's as this shifting could change the items they were pointing to */
   982 			 * news's as this shifting could change the items they were pointing to */
   985 			if (_total_news != 0) {
   983 			if (_total_news != 0) {
   986 				Window *w = FindWindowById(WC_NEWS_WINDOW, 0);
   984 				NewsWindow *w = dynamic_cast<NewsWindow*>(FindWindowById(WC_NEWS_WINDOW, 0));
   987 				NewsID visible_news = (w != NULL) ? (NewsID)(WP(w, news_d).ni - _news_items) : INVALID_NEWS;
   985 				NewsID visible_news = (w != NULL) ? (NewsID)(w->ni - _news_items) : INVALID_NEWS;
   988 
   986 
   989 				for (NewsID i = n;; i = DecreaseIndex(i)) {
   987 				for (NewsID i = n;; i = DecreaseIndex(i)) {
   990 					_news_items[i] = _news_items[DecreaseIndex(i)];
   988 					_news_items[i] = _news_items[DecreaseIndex(i)];
   991 
   989 
   992 					if (i != _latest_news) {
   990 					if (i != _latest_news) {
   993 						if (i == _current_news) _current_news = IncreaseIndex(_current_news);
   991 						if (i == _current_news) _current_news = IncreaseIndex(_current_news);
   994 						if (i == _forced_news) _forced_news = IncreaseIndex(_forced_news);
   992 						if (i == _forced_news) _forced_news = IncreaseIndex(_forced_news);
   995 						if (i == visible_news) WP(w, news_d).ni = &_news_items[IncreaseIndex(visible_news)];
   993 						if (i == visible_news) w->ni = &_news_items[IncreaseIndex(visible_news)];
   996 					}
   994 					}
   997 
   995 
   998 					if (i == _oldest_news) break;
   996 					if (i == _oldest_news) break;
   999 				}
   997 				}
  1000 				_oldest_news = IncreaseIndex(_oldest_news);
   998 				_oldest_news = IncreaseIndex(_oldest_news);