Files @ r12162:c4894f5339c3
Branch filter:

Location: cpp/openttd-patchpack/source/src/engine_gui.cpp - annotation

rubidium
(svn r16583) -Update: the order of the language files so it's in sync with english.txt. Normally WT2 would do this, but only with activity for those languages. Now we'd like to the order to match so we can more easily spot import bugs while developing WT3.
r5584:545d748cc681
r5584:545d748cc681
r9111:983de9c5a848
r6125:eb40461cb765
r5584:545d748cc681
r8107:82461791b7a2
r8224:194097dc7288
r8786:f24a6d1fba34
r9070:e059c65164f3
r8116:df67d3c5e4fd
r10960:e97ebf9cf99b
r5584:545d748cc681
r8114:866ed489ed98
r9380:6b24883f64de
r9567:b3592d86e408
r12037:7b4fedf64d47
r12037:7b4fedf64d47
r10000:91824eb4383b
r5584:545d748cc681
r8264:d493cb51fe8a
r8264:d493cb51fe8a
r5584:545d748cc681
r9199:7d9724de3af0
r5584:545d748cc681
r11917:612c11f7ab47
r6209:f315c4c30b43
r11725:57bc99fdc1bc
r11725:57bc99fdc1bc
r11725:57bc99fdc1bc
r6259:e2dba394134b
r10000:91824eb4383b
r5584:545d748cc681
r5584:545d748cc681
r5584:545d748cc681
r11423:97fd1230114c
r11423:97fd1230114c
r11423:97fd1230114c
r11423:97fd1230114c
r11423:97fd1230114c
r11423:97fd1230114c
r11423:97fd1230114c
r11423:97fd1230114c
r11423:97fd1230114c
r5584:545d748cc681
r11725:57bc99fdc1bc
r11725:57bc99fdc1bc
r11725:57bc99fdc1bc
r11725:57bc99fdc1bc
r11725:57bc99fdc1bc
r5584:545d748cc681
r5584:545d748cc681
r5584:545d748cc681
r11512:4e2f95d920fb
r11512:4e2f95d920fb
r11512:4e2f95d920fb
r11725:57bc99fdc1bc
r11512:4e2f95d920fb
r11512:4e2f95d920fb
r11512:4e2f95d920fb
r11512:4e2f95d920fb
r11725:57bc99fdc1bc
r11725:57bc99fdc1bc
r11512:4e2f95d920fb
r11512:4e2f95d920fb
r11512:4e2f95d920fb
r11512:4e2f95d920fb
r11512:4e2f95d920fb
r5668:e62c2fbafb7b
r11437:025ee7e57357
r5584:545d748cc681
r6248:b940b09d7ab8
r5584:545d748cc681
r5584:545d748cc681
r6248:b940b09d7ab8
r5584:545d748cc681
r11437:025ee7e57357
r11437:025ee7e57357
r11437:025ee7e57357
r11437:025ee7e57357
r5584:545d748cc681
r5584:545d748cc681
r6209:f315c4c30b43
r6209:f315c4c30b43
r6209:f315c4c30b43
r6209:f315c4c30b43
r5584:545d748cc681
r5584:545d748cc681
r9302:115cfeb49cd5
r9302:115cfeb49cd5
r9302:115cfeb49cd5
r9333:a36e9b553bc9
r9302:115cfeb49cd5
r5584:545d748cc681
r9302:115cfeb49cd5
r9302:115cfeb49cd5
r9302:115cfeb49cd5
r5584:545d748cc681
r9302:115cfeb49cd5
r5584:545d748cc681
r11761:eae452e003af
r5584:545d748cc681
r7059:0c2dc932a6ae
r11427:99c6f58948e0
r5584:545d748cc681
r11917:612c11f7ab47
r5584:545d748cc681
r9302:115cfeb49cd5
r12037:7b4fedf64d47
r11440:3b5200f9cbfd
r5584:545d748cc681
r5584:545d748cc681
r9302:115cfeb49cd5
r9302:115cfeb49cd5
r9302:115cfeb49cd5
r11423:97fd1230114c
r10499:570896340d7a
r5584:545d748cc681
r11423:97fd1230114c
r9302:115cfeb49cd5
r5584:545d748cc681
r5584:545d748cc681
r5584:545d748cc681
r9302:115cfeb49cd5
r5584:545d748cc681
r11368:058349c3a02c
r7341:72820788b006
r5893:6c4fd9987e0f
r10998:94dcb82c0e64
r11512:4e2f95d920fb
r11368:058349c3a02c
r5584:545d748cc681
r5584:545d748cc681
r5584:545d748cc681
r5584:545d748cc681
r9302:115cfeb49cd5
r5584:545d748cc681
r5584:545d748cc681
r11311:c4de431f8676
r9567:b3592d86e408
r9567:b3592d86e408
r9567:b3592d86e408
r9567:b3592d86e408
r9567:b3592d86e408
r9567:b3592d86e408
r9567:b3592d86e408
r9567:b3592d86e408
r9567:b3592d86e408
r9567:b3592d86e408
r9567:b3592d86e408
r11437:025ee7e57357
r5584:545d748cc681
r11917:612c11f7ab47
r5584:545d748cc681
r10927:eb69eaf0227d
r10967:2c98940d6c64
r10967:2c98940d6c64
r10967:2c98940d6c64
r5584:545d748cc681
r10927:eb69eaf0227d
r5584:545d748cc681
r9567:b3592d86e408
r9567:b3592d86e408
r11188:143f3c64befd
r9720:6d491d07d0a8
r5584:545d748cc681
r5584:545d748cc681
r5584:545d748cc681
r11761:eae452e003af
r5584:545d748cc681
r5584:545d748cc681
r11437:025ee7e57357
r5584:545d748cc681
r11917:612c11f7ab47
r11350:df593340eca2
r11350:df593340eca2
r11350:df593340eca2
r11350:df593340eca2
r11350:df593340eca2
r11712:c05ce4b83dd6
r11712:c05ce4b83dd6
r11712:c05ce4b83dd6
r11712:c05ce4b83dd6
r11712:c05ce4b83dd6
r10927:eb69eaf0227d
r11761:eae452e003af
r11350:df593340eca2
r11350:df593340eca2
r11350:df593340eca2
r11350:df593340eca2
r11403:ba31da6812eb
r11350:df593340eca2
r5584:545d748cc681
r11761:eae452e003af
r11350:df593340eca2
r5584:545d748cc681
r5584:545d748cc681
r11437:025ee7e57357
r5584:545d748cc681
r11917:612c11f7ab47
r5584:545d748cc681
r10927:eb69eaf0227d
r10967:2c98940d6c64
r11188:143f3c64befd
r11188:143f3c64befd
r11709:0908d1040b1c
r11709:0908d1040b1c
r11188:143f3c64befd
r11709:0908d1040b1c
r11188:143f3c64befd
r11709:0908d1040b1c
r5584:545d748cc681
r11761:eae452e003af
r5584:545d748cc681
r5584:545d748cc681
r11437:025ee7e57357
r5584:545d748cc681
r11917:612c11f7ab47
r10927:eb69eaf0227d
r10927:eb69eaf0227d
r10967:2c98940d6c64
r11188:143f3c64befd
r11403:ba31da6812eb
r10927:eb69eaf0227d
r11761:eae452e003af
r5584:545d748cc681
r5584:545d748cc681
r8763:c2c776621d56
r6209:f315c4c30b43
r12005:1096fe8178fd
r12005:1096fe8178fd
r11917:612c11f7ab47
r5584:545d748cc681
r6209:f315c4c30b43
r11761:eae452e003af
r6209:f315c4c30b43
r5584:545d748cc681
r5584:545d748cc681
r7059:0c2dc932a6ae
r11761:eae452e003af
r5584:545d748cc681
r12037:7b4fedf64d47
r11085:c87a330fb4c2
r11440:3b5200f9cbfd
r5584:545d748cc681
r9380:6b24883f64de
r9380:6b24883f64de
r9380:6b24883f64de
r9380:6b24883f64de
r9380:6b24883f64de
r9380:6b24883f64de
r9403:e5bffa930a63
r9380:6b24883f64de
r9403:e5bffa930a63
r9380:6b24883f64de
r9380:6b24883f64de
r9380:6b24883f64de
r9403:e5bffa930a63
r9380:6b24883f64de
r9380:6b24883f64de
r9380:6b24883f64de
r9380:6b24883f64de
r9380:6b24883f64de
r9380:6b24883f64de
r9380:6b24883f64de
r9380:6b24883f64de
r9403:e5bffa930a63
r9380:6b24883f64de
r9404:f74e13f5c66e
r9403:e5bffa930a63
r9403:e5bffa930a63
r9403:e5bffa930a63
r9380:6b24883f64de
r9380:6b24883f64de
/* $Id$ */

