diff options
-rw-r--r-- | src/depot_gui.cpp | 22 | ||||
-rw-r--r-- | src/newgrf.cpp | 20 | ||||
-rw-r--r-- | src/newgrf.h | 6 | ||||
-rw-r--r-- | src/newgrf_engine.cpp | 3 | ||||
-rw-r--r-- | src/newgrf_engine.h | 8 | ||||
-rw-r--r-- | src/roadveh_gui.cpp | 5 | ||||
-rw-r--r-- | src/train.h | 1 | ||||
-rw-r--r-- | src/train_cmd.cpp | 30 | ||||
-rw-r--r-- | src/train_gui.cpp | 25 |
9 files changed, 79 insertions, 41 deletions
diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index b6d3ec13b..7e54a3738 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -126,7 +126,6 @@ static const WindowDesc _aircraft_depot_desc( _depot_widgets ); -extern int WagonLengthToPixels(int len); extern void DepotSortList(VehicleList *list); /** @@ -276,7 +275,7 @@ struct DepotWindow : Window { DrawString(this->widget[DEPOT_WIDGET_MATRIX].left, this->widget[DEPOT_WIDGET_MATRIX].right - 1, y + 4, STR_TINY_BLACK, TC_FROMSTRING, SA_RIGHT); // Draw the counter break; - case VEH_ROAD: DrawRoadVehImage( v, x + 24, sprite_y, this->sel, 28); break; + case VEH_ROAD: DrawRoadVehImage( v, x + 24, sprite_y, this->sel, ROADVEHINFO_DEFAULT_VEHICLE_WIDTH); break; case VEH_SHIP: DrawShipImage( v, x + 19, sprite_y - 1, this->sel); break; case VEH_AIRCRAFT: { const Sprite *spr = GetSprite(v->GetImage(DIR_W), ST_NORMAL); @@ -305,7 +304,6 @@ struct DepotWindow : Window { { TileIndex tile = this->window_number; int x, y, i, maxval; - uint16 hnum; /* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */ uint16 rows_in_display = GB(this->widget[DEPOT_WIDGET_MATRIX].data, MAT_ROW_START, MAT_ROW_BITS); @@ -325,14 +323,17 @@ struct DepotWindow : Window { /* determine amount of items for scroller */ if (this->type == VEH_TRAIN) { - hnum = 8; + uint max_width = VEHICLEINFO_FULL_VEHICLE_WIDTH; for (uint num = 0; num < this->vehicle_list.Length(); num++) { - const Vehicle *v = this->vehicle_list[num]; - hnum = max(hnum, Train::From(v)->tcache.cached_total_length); + uint width = 0; + for (const Train *v = Train::From(this->vehicle_list[num]); v != NULL; v = v->Next()) { + width += v->GetDisplayImageWidth(); + } + max_width = max(max_width, width); } /* Always have 1 empty row, so people can change the setting of the train */ SetVScrollCount(w, this->vehicle_list.Length() + this->wagon_list.Length() + 1); - SetHScrollCount(w, WagonLengthToPixels(hnum)); + SetHScrollCount(w, max_width); } else { SetVScrollCount(w, (this->vehicle_list.Length() + this->hscroll.cap - 1) / this->hscroll.cap); } @@ -432,7 +433,7 @@ struct DepotWindow : Window { pos -= this->vehicle_list.Length(); *veh = this->wagon_list[pos]; /* free wagons don't have an initial loco. */ - x -= _traininfo_vehicle_width; + x -= VEHICLEINFO_FULL_VEHICLE_WIDTH; } switch (this->type) { @@ -447,7 +448,10 @@ struct DepotWindow : Window { x += skip; /* find the vehicle in this row that was clicked */ - while (v != NULL && (x -= WagonLengthToPixels(v->tcache.cached_veh_length)) >= 0) v = v->Next(); + for (; v != NULL; v = v->Next()) { + x -= v->GetDisplayImageWidth(); + if (x < 0) break; + } /* if an articulated part was selected, find its parent */ while (v != NULL && v->IsArticulatedPart()) v = v->Previous(); diff --git a/src/newgrf.cpp b/src/newgrf.cpp index df745c634..e8a384c97 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -3725,7 +3725,7 @@ bool GetGlobalVariable(byte param, uint32 *value) return true; case 0x0E: // Y-offset for train sprites - *value = _traininfo_vehicle_pitch; + *value = _cur_grffile->traininfo_vehicle_pitch; return true; case 0x0F: // Rail track type cost factors @@ -3769,6 +3769,10 @@ bool GetGlobalVariable(byte param, uint32 *value) case 0x1E: // Miscellaneous GRF features *value = _misc_grf_features; + + /* Add the local flags */ + assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS)); + if (_cur_grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS); return true; /* case 0x1F: // locale dependent settings not implemented */ @@ -4750,7 +4754,7 @@ static void ParamSet(byte *buf, size_t len) switch (target) { case 0x8E: // Y-Offset for train sprites - _traininfo_vehicle_pitch = res; + _cur_grffile->traininfo_vehicle_pitch = res; break; case 0x8F: { // Rail track type cost factors @@ -4779,8 +4783,12 @@ static void ParamSet(byte *buf, size_t len) case 0x9E: // Miscellaneous GRF features _misc_grf_features = res; + /* Set train list engine width */ - _traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? 32 : 29; + _cur_grffile->traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH; + + /* Remove the local flags from the global flags */ + ClrBit(_misc_grf_features, GMB_TRAIN_WIDTH_32_PIXELS); break; case 0x9F: // locale-dependent settings @@ -5565,8 +5573,6 @@ static void ResetNewGRFData() /* Reset misc GRF features and train list display variables */ _misc_grf_features = 0; - _traininfo_vehicle_pitch = 0; - _traininfo_vehicle_width = 29; _loaded_newgrf_features.has_2CC = false; _loaded_newgrf_features.has_newhouses = false; @@ -5620,6 +5626,10 @@ static void InitNewGRFFile(const GRFConfig *config, int sprite_offset) newfile->filename = strdup(config->filename); newfile->sprite_offset = sprite_offset; + /* Initialise local settings to defaults */ + newfile->traininfo_vehicle_pitch = 0; + newfile->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH; + /* Copy the initial parameter list */ assert(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80); newfile->param_end = config->num_params; diff --git a/src/newgrf.h b/src/newgrf.h index 23122e780..340dcb1f5 100644 --- a/src/newgrf.h +++ b/src/newgrf.h @@ -29,7 +29,7 @@ enum GrfMiscBit { GMB_DESERT_TREES_FIELDS = 0, // Unsupported. GMB_DESERT_PAVED_ROADS = 1, GMB_FIELD_BOUNDING_BOX = 2, // Unsupported. - GMB_TRAIN_WIDTH_32_PIXELS = 3, + GMB_TRAIN_WIDTH_32_PIXELS = 3, ///< Use 32 pixels per train vehicle in depot gui and vehicle details. Never set in the global variable; @see GRFFile::traininfo_vehicle_width GMB_AMBIENT_SOUND_CALLBACK = 4, // Unsupported. GMB_CATENARY_ON_3RD_TRACK = 5, // Unsupported. }; @@ -60,6 +60,7 @@ struct GRFLabel { struct GRFLabel *next; }; +/** Dynamic data of a loaded NewGRF */ struct GRFFile { char *filename; bool is_ottdfile; @@ -105,6 +106,9 @@ struct GRFFile { uint8 railtype_max; RailTypeLabel *railtype_list; + + int traininfo_vehicle_pitch; ///< Vertical offset for draing train images in depot GUI and vehicle details + int traininfo_vehicle_width; ///< Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details }; extern GRFFile *_first_grffile; diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 677b196f1..b3ee2e01c 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -18,9 +18,6 @@ #include "settings_type.h" #include "station_base.h" -int _traininfo_vehicle_pitch = 0; -int _traininfo_vehicle_width = 29; - struct WagonOverride { EngineID *train_id; uint trains; diff --git a/src/newgrf_engine.h b/src/newgrf_engine.h index 7a796a10d..f4ab67148 100644 --- a/src/newgrf_engine.h +++ b/src/newgrf_engine.h @@ -8,9 +8,11 @@ #include "direction_type.h" #include "newgrf_callbacks.h" -extern int _traininfo_vehicle_pitch; -extern int _traininfo_vehicle_width; - +enum { + TRAININFO_DEFAULT_VEHICLE_WIDTH = 29, + ROADVEHINFO_DEFAULT_VEHICLE_WIDTH = 28, + VEHICLEINFO_FULL_VEHICLE_WIDTH = 32, +}; void SetWagonOverrideSprites(EngineID engine, CargoID cargo, const struct SpriteGroup *group, EngineID *train_id, uint trains); const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, EngineID overriding_engine); diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp index d09792e2f..a234c2a4c 100644 --- a/src/roadveh_gui.cpp +++ b/src/roadveh_gui.cpp @@ -6,6 +6,7 @@ #include "roadveh.h" #include "window_gui.h" #include "gfx_func.h" +#include "newgrf_engine.h" #include "vehicle_gui.h" #include "strings_func.h" #include "vehicle_func.h" @@ -117,7 +118,7 @@ void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y) static inline int RoadVehLengthToPixels(int length) { - return (length * 28) / 8; + return (length * ROADVEHINFO_DEFAULT_VEHICLE_WIDTH) / 8; } /** @@ -130,7 +131,7 @@ static inline int RoadVehLengthToPixels(int length) */ void DrawRoadVehImage(const Vehicle *v, int x, int y, VehicleID selection, int max_width) { - int max_length = max_width / 28; + int max_length = max_width / ROADVEHINFO_DEFAULT_VEHICLE_WIDTH; /* Width of highlight box */ int highlight_w = 0; diff --git a/src/train.h b/src/train.h index 8dca09f96..5dc3c1cfa 100644 --- a/src/train.h +++ b/src/train.h @@ -126,6 +126,7 @@ struct Train : public SpecializedVehicle<Train, VEH_TRAIN> { int GetDisplaySpeed() const { return this->tcache.last_speed; } int GetDisplayMaxSpeed() const { return this->tcache.cached_max_speed; } Money GetRunningCost() const; + int GetDisplayImageWidth(Point *offset = NULL) const; bool IsInDepot() const { return CheckTrainInDepot(this, false) != -1; } bool IsStoppedInDepot() const { return CheckTrainStoppedInDepot(this) >= 0; } bool Tick(); diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 3319f3403..2f1e81658 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -586,6 +586,29 @@ void UpdateTrainAcceleration(Train *v) v->acceleration = Clamp(power / weight * 4, 1, 255); } +/** + * Get the width of a train vehicle image in the GUI. + * @param offset Additional offset for positioning the sprite; set to NULL if not needed + * @return Width in pixels + */ +int Train::GetDisplayImageWidth(Point *offset) const +{ + int reference_width = TRAININFO_DEFAULT_VEHICLE_WIDTH; + int vehicle_pitch = 0; + + const Engine *e = Engine::Get(this->engine_type); + if (e->grffile != NULL && is_custom_sprite(e->u.rail.image_index)) { + reference_width = e->grffile->traininfo_vehicle_width; + vehicle_pitch = e->grffile->traininfo_vehicle_pitch; + } + + if (offset != NULL) { + offset->x = reference_width / 2; + offset->y = vehicle_pitch; + } + return this->tcache.cached_veh_length * reference_width / 8; +} + static SpriteID GetDefaultTrainSprite(uint8 spritenum, Direction direction) { return ((direction + _engine_sprite_add[spritenum]) & _engine_sprite_and[spritenum]) + _engine_sprite_base[spritenum]; @@ -614,13 +637,16 @@ SpriteID Train::GetImage(Direction direction) const static SpriteID GetRailIcon(EngineID engine, bool rear_head, int &y) { + const Engine *e = Engine::Get(engine); Direction dir = rear_head ? DIR_E : DIR_W; - uint8 spritenum = RailVehInfo(engine)->image_index; + uint8 spritenum = e->u.rail.image_index; if (is_custom_sprite(spritenum)) { SpriteID sprite = GetCustomVehicleIcon(engine, dir); if (sprite != 0) { - y += _traininfo_vehicle_pitch; // TODO Make this per-GRF + if (e->grffile != NULL) { + y += e->grffile->traininfo_vehicle_pitch; + } return sprite; } diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 6f9d70bc1..c9f967711 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -55,16 +55,6 @@ void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2) } /** - * Get the number of pixels for the given wagon length. - * @param len Length measured in 1/8ths of a standard wagon. - * @return Number of pixels across. - */ -int WagonLengthToPixels(int len) -{ - return (len * _traininfo_vehicle_width) / 8; -} - -/** * Draws an image of a whole train * @param v Front vehicle + @param x x Position to start at @@ -88,11 +78,12 @@ void DrawTrainImage(const Train *v, int x, int y, VehicleID selection, int max_w int px = -skip; bool sel_articulated = false; for (; v != NULL && px < max_width; v = v->Next()) { - int width = WagonLengthToPixels(Train::From(v)->tcache.cached_veh_length); + Point offset; + int width = Train::From(v)->GetDisplayImageWidth(&offset); if (px + width > 0) { SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); - DrawSprite(v->GetImage(DIR_W), pal, px + 16, 7 + (is_custom_sprite(RailVehInfo(v->engine_type)->image_index) ? _traininfo_vehicle_pitch : 0)); + DrawSprite(v->GetImage(DIR_W), pal, px + offset.x, 7 + offset.y); } if (!v->IsArticulatedPart()) sel_articulated = false; @@ -236,17 +227,19 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po int x = 1; for (;;) { if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) { - int dx = 0; + int px = x; u = v; do { + Point offset; + int width = u->GetDisplayImageWidth(&offset); SpriteID pal = (u->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(u); - DrawSprite(u->GetImage(DIR_W), pal, x + WagonLengthToPixels(4 + dx), y + 6 + (is_custom_sprite(RailVehInfo(u->engine_type)->image_index) ? _traininfo_vehicle_pitch : 0)); - dx += Train::From(u)->tcache.cached_veh_length; + DrawSprite(u->GetImage(DIR_W), pal, x + offset.x, y + 6 + offset.y); + px += width; u = u->Next(); } while (u != NULL && u->IsArticulatedPart() && u->cargo_cap == 0); - int px = x + WagonLengthToPixels(dx) + 2; + px += 2; int py = y + 2; switch (det_tab) { default: NOT_REACHED(); |