engine_gui.cpp

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

Generated on Mon Mar 9 23:33:47 2009 for openttd by  doxygen 1.5.6