/** @file engine_gui.cpp GUI to show engine related information. */

#include "stdafx.h"
#include "window_gui.h"
#include "gfx_func.h"
#include "engine_func.h"
#include "engine_base.h"
#include "command_func.h"
#include "news_type.h"
#include "newgrf_engine.h"
#include "strings_func.h"
#include "engine_gui.h"
#include "articulated_vehicles.h"
#include "vehicle_func.h"
#include "company_func.h"
#include "rail.h"

#include "table/strings.h"
#include "table/sprites.h"

StringID GetEngineCategoryName(EngineID engine)
{
	switch (Engine::Get(engine)->type) {
		default: NOT_REACHED();
		case VEH_ROAD:              return STR_ENGINE_PREVIEW_ROAD_VEHICLE;
		case VEH_AIRCRAFT:          return STR_ENGINE_PREVIEW_AIRCRAFT;
		case VEH_SHIP:              return STR_ENGINE_PREVIEW_SHIP;
		case VEH_TRAIN:
			return GetRailTypeInfo(RailVehInfo(engine)->railtype)->strings.new_loco;
	}
}

/** Widgets used for the engine preview window */
enum EnginePreviewWidgets {
	EPW_CLOSE,      ///< Close button
	EPW_CAPTION,    ///< Title bar/caption
	EPW_BACKGROUND, ///< Background
	EPW_NO,         ///< No button
	EPW_YES,        ///< Yes button
};

