changeset 14357:8c37cdc73f7f draft

(svn r18912) -Codechange: free up a bunch of airporttile ids by using the tile animation frame
author yexo <yexo@openttd.org>
date Sun, 24 Jan 2010 20:25:28 +0000
parents c9c50e212a9b
children 4d3d74ffee51
files src/airport.h src/saveload/afterload.cpp src/saveload/saveload.cpp src/station_cmd.cpp src/table/airporttile_ids.h src/table/airporttiles.h src/table/station_land.h
diffstat 7 files changed, 279 insertions(+), 346 deletions(-) [+]
line wrap: on
line diff
--- a/src/airport.h
+++ b/src/airport.h
@@ -21,11 +21,7 @@
 	MAX_TERMINALS =  10, ///< maximum number of terminals per airport
 	MAX_HELIPADS  =   4, ///< maximum number of helipads per airport
 	MAX_ELEMENTS  = 255, ///< maximum number of aircraft positions at airport
-	NUM_AIRPORTTILES = 144, ///< total number of airport tiles
-};
-
-enum {
-	AIRPORTTILE_NOANIM    = 0xFF, ///< flag to mark airport tiles as having no animation
+	NUM_AIRPORTTILES = 74, ///< total number of airport tiles
 };
 
 /** Airport types */
@@ -79,7 +75,7 @@
  * Defines the data structure of each indivudual tile of an airport.
  */
 struct AirportTileSpec {
-	StationGfx anim_next;                 ///< Next StationGfx in an animation
+	uint16 animation_info;                ///< Information about the animation (is it looping, how many loops etc)
 	uint8 animation_speed;                ///< The speed of the animation
 
 	static const AirportTileSpec *Get(StationGfx gfx);
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -2026,6 +2026,43 @@
 		}
 	}
 
+	/* Airport tile animation uses animation frame instead of other graphics id */
+	if (CheckSavegameVersion(137)) {
+		struct AirportTileConversion {
+			byte old_start;
+			byte num_frames;
+		};
+		static const AirportTileConversion atc[] = {
+			{31,  12}, // APT_RADAR_GRASS_FENCE_SW
+			{50,   4}, // APT_GRASS_FENCE_NE_FLAG
+			{62,   2}, // 1 unused tile
+			{66,  12}, // APT_RADAR_FENCE_SW
+			{78,  12}, // APT_RADAR_FENCE_NE
+			{101, 10}, // 9 unused tiles
+			{111,  8}, // 7 unused tiles
+			{119, 15}, // 14 unused tiles (radar)
+			{140,  4}, // APT_GRASS_FENCE_NE_FLAG_2
+		};
+		for (TileIndex t = 0; t < map_size; t++) {
+			if (IsAirportTile(t)) {
+				StationGfx old_gfx = GetStationGfx(t);
+				byte offset = 0;
+				for (uint i = 0; i < lengthof(atc); i++) {
+					if (old_gfx < atc[i].old_start) {
+						SetStationGfx(t, old_gfx - offset);
+						break;
+					}
+					if (old_gfx < atc[i].old_start + atc[i].num_frames) {
+						SetStationAnimationFrame(t, old_gfx - atc[i].old_start);
+						SetStationGfx(t, atc[i].old_start - offset);
+						break;
+					}
+					offset += atc[i].num_frames - 1;
+				}
+			}
+		}
+	}
+
 	/* Road stops is 'only' updating some caches */
 	AfterLoadRoadStops();
 	AfterLoadLabelMaps();
--- a/src/saveload/saveload.cpp
+++ b/src/saveload/saveload.cpp
@@ -46,7 +46,7 @@
 
 #include "saveload_internal.h"
 
-extern const uint16 SAVEGAME_VERSION = 136;
+extern const uint16 SAVEGAME_VERSION = 137;
 
 SavegameType _savegame_type; ///< type of savegame we are loading
 
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -46,6 +46,7 @@
 #include "core/random_func.hpp"
 #include "company_base.h"
 #include "newgrf.h"
+#include "table/airporttile_ids.h"
 
 #include "table/strings.h"
 
@@ -2345,6 +2346,27 @@
 		total_offset = 0;
 		custom_ground_offset = 0;
 	}
