1
0
Fork 0

Codechange: Use vector for airport tile layouts. (#12607)

Simplify AirportSpec data by storing layout information together in a vector, instead of separate arrays.

This removes manual memory management and separate count members.

The default layouts will be copied instead of always referring to the originals.
pull/12613/head
Peter Nelson 2024-05-02 12:37:54 +01:00 committed by GitHub
parent 65c9df49d9
commit cf96d49ced
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 122 additions and 184 deletions

View File

@ -277,7 +277,7 @@ public:
const AirportSpec *as = ac->GetSpec(_selected_airport_index); const AirportSpec *as = ac->GetSpec(_selected_airport_index);
if (as->IsAvailable()) { if (as->IsAvailable()) {
/* Ensure the airport layout is valid. */ /* Ensure the airport layout is valid. */
_selected_airport_layout = Clamp(_selected_airport_layout, 0, as->num_table - 1); _selected_airport_layout = Clamp(_selected_airport_layout, 0, static_cast<uint8_t>(as->layouts.size() - 1));
selectFirstAirport = false; selectFirstAirport = false;
this->UpdateSelectSize(); this->UpdateSelectSize();
} }
@ -306,7 +306,7 @@ public:
StringID string = GetAirportTextCallback(as, _selected_airport_layout, CBID_AIRPORT_LAYOUT_NAME); StringID string = GetAirportTextCallback(as, _selected_airport_layout, CBID_AIRPORT_LAYOUT_NAME);
if (string != STR_UNDEFINED) { if (string != STR_UNDEFINED) {
SetDParam(0, string); SetDParam(0, string);
} else if (as->num_table > 1) { } else if (as->layouts.size() > 1) {
SetDParam(0, STR_STATION_BUILD_AIRPORT_LAYOUT_NAME); SetDParam(0, STR_STATION_BUILD_AIRPORT_LAYOUT_NAME);
SetDParam(1, _selected_airport_layout + 1); SetDParam(1, _selected_airport_layout + 1);
} }
@ -348,7 +348,7 @@ public:
for (int i = 0; i < NUM_AIRPORTS; i++) { for (int i = 0; i < NUM_AIRPORTS; i++) {
const AirportSpec *as = AirportSpec::Get(i); const AirportSpec *as = AirportSpec::Get(i);
if (!as->enabled) continue; if (!as->enabled) continue;
for (uint8_t layout = 0; layout < as->num_table; layout++) { for (uint8_t layout = 0; layout < static_cast<uint8_t>(as->layouts.size()); layout++) {
SpriteID sprite = GetCustomAirportSprite(as, layout); SpriteID sprite = GetCustomAirportSprite(as, layout);
if (sprite != 0) { if (sprite != 0) {
Dimension d = GetSpriteSize(sprite); Dimension d = GetSpriteSize(sprite);
@ -364,7 +364,7 @@ public:
for (int i = NEW_AIRPORT_OFFSET; i < NUM_AIRPORTS; i++) { for (int i = NEW_AIRPORT_OFFSET; i < NUM_AIRPORTS; i++) {
const AirportSpec *as = AirportSpec::Get(i); const AirportSpec *as = AirportSpec::Get(i);
if (!as->enabled) continue; if (!as->enabled) continue;
for (uint8_t layout = 0; layout < as->num_table; layout++) { for (uint8_t layout = 0; layout < static_cast<uint8_t>(as->layouts.size()); layout++) {
StringID string = GetAirportTextCallback(as, layout, CBID_AIRPORT_ADDITIONAL_TEXT); StringID string = GetAirportTextCallback(as, layout, CBID_AIRPORT_ADDITIONAL_TEXT);
if (string == STR_UNDEFINED) continue; if (string == STR_UNDEFINED) continue;
@ -474,14 +474,14 @@ public:
const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index); const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index);
int w = as->size_x; int w = as->size_x;
int h = as->size_y; int h = as->size_y;
Direction rotation = as->rotation[_selected_airport_layout]; Direction rotation = as->layouts[_selected_airport_layout].rotation;
if (rotation == DIR_E || rotation == DIR_W) Swap(w, h); if (rotation == DIR_E || rotation == DIR_W) Swap(w, h);
SetTileSelectSize(w, h); SetTileSelectSize(w, h);
this->preview_sprite = GetCustomAirportSprite(as, _selected_airport_layout); this->preview_sprite = GetCustomAirportSprite(as, _selected_airport_layout);
this->SetWidgetDisabledState(WID_AP_LAYOUT_DECREASE, _selected_airport_layout == 0); this->SetWidgetDisabledState(WID_AP_LAYOUT_DECREASE, _selected_airport_layout == 0);
this->SetWidgetDisabledState(WID_AP_LAYOUT_INCREASE, _selected_airport_layout + 1 >= as->num_table); this->SetWidgetDisabledState(WID_AP_LAYOUT_INCREASE, _selected_airport_layout + 1U >= as->layouts.size());
int rad = _settings_game.station.modified_catchment ? as->catchment : (uint)CA_UNMODIFIED; int rad = _settings_game.station.modified_catchment ? as->catchment : (uint)CA_UNMODIFIED;
if (_settings_client.gui.station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad); if (_settings_client.gui.station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);

View File

@ -3861,32 +3861,6 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop,
return ret; return ret;
} }
/**
* Create a copy of the tile table so it can be freed later
* without problems.
* @param as The AirportSpec to copy the arrays of.
*/
static void DuplicateTileTable(AirportSpec *as)
{
AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
for (int i = 0; i < as->num_table; i++) {
uint num_tiles = 1;
const AirportTileTable *it = as->table[0];
do {
num_tiles++;
} while ((++it)->ti.x != -0x80);
table_list[i] = MallocT<AirportTileTable>(num_tiles);
MemCpyT(table_list[i], as->table[i], num_tiles);
}
as->table = table_list;
HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
MemCpyT(depot_table, as->depot_table, as->nof_depots);
as->depot_table = depot_table;
Direction *rotation = MallocT<Direction>(as->num_table);
MemCpyT(rotation, as->rotation, as->num_table);
as->rotation = rotation;
}
/** /**
* Define properties for airports * Define properties for airports
* @param airport Local ID of the airport. * @param airport Local ID of the airport.
@ -3942,44 +3916,38 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B
as->grf_prop.grffile = _cur.grffile; as->grf_prop.grffile = _cur.grffile;
/* override the default airport */ /* override the default airport */
_airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id); _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
/* Create a copy of the original tiletable so it can be freed later. */
DuplicateTileTable(as);
} }
break; break;
} }
case 0x0A: { // Set airport layout case 0x0A: { // Set airport layout
uint8_t old_num_table = as->num_table; uint8_t num_layouts = buf->ReadByte();
free(as->rotation); buf->ReadDWord(); // Total size of definition, unneeded.
as->num_table = buf->ReadByte(); // Number of layaouts uint8_t size_x = 0;
as->rotation = MallocT<Direction>(as->num_table); uint8_t size_y = 0;
uint32_t defsize = buf->ReadDWord(); // Total size of the definition
AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
int size;
const AirportTileTable *copy_from;
try {
for (uint8_t j = 0; j < as->num_table; j++) {
const_cast<Direction&>(as->rotation[j]) = (Direction)buf->ReadByte();
for (int k = 0;; k++) {
att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
att[k].ti.y = buf->ReadByte();
if (att[k].ti.x == 0 && att[k].ti.y == 0x80) { std::vector<AirportTileLayout> layouts;
/* Not the same terminator. The one we are using is rather layouts.reserve(num_layouts);
* x = -80, y = 0 . So, adjust it. */
att[k].ti.x = -0x80;
att[k].ti.y = 0;
att[k].gfx = 0;
size = k + 1; for (uint8_t j = 0; j != num_layouts; ++j) {
copy_from = att; auto &layout = layouts.emplace_back();
layout.rotation = static_cast<Direction>(buf->ReadByte() & 6); // Rotation can only be DIR_NORTH, DIR_EAST, DIR_SOUTH or DIR_WEST.
for (;;) {
auto &tile = layout.tiles.emplace_back();
tile.ti.x = buf->ReadByte();
tile.ti.y = buf->ReadByte();
if (tile.ti.x == 0 && tile.ti.y == 0x80) {
/* Convert terminator to our own. */
tile.ti.x = -0x80;
tile.ti.y = 0;
tile.gfx = 0;
break; break;
} }
att[k].gfx = buf->ReadByte(); tile.gfx = buf->ReadByte();
if (att[k].gfx == 0xFE) { if (tile.gfx == 0xFE) {
/* Use a new tile from this GRF */ /* Use a new tile from this GRF */
int local_tile_id = buf->ReadWord(); int local_tile_id = buf->ReadWord();
@ -3990,41 +3958,26 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B
GrfMsg(2, "AirportChangeInfo: Attempt to use airport tile {} with airport id {}, not yet defined. Ignoring.", local_tile_id, airport + i); GrfMsg(2, "AirportChangeInfo: Attempt to use airport tile {} with airport id {}, not yet defined. Ignoring.", local_tile_id, airport + i);
} else { } else {
/* Declared as been valid, can be used */ /* Declared as been valid, can be used */
att[k].gfx = tempid; tile.gfx = tempid;
} }
} else if (att[k].gfx == 0xFF) { } else if (tile.gfx == 0xFF) {
att[k].ti.x = (int8_t)GB(att[k].ti.x, 0, 8); tile.ti.x = static_cast<int8_t>(GB(tile.ti.x, 0, 8));
att[k].ti.y = (int8_t)GB(att[k].ti.y, 0, 8); tile.ti.y = static_cast<int8_t>(GB(tile.ti.y, 0, 8));
} }
if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) { /* Determine largest size. */
as->size_x = std::max<uint8_t>(as->size_x, att[k].ti.y + 1); if (layout.rotation == DIR_E || layout.rotation == DIR_W) {
as->size_y = std::max<uint8_t>(as->size_y, att[k].ti.x + 1); size_x = std::max<uint8_t>(size_x, tile.ti.y + 1);
size_y = std::max<uint8_t>(size_y, tile.ti.x + 1);
} else { } else {
as->size_x = std::max<uint8_t>(as->size_x, att[k].ti.x + 1); size_x = std::max<uint8_t>(size_x, tile.ti.x + 1);
as->size_y = std::max<uint8_t>(as->size_y, att[k].ti.y + 1); size_y = std::max<uint8_t>(size_y, tile.ti.y + 1);
} }
} }
tile_table[j] = CallocT<AirportTileTable>(size);
memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
}
/* Free old layouts in the airport spec */
for (int j = 0; j < old_num_table; j++) {
/* remove the individual layouts */
free(as->table[j]);
}
free(as->table);
/* Install final layout construction in the airport spec */
as->table = tile_table;
free(att);
} catch (...) {
for (int i = 0; i < as->num_table; i++) {
free(tile_table[i]);
}
free(tile_table);
free(att);
throw;
} }
as->layouts = std::move(layouts);
as->size_x = size_x;
as->size_y = size_y;
break; break;
} }
@ -8726,18 +8679,6 @@ static void ResetCustomHouses()
static void ResetCustomAirports() static void ResetCustomAirports()
{ {
for (GRFFile * const file : _grf_files) { for (GRFFile * const file : _grf_files) {
for (auto &as : file->airportspec) {
if (as != nullptr) {
/* We need to remove the tiles layouts */
for (int j = 0; j < as->num_table; j++) {
/* remove the individual layouts */
free(as->table[j]);
}
free(as->table);
free(as->depot_table);
free(as->rotation);
}
}
file->airportspec.clear(); file->airportspec.clear();
file->airtspec.clear(); file->airtspec.clear();
} }

View File

@ -95,11 +95,11 @@ bool AirportSpec::IsAvailable() const
*/ */
bool AirportSpec::IsWithinMapBounds(uint8_t table, TileIndex tile) const bool AirportSpec::IsWithinMapBounds(uint8_t table, TileIndex tile) const
{ {
if (table >= this->num_table) return false; if (table >= this->layouts.size()) return false;
uint8_t w = this->size_x; uint8_t w = this->size_x;
uint8_t h = this->size_y; uint8_t h = this->size_y;
if (this->rotation[table] == DIR_E || this->rotation[table] == DIR_W) Swap(w, h); if (this->layouts[table].rotation == DIR_E || this->layouts[table].rotation == DIR_W) Swap(w, h);
return TileX(tile) + w < Map::SizeX() && return TileX(tile) + w < Map::SizeX() &&
TileY(tile) + h < Map::SizeY(); TileY(tile) + h < Map::SizeY();

View File

@ -94,16 +94,18 @@ struct HangarTileTable {
uint8_t hangar_num; ///< The hangar to which this tile belongs. uint8_t hangar_num; ///< The hangar to which this tile belongs.
}; };
struct AirportTileLayout {
std::vector<AirportTileTable> tiles; ///< List of all tiles in this layout.
Direction rotation; ///< The rotation of this layout.
};
/** /**
* Defines the data structure for an airport. * Defines the data structure for an airport.
*/ */
struct AirportSpec { struct AirportSpec {
const struct AirportFTAClass *fsm; ///< the finite statemachine for the default airports const struct AirportFTAClass *fsm; ///< the finite statemachine for the default airports
const AirportTileTable * const *table; ///< list of the tiles composing the airport std::vector<AirportTileLayout> layouts; ///< List of layouts composing the airport.
const Direction *rotation; ///< the rotation of each tiletable std::span<const HangarTileTable> depots; ///< Position of the depots on the airports.
uint8_t num_table; ///< number of elements in the table
const HangarTileTable *depot_table; ///< gives the position of the depots on the airports
uint8_t nof_depots; ///< the number of hangar tiles in this airport
uint8_t size_x; ///< size of airport in x direction uint8_t size_x; ///< size of airport in x direction
uint8_t size_y; ///< size of airport in y direction uint8_t size_y; ///< size of airport in y direction
uint8_t noise_level; ///< noise that this airport generates uint8_t noise_level; ///< noise that this airport generates

View File

@ -138,7 +138,8 @@
if (_settings_game.economy.station_noise_level) { if (_settings_game.economy.station_noise_level) {
uint dist; uint dist;
AirportGetNearestTown(as, as->rotation[0], tile, AirportTileTableIterator(as->table[0], tile), dist); const auto &layout = as->layouts[0];
AirportGetNearestTown(as, layout.rotation, tile, AirportTileTableIterator(layout.tiles.data(), tile), dist);
return GetAirportNoiseLevelForDistance(as, dist); return GetAirportNoiseLevelForDistance(as, dist);
} }
@ -154,7 +155,8 @@
if (!as->IsWithinMapBounds(0, tile)) return INVALID_TOWN; if (!as->IsWithinMapBounds(0, tile)) return INVALID_TOWN;
uint dist; uint dist;
return AirportGetNearestTown(as, as->rotation[0], tile, AirportTileTableIterator(as->table[0], tile), dist)->index; const auto &layout = as->layouts[0];
return AirportGetNearestTown(as, layout.rotation, tile, AirportTileTableIterator(layout.tiles.data(), tile), dist)->index;
} }
/* static */ SQInteger ScriptAirport::GetMaintenanceCostFactor(AirportType type) /* static */ SQInteger ScriptAirport::GetMaintenanceCostFactor(AirportType type)

View File

@ -322,7 +322,7 @@ struct Airport : public TileArea {
/** Check if this airport has at least one hangar. */ /** Check if this airport has at least one hangar. */
inline bool HasHangar() const inline bool HasHangar() const
{ {
return this->GetSpec()->nof_depots > 0; return !this->GetSpec()->depots.empty();
} }
/** /**
@ -357,10 +357,9 @@ struct Airport : public TileArea {
*/ */
inline TileIndex GetHangarTile(uint hangar_num) const inline TileIndex GetHangarTile(uint hangar_num) const
{ {
const AirportSpec *as = this->GetSpec(); for (const auto &depot : this->GetSpec()->depots) {
for (uint i = 0; i < as->nof_depots; i++) { if (depot.hangar_num == hangar_num) {
if (as->depot_table[i].hangar_num == hangar_num) { return this->GetRotatedTileFromOffset(depot.ti);
return this->GetRotatedTileFromOffset(as->depot_table[i].ti);
} }
} }
NOT_REACHED(); NOT_REACHED();
@ -376,7 +375,7 @@ struct Airport : public TileArea {
{ {
const AirportSpec *as = this->GetSpec(); const AirportSpec *as = this->GetSpec();
const HangarTileTable *htt = GetHangarDataByTile(tile); const HangarTileTable *htt = GetHangarDataByTile(tile);
return ChangeDir(htt->dir, DirDifference(this->rotation, as->rotation[0])); return ChangeDir(htt->dir, DirDifference(this->rotation, as->layouts[0].rotation));
} }
/** /**
@ -396,11 +395,10 @@ struct Airport : public TileArea {
{ {
uint num = 0; uint num = 0;
uint counted = 0; uint counted = 0;
const AirportSpec *as = this->GetSpec(); for (const auto &depot : this->GetSpec()->depots) {
for (uint i = 0; i < as->nof_depots; i++) { if (!HasBit(counted, depot.hangar_num)) {
if (!HasBit(counted, as->depot_table[i].hangar_num)) {
num++; num++;
SetBit(counted, as->depot_table[i].hangar_num); SetBit(counted, depot.hangar_num);
} }
} }
return num; return num;
@ -415,10 +413,9 @@ private:
*/ */
inline const HangarTileTable *GetHangarDataByTile(TileIndex tile) const inline const HangarTileTable *GetHangarDataByTile(TileIndex tile) const
{ {
const AirportSpec *as = this->GetSpec(); for (const auto &depot : this->GetSpec()->depots) {
for (uint i = 0; i < as->nof_depots; i++) { if (this->GetRotatedTileFromOffset(depot.ti) == tile) {
if (this->GetRotatedTileFromOffset(as->depot_table[i].ti) == tile) { return &depot;
return as->depot_table + i;
} }
} }
NOT_REACHED(); NOT_REACHED();

View File

@ -98,8 +98,8 @@ bool IsHangar(Tile t)
const Station *st = Station::GetByTile(t); const Station *st = Station::GetByTile(t);
const AirportSpec *as = st->airport.GetSpec(); const AirportSpec *as = st->airport.GetSpec();
for (uint i = 0; i < as->nof_depots; i++) { for (const auto &depot : as->depots) {
if (st->airport.GetHangarTile(i) == TileIndex(t)) return true; if (st->airport.GetRotatedTileFromOffset(depot.ti) == TileIndex(t)) return true;
} }
return false; return false;
@ -2414,10 +2414,10 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint8_t airport
/* Check if a valid, buildable airport was chosen for construction */ /* Check if a valid, buildable airport was chosen for construction */
const AirportSpec *as = AirportSpec::Get(airport_type); const AirportSpec *as = AirportSpec::Get(airport_type);
if (!as->IsAvailable() || layout >= as->num_table) return CMD_ERROR; if (!as->IsAvailable() || layout >= as->layouts.size()) return CMD_ERROR;
if (!as->IsWithinMapBounds(layout, tile)) return CMD_ERROR; if (!as->IsWithinMapBounds(layout, tile)) return CMD_ERROR;
Direction rotation = as->rotation[layout]; Direction rotation = as->layouts[layout].rotation;
int w = as->size_x; int w = as->size_x;
int h = as->size_y; int h = as->size_y;
if (rotation == DIR_E || rotation == DIR_W) Swap(w, h); if (rotation == DIR_E || rotation == DIR_W) Swap(w, h);
@ -2427,7 +2427,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint8_t airport
return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT); return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT);
} }
AirportTileTableIterator tile_iter(as->table[layout], tile); AirportTileTableIterator tile_iter(as->layouts[layout].tiles.data(), tile);
CommandCost cost = CheckFlatLandAirport(tile_iter, flags); CommandCost cost = CheckFlatLandAirport(tile_iter, flags);
if (cost.Failed()) return cost; if (cost.Failed()) return cost;
@ -2477,7 +2477,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint8_t airport
return_cmd_error(STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT); return_cmd_error(STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT);
} }
for (AirportTileTableIterator iter(as->table[layout], tile); iter != INVALID_TILE; ++iter) { for (AirportTileTableIterator iter(as->layouts[layout].tiles.data(), tile); iter != INVALID_TILE; ++iter) {
cost.AddCost(_price[PR_BUILD_STATION_AIRPORT]); cost.AddCost(_price[PR_BUILD_STATION_AIRPORT]);
} }
@ -2493,7 +2493,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint8_t airport
st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TRY); st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TRY);
for (AirportTileTableIterator iter(as->table[layout], tile); iter != INVALID_TILE; ++iter) { for (AirportTileTableIterator iter(as->layouts[layout].tiles.data(), tile); iter != INVALID_TILE; ++iter) {
Tile t(iter); Tile t(iter);
MakeAirport(t, st->owner, st->index, iter.GetStationGfx(), WATER_CLASS_INVALID); MakeAirport(t, st->owner, st->index, iter.GetStationGfx(), WATER_CLASS_INVALID);
SetStationTileRandomBits(t, GB(Random(), 0, 4)); SetStationTileRandomBits(t, GB(Random(), 0, 4));
@ -2503,7 +2503,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint8_t airport
} }
/* Only call the animation trigger after all tiles have been built */ /* Only call the animation trigger after all tiles have been built */
for (AirportTileTableIterator iter(as->table[layout], tile); iter != INVALID_TILE; ++iter) { for (AirportTileTableIterator iter(as->layouts[layout].tiles.data(), tile); iter != INVALID_TILE; ++iter) {
AirportTileAnimationTrigger(st, iter, AAT_BUILT); AirportTileAnimationTrigger(st, iter, AAT_BUILT);
} }

View File

@ -28,7 +28,7 @@
#define MKEND {{-0x80, 0}, 0} #define MKEND {{-0x80, 0}, 0}
/** Tiles for Country Airfield (small) */ /** Tiles for Country Airfield (small) */
static const AirportTileTable _tile_table_country_0[] = { static const std::initializer_list<AirportTileTable> _tile_table_country_0 = {
MK(0, 0, APT_SMALL_BUILDING_1), MK(0, 0, APT_SMALL_BUILDING_1),
MK(1, 0, APT_SMALL_BUILDING_2), MK(1, 0, APT_SMALL_BUILDING_2),
MK(2, 0, APT_SMALL_BUILDING_3), MK(2, 0, APT_SMALL_BUILDING_3),
@ -44,12 +44,12 @@ static const AirportTileTable _tile_table_country_0[] = {
MKEND MKEND
}; };
static const AirportTileTable * const _tile_table_country[] = { static const std::initializer_list<AirportTileLayout> _tile_table_country = {
_tile_table_country_0, { _tile_table_country_0, DIR_N },
}; };
/** Tiles for Commuter Airfield (small) */ /** Tiles for Commuter Airfield (small) */
static const AirportTileTable _tile_table_commuter_0[] = { static const std::initializer_list<AirportTileTable> _tile_table_commuter_0 = {
MK(0, 0, APT_TOWER), MK(0, 0, APT_TOWER),
MK(1, 0, APT_BUILDING_3), MK(1, 0, APT_BUILDING_3),
MK(2, 0, APT_HELIPAD_2_FENCE_NW), MK(2, 0, APT_HELIPAD_2_FENCE_NW),
@ -73,12 +73,12 @@ static const AirportTileTable _tile_table_commuter_0[] = {
MKEND MKEND
}; };
static const AirportTileTable * const _tile_table_commuter[] = { static const std::initializer_list<AirportTileLayout> _tile_table_commuter = {
_tile_table_commuter_0, { _tile_table_commuter_0, DIR_N },
}; };
/** Tiles for City Airport (large) */ /** Tiles for City Airport (large) */
static const AirportTileTable _tile_table_city_0[] = { static const std::initializer_list<AirportTileTable> _tile_table_city_0 = {
MK(0, 0, APT_BUILDING_1), MK(0, 0, APT_BUILDING_1),
MK(1, 0, APT_APRON_FENCE_NW), MK(1, 0, APT_APRON_FENCE_NW),
MK(2, 0, APT_STAND_1), MK(2, 0, APT_STAND_1),
@ -118,12 +118,12 @@ static const AirportTileTable _tile_table_city_0[] = {
MKEND MKEND
}; };
static const AirportTileTable * const _tile_table_city[] = { static const std::initializer_list<AirportTileLayout> _tile_table_city = {
_tile_table_city_0, { _tile_table_city_0, DIR_N },
}; };
/** Tiles for Metropolitain Airport (large) - 2 runways */ /** Tiles for Metropolitain Airport (large) - 2 runways */
static const AirportTileTable _tile_table_metropolitan_0[] = { static const std::initializer_list<AirportTileTable> _tile_table_metropolitan_0 = {
MK(0, 0, APT_BUILDING_1), MK(0, 0, APT_BUILDING_1),
MK(1, 0, APT_APRON_FENCE_NW), MK(1, 0, APT_APRON_FENCE_NW),
MK(2, 0, APT_STAND_1), MK(2, 0, APT_STAND_1),
@ -163,12 +163,12 @@ static const AirportTileTable _tile_table_metropolitan_0[] = {
MKEND MKEND
}; };
static const AirportTileTable * const _tile_table_metropolitan[] = { static const std::initializer_list<AirportTileLayout> _tile_table_metropolitan = {
_tile_table_metropolitan_0, { _tile_table_metropolitan_0, DIR_N },
}; };
/** Tiles for International Airport (large) - 2 runways */ /** Tiles for International Airport (large) - 2 runways */
static const AirportTileTable _tile_table_international_0[] = { static const std::initializer_list<AirportTileTable> _tile_table_international_0 = {
MK(0, 0, APT_RUNWAY_END_FENCE_NW), MK(0, 0, APT_RUNWAY_END_FENCE_NW),
MK(1, 0, APT_RUNWAY_FENCE_NW), MK(1, 0, APT_RUNWAY_FENCE_NW),
MK(2, 0, APT_RUNWAY_FENCE_NW), MK(2, 0, APT_RUNWAY_FENCE_NW),
@ -221,12 +221,12 @@ static const AirportTileTable _tile_table_international_0[] = {
MKEND MKEND
}; };
static const AirportTileTable * const _tile_table_international[] = { static const std::initializer_list<AirportTileLayout> _tile_table_international = {
_tile_table_international_0, { _tile_table_international_0, DIR_N },
}; };
/** Tiles for International Airport (large) - 2 runways */ /** Tiles for International Airport (large) - 2 runways */
static const AirportTileTable _tile_table_intercontinental_0[] = { static const std::initializer_list<AirportTileTable> _tile_table_intercontinental_0 = {
MK(0, 0, APT_RADAR_FENCE_NE), MK(0, 0, APT_RADAR_FENCE_NE),
MK(1, 0, APT_RUNWAY_END_FENCE_NE_NW), MK(1, 0, APT_RUNWAY_END_FENCE_NE_NW),
MK(2, 0, APT_RUNWAY_FENCE_NW), MK(2, 0, APT_RUNWAY_FENCE_NW),
@ -329,22 +329,22 @@ static const AirportTileTable _tile_table_intercontinental_0[] = {
MKEND MKEND
}; };
static const AirportTileTable * const _tile_table_intercontinental[] = { static const std::initializer_list<AirportTileLayout> _tile_table_intercontinental = {
_tile_table_intercontinental_0, { _tile_table_intercontinental_0, DIR_N },
}; };
/** Tiles for Heliport */ /** Tiles for Heliport */
static const AirportTileTable _tile_table_heliport_0[] = { static const std::initializer_list<AirportTileTable> _tile_table_heliport_0 = {
MK(0, 0, APT_HELIPORT), MK(0, 0, APT_HELIPORT),
MKEND MKEND
}; };
static const AirportTileTable * const _tile_table_heliport[] = { static const std::initializer_list<AirportTileLayout> _tile_table_heliport = {
_tile_table_heliport_0, { _tile_table_heliport_0, DIR_N },
}; };
/** Tiles for Helidepot */ /** Tiles for Helidepot */
static const AirportTileTable _tile_table_helidepot_0[] = { static const std::initializer_list<AirportTileTable> _tile_table_helidepot_0 = {
MK(0, 0, APT_LOW_BUILDING_FENCE_N), MK(0, 0, APT_LOW_BUILDING_FENCE_N),
MK(1, 0, APT_DEPOT_SE), MK(1, 0, APT_DEPOT_SE),
MK(0, 1, APT_HELIPAD_2_FENCE_NE_SE), MK(0, 1, APT_HELIPAD_2_FENCE_NE_SE),
@ -352,12 +352,12 @@ static const AirportTileTable _tile_table_helidepot_0[] = {
MKEND MKEND
}; };
static const AirportTileTable * const _tile_table_helidepot[] = { static const std::initializer_list<AirportTileLayout> _tile_table_helidepot = {
_tile_table_helidepot_0, { _tile_table_helidepot_0, DIR_N },
}; };
/** Tiles for Helistation */ /** Tiles for Helistation */
static const AirportTileTable _tile_table_helistation_0[] = { static const std::initializer_list<AirportTileTable> _tile_table_helistation_0 = {
MK(0, 0, APT_DEPOT_SE), MK(0, 0, APT_DEPOT_SE),
MK(1, 0, APT_LOW_BUILDING_FENCE_NW), MK(1, 0, APT_LOW_BUILDING_FENCE_NW),
MK(2, 0, APT_HELIPAD_3_FENCE_NW), MK(2, 0, APT_HELIPAD_3_FENCE_NW),
@ -369,29 +369,25 @@ static const AirportTileTable _tile_table_helistation_0[] = {
MKEND MKEND
}; };
static const AirportTileTable * const _tile_table_helistation[] = { static const std::initializer_list<AirportTileLayout> _tile_table_helistation = {
_tile_table_helistation_0, { _tile_table_helistation_0, DIR_N },
};
static const Direction _default_airports_rotation[] = {
DIR_N,
}; };
#undef MK #undef MK
#undef MKEND #undef MKEND
/** General AirportSpec definition. */ /** General AirportSpec definition. */
#define AS_GENERIC(fsm, att, rot, att_len, depot_tbl, num_depots, size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, enabled) \ #define AS_GENERIC(fsm, layouts, depots, size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, enabled) \
{fsm, att, rot, att_len, depot_tbl, num_depots, size_x, size_y, noise, catchment, min_year, max_year, name, ttdpatch_type, class_id, preview, maint_cost, enabled, GRFFileProps(AT_INVALID)} {fsm, layouts, depots, size_x, size_y, noise, catchment, min_year, max_year, name, ttdpatch_type, class_id, preview, maint_cost, enabled, GRFFileProps(AT_INVALID)}
/** AirportSpec definition for airports without any depot. */ /** AirportSpec definition for airports without any depot. */
#define AS_ND(ap_name, size_x, size_y, min_year, max_year, catchment, noise, maint_cost, ttdpatch_type, class_id, name, preview) \ #define AS_ND(ap_name, size_x, size_y, min_year, max_year, catchment, noise, maint_cost, ttdpatch_type, class_id, name, preview) \
AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, _default_airports_rotation, lengthof(_tile_table_##ap_name), nullptr, 0, \ AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, {}, \
size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, true) size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, true)
/** AirportSpec definition for airports with at least one depot. */ /** AirportSpec definition for airports with at least one depot. */
#define AS(ap_name, size_x, size_y, min_year, max_year, catchment, noise, maint_cost, ttdpatch_type, class_id, name, preview) \ #define AS(ap_name, size_x, size_y, min_year, max_year, catchment, noise, maint_cost, ttdpatch_type, class_id, name, preview) \
AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, _default_airports_rotation, lengthof(_tile_table_##ap_name), _airport_depots_##ap_name, lengthof(_airport_depots_##ap_name), \ AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, _airport_depots_##ap_name, \
size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, true) size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, true)
/* The helidepot and helistation have ATP_TTDP_SMALL because they are at ground level */ /* The helidepot and helistation have ATP_TTDP_SMALL because they are at ground level */
@ -405,12 +401,12 @@ extern const AirportSpec _origin_airport_specs[] = {
AS(helidepot, 2, 2, 1976, CalendarTime::MAX_YEAR, 4, 2, 7, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELIDEPOT, SPR_AIRPORT_PREVIEW_HELIDEPOT), AS(helidepot, 2, 2, 1976, CalendarTime::MAX_YEAR, 4, 2, 7, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELIDEPOT, SPR_AIRPORT_PREVIEW_HELIDEPOT),
AS(intercontinental, 9, 11, 2002, CalendarTime::MAX_YEAR, 10, 25, 72, ATP_TTDP_LARGE, APC_HUB, STR_AIRPORT_INTERCONTINENTAL, SPR_AIRPORT_PREVIEW_INTERCONTINENTAL), AS(intercontinental, 9, 11, 2002, CalendarTime::MAX_YEAR, 10, 25, 72, ATP_TTDP_LARGE, APC_HUB, STR_AIRPORT_INTERCONTINENTAL, SPR_AIRPORT_PREVIEW_INTERCONTINENTAL),
AS(helistation, 4, 2, 1980, CalendarTime::MAX_YEAR, 4, 3, 14, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELISTATION, SPR_AIRPORT_PREVIEW_HELISTATION), AS(helistation, 4, 2, 1980, CalendarTime::MAX_YEAR, 4, 3, 14, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELISTATION, SPR_AIRPORT_PREVIEW_HELISTATION),
AS_GENERIC(&_airportfta_oilrig, nullptr, _default_airports_rotation, 0, nullptr, 0, 1, 1, 0, 4, 0, 0, 0, ATP_TTDP_OILRIG, APC_HELIPORT, STR_NULL, 0, false), AS_GENERIC(&_airportfta_oilrig, {}, {}, 1, 1, 0, 4, 0, 0, 0, ATP_TTDP_OILRIG, APC_HELIPORT, STR_NULL, 0, false),
}; };
static_assert(NEW_AIRPORT_OFFSET == lengthof(_origin_airport_specs)); static_assert(NEW_AIRPORT_OFFSET == lengthof(_origin_airport_specs));
const AirportSpec AirportSpec::dummy = AS_GENERIC(&_airportfta_dummy, nullptr, _default_airports_rotation, 0, nullptr, 0, 0, 0, 0, 0, CalendarTime::MIN_YEAR, CalendarTime::MIN_YEAR, 0, ATP_TTDP_LARGE, APC_BEGIN, STR_NULL, 0, false); const AirportSpec AirportSpec::dummy = AS_GENERIC(&_airportfta_dummy, {}, {}, 0, 0, 0, 0, CalendarTime::MIN_YEAR, CalendarTime::MIN_YEAR, 0, ATP_TTDP_LARGE, APC_BEGIN, STR_NULL, 0, false);
#undef AS #undef AS
#undef AS_ND #undef AS_ND