static const Widget _engine_preview_widgets[] = {
{   WWT_CLOSEBOX,  RESIZE_NONE,  COLOUR_LIGHT_BLUE,    0,   10,    0,   13, STR_BLACK_CROSS,            STR_TOOLTIP_CLOSE_WINDOW},           // EPW_CLOSE
{    WWT_CAPTION,  RESIZE_NONE,  COLOUR_LIGHT_BLUE,   11,  299,    0,   13, STR_ENGINE_PREVIEW_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS}, // EPW_CAPTION
{      WWT_PANEL,  RESIZE_NONE,  COLOUR_LIGHT_BLUE,    0,  299,   14,  191, 0x0,                        STR_NULL},                           // EPW_BACKGROUND
{ WWT_PUSHTXTBTN,  RESIZE_NONE,  COLOUR_LIGHT_BLUE,   85,  144,  172,  183, STR_NO,                     STR_NULL},                           // EPW_NO
{ WWT_PUSHTXTBTN,  RESIZE_NONE,  COLOUR_LIGHT_BLUE,  155,  214,  172,  183, STR_YES,                    STR_NULL},                           // EPW_YES
{   WIDGETS_END},
};

static const NWidgetPart _nested_engine_preview_widgets[] = {
	NWidget(NWID_HORIZONTAL),
		NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE, EPW_CLOSE),
		NWidget(WWT_CAPTION, COLOUR_LIGHT_BLUE, EPW_CAPTION), SetDataTip(STR_ENGINE_PREVIEW_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
	EndContainer(),
	NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, EPW_BACKGROUND),
		NWidget(NWID_SPACER), SetMinimalSize(0, 158),
		NWidget(NWID_HORIZONTAL), SetPIP(85, 10, 85),
			NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, EPW_NO), SetMinimalSize(60, 12), SetDataTip(STR_NO, STR_NULL),
			NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, EPW_YES), SetMinimalSize(60, 12), SetDataTip(STR_YES, STR_NULL),
		EndContainer(),
		NWidget(NWID_SPACER), SetMinimalSize(0, 8),
	EndContainer(),
};

typedef void DrawEngineProc(int x, int y, EngineID engine, SpriteID pal);
typedef void DrawEngineInfoProc(EngineID, int left, int right, int top, int bottom);

struct DrawEngineInfo {
	DrawEngineProc *engine_proc;
	DrawEngineInfoProc *info_proc;
};

