# HG changeset patch # User michi_cc # Date 2012-12-23 01:00:25 # Node ID a1593074c6b8f66d480c94c678411ff0ce27894f # Parent 22e7337f8afa4bf79b024cf221e578ac2829a861 (svn r24839) -Feature [FS#5271]: [NewGRF] Support oversized purchase list sprites. (Based on patch by Eddi) diff --git a/src/aircraft.h b/src/aircraft.h --- a/src/aircraft.h +++ b/src/aircraft.h @@ -32,7 +32,7 @@ enum VehicleAirFlags { void HandleAircraftEnterHangar(Aircraft *v); -void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, EngineImageType image_type); +void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type); void UpdateAirplanesOnNewStation(const Station *st); void UpdateAircraftCache(Aircraft *v, bool update_range = false); diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -202,17 +202,22 @@ void DrawAircraftEngine(int left, int ri } /** - * Get the size of the sprite of an aircraft sprite heading west (used for lists) - * @param engine The engine to get the sprite from - * @param width The width of the sprite - * @param height The height of the sprite + * Get the size of the sprite of an aircraft sprite heading west (used for lists). + * @param engine The engine to get the sprite from. + * @param[out] width The width of the sprite. + * @param[out] height The height of the sprite. + * @param[out] xoffs Number of pixels to shift the sprite to the right. + * @param[out] yoffs Number of pixels to shift the sprite downwards. + * @param image_type Context the sprite is used in. */ -void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, EngineImageType image_type) +void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type) { const Sprite *spr = GetSprite(GetAircraftIcon(engine, image_type), ST_NORMAL); width = UnScaleByZoom(spr->width, ZOOM_LVL_GUI); height = UnScaleByZoom(spr->height, ZOOM_LVL_GUI); + xoffs = UnScaleByZoom(spr->x_offs, ZOOM_LVL_GUI); + yoffs = UnScaleByZoom(spr->y_offs, ZOOM_LVL_GUI); } /** diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -43,7 +43,7 @@ */ uint GetEngineListHeight(VehicleType type) { - return max(FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM, GetVehicleHeight(type)); + return max(FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM, GetVehicleImageCellSize(type, EIT_PURCHASE).height); } static const NWidgetPart _nested_build_vehicle_widgets[] = { @@ -871,19 +871,18 @@ int DrawVehiclePurchaseInfo(int left, in */ void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group) { - static const int sprite_widths[] = { 60, 60, 76, 67 }; static const int sprite_y_offsets[] = { -1, -1, -2, -2 }; /* Obligatory sanity checks! */ - assert((uint)type < lengthof(sprite_widths)); - assert_compile(lengthof(sprite_y_offsets) == lengthof(sprite_widths)); assert(max <= eng_list->Length()); bool rtl = _current_text_dir == TD_RTL; int step_size = GetEngineListHeight(type); - int sprite_width = sprite_widths[type]; + int sprite_left = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_left; + int sprite_right = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_right; + int sprite_width = sprite_left + sprite_right; - int sprite_x = (rtl ? r - sprite_width / 2 : l + sprite_width / 2) - 1; + int sprite_x = rtl ? r - sprite_right - 1 : l + sprite_left + 1; int sprite_y_offset = sprite_y_offsets[type] + step_size / 2; Dimension replace_icon = {0, 0}; @@ -894,8 +893,8 @@ void DrawEngineList(VehicleType type, in count_width = GetStringBoundingBox(STR_TINY_BLACK_COMA).width; } - int text_left = l + (rtl ? WD_FRAMERECT_LEFT + replace_icon.width + 8 + count_width : sprite_width); - int text_right = r - (rtl ? sprite_width : WD_FRAMERECT_RIGHT + replace_icon.width + 8 + count_width); + int text_left = l + (rtl ? WD_FRAMERECT_LEFT + replace_icon.width + 8 + count_width : sprite_width + WD_FRAMETEXT_LEFT); + int text_right = r - (rtl ? sprite_width + WD_FRAMETEXT_RIGHT : WD_FRAMERECT_RIGHT + replace_icon.width + 8 + count_width); int replace_icon_left = rtl ? l + WD_FRAMERECT_LEFT : r - WD_FRAMERECT_RIGHT - replace_icon.width; int count_left = l; int count_right = rtl ? text_left : r - WD_FRAMERECT_RIGHT - replace_icon.width - 8; @@ -910,7 +909,7 @@ void DrawEngineList(VehicleType type, in const uint num_engines = GetGroupNumEngines(_local_company, selected_group, engine); SetDParam(0, engine); - DrawString(text_left, text_right, y + normal_text_y_offset, STR_ENGINE_NAME, engine == selected_id ? TC_WHITE : TC_BLACK); + DrawString(text_left, text_right, y + normal_text_y_offset, STR_ENGINE_NAME, engine == selected_id ? TC_WHITE : TC_BLACK, SA_STRIP | (rtl ? SA_RIGHT : SA_LEFT)); DrawVehicleEngine(l, r, sprite_x, y + sprite_y_offset, engine, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_company), EIT_PURCHASE); if (show_count) { SetDParam(0, num_engines); diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -11,6 +11,7 @@ #include "stdafx.h" #include "train.h" +#include "roadveh.h" #include "ship.h" #include "aircraft.h" #include "gui.h" @@ -141,41 +142,63 @@ static void TrainDepotMoveVehicle(const DoCommandP(v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20, wagon == NULL ? INVALID_VEHICLE : wagon->index, CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE)); } +static VehicleCellSize _base_block_sizes_depot[VEH_COMPANY_END]; ///< Cell size for vehicle images in the depot view. +static VehicleCellSize _base_block_sizes_purchase[VEH_COMPANY_END]; ///< Cell size for vehicle images in the purchase list. + /** - * Array containing the cell size in pixels of the #WID_D_MATRIX widget for each vehicle type. - * @note The train vehicle type uses the entire row for each train. + * Get the GUI cell size for a vehicle image. + * @param type Vehicle type to get the size for. + * @param image_type Image type to get size for. + * @pre image_type == EIT_IN_DEPOT || image_type == EIT_PURCHASE + * @return Cell dimensions for the vehicle and image type. */ -static Dimension _base_block_sizes[4]; +VehicleCellSize GetVehicleImageCellSize(VehicleType type, EngineImageType image_type) +{ + switch (image_type) { + case EIT_IN_DEPOT: return _base_block_sizes_depot[type]; + case EIT_PURCHASE: return _base_block_sizes_purchase[type]; + default: NOT_REACHED(); + } +} -static void InitBlocksizeForShipAircraft(VehicleType type) +static void InitBlocksizeForVehicles(VehicleType type, EngineImageType image_type) { - uint max_width = 0; + int max_extend_left = 0; + int max_extend_right = 0; uint max_height = 0; const Engine *e; FOR_ALL_ENGINES_OF_TYPE(e, type) { EngineID eid = e->index; uint x, y; + int x_offs, y_offs; switch (type) { default: NOT_REACHED(); - case VEH_SHIP: GetShipSpriteSize( eid, x, y, EIT_IN_DEPOT); break; - case VEH_AIRCRAFT: GetAircraftSpriteSize(eid, x, y, EIT_IN_DEPOT); break; + case VEH_TRAIN: GetTrainSpriteSize( eid, x, y, x_offs, y_offs, image_type); break; + case VEH_ROAD: GetRoadVehSpriteSize( eid, x, y, x_offs, y_offs, image_type); break; + case VEH_SHIP: GetShipSpriteSize( eid, x, y, x_offs, y_offs, image_type); break; + case VEH_AIRCRAFT: GetAircraftSpriteSize(eid, x, y, x_offs, y_offs, image_type); break; } - if (x > max_width) max_width = x; if (y > max_height) max_height = y; + if (-x_offs > max_extend_left) max_extend_left = -x_offs; + if ((int)x + x_offs > max_extend_right) max_extend_right = x + x_offs; } - switch (type) { - default: NOT_REACHED(); - case VEH_SHIP: - _base_block_sizes[VEH_SHIP].width = max(76U, max_width); + switch (image_type) { + case EIT_IN_DEPOT: + _base_block_sizes_depot[type].height = max(GetVehicleHeight(type), max_height); + _base_block_sizes_depot[type].extend_left = Clamp(max_extend_left, 16, 98); + _base_block_sizes_depot[type].extend_right = Clamp(max_extend_right, 16, 98); break; - case VEH_AIRCRAFT: - _base_block_sizes[VEH_AIRCRAFT].width = max(67U, max_width); + case EIT_PURCHASE: + _base_block_sizes_purchase[type].height = max(GetVehicleHeight(type), max_height); + _base_block_sizes_purchase[type].extend_left = Clamp(max_extend_left, 16, 98); + _base_block_sizes_purchase[type].extend_right = Clamp(max_extend_right, 16, 98); break; + + default: NOT_REACHED(); } - _base_block_sizes[type].height = max(GetVehicleHeight(type), max_height); } /** @@ -184,14 +207,10 @@ static void InitBlocksizeForShipAircraft */ void InitDepotWindowBlockSizes() { - _base_block_sizes[VEH_TRAIN].width = 0; - _base_block_sizes[VEH_TRAIN].height = GetVehicleHeight(VEH_TRAIN); - - _base_block_sizes[VEH_ROAD].width = 32; - _base_block_sizes[VEH_ROAD].height = GetVehicleHeight(VEH_ROAD); - - InitBlocksizeForShipAircraft(VEH_SHIP); - InitBlocksizeForShipAircraft(VEH_AIRCRAFT); + for (VehicleType vt = VEH_BEGIN; vt < VEH_COMPANY_END; vt++) { + InitBlocksizeForVehicles(vt, EIT_IN_DEPOT); + InitBlocksizeForVehicles(vt, EIT_PURCHASE); + } } static void DepotSellAllConfirmationCallback(Window *w, bool confirmed); @@ -600,13 +619,13 @@ struct DepotWindow : Window { } int base_width = this->count_width + this->header_width; - resize->height = max(_base_block_sizes[this->type].height, min_height); + resize->height = max(GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).height, min_height); if (this->type == VEH_TRAIN) { resize->width = 1; size->width = base_width + 2 * 29; // about 2 parts size->height = resize->height * 6; } else { - resize->width = base_width + _base_block_sizes[this->type].width; + resize->width = base_width + GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).extend_left + GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).extend_right; size->width = resize->width * (this->type == VEH_ROAD ? 5 : 3); size->height = resize->height * (this->type == VEH_ROAD ? 5 : 3); } diff --git a/src/roadveh.h b/src/roadveh.h --- a/src/roadveh.h +++ b/src/roadveh.h @@ -80,6 +80,7 @@ static const uint RVC_DEPOT_STOP_FRAME static const byte RV_OVERTAKE_TIMEOUT = 35; void RoadVehUpdateCache(RoadVehicle *v, bool same_length = false); +void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type); /** * Buses, trucks and trams belong to this class. diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -156,6 +156,25 @@ void DrawRoadVehEngine(int left, int rig } /** + * Get the size of the sprite of a road vehicle sprite heading west (used for lists). + * @param engine The engine to get the sprite from. + * @param[out] width The width of the sprite. + * @param[out] height The height of the sprite. + * @param[out] xoffs Number of pixels to shift the sprite to the right. + * @param[out] yoffs Number of pixels to shift the sprite downwards. + * @param image_type Context the sprite is used in. + */ +void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type) +{ + const Sprite *spr = GetSprite(GetRoadVehIcon(engine, image_type), ST_NORMAL); + + width = UnScaleByZoom(spr->width, ZOOM_LVL_GUI); + height = UnScaleByZoom(spr->height, ZOOM_LVL_GUI); + xoffs = UnScaleByZoom(spr->x_offs, ZOOM_LVL_GUI); + yoffs = UnScaleByZoom(spr->y_offs, ZOOM_LVL_GUI); +} + +/** * Get length of a road vehicle. * @param v Road vehicle to query length. * @return Length of the given road vehicle. diff --git a/src/ship.h b/src/ship.h --- a/src/ship.h +++ b/src/ship.h @@ -15,7 +15,7 @@ #include "vehicle_base.h" #include "water_map.h" -void GetShipSpriteSize(EngineID engine, uint &width, uint &height, EngineImageType image_type); +void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type); WaterClass GetEffectiveWaterClass(TileIndex tile); /** diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -86,17 +86,22 @@ void DrawShipEngine(int left, int right, } /** - * Get the size of the sprite of a ship sprite heading west (used for lists) - * @param engine The engine to get the sprite from - * @param width The width of the sprite - * @param height The height of the sprite + * Get the size of the sprite of a ship sprite heading west (used for lists). + * @param engine The engine to get the sprite from. + * @param[out] width The width of the sprite. + * @param[out] height The height of the sprite. + * @param[out] xoffs Number of pixels to shift the sprite to the right. + * @param[out] yoffs Number of pixels to shift the sprite downwards. + * @param image_type Context the sprite is used in. */ -void GetShipSpriteSize(EngineID engine, uint &width, uint &height, EngineImageType image_type) +void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type) { const Sprite *spr = GetSprite(GetShipIcon(engine, image_type), ST_NORMAL); width = UnScaleByZoom(spr->width, ZOOM_LVL_GUI); height = UnScaleByZoom(spr->height, ZOOM_LVL_GUI); + xoffs = UnScaleByZoom(spr->x_offs, ZOOM_LVL_GUI); + yoffs = UnScaleByZoom(spr->y_offs, ZOOM_LVL_GUI); } SpriteID Ship::GetImage(Direction direction, EngineImageType image_type) const diff --git a/src/train.h b/src/train.h --- a/src/train.h +++ b/src/train.h @@ -50,6 +50,8 @@ bool TryPathReserve(Train *v, bool mark_ int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, int *station_ahead, int *station_length); +void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type); + /** Variables that are cached to improve performance and such */ struct TrainCache { /* Cached wagon override spritegroup */ diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -528,6 +528,39 @@ void DrawTrainEngine(int left, int right } /** + * Get the size of the sprite of a train sprite heading west, or both heads (used for lists). + * @param engine The engine to get the sprite from. + * @param[out] width The width of the sprite. + * @param[out] height The height of the sprite. + * @param[out] xoffs Number of pixels to shift the sprite to the right. + * @param[out] yoffs Number of pixels to shift the sprite downwards. + * @param image_type Context the sprite is used in. + */ +void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type) +{ + int y = 0; + + SpriteID sprite = GetRailIcon(engine, false, y, image_type); + const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL); + + width = UnScaleByZoom(real_sprite->width, ZOOM_LVL_GUI); + height = UnScaleByZoom(real_sprite->height, ZOOM_LVL_GUI); + xoffs = UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI); + yoffs = UnScaleByZoom(real_sprite->y_offs, ZOOM_LVL_GUI); + + if (RailVehInfo(engine)->railveh_type == RAILVEH_MULTIHEAD) { + sprite = GetRailIcon(engine, true, y, image_type); + real_sprite = GetSprite(sprite, ST_NORMAL); + + /* Calculate values relative to an imaginary center between the two sprites. */ + width = TRAININFO_DEFAULT_VEHICLE_WIDTH + UnScaleByZoom(real_sprite->width, ZOOM_LVL_GUI) + UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI) - xoffs; + height = max(height, UnScaleByZoom(real_sprite->height, ZOOM_LVL_GUI)); + xoffs = xoffs - TRAININFO_DEFAULT_VEHICLE_WIDTH / 2; + yoffs = min(yoffs, UnScaleByZoom(real_sprite->y_offs, ZOOM_LVL_GUI)); + } +} + +/** * Build a railroad wagon. * @param tile tile of the depot where rail-vehicle is built. * @param flags type of operation. diff --git a/src/vehicle_gui.h b/src/vehicle_gui.h --- a/src/vehicle_gui.h +++ b/src/vehicle_gui.h @@ -66,6 +66,15 @@ static inline uint GetVehicleHeight(Vehi int GetVehicleWidth(Vehicle *v, EngineImageType image_type); +/** Dimensions of a cell in the purchase/depot windows. */ +struct VehicleCellSize { + uint height; ///< Vehicle cell height. + uint extend_left; ///< Extend of the cell to the left. + uint extend_right; ///< Extend of the cell to the right. +}; + +VehicleCellSize GetVehicleImageCellSize(VehicleType type, EngineImageType image_type); + /** * Get WindowClass for vehicle list of given vehicle type * @param vt vehicle type to check