+
+	if (IsAirport(ti->tile)) {
+		switch (GetStationGfx(ti->tile)) {
+			case APT_RADAR_GRASS_FENCE_SW:
+				t = &_station_display_datas_airport_radar_grass_fence_sw[GetStationAnimationFrame(ti->tile)];
+				break;
+			case APT_GRASS_FENCE_NE_FLAG:
+				t = &_station_display_datas_airport_flag_grass_fence_ne[GetStationAnimationFrame(ti->tile)];
+				break;
+			case APT_RADAR_FENCE_SW:
+				t = &_station_display_datas_airport_radar_fence_sw[GetStationAnimationFrame(ti->tile)];
+				break;
+			case APT_RADAR_FENCE_NE:
+				t = &_station_display_datas_airport_radar_fence_ne[GetStationAnimationFrame(ti->tile)];
+				break;
+			case APT_GRASS_FENCE_NE_FLAG_2:
+				t = &_station_display_datas_airport_flag_grass_fence_ne_2[GetStationAnimationFrame(ti->tile)];
+				break;
+		}
+	}
+
 	Owner owner = GetTileOwner(ti->tile);
 
 	PaletteID palette;
@@ -2602,7 +2624,7 @@
 	 * hardcoded.....not good */
 	switch (GetStationType(tile)) {
 		case STATION_AIRPORT:
-			if (AirportTileSpec::Get(GetStationGfx(tile))->anim_next != AIRPORTTILE_NOANIM) {
+			if (AirportTileSpec::Get(GetStationGfx(tile))->animation_info != 0xFFFF) {
 				AddAnimatedTile(tile);
 			}
 			break;
@@ -2630,8 +2652,10 @@
 	if (IsAirport(tile)) {
 		const AirportTileSpec *ats = AirportTileSpec::Get(GetStationGfx(tile));
 		uint16 mask = (1 << ats->animation_speed) - 1;
-		if (ats->anim_next != AIRPORTTILE_NOANIM && (_tick_counter & mask) == 0) {
-			SetStationGfx(tile, ats->anim_next);
+		if (ats->animation_info != 0xFFFF && (_tick_counter & mask) == 0) {
+			uint8 next_frame = GetStationAnimationFrame(tile) + 1;
+			if (next_frame >= GB(ats->animation_info, 0, 8)) next_frame = 0;
+			SetStationAnimationFrame(tile, next_frame);
 			MarkTileDirtyByTile(tile);
 		}
 	}
--- a/src/table/airporttile_ids.h
+++ b/src/table/airporttile_ids.h
@@ -13,106 +13,80 @@
 #define AIRPORTTILE_IDS_H
 
 enum AirportTiles {
-	APT_APRON                  = 0,
-	APT_APRON_FENCE_NW         = 1,
-	APT_APRON_FENCE_SW         = 2,
-	APT_STAND                  = 3,
-	APT_APRON_W                = 4,
-	APT_APRON_S                = 5,
-	APT_APRON_VER_CROSSING_S   = 6,
-	APT_APRON_HOR_CROSSING_W   = 7,
-	APT_APRON_VER_CROSSING_N   = 8,
-	APT_APRON_HOR_CROSSING_E   = 9,
-	APT_APRON_E                = 10,
-	APT_ARPON_N                = 11,
-	APT_APRON_HOR              = 12,
-	APT_APRON_N_FENCE_SW       = 13,
-	APT_RUNWAY_1               = 14,
-	APT_RUNWAY_2               = 15,
-	APT_RUNWAY_3               = 16,
-	APT_RUNWAY_4               = 17,
-	APT_RUNWAY_END_FENCE_SE    = 18,
-	APT_BUILDING_2             = 19,
-	APT_TOWER_FENCE_SW         = 20,
-	APT_ROUND_TERMINAL         = 21,
-	APT_BUILDING_3             = 22,
-	APT_BUILDING_1             = 23,
-	APT_DEPOT_SE               = 24,
-	APT_STAND_1                = 25,
-	APT_STAND_PIER_NE          = 26,
-	APT_PIER_NW_NE             = 27,
-	APT_PIER                   = 28,
-	APT_EMPTY                  = 29,
-	APT_EMPTY_FENCE_NE         = 30,
-	APT_RADAR_GRASS_FENCE_SW   = 31,
-	/* 32-42 are for turning the radar */
-	APT_RADIO_TOWER_FENCE_NE   = 43,
-	APT_SMALL_BUILDING_3       = 44,
-	APT_SMALL_BUILDING_2       = 45,
-	APT_SMALL_BUILDING_1       = 46,
-	APT_GRASS_FENCE_SW         = 47,
-	APT_GRASS_2                = 48,
-	APT_GRASS_1                = 49,
-	APT_GRASS_FENCE_NE_FLAG    = 50,
-	/* 51-53 are for flag animation */
-	APT_RUNWAY_SMALL_NEAR_END  = 54,
-	APT_RUNWAY_SMALL_MIDDLE    = 55,
-	APT_RUNWAY_SMALL_FAR_END   = 56,
-	APT_SMALL_DEPOT_SE         = 57,
-	APT_HELIPORT               = 58,
-	APT_RUNWAY_END             = 59,
-	APT_RUNWAY_5               = 60,
-	APT_TOWER                  = 61,
-	APT_SMALL_DEPOT_SE_2       = 62, // unused (copy of APT_SMALL_DEPOT_SE)
-	APT_APRON_FENCE_NE         = 63,
-	APT_RUNWAY_END_FENCE_NW    = 64,
-	APT_RUNWAY_FENCE_NW        = 65,
-	APT_RADAR_FENCE_SW         = 66,
-	/* 67-77 are for turning the radar */
-	APT_RADAR_FENCE_NE         = 78,
-	/* 79-89 are for turning the radar */
-	APT_HELIPAD_1              = 90,
-	APT_HELIPAD_2_FENCE_NW     = 91,
-	APT_HELIPAD_2              = 92,
-	APT_APRON_FENCE_NE_SW      = 93,
-	APT_RUNWAY_END_FENCE_NW_SW = 94,
-	APT_RUNWAY_END_FENCE_SE_SW = 95,
-	APT_RUNWAY_END_FENCE_NE_NW = 96,
-	APT_RUNWAY_END_FENCE_NE_SE = 97,
-	APT_HELIPAD_2_FENCE_NE_SE  = 98,
-	APT_APRON_FENCE_SE_SW      = 99,
-	APT_LOW_BUILDING_FENCE_N   = 100,
-	APT_ROT_RUNWAY_FENCE_NE    = 101, // unused
-	APT_ROT_RUNWAY_END_FENCE_NE= 102, // unused
-	APT_ROT_RUNWAY_FENCE_SW    = 103, // unused
-	APT_ROT_RUNWAY_END_FENCE_SW= 104, // unused
-	APT_DEPOT_SW               = 105, // unused
-	APT_DEPOT_NW               = 106, // unused
-	APT_DEPOT_NE               = 107, // unused
-	APT_HELIPAD_2_FENCE_SE_SW  = 108, // unused
-	APT_HELIPAD_2_FENCE_SE     = 109, // unused
-	APT_LOW_BUILDING_FENCE_NW  = 110,
-	APT_LOW_BUILDING_FENCE_NE  = 111, // unused
-	APT_LOW_BUILDING_FENCE_SW  = 112, // unused
-	APT_LOW_BUILDING_FENCE_SE  = 113, // unused
-	APT_STAND_FENCE_NE         = 114, // unused
-	APT_STAND_FENCE_SE         = 115, // unused
-	APT_STAND_FENCE_SW         = 116, // unused
-	APT_APRON_FENCE_NE_2       = 117, // unused (copy of APT_APRON_FENCE_NE)
-	APT_APRON_FENCE_SE         = 118,
-	APT_HELIPAD_2_FENCE_NW_SW  = 119, // unused
-	APT_HELIPAD_2_FENCE_SW     = 120, // unused
-	APT_RADAR_FENCE_SE         = 121, // unused
-	/* 122-132 used for radar rotation */
-	APT_HELIPAD_3_FENCE_SE_SW  = 133,
-	APT_HELIPAD_3_FENCE_NW_SW  = 134,
-	APT_HELIPAD_3_FENCE_NW     = 135,
-	APT_LOW_BUILDING           = 136,
-	APT_APRON_FENCE_NE_SE      = 137,
-	APT_APRON_HALF_EAST        = 138,
-	APT_APRON_HALF_WEST        = 139,
-	APT_GRASS_FENCE_NE_FLAG_2  = 140,
-	/* 141-143 used for flag animation */
+	APT_APRON,
+	APT_APRON_FENCE_NW,
+	APT_APRON_FENCE_SW,
+	APT_STAND,
+	APT_APRON_W,
+	APT_APRON_S,
+	APT_APRON_VER_CROSSING_S,
+	APT_APRON_HOR_CROSSING_W,
+	APT_APRON_VER_CROSSING_N,
+	APT_APRON_HOR_CROSSING_E,
+	APT_APRON_E,
+	APT_ARPON_N,
+	APT_APRON_HOR,
+	APT_APRON_N_FENCE_SW,
+	APT_RUNWAY_1,
+	APT_RUNWAY_2,
+	APT_RUNWAY_3,
+	APT_RUNWAY_4,
+	APT_RUNWAY_END_FENCE_SE,
+	APT_BUILDING_2,
+	APT_TOWER_FENCE_SW,
+	APT_ROUND_TERMINAL,
+	APT_BUILDING_3,
+	APT_BUILDING_1,
+	APT_DEPOT_SE,
+	APT_STAND_1,
+	APT_STAND_PIER_NE,
+	APT_PIER_NW_NE,
+	APT_PIER,
+	APT_EMPTY,
+	APT_EMPTY_FENCE_NE,
+	APT_RADAR_GRASS_FENCE_SW,
+	APT_RADIO_TOWER_FENCE_NE,
+	APT_SMALL_BUILDING_3,
+	APT_SMALL_BUILDING_2,
+	APT_SMALL_BUILDING_1,
+	APT_GRASS_FENCE_SW,
+	APT_GRASS_2,
+	APT_GRASS_1,
+	APT_GRASS_FENCE_NE_FLAG,
+	APT_RUNWAY_SMALL_NEAR_END,
+	APT_RUNWAY_SMALL_MIDDLE,
+	APT_RUNWAY_SMALL_FAR_END,
+	APT_SMALL_DEPOT_SE,
+	APT_HELIPORT,
+	APT_RUNWAY_END,
+	APT_RUNWAY_5,
+	APT_TOWER,
+	APT_APRON_FENCE_NE,
+	APT_RUNWAY_END_FENCE_NW,
+	APT_RUNWAY_FENCE_NW,
+	APT_RADAR_FENCE_SW,
+	APT_RADAR_FENCE_NE,
+	APT_HELIPAD_1,
+	APT_HELIPAD_2_FENCE_NW,
+	APT_HELIPAD_2,
+	APT_APRON_FENCE_NE_SW,
+	APT_RUNWAY_END_FENCE_NW_SW,
+	APT_RUNWAY_END_FENCE_SE_SW,
+	APT_RUNWAY_END_FENCE_NE_NW,
+	APT_RUNWAY_END_FENCE_NE_SE,
+	APT_HELIPAD_2_FENCE_NE_SE,
+	APT_APRON_FENCE_SE_SW,
+	APT_LOW_BUILDING_FENCE_N,
+	APT_LOW_BUILDING_FENCE_NW,
+	APT_APRON_FENCE_SE,
+	APT_HELIPAD_3_FENCE_SE_SW,
+	APT_HELIPAD_3_FENCE_NW_SW,
+	APT_HELIPAD_3_FENCE_NW,
+	APT_LOW_BUILDING,
+	APT_APRON_FENCE_NE_SE,
+	APT_APRON_HALF_EAST,
+	APT_APRON_HALF_WEST,
+	APT_GRASS_FENCE_NE_FLAG_2,
 };
 
 #endif /* AIRPORTTILE_IDS_H */
--- a/src/table/airporttiles.h
+++ b/src/table/airporttiles.h
@@ -12,189 +12,101 @@
 #ifndef AIRPORTTILES_H
 #define AIRPORTTILES_H
 
+/** Writes all airport tile properties in the AirportTile struct */
+#define AT(num_frames, anim_speed) {(1 << 8) | num_frames, anim_speed}
+/** Writes an airport tile without animation in the AirportTile struct */
+#define AT_NOANIM {0xFFFF, 2}
 
-/** Writes all airport tile properties in the AirportTile struct */
-#define AT(anim_next, anim_speed) {anim_next, anim_speed}
 /** All default airport tiles.
  * @see AirportTiles for a list of names. */
 static const AirportTileSpec _origin_airporttile_specs[] = {
 	/* 0..9 */
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-
-	/* 10..19 */
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-
-	/* 20..29*/
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
 
-	/* 30..39*/
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(                32, 2),
-	AT(                33, 2),
-	AT(                34, 2),
-	AT(                35, 2),
-	AT(                36, 2),
-	AT(                37, 2),
-	AT(                38, 2),
-	AT(                39, 2),
-	AT(                40, 2),
-
-	/* 40..49 */
-	AT(                41, 2),
-	AT(                42, 2),
-	AT(                31, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
 
-	/* 50..59 */
-	AT(                51, 1),
-	AT(                52, 1),
-	AT(                53, 1),
-	AT(                50, 1),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-
-	/* 60..69 */
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(                67, 2),
-	AT(                68, 2),
-	AT(                69, 2),
-	AT(                70, 2),
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
 
-	/* 70..79 */
-	AT(                71, 2),
-	AT(                72, 2),
-	AT(                73, 2),
-	AT(                74, 2),
-	AT(                75, 2),
-	AT(                76, 2),
-	AT(                77, 2),
-	AT(                66, 2),
-	AT(                79, 2),
-	AT(                80, 2),
+	AT_NOANIM,
+	AT(12, 2), // APT_RADAR_GRASS_FENCE_SW
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT(4, 1), // APT_GRASS_FENCE_NE_FLAG
 
-	/* 80..89 */
-	AT(                81, 2),
-	AT(                82, 2),
-	AT(                83, 2),
-	AT(                84, 2),
-	AT(                85, 2),
-	AT(                86, 2),
-	AT(                87, 2),
-	AT(                88, 2),
-	AT(                89, 2),
-	AT(                78, 2),
-
-	/* 90..99 */
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
 
-	/* 100..109 */
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-
-	/* 110..119 */
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
+	AT_NOANIM,
+	AT(12, 2), // APT_RADAR_FENCE_SW
+	AT(12, 2), // APT_RADAR_FENCE_NE
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
 
-	/* 120..129 */
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(               122, 2),
-	AT(               123, 2),
-	AT(               124, 2),
-	AT(               125, 2),
-	AT(               126, 2),
-	AT(               127, 2),
-	AT(               128, 2),
-	AT(               129, 2),
-	AT(               130, 2),
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
 
-	/* 130..139 */
-	AT(               131, 2),
-	AT(               132, 2),
-	AT(               121, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-	AT(AIRPORTTILE_NOANIM, 2),
-
-	/* 140..143 */
-	AT(               141, 1),
-	AT(               142, 1),
-	AT(               143, 1),
-	AT(               140, 1),
+	AT_NOANIM,
+	AT_NOANIM,
+	AT_NOANIM,
+	AT(4, 1), // APT_GRASS_FENCE_NE_FLAG_2
 };
 
 assert_compile(NUM_AIRPORTTILES == lengthof(_origin_airporttile_specs));
 
+#undef AT_NOANIM
 #undef AT
 
 #endif /* AIRPORTTILES_H */
--- a/src/table/station_land.h
+++ b/src/table/station_land.h
@@ -810,6 +810,52 @@
 	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_passenger_tunnel) // APT_PIER
 	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_nothing)   // APT_EMPTY
 	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_fence_ne)  // APT_EMPTY_FENCE_NE
+	{0, NULL}, // APT_RADAR_GRASS_FENCE_SW
+	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_transmitter_fence_ne) // APT_RADIO_TOWER_FENCE_NE
+	TILE_SPRITE_LINE(SPR_AIRFIELD_TERM_A,            _station_display_nothing)   // APT_SMALL_BUILDING_3
+	TILE_SPRITE_LINE(SPR_AIRFIELD_TERM_B,            _station_display_nothing)   // APT_SMALL_BUILDING_2
+	TILE_SPRITE_LINE(SPR_AIRFIELD_TERM_C_GROUND | (1 << PALETTE_MODIFIER_COLOUR), _station_display_datas_terminal_c_2) // APT_SMALL_BUILDING_1
+	TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_A,           _station_display_fence_sw)  // APT_GRASS_FENCE_SW
+	TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_B,           _station_display_nothing)   // APT_GRASS_2
+	TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_C,           _station_display_nothing)   // APT_GRASS_1
+	{0, NULL}, // APT_GRASS_FENCE_NE_FLAG
+	TILE_SPRITE_LINE(SPR_AIRFIELD_RUNWAY_NEAR_END,   _station_display_fence_se)  // APT_RUNWAY_SMALL_NEAR_END
+	TILE_SPRITE_LINE(SPR_AIRFIELD_RUNWAY_MIDDLE,     _station_display_fence_se)  // APT_RUNWAY_SMALL_MIDDLE
+	TILE_SPRITE_LINE(SPR_AIRFIELD_RUNWAY_FAR_END,    _station_display_fence_se)  // APT_RUNWAY_SMALL_FAR_END
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_small_depot_se) // APT_SMALL_DEPOT_SE
+	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_heliport)  // APT_HELIPORT
+	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_END,         _station_display_nothing)   // APT_RUNWAY_END
+	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_EXIT_B,      _station_display_nothing)   // APT_RUNWAY_5
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_tower)     // APT_TOWER
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_fence_ne)  // APT_APRON_FENCE_NE
+	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_END,         _station_display_fence_nw)  // APT_RUNWAY_END_FENCE_NW
+	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_EXIT_B,      _station_display_fence_nw)  // APT_RUNWAY_FENCE_NW
+	{0, NULL}, // APT_RADAR_FENCE_SW
+	{0, NULL}, // APT_RADAR_FENCE_NE
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_helipad_fence_sw) // APT_HELIPAD_1
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_helipad_fence_nw) // APT_HELIPAD_2_FENCE_NW
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_helipad)     // APT_HELIPAD_2
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_fence_ne_sw) // APT_APRON_FENCE_NE_SW
+	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_END,         _station_display_fence_nw_sw) // APT_RUNWAY_END_FENCE_NW_SW
+	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_END,         _station_display_fence_se_sw) // APT_RUNWAY_END_FENCE_SE_SW
+	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_END,         _station_display_fence_ne_nw) // APT_RUNWAY_END_FENCE_NE_NW
+	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_END,         _station_display_fence_ne_se) // APT_RUNWAY_END_FENCE_NE_SE
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_helipad_fence_NE_SE) // APT_HELIPAD_2_FENCE_NE_SE
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_fence_se_sw) // APT_APRON_FENCE_SE_SW
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_low_building_fence_ne_nw) // APT_LOW_BUILDING_FENCE_N
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_low_building_fence_nw) // APT_LOW_BUILDING_FENCE_NW
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_fence_se) // APT_APRON_FENCE_SE
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_newhelipad_fence_se_sw) // APT_HELIPAD_3_FENCE_SE_SW
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_newhelipad_fence_nw_sw) // APT_HELIPAD_3_FENCE_NW_SW
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_newhelipad_fence_nw) // APT_HELIPAD_3_FENCE_NW
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_low_building) // APT_LOW_BUILDING
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_fence_ne_se) // APT_APRON_FENCE_NE_SE
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_grass_west) // APT_APRON_HALF_EAST
+	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_grass_east) // APT_APRON_HALF_WEST
+	{0, NULL}, // APT_GRASS_FENCE_NE_FLAG_2
+};
+
+static const DrawTileSprites _station_display_datas_airport_radar_grass_fence_sw[] = {
 	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_radar_1_fence_sw) // APT_RADAR_GRASS_FENCE_SW
 	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_radar_2_fence_sw)
 	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_radar_3_fence_sw)