static void DrawTrainEngineInfo(EngineID engine, int left, int right, int top, int bottom);
static void DrawRoadVehEngineInfo(EngineID engine, int left, int right, int top, int bottom);
static void DrawShipEngineInfo(EngineID engine, int left, int right, int top, int bottom);
static void DrawAircraftEngineInfo(EngineID engine, int left, int right, int top, int bottom);

static const DrawEngineInfo _draw_engine_list[4] = {
	{ DrawTrainEngine,    DrawTrainEngineInfo    },
	{ DrawRoadVehEngine,  DrawRoadVehEngineInfo  },
	{ DrawShipEngine,     DrawShipEngineInfo     },
	{ DrawAircraftEngine, DrawAircraftEngineInfo },
};

struct EnginePreviewWindow : Window {
	EnginePreviewWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
	{
		this->FindWindowPlacementAndResize(desc);
	}

	virtual void OnPaint()
	{
		this->DrawWidgets();

		EngineID engine = this->window_number;
		SetDParam(0, GetEngineCategoryName(engine));
		DrawStringMultiLine(this->widget[EPW_BACKGROUND].left + 2, this->widget[EPW_BACKGROUND].right - 2, 18, 80, STR_ENGINE_PREVIEW_MESSAGE, TC_FROMSTRING, SA_CENTER);

		SetDParam(0, engine);
		DrawString(this->widget[EPW_BACKGROUND].left + 2, this->widget[EPW_BACKGROUND].right - 2, 80, STR_ENGINE_NAME, TC_BLACK, SA_CENTER);

		const DrawEngineInfo *dei = &_draw_engine_list[Engine::Get(engine)->type];

		int width = this->width;
		dei->engine_proc(width >> 1, 100, engine, GetEnginePalette(engine, _local_company));
		dei->info_proc(engine, this->widget[EPW_BACKGROUND].left + 26, this->widget[EPW_BACKGROUND].right - 26, 100, 170);
	}

	virtual void OnClick(Point pt, int widget)
	{
		switch (widget) {
			case EPW_YES:
				DoCommandP(0, this->window_number, 0, CMD_WANT_ENGINE_PREVIEW);
				/* Fallthrough */
			case EPW_NO:
				delete this;
				break;
		}
	}
};

static const WindowDesc _engine_preview_desc(
	WDP_CENTER, WDP_CENTER, 300, 192, 300, 192,
	WC_ENGINE_PREVIEW, WC_NONE,
	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_CONSTRUCTION,
	_engine_preview_widgets, _nested_engine_preview_widgets, lengthof(_nested_engine_preview_widgets)
);


void ShowEnginePreviewWindow(EngineID engine)
{
	AllocateWindowDescFront<EnginePreviewWindow>(&_engine_preview_desc, engine);
}

uint GetTotalCapacityOfArticulatedParts(EngineID engine, VehicleType type)
{
	uint total = 0;

	uint16 *cap = GetCapacityOfArticulatedParts(engine, type);
	for (uint c = 0; c < NUM_CARGO; c++) {
		total += cap[c];
	}

	return total;
}

static void DrawTrainEngineInfo(EngineID engine, int left, int right, int top, int bottom)
{
	const Engine *e = Engine::Get(engine);

	SetDParam(0, e->GetCost());
	SetDParam(2, e->GetDisplayMaxSpeed());
	SetDParam(3, e->GetPower());
	SetDParam(1, e->GetDisplayWeight());

	SetDParam(4, e->GetRunningCost());

	uint capacity = GetTotalCapacityOfArticulatedParts(engine, VEH_TRAIN);
	if (capacity != 0) {
		SetDParam(5, e->GetDefaultCargoType());
		SetDParam(6, capacity);
	} else {
		SetDParam(5, CT_INVALID);
	}
	DrawStringMultiLine(left, right, top, bottom, STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER, TC_FROMSTRING, SA_CENTER);
}

