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.
This commit is contained in:
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