326 { |
326 { |
327 DeleteWindowById(WC_GAME_OPTIONS, 0); |
327 DeleteWindowById(WC_GAME_OPTIONS, 0); |
328 new AboutWindow(); |
328 new AboutWindow(); |
329 } |
329 } |
330 |
330 |
331 static uint64 _errmsg_decode_params[20]; |
|
332 static StringID _errmsg_message_1, _errmsg_message_2; |
|
333 static uint _errmsg_duration; |
|
334 |
|
335 |
|
336 static const Widget _errmsg_widgets[] = { |
331 static const Widget _errmsg_widgets[] = { |
337 { WWT_CLOSEBOX, RESIZE_NONE, 4, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
332 { WWT_CLOSEBOX, RESIZE_NONE, 4, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
338 { WWT_CAPTION, RESIZE_NONE, 4, 11, 239, 0, 13, STR_00B2_MESSAGE, STR_NULL}, |
333 { WWT_CAPTION, RESIZE_NONE, 4, 11, 239, 0, 13, STR_00B2_MESSAGE, STR_NULL}, |
339 { WWT_PANEL, RESIZE_NONE, 4, 0, 239, 14, 45, 0x0, STR_NULL}, |
334 { WWT_PANEL, RESIZE_NONE, 4, 0, 239, 14, 45, 0x0, STR_NULL}, |
340 { WIDGETS_END}, |
335 { WIDGETS_END}, |
345 { WWT_CAPTION, RESIZE_NONE, 4, 11, 333, 0, 13, STR_00B3_MESSAGE_FROM, STR_NULL}, |
340 { WWT_CAPTION, RESIZE_NONE, 4, 11, 333, 0, 13, STR_00B3_MESSAGE_FROM, STR_NULL}, |
346 { WWT_PANEL, RESIZE_NONE, 4, 0, 333, 14, 136, 0x0, STR_NULL}, |
341 { WWT_PANEL, RESIZE_NONE, 4, 0, 333, 14, 136, 0x0, STR_NULL}, |
347 { WIDGETS_END}, |
342 { WIDGETS_END}, |
348 }; |
343 }; |
349 |
344 |
350 static void ErrmsgWndProc(Window *w, WindowEvent *e) |
345 struct ErrmsgWindow : public Window { |
351 { |
346 private: |
352 switch (e->event) { |
347 uint duration; |
353 case WE_PAINT: |
348 uint64 decode_params[20]; |
354 CopyInDParam(0, _errmsg_decode_params, lengthof(_errmsg_decode_params)); |
349 StringID message_1; |
355 DrawWindowWidgets(w); |
350 StringID message_2; |
356 CopyInDParam(0, _errmsg_decode_params, lengthof(_errmsg_decode_params)); |
351 |
357 |
352 public: |
358 /* If the error message comes from a NewGRF, we must use the text ref. stack reserved for error messages. |
353 ErrmsgWindow(Point pt, int width, int height, StringID msg1, StringID msg2, const Widget *widget) : Window(pt.x, pt.y, width, height, NULL, WC_ERRMSG, widget) |
359 * If the message doesn't come from a NewGRF, it won't use the TTDP-style text ref. stack, so we won't hurt anything |
354 { |
360 */ |
355 this->duration = _patches.errmsg_duration; |
361 SwitchToErrorRefStack(); |
356 CopyOutDParam(this->decode_params, 0, lengthof(this->decode_params)); |
362 RewindTextRefStack(); |
357 this->message_1 = msg1; |
363 |
358 this->message_2 = msg2; |
364 if (!IsWindowOfPrototype(w, _errmsg_face_widgets)) { |
359 this->desc_flags = WDF_STD_BTN | WDF_DEF_WIDGET; |
365 DrawStringMultiCenter( |
360 this->FindWindowPlacementAndResize(width, height); |
366 120, |
361 } |
367 (_errmsg_message_1 == INVALID_STRING_ID ? 25 : 15), |
362 |
368 _errmsg_message_2, |
363 virtual void OnPaint() |
369 w->width - 2); |
364 { |
370 if (_errmsg_message_1 != INVALID_STRING_ID) { |
365 static int y[][3] = { |
371 DrawStringMultiCenter( |
366 {15, 25, 30}, // _errmsg_widgets |
372 120, |
367 {45, 65, 90}, // _errmsg_face_widgets |
373 30, |
368 }; |
374 _errmsg_message_1, |
369 |
375 w->width - 2); |
370 CopyInDParam(0, this->decode_params, lengthof(this->decode_params)); |
376 } |
371 DrawWindowWidgets(this); |
377 } else { |
372 CopyInDParam(0, this->decode_params, lengthof(this->decode_params)); |
378 const Player *p = GetPlayer((PlayerID)GetDParamX(_errmsg_decode_params,2)); |
373 |
379 DrawPlayerFace(p->face, p->player_color, 2, 16); |
374 /* If the error message comes from a NewGRF, we must use the text ref. stack reserved for error messages. |
380 |
375 * If the message doesn't come from a NewGRF, it won't use the TTDP-style text ref. stack, so we won't hurt anything |
381 DrawStringMultiCenter( |
376 */ |
382 214, |
377 SwitchToErrorRefStack(); |
383 (_errmsg_message_1 == INVALID_STRING_ID ? 65 : 45), |
378 RewindTextRefStack(); |
384 _errmsg_message_2, |
379 |
385 w->width - 2); |
380 byte i = 0; |
386 if (_errmsg_message_1 != INVALID_STRING_ID) { |
381 if (IsWindowOfPrototype(this, _errmsg_face_widgets)) { |
387 DrawStringMultiCenter( |
382 const Player *p = GetPlayer((PlayerID)GetDParamX(this->decode_params, 2)); |
388 214, |
383 DrawPlayerFace(p->face, p->player_color, 2, 16); |
389 90, |
384 i = 1; |
390 _errmsg_message_1, |
385 } |
391 w->width - 2); |
386 |
392 } |
387 byte j = (this->message_1 == INVALID_STRING_ID) ? 1 : 0; |
393 } |
388 DrawStringMultiCenter(this->width - 120, y[i][j], this->message_2, this->width - 2); |
394 |
389 if (j == 0) { |
395 /* Switch back to the normal text ref. stack for NewGRF texts */ |
390 DrawStringMultiCenter(this->width - 120, y[i][2], this->message_1, this->width - 2); |
396 SwitchToNormalRefStack(); |
391 } |
397 break; |
392 |
398 |
393 /* Switch back to the normal text ref. stack for NewGRF texts */ |
399 case WE_MOUSELOOP: |
394 SwitchToNormalRefStack(); |
400 if (_right_button_down) delete w; |
395 } |
401 break; |
396 |
402 |
397 virtual void OnMouseLoop() |
403 case WE_100_TICKS: |
398 { |
404 if (--_errmsg_duration == 0) delete w; |
399 if (_right_button_down) delete this; |
405 break; |
400 } |
406 |
401 |
407 case WE_DESTROY: |
402 virtual void OnHundredthTick() |
408 SetRedErrorSquare(0); |
403 { |
409 extern StringID _switch_mode_errorstr; |
404 if (--this->duration == 0) delete this; |
410 _switch_mode_errorstr = INVALID_STRING_ID; |
405 } |
411 break; |
406 |
412 |
407 ~ErrmsgWindow() |
413 case WE_KEYPRESS: |
408 { |
414 if (e->we.keypress.keycode == WKC_SPACE) { |
409 SetRedErrorSquare(0); |
415 /* Don't continue. */ |
410 extern StringID _switch_mode_errorstr; |
416 e->we.keypress.cont = false; |
411 _switch_mode_errorstr = INVALID_STRING_ID; |
417 delete w; |
412 } |
418 } |
413 |
419 break; |
414 virtual bool OnKeyPress(uint16 key, uint16 keycode) |
420 } |
415 { |
421 } |
416 if (keycode != WKC_SPACE) return true; |
|
417 delete this; |
|
418 return false; |
|
419 } |
|
420 }; |
422 |
421 |
423 void ShowErrorMessage(StringID msg_1, StringID msg_2, int x, int y) |
422 void ShowErrorMessage(StringID msg_1, StringID msg_2, int x, int y) |
424 { |
423 { |
425 DeleteWindowById(WC_ERRMSG, 0); |
424 DeleteWindowById(WC_ERRMSG, 0); |
426 |
425 |
|
426 if (!_patches.errmsg_duration) return; |
|
427 |
427 if (msg_2 == STR_NULL) msg_2 = STR_EMPTY; |
428 if (msg_2 == STR_NULL) msg_2 = STR_EMPTY; |
428 |
|
429 _errmsg_message_1 = msg_1; |
|
430 _errmsg_message_2 = msg_2; |
|
431 CopyOutDParam(_errmsg_decode_params, 0, lengthof(_errmsg_decode_params)); |
|
432 _errmsg_duration = _patches.errmsg_duration; |
|
433 if (!_errmsg_duration) return; |
|
434 |
429 |
435 Point pt; |
430 Point pt; |
436 const ViewPort *vp; |
431 const ViewPort *vp; |
437 Window *w; |
432 |
438 |
433 if (msg_1 != STR_013B_OWNED_BY || GetDParam(2) >= 8) { |
439 if (_errmsg_message_1 != STR_013B_OWNED_BY || GetDParamX(_errmsg_decode_params,2) >= 8) { |
|
440 if ((x | y) != 0) { |
434 if ((x | y) != 0) { |
441 pt = RemapCoords2(x, y); |
435 pt = RemapCoords2(x, y); |
442 vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; |
436 vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; |
443 |
437 |
444 /* move x pos to opposite corner */ |
438 /* move x pos to opposite corner */ |
451 |
445 |
452 } else { |
446 } else { |
453 pt.x = (_screen.width - 240) >> 1; |
447 pt.x = (_screen.width - 240) >> 1; |
454 pt.y = (_screen.height - 46) >> 1; |
448 pt.y = (_screen.height - 46) >> 1; |
455 } |
449 } |
456 w = new Window(pt.x, pt.y, 240, 46, ErrmsgWndProc, WC_ERRMSG, _errmsg_widgets); |
450 new ErrmsgWindow(pt, 240, 46, msg_1, msg_2, _errmsg_widgets); |
457 } else { |
451 } else { |
458 if ((x | y) != 0) { |
452 if ((x | y) != 0) { |
459 pt = RemapCoords2(x, y); |
453 pt = RemapCoords2(x, y); |
460 vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; |
454 vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; |
461 pt.x = Clamp(UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left - (334/2), 0, _screen.width - 334); |
455 pt.x = Clamp(UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left - (334/2), 0, _screen.width - 334); |
462 pt.y = Clamp(UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top - (137/2), 22, _screen.height - 137); |
456 pt.y = Clamp(UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top - (137/2), 22, _screen.height - 137); |
463 } else { |
457 } else { |
464 pt.x = (_screen.width - 334) >> 1; |
458 pt.x = (_screen.width - 334) >> 1; |
465 pt.y = (_screen.height - 137) >> 1; |
459 pt.y = (_screen.height - 137) >> 1; |
466 } |
460 } |
467 w = new Window(pt.x, pt.y, 334, 137, ErrmsgWndProc, WC_ERRMSG, _errmsg_face_widgets); |
461 new ErrmsgWindow(pt, 334, 137, msg_1, msg_2, _errmsg_face_widgets); |
468 } |
462 } |
469 |
463 } |
470 w->desc_flags = WDF_STD_BTN | WDF_DEF_WIDGET; |
|
471 } |
|
472 |
|
473 |
464 |
474 void ShowEstimatedCostOrIncome(Money cost, int x, int y) |
465 void ShowEstimatedCostOrIncome(Money cost, int x, int y) |
475 { |
466 { |
476 StringID msg = STR_0805_ESTIMATED_COST; |
467 StringID msg = STR_0805_ESTIMATED_COST; |
477 |
468 |