@@ -822,29 +868,16 @@
 	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_radar_10_fence_sw)
 	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_radar_11_fence_sw)
 	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_radar_12_fence_sw)
-	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_transmitter_fence_ne) // APT_RADIO_TOWER_FENCE_NE
-	TILE_SPRITE_LINE(SPR_AIRFIELD_TERM_A,            _station_display_nothing)   // APT_SMALL_BUILDING_3
-	TILE_SPRITE_LINE(SPR_AIRFIELD_TERM_B,            _station_display_nothing)   // APT_SMALL_BUILDING_2
-	TILE_SPRITE_LINE(SPR_AIRFIELD_TERM_C_GROUND | (1 << PALETTE_MODIFIER_COLOUR), _station_display_datas_terminal_c_2) // APT_SMALL_BUILDING_1
-	TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_A,           _station_display_fence_sw)  // APT_GRASS_FENCE_SW
-	TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_B,           _station_display_nothing)   // APT_GRASS_2
-	TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_C,           _station_display_nothing)   // APT_GRASS_1
+};
+
+static const DrawTileSprites _station_display_datas_airport_flag_grass_fence_ne[] = {
 	TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_D,           _station_display_flag_1_fence_ne) // APT_GRASS_FENCE_NE_FLAG
 	TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_D,           _station_display_flag_2_fence_ne)
 	TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_D,           _station_display_flag_3_fence_ne)
 	TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_D,           _station_display_flag_4_fence_ne)