static void DrawAircraftEngineInfo(EngineID engine, int left, int right, int top, int bottom)
{
	const Engine *e = Engine::Get(engine);
	CargoID cargo = e->GetDefaultCargoType();

	if (cargo == CT_INVALID || cargo == CT_PASSENGERS) {
		SetDParam(0, e->GetCost());
		SetDParam(1, e->GetDisplayMaxSpeed());
		SetDParam(2, CT_PASSENGERS),
		SetDParam(3, e->GetDisplayDefaultCapacity());
		SetDParam(4, CT_MAIL),
		SetDParam(5, e->u.air.mail_capacity);
		SetDParam(6, e->GetRunningCost());

		DrawStringMultiLine(left, right, top, bottom, STR_VEHICLE_INFO_COST_MAX_SPEED_CAPACITY_CAPACITY_RUNCOST, TC_FROMSTRING, SA_CENTER);
	} else {
		SetDParam(0, e->GetCost());
		SetDParam(1, e->GetDisplayMaxSpeed());
		SetDParam(2, cargo);
		SetDParam(3, e->GetDisplayDefaultCapacity());
		SetDParam(4, e->GetRunningCost());

		DrawStringMultiLine(left, right, top, bottom, STR_VEHICLE_INFO_COST_MAX_SPEED_CAPACITY_RUNCOST, TC_FROMSTRING, SA_CENTER);
	}
}

static void DrawRoadVehEngineInfo(EngineID engine, int left, int right, int top, int bottom)
{
	const Engine *e = Engine::Get(engine);

	SetDParam(0, e->GetCost());
	SetDParam(1, e->GetDisplayMaxSpeed());
	uint capacity = GetTotalCapacityOfArticulatedParts(engine, VEH_ROAD);
	if (capacity != 0) {
		SetDParam(2, e->GetDefaultCargoType());
		SetDParam(3, capacity);
	} else {
		SetDParam(2, CT_INVALID);
	}
	SetDParam(4, e->GetRunningCost());

	DrawStringMultiLine(left, right, top, bottom, STR_VEHICLE_INFO_COST_MAX_SPEED_CAPACITY_RUNCOST, TC_FROMSTRING, SA_CENTER);
}

static void DrawShipEngineInfo(EngineID engine, int left, int right, int top, int bottom)
{
	const Engine *e = Engine::Get(engine);

	SetDParam(0, e->GetCost());
	SetDParam(1, e->GetDisplayMaxSpeed());
	SetDParam(2, e->GetDefaultCargoType());
	SetDParam(3, e->GetDisplayDefaultCapacity());
	SetDParam(4, e->GetRunningCost());
	DrawStringMultiLine(left, right, top, bottom, STR_VEHICLE_INFO_COST_MAX_SPEED_CAPACITY_RUNCOST, TC_FROMSTRING, SA_CENTER);
}

void DrawNewsNewVehicleAvail(Window *w, const NewsItem *ni)
{
	assert(ni->reftype1 == NR_ENGINE);
	EngineID engine = ni->ref1;
	const DrawEngineInfo *dei = &_draw_engine_list[Engine::Get(engine)->type];

	SetDParam(0, GetEngineCategoryName(engine));
	DrawStringMultiLine(1, w->width - 2, 0, 56, STR_NEW_VEHICLE_NOW_AVAILABLE, TC_FROMSTRING, SA_CENTER);

	GfxFillRect(25, 56, w->width - 25, w->height - 2, 10);

	SetDParam(0, engine);
	DrawStringMultiLine(1, w->width - 2, 56, 88, STR_NEW_VEHICLE_TYPE, TC_FROMSTRING, SA_CENTER);

	dei->engine_proc(w->width >> 1, 88, engine, GetEnginePalette(engine, _local_company));
	GfxFillRect(25, 56, w->width - 56, 112, PALETTE_TO_STRUCT_GREY, FILLRECT_RECOLOUR);
	dei->info_proc(engine, 26, w->width - 26, 100, 170);
}


/** Sort all items using qsort() and given 'CompareItems' function
 * @param el list to be sorted
 * @param compare function for evaluation of the quicksort
 */
void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare)
{
	uint size = el->Length();
	/* out-of-bounds access at the next line for size == 0 (even with operator[] at some systems)
	 * generally, do not sort if there are less than 2 items */
	if (size < 2) return;
	qsort(el->Begin(), size, sizeof(*el->Begin()), compare); // MorphOS doesn't know vector::at(int) ...
}

/** Sort selected range of items (on indices @ <begin, begin+num_items-1>)
 * @param el list to be sorted
 * @param compare function for evaluation of the quicksort
 * @param begin start of sorting
 * @param num_items count of items to be sorted
 */
void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items)
{
	if (num_items < 2) return;
	assert(begin < el->Length());
	assert(begin + num_items <= el->Length());
	qsort(el->Get(begin), num_items, sizeof(*el->Begin()), compare);
}