00001
00002
00005 #include "stdafx.h"
00006 #include "window_gui.h"
00007 #include "gfx_func.h"
00008 #include "engine_func.h"
00009 #include "engine_base.h"
00010 #include "command_func.h"
00011 #include "news_type.h"
00012 #include "newgrf_engine.h"
00013 #include "strings_func.h"
00014 #include "engine_gui.h"
00015 #include "articulated_vehicles.h"
00016 #include "rail.h"
00017 #include "aircraft.h"
00018
00019 #include "table/strings.h"
00020 #include "table/sprites.h"
00021
00022 StringID GetEngineCategoryName(EngineID engine)
00023 {
00024 switch (GetEngine(engine)->type) {
00025 default: NOT_REACHED();
00026 case VEH_ROAD: return STR_8103_ROAD_VEHICLE;
00027 case VEH_AIRCRAFT: return STR_8104_AIRCRAFT;
00028 case VEH_SHIP: return STR_8105_SHIP;
00029 case VEH_TRAIN:
00030 return GetRailTypeInfo(RailVehInfo(engine)->railtype)->strings.new_loco;
00031 }
00032 }
00033
00034 static const Widget _engine_preview_widgets[] = {
00035 { WWT_CLOSEBOX, RESIZE_NONE, COLOUR_LIGHT_BLUE, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
00036 { WWT_CAPTION, RESIZE_NONE, COLOUR_LIGHT_BLUE, 11, 299, 0, 13, STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE, STR_018C_WINDOW_TITLE_DRAG_THIS},
00037 { WWT_PANEL, RESIZE_NONE, COLOUR_LIGHT_BLUE, 0, 299, 14, 191, 0x0, STR_NULL},
00038 { WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_LIGHT_BLUE, 85, 144, 172, 183, STR_00C9_NO, STR_NULL},
00039 { WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_LIGHT_BLUE, 155, 214, 172, 183, STR_00C8_YES, STR_NULL},
00040 { WIDGETS_END},
00041 };
00042
00043 typedef void DrawEngineProc(int x, int y, EngineID engine, SpriteID pal);
00044 typedef void DrawEngineInfoProc(EngineID, int x, int y, int maxw);
00045
00046 struct DrawEngineInfo {
00047 DrawEngineProc *engine_proc;
00048 DrawEngineInfoProc *info_proc;
00049 };
00050
00051 static void DrawTrainEngineInfo(EngineID engine, int x, int y, int maxw);
00052 static void DrawRoadVehEngineInfo(EngineID engine, int x, int y, int maxw);
00053 static void DrawShipEngineInfo(EngineID engine, int x, int y, int maxw);
00054 static void DrawAircraftEngineInfo(EngineID engine, int x, int y, int maxw);
00055
00056 static const DrawEngineInfo _draw_engine_list[4] = {
00057 { DrawTrainEngine, DrawTrainEngineInfo },
00058 { DrawRoadVehEngine, DrawRoadVehEngineInfo },
00059 { DrawShipEngine, DrawShipEngineInfo },
00060 { DrawAircraftEngine, DrawAircraftEngineInfo },
00061 };
00062
00063 struct EnginePreviewWindow : Window {
00064 EnginePreviewWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
00065 {
00066 this->FindWindowPlacementAndResize(desc);
00067 }
00068
00069 virtual void OnPaint()
00070 {
00071 this->DrawWidgets();
00072
00073 EngineID engine = this->window_number;
00074 SetDParam(0, GetEngineCategoryName(engine));
00075 DrawStringMultiCenter(150, 44, STR_8101_WE_HAVE_JUST_DESIGNED_A, 296);
00076
00077 SetDParam(0, engine);
00078 DrawStringCentered(this->width >> 1, 80, STR_ENGINE_NAME, TC_BLACK);
00079
00080 const DrawEngineInfo *dei = &_draw_engine_list[GetEngine(engine)->type];
00081
00082 int width = this->width;
00083 dei->engine_proc(width >> 1, 100, engine, 0);
00084 dei->info_proc(engine, width >> 1, 130, width - 52);
00085 }
00086
00087 virtual void OnClick(Point pt, int widget)
00088 {
00089 switch (widget) {
00090 case 4:
00091 DoCommandP(0, this->window_number, 0, CMD_WANT_ENGINE_PREVIEW);
00092
00093 case 3:
00094 delete this;
00095 break;
00096 }
00097 }
00098 };
00099
00100 static const WindowDesc _engine_preview_desc(
00101 WDP_CENTER, WDP_CENTER, 300, 192, 300, 192,
00102 WC_ENGINE_PREVIEW, WC_NONE,
00103 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_CONSTRUCTION,
00104 _engine_preview_widgets
00105 );
00106
00107
00108 void ShowEnginePreviewWindow(EngineID engine)
00109 {
00110 AllocateWindowDescFront<EnginePreviewWindow>(&_engine_preview_desc, engine);
00111 }
00112
00113 uint GetTotalCapacityOfArticulatedParts(EngineID engine, VehicleType type)
00114 {
00115 uint total = 0;
00116
00117 uint16 *cap = GetCapacityOfArticulatedParts(engine, type);
00118 for (uint c = 0; c < NUM_CARGO; c++) {
00119 total += cap[c];
00120 }
00121
00122 return total;
00123 }
00124
00125 static void DrawTrainEngineInfo(EngineID engine, int x, int y, int maxw)
00126 {
00127 const Engine *e = GetEngine(engine);
00128
00129 SetDParam(0, e->GetCost());
00130 SetDParam(2, e->GetDisplayMaxSpeed());
00131 SetDParam(3, e->GetPower());
00132 SetDParam(1, e->GetDisplayWeight());
00133
00134 SetDParam(4, e->GetRunningCost());
00135
00136 uint capacity = GetTotalCapacityOfArticulatedParts(engine, VEH_TRAIN);
00137 if (capacity != 0) {
00138 SetDParam(5, e->GetDefaultCargoType());
00139 SetDParam(6, capacity);
00140 } else {
00141 SetDParam(5, CT_INVALID);
00142 }
00143 DrawStringMultiCenter(x, y, STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER, maxw);
00144 }
00145
00146 static void DrawAircraftEngineInfo(EngineID engine, int x, int y, int maxw)
00147 {
00148 const Engine *e = GetEngine(engine);
00149 CargoID cargo = e->GetDefaultCargoType();
00150
00151 if (cargo == CT_INVALID || cargo == CT_PASSENGERS) {
00152 SetDParam(0, e->GetCost());
00153 SetDParam(1, e->GetDisplayMaxSpeed());
00154 SetDParam(2, e->u.air.passenger_capacity);
00155 SetDParam(3, e->u.air.mail_capacity);
00156 SetDParam(4, e->GetRunningCost());
00157
00158 DrawStringMultiCenter(x, y, STR_A02E_COST_MAX_SPEED_CAPACITY, maxw);
00159 } else {
00160 SetDParam(0, e->GetCost());
00161 SetDParam(1, e->GetDisplayMaxSpeed());
00162 SetDParam(2, cargo);
00163 SetDParam(3, AircraftDefaultCargoCapacity(cargo, &e->u.air));
00164 SetDParam(4, e->GetRunningCost());
00165
00166 DrawStringMultiCenter(x, y, STR_982E_COST_MAX_SPEED_CAPACITY, maxw);
00167 }
00168 }
00169
00170 static void DrawRoadVehEngineInfo(EngineID engine, int x, int y, int maxw)
00171 {
00172 const Engine *e = GetEngine(engine);
00173
00174 SetDParam(0, e->GetCost());
00175 SetDParam(1, e->GetDisplayMaxSpeed());
00176 SetDParam(2, e->GetRunningCost());
00177 uint capacity = GetTotalCapacityOfArticulatedParts(engine, VEH_ROAD);
00178 if (capacity != 0) {
00179 SetDParam(3, e->GetDefaultCargoType());
00180 SetDParam(4, capacity);
00181 } else {
00182 SetDParam(3, CT_INVALID);
00183 }
00184
00185 DrawStringMultiCenter(x, y, STR_902A_COST_SPEED_RUNNING_COST, maxw);
00186 }
00187
00188 static void DrawShipEngineInfo(EngineID engine, int x, int y, int maxw)
00189 {
00190 const ShipVehicleInfo *svi = ShipVehInfo(engine);
00191 const Engine *e = GetEngine(engine);
00192
00193 SetDParam(0, e->GetCost());
00194 SetDParam(1, e->GetDisplayMaxSpeed());
00195 SetDParam(2, e->GetDefaultCargoType());
00196 SetDParam(3, GetEngineProperty(engine, 0x0D, svi->capacity));
00197 SetDParam(4, e->GetRunningCost());
00198 DrawStringMultiCenter(x, y, STR_982E_COST_MAX_SPEED_CAPACITY, maxw);
00199 }
00200
00201 void DrawNewsNewVehicleAvail(Window *w, const NewsItem *ni)
00202 {
00203 EngineID engine = ni->data_a;
00204 const DrawEngineInfo *dei = &_draw_engine_list[GetEngine(engine)->type];
00205
00206 SetDParam(0, GetEngineCategoryName(engine));
00207 DrawStringMultiCenter(w->width >> 1, 20, STR_NEW_VEHICLE_NOW_AVAILABLE, w->width - 2);
00208
00209 GfxFillRect(25, 56, w->width - 25, w->height - 2, 10);
00210
00211 SetDParam(0, engine);
00212 DrawStringMultiCenter(w->width >> 1, 57, STR_NEW_VEHICLE_TYPE, w->width - 2);
00213
00214 dei->engine_proc(w->width >> 1, 88, engine, 0);
00215 GfxFillRect(25, 56, w->width - 56, 112, PALETTE_TO_STRUCT_GREY, FILLRECT_RECOLOUR);
00216 dei->info_proc(engine, w->width >> 1, 129, w->width - 52);
00217 }
00218
00219
00224 void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare)
00225 {
00226 uint size = el->Length();
00227
00228
00229 if (size < 2) return;
00230 qsort(el->Begin(), size, sizeof(*el->Begin()), compare);
00231 }
00232
00239 void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items)
00240 {
00241 if (num_items < 2) return;
00242 assert(begin < el->Length());
00243 assert(begin + num_items <= el->Length());
00244 qsort(el->Get(begin), num_items, sizeof(*el->Begin()), compare);
00245 }
00246