-	TILE_SPRITE_LINE(SPR_AIRFIELD_RUNWAY_NEAR_END,   _station_display_fence_se)  // APT_RUNWAY_SMALL_NEAR_END
-	TILE_SPRITE_LINE(SPR_AIRFIELD_RUNWAY_MIDDLE,     _station_display_fence_se)  // APT_RUNWAY_SMALL_MIDDLE
-	TILE_SPRITE_LINE(SPR_AIRFIELD_RUNWAY_FAR_END,    _station_display_fence_se)  // APT_RUNWAY_SMALL_FAR_END
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_small_depot_se) // APT_SMALL_DEPOT_SE
-	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_heliport)  // APT_HELIPORT
-	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_END,         _station_display_nothing)   // APT_RUNWAY_END
-	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_EXIT_B,      _station_display_nothing)   // APT_RUNWAY_5
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_tower)     // APT_TOWER
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_small_depot_se) // APT_SMALL_DEPOT_SE_2
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_fence_ne)  // APT_APRON_FENCE_NE
-	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_END,         _station_display_fence_nw)  // APT_RUNWAY_END_FENCE_NW
-	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_EXIT_B,      _station_display_fence_nw)  // APT_RUNWAY_FENCE_NW
+};
+
+static const DrawTileSprites _station_display_datas_airport_radar_fence_sw[] = {
 	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_1_fence_sw) // APT_RADAR_FENCE_SW
 	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_2_fence_sw)
 	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_3_fence_sw)
@@ -857,6 +890,9 @@
 	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_10_fence_sw)
 	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_11_fence_sw)
 	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_12_fence_sw)
+};
+
+static const DrawTileSprites _station_display_datas_airport_radar_fence_ne[] = {
 	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_1_fence_ne) // APT_RADAR_FENCE_NE
 	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_2_fence_ne)
 	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_3_fence_ne)
@@ -869,62 +905,16 @@
 	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_10_fence_ne)
 	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_11_fence_ne)
 	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_12_fence_ne)
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_helipad_fence_sw) // APT_HELIPAD_1
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_helipad_fence_nw) // APT_HELIPAD_2_FENCE_NW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_helipad)     // APT_HELIPAD_2
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_fence_ne_sw) // APT_APRON_FENCE_NE_SW
-	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_END,         _station_display_fence_nw_sw) // APT_RUNWAY_END_FENCE_NW_SW
-	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_END,         _station_display_fence_se_sw) // APT_RUNWAY_END_FENCE_SE_SW
-	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_END,         _station_display_fence_ne_nw) // APT_RUNWAY_END_FENCE_NE_NW
-	TILE_SPRITE_LINE(SPR_AIRPORT_RUNWAY_END,         _station_display_fence_ne_se) // APT_RUNWAY_END_FENCE_NE_SE
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_helipad_fence_NE_SE) // APT_HELIPAD_2_FENCE_NE_SE
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_fence_se_sw) // APT_APRON_FENCE_SE_SW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_low_building_fence_ne_nw) // APT_LOW_BUILDING_FENCE_N
-	TILE_SPRITE_LINE(SPR_NSRUNWAY1,                  _station_display_fence_ne) // APT_ROT_RUNWAY_FENCE_NE
-	TILE_SPRITE_LINE(SPR_NSRUNWAY_END,               _station_display_fence_ne) // APT_ROT_RUNWAY_END_FENCE_NE
-	TILE_SPRITE_LINE(SPR_NSRUNWAY1,                  _station_display_fence_sw) // APT_ROT_RUNWAY_FENCE_SW
-	TILE_SPRITE_LINE(SPR_NSRUNWAY_END,               _station_display_fence_sw) // APT_ROT_RUNWAY_END_FENCE_SW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_hangar_sw) // APT_DEPOT_SW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_hangar_nw) // APT_DEPOT_NW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_hangar_ne) // APT_DEPOT_NE
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_helipad_fence_se_sw) // APT_HELIPAD_2_FENCE_SE_SW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_helipad_fence_se) // APT_HELIPAD_2_FENCE_SE
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_low_building_fence_nw) // APT_LOW_BUILDING_FENCE_NW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_low_building_fence_ne) // APT_LOW_BUILDING_FENCE_NE
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_low_building_fence_sw) // APT_LOW_BUILDING_FENCE_SW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_low_building_fence_se) // APT_LOW_BUILDING_FENCE_SE
-	TILE_SPRITE_LINE(SPR_AIRPORT_AIRCRAFT_STAND,     _station_display_fence_ne) // APT_STAND_FENCE_NE
-	TILE_SPRITE_LINE(SPR_AIRPORT_AIRCRAFT_STAND,     _station_display_fence_se) // APT_STAND_FENCE_SE
-	TILE_SPRITE_LINE(SPR_AIRPORT_AIRCRAFT_STAND,     _station_display_fence_sw) // APT_STAND_FENCE_SW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_fence_ne) // APT_APRON_FENCE_NE_2
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_fence_se) // APT_APRON_FENCE_SE
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_helipad_fence_nw_sw) // APT_HELIPAD_2_FENCE_NW_SW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_helipad_fence_sw) // APT_HELIPAD_2_FENCE_SW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_1_fence_se) // APT_RADAR_FENCE_SE
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_2_fence_se)
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_3_fence_se)
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_4_fence_se)
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_5_fence_se)
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_6_fence_se)
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_7_fence_se)
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_8_fence_se)
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_9_fence_se)
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_10_fence_se)
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_11_fence_se)
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_radar_12_fence_se)
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_newhelipad_fence_se_sw) // APT_HELIPAD_3_FENCE_SE_SW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_newhelipad_fence_nw_sw) // APT_HELIPAD_3_FENCE_NW_SW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_newhelipad_fence_nw) // APT_HELIPAD_3_FENCE_NW
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_low_building) // APT_LOW_BUILDING
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_fence_ne_se) // APT_APRON_FENCE_NE_SE
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_grass_west) // APT_APRON_HALF_EAST
-	TILE_SPRITE_LINE(SPR_AIRPORT_APRON,              _station_display_grass_east) // APT_APRON_HALF_WEST
+};
+
+static const DrawTileSprites _station_display_datas_airport_flag_grass_fence_ne_2[] = {
 	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_flag_1_fence_ne) // APT_GRASS_FENCE_NE_FLAG_2
 	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_flag_2_fence_ne)
 	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_flag_3_fence_ne)
 	TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE,            _station_display_flag_4_fence_ne)
 };
 
+
 static const DrawTileSprites _station_display_datas_truck[] = {
 	TILE_SPRITE_LINE(SPR_TRUCK_STOP_NE_GROUND | (1 << PALETTE_MODIFIER_COLOUR), _station_display_datas_67)
 	TILE_SPRITE_LINE(SPR_TRUCK_STOP_SE_GROUND | (1 << PALETTE_MODIFIER_COLOUR), _station_display_datas_68)